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.

(* Specifications: *)
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'.
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'.
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'.
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' .
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'.
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'.
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'.
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'.
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'.
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'.
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'.
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'.
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.
Lemma MS_step_case_InternalCall: forall cenv f j m tm e cs k tk vargs targs x m1 lenv (Param1: list_norepet (map fst (Csharpminor.fn_vars f))) (Param2 : list_norepet (Csharpminor.fn_params f)) (Param3 : list_disjoint (Csharpminor.fn_params f) (fn_temps f)) (AlocVars : alloc_variables empty_env m (Csharpminor.fn_vars f) e m1) (BindParams: bind_parameters (Csharpminor.fn_params f) vargs (create_undef_temps (fn_temps f)) = Some lenv) (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 vargs targs) (EQ : transl_function f = OK x) (*NEW:*) (PG: meminj_preserves_globals ge j), exists (c2' : CMin_core) (m2' : mem), corestep_plus CMin_core_sem tge (CMin_Callstate (AST.Internal x) targs tk) tm c2' m2' /\ exists (j' : meminj), inject_incr j j' /\ inject_separated j j' m tm /\ match_cores (CSharpMin_State f (Csharpminor.fn_body f) k e lenv) j' (CSharpMin_State f (Csharpminor.fn_body f) k e lenv) m1 c2' m2'.
Lemma MS_step_case_Return: forall j m tm cs f e lenv k tk cenv v tv optid (MINJ : Mem.inject j m tm) (MCS : match_callstack prog j m tm cs (Mem.nextblock m) (Mem.nextblock tm)) (MK : match_cont (Csharpminor.Kcall optid f e lenv k) tk cenv nil cs) (RESINJ : val_inject j v tv) (*NEW:*) (PG: meminj_preserves_globals ge j), exists c2' : CMin_core, exists m2' : mem, corestep_plus CMin_core_sem tge (CMin_Returnstate tv tk) tm c2' m2' /\ match_cores (CSharpMin_State f Csharpminor.Sskip k e (set_optvar optid v lenv)) j (CSharpMin_State f Csharpminor.Sskip k e (set_optvar optid v lenv)) m c2' m2' .
Lemma MS_step: forall (c1 : core_data) (m1 : mem) (c1' : core_data) (m1' : mem), corestep CSharpMin_core_sem ge c1 m1 c1' m1' -> forall (c2 : CMin_core) (m2 : mem) (j : meminj), match_cores c1 j c1 m1 c2 m2 -> (exists c2' : CMin_core, exists m2' : mem, exists j' : meminj, inject_incr j j' /\ Events.inject_separated j j' m1 m2 /\ corestep_plus CMin_core_sem tge c2 m2 c2' m2' /\ match_cores c1' j' c1' m1' c2' m2') \/ (MC_measure c1' < MC_measure c1)%nat /\ match_cores c1' j c1' m1' c2 m2.
Theorem transl_program_correct: forall (R: list_norepet (map fst (prog_defs prog))) 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) (init_mem: exists m0, Genv.init_mem prog = Some m0), Forward_simulation_inj.Forward_simulation_inject CSharpMin_core_sem CMin_core_sem ge tge entrypoints.
Lemma MS_step_coopsem: forall (c1 : core_data) (m1 : mem) (c1' : core_data) (m1' : mem), corestep csharpmin_coop_sem ge c1 m1 c1' m1' -> forall (c2 : CMin_core) (m2 : mem) (j : meminj), match_cores c1 j c1 m1 c2 m2 -> (exists c2' : CMin_core, exists m2' : mem, exists j' : meminj, inject_incr j j' /\ Events.inject_separated j j' m1 m2 /\ corestep_plus cmin_coop_sem tge c2 m2 c2' m2' /\ match_cores c1' j' c1' m1' c2' m2') \/ (MC_measure c1' < MC_measure c1)%nat /\ match_cores c1' j c1' m1' c2 m2.
Theorem transl_program_correct_coopsem: forall (R: list_norepet (map fst (prog_defs prog))) 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) (init_mem: exists m0, Genv.init_mem prog = Some m0), Forward_simulation_inj.Forward_simulation_inject csharpmin_coop_sem cmin_coop_sem ge tge entrypoints.