2017-04-14 89 views
1

我寫了一個成員函數來檢查一個元素是否存在於一個列表中。成員函數給出奇怪的結果。

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

我將.pl文件加載到SWI prolog中,並且我沒有收到有關成員的警告或錯誤。我測試成員函數使用...

member(A, [1,2,3,4]). 

這,顯然應該返回false。相反,我得到

A = 1 

然後,當我試圖進入新的命令時,IDE只是表明我,我輸入的鑰匙,並說不明行動「什麼都鍵I按下」

我覺得我的成員函數聲音,因爲它與我的教授寫的相匹配。

任何想法?

+2

爲什麼'member(A,[1,2,3,4])*顯然返回false *?對於A = 1和A = 2,A = 3和A = 4,顯然應該是成功的。當它顯示「A = 1」時,如果有(根據Prolog文檔),您需要按SPACE或';'查看下一個結果。 – lurker

+1

可能性是,這個謂詞不是由你的教授寫的。 'member/2',這個實現,已經存在幾十年了,我想呢?我在1986年出版的死樹教科書中看到過它,但我猜它早於這本書。 – 2017-04-15 08:08:40

+0

@Boris:最近〜不到10年,'member/2'成了一個真正的內置。所以提供它的定義是很自然的。 – false

回答

0

您已在I/O模式(o,i) e.i.中調用了謂詞member/2。第一個參數免費(未綁定)變量,第二個是綁定變量。

在這種模式下(儘管它的名字)member/2其實並不對測試列表成員元素只是簡單列舉列表元素一個接一個,最後,當沒有元素被保留,它失敗(謂詞在失敗條款邏輯編程,而不是返回false)。

該斷言經常在所謂的故障驅動的控制技術使用,例如:

當枚舉列表元素被簡單地寫

?- forall(member(X, [1,2,3,4]), write(X)). 

注意,在這種情況下將不發生故障後

簡單的例子列表已用盡。 爲了確保這一點,添加了最後一個子句,這意味着「謂詞成功」。

p(List, Action) :- generator(Variant, List), side_effect_action(Variant), fail. 
p(_ , _). 

generator(X, L) :- member(X, L). 
+0

」member/2「的文檔通常很?)緩慢,參見例如[SWI-Prolog手冊](http://eu.swi-prolog.org/pldoc/doc_for?object=member/2):「True w母雞'Elem'是'List'的成員。「當Elem是一個變量時,「是一個成員」翻譯爲「與成員相結合」。我指出這一點只是爲了說明「member/2」的實現或文檔中沒有任何內容聲明它只是測試地面元素是否在地面列表中。 – 2017-04-15 09:06:55

+0

同意。我只是(由我的個人經驗)指出,由於它的典型用法(X是X的成員),成員/ 2可能會被忽視。 –

+0

通常情況下,如果您想測試地面列表中的地面元素的成員資格,您可以使用「memberchk/2」,因爲它更高效並且不會有選擇點。 **不能被** memberchk/2替換的'member/2'的所有用法涉及**不是**的第一個參數;例如'? - member(a(X),[a(1),b(2),a(3)])''。 – 2017-04-15 09:50:56