cal(cal(1, plus, 2), minus, 3)我需要从中得到一个结果。我该怎么做?我被prolog伤害了。T.T
AST 是通过调用以下内容生成的:
?- calculations(Tree,[1,+,2,-,3],[]).
Tree = cal(cal(1, plus, 2), minus, 3) .
在以下 DCG 代码上:
calculations(VV) -->
vv(VV).
calculations(ResultTree) -->
vv(VV1), more_calculations(VV1,ResultTree).
more_calculations(VV1,cal(VV1,Operator,VV2)) -->
more_calculation(Operator,VV2).
more_calculations(VV1,ResultTree) -->
more_calculation(Operator1,VV2),
more_calculations(cal(VV1,Operator1,VV2),ResultTree).
more_calculation(Operator,VV) -->
operator(Operator),vv(VV).
vv(Name) --> var_name(Name).
vv(Value) --> var_value(Value).
operator(plus) --> [+].
operator(minus) --> [-].
var_name(Name) -->
[Name],{check_name(Name),+member(Name,[write,read,begin,end,while])}.
var_value(Value) -->[Value],{number(Value)}.
check_name(N):-
catch(atom_chars(N, L), _, fail),
is_lower(L).
is_lower([]).
is_lower([H|T]) :-
catch(char_type(H, lower), _, fail),
is_lower(T).
有很多方法可以做到这一点,这取决于你正在做的事情和你的目标是什么。但这里有一种可能性:
evaluate(cal(X, Op, Y), Result) :-
evaluate(X, Xr),
evaluate(Y, Yr),
Exp =.. [Op, Xr, Yr, Result],
call(Exp).
evaluate(X, X) :- number(X).
plus(X, Y, R) :- R is X + Y.
minus(X, Y, R) :- R is X - Y.
evaluate/2
假设您向其传递看起来像数字或cal/3
的东西,其中要cal/3
的参数分别是操作数、运算符和另一个操作数。您编写一个谓词来评估每个单独的运算符,它们假定操作数已减少为数字。
例:
evaluate(cal(cal(2, plus, 3), minus, 8), Result).
给:
Result = -3.
在所述示例中:
| ?- calculations(Tree,[1,+,2,-,3],[]), evaluate(Tree, Result).
Result = 0
Tree = cal(cal(1,plus,2),minus,3) ? a
no