Section TRANSLATION.
Variable prog: Csharpminor.program.
Variable tprog: Cminor.program.
Hypothesis TRANSL: transl_program prog = OK tprog.
Let ge : Csharpminor.genv := Genv.globalenv prog.
(*Let gce : compilenv := build_global_compilenv prog.*)
Let tge: genv := Genv.globalenv tprog.
Let core_data := CSharpMin_core.
(*Lenb -- meminj_preserves_globales is new, and needed since this property is now required by the simulation realtions, rather than only at/efterexternal clauses*)
Inductive match_cores: core_data -> meminj -> CSharpMin_core -> mem -> CMin_core -> mem -> Prop :=
| MC_states:
forall d fn s k e le m tfn ts tk sp te tm cenv xenv j lo hi cs sz
(TRF: transl_funbody cenv sz fn = OK tfn)
(TR: transl_stmt cenv xenv s = OK ts)
(MINJ: Mem.inject j m tm)
(MCS: match_callstack prog j m tm
(Frame cenv tfn e le te sp lo hi :: cs)
(Mem.nextblock m) (Mem.nextblock tm))
(MK: match_cont k tk  cenv xenv cs)
(PG: meminj_preserves_globals ge j),
match_cores d j (CSharpMin_State fn s k e le) m
(CMin_State tfn ts tk (Vptr sp Int.zero) te) tm
| MC_state_seq:
forall d fn s1 s2 k e le m tfn ts1 tk sp te tm cenv xenv j lo hi cs sz
(TRF: transl_funbody cenv sz fn = OK tfn)
(TR: transl_stmt cenv xenv s1 = OK ts1)
(MINJ: Mem.inject j m tm)
(MCS: match_callstack prog j m tm
(Frame cenv tfn e le te sp lo hi :: cs)
(Mem.nextblock m) (Mem.nextblock tm))
(MK: match_cont (Csharpminor.Kseq s2 k) tk cenv xenv cs)
(PG: meminj_preserves_globals ge j),
match_cores d j (CSharpMin_State fn (Csharpminor.Sseq s1 s2) k e le) m
(CMin_State tfn ts1 tk (Vptr sp Int.zero) te) tm
| MC_callstate:
forall d fd args k m tfd targs tk tm j cs cenv
(TR: transl_fundef fd = OK tfd)
(MINJ: Mem.inject j m tm)
(MCS: match_callstack prog j m tm cs (Mem.nextblock m) (Mem.nextblock tm))
(MK: match_cont k tk cenv nil cs)
(ISCC: Csharpminor.is_call_cont k)
(ARGSINJ: val_list_inject j args targs)
(PG: meminj_preserves_globals ge j),
match_cores d j (CSharpMin_Callstate fd args k) m
(CMin_Callstate tfd targs tk) tm
| MC_returnstate:
forall d v k m tv tk tm j cs cenv
(MINJ: Mem.inject j m tm)
(MCS: match_callstack prog j m tm cs (Mem.nextblock m) (Mem.nextblock tm))
(MK: match_cont k tk cenv nil cs)
(RESINJ: val_inject j v tv)
(PG: meminj_preserves_globals ge j),
match_cores d j (CSharpMin_Returnstate v k) m
(CMin_Returnstate tv tk) tm.
(*--------------------------------------------------------------------*)
(****************The following three conditions are new******************)
(****************The following three conditions are new******************)
(* In the third clause, we now stepfrom  m' to m, and also from f' to f and from tm' to tm******************)
(***** All the additional conditions in the above auxiliary lemmas were needed for proving the condition Events.inject_separated j j' m tm in his lemma; otherwise, the claim is as before, just updated by replacing star step by corestep_star, as ususal*)

Theorem MS_match_callstack_function_entry:
forall fn cenv tf m e m' tm tm' sp f cs args targs le,
build_compilenv fn = (cenv, tf.(fn_stackspace)) ->
tf.(fn_stackspace) <= Int.max_unsigned ->
list_norepet (map fst (Csharpminor.fn_vars fn)) ->
list_norepet (Csharpminor.fn_params fn) ->
list_disjoint (Csharpminor.fn_params fn) (Csharpminor.fn_temps fn) ->
alloc_variables Csharpminor.empty_env m (Csharpminor.fn_vars fn) e m' ->
bind_parameters (Csharpminor.fn_params fn) args (create_undef_temps fn.(fn_temps)) = Some le ->
val_list_inject f args targs ->
Mem.alloc tm 0 tf.(fn_stackspace) = (tm', sp) ->
match_callstack prog f m tm cs (Mem.nextblock m) (Mem.nextblock tm) ->
Mem.inject f m tm ->
let te := set_locals (Csharpminor.fn_temps fn) (set_params targs (Csharpminor.fn_params fn)) in
exists f',
match_callstack prog f' m' tm'
(Frame cenv tf e le te sp (Mem.nextblock m) (Mem.nextblock m') :: cs)
(Mem.nextblock m') (Mem.nextblock tm')
/\ Mem.inject f' m' tm'
/\ (*LENB: this clause is new in Restructured Proof*) inject_incr f f'
/\ (*LENB this clause in new in coop-sim proof*) inject_separated f f' m tm.