なぜこのコマンドはPrologでスタックオーバーフローを引き起こすのですか?
-
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).
所属していません StackOverflow