Prolog 阶乘谓词
Prolog factorial predicate
我有一个阶乘谓词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是怎么想的。
这是我在查看您的程序时所看到的 - 这称为 failure-slice
fact(0,1) :- false.
fact(N,F) :-
fact(N1,F1), false,
N is N1 + 1,
F is N * F1.
这个片段什么时候结束?看看剩下的可见部分! N
只在头部出现一次:没有人对第一个参数感兴趣! F
也一样。因此:无论你有什么参数,程序都不会终止。 因此您的原始程序也是如此!
原版中不是很清楚。注意:
?- fact(29,F).
F = 8841761993739701954543616000000
起初这看起来不错,但如果你要求下一个答案(使用 SPACE 或 ;
),你将以循环结束。更糟糕的是,错误查询现在会立即循环:
?- fact(29,1).
** LOOPS **
那么,在不准确了解发生了什么的情况下,如何找到这些问题呢?这就是 false
的用途。一个永远不真实的目标。如果你添加它像 fact(29,F), <b>false</b>.
你永远不会被美丽的答案分心。
为什么你把所有的算术都放在最后?我怀疑是因为你之前有一些错误。有一个简单的方法可以避免所有此类错误:
:- use_module(library(clpfd)).
你现在写 is
而不是 #=
,你需要像 N #>= 1
这样的限制。我可以把你留在那里吗?
我有一个阶乘谓词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是怎么想的。
这是我在查看您的程序时所看到的 - 这称为 failure-slice
fact(0,1) :- false. fact(N,F) :- fact(N1,F1), false,N is N1 + 1,F is N * F1.
这个片段什么时候结束?看看剩下的可见部分! N
只在头部出现一次:没有人对第一个参数感兴趣! F
也一样。因此:无论你有什么参数,程序都不会终止。 因此您的原始程序也是如此!
原版中不是很清楚。注意:
?- fact(29,F).
F = 8841761993739701954543616000000
起初这看起来不错,但如果你要求下一个答案(使用 SPACE 或 ;
),你将以循环结束。更糟糕的是,错误查询现在会立即循环:
?- fact(29,1).
** LOOPS **
那么,在不准确了解发生了什么的情况下,如何找到这些问题呢?这就是 false
的用途。一个永远不真实的目标。如果你添加它像 fact(29,F), <b>false</b>.
你永远不会被美丽的答案分心。
为什么你把所有的算术都放在最后?我怀疑是因为你之前有一些错误。有一个简单的方法可以避免所有此类错误:
:- use_module(library(clpfd)).
你现在写 is
而不是 #=
,你需要像 N #>= 1
这样的限制。我可以把你留在那里吗?