我需要编写一个程序,用于计算范围内的产品产品:
我写了以下代码:
mult(N,N,R,R).
mult(N,Nt,R,Rt):-N1=Nt+1,R1=Rt*(1/(log(Nt))),mult(N,N1,R,R1).
这应该实现从Nt
到N
1/ln(j)
的基本产品。据我所知,当Nt和N相等时,它必须被停止。但是,由于以下原因,我无法使其正常工作:
?- mult(10,2,R,1), write(R).
ERROR: Out of global stack
以下错误。有没有其他方法可以实现循环而不使用SWI-Prolog的默认库?
答案 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统一,这就是问题所在。