Prolog:错误的全局堆栈与看起来像一级递归给我

War*_* P 4 prolog failure-slice

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

frack(3).

frack(X) :- frack(X-1).
Run Code Online (Sandbox Code Playgroud)

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

ERROR: Out of global stack
Run Code Online (Sandbox Code Playgroud)

mat*_*mat 5

试试吧:

?- 4-1 = 3.
false.
Run Code Online (Sandbox Code Playgroud)

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

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

| ?- 4-1 #= X.

X = 3

在SWI-Prolog中,图形跟踪器可能对您有用,可以查看发生的情况:

?- gtrace, frack(4).
Run Code Online (Sandbox Code Playgroud)

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

  • 我不知道SWI有那个.太好了! (2认同)

fal*_*lse 5

这是不终止的原因.您的查询不会终止,因为您的程序的不会终止:

?- frack(4).

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

您只能通过修改可见部分中的内容来解决此问题.建议使用三个SO答案(is)/2.但这不会删除非终止!实际上,使用(is)/2导致基本相同的片段:

?- frack(4).

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

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