Definition mkinitial_SM (mu: SM_Injection) frgnS frgnT :=
match mu with
Build_SM_Injection locBSrc locBTgt pSrc pTgt local extBSrc extBTgt fSrc fTgt extern =>
Build_SM_Injection (fun b => false) (fun b => false) (fun b => false) (fun b => false) (fun b => None)
(DomSrc mu) (DomTgt mu) frgnS frgnT (as_inj mu)
end.

(* Specifications: *)
Lemma mkinitial_SM_as_inj: forall mu S T,
as_inj (mkinitial_SM mu S T) = as_inj mu.
Lemma mkinitial_SM_local: forall mu S T,
local_of (mkinitial_SM mu S T) = fun b => None.
Lemma vals_def_inject_getBlock j b2: forall vals1 vals2
(INJ: Val.inject_list j vals1 vals2)
(DEF : vals_def vals1 = true)
(GB: getBlocks vals2 b2 = true),
exists b1 d, j b1 = Some(b2,d) /\ getBlocks vals1 b1 = true.
Lemma visTgt_DomTgt mu b: visTgt mu b = true -> SM_wd mu -> DomTgt mu b = true.
Lemma replace_locals_wd_AtExternal: forall mu vals1 vals2 m1 m2
(WD : SM_wd mu)
(MINJ : Mem.inject (as_inj mu) m1 m2)
(AINJ : Forall2 (val_inject (as_inj mu)) vals1 vals2),
SM_wd
(replace_locals mu
(fun b => locBlocksSrc mu b && REACH m1 (exportedSrc mu vals1) b)
(fun b => locBlocksTgt mu b && REACH m2 (exportedTgt mu vals2) b)).
Lemma inject_shared_replace_locals m1 m2 mu vals1 vals2:
forall (RC : REACH_closed m1 (vis mu))
(WD : SM_wd mu)
(MINJ : Mem.inject (as_inj mu) m1 m2)
pubSrc' pubTgt'
(HPS: pubSrc' = (fun b => locBlocksSrc mu b && REACH m1 (exportedSrc mu vals1) b))
(HPT: pubTgt' = (fun b => locBlocksTgt mu b && REACH m2 (exportedTgt mu vals2) b))
nu (Hnu : nu = replace_locals mu pubSrc' pubTgt')
(WDnu: SM_wd nu),
Mem.inject (shared_of nu) m1 m2.
Lemma forall_vals_inject_restrictD' j vals1 vals2 X
(Inj : Forall2 (val_inject (restrict j X)) vals1 vals2) :
Forall2 (val_inject j) vals1 vals2
/\ (forall b : block, getBlocks vals1 b = true -> X b = true).
Lemma forall_vals_inject_intern_incr mu mu' vals1 vals2
(Inj : Forall2 (val_inject (as_inj mu)) vals1 vals2)
(Incr : intern_incr mu mu')
(WD : SM_wd mu') :
Forall2 (val_inject (as_inj mu')) vals1 vals2.
Lemma forall_vals_inject_extern_incr mu mu' vals1 vals2
(Inj : Forall2 (val_inject (as_inj mu)) vals1 vals2)
(Incr : extern_incr mu mu')
(WD : SM_wd mu') :
Forall2 (val_inject (as_inj mu')) vals1 vals2.
Lemma local_of_vis mu: forall b1 b2 d
(LOC: local_of mu b1 = Some (b2,d))
(WD: SM_wd mu), vis mu b1 = true.
Lemma incr_local_restrictvis mu: SM_wd mu ->
inject_incr (local_of mu) (restrict (as_inj mu)(vis mu)).
Lemma local_visTgt mu (WD: SM_wd mu) b1 b2 d:
local_of mu b1 = Some(b2,d) -> visTgt mu b2 = true.
Lemma mkinitial_SM_as_inj: forall mu S T,
as_inj (mkinitial_SM mu S T) = as_inj mu.
Lemma mkinitial_SM_local: forall mu S T,
local_of (mkinitial_SM mu S T) = fun b => None.
Lemma mkinitial_SM_ok: forall {F1 V1 F2 V2:Type}
(g1: Genv.t F1 V1) (g2: Genv.t F2 V2) (G:genvs_domain_eq g1 g2)
mu (WD: SM_wd mu)
(PG: meminj_preserves_globals g1 (as_inj mu))
vals1 vals2 (VALS: Forall2 (val_inject (as_inj mu)) vals1 vals2)
m1 m2 (SMV: sm_valid mu m1 m2) (INJ: Mem.inject (as_inj mu) m1 m2)
(RchTgt: forall b, REACH m2 (fun b' => isGlobalBlock g2 b' || getBlocks vals2 b') b = true -> DomTgt mu b = true)
nu (NU: nu = mkinitial_SM mu
(REACH m1 (fun b => isGlobalBlock g1 b || getBlocks vals1 b))
(REACH m2 (fun b => isGlobalBlock g2 b || getBlocks vals2 b))),
SM_wd nu /\ sm_valid nu m1 m2 /\
meminj_preserves_globals g1 (extern_of nu) /\
(forall b, isGlobalBlock g1 b = true -> frgnBlocksSrc nu b = true) /\
REACH_closed m1 (vis nu) /\
REACH_closed m1 (mapped (as_inj nu)).