(** Relating execution states *)
Inductive match_states: state -> state -> Prop :=
| match_regular_states:
forall f s k e le m tf ts tk te tle tm j lo hi tlo thi
(TRF: transf_function f = OK tf)
(TRS: simpl_stmt (cenv_for f) s = OK ts)
(MENV: match_envs j (cenv_for f) e le m lo hi te tle tlo thi)
(MCONT: match_cont j (cenv_for f) k tk m lo tlo)
(MINJ: Mem.inject j m tm)
(COMPAT: compat_cenv (addr_taken_stmt s) (cenv_for f))
(BOUND: Ple hi (Mem.nextblock m))
(TBOUND: Ple thi (Mem.nextblock tm)),
match_states (State f s k e le m)
(State tf ts tk te tle tm)
| match_call_state:
forall fd vargs k m tfd tvargs tk tm j targs tres cconv
(TRFD: transf_fundef fd = OK tfd)
(MCONT: forall cenv, match_cont j cenv k tk m (Mem.nextblock m) (Mem.nextblock tm))
(MINJ: Mem.inject j m tm)
(AINJ: Val.inject_list j vargs tvargs)
(FUNTY: type_of_fundef fd = Tfunction targs tres cconv)
(ANORM: val_casted_list vargs targs),
match_states (Callstate fd vargs k m)
(Callstate tfd tvargs tk tm)
| match_return_state:
forall v k m tv tk tm j
(MCONT: forall cenv, match_cont j cenv k tk m (Mem.nextblock m) (Mem.nextblock tm))
(MINJ: Mem.inject j m tm)
(RINJ: Val.inject j v tv),
match_states (Returnstate v k m)
(Returnstate tv tk tm).
(** The simulation diagrams *)
Remark is_liftable_var_charact:
forall cenv a,
match is_liftable_var cenv a with
| Some id => exists ty, a = Evar id ty /\ VSet.mem id cenv = true
| None => match a with Evar id ty => VSet.mem id cenv = false | _ => True end
end.
Remark simpl_select_switch:
forall cenv n ls tls,
simpl_lblstmt cenv ls = OK tls ->
simpl_lblstmt cenv (select_switch n ls) = OK (select_switch n tls).
Remark simpl_seq_of_labeled_statement:
forall cenv ls tls,
simpl_lblstmt cenv ls = OK tls ->
simpl_stmt cenv (seq_of_labeled_statement ls) = OK (seq_of_labeled_statement tls).
Remark compat_cenv_select_switch:
forall cenv n ls,
compat_cenv (addr_taken_lblstmt ls) cenv ->
compat_cenv (addr_taken_lblstmt (select_switch n ls)) cenv.
Remark addr_taken_seq_of_labeled_statement:
forall ls, addr_taken_stmt (seq_of_labeled_statement ls) = addr_taken_lblstmt ls.
Section FIND_LABEL.
Variable f: meminj.
Variable cenv: compilenv.
Variable m: mem.
Variables bound tbound: block.
Variable lbl: ident.

Lemma simpl_find_label:
forall s k ts tk,
simpl_stmt cenv s = OK ts ->
match_cont f cenv k tk m bound tbound ->
compat_cenv (addr_taken_stmt s) cenv ->
match find_label lbl s k with
| None =>
find_label lbl ts tk = None
| Some(s', k') =>
exists ts', exists tk',
find_label lbl ts tk = Some(ts', tk')
/\ compat_cenv (addr_taken_stmt s') cenv
/\ simpl_stmt cenv s' = OK ts'
/\ match_cont f cenv k' tk' m bound tbound
end
with simpl_find_label_ls:
forall ls k tls tk,
simpl_lblstmt cenv ls = OK tls ->
match_cont f cenv k tk m bound tbound ->
compat_cenv (addr_taken_lblstmt ls) cenv ->
match find_label_ls lbl ls k with
| None =>
find_label_ls lbl tls tk = None
| Some(s', k') =>
exists ts', exists tk',
find_label_ls lbl tls tk = Some(ts', tk')
/\ compat_cenv (addr_taken_stmt s') cenv
/\ simpl_stmt cenv s' = OK ts'
/\ match_cont f cenv k' tk' m bound tbound
end.