Prolog系列产品

时间:2014-11-23 17:40:06

标签: math prolog failure-slice

我需要编写一个程序,用于计算范围内的产品产品:enter image description here

我写了以下代码:

mult(N,N,R,R).
mult(N,Nt,R,Rt):-N1=Nt+1,R1=Rt*(1/(log(Nt))),mult(N,N1,R,R1).

这应该实现从NtN 1/ln(j)的基本产品。据我所知,当Nt和N相等时,它必须被停止。但是,由于以下原因,我无法使其正常工作:

?- mult(10,2,R,1), write(R).
ERROR: Out of global stack

以下错误。有没有其他方法可以实现循环而不使用SWI-Prolog的默认库?

2 个答案:

答案 0 :(得分:2)

你的程序永远不会终止!要查看此内容,请考虑以下failure-slice您的计划:

mult(N,N,R,R) :- false.
mult(N,Nt,R,Rt):-
   N1=Nt+1,
   R1=Rt*(1/(log(Nt))),
   mult(N,N1,R,R1), false.

这个新程序永远不会终止,因此原始程序不会终止。要看到这永远不会终止,请考虑两个(=)/2目标。在第一个中,新变量N1与某些东西统一起来。这将永远成功。同样,第二个目标始终成功。在递归目标之前永远不会有失败的可能性。因此,该程序永远不会终止。

您需要添加一些目标,或者替换现有目标。在可见部分。也许添加 N > Nt

此外,以(=)/2替换两个(is)/2目标可能是个好主意。但严格来说,这不是终止所必需的。

答案 1 :(得分:0)

超出全局堆栈意味着您输入了太长的递归链,可能是无限的。

问题源于在作业中使用=而不是is

mult(N,N,R,R).
mult(N,Nt,R,Rt):-N1 is Nt+1, R1 is Rt*(1/(log(Nt))), mult(N,N1,R,R1). 

您可能希望在第一个条款中插入一个剪切,以避免在得到答案后继续。

如果您有图形调试器(如SWI中的那个),请尝试设置'trace'和'debug'并运行。您很快就会意识到,N1 = Nt+1执行Nt作为2会产生2+1一词。由于2+1+1+1+(...)永远不会与10统一,这就是问题所在。