4

私はプロローグでかなり錆びていますが、なぜこのようなことが失敗するのかわかりません:

frack(3).

frack(X) :- frack(X-1).

したがって、frack(4) を評価するとします。上記の事実が定義された対話型プロンプトから、4-1 = 3 であるため、無限に再帰する必要はないと思います。しかし、SWI-Prolog で次のエラーが発生します。

ERROR: Out of global stack
4

4 に答える 4

5

これが、この非終了の理由です。終了しないプログラムのがあるため、クエリは終了しません。

?- frack(4)。

frack(3) :- false。
フラック(X) :-
   frack(X-1), false .

これは、表示されている部分を変更することによってのみ修正できます。3 つの SO 回答は、 を使用することを提案しています(is)/2。しかし、これは非終了を削除しません! 実際、 を使用(is)/2すると、本質的に同じフラグメントにつながります。

?- frack(4)。

frack(3) :- false。
フラック(X) :-
   Y は X - 1、
   frack(Y), false .

少なくとも、frack(4)今は成功しますが、バックトラックでループします。X非終了を避けるために、のテストのように、目に見える部分で何かを変更する必要があります。詳細については、 を参照してください。

于 2012-11-15T12:05:16.420 に答える
5

それを試してみてください:

?- 4-1 = 3.
false.

なんで?なぜなら4-1 = -(4, 1)、これは明らかに数ではなく複合項だからです。

Prolog で整数について推論するには、たとえば (GNU Prolog または B-Prolog を使用して)

| | ?- 4-1 #= X.

X = 3

SWI-Prolog では、グラフィカル トレーサーが何が起こるかを確認するのに役立つ場合があります。

?- gtrace, frack(4).

より複雑なデバッグについては、 false's answerに示されているように、をお勧めします。

于 2012-02-10T14:36:47.793 に答える
3
frack(X) :- frack(X-1).

する必要があります

frack(X) :- Y is X - 1, frack(Y).

あなたがそれを書いた方法X-1では、最初のレベルの表現は次のレベルの変数と統合され、事実Xに決して行きません。frack(3)

于 2012-02-10T14:33:02.007 に答える
2

is演算子を使用しない限り、Prologは算術演算を行いません。

frack(X) :- X1 is X-1, frack(X1).
于 2012-02-10T14:33:01.260 に答える