Search code examples
prologclpfd

Duplicate constraints in CLP(FD) and with dif/2


In SWI-Prolog, the following query gives this result:

?- X mod 2 #= 0, X mod 2 #= 0.
X mod 2#=0,
X mod 2#=0.

While correct, there is obviously no need for the second constraint

Similarly:

?- dif(X,0), dif(X,0).
dif(X, 0),
dif(X, 0).

Is there no way to avoid such duplicate constraints? (Obviously the most correct way would be to not write code that leads to that situation, but it is not always that easy).


Solution

  • You can either avoid posting redundant constraints, or remove them with a setof/3-like construct. Both are very implementation specific. The best interface for such purpose is offered by SICStus. Other implementations like YAP or SWI more or less copied that interface, by leaving out some essential parts. A recent attempt to overcome SWI's deficiencies was rejected.

    Avoid posting constraints

    In SICStus, you can use frozen/2 for this purpose:

    | ?- dif(X,0), frozen(X,Goal).
    Goal = prolog:dif(X,0),
    prolog:dif(X,0) ? ;
    no
    | ?- X mod 2#=0, frozen(X, Goal).
    Goal = clpfd:(X in inf..sup,X mod 2#=0),
    X mod 2#=0,
    X in inf..sup ? ;
    no
    

    Otherwise, copy_term/3 might be good enough, provided the constraints are not too much interconnected with each other.

    Eliminate redundant constraints

    Here, a setof-like construct together with call_residue_vars/1 and copy_term/3 is probably the best approach. Again, the original implementation is in SICStus....