我假設你正在調用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會告訴我們沒有其他答案。
感謝您的編輯..它使得它更加清晰.. – Firefox