2013-04-07 38 views
4

我學習Prolog的一個大學考試,我有這個練習的問題:實現一個Prolog謂詞,指出一個元素是否屬於一個列表。有沒有數值列表問題

Implement the predicate not_member(X,L) that is TRUE if the element X does not belong to the list L .

如果我的推論是正確的,我已經找到了解決辦法:

% FACT (BASE CASE): It is TRUE that X is not in the list if the list is empty. 
not_member(_,[]). 

% RULE (GENERAL CASE): If the list is non-empty, I can divide it in its Head 
% element and the sublist Tail. X does not belong to the list if it is different 
% from the current Head element and if it does not belong to the sublist Tail. 
not_member(X,[Head|Tail]) :- 
    X =\= Head, 
    not_member(X,Tail). 

這代碼與數字列表一起工作良好,如以下查詢所示:

2 ?- not_member(4, [1,2,3]). 
true. 

3 ?- not_member(1, [1,2,3]). 
false. 

但是,列表中包含一些非數字元素, 它不起作用並報告錯誤:

4 ?- not_member(a, [a,b,c]). 
ERROR: =\=/2: Arithmetic: `a/0' is not a function 

爲什麼?

回答

4

讓我們來檢查文檔!

(=\=)/2是一個算術運算符。

+Expr1 =\= +Expr2 True if expression Expr1 evaluates to a number non-equal to Expr2.

你必須使用(\=)/2比較兩個通用術語:

not_member(_, []) :- !. 

not_member(X, [Head|Tail]) :- 
    X \= Head, 
    not_member(X, Tail). 

和:

?- not_member(d, [a,b,c]). 
true. 
+0

好的,tnx這麼多。只有一點澄清:你爲什麼使用:not_member(_,[]): - !相反:not_member(_,[])。 究竟是什麼意思! ? Tnx – AndreaNobili 2013-04-07 17:24:38

+3

(不是一個詳細的解釋)這是一個切割。它可以防止回溯,但這不是強制性的。在這種情況下可以使用它,因爲一旦統一在not_member(_,[])上成功了。我們不需要檢查其他的「解決方案」,所以我們「切斷」序言搜索樹並停止計算。 – Haile 2013-04-07 17:32:22

2

使用得到邏輯的聲音回答 - 用於地面非地面情況!我們將non_member(E,Xs)定義爲maplist(dif(E),Xs)

讓我們把maplist(dif(E),Xs)not_member(E,Xs) by @Haile來測試!

 
?- not_member(E,[1,2,3]). 
false.         % wrong! What about `E=4`? 

?- maplist(dif(E),[1,2,3]). 
dif(E,1), dif(E,2), dif(E,3).   % success with pending goals 

它堅定嗎? (有關這一重要問題的詳細信息,請閱讀 thisthisthisthis答案。)

 
?- E=d, not_member(E,[a,b,c]). 
E = d. 
?-  not_member(E,[a,b,c]), E=d. 
false.         % not steadfast 

?- E=d, maplist(dif(E),[a,b,c]). 
E = d. 
?-  maplist(dif(E),[a,b,c]), E=d. % steadfast 
E = d. 

讓我們不要忘了最普遍的使用!

 
?- not_member(E,Xs).    
Xs = [].        % a lot of solutions are missing! 

?- maplist(dif(E),Xs). 
    Xs = [] 
; Xs = [_A]  , dif(E,_A) 
; Xs = [_A,_B] , dif(E,_A), dif(E,_B) 
; Xs = [_A,_B,_C], dif(E,_A), dif(E,_B), dif(E,_C) 
... 
相關問題