2016-03-25 9 views
2

算術バイナリツリーを評価しようとしています。エラー: `compute/4 'は関数ではありません

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 

私はこのエラーとしてスローされる理由を動作するように見えることはできません私は、関数が定義されていない場合にのみこれが表示されると考えました。

ありがとうございました。

答えて

1

スコットは、あなたが経験しているほとんどの技術的な問題に対処している間、あなたは単純に、宣言型、アプローチについて知って興味がある可能性があり:

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(2進)算術演算子を使用できます。カットは、バックトラッキング時に、原子上でuniv/2を呼び出すことを避けるために必要です。

+0

OPが 'tree/3'の定義を変更しない限り、最初の解決策は正しいはずです。これは彼らの[最初の投稿](http://stackoverflow.com/questions/36197849/returning-results-in-recursion)の続きです。今OPは中間の引数 'Root'を呼び出しますが、少し混乱します。 – lurker

0

isは、統一のためではなく算術割り当てに使用されます。 (例えば、A=1+1Aが2で終わらず、A is 1+1となります。)したがって、Prologは算術関数のように見える式を算術的に評価しようとしていますが、明らかにそうではありません。

あなたはEを排除し、ちょうど直接Evalで統一、代わりに、より簡潔isか、の=を使用することができます。Eval =..[Root, compute( ...

その後、再び、あなたはAの一部であり、何かを返すようにcomputeを使用しているように見えますPrologは混乱している唯一の人ではないかもしれません。

+0

Thanks Scott。私は実際に質問を投稿する前に '='を使って試してみました。しかし、これは単純に次のように書かれているようです: 'Eval = compute(2、空、空、_G413)+計算((/)、ツリー(空、1、空)、ツリー(空、2、空)、_G418) – Archer

+0

'compute'を関数にしたい場合は、そのように定義します。述語にしたい場合は、そのように定義します。それは両方になることはできません。 –

関連する問題