Inductive match_states: state -> state -> Prop :=
| match_states_regular: forall s f sp pc rs m ts tsp trs tm j
(STACKS: match_stacks j s ts sp tsp)
(KEPT: forall id, ref_function f id -> kept id)
(SPINJ: j sp = Some(tsp, 0))
(REGINJ: regset_inject j rs trs)
(MEMINJ: Mem.inject j m tm),
match_states (State s f (Vptr sp Ptrofs.zero) pc rs m)
(State ts f (Vptr tsp Ptrofs.zero) pc trs tm)
| match_states_call: forall s fd args m ts targs tm j
(STACKS: match_stacks j s ts (Mem.nextblock m) (Mem.nextblock tm))
(KEPT: forall id, ref_fundef fd id -> kept id)
(ARGINJ: Val.inject_list j args targs)
(MEMINJ: Mem.inject j m tm),
match_states (Callstate s fd args m)
(Callstate ts fd targs tm)
| match_states_return: forall s res m ts tres tm j
(STACKS: match_stacks j s ts (Mem.nextblock m) (Mem.nextblock tm))
(RESINJ: Val.inject j res tres)
(MEMINJ: Mem.inject j m tm),
match_states (Returnstate s res m)
(Returnstate ts tres tm).

Theorem step_simulation:
forall S1 t S2, step ge S1 t S2 ->
forall S1' (MS: match_states S1 S1'),
exists S2', step tge S1' t S2' /\ match_states S2 S2'.