2016-03-24 11 views
0

私はバイナリ式ツリーの値を評価する必要がある問題を解決しようとしています。再帰の結果を返す

tree(LeftNode, Operator, RightNode) 

私は上記のフォームに従ってtree関数を作成した場合、どのように私は結果を渡すことになっています:Evalは、最終的な結果を保持しなければならないとTreeは形式でなければなりません

tree_calc(Tree, Eval) 

結果を格納する空の変数がない場合、計算は再帰をバックアップしますか?

私の理解では、余分な変数は常に、結果を格納するのに必要とされることである。事前に

謝罪、私は基本的に何かを誤解しています確信しているよう。

ありがとうございました。これに関連して

+2

このようなツリーと値の間に*関係*を定義する必要があります。これを行うには、2つの引数を持つ述語で十分です。あなたが定義する必要があるのは、ツリーとその子(もしあれば)の値とツリー自体の価値の関係は何ですか? – mat

答えて

1

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 
| ?- 
+0

そのlurkerに感謝します。私は上記の関係@matをどのように定義するかについて頭を悩ますようには思えません。 'tree'は何も返さないのでしょうか?または、あなたが言及したように、それは単に木を表現するためにそこにあるのでしょうか?また 'Tree'変数が' tree(tree(2、+、3)、*、4) 'を参照する場合、何とか' Tree'を使って左右の枝にアクセスするはずですか?それについて考え続けるだろう..あなたの助けをありがとう。 – Archer

+1

@Archerは、 'tree'が何かを返すかもしれないと考えても、関係を考えていません。プロローグは物事を返さないと予測します。それらは成功または失敗し、その過程で成功するために変数をインスタンス化します。この文脈で 'tree/3'は、言及したように、あなたのデータの構造を定義するのに使われる用語で、Cの' struct'と同じ(緩やかな)意味でデータ構造を定義します。それは何も返さない。私の答えで説明したように、tree_calcにデータ構造( 'tree'を使って)を渡すと、そのクエリは式の適切な評価で成功し、' Eval'を返します。 – lurker

+0

@Archer 'tree/3'の処理の詳細については、私の更新された答えを見てください。 – lurker