私は次のコードでプロローグに次の関数を実装しました:
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の最初の節にはカットの役割がもっとあります。ニコラスが指摘しているように、2番目の節の終わりのカットは効果がありません(そこに着いたときに選択ポイントは残っていません)。しかし、カーレルが指摘しているように、最初の節が成功した場合、選択ポイントは開いたままになります。
だから私が書いたであろう、カットの使用を許可するものは、これです:
abs2(X,X) :- X >= 0, !.
abs2(X,Y) :- Y is -X.
Nicholasのコメントは、(論理定義を使用するのではなく)絶対値を「算術化」し、そのように「カット」することを回避する方法も提案しています。
私のプロローグは少し錆びていますが、なぜカットが必要なのですか?述語を適切に記述した場合、バックトラックは成功しないため、カットは不要です。
abs(X, Y) :- number(X) , X < 0 , Y is -X .
abs(X, X) :- number(X) , X >= 0 .