Prolog:全局堆栈出错,在我看来是一级递归



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

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

所以,如果我评估frack(4)。从定义了上述事实的交互式提示中,我预计它不应该无休止地重复出现,因为4-1=3。但我在SWI Prolog中得到了这个错误:

ERROR: Out of global stack

试试看:

?- 4-1 = 3.
false.

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

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

|?-4-1#=X。X=3

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

?- gtrace, frack(4).

对于更复杂的调试,我建议失败切片,如false中所示;答复

以下是未终止的原因。您的查询不会终止,因为您的程序中有一个失败部分没有终止:

?-压裂(4)。 frack(3):-false。压裂(X):-frack(X-1),false

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

?-压裂(4)。 frack(3):-false。压裂(X):-Y是X-1,frack(Y),false

至少,frack(4)现在成功了,但它将在回溯时循环。为了避免不终止,您必须更改可见部分中的某些内容,例如X的一些测试。有关详细信息,请参阅故障切片。

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

应该是

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

按照您的编写方式,第一级X-1表达式将与下一级的X变量统一在一起,而不会采用frack(3)事实。

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

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

最新更新