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.