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.

(* Specifications: *)
Lemma reestablish_DomSrc: forall mu0 mu (D: forall b, locBlocksSrc mu0 b = true -> DomSrc mu b = true), DomSrc (reestablish mu0 mu) = DomSrc mu.
Lemma reestablish_DomTgt: forall mu0 mu (D: forall b, locBlocksTgt mu0 b = true -> DomTgt mu b = true), DomTgt (reestablish mu0 mu) = DomTgt mu.
Lemma reestablish_wd: forall mu0 mu (WD0:SM_wd mu0) (WD:SM_wd mu) (REST: restrict (as_inj mu) (DomSrc mu0) = as_inj mu0) (SEP: forall b1 b2 d, as_inj mu0 b1 = None -> as_inj mu b1 = Some(b2,d) -> (DomSrc mu0 b1 = false /\ DomTgt mu0 b2 = false)) (ExtTgt: forall b, extBlocksTgt mu0 b = true -> DomTgt mu b = true), SM_wd (reestablish mu0 mu).
Lemma reestablish_wd': forall mu0 mu (WD0:SM_wd mu0) (WD:SM_wd mu) (INC: inject_incr (as_inj mu0) (as_inj mu)) (Hmu: forall b1 b2 z (A:as_inj mu b1 = Some(b2,z)), locBlocksSrc mu0 b1 = locBlocksTgt mu0 b2 /\ extBlocksSrc mu0 b1 = extBlocksTgt mu0 b2) (ExtTgt: forall b, extBlocksTgt mu0 b = true -> DomTgt mu b = true), SM_wd (reestablish mu0 mu).
Lemma reestablish_extern_incr': forall mu0 mu (WD0:SM_wd mu0) (WD:SM_wd mu) (INC: inject_incr (as_inj mu0) (as_inj mu)) (ExtSrc: forall b, extBlocksSrc mu0 b = true -> DomSrc mu b = true) (ExtTgt: forall b, extBlocksTgt mu0 b = true -> DomTgt mu b = true), extern_incr mu0 (reestablish mu0 mu).
Lemma reestablish_extern_incr: forall mu0 mu (WD0:SM_wd mu0) (WD:SM_wd mu) (REST: restrict (as_inj mu) (DomSrc mu0) = as_inj mu0) (ExtSrc: forall b, extBlocksSrc mu0 b = true -> DomSrc mu b = true) (ExtTgt: forall b, extBlocksTgt mu0 b = true -> DomTgt mu b = true), extern_incr mu0 (reestablish mu0 mu).
Lemma reestablish_internstep': forall mu0 mu mu' (WD0:SM_wd mu0) (WD:SM_wd mu) (WD:SM_wd mu') (INC: inject_incr (as_inj mu0) (as_inj mu)) (ExtSrc: forall b, extBlocksSrc mu0 b = true -> DomSrc mu b = true) (ExtTgt: forall b, extBlocksTgt mu0 b = true -> DomTgt mu b = true) (II: intern_incr mu mu'), extern_incr mu0 (reestablish mu0 mu').
Lemma reestablish_internstep: forall mu0 mu mu' (WD0:SM_wd mu0) (WD:SM_wd mu) (WD:SM_wd mu') (REST: restrict (as_inj mu) (DomSrc mu0) = as_inj mu0) (ExtSrc: forall b, extBlocksSrc mu0 b = true -> DomSrc mu b = true) (ExtTgt: forall b, extBlocksTgt mu0 b = true -> DomTgt mu b = true) (II: intern_incr mu mu'), extern_incr mu0 (reestablish mu0 mu').
Lemma reestablish_as_inj: forall mu0 mu (WD0:SM_wd mu0) (REST: restrict (as_inj mu) (DomSrc mu0) = as_inj mu0), as_inj (reestablish mu0 mu) = as_inj mu.
Lemma reestablish_as_inj': forall mu0 mu (WD0:SM_wd mu0) (HINC: inject_incr (as_inj mu0) (as_inj mu)) (H: forall b, locBlocksSrc mu0 b = true -> local_of mu0 b = None -> as_inj mu b = None), as_inj (reestablish mu0 mu) = as_inj mu.
Lemma reestablish_sm_injsep: forall mu0 mu (WD0:SM_wd mu0) (WD:SM_wd mu) (REST: restrict (as_inj mu) (DomSrc mu0) = as_inj mu0) (LocSrc: forall b, locBlocksSrc mu0 b = true -> DomSrc mu b = true) (LocTgt: forall b, locBlocksTgt mu0 b = true -> DomTgt mu b = true) m1 m2 (SEP: sm_inject_separated mu0 mu m1 m2), sm_inject_separated mu0 (reestablish mu0 mu) m1 m2.
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.
Lemma as_inj_locBlocks mu b1 b2 delta: forall (WD: SM_wd mu) (A: as_inj mu b1 = Some(b2,delta)), locBlocksSrc mu b1 = locBlocksTgt mu b2.
Lemma as_inj_extBlocks mu b1 b2 delta: forall (WD: SM_wd mu) (A: as_inj mu b1 = Some(b2,delta)), extBlocksSrc mu b1 = extBlocksTgt mu b2.
Lemma locBlocksSrc_as_inj_local mu b: forall (WD: SM_wd mu) (L: locBlocksSrc mu b = true), as_inj mu b = local_of mu b.
Lemma frgnBlocksSrc_false_foreign_None mu b: forall (F: frgnBlocksSrc mu b = false), foreign_of mu b = None.
Lemma foreign_None_frgnBlocksSrc_false mu b: forall (WD: SM_wd mu) (F: foreign_of mu b = None), as_inj mu b = None \/ frgnBlocksSrc mu b = false.
Lemma locBlocksSrc_false_local_None mu b: forall (WD: SM_wd mu) (L: locBlocksSrc mu b = false), local_of mu b = None.
Lemma reestablish_DomSrc: forall mu0 mu (D: forall b, locBlocksSrc mu0 b = true -> DomSrc mu b = true), DomSrc (reestablish mu0 mu) = DomSrc mu.
Lemma reestablish_DomTgt: forall mu0 mu (D: forall b, locBlocksTgt mu0 b = true -> DomTgt mu b = true), DomTgt (reestablish mu0 mu) = DomTgt mu.
Lemma reestablish_wd: forall mu0 mu (WD0:SM_wd mu0) (WD:SM_wd mu) (REST: restrict (as_inj mu) (DomSrc mu0) = as_inj mu0) (SEP: forall b1 b2 d, as_inj mu0 b1 = None -> as_inj mu b1 = Some(b2,d) -> (DomSrc mu0 b1 = false /\ DomTgt mu0 b2 = false)) (ExtTgt: forall b, extBlocksTgt mu0 b = true -> DomTgt mu b = true), SM_wd (reestablish mu0 mu).
Lemma reestablish_wd': forall mu0 mu (WD0:SM_wd mu0) (WD:SM_wd mu) (INC: inject_incr (as_inj mu0) (as_inj mu)) (Hmu: forall b1 b2 z (A:as_inj mu b1 = Some(b2,z)), locBlocksSrc mu0 b1 = locBlocksTgt mu0 b2 /\ extBlocksSrc mu0 b1 = extBlocksTgt mu0 b2) (ExtTgt: forall b, extBlocksTgt mu0 b = true -> DomTgt mu b = true), SM_wd (reestablish mu0 mu).
Lemma reestablish_extern_incr': forall mu0 mu (WD0:SM_wd mu0) (WD:SM_wd mu) (INC: inject_incr (as_inj mu0) (as_inj mu)) (ExtSrc: forall b, extBlocksSrc mu0 b = true -> DomSrc mu b = true) (ExtTgt: forall b, extBlocksTgt mu0 b = true -> DomTgt mu b = true), extern_incr mu0 (reestablish mu0 mu).
Lemma reestablish_extern_incr: forall mu0 mu (WD0:SM_wd mu0) (WD:SM_wd mu) (REST: restrict (as_inj mu) (DomSrc mu0) = as_inj mu0) (ExtSrc: forall b, extBlocksSrc mu0 b = true -> DomSrc mu b = true) (ExtTgt: forall b, extBlocksTgt mu0 b = true -> DomTgt mu b = true), extern_incr mu0 (reestablish mu0 mu).
Lemma reestablish_internstep': forall mu0 mu mu' (WD0:SM_wd mu0) (WD:SM_wd mu) (WD:SM_wd mu') (INC: inject_incr (as_inj mu0) (as_inj mu)) (ExtSrc: forall b, extBlocksSrc mu0 b = true -> DomSrc mu b = true) (ExtTgt: forall b, extBlocksTgt mu0 b = true -> DomTgt mu b = true) (II: intern_incr mu mu'), extern_incr mu0 (reestablish mu0 mu').
Lemma reestablish_internstep: forall mu0 mu mu' (WD0:SM_wd mu0) (WD:SM_wd mu) (WD:SM_wd mu') (REST: restrict (as_inj mu) (DomSrc mu0) = as_inj mu0) (ExtSrc: forall b, extBlocksSrc mu0 b = true -> DomSrc mu b = true) (ExtTgt: forall b, extBlocksTgt mu0 b = true -> DomTgt mu b = true) (II: intern_incr mu mu'), extern_incr mu0 (reestablish mu0 mu').
Lemma reestablish_as_inj: forall mu0 mu (WD0:SM_wd mu0) (REST: restrict (as_inj mu) (DomSrc mu0) = as_inj mu0), as_inj (reestablish mu0 mu) = as_inj mu.
Lemma reestablish_as_inj': forall mu0 mu (WD0:SM_wd mu0) (HINC: inject_incr (as_inj mu0) (as_inj mu)) (H: forall b, locBlocksSrc mu0 b = true -> local_of mu0 b = None -> as_inj mu b = None), as_inj (reestablish mu0 mu) = as_inj mu.
Lemma reestablish_sm_injsep: forall mu0 mu (WD0:SM_wd mu0) (WD:SM_wd mu) (REST: restrict (as_inj mu) (DomSrc mu0) = as_inj mu0) (LocSrc: forall b, locBlocksSrc mu0 b = true -> DomSrc mu b = true) (LocTgt: forall b, locBlocksTgt mu0 b = true -> DomTgt mu b = true) m1 m2 (SEP: sm_inject_separated mu0 mu m1 m2), sm_inject_separated mu0 (reestablish mu0 mu) m1 m2.
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.