(** * Semantic preservation for the translation *)

(** The proof of semantic preservation uses simulation diagrams of the
  following form:
<<
       e, m1, s ----------------- sp, te1, tm1, ts
          |                                |
         t|                                |t
          v                                v
       e, m2, out --------------- sp, te2, tm2, tout
>>
  where [ts] is the Cminor statement obtained by translating the
  C#minor statement [s].  The left vertical arrow is an execution
  of a C#minor statement.  The right vertical arrow is an execution
  of a Cminor statement.  The precondition (top vertical bar)
  includes a [mem_inject] relation between the memory states [m1] and [tm1],
  and a [match_callstack] relation for any callstack having
  [e], [te1], [sp] as top frame.  The postcondition (bottom vertical bar)
  is the existence of a memory injection [f2] that extends the injection
  [f1] we started with, preserves the [match_callstack] relation for
  the transformed callstack at the final state, and validates a
  [outcome_inject] relation between the outcomes [out] and [tout].
*)

(** ** Semantic preservation for expressions *)

Remark bool_of_val_inject:
  forall f v tv b,
  Val.bool_of_val v b -> val_inject f v tv -> Val.bool_of_val tv b.

(* Specifications: *)
Lemma transl_constant_correct: forall f sp cst v, Csharpminor.eval_constant cst = Some v -> let (tcst, a) := transl_constant cst in exists tv, eval_constant tge sp tcst = Some tv /\ val_inject f v tv /\ val_match_approx a v.
Lemma transl_expr_correct: forall f m tm cenv tf e le te sp lo hi cs (MINJ: Mem.inject f m tm) (MATCH: match_callstack f m tm (Frame cenv tf e le te sp lo hi :: cs) (Mem.nextblock m) (Mem.nextblock tm)), forall a v, Csharpminor.eval_expr ge e le m a v -> forall ta app (TR: transl_expr cenv a = OK (ta, app)), exists tv, eval_expr tge (Vptr sp Int.zero) te tm ta tv /\ val_inject f v tv /\ val_match_approx app v.
Lemma transl_exprlist_correct: forall f m tm cenv tf e le te sp lo hi cs (MINJ: Mem.inject f m tm) (MATCH: match_callstack f m tm (Frame cenv tf e le te sp lo hi :: cs) (Mem.nextblock m) (Mem.nextblock tm)), forall a v, Csharpminor.eval_exprlist ge e le m a v -> forall ta (TR: transl_exprlist cenv a = OK ta), exists tv, eval_exprlist tge (Vptr sp Int.zero) te tm ta tv /\ val_list_inject f v tv.
Lemma transl_constant_correct: forall f sp cst v, Csharpminor.eval_constant cst = Some v -> let (tcst, a) := transl_constant cst in exists tv, eval_constant tge sp tcst = Some tv /\ val_inject f v tv /\ val_match_approx a v.
Lemma transl_expr_correct: forall f m tm cenv tf e le te sp lo hi cs (MINJ: Mem.inject f m tm) (MATCH: match_callstack f m tm (Frame cenv tf e le te sp lo hi :: cs) (Mem.nextblock m) (Mem.nextblock tm)), forall a v, Csharpminor.eval_expr ge e le m a v -> forall ta app (TR: transl_expr cenv a = OK (ta, app)), exists tv, eval_expr tge (Vptr sp Int.zero) te tm ta tv /\ val_inject f v tv /\ val_match_approx app v.
Lemma transl_exprlist_correct: forall f m tm cenv tf e le te sp lo hi cs (MINJ: Mem.inject f m tm) (MATCH: match_callstack f m tm (Frame cenv tf e le te sp lo hi :: cs) (Mem.nextblock m) (Mem.nextblock tm)), forall a v, Csharpminor.eval_exprlist ge e le m a v -> forall ta (TR: transl_exprlist cenv a = OK ta), exists tv, eval_exprlist tge (Vptr sp Int.zero) te tm ta tv /\ val_list_inject f v tv.