Section ForwardSimulations.
Context (L1 L2: semantics).
(** The general form of a forward simulation. *)
(** NEW: I will tolerate the duplication of entry_points/initial_states, while we find a better abstraction. *)
Record fsim_properties (index: Type)
(order: index -> index -> Prop)
(match_states: index -> state L1 -> state L2 -> Prop) : Prop := {
fsim_order_wf: well_founded order;
fsim_match_entry_points:
forall s1 f arg m0, entry_point L1 m0 s1 f arg  ->
exists i, exists s2, entry_point L2 m0 s2 f arg /\ match_states i s1 s2;
fsim_match_initial_states:
forall s1, initial_state L1 s1  ->
exists i, exists s2, initial_state L2 s2 /\ match_states i s1 s2;
fsim_match_final_states:
forall i s1 s2 r,
match_states i s1 s2 -> final_state L1 s1 r -> final_state L2 s2 r;
fsim_simulation:
forall s1 t s1', Step L1 s1 t s1' ->
forall i s2, match_states i s1 s2 ->
exists i', exists s2',
(Plus L2 s2 t s2' \/ (Star L2 s2 t s2' /\ order i' i))
/\ match_states i' s1' s2';
fsim_public_preserved:
forall id, Senv.public_symbol (symbolenv L2) id = Senv.public_symbol (symbolenv L1) id
}.
End ForwardSimulations.
Arguments fsim_properties: clear implicits.
Inductive forward_simulation (L1 L2: semantics) : Prop :=
Forward_simulation (index: Type)
(order: index -> index -> Prop)
(match_states: index -> state L1 -> state L2 -> Prop)
(props: fsim_properties L1 L2 index order match_states).
Arguments Forward_simulation {L1 L2 index} order match_states props.
(** An alternate form of the simulation diagram *)

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