2011-01-26 24 views
5

でのカットの使用を回避私は次のコードでプロローグに以下の機能を実装しました:Prologの絶対値述語

abs2(X, Y) :- X < 0, Y is -X. 
abs2(X, X) :- X >= 0, !. 

どのように私は(「!」)カットを使用せずにこの機能を実装することができますか?

答えて

8

はプロローグのされたif-then-else構文で「非表示」のカットがあります:あなたが適切に述語を記述する場合、カットが不要であるので、バックトラックは、成功することはできませんこれは変わったものですが、もしPrologがif-thenやif-then-else構造の「前提」を構成する副目標に逆戻りすることはありません。ここで、X < 0が最初の試行に成功すると、 "else"節よりも "then"節の選択が確定する(したがって、この動作を「隠し」として記述する)。

質問に書かれた述語ABS2/2最初句のカットの役割の多くのがあります。ニコラスが指摘しているように、2番目の節の終わりにあるカットは効果がありません(そこに着くときに選択肢が残っていません)。しかしKaarelが指摘しているように、最初の句が成功すると、選択肢が残っています。

ので、カットの使用を可能に私が書かれているだろうが、これです:

abs2(X,X) :- X >= 0, !. 
abs2(X,Y) :- Y is -X. 

ニコラスのコメントも絶対値を「arithmetize」(というよりもロジックの定義を使用)する方法を提案し、避けますそのように "カット"。

+1

「隠しカット」という名前のものはカットのようには動作しません:!/ 0は代替句の試行を防ぎますが、 if-then-elseはコミットしません。したがって私はこの貧弱な用語を見つける。 – mat

+2

@mat:私はより良い用語を学ぶのがうれしいです。私はカットの(明らかな)使用を避けて私の解決策を提供することで「隠されたカット」を書いたので、読者は自分の解決策が有効かどうかを判断することができます。 "if-then-else"のローカライズされたコミット/カットの説明については、SWI-PrologのControl Predicates(2.4.7項)のドキュメントを比較してください。 http://www.swi-prolog.org/pldoc/doc_for?object=section%282,%274.7%27,swi%28%27/doc/Manual/control.html%27%29%29 – hardmath

5

私のプロローグはちょっと錆びますが、なぜカットも必要ですか?

abs2(X,Y) :- X < 0 -> Y is -X ; Y = X. 

abs(X, Y) :- number(X) , X < 0 , Y is -X . 
abs(X, X) :- number(X) , X >= 0 . 
+4

をあなたのコードはまだ選択肢ポイントを残します。この選択は失敗につながりますが、それでも考慮されます。切れ目はそれを避けるでしょう。 – Kaarel

+3

積分値を扱っていることがわかっている場合は、選択ポイントを使ってビットを並べ替えることでABSを計算することができます:http://www-graphics.stanford.edu/~seander/bithacks.html#IntegerAbs –

+6

もう一つの選択肢はこれです: 'abs(X、Y): - Yはsign(X)* Xです.'(あなたのプロローグの実装が組み込みのsign/1述語をサポートしていると仮定します)。 –

3

を使用する必要はありません!

単に書く:

abs2(X,Y) :- Y is abs(X).