2012-10-16 52 views
3
union([H|T],[],[H|T]).  
union([],[H|T],[H|T]).  
union([H|T], SET2, RESULT) :- member(H,SET2), union(T,SET2,RESULT).  
union([H|T], SET2, [H|RESULT]) :- not(member(H,SET2)), union(T,SET2,RESULT). 

我能夠理解,它是經過第一列表和添加基於元素是否是第二個名單或不是的成員。我明白了邏輯。但是,工作流對我來說很神祕,因爲一旦第一個列表用完,它會將「第二個列表」的元素添加到結果中。並集操作:解釋

請有人拿一個簡單的例子,如union([1,2], [2,3], Result),並解釋工作流程。

+0

感謝您的編輯..它使得它更加清晰.. – Firefox

回答

7

我假設你正在調用union/3的第一個和第二個參數實例化。第三個參數可以在調用時沒有實例化,並且在返回時與兩個列表的聯合統一,或者如果它已經實例化,它可以用來檢查它是否與前兩個列表的(有序)聯合相匹配。

第一個條款規定,如果第二個參數是空列表第一個列表至少有一個元素,那麼union就是這個第一個列表。 同樣,第二個條款規定,如果第一個參數是空列表第二個列表至少有一個元素,那麼union就是第二個列表。

第三個子句在第一個列表上遞歸併檢查第二個列表以查看該項目是否已經存在。在這種情況下,它只是用第一個列表的尾部調用自己。

第四個子句測試第一個列表的頭部,檢查它是否不包含在第二個列表中,並用尾部遞歸調用(就像第三個子句一樣)。然而,在遞歸返回時,它將該項目添加到第三個列表的頭部,從而將該項目添加到該聯合。

請注意,在您的實現中,兩個空集合的聯合將始終失敗。你可以通過修改第一個或第二個子句來解決這個問題,以允許一個空列表或者爲這種情況添加另一個子句。例如。

union([],[],[]). 

現在,讓我們看看會發生什麼,當我們要求union([1,2],[2,3], Result)

前兩個條款將無法匹配爲他們都不是空列表。

我們輸入第三個子句並檢查元素1是否不是第二個列表的成員,從而失敗。

我們現在嘗試第四條和測試元件1我不是在第二個列表,所以我們稱之爲union([2], [2,3], Result),我們紀念這個執行點(* 1)。

再次,兩個第一個子句將不匹配,所以我們輸入第三個子句。在這裏,我們測試確實元件2包含在第二列表,以便我們稱之爲union([], [2,3], Result),我們紀念這個執行點(* 2

現在第一款作爲第一個參數是空列表失敗。 我們現在輸入將第三個參數與第二個列表([2,3])統一的第二個子句。

在這一點上,我們返回(* 2),其中Result現在用[2,3]實例化。這個子句在那裏結束,所以我們用[1,2,3]來限定第三個參數,然後我們返回(* 1)。

我們現在在(* 1)其中Result和因此第三個參數用[1,2,3]實例化。

這給了我們第一個結果[1,2,3]。 (* 2),所以如果我們要求Prolog尋找另一個答案,它仍然必須嘗試聯合的第四個子句([2],[2,3] ],結果)。

因此,我們輸入第四個子句來測試2是否不是[2,3]中的成員,因此Prolog會告訴我們沒有其他答案。

+0

一流...閱讀'一次'就夠了..你當然是一位出色的老師。非常感謝:) – Firefox

1

您還沒有檢查SET2,從而假設有沒有它重複,則基本遞歸可以是單個謂詞

union([], U, U). 

@gusbro已經解釋的,當H不屬於SET2它是放置在結果的(本地)前面,遞歸調用成功。

該解釋應該清除您的疑問,但請注意,not/1基本上重複了之前(失敗)調用中已執行的相同測試。然後,更好的代碼可能是

union([H|T], SET2, RESULT) :- 
    member(H,SET2), !, % note the commit 
    union(T,SET2,RESULT).  
union([H|T], SET2, [H|RESULT]) :- 
    % useless now 
    % not(member(H,SET2)), 
    union(T,SET2,RESULT). 

這相當於你的代碼,假設member/2是無副作用(它是)。

not/1可以使用!/0來實現。

+0

感謝您的回覆..我想我理解你指出的這個技巧..這很有幫助,幫助我理解了'!'的用例。但是,有了這個檢查(至少已經註釋掉了)提高了可讀性。 – Firefox

1

my answer回答相關問題「Intersection and union of 2 lists」我提出了一個邏輯上純粹的交集和聯合實現。

與其他問題的答案不同,純粹的變體是單調的,因此在與非基礎條件一起使用時會保持邏輯合理。