为什么会这样:
power(_,0,1) :- !.
power(X,Y,Z) :-
Y1 is Y - 1,
power(X,Y1,Z1),
Z is X * Z1.
这会产生堆栈溢出异常吗?
power(_,0,1) :- !.
power(X,Y,Z) :-
power(X,Y - 1,Z1),
Z is X * Z1.
为什么会这样:
power(_,0,1) :- !.
power(X,Y,Z) :-
Y1 is Y - 1,
power(X,Y1,Z1),
Z is X * Z1.
这会产生堆栈溢出异常吗?
power(_,0,1) :- !.
power(X,Y,Z) :-
power(X,Y - 1,Z1),
Z is X * Z1.
因为算术运算仅通过is
运算符对子句执行。在您的第一个示例中,Y1 与计算 Y - 1 的结果绑定。在后面,系统尝试证明子句 power(X, Y - 1, Z1),它与 power(X', Y', Z') 绑定 X' = X, Y' = Y - 1, Z' = Z。然后再次递归,所以 Y'' = Y - 1 - 1 等无穷大,从不实际执行计算。
Prolog 主要只是术语的统一 - 在“常识”意义上,必须明确要求计算。
这两个定义都不能正常工作。
考虑
?- pow(1, 1, 2).
which 为两个定义循环,因为无论第二个参数如何,都可以应用第二个子句。第一个子句中的删减不能撤消这一点。第二个子句Y > 0
在递归目标之前需要一个目标。使用(is)/2
仍然是获得实际解决方案的好主意。
最好的(对于初学者)是从后继算法或clpfd开始,并完全避免prolog-cut。
参见例如:Prolog 谓词 - 无限循环