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

后端 未结 8 1018
野的像风
野的像风 2020-12-07 00:24
different(Xs, Ys) :-
   member(X, Xs),
   non_member(X, Ys).
different(Xs, Ys) :-
   member(Y, Ys),
   non_member(Y, Xs).

While this definition usi

8条回答
  •  离开以前
    2020-12-07 01:03

    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!

提交回复
热议问题