我对序言很生疏,但我不确定为什么这样的事情会失败:
frack(3).
frack(X) :- frack(X-1).
所以,如果我评估 frack(4)。从定义了上述事实的交互式提示中,我希望它不必无休止地递归,因为 4-1 = 3。但是我在 SWI-Prolog 中收到此错误:
ERROR: Out of global stack
我对序言很生疏,但我不确定为什么这样的事情会失败:
frack(3).
frack(X) :- frack(X-1).
所以,如果我评估 frack(4)。从定义了上述事实的交互式提示中,我希望它不必无休止地递归,因为 4-1 = 3。但是我在 SWI-Prolog 中收到此错误:
ERROR: Out of global stack
这是不终止的原因。您的查询不会终止,因为您的程序有一个失败片没有终止:
?- 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
,以避免未终止。有关更多信息,请参见故障切片。
frack(X) :- frack(X-1).
应该
frack(X) :- Y is X - 1, frack(Y).
您编写它的方式,X-1
第一级的表达式与下一级的变量统一X
,从不追求frack(3)
事实。
除非您使用 is 运算符,否则 Prolog 不会进行算术运算:
frack(X) :- X1 is X-1, frack(X1).