2016-03-25 25 views
2

Bir aritmetik ikili ağacı değerlendirmeye çalışıyorum.Hata: `hesaplama/4 'bir işlev değil

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.       

ben girişi ile programı çalıştırdığınızda:

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

ben hata alıyorum:

ERROR: is/2: Arithmetic: `compute/4' is not a function 
bu hata olarak atılıyor neden çalışmak için görünmüyor olabilir

Bir fonksiyon tanımlanmamışsa, bunun sadece gösterildiğini düşündüm.

Yardımlarınız için teşekkürler. Birleştirme için değil, aritmetik ataması için

cevap

1

, sen daha basit, bildirim, yaklaşımı hakkında bilmek ilgi olabilir örneğin, bir yaprak, bir sayıdır, ve sadece belirli operatörler) kullanılır:

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

diğer bir yaklaşım,/2, aslında bir ifade ağaç değerlendirir olduğu, olabilir

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). 

Artık tüm Prolog (ikili) aritmetik işleçler kullanılabilir. Kesim, geriye dönük olarak, bir atom üzerinde univ/2'yi çağırmaktan kaçınmak için gereklidir ...

+0

OP, "ağaç/3" tanımını değiştirmediği sürece, ilk çözümünüz doğru olmalıdır. Bu onların [ilk yazı] bir devamıdır (http://stackoverflow.com/questions/36197849/returning-results-in-recursion). Şimdi OP, biraz kafa karıştırıcı olan 'Kök' orta argümanını çağırıyor. – lurker

0

is kullanılır. (Örneğin, A=1+1, A 2 ile bitmeyecek, ancak A is 1+1 olur.) Bu nedenle Prolog, aritmetik olarak aritmetik bir işleve benzeyen, ancak açıkça bulunmayan ifadeyi, sağdaki ifadeyi aritmetik olarak değerlendirmeye çalışıyor.

tekrar Sonra

, bir parçası olan bir şey dönmek için compute kullanıyor görünüyor ... Eval =..[Root, compute(:

Sen = yerine is ait kullanabilirsiniz

veya daha kısaca, E ortadan kaldırmak ve sadece doğrudan Eval ile birleşme Liste, bu yüzden şaşkın olan tek kişi Prolog olmayabilir. (Bu ağacın doğruluğu hakkında bazı kısıtlı varsayımı altında çalışır

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). 

: Scott Yaşadığınız en teknik sorunu ele ederken

+0

Teşekkürler Scott. Ben aslında soruyu göndermeden önce '=' kullanmayı denedim. Ancak, bu basitçe yazıyor gibi görünüyor: 'Eval = hesaplama (2, boş, boş, _G413) + hesaplama ((/), ağaç (boş, 1, boş), ağaç (boş, 2, boş), _G418) – Archer

+0

Eğer 'compute' işlevini istiyorsanız, onu tanımlayın. Bunu bir yüklem olarak görmek istiyorsanız, onu tanımlayın. İkisi de olamaz. –