對Prolog謂詞控制有好奇心。Prolog中的謂詞控制
假設我有一個謂詞f(A,X)和g(B)。
f(A,X):- a,b,c, g(X).
g(B):- true.
a - returns true
b - returns true.
c - returns false.
where a,b and c are random predicates.
我怎麼能繼續在謂語f(A,X)
如果c返回false評估g(X)
?
對Prolog謂詞控制有好奇心。Prolog中的謂詞控制
假設我有一個謂詞f(A,X)和g(B)。
f(A,X):- a,b,c, g(X).
g(B):- true.
a - returns true
b - returns true.
c - returns false.
where a,b and c are random predicates.
我怎麼能繼續在謂語f(A,X)
如果c返回false評估g(X)
?
如果你的目的是要確定c
是否失敗,那麼f(A,X)
這樣g(X)
應評估兩種:
->
)和/或析取(;
),或f(A,X)
不需要根據c
來定義。假定c
沒有副作用(例如,使用assert
聲明數據庫事實,或者將IO打印到流中),這會改變環境並且在c
失敗時不能撤銷,在這種情況下,第一個選項是優選的。有幾個選擇使用脫節,如:
f(A,X) :- ((a, b, c) ; (a, b)), g(X).
這個定義(以上)不依賴於c
可言,但它總會執行c
(只要a
和b
成功)。該分離(;
)允許PROLOG回溯嘗試執行a, b
再次如果c
失敗,並繼續到g(X)
。請注意,這等同於:
f(A,X) :- a, b, c, g(X).
f(A,X) :- a, b, g(X).
爲了PROLOG不走回頭路評估f(A,X)
因爲第二(相同的)頭謂詞f(A,X)
的兩次每次評估,您可以選擇將切割(!
)如果您的實施支持它,之後立即在c
子目標的第一個子句中。因爲如果c
失敗,我們不希望口譯人員承諾選擇f(A,X)
條款,相反,我們希望解釋器失敗並嘗試下一個,以便有效地執行下一步忽略c
並繼續處理g(X)
。
另外請注意,此解決方案依賴於a
和b
沒有副作用,因爲當c
失敗,a
和b
再次執行。如果所有a
,b
,並c
有副作用,你可以嘗試使用寓意:
f(A,X) :- a, b, (c -> g(X) ; g(X)).
這也將有效地一直執行g(X)
是否c
失敗與否,並不會a
和b
再次執行,如果c
失敗。這個單子句定義也不會像以前的建議那樣留下選擇點。
我想你可以把c
換成ignore/1
。考慮例如
?- false, writeln('Hello World!').
false.
?- ignore(false), writeln('Hello World!').
Hello World!
true.
但是如果c
失敗,爲什麼要繼續?什麼是用例?
我在SWI-Prolog中測試了這段代碼,我不確定其他Prolog是否有false/0
和ignore/1
。 後者可以這樣雖然被定義爲:
ignore(Goal) :- Goal, !.
ignore(_).
+1問爲什麼這會有用。可移植故障謂詞是「失敗」,順便說一句。 (這是微不足道的實現:'失敗: - 0 = 1。) – 2010-11-09 09:21:29
一種情況下,如果'c'失敗,你可能想繼續是'c'具有_side-effects_;有關詳細信息,請參閱我對此問題的回答。 – sharky 2010-11-09 13:38:47