Search code examples
prologclpfd

List inequality constraint


I am trying to write a Prolog (CLP) predicate that would build a constraint constraining inequality of two lists.

More formally, having two lists A=[A1,...,AN], B=[B1,...,BN] the constraint is defined as (A1 #\= B1) #\/ (A2 #\= B2) #\/ ... #\/ (AN #\= BN).

I am unsure how to build this constraint given two lists of arbitrary length. This is my attempt. I understand why it does not work, but can not fix it.

any_different([], []).
any_different([H1|T1], [H2|T2]):-
    H1 #\= H2 #\/ any_different(T1, T2).

Solution

  • You'll want to build up the disjunction and return it through a third argument:

    any_different([], [], V) :-
        V #= 0.  % no differences between [] and []
    any_different([H1|T1], [H2|T2], Disj) :-
        any_different(T1, T2, Disj0),
        Disj #<==> (H1 #\= H2) #\/ Disj0.
    

    Now, calling any_different(List1, List2, AnyDiff) contrains a variable AnyDiff that you can pass to the labeling predicate along with your other variables. By stating AnyDiff #= 0 you can constrain List1 and List2 to be equal, while AnyDiff #= 1 will cause them to be unequal.