6

私は次のコードでプロローグに次の関数を実装しました:

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

カット( "!")を使用せずにこの関数を実装するにはどうすればよいですか?

4

3 に答える 3

10

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のコメントは、(論理定義を使用するのではなく)絶対値を「算術化」し、そのように「カット」することを回避する方法も提案しています。

于 2011-01-27T04:23:57.403 に答える
6

私のプロローグは少し錆びていますが、なぜカットが必要なのですか?述語を適切に記述した場合、バックトラックは成功しないため、カットは不要です。

abs(X, Y) :- number(X) , X <  0 , Y is -X .
abs(X, X) :- number(X) , X >= 0 .
于 2011-01-26T20:08:16.387 に答える
4

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

単に書く:

abs2(X,Y) :- Y is abs(X).
于 2015-05-26T07:14:07.180 に答える