Prolog阶乘谓词

zai*_*aig 3 prolog factorial failure-slice

我有一个阶乘谓词fact(N,F),其中任NF或两者是有界的数字。

例如,我可以拥有fact(3,F)fact(N,6)。这是我的谓词,该谓词有效,但我不太了解如何做。我曾经使用过,trace但在理解上仍然有困难。

fact(0,1).
fact(N,F) :-
        fact(N1,F1),
        N is N1 + 1,
        F is N * F1.
Run Code Online (Sandbox Code Playgroud)

fal*_*lse 5

您可以尝试逐步完成程序,以了解发生了什么。实际上,您将非常缓慢,并且非常不可靠。或者,您改为让Prolog做(部分)工作。因此,想法是稍微修改程序,然后查看Prolog对它的看法。

这是我查看您的程序时所看到的-这称为

其实(0,1): - 。
事实(N,F):-
        fact(N1,F1),falseN是N1 +1F是N * F1

该片段何时终止?看剩下的可见部分!该N只发生一次在头:无人问津的第一个参数!相同F。因此:无论您拥有什么参数,程序都不会终止。因此,您的原始程序也是如此!

在原始版本中不清楚。小心:

?- fact(29,F).
F = 8841761993739701954543616000000 
Run Code Online (Sandbox Code Playgroud)

最初看起来不错,但是如果您要求下一个答案(使用SPACE或;),则将以循环结尾。更糟糕的是,错误查询现在立即循环:

?- fact(29,1).
** LOOPS **
Run Code Online (Sandbox Code Playgroud)

那么,如何在不确切了解发生了什么情况的情况下找到这些问题呢?这false是为了什么。一个永远不可能实现的目标。如果您像添加它一样,您将永远不会被漂亮的答案所困扰。fact(29,F), false.

你为什么把所有的算术都放在最后?我怀疑是因为您之前有一些错误。有一个简单的方法可以避免所有这些错误:

:- use_module(library(clpfd)).
Run Code Online (Sandbox Code Playgroud)

is现在写而不是现在#=,并且需要一些限制N #>= 1。我可以把你留在那里吗?