Prolog - Substitute atom with value and evaluate

2019-08-13 00:06发布

问题:

Given

Result = 4* (3*x)^3*3,

and

VarValue = x:2,

How can I get the following output

Value = 2592 ;

if I have to defined the following predicate:

evaluate(Result,Value,VarValue)

I tried doing the following:

evaluate(Result, Value, VarValue) :- member(VarValue, [x:X]).

and trying to substitute X into the equation.. I could not think of a nice way to go from there.

EDIT: Is there a way to only use the following built-predicates :

 //, /, +, -, ^, *,=..,>, <,
 atom, is_list, functor, arg, integer, number, member, append

回答1:

I think joel76 solution can be made a bit more compact:

exp_symbols(Symbols, Expr, WithSym) :-
    Expr =.. [F|Args],
    ( memberchk(F:V, Symbols) -> G = V ; G = F ),
    maplist(exp_symbols(Symbols), Args, ArgsSWithSym),
    WithSym =.. [G|ArgsSWithSym].

evaluate(Exp, LstVars, Val) :-
    exp_symbols(LstVars, Exp, NewExp),
    Val is NewExp.


回答2:

You can use =.. :

evaluate(Exp, LstVars, Val) :-
    analyse(LstVars, Exp, NewExp),
    Val is NewExp.


analyse(LstVars, Term,R) :-
    functor(Term, Term, 0), !,
    (   member(Term : V, LstVars)
    ->  R = V
    ;   R = Term).

analyse(LstVars, Term, V) :-
    functor(Term, Name, _),
    Term =.. [Name | Lst],
    maplist(analyse(LstVars), Lst, LstV),
    V =.. [Name|LstV].

For example :

?- evaluate(4* (3*x)^3*y, [x:2, y:(-3)], L). 
L = -2592.

?- evaluate(4* (3*x)^3*3, [x:2], L). 
L = 2592.

EDIT I remove member(Term:(V), LstVars) -> R = (V) wich is useless.



回答3:

Here is something to get you started. It supports only addition and subtraction, and no braces. Adding more operations is trivial, adding braces support is more tricky.

evaluate(X, X, _) :- number(X).
evaluate(Var, Val, Var:Val).
evaluate(A-B, Val, VarVal) :-
    evaluate(A, Aval, VarVal),
    evaluate(B, Bval, VarVal),
    Val is Aval - Bval.
evaluate(A+B, Val, VarVal) :-
    evaluate(A, Aval, VarVal),
    evaluate(B, Bval, VarVal),
    Val is Aval + Bval.

Let's try it:

?- evaluate(2+2, Result, x:10).
Result = 4 

?- evaluate(2+x, Result, x:10).
Result = 12 

?- evaluate(2+x-34+x, Result, x:10).
Result = -12 


标签: prolog