Section Eff_INJ_SIMU_DIAGRAMS.
Context {F1 V1 C1 F2 V2 C2:Type}
{Sem1 : @EffectSem (Genv.t F1 V1) C1}
{Sem2 : @EffectSem (Genv.t F2 V2) C2}
{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 -> SM_Injection -> C1 -> mem -> C2 -> mem -> Prop.
Hypothesis genvs_dom_eq: genvs_domain_eq ge1 ge2.
Hypothesis match_sm_wd: forall d mu c1 m1 c2 m2,
match_states d mu c1 m1 c2 m2 ->
SM_wd mu.
Hypothesis match_visible: forall d mu c1 m1 c2 m2,
match_states d mu c1 m1 c2 m2 ->
REACH_closed m1 (vis mu).
Hypothesis match_restrict: forall d mu c1 m1 c2 m2 X,
match_states d mu c1 m1 c2 m2 ->
(forall b, vis mu b = true -> X b = true) ->
REACH_closed m1 X ->
match_states d (restrict_sm mu X) c1 m1 c2 m2.
Hypothesis match_validblocks: forall d mu c1 m1 c2 m2,
match_states d mu c1 m1 c2 m2 ->
sm_valid mu m1 m2.
(*experimental Hypothesis match_protected: forall d mu c1 m1 c2 m2, match_states d mu c1 m1 c2 m2 -> forall b, REACH m1 (extBlocksSrc mu) b = true -> locBlocksSrc mu b = true -> REACH m1 (frgnBlocksSrc mu) b = true. *)
(* Hypothesis match_genv: forall d mu c1 m1 c2 m2,  match_state d mu c1 m1 c2 m2 -> meminj_preserves_globals ge1 (foreign_of mu); *)
Hypothesis match_genv: forall d mu c1 m1 c2 m2 (MC:match_states d mu c1 m1 c2 m2),
meminj_preserves_globals ge1 (extern_of mu) /\
(forall b, isGlobalBlock ge1 b = true -> frgnBlocksSrc mu b = true).
(*Version if the environment provides structured injections: Hypothesis core_initial_sm : forall v1 v2 sig, In (v1,v2,sig) entry_points -> forall vals1 c1 m1 mu vals2 m2, initial_core Sem1 ge1 v1 vals1 = Some c1 -> Mem.inject (as_inj mu) m1 m2 -> Forall2 (val_inject (as_inj mu)) vals1 vals2 -> meminj_preserves_globals ge1 (as_inj mu) -> SM_wd mu -> sm_valid mu m1 m2 -> (forall b, REACH m2 (fun b' => isGlobalBlock ge2 b' || getBlocks vals2 b') b = true -> DomTgt mu b = true) -> exists c2, initial_core Sem2 ge2 v2 vals2 = Some c2 /\ match_states c1 (mkinitial_SM mu (REACH m1 (fun b => isGlobalBlock ge1 b || getBlocks vals1 b)) (REACH m2 (fun b => isGlobalBlock ge2 b || getBlocks vals2 b))) c1 m1 c2 m2. *)
Hypothesis inj_initial_cores: forall v1 v2 sig,
In (v1,v2,sig) entry_points ->
forall vals1 c1 m1 j vals2 m2 DomS DomT,
initial_core Sem1 ge1 v1 vals1 = Some c1 ->
Mem.inject j m1 m2 ->
Forall2 (val_inject j) vals1 vals2 ->
meminj_preserves_globals ge1 j ->
(*the next two conditions are required to guarantee intialSM_wd*)
(forall b1 b2 d, j b1 = Some (b2, d) ->
DomS b1 = true /\ DomT b2 = true) ->
(forall b, REACH m2 (fun b' => isGlobalBlock ge2 b' || getBlocks vals2 b') b = true -> DomT b = true) ->
(*the next two conditions ensure the initialSM satisfies sm_valid*)
(forall b, DomS b = true -> Mem.valid_block m1 b) ->
(forall b, DomT b = true -> Mem.valid_block m2 b) ->
exists c2,
initial_core Sem2 ge2 v2 vals2 = Some c2 /\
match_states c1 (initial_SM DomS
DomT
(REACH m1 (fun b => isGlobalBlock ge1 b || getBlocks vals1 b))
(REACH m2 (fun b => isGlobalBlock ge2 b || getBlocks vals2 b)) j)
c1 m1 c2 m2.
Hypothesis inj_halted : forall cd mu c1 m1 c2 m2 v1,
match_states cd mu c1 m1 c2 m2 ->
halted Sem1 c1 = Some v1 ->
exists v2,
Mem.inject (as_inj mu) m1 m2 /\
val_inject (restrict (as_inj mu) (vis mu)) v1 v2 /\
halted Sem2 c2 = Some v2.
Hypothesis inj_at_external :
forall mu c1 m1 c2 m2 e vals1 ef_sig,
match_states c1 mu c1 m1 c2 m2 ->
at_external Sem1 c1 = Some (e,ef_sig,vals1) ->
( Mem.inject (as_inj mu) m1 m2 /\
exists vals2,
Forall2 (val_inject (restrict (as_inj mu) (vis mu))) vals1 vals2 /\
at_external Sem2 c2 = Some (e,ef_sig,vals2)).
Hypothesis inj_after_external:
forall mu st1 st2 m1 e vals1 m2 ef_sig vals2 e' ef_sig'
(MemInjMu: Mem.inject (as_inj mu) m1 m2)
(MatchMu: match_states st1 mu st1 m1 st2 m2)
(AtExtSrc: at_external Sem1 st1 = Some (e,ef_sig,vals1))
(AtExtTgt: at_external Sem2 st2 = Some (e',ef_sig',vals2))
(ValInjMu: Forall2 (val_inject (restrict (as_inj mu) (vis mu))) vals1 vals2)
pubSrc' (pubSrcHyp: pubSrc' = fun b => andb (locBlocksSrc mu b)
(REACH m1 (exportedSrc mu vals1) b))
pubTgt' (pubTgtHyp: pubTgt' = fun b => andb (locBlocksTgt mu b)
(REACH m2 (exportedTgt mu vals2) b))
nu (NuHyp: nu = replace_locals mu pubSrc' pubTgt'),
forall nu' ret1 m1' ret2 m2'
(INC: extern_incr nu nu')
(SEP: sm_inject_separated nu nu' m1 m2)
(WDnu': SM_wd nu') (SMvalNu': sm_valid nu' m1' m2')
(MemInjNu': Mem.inject (as_inj nu') m1' m2')
(RValInjNu': val_inject (as_inj nu') ret1 ret2)
(FwdSrc: mem_forward m1 m1') (FwdTgt: mem_forward m2 m2')
frgnSrc' (frgnSrcHyp: frgnSrc' = fun b => andb (DomSrc nu' b)
(andb (negb (locBlocksSrc nu' b))
(REACH m1' (exportedSrc nu' (ret1::nil)) b)))
frgnTgt' (frgnTgtHyp: frgnTgt' = fun b => andb (DomTgt nu' b)
(andb (negb (locBlocksTgt nu' b))
(REACH m2' (exportedTgt nu' (ret2::nil)) b)))
mu' (Mu'Hyp: mu' = replace_externs nu' frgnSrc' frgnTgt')
(UnchPrivSrc: Mem.unchanged_on (fun b ofs => locBlocksSrc nu b = true /\
pubBlocksSrc nu b = false) m1 m1')
(UnchLOOR: Mem.unchanged_on (local_out_of_reach nu m1) m2 m2'),
exists st1', exists st2',
after_external Sem1 (Some ret1) st1 = Some st1' /\
after_external Sem2 (Some ret2) st2 = Some st2' /\
match_states st1' mu' st1' m1' st2' m2'.
Section EFF_INJ_SIMULATION_STAR_WF.
Variable order: C1 -> C1 -> Prop.
Hypothesis order_wf: well_founded order.
Hypothesis inj_core_diagram :
forall st1 m1 st1' m1',
corestep Sem1 ge1 st1 m1 st1' m1' ->
forall st2 mu m2,
match_states st1 mu st1 m1 st2 m2 ->
exists st2', exists m2', exists mu',
intern_incr mu mu' /\
sm_inject_separated mu mu' m1 m2 /\
sm_locally_allocated mu mu' m1 m2 m1' m2' /\
match_states st1' mu' st1' m1' st2' m2' /\
SM_wd mu' /\ sm_valid mu' m1' m2' /\
((corestep_plus Sem2 ge2 st2 m2 st2' m2') \/
corestep_star Sem2 ge2 st2 m2 st2' m2' /\
order st1' st1).
Hypothesis inj_effcore_diagram :
forall st1 m1 st1' m1' U1,
effstep Sem1 ge1 U1 st1 m1 st1' m1' ->
forall st2 mu m2
(UHyp: forall b z, U1 b z = true -> Mem.valid_block m1 b ->
vis mu b = true),
match_states st1 mu st1 m1 st2 m2 ->
exists st2', exists m2', exists mu',
intern_incr mu mu' /\
sm_inject_separated mu mu' m1 m2 /\
sm_locally_allocated mu mu' m1 m2 m1' m2' /\
match_states st1' mu' st1' m1' st2' m2' /\
exists U2,
((effstep_plus Sem2 ge2 U2 st2 m2 st2' m2' \/
(effstep_star Sem2 ge2 U2 st2 m2 st2' m2' /\
order st1' st1)) /\
forall b ofs, U2 b ofs = true ->
(Mem.valid_block m2 b /\
(locBlocksTgt mu b = false ->
exists b1 delta1, foreign_of mu b1 = Some(b,delta1) /\
U1 b1 (ofs-delta1) = true /\
Mem.perm m1 b1 (ofs-delta1) Max Nonempty))).

Lemma  inj_simulation_star_wf:
SM_simulation.SM_simulation_inject Sem1 Sem2 ge1 ge2 entry_points.