2014-05-01 106 views
-2

有人可以幫助我將其轉換爲符合此更新的要求嗎?SWI-Prolog謂詞示例第2部分

定義謂詞strikeDuplicates(X,Y)其成功,當且僅列表Y將 被如果一個人從列表中刪除X每個元素 的第二和後續出現獲得。 (您可能讀strikeDuplicates (X,Y)列表X沒有重複 是列表Y)時X是 綁定變量strikeDuplicates/2謂詞不必工作。

我問過類似的問題,前兩天問這個:

定義謂詞strike(X,Y,Z)是成功的,當且僅當列表Z將獲得 如果一個人刪除元素X的所有出現從列表Y。當Y是未綁定變量時,謂詞不需要很好地工作。

沒有人幫助我,所以我必須自己做。這個問題的答案是這樣的:

strike(_ , [] , [] ) . 
strike(X , [X|T] , Z ) :-   strike(X,T,Z) . 
strike(X , [A|T] , [A|Z]) :- dif(X,A) , strike(X,T,Z) . 

dif(X,A). 
+2

你嘗試過什麼嗎? – Rubens

+1

你對輔助謂詞'dif/2'的定義是錯誤的。例如,'dif(1,1)'是真的。您可以通過調用標準術語相等謂詞'(\ ==)/ 2'來替換它。 –

回答

1

一個簡單的解決方案,不保留順序是:

strike_duplicates([], []). 
strike_duplicates([X| Xs], List) :- 
    ( member(X, Xs) -> 
     strike_duplicates(Xs, List) 
    ; List = [X| Tail], 
     strike_duplicates(Xs, Tail) 
    ). 

爲了維持秩序,你需要跟蹤到目前爲止,而你遍歷列表中找到的元素。一個解決辦法是:

strip_duplicates(List, Set) :- 
    strip_duplicates(List, [], Set). 

strip_duplicates([], _, []). 
strip_duplicates([X| Xs], Found, List) :- 
    ( member(X, Found) -> 
     strip_duplicates(Xs, Found, List) 
    ; List = [X| Tail], 
     strip_duplicates(Xs, [X| Found], Tail) 
    ). 

謂詞member/2通常要麼是一個內置的謂詞或可作爲一個庫謂語。如有必要,請檢查您的Prolog系統文檔。

+0

你可以使用我在問題中表達的變量和謂詞名稱嗎? – Shimori

+0

當你從'strip_duplicates/2'問到'strike_duplicates/2'時,我改變了謂詞名稱。在Prolog中,使用CamelCase作爲謂詞名稱被認爲是不好的編程風格。下劃線的使用有助於可讀性。 –

+0

謝謝,我猜規則謂詞不需要表達關於變量Y的任何內容嗎? – Shimori

1

好了,簡單的方法是使用內置的謂詞setof/3,但我懷疑這不是你的教授想要的東西。

考慮一兩秒鐘的問題。一個明顯的問題陳述往往是有幫助的(和Prolog是經常的解決方案本身):

爲了使信源列表中設置(獨特的元素),而不是(可重複),你」將不得不

  • 遍歷源列表中,您已經看到
  • 田徑項目(以下簡稱「訪問名單)
  • 每個項目添加到訪問列表只有在訪問列表不alread y包含它。

一旦你這樣做了,你已經得到了預期的結果。

這裏有一個提示:一個非常普遍的序言成語是利用幫手謂詞與它的累加器攜帶。通常助手謂詞具有相同的函數,但是不同的元數。例如,要總結在列表(sum/2),我們可以使用一個輔助sum/3攜帶的蓄電池,0種子值:

sum(Xs,N) :- sum(Xs,0,N). 

sum([],S,S). 
sum([N|Ns],T,S) :- 
    T1 is T+N, 
    sum(Ns,T1,S) 
    . 

你會發現如何unfication與結果推遲直到已計算最終價值。

你需要做一些類似的事情,但使用累加器[012]空白列表將用您發現的唯一值進行擴展。

另一個提示:內置謂詞member/2將檢查一個術語是否是列表的成員。這是寫

member(X,[X|Xs]). 
member(X,[_|Xs]) :- member(X,Xs). 

所以member(2,[1,2,3])truemember(2,[1,3])false

相反,人們可以使用member/2通過回溯到先後返回一個列表中的每個元素:member(X,[1,2,3])產生

X = 1 ; 
X = 2 ; 
X = 3 ; 
false 

鑑於這兩個概念,你應該能夠找出解決方案。回來向我們展示您的代碼,我們可以幫助您。還有一個小小的gotcha,但我相信你會弄明白的。

+0

最新的解決方案我有一個Paulo Moura提出了,但它沒有證明正確的,當我測試它與單元測試 – Shimori

+0

尼古拉斯,我刪除了我的過時的評論,並投票了你的答覆。 –