3

我有一个阶乘谓词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.
4

1 回答 1

5

您可以尝试逐步完成您的程序以了解发生了什么。你确实会很慢,而且很不可靠。或者,您改为让 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. 我可以把你留在那里吗?

于 2017-02-21T15:30:25.437 回答