Section PRESERVATION.
Variable prog: program.
Variable tprog: program.
Hypothesis TRANSF: match_prog prog tprog.
Let ge := Genv.globalenv prog.
Let tge := Genv.globalenv tprog.
Proof (Genv.find_symbol_match TRANSF).
Proof (Genv.senv_match TRANSF).
Proof (Genv.find_funct_transf_partial TRANSF).
Proof (Genv.find_funct_ptr_transf_partial TRANSF).
(** Evaluation of the debug annotations introduced by the transformation. *)
(** Matching between program states. *)
Inductive match_stackframes: Linear.stackframe -> Linear.stackframe -> Prop :=
| match_stackframe_intro:
forall f sp rs c tf tc before after,
match_function f tf ->
match_code c tc ->
match_stackframes
(Stackframe f sp rs c)
(Stackframe tf sp rs (add_delta_ranges before after tc)).
Inductive match_states: Linear.state ->  Linear.state -> Prop :=
| match_states_instr:
forall s f sp c rs m tf ts tc
(STACKS: list_forall2 match_stackframes s ts)
(TRF: match_function f tf)
(TRC: match_code c tc),
match_states (State s f sp c rs m)
(State ts tf sp tc rs m)
| match_states_call:
forall s f rs m tf ts,
list_forall2 match_stackframes s ts ->
transf_fundef f = OK tf ->
match_states (Callstate s f rs m)
(Callstate ts tf rs m)
| match_states_return:
forall s rs m ts,
list_forall2 match_stackframes s ts ->
match_states (Returnstate s rs m)
(Returnstate ts rs m).
(** The simulation diagram. *)

Theorem transf_step_correct:
forall s1 t s2, step ge s1 t s2 ->
forall ts1 (MS: match_states s1 ts1),
exists ts2, plus step tge ts1 t ts2 /\ match_states s2 ts2.