なぜこのコマンドはPrologでスタックオーバーフローを引き起こすのですか?

StackOverflow https://stackoverflow.com/questions/4836146

  •  27-10-2019
  •  | 
  •  

質問

プロログコードの次のスニペットがあります:

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).
役に立ちましたか?

解決

まず、ルールを見ています

  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), 、続いて fact(-2,V2) など... aに対して一致が発生するまで fact(-value, Var) 局所的な結果がVARが見つかる場所。

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

他のヒント

その理由 fact(6) 終了しないことは、以下にあります :

?- fact(6).

num(0): - 間違い.
num(X) :-
   num(X1), 間違い,
   xはx1 + 1です.

fact(X) :-
   num(Y), 間違い,
   事実(y、x).

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

使用することを検討してください の別の定義 fact/2, 、そのために終了します fact(N, 6).

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top