2016-07-27 58 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