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)
试试吧:
?- 4-1 = 3.
false.
Run Code Online (Sandbox Code Playgroud)
为什么?因为4-1 = -(4, 1),这显然不是数字而是复合词.
要推理Prolog中的整数,请使用clpfd约束,例如(使用GNU Prolog或B-Prolog):
| ?- 4-1 #= X. X = 3
在SWI-Prolog中,图形跟踪器可能对您有用,可以查看发生的情况:
?- gtrace, frack(4).
Run Code Online (Sandbox Code Playgroud)
对于更复杂的调试,我建议使用false -slice,如false的答案所示.
这是不终止的原因.您的查询不会终止,因为您的程序的故障片段不会终止:
?- 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,以避免不终止.请参阅failure-slice了解更多信息.