使用Prolog查找相交列表

时间:2014-03-20 05:23:13

标签: prolog intersection

我在尝试调试此代码时无法找到两个列表之间的交集......

例如: List1 = [3, 4, 5, 6]List2 = [5, 1, 0, 2, 4]

因此,相交的行将存储到List3 [4, 5]

所以这里是Prolog的代码。

任何帮助将不胜感激!!!

setIntersection([], [], []).
setIntersection([], _, []).

setIntersection([X|Xs], Y, [Z|W]) :-
    keepDuplicates(X, Y, [Z|Zs]),
    setIntersection(Xs, Y, W).

keepDuplicates(_, [], []).
keepDuplicates([], _, []).
keepDuplicates([], [], []).

% Check if the head of the first list is not a match to the
% first head of the second list
keepDuplicates(G, [H|Hs], Line) :-
    G \= H,
    keepDuplicates(G, Hs, Line).

% Check if the head of the first list
% Does match to the head of the second list
keepDuplicates(G, [G|Gs], [G|NewLine]) :-
    keepDuplicates(G, Gs, NewLine).

2 个答案:

答案 0 :(得分:2)

您可以在my answer中找到与相关问题“Intersection and union of 2 lists”相关的几个逻辑纯的,单调的列表交集和联合实现。

让我们看一个示例查询:

?- list_list_intersection([3,4,5,6],[5,1,0,2,4],Intersection).
Intersection = [4,5].             % succeeds deterministically

由于建议的实施方式是单调,您也可以通过更一般的方式使用它,并且仍能获得逻辑上合理的答案

?- L2 = [_,_,_], list_list_intersection([3,4,5,6],L2,[4,5]).
L2 = [ 4, 5,_A], dif(_A,6), dif(_A,3)                      ;
L2 = [ 4,_A, 5], dif(_A,6), dif(_A,5), dif(_A,3)           ;
L2 = [ 5, 4,_A], dif(_A,6), dif(_A,3)                      ;
L2 = [_A, 4, 5], dif(_A,6), dif(_A,5), dif(_A,4),dif(_A,3) ;
L2 = [ 5,_A, 4], dif(_A,6), dif(_A,4), dif(_A,3)           ;
L2 = [_A, 5, 4], dif(_A,6), dif(_A,5), dif(_A,4),dif(_A,3) ;
false.

答案 1 :(得分:1)

Prolog中的sets通常用排序列表表示,然后避免出现重复元素时出现的表示的歧义。我们忽略这个问题......

这个事实setIntersection([], [], []).setIntersection([], _, []). 包含,然后可以(应该!)被删除。 keepDuplicates([], [], []).也一样(为什么你在这里反转条款?)

你有一个单身Zs:...,keepDuplicates(X, Y, [Z|Zs]),...你应该注意那个警告(当然,如果你的编译器显示它),因为它经常是真正错误的症状。

此外,该谓词无法涵盖所有​​情况:当Y中的X 时,您与Z相关联的是什么?

说实话,我认为你做的比实际要复杂得多。忽略重复,整体可以很容易

?- L1=[3,4,5,6],L2=[5,1,0,2,4],findall(C, (member(C,L1),memberchk(C,L2)), I).