2

我试图找到一个列表的补集,给定一个列表 L1 和一个具有以下代码的通用列表 L2:

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 的内置回溯,但我不确定如何解决这个问题以正确格式化结果并让它删除结果中的任何重复项。

4

1 回答 1

3

您会从代码中收到关于N成为单例的警告,并且 setof/3要求声明每个变量“普遍量化”。因此,您有两个问题一起消失:将 nth0/3 替换为 member/2:

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

于 2016-07-27T10:44:14.010 回答