different(Xs, Ys) :-
member(X, Xs),
non_member(X, Ys).
different(Xs, Ys) :-
member(Y, Ys),
non_member(Y, Xs).
While this definition usi
Here's another try! We utilize the monotone if-then-else control construct if_/3, in combination with the reified list membership predicate memberd_t/3, and first argument indexing to avoid the creation of useless choice-points.
different(Xs,Ys) :-
different_aux(Xs,Ys,Xs,Ys).
different_aux([],[_|_],Xs0,Ys0) :-
different_aux(Ys0,[],Ys0,Xs0). % swap Xs/Ys pair
different_aux([X|Xs],Ys,Xs0,Ys0) :-
if_(memberd_t(X,Ys0),
different_aux(Ys,Xs,Ys0,Xs0), % variant: different_aux(Xs,Ys,Xs0,Ys0)
true).
First, we run a query that we expect to fail:
?- different([1,2,3],[2,3,1]).
false.
The following queries are similar to the failing query given above; each one has a single "different" item x
placed at different indices in the first [1,2,3]
or the second list [2,3,1]
:
?- different([4,2,3],[2,3,1]), different([1,2,3],[4,3,1]), different([1,4,3],[2,3,1]), different([1,2,3],[2,4,1]), different([1,2,4],[2,3,1]), different([1,2,3],[2,3,4]). true. % all subgoals succeed deterministically
OK! Let's run another (quite general) query that I used in my previous answer:
?- different([A,B],[X,Y]).
A=X , B=X , dif(Y,X)
; A=X , dif(B,X), dif(Y,B)
; A=Y , dif(B,X), dif(Y,X)
; dif(A,X), dif(A,Y).
Compact! A big improvement over what I presented earlier!