Section eval.
Variable eval : mem -> expr -> (mem * expr).
Definition eval' (m:mem) (e0:expr) : mem * expr :=
match e0 with
| App e1 e2 =>
match eval m e1 with
| (m', Lam e1') =>
let (m'',e2') := eval m' e2 in
match value_dec e2' with
| left H => eval m'' (subst 0 (exp_to_val e2' H) e1')
| _ => (m'',App (Lam e1') e2')
end
| (m',e1') => (m',App e1' e2)
end
| Prim f e1 =>
match eval m e1 with
| (m', Nat x) =>
match value_dec (f x) with
| left H => (m',f x)
| _ => (m',Prim f (Nat x))
end
| (m',e1') => (m',Prim f e1')
end
| New e1 =>
let (m',e') := eval m e1 in
match value_dec e' with
| left H =>
let (m'',l) := new m' (exp_to_val e' H) in (m'',Loc l)
| _ => (m',New e')
end
| Deref e1 =>
match eval m e1 with
| (m',Loc l) => eval m' (val_to_exp (deref m' l))
| (m',e1') => (m',Deref e1')
end
| Update e1 e2 e3 =>
match eval m e1 with
| (m',Loc l) =>
let (m'',e2') := eval m' e2 in
match value_dec e2' with
| left H =>
eval (update m'' l (exp_to_val e2' H)) e3
| _ => (m'',Update (Loc l) e2' e3)
end
| (m',x) => (m',Update x e2 e3)
end
| x => (m,x)
end.
Hypothesis Heval :
forall m e m' e',
eval m e = (m',e') ->
stepstar (m,e) (m',e').
End eval.
Definition eval (x:Z) := Zmisc.iter x _ eval' (fun m e => (m,e)).

Lemma eval_correct : forall x m e m' e',
eval x m e = (m',e') ->
stepstar (m,e) (m',e').