4

我对序言很生疏,但我不确定为什么这样的事情会失败:

frack(3).

frack(X) :- frack(X-1).

所以,如果我评估 frack(4)。从定义了上述事实的交互式提示中,我希望它不必无休止地递归,因为 4-1 = 3。但是我在 SWI-Prolog 中收到此错误:

ERROR: Out of global stack
4

4 回答 4

5

尝试一下:

?- 4-1 = 3.
false.

为什么?因为4-1 = -(4, 1), 这显然不是一个数字,而是一个复合词。

要推理 Prolog 中的整数,请使用约束,例如(使用 GNU Prolog 或 B-Prolog):

| ?- 4-1 #= X。

X = 3

在 SWI-Prolog 中,图形跟踪器可能有助于您查看发生了什么:

?- gtrace, frack(4).

对于更复杂的调试,我建议使用false 的答案中所示的

于 2012-02-10T14:36:47.793 回答
5

这是不终止的原因。您的查询不会终止,因为您的程序有一个没有终止:

?- frack(4)。

frack(3) :-的。
水力压裂(X):-
   水力压裂(X-1),

您只能通过修改可见部分中的某些内容来解决此问题。三个 SO-answers 建议使用(is)/2. 但这不会消除不终止!事实上,使用(is)/2导致本质上相同的片段:

?- frack(4)。

frack(3) :-的。
水力压裂(X):-
   Y 是 X - 1,
   压裂(Y),

至少,frack(4)现在成功了,但它会循环回溯。您必须更改可见部分中的某些内容,例如对 的一些测试X,以避免未终止。有关更多信息,请参见

于 2012-11-15T12:05:16.420 回答
3
frack(X) :- frack(X-1).

应该

frack(X) :- Y is X - 1, frack(Y).

您编写它的方式,X-1第一级的表达式与下一级的变量统一X,从不追求frack(3)事实。

于 2012-02-10T14:33:02.007 回答
2

除非您使用 is 运算符,否则 Prolog 不会进行算术运算:

frack(X) :- X1 is X-1, frack(X1).
于 2012-02-10T14:33:01.260 回答