为什么这个命令导致prolog中的堆栈溢出?

roo*_*kie 7 prolog failure-slice

我有以下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).
Run Code Online (Sandbox Code Playgroud)

有人可以解释为什么以下命令导致堆栈溢出?提前致谢.

fact(6).
Run Code Online (Sandbox Code Playgroud)

Rin*_*g Ø 2

首先,看规则

  num(0).
  num(X) :- num(X1), X is X1 + 1.
Run Code Online (Sandbox Code Playgroud)

该谓词num(Y)将立即对 有效Y = 0

因此规则

  fact(X) :- num(Y), fact(Y,X).
Run Code Online (Sandbox Code Playgroud)

可以简化为

  fact(X) :- fact(0,X).
Run Code Online (Sandbox Code Playgroud)

将会找到 的匹配项fact(0,1)。对于X = 6,发生的情况是,由于没有规则定义 的谓词fact(0,6),因此搜索从 开始fact(-1,V1),然后是fact(-2,V2)等等...直到出现匹配,其中fact(-value, Var)本地结果将是找到的 Var。

这是不可能发生的,无限循环会消耗整个堆栈,直到触发错误。

  • 也许你应该向菜鸟指出,你分析的问题可以通过在 **fact/2** 的第二个子句正文中添加 `X > 0` 来避免。 (3认同)