2009-12-09 33 views
3

我需要一些幫助,我正在嘗試創建一個例程。我需要做一個常規的,將是這個樣子:Prolog差異例程

difference([(a,b),(a,c),(b,c),(d,e)],[(a,_)],X). 

X = [(b,c),(d,e)]. 

我真的需要在這一個幫助..

我寫了一個方法,到目前爲止,可以刪除第一次出現,它認爲。但是我需要它刪除所有的事件。以下是我迄今爲止...

memberOf(A, [A|_]). 
memberOf(A, [_|B]) :- 
    memberOf(A, B). 

mapdiff([], _, []) :- !. 
mapdiff([A|C], B, D) :- 
     memberOf(A, B), !, 
     mapdiff(C, B, D). 
mapdiff([A|B], C, [A|D]) :- 
     mapdiff(B, C, D). 

我採取這種代碼列表(減去)。

我不完全明白它的作用,但我知道它幾乎是我想要的。我沒有使用減法,因爲我的最終代碼必須與WIN-Prolog兼容......我正在SWI Prolog上測試它。

+0

您的代碼適用於我(在SWI-Prolog和GNU-Prolog中)。我不知道WIN-Prolog,所以我不能幫你。 – Stephan202 2009-12-09 18:52:25

+1

它的工作原理,但它並沒有消除所有的A的發生。它只消除了第一個。 – SteveW 2009-12-09 18:55:00

+1

你是對的。不知何故,我看起來錯了(?)。我認爲問題在於成員檢查執行統一,結果在第一次測試後'(a,_)'成爲'(a,b)',這將不再與'(a,c)'匹配。我正在考慮一個不錯的解決方案... – Stephan202 2009-12-09 19:06:43

回答

2

我不確定,但是像這樣的東西可以工作。您可以使用findall發現不能與模式統一所有元素:

?- findall(X, (member(X, [(a,b),(b,c),(a,c)]), X \= (a,_)), Res). 

得到的答覆

Res = [ (b, c) ] 

所以

removeAll(Pattern, List, Result) :- 
    findall(ZZ109, (member(ZZ109, List), ZZ109 \= Pattern), Result). 

應該工作,假設ZZ109 ISN」在Pattern中有一個變量(不幸的是,我不知道如何獲得一個新的變量,WIN-Prolog中可能有一個不可移植的變量)。然後difference可以遞歸定義:

difference(List, [], List). 
difference(List, [Pattern|Patterns], Result) :- 
    removeAll(Pattern, List, Result1), 
    difference(Result1, Patterns, Result). 
+2

ZZ109是一個新鮮的變量。在內部,Prolog更改變量的名稱。如果您在同一個子句中明確使用ZZ109,它只會是相同的變量。即:模式中的ZZ109可能在內部重命名爲_123,而差異子句中的ZZ109將重命名爲_314。沒有什麼可擔心的..雖然好的解決方案。 – neXus 2010-11-11 16:44:37

2

您的代碼可以輕鬆地修改以使其工作,以便memberOF謂詞只檢查到存在可以沒有統一列表中的某個元素實際上統一它。在SWI序言這是可以做到這樣:

memberOf(A, [B|_]) :- unifiable(A,B,_). 

但我不熟悉的WIN-PROLOG所以不知道它是否有一個謂語或操作員只測試是否論據是可以統一的。

3

棘手的一個! 不起眼的咖啡有正確的想法。這是一個使用雙重否定的奇特解決方案:

difference([], _, []). 
difference([E|Es], DL, Res) :- 
    \+ \+ member(E, DL), !, 
    difference(Es, DL, Res). 
difference([E|Es], DL, [E|Res]) :- 
    difference(Es, DL, Res). 

適用於SWI-PROLOG。說明:

第1條:基本情況。沒有任何差異!

第2條:如果E是在差異列表DL的member/2子目標的計算結果爲true,但我們不希望接受member/2使得目前的變量之間的條件任一列表綁定,因爲我們想例如,術語(a,_)中的變量可以在其他術語中重複使用,而不受第一種解決方案的約束。因此,根據需要,第一個\+刪除由成功評估member/2創建的可變綁定,第二個\+將評估狀態反轉爲true。剪切發生在檢查之後,不包括第三個子句,並丟棄可一致的元素。

第3條:讓任何元素在兩個列表中都不可統一。