Math Prolog中的射程积

Math Prolog中的射程积,math,prolog,failure-slice,Math,Prolog,Failure Slice,我需要编写一个程序,计算范围内产品的产品: 我编写了以下代码: 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

我需要编写一个程序,计算范围内产品的产品:

我编写了以下代码:

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

全局堆栈外意味着您进入了一个太长的递归链,可能是无限的

问题源于在作业中使用
=
而不是
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中的调试器),请尝试打开并运行“跟踪”和“调试”。您很快就会意识到,执行
N1=Nt+1
Nt
赋予为2会产生术语
2+1
。由于
2+1+1+1+(…)
永远不会与10统一,这就是问题所在。

您的程序永远不会终止!要看到这一点,请考虑下面的程序:

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. mult(N,N,R,R):-错。 mult(N、Nt、R、Rt):- N1=Nt+1, R1=Rt*(1/(对数(Nt)), mult(N,N1,R,R1),false。 这个新程序永远不会终止,因此原始程序不会终止。要看到这永远不会终止,请考虑两个<代码>(=)/2 目标。在第一种情况下,新变量
N1
与某物统一。这将永远成功。同样,第二个目标总是成功的。在递归目标之前,永远不会有失败的可能性。因此,这个程序永远不会终止

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


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

这显然是不够的,您的程序也会循环!是吗?我正在运行它,得到的答案是R=0.03694679293917323<代码>9?-mult(10,2,R,1)。
R=0.03694679293917323。
请尝试:
?-mult(10,2,R,1),R=1
应该失败,但它会按照您的定义循环。嗯,它在这里工作(正确地失败)。你是用第一个子句中的cut来运行它吗?然后你有了一些其他的定义!在上面,两个
(is)/2
目标都不会失败,因此您总是有一个循环<代码>a(5)从未终止,它再次错过了一个目标,如
N>=0
或类似的目标。哦,好的,我现在得到了。答案的越界开始永远不会终止。@vmg:如果您声称您的定义终止,您肯定还没有理解这个问题,因为您的定义可能会产生错误,但它永远不会终止…@vmg:您现在正在更改程序。但即使在这种情况下(切割),它并不总是终止!即使在这种情况下,
mult(10,2,1,1)
循环没有上面建议的
N>Nt这样的目标。削减不是解决办法。