2010-06-08 71 views

回答

16

優雅的系統提供false/0作爲命令fail/0的聲明性同義詞。它是非常有用的一個例子是,當你手動要強制回溯的副作用,如:

?- between(1,3,N), format("line ~w\n", [N]), false. 
line 1 
line 2 
line 3 

相反的false/0,你也可以用失敗的任何目標,例如短一點:

?- between(1,3,N), format("line ~w\n", [N]), 0=1. 
line 1 
line 2 
line 3 

因此,false/0不是嚴格需要,但相當不錯。

編輯:我有時會看到誰想要狀態。例如初學者「我關係爲空表不成立」,然後添加:

my_relation([]) :- false.

到他們的代碼。這是必需的而不是,而不是使用false/0的一個很好的示例,例外情況是以編程方式生成的失敗片。相反,請專心說明對你的關係持有的事情。在這種情況下,就離開了整個條款,並定義之間的關係僅是不是空的,即名單,至少有一個元素:

my_relation([L|Ls]) :- etc.

,或者,如果你所描述除了其他方面以列表以及使用像一個約束:

my_relation(T) :- dif(T, []), etc.

鑑於只有這兩個條款的任一個(或兩個都有),查詢?- my_relation([]).將自動失效。沒有必要引入一個額外的條款,爲此目的從來沒有成功。

+0

s /優雅/優雅和符合/ – false 2016-03-31 13:44:32

2

一種情況(從Constraint Logic Programming using Eclipse採取)是不/ 1的實施方式:(!)

:- op(900, fy, not). 
not Q :- Q, !, fail. 
not _ . 

如果Q成功,則切口使第二不子句被丟棄,和故障確保負結果。如果Q失敗,則第二個非子句首先觸發。

1

另一個用途的失敗是強制使用帶有副作用的謂詞時通過替代回溯:

writeall(X) :- member(A,X), write(A), fail. 
writeall(_). 

有些人可能不考慮,雖然這個特別良好的編程風格。 :)

+0

糟糕,看起來像席子打我。 – hdan 2010-06-09 22:05:16

7

顯式失敗。fail通常與cut一起使用:... !, fail.強制執行失敗。

對於所有結構。明確使用fail/false來枚舉通過回溯是一個非常容易出錯的行爲。考慮一個案例:

... (generator(X), action(X), fail ; true), ... 

這個想法是因此爲所有的「做」行動X。但是,如果action(X)失敗會發生什麼?這個結構只是繼續與下一個候選人—,就好像什麼都沒發生一樣。以這種方式,某些錯誤可能會很長時間未被發現。

對於這種情況下,最好使用\+ (generator(X), \+ action(X))失敗,應該action(X)失敗的一些X。有些系統將此作爲內置forall/2提供。就個人而言,我更喜歡在這種情況下使用\+,因爲\+更清楚一點,即構造不會留下綁定。

失敗切片。出於診斷目的,將false添加到您的程序中通常很有用。有關更多詳細信息,請參見