zai*_*aig 3 prolog factorial failure-slice
我有一个阶乘谓词fact(N,F)
,其中任N
或F
或两者是有界的数字。
例如,我可以拥有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)
您可以尝试逐步完成程序,以了解发生了什么。实际上,您将非常缓慢,并且非常不可靠。或者,您改为让Prolog做(部分)工作。因此,想法是稍微修改程序,然后查看Prolog对它的看法。
这是我查看您的程序时所看到的-这称为故障切片
其实(0,1): - 假。 事实(N,F):- fact(N1,F1),false,N是N1 +1,F是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
。我可以把你留在那里吗?