如何确定两个列表在prolog中是否具有相同的元素?

时间:2009-11-17 10:17:37

标签: list prolog

如何确定两个列表在prolog中是否具有相同的元素? 如果我有两个列表A和B,我想知道它们是否具有相同的元素。

5 个答案:

答案 0 :(得分:3)

你需要写一个谓词。您可能会发现内置member/2的prolog非常有用。

如果不给出答案,就很难再说了。试想一下吧。你会明白的。

答案 1 :(得分:1)

我们从基于内置谓词member/2的纯实现开始:

common_member(Xs,Ys) :-
   member(E,Xs),
   member(E,Ys).

示例查询:

?- common_member([1,2,3],[1]).
  true
; false.

?- common_member([1,2,3],[4]).
false.

?- common_member([1,2,3],[2,3,1]).
  true
; true
; true
; false.

声明地说,上面的代码是可以的。 但是,它在成功时留下了无用的选择点。 此外,如果两个列表中都有多个项目,我们会得到多余的答案。

我们能否在保持逻辑纯净的同时提高效率? 是!

但是怎么样?将if_/3与已确定的测试谓词memberd_t/3一起使用!

common_memberd([X|Xs],Ys) :-
   if_(memberd_t(X,Ys), true, common_memberd(Xs,Ys)).

让我们再次在样本查询之上运行,这次使用common_memberd/2

?- common_memberd([1,2,3],[1]).
true.

?- common_memberd([1,2,3],[4]).
false.

?- common_memberd([1,2,3],[2,3,1]).
true.

已经消除了冗余答案,并且后续查询确实如此。

请注意common_memberd/2是纯粹的,所以即使是非常一般的查询,我们也能得到合理的答案!

?- common_memberd([1,2,3],[A,B]).
      A=1
; dif(A,1),                         B=1
;               A=2 ,           dif(B,1)
; dif(A,1), dif(A,2),                         B=2
;                         A=3 , dif(B,1), dif(B,2)
; dif(A,1), dif(A,2), dif(A,3),                     B=3
; false.

答案 2 :(得分:1)

如何使用intersection/3

doesIntersect(X,Y) :-
    intersection(X,Y,Z),
    dif(Z,[]).

如果intersection/3生成一个空列表,则列表没有任何共同之处,结果为false。

intersection/3递归调用member/2

intersection([X|Tail],Y,[X|Z]) :-
    member(X,Y),
    intersection(Tail,Y,Z).
intersection([X|Tail],Y,Z) :-
    \+ member(X,Y),
    intersection(Tail,Y,Z).
intersection([],_,[]).

source.

答案 3 :(得分:0)

您可以首先构建一个谓词differs/2,以验证列表A上的任何元素是否不是列表B的成员。如果您在A上找到满足此条件的元素,则可以确认A中未包含B。这实际上更容易尝试验证A中是否存在B的每个元素 使用内置谓词member/2differs/2将如下所示:

differs(T, Q):- 
         member(X,T), 
         not( member(X, Q)). 

现在要证明两个列表都包含相同的元素,您只需要验证它们不是differs。使用@repeat使用的相同谓词名称(好奇,谁现在重复?),这是我的common_memberd\2谓词:

common_memberd(T, Q):- 
                not( differs(T, Q)), 
                not( differs(Q, T)).

请教:

?- common_memberd( [2,3,4,1], [3, 1,4,2]).  
   true.  
?- common_memberd( [2,3,1,5], [3, 1,4,2]).  
   false.

注意:无论元素的顺序如何,此解决方案都有效,或者它们是否重复。

答案 4 :(得分:-1)

请告诉我这是您要找的地方:

same(T, Q) :- any(T, Q), !; any(Q, T), !.

any([X|_], [X,_]):- !.
any([X|T], Q) :- member(X, Q), !; any(T, Q), !.

如果您查阅:

?- same([1,2,3,4], [3]).
true.

?- same([1,2,3,4], [4]).
true.

?- same([1], [1,4]).
true.

?- same([1,4], [1]).
true.