使用切我已經用下面的代碼來實現以下功能在序言:避免在序言絕對值謂詞
abs2(X, Y) :- X < 0, Y is -X.
abs2(X, X) :- X >= 0, !.
我怎樣才能實現這個功能,而無需使用切(「!」)的?
使用切我已經用下面的代碼來實現以下功能在序言:避免在序言絕對值謂詞
abs2(X, Y) :- X < 0, Y is -X.
abs2(X, X) :- X >= 0, !.
我怎樣才能實現這個功能,而無需使用切(「!」)的?
有 「隱藏」 切的Prolog的if-then-else結構:
abs2(X,Y) :- X < 0 -> Y is -X ; Y = X.
這是一個怪癖,但Prolog不會回溯到構成if-then或if-then-else構造的「前提」的子目標。在這裏,如果X < 0成功完成第一次嘗試,那麼在「else」子句之上的「then」子句的選擇將被提交(因此,將該行爲描述爲「隱藏」子事件)。
有謂詞寫在問題ABS2/2的第一子句中削減更多的作用。正如尼古拉斯指出的那樣,第二個條款結尾處的裁減沒有任何影響(當你到達那裏時沒有選擇點)。但正如卡雷爾指出的那樣,如果第一個條款成功,還有一個選擇點可以開放。
所以,我會寫,允許使用切割的,是這樣的:
abs2(X,X) :- X >= 0, !.
abs2(X,Y) :- Y is -X.
尼古拉斯的評論也暗示方法「arithmetize」絕對值(而不是使用一個邏輯的定義),並避免「削減」這種方式。
我的序言有點生疏,但爲什麼你甚至需要剪切?如果你寫正確的謂詞,回溯能不能成功,所以切是不必要的:
abs(X, Y) :- number(X) , X < 0 , Y is -X .
abs(X, X) :- number(X) , X >= 0 .
您的代碼仍然留下一個選擇點。這種選擇導致失敗,但仍然被考慮。剪切可以避免這種情況。 – Kaarel 2011-01-26 20:34:56
如果你知道你在處理積分值,你可以通過旋轉位來計算ABS的選擇點:http://www-graphics.stanford.edu/~seander/bithacks.html#IntegerAbs – 2011-01-26 20:56:07