错误:`compute / 4'不是函数

时间:2016-03-25 12:45:39

标签: prolog

我正在尝试评估算术二叉树。

tree_calc(tree(L, Root, R), Eval) :- compute(Root, L, R, Eval).


compute(Root, 'empty', 'empty', Root).
compute(Root, L, R, Eval):- number(L), number(R), E =..[Root,L,R], Eval is E.
compute(Root, L, R, Eval):- 
        L = tree(LL, LRoot, LR), R = tree(RL, RRoot, RR),
        E =..[Root, compute(LRoot, LL, LR, LEval), compute(RRoot, RL, RR, REval)],
        Eval is E.                          

当我使用输入运行程序时:

tree_calc(tree(tree(empty,2,empty),
             '+',tree(tree(empty,1,empty),
                  '/',tree(empty,2,empty))), Eval).

我收到错误:

ERROR: is/2: Arithmetic: `compute/4' is not a function

我似乎无法弄清楚为什么会抛出这个错误,因为我认为只有在未定义函数时才会显示此错误。

感谢您的帮助。

2 个答案:

答案 0 :(得分:1)

虽然Scott解决了您遇到的最棘手的技术问题,但您可能有兴趣了解更简单,声明性的方法:

tree_calc(tree(L, +, R), Eval) :- tree_calc(L, Lr), tree_calc(R, Rr), Eval is Lr+Rr.
tree_calc(tree(L, /, R), Eval) :- tree_calc(L, Lr), tree_calc(R, Rr), Eval is Lr/Rr.
tree_calc(tree(empty, N, empty), N).

这在关于树的正确性的一些限制性假设下工作(例如,叶子是数字,并且仅使用指定的运算符):

?- tree_calc(tree(tree(empty,2,empty),
             '+',tree(tree(empty,1,empty),
                  '/',tree(empty,2,empty))), Eval).
Eval = 2.5 ;
false.

另一种方法,因为/ 2实际上是对表达式树进行求值,可能是

tree_calc(T, V) :- translate(T, E), V is E.

translate(tree(empty,N,empty), N) :- !.
translate(tree(L,Op,R), E) :-
    E =.. [Op,Lt,Rt],
    translate(L, Lt),
    translate(R, Rt).

现在可以使用所有Prolog(二进制)算术运算符。切换是为了避免在回溯时尝试在原子上调用univ / 2 ...

答案 1 :(得分:0)

is用于算术分配,不用于统一。 (例如,A=1+1不会以A为2结束,但A is 1+1会结束。)因此,Prolog正在尝试对右边的表达式进行算术计算,其中包含看似算术的表达式功能,但显然不是。

您可以使用=代替is,或者更简洁地消除E,并直接与Eval统一:Eval =..[Root, compute( ...

然后,您似乎正在使用compute返回列表中的某些内容,因此Prolog可能不是唯一一个感到困惑的人。