2016-07-27 31 views
2

我试图找到一个列表的补集,给出一个列表L1和通用列表L2用下面的代码:/3似乎SETOF并没有被删除重复

complement(L1, L2, Res):- 
    setof(X, (nth0(N, L2, X), not(member(X,L1))),Res). 

然而,我结果包括重复并以列表形式都没有给我宁愿:

23 ?- complement([1,3], [-1,1,3,5,2,4,2,55,1,0], Res). 
Res = [-1] ; 
Res = [5] ; 
Res = [2] ; 
Res = [4] ; 
Res = [2] ; 
Res = [55] ; 
Res = [0]. 

我想这可能是由于Prolog的内建的回溯,但我不知道如何解决这对去格式化正确结果并使其去除结果中的任何重复项目。

回答

3

您从您的代码得到一个警告,约N是一个单身,和SETOF/3 要求每个变量“普遍量化”得到声明。 所以,你有走在一起的两个问题:更换会员/ 2 nth0/3:

complement(L1, L2, Res):- 
    setof(X, (member(X, L2), not(member(X, L1))), Res). 

编辑

对称的差异可能是

symdiff(L1,L2,Diff) :- 
    setof(X,(eldiff(L1,L2,X);eldiff(L2,L1,X)),Diff). 
eldiff(L1,L2,X) :- 
    member(X,L1), \+member(X,L2). 

如果L1和L2是有序集合,使用起来更好ord_symdiff

+0

修正了它。谢谢:) –

+0

有没有两种方法可以做到这一点,即不是补全,而是来自两者的元素,即对称差异,也使用setof/findall/bagof?我已经做了很长的路,但上述解决方案可以用来实现这一目标? – ildsarria

+0

@ildsarria:对不起,我不确定。可以从库(ordsets)中计算出对称差异 - IIRC - – CapelliC