(** The general form of a backward simulation. *)
Record bsim_properties (L1 L2: semantics) (index: Type)
(order: index -> index -> Prop)
(match_states: index -> state L1 -> state L2 -> Prop) : Prop := {
bsim_order_wf: well_founded order;
bsim_initial_states_exist:
forall s1, initial_state L1 s1 -> exists s2, initial_state L2 s2;
bsim_match_initial_states:
forall s1 s2, initial_state L1 s1 -> initial_state L2 s2 ->
exists i, exists s1', initial_state L1 s1' /\ match_states i s1' s2;
bsim_match_final_states:
forall i s1 s2 r,
match_states i s1 s2 -> safe L1 s1 -> final_state L2 s2 r ->
exists s1', Star L1 s1 E0 s1' /\ final_state L1 s1' r;
bsim_progress:
forall i s1 s2,
match_states i s1 s2 -> safe L1 s1 ->
(exists r, final_state L2 s2 r) \/
(exists t, exists s2', Step L2 s2 t s2');
bsim_simulation:
forall s2 t s2', Step L2 s2 t s2' ->
forall i s1, match_states i s1 s2 -> safe L1 s1 ->
exists i', exists s1',
(Plus L1 s1 t s1' \/ (Star L1 s1 t s1' /\ order i' i))
/\ match_states i' s1' s2';
bsim_public_preserved:
forall id, Senv.public_symbol (symbolenv L2) id = Senv.public_symbol (symbolenv L1) id
}.
Arguments bsim_properties: clear implicits.
Inductive backward_simulation (L1 L2: semantics) : Prop :=
Backward_simulation (index: Type)
(order: index -> index -> Prop)
(match_states: index -> state L1 -> state L2 -> Prop)
(props: bsim_properties L1 L2 index order match_states).
Arguments Backward_simulation {L1 L2 index} order match_states props.
(** An alternate form of the simulation diagram *)

Lemma bsim_simulation':
forall L1 L2 index order match_states, bsim_properties L1 L2 index order match_states ->
forall i s2 t s2', Step L2 s2 t s2' ->
forall s1, match_states i s1 s2 -> safe L1 s1 ->
(exists i', exists s1', Plus L1 s1 t s1' /\ match_states i' s1' s2')
\/ (exists i', order i' i /\ t = E0 /\ match_states i' s1 s2').