End EXT_SIMULATION_PLUS.
End Sim_EXT_SIMU_DIAGRAMS.
Section Sim_INJ_SIMU_DIAGRAMS.
Context {F1 V1 C1 F2 V2 C2:Type}
{Sem1 : CoreSemantics (Genv.t F1 V1) C1 mem}
{Sem2 : CoreSemantics (Genv.t F2 V2) C2 mem}
{ge1: Genv.t F1 V1}
{ge2: Genv.t F2 V2}
{entry_points : list (val * val * signature)}.
Let core_data := C1.
Variable match_states: core_data -> meminj -> C1 -> mem -> C2 -> mem -> Prop.
Hypothesis genvs_dom_eq: genvs_domain_eq ge1 ge2.
Hypothesis match_validblocks: forall d j c1 m1 c2 m2,
match_states d j c1 m1 c2 m2 ->
forall b1 b2 ofs, j b1 = Some(b2,ofs) ->
(Mem.valid_block m1 b1 /\ Mem.valid_block m2 b2).
Hypothesis match_genv: forall d j c1 m1 c2 m2, match_states d j c1 m1 c2 m2 ->
meminj_preserves_globals ge1 j.
Hypothesis match_initial_cores: forall v1 v2 sig,
In (v1,v2,sig) entry_points ->
forall vals1 c1 m1 j vals2 m2,
initial_core Sem1 ge1 v1 vals1 = Some c1 ->
Mem.inject j m1 m2 ->
Forall2 (val_inject j) vals1 vals2 ->
meminj_preserves_globals ge1 j ->
exists c2,
initial_core Sem2 ge2 v2 vals2 = Some c2 /\
match_states c1 j c1 m1 c2 m2.
Hypothesis inj_halted:forall cd j c1 m1 c2 m2 v1,
match_states cd j c1 m1 c2 m2 ->
halted Sem1 c1 = Some v1 ->
exists v2, val_inject j v1 v2 /\
halted Sem2 c2 = Some v2 /\
Mem.inject j m1 m2.
Hypothesis inj_at_external:
forall d j st1 m1 st2 m2 e vals1 sig,
d = st1 /\ match_states d j st1 m1 st2 m2 ->
at_external Sem1 st1 = Some (e,sig,vals1) ->
( Mem.inject j m1 m2 /\
exists vals2, Forall2 (val_inject j) vals1 vals2 /\
at_external Sem2 st2 = Some (e,sig,vals2)).
Hypothesis inj_after_external:
forall d j j' st1 st2 m1 e vals1 (*vals2*) ret1 m1' m2 m2' ret2 sig,
(d=st1 /\ match_states d j st1 m1 st2 m2) ->
at_external Sem1 st1 = Some (e,sig,vals1) ->
(* LENB: we may want to add meminj_preserves_globals ge1 j as another asumption here, to get rid of meminj_preserved_globals_inject_incr below. But this would require spaeicaliing G1 to Genv.t....  Maybe we can specialize G1 and G2 of CompCertCoreSem's to Genv F1 V1/Genv F2 V2, but not specialize CoreSem's?*)
inject_incr j j' ->
inject_separated j j' m1 m2 ->
Mem.inject j' m1' m2' ->
val_inject j' ret1 ret2 ->
mem_forward m1 m1'  ->
Mem.unchanged_on (loc_unmapped j) m1 m1' ->
mem_forward m2 m2' ->
Mem.unchanged_on (loc_out_of_reach j m1) m2 m2' ->
exists st1', exists st2', exists d',
after_external Sem1 (Some ret1) st1 = Some st1' /\
after_external Sem2 (Some ret2) st2 = Some st2' /\
d' = st1' /\ match_states d' j' st1' m1' st2' m2'.
Section INJ_SIMULATION_STAR_WF.
Variable order: C1 -> C1 -> Prop.
Hypothesis order_wf: well_founded order.
Hypothesis inj_simulation:
forall c1 m1 c1' m1',  corestep Sem1 ge1 c1 m1 c1' m1' ->
forall j c2 m2, match_states c1 j c1 m1 c2 m2 ->
exists c2', exists m2', exists j',
inject_incr j j' /\
inject_separated j j' m1 m2 /\
match_states c1' j' c1' m1' c2' m2' /\
(corestep_plus Sem2 ge2  c2 m2 c2' m2' \/
(corestep_star Sem2 ge2 c2 m2 c2' m2' /\ order c1' c1)).

Lemma  inj_simulation_star_wf:
Forward_simulation_inj.Forward_simulation_inject Sem1 Sem2 ge1 ge2 entry_points.