为什么这个命令在prolog中导致堆栈溢出?
我有以下prolog代码片段:
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)匹配fact(0,1) 。 对于X = 6 ,反而会发生什么,因为没有规则定义fact(0,6)的谓词,因此搜索以fact(-1,V1) ,然后是fact(-2,V2)等。直到匹配发生了一个fact(-value, Var) ,其中本地结果将是Var找到的。
这不会发生,并且无限循环会消耗整个堆栈,直到触发错误。
fact(6)不终止的原因可以在以下失败片段中找到:
?- fact(6). num(0) :- false. num(X) :- num(X1), false, X is X1 + 1. fact(X) :- num(Y), false, fact(Y,X).
因为这个片段不会终止,所以你的原始程序也不会终止。 请注意,非终止与fact/2的定义无关! 充其量,你的程序可能会成功,但它永远不会(有限)失败。
考虑使用fact/2另一个定义,它也终止于fact(N, 6).
上一篇: Why does this command cause a stack overflow in prolog?
