检查两个列表是否具有公共元素

问题描述 投票:1回答:1

所以,基本上,我有一个称为common_elements(List1,List2)的谓词,该谓词的目的是检查List1是否至少具有属于List2的元素。

示例:

?- common_elements([1,2,3,4,5,6],[6]).
true.

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

?- common_elements([1,2,3],[6]).
false.

?- common_elements([P1,P2,P3,P4,P5,P6],[P7,P8,P6]).
true.

因此,对于数字来说,这很好用,但是如果我输入变量,它将统一变量,而不是检查它们是否在第二个列表中。

示例:

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

?- common_elements([1,2,3],[6]).
false.

?- common_elements([P1,P2,P3,P4,P5,P6],[P7,P8,P6]).
P1 = P7.

因此,您可以看到数字效果很好,但是由于某种原因,如果类型变量将它们统一起来,而不是仅仅比较它们而似乎不明白为什么。

程序:

common_elements(L1,L2) :- common_elements(L1,L2,[]).

common_elements([],_,AC) :- length(AC,C),
                            C >= 1.

common_elements([P|_],L2,AC) :- member(P,L2),!,
                                append(AC,[P],NAC),
                                common_elements([],L2,NAC).

common_elements([P|R],L2,AC) :- \+ member(P,L2),!,
                                common_elements(R,L2,AC).

list prolog swi-prolog
1个回答
0
投票

member/2谓词将执行统一。实际上,例如:

?- member(P1, [P2]).
P1 = P2.

您可以使用==/2避免统一,因此:

[如果==/2等于Term1,则为真。变量仅与共享变量相同

所以我们在这里可以做的是使用以下命令检查一个变量是否等效于另一个变量:

Term2

然后我们可以检查:

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

然后用以下命令回答查询:

common_elements([H|_], L2) :-
    membereq(H, L2).
common_elements([_|T], L2) :-
    common_elements(T, L2).
© www.soinside.com 2019 - 2024. All rights reserved.