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.

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