(*--------------------------------------------------------------------*)

(* Specifications: *)
Lemma init_cores: forall (v1 v2 : val) (sig : signature) entrypoints
(EP: In (v1, v2, sig) entrypoints)
(entry_points_ok :
forall v1 v2 sig,
In (v1, v2, sig) entrypoints ->
exists b f1 f2,
v1 = Vptr b Int.zero
/\ v2 = Vptr b Int.zero
/\ Genv.find_funct_ptr ge b = Some f1
/\ Genv.find_funct_ptr tge b = Some f2)
(vals1 : list val) (c1 : core_data) (m1 : mem) (j : meminj)
(vals2 : list val) (m2 : mem)
(CSM_Ini : initial_core CSharpMin_core_sem ge v1 vals1 = Some c1)
(Inj : Mem.inject j m1 m2)
(VI: Forall2 (val_inject j) vals1 vals2)
(PG: meminj_preserves_globals ge j)
(R: list_norepet (map fst (prog_defs prog)))
(INIT_MEM: exists m0, Genv.init_mem prog = Some m0
/\ Ple (Mem.nextblock m0) (Mem.nextblock m1)
/\ Ple (Mem.nextblock m0) (Mem.nextblock m2)),
exists c2 : CMin_core,
initial_core CMin_core_sem tge v2 vals2 = Some c2 /\
match_cores c1 j c1 m1 c2 m2.
Lemma MC_safely_halted: forall (cd : core_data) (j : meminj) (c1 : CSharpMin_core) (m1 : mem)
(c2 : CMin_core) (m2 : mem) (v1 : val),
match_cores cd j c1 m1 c2 m2 ->
halted CSharpMin_core_sem  c1 = Some v1 ->
exists v2,
halted CMin_core_sem c2 = Some v2 /\ Mem.inject j m1 m2 /\
val_inject j v1 v2.
Lemma MC_at_external: forall (cd : core_data) (j : meminj) (st1 : CSharpMin_core) (m1 : mem)
(st2 : CMin_core) (m2 : mem) (e : external_function) (vals1 : list val) sig,
(cd = st1 /\ match_cores cd j st1 m1 st2 m2) ->
at_external CSharpMin_core_sem st1 = Some (e, sig, vals1) ->
Mem.inject j m1 m2 /\
Events.meminj_preserves_globals ge j /\
(exists vals2 : list val,
Forall2 (val_inject j) vals1 vals2 /\
at_external CMin_core_sem st2 = Some (e, sig, vals2)).
Lemma MC_after_external:forall (d : core_data) (j j' : meminj) (st1 : core_data) (st2 : CMin_core)
(m1 : mem) (e : external_function) (vals1 : list val) (ret1 : val)
(m1' m2 m2' : mem) (ret2 : val) (sig : signature),
d = st1 /\ match_cores d j st1 m1 st2 m2 ->
at_external CSharpMin_core_sem st1 = Some (e, sig, vals1) ->
Events.meminj_preserves_globals ge j ->
inject_incr j j' ->
Events.inject_separated j j' m1 m2 ->
Mem.inject j' m1' m2' ->
val_inject j' ret1 ret2 ->
mem_forward m1 m1' ->
Mem.unchanged_on (Events.loc_unmapped j) m1 m1' ->
mem_forward m2 m2' ->
Mem.unchanged_on (Events.loc_out_of_reach j m1) m2 m2' ->
exists st1' : core_data,
exists st2' : CMin_core,
exists d' : core_data,
after_external CSharpMin_core_sem (Some ret1) st1 = Some st1' /\
after_external CMin_core_sem (Some ret2) st2 = Some st2' /\
d' = st1' /\ match_cores d' j' st1' m1' st2' m2'.
Lemma MC_MSI: forall d j
q m q' m',
match_cores d j q m q' m' ->
match_statesInj prog j  (ToState q m) (Cminor_coop.ToState q' m').
Lemma MSI_MC: forall j q m q' m' d
(*NEW:*) (PG: meminj_preserves_globals ge j), match_statesInj prog j (ToState q m) (Cminor_coop.ToState q' m') -> match_cores d j q m q' m'.  Lemma MSI_atExt: forall j c1 m1 c2 m2 (H: match_statesInj prog j (ToState c1 m1) (Cminor_coop.ToState c2 m2) ), (CSharpMin_at_external c1 = None) = (CMin_at_external c2 = None).  Parameter MC_order :  core_data -> core_data -> Prop. Parameter MC_wellfounded: well_founded MC_order. Definition MC_measure (q:CSharpMin_core): nat := match q with | CSharpMin_State fn s k e lenv => seq_left_depth s | _ => O end. (*Parameter MC_measure: CSharpMin_core-> nat.*)
Lemma MS_step_case_SkipSeq:
forall cenv sz f tfn j m tm  e lenv te sp lo hi cs s k tk xenv
(TRF : transl_funbody cenv sz f = OK tfn)
(MINJ : Mem.inject j m tm)
(MK : match_cont (Csharpminor.Kseq s k) tk cenv xenv cs)
(MCS : match_callstack prog j m tm (Frame cenv tfn e lenv te sp lo hi :: cs)
(Mem.nextblock m) (Mem.nextblock tm))
(*NEW:*) (PG: meminj_preserves_globals ge j), exists c2' : CMin_core, exists m2' : mem, corestep_plus CMin_core_sem tge (CMin_State tfn Sskip tk (Vptr sp Int.zero) te) tm c2' m2' /\ match_cores (CSharpMin_State f s k e lenv) j (CSharpMin_State f s k e lenv) m c2' m2'. (*   exists c' : CSharpMin_core, inj_match_states_star unit match_cores MC_measure (tt,c') j (CSharpMin_State f s k e lenv) m c2' m2'.*)
Lemma MS_step_case_SkipBlock:
forall cenv sz f tfn j m tm e lenv te sp lo hi cs k tk xenv
(TRF : transl_funbody cenv sz f = OK tfn)
(MINJ : Mem.inject j m tm)
(MK : match_cont (Csharpminor.Kblock k) tk cenv xenv cs)
(MCS : match_callstack prog j m tm (Frame cenv tfn e lenv te sp lo hi :: cs)
(Mem.nextblock m) (Mem.nextblock tm))
(*NEW:*) (PG: meminj_preserves_globals ge j), exists c2' : CMin_core, exists m2' : mem, corestep_plus CMin_core_sem tge (CMin_State tfn Sskip tk (Vptr sp Int.zero) te) tm c2' m2' /\ match_cores  (CSharpMin_State f Csharpminor.Sskip k e lenv)   j (CSharpMin_State f Csharpminor.Sskip k e lenv) m c2' m2' (*exists c' : CSharpMin_core, inj_match_states_star unit match_cores MC_measure (tt,c') j (CSharpMin_State f Csharpminor.Sskip k e le) m c2' m2'*).  Lemma MS_match_is_call_cont: forall tfn te sp tm k tk cenv xenv cs, match_cont k tk cenv xenv cs -> Csharpminor.is_call_cont k -> exists tk', corestep_star CMin_core_sem tge (CMin_State tfn Sskip tk sp te) tm (CMin_State tfn Sskip tk' sp te) tm /\ is_call_cont tk' /\ match_cont k tk' cenv nil cs.  Lemma MS_step_case_SkipCall: forall cenv sz f tfn j m tm e lenv te sp lo hi cs k tk xenv m' (CC: Csharpminor.is_call_cont k) (FL: Mem.free_list m (blocks_of_env e) = Some m') (TRF : transl_funbody cenv sz f = OK tfn) (MINJ : Mem.inject j m tm) (MK : match_cont k tk cenv xenv cs) (MCS : match_callstack prog j m tm (Frame cenv tfn e lenv te sp lo hi :: cs) (Mem.nextblock m) (Mem.nextblock tm)) (*NEW:*) (PG: meminj_preserves_globals ge j), exists c2' : CMin_core, exists m2' : mem, corestep_plus CMin_core_sem tge (CMin_State  tfn Sskip tk (Vptr sp Int.zero) te) tm c2' m2' /\ match_cores  (CSharpMin_Returnstate Vundef k)  j (CSharpMin_Returnstate Vundef k) m' c2' m2'. (*exists c' : CSharpMin_core, inj_match_states_star unit match_cores MC_measure (tt,c') j (CSharpMin_Returnstate Vundef k) m' c2' m2'.*)
Lemma MS_step_case_Assign:
forall cenv sz f tfn j m tm e lenv te sp lo hi cs k tk xenv  x a x0 v id
(EE:Csharpminor.eval_expr ge e lenv m a v)
(TRF : transl_funbody cenv sz f = OK tfn)
(MINJ : Mem.inject j m tm)
(MK : match_cont k tk cenv xenv cs)
(MCS : match_callstack prog j m tm (Frame cenv tfn e lenv te sp lo hi :: cs)
(Mem.nextblock m) (Mem.nextblock tm))
(EQ : transl_expr cenv a = OK (x, x0))
*)
(*NEW:*) (PG: meminj_preserves_globals ge j), exists c2' : CMin_core, exists m2' : mem, corestep_plus CMin_core_sem tge (CMin_State tfn (Sassign id x) tk (Vptr sp Int.zero) te) tm c2' m2' /\ match_cores (CSharpMin_State f Csharpminor.Sskip k e (PTree.set id v lenv)) j (CSharpMin_State f Csharpminor.Sskip k e (PTree.set id v lenv)) m c2' m2'. (*  exists c' : CSharpMin_core, inj_match_states_star unit match_cores MC_measure (tt,c') j (CSharpMin_State f Csharpminor.Sskip k e lenv) m' c2' m2'.*)
(*no case Set in CompCert 2.0 Lemma MS_step_case_Set: forall cenv sz f tfn j m tm e lenv te sp lo hi cs k tk xenv x x0 v a id (H: Csharpminor.eval_expr ge e lenv m a v) (TRF : transl_funbody cenv sz f = OK tfn) (MINJ : Mem.inject j m tm) (MCS : match_callstack prog j m tm (Frame cenv tfn e lenv te sp lo hi :: cs) (Mem.nextblock m) (Mem.nextblock tm)) (MK : match_cont k tk (fn_return f) cenv xenv cs) (EQ : transl_expr cenv a = OK (x, x0)), exists c2' : CMin_core, exists m2' : mem, corestep_plus CMin_core_sem tge (CMin_State  tfn (Sassign (for_temp id) x) tk (Vptr sp Int.zero) te) tm c2' m2' /\ match_cores (CSharpMin_State f Csharpminor.Sskip k e (PTree.set id v lenv)) j (CSharpMin_State f Csharpminor.Sskip k e (PTree.set id v lenv)) m c2' m2' . (*  exists c' : CSharpMin_core, inj_match_states_star unit match_cores MC_measure (tt,c') j (CSharpMin_State f Csharpminor.Sskip k e (PTree.set id v lenv)) m c2' m2' .*)
Lemma MS_step_case_Store:
forall cenv sz f tfn j m tm e lenv te sp lo hi cs k tk xenv x x0 x1 x2
chunk m' a addr vaddr v
(CH: Mem.storev chunk m vaddr v = Some m')
(EvAddr : Csharpminor.eval_expr ge e lenv m addr vaddr)
(EvA : Csharpminor.eval_expr ge e lenv m a v)
(TRF : transl_funbody cenv sz f = OK tfn)
(MINJ : Mem.inject j m tm)
(MCS : match_callstack prog j m tm (Frame cenv tfn e lenv te sp lo hi :: cs)
(Mem.nextblock m) (Mem.nextblock tm))
(MK : match_cont k tk cenv xenv cs)
(EQ : transl_expr cenv addr = OK (x, x0))
(EQ1 : transl_expr cenv a = OK (x1, x2))
(*NEW:*) (PG: meminj_preserves_globals ge j), exists c2' : CMin_core, exists m2' : mem, corestep_plus CMin_core_sem tge (CMin_State  tfn (make_store chunk x x1) tk (Vptr sp Int.zero) te) tm c2' m2' /\ match_cores (CSharpMin_State f Csharpminor.Sskip k e lenv) j (CSharpMin_State f Csharpminor.Sskip k e lenv) m' c2' m2' . (* exists c' : CSharpMin_core, inj_match_states_star unit match_cores MC_measure (tt,c') j (CSharpMin_State f Csharpminor.Sskip k e lenv) m' c2' m2' .*)
Lemma MS_step_case_Call:
forall cenv sz f tfn j m tm e lenv te sp lo hi cs k tk xenv  x x0 x1 a vf fd optid vargs bl
(EvalA: Csharpminor.eval_expr ge e lenv m a vf)
(EvalBL: Csharpminor.eval_exprlist ge e lenv m bl vargs)
(FF: Genv.find_funct ge vf = Some fd)
(TRF : transl_funbody cenv sz f = OK tfn)
(MINJ : Mem.inject j m tm)
(MCS : match_callstack prog j m tm (Frame cenv tfn e lenv te sp lo hi :: cs)
(Mem.nextblock m) (Mem.nextblock tm))
(MK : match_cont tk k cenv xenv cs)
(EQ : transl_expr cenv a = OK (x, x0))
(EQ1 : transl_exprlist cenv bl = OK x1)
(*NEW:*) (PG: meminj_preserves_globals ge j), exists c2' : CMin_core, exists m2' : mem, corestep_plus CMin_core_sem tge (CMin_State  tfn (Scall optid (Csharpminor.funsig fd) x x1)  k (Vptr sp Int.zero) te) tm c2' m2' /\ match_cores (CSharpMin_Callstate fd vargs (Csharpminor.Kcall optid f e lenv tk))  j (CSharpMin_Callstate fd vargs (Csharpminor.Kcall optid f e lenv tk)) m c2' m2'. (* exists c' : CSharpMin_core, inj_match_states_star unit match_cores MC_measure (tt,c') j (CSharpMin_Callstate fd vargs (Csharpminor.Kcall optid f e lenv tk)) m c2' m2'.*)
Lemma MS_step_case_Builtin:
forall cenv sz f tfn j m tm e lenv te sp lo hi cs k tk xenv x t ef optid vres m' bl vargs
(EvalArgs: Csharpminor.eval_exprlist ge e lenv m bl vargs)
(ExtCall: Events.external_call ef ge vargs m t vres m')
(TRF : transl_funbody cenv sz f = OK tfn)
(MINJ : Mem.inject j m tm)
(MCS : match_callstack prog j m tm (Frame cenv tfn e lenv te sp lo hi :: cs)
(Mem.nextblock m) (Mem.nextblock tm))
(MK : match_cont k tk cenv xenv cs)
(EQ : transl_exprlist cenv bl = OK x)
(*NEW:*) (PG: meminj_preserves_globals ge j), exists c2' : CMin_core, exists m2' : mem, corestep_plus CMin_core_sem tge (CMin_State tfn (Sbuiltin optid ef x) tk (Vptr sp Int.zero) te) tm c2' m2' /\ exists j' : meminj, inject_incr j j' /\ Events.inject_separated j j' m tm /\ match_cores (CSharpMin_State f Csharpminor.Sskip k e (set_optvar optid vres lenv))  j' (CSharpMin_State f Csharpminor.Sskip k e (set_optvar optid vres lenv)) m' c2' m2'. (*  exists c', inj_match_states_star unit match_cores MC_measure (tt,c') j' (CSharpMin_State f Csharpminor.Sskip k e (set_optvar optid vres lenv)) m' c2' m2'.*)
Lemma MS_step_case_Ite:
forall cenv sz f tfn j m tm e lenv te sp lo hi cs k tk xenv x x0 x1 x2 b v a s1 s2
(H : Csharpminor.eval_expr ge e lenv m a v)
(BoolOfVal : Val.bool_of_val v b)
(TRF : transl_funbody cenv sz f = OK tfn)
(MINJ : Mem.inject j m tm)
(MCS : match_callstack prog j m tm (Frame cenv tfn e lenv te sp lo hi :: cs)
(Mem.nextblock m) (Mem.nextblock tm))
(MK : match_cont k tk cenv xenv cs)
(EQ : transl_expr cenv a = OK (x, x0))
(EQ1 : transl_stmt cenv xenv s1 = OK x1)
(EQ0 : transl_stmt cenv xenv s2 = OK x2)
(*NEW:*) (PG: meminj_preserves_globals ge j), exists c2' : CMin_core, exists m2' : mem, corestep_plus CMin_core_sem tge (CMin_State tfn (Sifthenelse x x1 x2) tk (Vptr sp Int.zero) te) tm c2' m2' /\ match_cores  (CSharpMin_State f (if b then s1 else s2) k e lenv)  j (CSharpMin_State f (if b then s1 else s2) k e lenv) m c2' m2'. (*  exists c', inj_match_states_star unit match_cores MC_measure (tt,c') j (CSharpMin_State f (if b then s1 else s2) k e lenv) m c2' m2'.*)
Lemma MS_step_case_Loop:
forall cenv sz f tfn j m tm e lenv te sp lo hi cs k tk xenv x s
(TRF : transl_funbody cenv sz f = OK tfn)
(MINJ : Mem.inject j m tm)
(MCS : match_callstack prog j m tm (Frame cenv tfn e lenv te sp lo hi :: cs)
(Mem.nextblock m) (Mem.nextblock tm))
(MK : match_cont tk k cenv xenv cs)
(EQ : transl_stmt cenv xenv s = OK x)
(*NEW:*) (PG: meminj_preserves_globals ge j), exists c2' : CMin_core, exists m2' : mem, corestep_plus CMin_core_sem tge (CMin_State tfn (Sloop x) k (Vptr sp Int.zero) te) tm c2' m2' /\ match_cores  (CSharpMin_State f s (Csharpminor.Kseq (Csharpminor.Sloop s) tk) e lenv)  j (CSharpMin_State f s (Csharpminor.Kseq (Csharpminor.Sloop s) tk) e lenv) m c2' m2'. (*    exists c',   inj_match_states_star unit match_cores MC_measure (tt,c') j (CSharpMin_State f s (Csharpminor.Kseq (Csharpminor.Sloop s) tk) e lenv) m c2' m2'. *)
Lemma MS_step_case_Block:
forall cenv sz f tfn j m tm e lenv te sp lo hi cs k tk xenv x s
(TRF : transl_funbody cenv sz f = OK tfn)
(MINJ : Mem.inject j m tm)
(MCS : match_callstack prog j m tm (Frame cenv tfn e lenv te sp lo hi :: cs)
(Mem.nextblock m) (Mem.nextblock tm))
(MK : match_cont tk k cenv xenv cs)
(EQ : transl_stmt cenv (true :: xenv) s = OK x)
(*NEW:*) (PG: meminj_preserves_globals ge j), exists c2' : CMin_core, exists m2' : mem, corestep_plus CMin_core_sem tge (CMin_State tfn (Sblock x) k (Vptr sp Int.zero) te) tm c2' m2' /\ match_cores (CSharpMin_State f s (Csharpminor.Kblock tk) e lenv) j (CSharpMin_State f s (Csharpminor.Kblock tk) e lenv) m c2' m2'. (*    exists c' , inj_match_states_star unit match_cores MC_measure (tt,c') j (CSharpMin_State f s (Csharpminor.Kblock tk) e lenv) m c2' m2'.*)
Lemma MS_step_case_ExitSeq:
forall  cenv sz f tfn j m tm e lenv te sp lo hi cs k tk xenv n s
(TRF : transl_funbody cenv sz f = OK tfn)
(MINJ : Mem.inject j m tm)
(MCS : match_callstack prog j m tm (Frame cenv tfn e lenv te sp lo hi :: cs)
(Mem.nextblock m) (Mem.nextblock tm))
(MK : match_cont (Csharpminor.Kseq s tk) k cenv xenv cs)
(*NEW:*) (PG: meminj_preserves_globals ge j), exists c2' : CMin_core, exists m2' : mem, corestep_plus CMin_core_sem tge (CMin_State tfn (Sexit (shift_exit xenv n)) k (Vptr sp Int.zero) te) tm c2' m2'  /\ match_cores (CSharpMin_State f (Csharpminor.Sexit n) tk e lenv) j (CSharpMin_State f (Csharpminor.Sexit n) tk e lenv) m c2' m2'. (*    exists c',  inj_match_states_star unit match_cores MC_measure (tt,c') j (CSharpMin_State f (Csharpminor.Sexit n) tk e lenv) m c2' m2'.*)
Lemma MS_step_case_ExitBlockZero:
forall  cenv sz f tfn j m tm e lenv te sp lo hi cs k tk xenv
(TRF : transl_funbody cenv sz f = OK tfn)
(MINJ : Mem.inject j m tm)
(MCS : match_callstack prog j m tm (Frame cenv tfn e lenv te sp lo hi :: cs)
(Mem.nextblock m) (Mem.nextblock tm))
(MK : match_cont (Csharpminor.Kblock tk) k cenv xenv cs)
(*NEW:*) (PG: meminj_preserves_globals ge j), exists c2' : CMin_core, exists m2' : mem, corestep_plus CMin_core_sem tge (CMin_State tfn (Sexit (shift_exit xenv 0)) k (Vptr sp Int.zero) te) tm c2' m2' /\ match_cores  (CSharpMin_State f Csharpminor.Sskip tk e lenv) j (CSharpMin_State f Csharpminor.Sskip tk e lenv) m c2' m2'. (*    exists c', inj_match_states_star unit match_cores MC_measure (tt,c') j (CSharpMin_State f Csharpminor.Sskip tk e lenv) m c2' m2'.*)
Lemma MS_step_case_ExitBlockNonzero:
forall  cenv sz f tfn j m tm e lenv te sp lo hi cs k tk xenv n
(TRF : transl_funbody cenv sz f = OK tfn)
(MINJ : Mem.inject j m tm)
(MCS : match_callstack prog j m tm (Frame cenv tfn e lenv te sp lo hi :: cs)
(Mem.nextblock m) (Mem.nextblock tm))
(MK : match_cont (Csharpminor.Kblock tk) k cenv xenv cs)
(*NEW:*) (PG: meminj_preserves_globals ge j), exists c2' : CMin_core, exists m2' : mem, corestep_plus CMin_core_sem tge (CMin_State tfn (Sexit (shift_exit xenv (S n))) k (Vptr sp Int.zero) te) tm c2' m2' /\ match_cores (CSharpMin_State f (Csharpminor.Sexit n) tk e lenv)  j (CSharpMin_State f (Csharpminor.Sexit n) tk e lenv) m c2' m2'.  Lemma MS_switch_descent: forall cenv xenv k ls body s, transl_lblstmt cenv (switch_env ls xenv) ls body = OK s -> exists k', transl_lblstmt_cont cenv xenv ls k k' /\ (forall f sp e m, corestep_plus CMin_core_sem tge (CMin_State f s k sp e) m (CMin_State f body k' sp e) m).  Lemma MS_switch_ascent: forall f n sp e m cenv xenv k ls k1, let tbl := switch_table ls O in let ls' := select_switch n ls in transl_lblstmt_cont cenv xenv ls k k1 -> exists k2, corestep_star CMin_core_sem tge (CMin_State f (Sexit (Switch.switch_target n (length tbl) tbl)) k1 sp e) m (CMin_State f (Sexit O) k2 sp e) m /\ transl_lblstmt_cont cenv xenv ls' k k2.  Lemma MS_switch_MSI: forall fn k e lenv m tfn ts tk sp te tm cenv xenv j lo hi cs sz ls body tk' (TRF: transl_funbody cenv sz fn = OK tfn) (TR: transl_lblstmt cenv (switch_env ls xenv) ls body = OK ts) (MINJ: Mem.inject j m tm) (MCS: match_callstack prog j m tm (Frame cenv tfn e lenv te sp lo hi :: cs) (Mem.nextblock m) (Mem.nextblock tm)) (MK: match_cont k tk cenv xenv cs) (TK: transl_lblstmt_cont cenv xenv ls tk tk'), exists S, exists mm, corestep_plus CMin_core_sem tge (CMin_State tfn (Sexit O) tk' (Vptr sp Int.zero) te) tm S mm /\ match_statesInj prog j (Csharpminor.State fn (seq_of_lbl_stmt ls) k e lenv m) (Cminor_coop.ToState S mm).  Lemma MS_step_case_Switch: forall cenv sz f tfn j m tm e lenv te sp lo hi cs k tk xenv a x x0 ts cases n (EvalA: Csharpminor.eval_expr ge e lenv m a (Vint n)) (TRF : transl_funbody cenv sz f = OK tfn) (MINJ : Mem.inject j m tm) (MCS : match_callstack prog j m tm (Frame cenv tfn e lenv te sp lo hi :: cs) (Mem.nextblock m) (Mem.nextblock tm)) (MK : match_cont k tk cenv xenv cs) (EQ : transl_expr cenv a = OK (x, x0)) (EQ0 : transl_lblstmt cenv (switch_env cases xenv) cases (Sswitch x (switch_table cases 0) (length (switch_table cases 0))) = OK ts) (*NEW:*) (PG: meminj_preserves_globals ge j), exists c2' : CMin_core, exists m2' : mem, corestep_plus CMin_core_sem tge (CMin_State tfn ts tk (Vptr sp Int.zero) te) tm c2' m2' /\ match_cores (CSharpMin_State f (seq_of_lbl_stmt (select_switch n cases)) k e lenv)  j (CSharpMin_State f (seq_of_lbl_stmt (select_switch n cases)) k e lenv) m c2' m2'.  Lemma MS_step_case_ReturnNone: forall cenv sz f tfn j m tm e lenv te sp lo hi cs k tk xenv m' (Freelist: Mem.free_list m (blocks_of_env e) = Some m') (TRF : transl_funbody cenv sz f = OK tfn) (MINJ : Mem.inject j m tm) (MCS : match_callstack prog j m tm (Frame cenv tfn e lenv te sp lo hi :: cs) (Mem.nextblock m) (Mem.nextblock tm)) (MK : match_cont tk k cenv xenv cs) (*NEW:*) (PG: meminj_preserves_globals ge j), exists c2' : CMin_core, exists m2' : mem, corestep_plus CMin_core_sem tge (CMin_State tfn (Sreturn None) k (Vptr sp Int.zero) te) tm c2' m2'  /\ match_cores (CSharpMin_Returnstate Vundef (Csharpminor.call_cont tk))  j (CSharpMin_Returnstate Vundef (Csharpminor.call_cont tk)) m' c2' m2'.  Lemma MS_step_case_ReturnSome: forall cenv sz f tfn j m tm e lenv te sp lo hi cs k tk xenv a x x0 m' v (EvalA: Csharpminor.eval_expr ge e lenv m a v) (Freelist: Mem.free_list m (blocks_of_env e) = Some m') (TRF : transl_funbody cenv sz f = OK tfn) (MINJ : Mem.inject j m tm) (MCS : match_callstack prog j m tm (Frame cenv tfn e lenv te sp lo hi :: cs) (Mem.nextblock m) (Mem.nextblock tm)) (MK : match_cont tk k cenv xenv cs) (EQ : transl_expr cenv a = OK (x, x0)) (*NEW:*) (PG: meminj_preserves_globals ge j), exists c2' : CMin_core, exists m2' : mem, corestep_plus CMin_core_sem tge (CMin_State tfn (Sreturn (Some x)) k (Vptr sp Int.zero) te) tm c2' m2' /\ match_cores  (CSharpMin_Returnstate v (Csharpminor.call_cont tk)) j (CSharpMin_Returnstate v (Csharpminor.call_cont tk)) m' c2' m2'.  Lemma MS_step_case_Label: forall cenv sz f tfn j m tm e lenv te sp lo hi cs k tk xenv lbl x s (TRF : transl_funbody cenv sz f = OK tfn) (MINJ : Mem.inject j m tm) (MCS : match_callstack prog j m tm (Frame cenv tfn e lenv te sp lo hi :: cs) (Mem.nextblock m) (Mem.nextblock tm)) (MK : match_cont k tk cenv xenv cs) (EQ : transl_stmt cenv xenv s = OK x) (*NEW:*) (PG: meminj_preserves_globals ge j), exists c2' : CMin_core, exists m2' : mem, corestep_plus CMin_core_sem tge (CMin_State tfn (Slabel lbl x) tk (Vptr sp Int.zero) te) tm c2' m2' /\ match_cores (CSharpMin_State f s k e lenv)  j (CSharpMin_State f s k e lenv) m c2' m2'.  Lemma MS_step_case_Goto: forall cenv sz f tfn j m tm e lenv te sp lo hi cs k tk xenv lbl s' k' (FindLab: Csharpminor.find_label lbl (Csharpminor.fn_body f) (Csharpminor.call_cont k) = Some (s', k')) (TRF : transl_funbody cenv sz f = OK tfn) (MINJ : Mem.inject j m tm) (MCS : match_callstack prog j m tm (Frame cenv tfn e lenv te sp lo hi :: cs) (Mem.nextblock m) (Mem.nextblock tm)) (MK : match_cont k tk cenv xenv cs) (*NEW:*) (PG: meminj_preserves_globals ge j), exists c2' : CMin_core, exists m2' : mem, corestep_plus CMin_core_sem tge (CMin_State tfn (Sgoto lbl) tk (Vptr sp Int.zero) te) tm c2' m2' /\ match_cores  (CSharpMin_State f s' k' e lenv) j (CSharpMin_State f s' k' e lenv) m c2' m2'.  (******************************Functions required for internal call rule*****************************)
(****These extend the original lemmas by additional guarantees of the (now exposed) memory injections, in order for the overall lemma for internal calls to establish the inject_separated fact******************************)
Lemma MS_match_callstack_alloc_variables_rec:
forall tm sp tf cenv le te lo cs,
Mem.valid_block tm sp ->
fn_stackspace tf <= Int.max_unsigned ->
(forall ofs k p, Mem.perm tm sp ofs k p -> 0 <= ofs < fn_stackspace tf) ->
(forall ofs k p, 0 <= ofs < fn_stackspace tf -> Mem.perm tm sp ofs k p) ->
forall e1 m1 vars e2 m2,
alloc_variables e1 m1 vars e2 m2 ->
forall f1,
list_norepet (map fst vars) ->
cenv_compat cenv vars (fn_stackspace tf) ->
cenv_separated cenv vars ->
cenv_mem_separated cenv vars f1 sp m1 ->
(forall id sz, In (id, sz) vars -> e1!id = None) ->
match_callstack prog f1 m1 tm
(Frame (cenv_remove cenv vars) tf e1 le te sp lo (Mem.nextblock m1) :: cs)
(Mem.nextblock m1) (Mem.nextblock tm) ->
Mem.inject f1 m1 tm ->
exists f2,
match_callstack prog f2 m2 tm
(Frame cenv tf e2 le te sp lo (Mem.nextblock m2) :: cs)
(Mem.nextblock m2) (Mem.nextblock tm)
/\ Mem.inject f2 m2 tm
/\ (*LENB: THIS IS NEW*) inject_incr f1 f2
/\ (forall b, Mem.valid_block m1 b -> f2 b = f1 b)
/\ (forall b b' d', f1 b = None -> f2 b = Some (b',d') -> b' = sp)
/\ forall j',  inject_incr f2 j' -> inject_separated f2 j' m2 tm ->
inject_separated f2 j' m1 tm.