(** The proof of semantic preservation is a simulation argument based on "option" diagrams of the following form: << n st1 --------------- st2 |                   | t|                   |t or (? and n' < n) |                   | v                   v st1'--------------- st2' n' >> The left vertical arrow represents a transition in the original RTL code.  The top horizontal bar is the [match_states] invariant between the initial state [st1] in the original RTL code and an initial state [st2] in the transformed code. This invariant expresses that all code fragments appearing in [st2] are obtained by [transf_code] transformation of the corresponding fragments in [st1].  Moreover, the state [st1] must match its compile-time approximations at the current program point. These two parts of the diagram are the hypotheses.  In conclusions, we want to prove the other two parts: the right vertical arrow, which is a transition in the transformed RTL code, and the bottom horizontal bar, which means that the [match_state] predicate holds between the final states [st1'] and [st2']. *)
Inductive match_stackframes: stackframe -> stackframe -> Prop :=
match_stackframe_intro:
forall res sp pc rs f rs' cu,
linkorder cu prog ->
regs_lessdef rs rs' ->
match_stackframes
(Stackframe res f sp pc rs)
(Stackframe res (transf_function (romem_for cu) f) sp pc rs').
Inductive match_states: nat -> state -> state -> Prop :=
| match_states_intro:
forall s sp pc rs m f s' pc' rs' m' cu n
(LINK: linkorder cu prog)
(STACKS: list_forall2 match_stackframes s s')
(PC: match_pc f rs m n pc pc')
(REGS: regs_lessdef rs rs')
(MEM: Mem.extends m m'),
match_states n (State s f sp pc rs m)
(State s' (transf_function (romem_for cu) f) sp pc' rs' m')
| match_states_call:
forall s f args m s' args' m' cu
(LINK: linkorder cu prog)
(STACKS: list_forall2 match_stackframes s s')
(ARGS: Val.lessdef_list args args')
(MEM: Mem.extends m m'),
match_states O (Callstate s f args m)
(Callstate s' (transf_fundef (romem_for cu) f) args' m')
| match_states_return:
forall s v m s' v' m'
(STACKS: list_forall2 match_stackframes s s')
(RES: Val.lessdef v v')
(MEM: Mem.extends m m'),
list_forall2 match_stackframes s s' ->
match_states O (Returnstate s v m)
(Returnstate s' v' m').

Lemma transf_instr_at:
forall rm f pc i,
f.(fn_code)!pc = Some i ->
(transf_function rm f).(fn_code)!pc = Some(transf_instr f (analyze rm f) rm pc i).