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.
(** Commutation between label resolution and compilation *)
Section FIND_LABEL.
Variable lbl: label.
Variable tyret: type.

Lemma transl_find_label:
forall s j nbrk ncnt k ts tk
(TR: transl_statement tyret nbrk ncnt s = OK ts)
(MC: match_cont j tyret nbrk ncnt k tk),
match Clight.find_label lbl s k with
| None => find_label lbl ts tk = None
| Some (s', k') =>
exists ts', exists tk', exists nbrk', exists ncnt',
find_label lbl ts tk = Some (ts', tk')
/\ transl_statement tyret nbrk' ncnt' s' = OK ts'
/\ match_cont j tyret nbrk' ncnt' k' tk'
end
with transl_find_label_ls:
forall ls j nbrk ncnt k tls tk
(TR: transl_lbl_stmt tyret nbrk ncnt ls = OK tls)
(MC: match_cont j tyret nbrk ncnt k tk),
match Clight.find_label_ls lbl ls k with
| None => find_label_ls lbl tls tk = None
| Some (s', k') =>
exists ts', exists tk', exists nbrk', exists ncnt',
find_label_ls lbl tls tk = Some (ts', tk')
/\ transl_statement tyret nbrk' ncnt' s' = OK ts'
/\ match_cont j tyret nbrk' ncnt' k' tk'
end.