Returning results in recursion

醉酒当歌 提交于 2020-01-07 02:43:08

问题


I am trying to solve a problem where I need to evaluate the value of a binary expression tree.

tree_calc(Tree, Eval)

where Eval should hold the final result and Tree must be in the form:

tree(LeftNode, Operator, RightNode)

If I create the tree function as per the form above, how am I supposed to pass the results of the calculations back up the recursion if there isn't an empty variable to store the results?

My understanding is that an extra variable is always needed to store the result in.

Apologies in advance as I am sure I am misunderstanding something basic.

Thanks for your help.


回答1:


In this context, tree isn't what you are calling a function, nor is it what Prolog would refer to as a predicate. tree(LeftNode, Operator, RightNode) is just a term that is used as a structure to represent the tree. So, for example, (2 + 3) * 4 would be represented by, tree(tree(2,+,3), *, 4). You would call your predicate with tree_calc(tree(tree(2,+,3),*,4), Eval) and expect that query to yield, Eval = 20. The term, tree/3 doesn't carry results in this case.

To give an example of how to access tree/3 in a predicate, here's a simple predicate that evaluates the simplest tree (so there's no recursion to tree leaves):

tree_calc(tree(L, Op, R), E) :-
    % Neither L or R are of the form `tree/3`
    compute(Op, L, R, E).

compute(+, L, R, E) :- E is L + R.
compute(*, L, R, E) :- E is L * R.
compute(-, L, R, E) :- E is L - R.
compute(/, L, R, E) :- E is L / R.

You can generalize compute/4:

compute(Op, L, R, E) :-
    Exp =.. [Op, L, R],
    E is Exp.

And you can call it like so:

| ?- tree_calc(tree(2,+,3), Eval).

Eval = 5

yes

For your more general case, you'll need to check L and R to see if they are a tree/3 structure themselves and recursively call tree_calc recursively if so.

Prolog is good at matching term patters. So if you check unification L = tree(LL, Op, LR) and it succeeds, that means L is a tree with left branch LL, operation Op, and right branch LR. You can play with this behavior at the Prolog prompt to see how it works:

| ?- Tree = tree(2, +, 3), Tree = tree(L, Op, R).

L = 2
Op = (+)
R = 3
Tree = tree(2,+,3)

yes
| ?- Tree = tree(2,+,tree(3,*,4)), Tree = tree(L, Op, R).

L = 2
Op = (+)
R = tree(3,*,4)
Tree = tree(2,+,tree(3,*,4))

yes

| ?- Tree = tree(2,+,tree(3,*,4)), Tree = tree(L, Op, R), R = tree(LR, OpR, RR).

L = 2
LR = 3
Op = (+)
OpR = (*)
R = tree(3,*,4)
RR = 4
Tree = tree(2,+,tree(3,*,4))

yes
| ?-


来源:https://stackoverflow.com/questions/36197849/returning-results-in-recursion

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!