2

我需要编写一个程序,计算范围内产品的乘积:在此处输入图像描述

我写了以下代码:

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 的默认库来实现循环?

4

2 回答 2

2

你的程序永远不会终止!要查看这一点,请考虑程序的以下故障片

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

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

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

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

于 2014-11-23T18:08:13.773 回答
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). 

你可能想在你的第一个子句中插入一个cut,以避免在得到答案后继续。

如果您有图形调试器(如 SWI 中的调试器),请尝试设置“跟踪”和“调试”并运行。您很快就会意识到,将N1 = Nt+1给予Nt作为 2 会产生术语2+1。既然2+1+1+1+(...)永远不会与 10 统一,那就是问题所在。

于 2014-11-23T18:02:30.003 回答