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 varinfo_preserved: forall b, (exists gv : globvar type, Genv.find_var_info ge b = Some gv) <-> (exists gv : globvar unit, Genv.find_var_info tge b = Some gv).