setof/3 似乎没有删除重复项

setof/3 does not seem to be removing duplicates

我正在尝试使用以下代码找到列表的补集,给定列表 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 的内置回溯,但我不确定如何解决这个问题以正确格式化结果并让它删除结果中的任何重复项。

您的代码收到警告,关于 N 是单例,并且 setof/3 要求 声明每个变量 'universally quantified' . 所以,你有两个一起消失的问题:将 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