7

私は次のプロローグコードのスニペットを持っています:

num(0).
num(X) :- num(X1), X is X1 + 1.

fact(0,1) :-!.
fact(X,Y) :- X1 is X-1, fact(X1,Y1), !, Y is Y1 * X.

fact(X) :- num(Y), fact(Y,X).

次のコマンドがスタックオーバーフローを引き起こす理由を誰かが説明できますか?前もって感謝します。

fact(6).
4

2 に答える 2

2

まずはルールを確認

  num(0).
  num(X) :- num(X1), X is X1 + 1.

述語num(Y)は に対してすぐに有効になりY = 0ます。

したがって、ルール

  fact(X) :- num(Y), fact(Y,X).

次のように簡略化できます

  fact(X) :- fact(0,X).

の一致が見つかりますfact(0,1)。の場合X = 6、代わりに起こることは、 の述語を定義するルールがないためfact(0,6)、 で検索が開始されfact(-1,V1)、その後にetc が続きます...ローカル結果が見つかった Var であるfact(-2,V2)a に一致するまで。fact(-value, Var)

これは発生せず、エラーがトリガーされるまで無限ループがスタック全体を消費します。

于 2011-01-29T11:48:41.407 に答える
2

fact(6)が終了しない理由は、次のあります。

?-事実(6)。

num(0) :- false。
数値(X) :-
   num(X1), false ,
    X は X1 + 1 .

事実(X) :-
   num(Y), false ,
    fact(Y,X) .

このフラグメントは終了しないため、元のプログラムも終了しません。非終了はfact/2!の定義とは無関係であることに注意してください。せいぜい、あなたのプログラムは成功するかもしれませんが、(限りなく) 失敗することはありません。

の別の定義fact/2を使用することを検討してください。fact(N, 6).

于 2012-11-15T11:47:55.480 に答える