我有一个阶乘谓词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.
我有一个阶乘谓词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.
您可以尝试逐步完成您的程序以了解发生了什么。你确实会很慢,而且很不可靠。或者,您改为让 Prolog 完成(部分)工作。所以想法是稍微修改一下程序,然后看看 Prolog 是怎么想的。
这就是我在查看您的程序时看到的 - 这称为故障切片
事实(0,1):-假。 事实(N,F):- fact(N1,F1), false ,N 是 N1 + 1,F 是 N * F1。
该片段何时终止?看看剩下的可见部分!唯一在头脑中N
出现一次:没有人对第一个参数感兴趣!对于F
. 因此:无论您有什么参数,程序都不会终止。因此,您的原始程序也是如此!
在原始版本中并不清楚。小心:
?- fact(29,F).
F = 8841761993739701954543616000000
起初这看起来不错,但如果您要求下一个答案(使用 SPACE 或;
),您将在一个循环中结束。更糟糕的是,错误查询现在会立即循环:
?- fact(29,1).
** LOOPS **
那么,如果不准确了解发生了什么,你怎么能找到这些问题呢?这是false
为了什么。一个永远不真实的目标。如果您像这样添加它,您将永远不会被漂亮的答案分心。fact(29,F), false.
为什么你把所有的算术都放在最后?我怀疑是因为您之前遇到了一些错误。有一个简单的方法可以避免所有此类错误:
:- use_module(library(clpfd)).
你写而不是is
现在#=
,你需要一些限制,比如N #>= 1
. 我可以把你留在那里吗?