Your code seems appropriate, only some typos around leading to singleons, which are likely to harm your work.
There are + 2 singletones in simple_assign (Var_Name2 and Var_Value) and + Var_Name2 is a singleton in var_name
I think you are not using an IDE with suitable syntax highlighting ...
edit single loners, I have to say that the user's response is more useful than mine (+1). Trying to provide a mutable environment while parsing does not work. Here's how I tested, with a slightly different version of your grammar:
test :- phrase(statement(S), [begin,a,:=,10,while,a,>,5,begin,write,a,a,:=,a,-,1,end,end]), eval(S, [], _). % grammar statement(Var := Expr) --> var(Var), [:=], expr(Expr). statement(write(E)) --> [write], expr(E). statement(while(C, S)) --> [while], condition(C), statement(S). statement(S) --> [begin], statements(S), [end]. statements([S|R]) --> statement(S), statements(R). statements([]) --> []. condition(L > R) --> expr(L), [>], expr(R). expr(L - R) --> (var(L) ; num(L)), [-], expr(R). expr(E) --> (var(E) ; num(E)). var(var(V)) --> [V], {atom(V)}. num(num(N)) --> [N], {number(N)}. % evaluation eval([S|R], Vs, Us) :- eval(S, Vs, V1), eval(R, V1, Us). eval([], Vs, Vs). eval(V := E, Vs, Us) :- exprv(E, Vs, Ve), ( select(V := _, Vs, R) -> Us = [V := Ve | R] ; Us = [V := Ve | Vs] ). eval(write(E), Vs, Vs) :- exprv(E, Vs, Ve), writeln(Ve). eval(while(C, S), Vs, Ts) :- satisfied(C, Vs) -> eval(S, Vs, Us), eval(while(C, S), Us, Ts) ; Vs = Ts. % no side effect here exprv(LE, Vs, Ve) :- exprv(L, Vs, Vl), exprv(E, Vs, R), Ve is Vl - R. exprv(num(N), _, N). exprv(var(V), Vs, Vv) :- memberchk(var(V) := Vv, Vs). satisfied(L > R, Vs) :- exprv(L, Vs, Vl), exprv(R, Vs, Vr), Vl > Vr.