通過z=Value
你實際上是統一變量Value
與原子z
。如果你的意思是Z到是你有一個變量,它寫成大寫字母Z
作爲@vmg指出:
tree_eval(Value,tree(empty,Z,empty),Value):-
Z = Value.
在這種情況下,有趣的是考慮查詢謂詞時會發生什麼:
?- tree_eval(V,tree(empty,3,empty),E).
E = 3 ? ;
E = V = 3 ? ;
no
第一個解決方案是由您的第一個規則生成的,其中第一個參數有一個匿名變量。第二個解決方案是由你的第二個規則產生的,你要求第一個和第三個參數是相同的。所以基本上你有兩個派生路徑的值爲3在這兩種情況下。現在,讓我們來看看一個稍微大一點的樹:
?- tree_eval(V,tree(tree(empty,2,empty),+,tree(empty,3,empty)),E).
E = 5 ? ;
E = 5,
V = 3 ? ;
E = 5,
V = 2 ? ;
no
第一個答案是很難suprising作爲樹的計算結果爲5的確但對於接下來的兩個解決方案?讓我們來看看這些解決方案的前景如何:術語
tree(tree(empty,2,empty),+,tree(empty,3,empty))
只與第三條規則相匹配,因爲子樹不是空的。所以tree_eval/3被調用的子樹tree(empty,2,empty)
和產率第一溶液:(_,tree(empty,2,empty),2)
然後tree_eval/3被調用的子樹tree(empty,3,empty)
與第一溶液:(_,tree(empty,3,empty),3)
現在eval(2,3,+,Eval)
產量Eval=5
。然而,第一個參數仍然是Value=_
。因此查詢的第一個解決方案是:E=5
。
如果您要求其他答案,prolog會嘗試是否存在第三個目標的進一步解決方案,確定沒有,因此回溯到第二個目標:正確的子樹,實際上您的第二個規則提供:(3,tree(empty,3,empty),3)
。 eval(2,3,+,Eval)
再次貢獻Eval=5
,因此查詢的第二個解決方案:E=5, V=3
。
如果您仍然需要更多解決方案,prolog必須進一步回溯到第一個目標:並且您的第二個規則再次提供:(2,tree(empty,2,empty),2)
。現在你的第二個進球再次相匹配的第一個規則:(_,tree(empty,3,empty),3)
,EVAL/4再送Eval=5
,所以要查詢的第三個解決方案是:E=5, V=2
回溯一個更多的時間目標2序言再次嘗試第二規則和失敗的原因第一個參數不能同時爲2和3。因此,查詢沒有第四種解決方案。
但是,如果tree_eval/3將使用相同的樹結構進行查詢,但兩者的葉子被二是,通過上面的推理,不是真的suprising有4個解決方案:
?- tree_eval(V,tree(tree(empty,2,empty),+,tree(empty,2,empty)),E).
E = 4 ? ;
E = 4,
V = 2 ? ;
E = 4,
V = 2 ? ;
E = 4,
V = 2 ? ;
no
看着那些多種解決方案顯然你的第三個參數是提供正確的解決方案,而且你並不需要第一個參數。你也可以沒有第二條規則。通過合併建議@mat一些改進,你的斷言可能會再看看這樣的事情:
tree_evaluation(tree(empty,Num,empty),Num).
tree_evaluation(tree(L,Op,R),Val) :-
tree_evaluation(L,LVal),
tree_evaluation(R,RVal),
evaluation(LVal,RVal,Op,Val).
evaluation(L,R,+,V) :-
V is L + R.
evaluation(L,R,-,V) :-
V is L - R.
evaluation(L,R,/,V) :-
V is L/R.
這個版本的產量獨特的答案:
?- tree_evaluation(tree(empty,3,empty),E).
E = 3 ? ;
no
?- tree_evaluation(tree(tree(empty,2,empty),+,tree(empty,3,empty)),E).
E = 5 ? ;
no
您需要繞過一個額外的參數,可以讓你「擡頭「這些符號常數的值。我建議在關聯列表中傳遞(參見'library(assoc)')這些用例。另外,不需要如此多的'Op =( - )'目標:只需將統一*直接拉入子句頭:'評估(+,左,右,符號,結果): - ...等等。還要注意更多的聲明性名稱,*不*表示特定的方向。 – mat
'z'評估爲零元謂詞。如果你想讓Z成爲一個變量,它需要以大寫字母開頭。即使那樣,'Z = Value'也不是你想要的 - 你需要'Z是Value'。或者你的第二個謂詞可以替換爲'tree_eval(Z,樹(空,Z,空),Z)。「現在我看到它,它似乎與第一個似乎是多餘的。 – vmg