Search code examples
prologprolog-diflogical-purity

different/2 - does a pure, determinate definition exist?


different(Xs, Ys) :-
   member(X, Xs),
   non_member(X, Ys).
different(Xs, Ys) :-
   member(Y, Ys),
   non_member(Y, Xs).

While this definition using member/2 and non_member/2 is almost1 perfect from a declarative viewpoint, it produces redundant solutions for certain queries and leaves choice points all around.

What is a definition that improves upon this (in a pure manner probably using if_/3 and (=)/3) such that exactly the same set of solutions is described by different/2 but is determinate at least for ground queries (thus does not leave any useless choice points open) and omits (if possible) any redundant answer?


1 Actually, different([a|nonlist],[]), different([],[b|nonlist]) succeeds. It could equally fail. So a solution that fails for both is fine (maybe even finer).


Solution

  • Let's take it to the limit---by the help of list_nonmember_t/3, exists_in_t/3, and or_/2!

    some_absent_t(Xs,Ys,Truth) :-
       exists_in_t(list_nonmember_t(Ys),Xs,Truth).
    
    different(Xs,Ys) :-
       or_(some_absent_t(Xs,Ys),
           some_absent_t(Ys,Xs)).