val3(plus(X, Y), Context, Value) :- val3(X, Context, XValue), val3(Y, Context, YValue), Value is XValue + YValue. val3(times(X, Y), Context, Value) :- val3(X, Context, XValue), val3(Y, Context, YValue), Value is XValue * YValue. val3(const(X), _, X). val3(var(X), Context, Value) :- lookup(X, Context, Value). val3(let(X, Exp1, Exp2), Context, Value2) :- val3(Exp1, Context, Value1), val3(Exp2, [bind(X, Value1) | Context], Value2). val3(fn(Formal, Body), _, fval(Formal, Body)). val3(apply(Function, Actual), Context, Value) :- val3(Function, Context, fval(Formal, Body)), val3(Actual, Context, ParamValue), val3(Body, [bind(Formal, ParamValue)|Context], Value). lookup(Variable, [bind(Variable, Value)|_], Value). lookup(VarX, [bind(VarY, _)|Rest], Value) :- VarX \= VarY, lookup(VarX, Rest, Value). /* val3(let(y, const(1), let(y, const(2), var(y))), nil, X). val3(let(a, plus(const(3), const(4)), times(var(a), const(5))), nil, V). val3(apply(fn(x,times(var(x), var(x))), const(3)), nil, X). val3(let(x, const(1), let(f, fn(n, plus(var(n), var(x))), let(x, const(2), apply(var(f), const(0))))), nil, X). */