两个重复列表之间的交集

时间:2014-02-03 17:03:21

标签: prolog

重复列表由元素(element,number_of_occurrences)组成。对于这样的两个元素列表找到交集。

我写了以下代码

min(X,Y,X):-X=<Y.
min(X,Y,Y):-X>Y.

search([X,Y],[[X,W]|_],[X,Z]):-min(Y,W,Z).
search([X,Z],[[_,_]|T],Answer):-search([X,Z],T,Answer).

intersection([],_,[]).
intersection([[H,O]|T],L2,[Z|Temp]):-
         member([H,_],L2),
         search([H,O],L2,Z),
         intersection(T,L2,Temp).
intersection([H|T],L2,Temp):-
         \+member(H,L2),
          intersection(T,L2,Temp).

当我在此测试时:交叉点([[1,2],[2,2],[5,5]],[[1,1],[2,3],[4,5] ],一个)。 它给出A = [[1,1],[2,2]],A = [[1,1]]和A = [[2,2]] A = [] 我只想要第一个答案,我该怎么做?我的代码出了什么问题?

1 个答案:

答案 0 :(得分:1)

我认为使用member/2后跟search/3会因回溯而创建子集解决方案。 search/3谓词已经成功或失败,取决于其设计的成员资格。因此,如果您重新调用intersection/3谓词,则可以消除冗余并强制执行完整解决方案。

您还可以删除min/3谓词,注意SWI Prolog支持min/2。您可以将min(Y, W, Z)替换为Z is min(Y, W),但只是意识到假设YW始终都是实例化的。

search([X,Y], [[X,W]|_], [X,Z]) :- Z is min(Y, W).
search([X,Z], [_|T], Answer) :- search([X,Z], T, Answer).

intersection([], _, []).
intersection([[H,O]|T], L2, R) :-
    (  search([H,O], L2, Z)
    -> R = [Z|Temp]
    ;  R = Temp
    ),
    intersection(T, L2, Temp).

?- intersection([[1,2],[2,2],[5,5]], [[1,1],[2,3],[4,5]], A).
A = [[1, 1], [2, 2]].

?-