Bug in element/3?

Hi there!
I’m using SWI-Prolog version 9.3.19
and I’ve found probably a bug in element/3 with this test:


test(N) :-
element(N, [1,2], A),
element(N, [1,2], B),
A #=< 2,
A + B #>= 3.

The correct output I expect is:

?- test(N).
N = 2.

But instead, it now outputs:

?- test(N).
N in 1..2,

Does it look familiar to something discussed before?
Thanks a lot!!

When you say “the correct output I expect to see is N=2”, is this based on a older version of SWI, or a different Prolog system?
What you seeing is the list of constraints after the clpfd implementation has attempted to reduce the domains of variables. In your example, it cannot constrain N smaller than 1..2. (even though N is 2 is the only answer). What typically occurs with constraints is that some variables can be constrained to a single value (and hence are unified to that value), whereas the other variables need to be tested for valid values using label/1 or labeling/2.
e.g. adding label to your example shows.

?- element(N, [1,2], A),element(N, [1,2], B),A #=< 2,A + B #>= 3,label([A,B,N]).
N = A, A = B, B = 2.

Thanks Ian for explaining :slight_smile:
My expectation of “N=2” is not based on any Prolog version or implementation, but just on pure logic.
I just expected the constrain solver can really reduce to the smallest domain within which every value satisfies the constraint.
But since labelling can give the correct result, perhaps I don’t need to worry about it? Although I am still unsure wether this suggests some potential side effect in more complicated situations.
Will come back later if something unusual happens.
Thank you very much!

In general, local constraint propagation isn’t strong enough to “reduce to the smallest domain” and still be efficient. So some form of searching (labelling in clpfd) is usually necessary. That’s the general CLP paradigm - constrain, then search vs. the normal LP paradigm of generate, then test.

Thanks! That makes sense!