背景
我需要编写一个谓词 eval(P,A,R),其中:
P表示多项式系数列表,即1+2x+3x^2表示为[1,2,3]。
A 代表 X 的值。
R 是 X=A 处多项式的结果。
示例: eval([3,1,2],3,R) 生成 R = 24。*编辑,之前不正确的示例
我正在尝试使用本文和 Learn Prolog Now 上的示例中的累加器。
我的算法:
0. 将结果和指数变量初始化为0。
1. 取列表的头部。
2. 将列表的头部乘以 A^(指数)。
3. 更新结果和指数。
我的代码:
eval(P,A,R) :- accEval(P,A,0,0,R).
accEval(([H|T]),A,Pow,Accres,R) :-
Rnew is (Accres+H*(A**Pow)),
Pownew is Pow+1,
R = Accres,
accEval(T,A,Pownew,Rnew,Rnew). % *See below
accEval([],A,Pow,Accres,Accres).
% *Previously, when the second Rnew in this line was R instead, output was "no".
产生痕迹:
| ?- eval([1,2],3,R).
1 1 Call: eval([1,2],3,_20) ?
2 2 Call: accEval([1,2],3,0,0,_20) ?
3 3 Call: _126 is 0+1*3**0 ?
3 3 Exit: 1.0 is 0+1*3**0 ?
4 3 Call: _157 is 0+1 ?
4 3 Exit: 1 is 0+1 ?
5 3 Call: accEval([2],3,1,1.0,1.0) ?
6 4 Call: _218 is 1.0+2*3**1 ?
6 4 Exit: 7.0 is 1.0+2*3**1 ?
7 4 Call: _249 is 1+1 ?
7 4 Exit: 2 is 1+1 ?
8 4 Call: accEval([],3,2,7.0,7.0) ?
8 4 Exit: accEval([],3,2,7.0,7.0) ? % We have the correct answer.
5 3 Exit: accEval([2],3,1,1.0,1.0) ? % Wait! What are you doing!?
2 2 Exit: accEval([1,2],3,0,0,0) ? % Why is this falling back out?
1 1 Exit: eval([1,2],3,0) ?
R = 0 % Incorrect. The answer should be 7.
正如我的代码中所指出的,之前的尝试没有为 R 产生任何值(value),而是产生“否”或在其他实现中产生"is"。
问题
为什么结果丢失并且没有带回原始调用?
最佳答案
在递归结束时应该与累加器值统一的变量已经绑定(bind)到一个值。使用累加器的方式如下:
- 首次“调用”谓词时为累加器指定一个初始值
- 使用累加器将累加值向下递归调用传递
- 将结果与递归结束子句中的累加器统一
根据经验,谓词头部的 Result 变量与向下传递给递归调用的变量相同。这样,一旦它与最后的实际结果(在递归结束子句中)统一,它也将从递归中向上传递给调用者。
关于prolog - 使用 Prolog 中的累加器计算多项式的计算问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15259118/