2017-03-15 81 views
1

我正在學習使用SWI Prolog,並且正在學習使用列表。一個小練習是檢查元素是否在列表中。下面是我的了:序言:具有真值和假值

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

第一種情況都按預期:

?- member(a,[b,a]). 
true. 

但第二次卻並不像有些回溯似乎出現:

?- member(a,[a,b]). 
true ; 
false. 

我怎麼可能防止這種情況發生,即讓Prolog只返回我true? (我不想忽視錯誤。)

+1

第一個'true'意味着它成功。 '假'意味着當你用''找到更多的解決方案時,它不會再找到解決方案,所以它在那個時候又回來了'假'。正常的Prolog行爲。另外,'member/2'是一個標準的Prolog謂詞。你應該把你的名字命名爲別的。標準謂詞具有與您顯示的行爲相同的行爲。 – lurker

回答

4

member/2是一個標準的Prolog謂詞。你應該把你的名字命名爲別的。標準謂詞具有與您顯示的行爲相同的行爲。

當您查詢:

?- member(a, [a,b]). 
true ; 
false. 

序言發現a第一元素相匹配和成功。列表中還有更多內容需要檢查,以便提示您提供更多信息。按;說:「是的,請檢查更多」。當它發生時,它找不到更多的a成員,然後得到false(在GNU Prolog中,它會說no)。

你可以把它通過任一走開:

  • 不按;但按回車鍵來替代,或者
  • 使用once/1once(member(a, [a,b])),或
  • 你可以改變你的斷言,包括已切斷第一個條款,但這是一個壞主意,因爲它在一般情況下不起作用:member(X, [a,b])將只返回X = a,然後停止。
0

注意,任何的查詢將與這兩個條款統一,因爲member(X,[X|_])member(X,[_|T])結合。你需要互斥條款。由於序言削減將打破可逆性(如前所述),還有另一種選擇:

member(X,[X|_]). 
member(X,[Y|T]):- X \== Y, member[X|T]. 
+1

這裏有一個好主意,但是你需要'dif/2'來替代'(==)/ 2'!和一些括號等 – false

0

對方回答是好的,但也許它補充說,member/2與正是這個實現教科書是重要的,因爲它使用模式配套配件和統一它可以做更有趣的事情......

?- member(a(X), [a(1), b(2), c(3), a(4), b(5), a(6)]). 
X = 1 ; 
X = 4 ; 
X = 6. 

還有memberchk/2是用於測試僅成員。另一個答案也解釋瞭如何實現。

看起來這兩個目的不一樣(爲什麼使兩者都不相同?)

3

使用memberd/2基於library(reif)可用於SICStus | SWI,你在許多情況下獲得確定性:

?- memberd(a, [a,b]). 
true. 

?- memberd(a, [a,a]). 
true. 

?- memberd(a, [a,X]). 
true. 

?- memberd(a, [a|Xs]). 
true. 

比較這對member/2

?- member(a, [a,b]). 
    true 
; false.    % leftover choicepoint 

?- member(a, [a,a]). 
    true 
; true.    % redundant solution 

?- member(a, [a,X]). 
    true 
; X = a.    % redundant solution 

?- member(a, [a|Xs]). 
    true 
; Xs = [a|_A]   % redundant answer 
; Xs = [_A, a|_B]  % redundant answer 
; Xs = [_A, _B, a|_C] % redundant answer 
... 

而且仍然memberd/2實施產生不同的答案,必要時

?- memberd(a, [X,Y]). 
    X = a 
; Y = a, 
    dif(X, a) 
; false. 

即使在這種情況下,memberd/2避免了冗餘member/2

?- member(a, [X,Y]). 
    X = a 
; Y = a.  % partially redundant 

這兩個答案是部分多餘的:X = a, Y = a由兩者描述!

?- member(a, [X,Y]), X = a, Y = a. 
    X = Y, Y = a 
; X = Y, Y = a. % redundant solution