两个列表至少有一个没有Prolog内置谓词的公共元素

两个列表至少有一个没有Prolog内置谓词的公共元素,prolog,swi-prolog-for-sharing,Prolog,Swi Prolog For Sharing,我不熟悉prolog。我想编写compare_list/2,它将比较两个列表,如果它们至少有一个公共元素,则返回true。我知道这样的事情可以做到 common_list([H|_],T) :- member(H,T). common_list([_|T],L) :- common_list(T,L). common_list2(L1,L2) :- member(X,L1),member(X,L2). 但是我想在不使用Prolog内置谓词的情况下实现它。我试着写这个 common_eleme

我不熟悉prolog。我想编写compare_list/2,它将比较两个列表,如果它们至少有一个公共元素,则返回true。我知道这样的事情可以做到

common_list([H|_],T) :- member(H,T).
common_list([_|T],L) :- common_list(T,L).

common_list2(L1,L2) :- member(X,L1),member(X,L2).
但是我想在不使用Prolog内置谓词的情况下实现它。我试着写这个

common_elements([H|_],[H|_]).
common_elements(L,[_|T]) :- common_elements(L,T).
common_elements([_|T],L):-common_elements(T,L).


但是当我问在线swish prolog工具
公共元素([3,13,8,1],[5,3,7,3,1])。
它回答了37次正确的答案,而不是像公共列表/2和公共列表2/2那样的3(我必须使用cut只得到1而不是3,但这是另一回事)。

你可以自己很容易地编写成员函数

my_member(H, [H|_]).
my_member(X, [_|T]) :-
    my_member(X,T).


根据您的条件,当两个列表至少有一个公共元素时,如果它们没有公共元素,则返回
True
False

您所要做的就是检查第二个列表中是否存在列表的
Head
。如果第二个列表中存在
Head
,则返回True。否则,对第一个列表的尾部重复该过程的其余部分

我的方法如下:-

is_member(X,[X|_]):- !.
is_member(X,[_|T]):- is_member(X,T).

compare1([],[]):- false.
compare1([H|_],List):- is_member(H,List) , !.
compare1([H|T],List):- \+is_member(H,List) , compare1(T,List).
输出


希望这对您有所帮助。

您的第一个子句是不必要的,因为如果您省略它,Prolog将已经失败。您是对的!谢谢你的评论。我已经更正了代码。。。
?- compare1([3,4],[1,2,2]).
   false
?- compare1([1,2,3,4],[5,6]).
   false
?- compare1([1,2,3],[4,5,6,3]).
   true
?- compare1([1,2,3],[]).
   false
?- compare1([],[]).
   false
?- compare1([],[1,2,3]).
   false