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

时间:2016-07-27 10:20:17

标签: prolog prolog-setof

我试图找到列表的补充,给定列表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的内置回溯,但我不知道如何解决这个问题,以便正确地格式化结果并让它删除结果中的任何重复项。

1 个答案:

答案 0 :(得分:3)

您的代码会收到警告,关于N是单身人士,而setof / 3 需要每个变量'普遍量化'得到宣布。 所以,你有两个问题一起消失:用member / 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