(*Construction used in make_initial_core: put incoming injection into foreign/unknown component as specified, initialize local_of, locBlocksSrc/Tgt, and pubBlocksSrc/Tgt as empty*)
Definition initial_SM (extS extT frgnS frgnT: block->bool)
(extern:meminj): SM_Injection :=
Build_SM_Injection
(*locBlocksSrc/Tgt:*) (fun b => false) (fun b => false) (*pubBlocksSrc/Tgt:*)(fun b => false) (fun b => false) (*local:*)(fun b => None) (*extBlocksSrc/Tgt:*) extS extT (*frgnBlocksSrc/Tgt:*) frgnS frgnT extern.  Lemma initial_SM_wd: forall extS extT frgnS frgnT extern (EXT: forall b1 b2 d, extern b1 =Some(b2,d) -> extS b1 = true /\ extT b2 = true) (F: forall b1, frgnS b1 = true -> exists b2 z, extern b1 = Some (b2, z) /\ frgnT b2 = true) (FS: forall b, frgnS b = true -> extS b = true) (FT: forall b, frgnT b = true -> extT b = true), SM_wd (initial_SM extS extT frgnS frgnT extern).  Lemma initial_SM_as_inj: forall extS extT frgnS frgnT j, as_inj (initial_SM extS extT frgnS frgnT j) = j.  Definition restrict (j: meminj) (X:block -> bool) : meminj := fun b => if X b then j b else None.  Lemma restrictD_Some: forall j X b1 b2 d (R:restrict j X b1 = Some(b2,d)), j b1 = Some(b2,d) /\ X b1 = true. Lemma restrictI_Some: forall j X b b2 d (J:j b = Some(b2,d)) (Hb: X b = true), restrict j X b = Some(b2,d). Lemma restrictD_None: forall j X b1 b2 d (R:restrict j X b1 = None) (J: j b1 = Some(b2,d)), X b1 = false. Lemma restrictD_None': forall j X b1 (R:restrict j X b1 = None), j b1 = None \/ (exists b2 d, j b1 =Some(b2,d) /\ X b1 = false). Lemma restrictI_None: forall j X b (Hb: j b = None \/ X b = false), restrict j X b = None.  Lemma join_restrict: forall j k X, join (restrict j X) (restrict k X) = restrict (join j k) X.  Lemma restrict_outside: forall j X (HX: forall b1 b2 d, j b1 = Some(b2, d) -> X b1 = true), restrict j X = j.  Lemma restrict_incr: forall j X, inject_incr (restrict j X) j.  Lemma restrict_nest: forall j X Y (HXY: forall b, Y b = true -> X b = true), restrict (restrict j X) Y = restrict j Y. Lemma restrict_nest': forall j X Y (HXY: forall b, Y b = true -> X b = true), restrict (restrict j Y) X = restrict j Y.  Lemma val_inject_restrictD: forall j v v' X (V: val_inject (restrict j X) v v'), val_inject j v v'.  Lemma forall_vals_inject_restrictD: forall j vals1 vals2 X (Inj : Forall2 (val_inject (restrict j X)) vals1 vals2), Forall2 (val_inject j) vals1 vals2.  Definition reestablish (mu0 mu: SM_Injection): SM_Injection := match mu0, mu with Build_SM_Injection locBSrc0 locBTgt0 pSrc0 pTgt0 local0 extBSrc0 extBTgt0 fSrc0 fTgt0 extern0, Build_SM_Injection locBSrc locBTgt pSrc pTgt local extBSrc extBTgt fSrc fTgt extern => Build_SM_Injection locBSrc0 locBTgt0 pSrc0 pTgt0 local0 (fun b => if locBSrc0 b then false else locBSrc b || extBSrc b) (fun b => if locBTgt0 b then false else locBTgt b || extBTgt b) fSrc0 fTgt0 (*We have not YET learned about additional blocks - that's done by replace_externs in AfterEtxernal!*)
(fun b => if locBSrc0 b then None else join extern local b)
end.

Lemma reestablish_sm_valid: forall mu0 mu (WD0:SM_wd mu0) (WD:SM_wd mu)
(LocSrc: forall b, locBlocksSrc mu0 b = true -> DomSrc mu b = true)
(DomTgt: forall b, locBlocksTgt mu0 b = true -> DomTgt mu b = true)
m1 m2 (VAL: sm_valid mu m1 m2),
sm_valid (reestablish mu0 mu) m1 m2.