Section PRESERVATION.
Variable prog: Csyntax.program.
Variable tprog: Clight.program.
Hypothesis TRANSL: match_prog prog tprog.
Let ge := Csem.globalenv prog.
Let tge := Clight.globalenv tprog.
(** Invariance properties. *)
Proof (Genv.find_symbol_match (proj1 TRANSL)).
Proof (Genv.senv_match (proj1 TRANSL)).
(** Properties of smart constructors. *)
(** Translation of simple expressions. *)
Proof (proj1 tr_simple_nil).
Proof (proj2 tr_simple_nil).
(** Translation of [deref_loc] and [assign_loc] operations. *)
Remark deref_loc_translated:
forall ty m b ofs t v,
Csem.deref_loc ge ty m b ofs t v ->
match chunk_for_volatile_type ty with
| None => t = E0 /\ Clight.deref_loc ty m b ofs v
| Some chunk => volatile_load tge chunk m b ofs t v
end.
Remark assign_loc_translated:
forall ty m b ofs v t m',
Csem.assign_loc ge ty m b ofs v t m' ->
match chunk_for_volatile_type ty with
| None => t = E0 /\ Clight.assign_loc tge ty m b ofs v m'
| Some chunk => volatile_store tge chunk m b ofs v t m'
end.
(** Evaluation of simple expressions and of their translation *)
(** Commutation between the translation of expressions and left contexts. *)
Scheme leftcontext_ind2 := Minimality for leftcontext Sort Prop
with leftcontextlist_ind2 := Minimality for leftcontextlist Sort Prop.
Combined Scheme leftcontext_leftcontextlist_ind from leftcontext_ind2, leftcontextlist_ind2.

Lemma tr_expr_leftcontext_rec:
(
forall from to C, leftcontext from to C ->
forall le e dst sl a tmps,
tr_expr le dst (C e) sl a tmps ->
exists dst', exists sl1, exists sl2, exists a', exists tmp',
tr_expr le dst' e sl1 a' tmp'
/\ sl = sl1 ++ sl2
/\ incl tmp' tmps
/\ (forall le' e' sl3,
tr_expr le' dst' e' sl3 a' tmp' ->
(forall id, ~In id tmp' -> le'!id = le!id) ->
Csyntax.typeof e' = Csyntax.typeof e ->
tr_expr le' dst (C e') (sl3 ++ sl2) a tmps)
) /\ (
forall from C, leftcontextlist from C ->
forall le e sl a tmps,
tr_exprlist le (C e) sl a tmps ->
exists dst', exists sl1, exists sl2, exists a', exists tmp',
tr_expr le dst' e sl1 a' tmp'
/\ sl = sl1 ++ sl2
/\ incl tmp' tmps
/\ (forall le' e' sl3,
tr_expr le' dst' e' sl3 a' tmp' ->
(forall id, ~In id tmp' -> le'!id = le!id) ->
Csyntax.typeof e' = Csyntax.typeof e ->
tr_exprlist le' (C e') (sl3 ++ sl2) a tmps)
).