Inductive match_states (j:meminj) : CL_core -> mem -> CSharpMin_core -> mem -> Prop :=
  | match_state:
      forall f nbrk ncnt s k e le m tf ts tk te tle ts' tk' tm
          (TRF: transl_function f = OK tf)
          (TR: transl_statement (Clight.fn_return f) nbrk ncnt s = OK ts)
          (MTR: match_transl ts tk ts' tk')
          (MENV: match_env j e te)
          (TENV: match_tempenv j le tle)
          (MK: match_cont j (Clight.fn_return f) nbrk ncnt k tk),
      match_states j (CL_State f s k e le) m
                   (CSharpMin_State tf ts' tk' te tle) tm
  | match_callstate:
      forall fd args1 k m tfd tk targs tres tm args2
          (TR: transl_fundef fd = OK tfd)
          (MK: match_cont j Tvoid 0%nat 0%nat k tk)
          (ISCC: Clight.is_call_cont k)
          (TY: type_of_fundef fd = Tfunction targs tres)
           (ArgsInj: val_list_inject j args1 args2),
      match_states j (CL_Callstate fd args1 k) m
                   (CSharpMin_Callstate tfd args2 tk) tm
  | match_returnstate:
      forall res1 res2 k m tk tm
          (MK: match_cont j Tvoid 0%nat 0%nat k tk)
          (Vinj: val_inject j res1 res2),
      match_states j (CL_Returnstate res1 k) m
                   (CSharpMin_Returnstate res2 tk) tm.Inductive match_states (j:meminj) : CL_core -> mem -> CSharpMin_core -> mem -> Prop :=
  | match_state:
      forall f nbrk ncnt s k e le m tf ts tk te tle ts' tk' tm
          (TRF: transl_function f = OK tf)
          (TR: transl_statement (Clight.fn_return f) nbrk ncnt s = OK ts)
          (MTR: match_transl ts tk ts' tk')
          (MENV: match_env j e te)
          (TENV: match_tempenv j le tle)
          (MK: match_cont j (Clight.fn_return f) nbrk ncnt k tk),
      match_states j (CL_State f s k e le) m
                   (CSharpMin_State tf ts' tk' te tle) tm
  | match_callstate:
      forall fd args1 k m tfd tk targs tres tm args2
          (TR: transl_fundef fd = OK tfd)
          (MK: match_cont j Tvoid 0%nat 0%nat k tk)
          (ISCC: Clight.is_call_cont k)
          (TY: type_of_fundef fd = Tfunction targs tres)
           (ArgsInj: val_list_inject j args1 args2),
      match_states j (CL_Callstate fd args1 k) m
                   (CSharpMin_Callstate tfd args2 tk) tm
  | match_returnstate:
      forall res1 res2 k m tk tm
          (MK: match_cont j Tvoid 0%nat 0%nat k tk)
          (Vinj: val_inject j res1 res2),
      match_states j (CL_Returnstate res1 k) m
                   (CSharpMin_Returnstate res2 tk) tm.Inductive match_states (j:meminj) : CL_core -> mem -> CSharpMin_core -> mem -> Prop :=
  | match_state:
      forall f nbrk ncnt s k e le m tf ts tk te tle ts' tk' tm
          (TRF: transl_function f = OK tf)
          (TR: transl_statement (Clight.fn_return f) nbrk ncnt s = OK ts)
          (MTR: match_transl ts tk ts' tk')
          (MENV: match_env j e te)
          (TENV: match_tempenv j le tle)
          (MK: match_cont j (Clight.fn_return f) nbrk ncnt k tk),
      match_states j (CL_State f s k e le) m
                   (CSharpMin_State tf ts' tk' te tle) tm
  | match_callstate:
      forall fd args1 k m tfd tk targs tres tm args2
          (TR: transl_fundef fd = OK tfd)
          (MK: match_cont j Tvoid 0%nat 0%nat k tk)
          (ISCC: Clight.is_call_cont k)
          (TY: type_of_fundef fd = Tfunction targs tres)
           (ArgsInj: val_list_inject j args1 args2),
      match_states j (CL_Callstate fd args1 k) m
                   (CSharpMin_Callstate tfd args2 tk) tm
  | match_returnstate:
      forall res1 res2 k m tk tm
          (MK: match_cont j Tvoid 0%nat 0%nat k tk)
          (Vinj: val_inject j res1 res2),
      match_states j (CL_Returnstate res1 k) m
                   (CSharpMin_Returnstate res2 tk) tm.Inductive match_states (j:meminj) : CL_core -> mem -> CSharpMin_core -> mem -> Prop :=
  | match_state:
      forall f nbrk ncnt s k e le m tf ts tk te tle ts' tk' tm
          (TRF: transl_function f = OK tf)
          (TR: transl_statement (Clight.fn_return f) nbrk ncnt s = OK ts)
          (MTR: match_transl ts tk ts' tk')
          (MENV: match_env j e te)
          (TENV: match_tempenv j le tle)
          (MK: match_cont j (Clight.fn_return f) nbrk ncnt k tk),
      match_states j (CL_State f s k e le) m
                   (CSharpMin_State tf ts' tk' te tle) tm
  | match_callstate:
      forall fd args1 k m tfd tk targs tres tm args2
          (TR: transl_fundef fd = OK tfd)
          (MK: match_cont j Tvoid 0%nat 0%nat k tk)
          (ISCC: Clight.is_call_cont k)
          (TY: type_of_fundef fd = Tfunction targs tres)
           (ArgsInj: val_list_inject j args1 args2),
      match_states j (CL_Callstate fd args1 k) m
                   (CSharpMin_Callstate tfd args2 tk) tm
  | match_returnstate:
      forall res1 res2 k m tk tm
          (MK: match_cont j Tvoid 0%nat 0%nat k tk)
          (Vinj: val_inject j res1 res2),
      match_states j (CL_Returnstate res1 k) m
                   (CSharpMin_Returnstate res2 tk) tm.Remark match_states_skip:
  forall j f e le te tle nbrk ncnt k tf tk m tm,
  transl_function f = OK tf ->
  match_env j e te ->
  match_tempenv j le tle ->
  match_cont j (Clight.fn_return f) nbrk ncnt k tk ->
  match_states j (CL_State f Clight.Sskip k e le) m (CSharpMin_State tf Sskip tk te tle) tm.

Lemma assign_loc_inject: forall ty m1 b1 ofs v m1' R (ASS: assign_loc ty m1 b1 ofs v m1') j v2 (V:val_inject (restrict j R) v v2) b2 delta (J: restrict j R b1 = Some(b2,delta)) m2 (MInj: Mem.inject j m1 m2), exists m2', assign_loc ty m2 b2 (Int.add ofs (Int.repr delta)) v2 m2' /\ Mem.inject j m1' m2'.