でのカットの使用を回避私は次のコードでプロローグに以下の機能を実装しました:Prologの絶対値述語
abs2(X, Y) :- X < 0, Y is -X.
abs2(X, X) :- X >= 0, !.
どのように私は(「!」)カットを使用せずにこの機能を実装することができますか?
でのカットの使用を回避私は次のコードでプロローグに以下の機能を実装しました:Prologの絶対値述語
abs2(X, Y) :- X < 0, Y is -X.
abs2(X, X) :- X >= 0, !.
どのように私は(「!」)カットを使用せずにこの機能を実装することができますか?
はプロローグのされた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」(というよりもロジックの定義を使用)する方法を提案し、避けますそのように "カット"。
私のプロローグはちょっと錆びますが、なぜカットも必要ですか?
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 .
をあなたのコードはまだ選択肢ポイントを残します。この選択は失敗につながりますが、それでも考慮されます。切れ目はそれを避けるでしょう。 – Kaarel
積分値を扱っていることがわかっている場合は、選択ポイントを使ってビットを並べ替えることでABSを計算することができます:http://www-graphics.stanford.edu/~seander/bithacks.html#IntegerAbs –
もう一つの選択肢はこれです: 'abs(X、Y): - Yはsign(X)* Xです.'(あなたのプロローグの実装が組み込みのsign/1述語をサポートしていると仮定します)。 –
「隠しカット」という名前のものはカットのようには動作しません:!/ 0は代替句の試行を防ぎますが、 if-then-elseはコミットしません。したがって私はこの貧弱な用語を見つける。 – mat
@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