2013-07-04 34 views
1

嘿,我想追加兩個列表沒有 「雙重」 成員序言,追加無repititions

例如

A = [a, b, c] 
B = [x, c, q] 

然後 - >

append2(A,B,P) 

P= [a,b,c,x,q] 

我寫這篇文章代碼,但它不起作用...

not_member(_, []). 
not_member(X, [Y|Ys]) :- X \= Y, not_member(X, Ys). 

append2(A, [], A). 
append2([], A, A). 
append2([h1|ls], B, [h1|P]) :- not_member(h1, B), !, append2(ls, B, P). 
append2([h1|ls], B, P) :- member(h1, P), append2(ls, B, P). 

感謝您的幫助:)

+1

一個主要問題是您正在使用原子而不是變量。 'h1'是一個原子(不可變)。 H1將是一個變量(以大寫字母開頭)。你的'ls'也一樣。你需要'LS'或'Ls'。解決這個問題,並看看你有多遠。也不清楚爲什麼你必須定義'not_member'。在你的'append2'中,你可以使用'\ + member(...)'。至少,你可以定義'not_member(X,L): - \ + member(X,L).'。 – lurker

+0

嘿,我做了更改,否爲: append2([a,b,c],[c],P)。我得到了: P = [a,b,c]。 但對於更大的輸入,如: append2([a,b,c],[b,x,a,u],P)。 我得到了: 錯誤:超出全局堆棧 –

+0

這意味着你的代碼中有循環邏輯。看起來@gusbro給了你一個重寫。 – lurker

回答

1

假設有在你的輸入列表中沒有變量,但允許重複在每個列表中你可能會寫:

append2(A,B,C):- 
    findall(Item, append2_item(A,B,Item), C). 

append2_item(A,_,ItemA):- 
    append(HeadA, [ItemA|_], A), 
    \+ member(ItemA, HeadA). 
append2_item(A,B,ItemB):- 
    append(HeadB, [ItemB|_], B), 
    \+ member(ItemB, HeadB), 
    \+ member(ItemB, A). 

第一款第append2_item/3選擇(訂購)從第一個不同的項目名單。 append2_item/3的第二個子句從第二個列表中選擇不在第一個列表中的(排序)不同的項目。 append2/3只是收集這些元素。

測試用例:

?- append2([a,b,c,a],[x,c,q,x],C). 
C = [a, b, c, x, q]. 
+0

謝謝。但什麼「findall」呢? –

+1

@Kika:[findall/3](http://www.swi-prolog.org/pldoc/man?predicate=findall/3)從執行第二個參數的目標(回溯)中收集第一個參數(模板)測試所有解決方案)並將第三個參數與收集的模板列表相結合。 – gusbro

+0

ahhhh,不錯的一個。 謝謝:) –

1

查覈在my answer 到相關的問題 「intersection and union of 2 lists」 的代碼!

從您的需求告訴,謂語list_list_union/3只是你在找什麼:

?- list_list_union([a,b,c],[x,c,q],Ls). 
Ls = [a,b,c,x,q].        % succeeds deterministically 

list_list_union/3單調,所以我們得到使用非地面條件時聲音回答 連:

?- As = [_,_,_], Bs = [_,_,_], list_list_union(As,Bs,Ls), As = [a,b,c], Bs = [x,c,q]. 
As = [a,b,c], Bs = [x,c,q], Ls = [a,b,c,x,q] ; % logically sound result 
false.