Thank you for the insight @jan!
You are right in saying that solve/4
, and in particular the findnsols/4
solution in pengines.pl
is the problem. Here’s how I confirmed it.
1) Trying to use once/1
First I though I could get around the problem with a clever use of once/1
: I noted at a recursive repl that this invocation loses the CHR constraints (here sugar/0
is a CHR constraint):
findnsols(1, X, (sugar, member(X, [1,2])), Xs).
But this one keeps them:
once(findnsols(1, X, (sugar, member(X, [1,2])), Xs)).
Interestingly this one loses them again:
once(findnsols(1, X, (sugar, member(X, [1])), Xs)).
I think this behavior has to do with leaving choicepoints but I’d like to understand it better.
2) Changing findsols_no_empty/4
in pengines.pl
The most ergonomic way to change pengines.el
seemed to rewrite the findsols_no_empty/4
predicate. I could get it working in 2 ways:
findnsols_no_empty(N, Template, Goal, List) :-
call(Goal),
List = [Template].
- The one trying to use
once/1
but adding a fake predicate to retain a choice point (?).
findnsols_no_empty(N, Template, Goal, List) :-
once(findnsols(N, Template, (Goal, member(_, [1,2])), List)),
List \== [].
I like the second solution you proposed more, but I’m not familiar with all the implication that changing this code could have for SWISH, so I would appreciate more guidance on the type of solution that you are envisioning here.