、tree
あなたが機能を呼び出しているものではありません、またそれはプロローグが述語と呼ぶであろうものです。 tree(LeftNode, Operator, RightNode)
は、木を表す構造として使用されるちょうどの用語です。したがって、たとえば、(2 + 3) * 4
は、tree(tree(2,+,3), *, 4)
で表されます。 述部をtree_calc(tree(tree(2,+,3),*,4), Eval)
とし、その照会には、Eval = 20
と入力します。この場合、tree/3
という語は結果を持ちません。
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.
あなたはcompute/4
を一般化することができます:
述語でtree/3
にアクセスする方法の例を与えることが、ここで最も単純なツリーを評価して、単純な述語だ(そう木の葉への再帰はありません)
compute(Op, L, R, E) :-
Exp =.. [Op, L, R],
E is Exp.
そして、あなたはそうのようにそれを呼び出すことができます。
| ?- tree_calc(tree(2,+,3), Eval).
Eval = 5
yes
より一般的なケースでは、とR
をチェックして、それらがtree/3
構造体であるかどうかを確認し、そうであれば再帰的にtree_calc
を呼び出します。
Prologは、用語パターンのマッチングに適しています。したがって、ユニファイドL = tree(LL, Op, LR)
を確認して成功した場合は、L
が、左側ブランチがLL
、操作がOp
、右ブランチがLR
であることを意味します。この動作をPrologのプロンプトで再生して、動作を確認することができます。
| ?- 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
| ?-
このようなツリーと値の間に*関係*を定義する必要があります。これを行うには、2つの引数を持つ述語で十分です。あなたが定義する必要があるのは、ツリーとその子(もしあれば)の値とツリー自体の価値の関係は何ですか? – mat