multiply(A,0,0).
multiply(A,B,C) :- D is B-1, multiply(A,D,E), C is E+A.
使用此规则一次后,Prolog返回一个答案,如果我希望它继续搜索(提示A = 5?,然后单击;),则Prolog崩溃。我不明白为什么?任何人都可以解释。谢谢。
答案 0 :(得分:5)
问题是
multiply(A,B,C) :- D is B-1, multiply(A,D,E), C is E+A.
此代码没有约束B > 0
,该约束将防止发生堆栈溢出。
您可以将代码修改为
multiply(A,B,C) :- B > 0, D is B-1, multiply(A,D,E), C is E+A.
此外,此行multiply(A,0,0).
发出单例警告,因此您可以将其更改为multiply(_,0,0)
注意:我写了约束B > 0
,认为您将谓词称为multiply(5,1,A)
。
答案 1 :(得分:1)
以下是您可以轻松进行无限循环的方法:
?- [user].
|: loop(0).
|: loop(X) :- X0 is X - 1, loop(X0).
|: ^D% user://1 compiled 0.01 sec, 2 clauses
true.
?- loop(3).
true ;
重做后(按;
时)将返回到带有0的第二个子句。
然后X0
变为-1,进入递归loop(X0)
,从这里开始,第一个子句将不再匹配。
尝试例如查询:
?- loop(-1).
您的无限循环版本不是尾递归的,这意味着它最终将耗尽堆栈。这是一个最小的示例:
?- [user].
|: out_of_stack(0, 0).
|: out_of_stack(X, Y) :- X0 is X - 1, out_of_stack(X0, Y0), Y is Y0 + 1.
|: ^D% user://1 compiled 0.01 sec, 2 clauses
true.
?- out_of_stack(3, R).
R = 3 ;
ERROR: Stack limit (1.0Gb) exceeded
ERROR: Stack sizes: local: 1.0Gb, global: 19Kb, trail: 1Kb
ERROR: Stack depth: 11,183,864, last-call: 0%, Choice points: 3
ERROR: Possible non-terminating recursion:
ERROR: [11,183,864] user:out_of_stack(-11183853, _5046)
ERROR: [11,183,863] user:out_of_stack(-11183852, _5066)
这就是正在发生的事情,也是Prolog崩溃的原因。
要解决此问题,请按照其他建议进行操作。另一种解决方案是使用0
,s(0)
,s(s(0))
,...表示自然数。