Definition replace_externs (mu:SM_Injection) fSrc' fTgt': SM_Injection :=
match mu with
Build_SM_Injection locBSrc locBTgt pSrc pTgt local extBSrc extBTgt fSrc fTgt extern =>
Build_SM_Injection locBSrc locBTgt pSrc pTgt local extBSrc extBTgt fSrc' fTgt' extern
end.
(*typically, we have forall b, fSrc b -> fSrc' b and forall b, fTgt b -> fTgt' b, i.e. only reclassify unknown entries as foreign*)

(* Specifications: *)
Lemma replace_externs_wd: forall mu (WD: SM_wd mu) fSrc' fTgt'
(SRC: forall b1, fSrc' b1 = true ->
exists b2 d, extern_of mu b1 = Some(b2,d) /\ fTgt' b2=true)
(TGT: forall b, fTgt' b = true -> extBlocksTgt mu b = true),
SM_wd (replace_externs mu fSrc' fTgt').
Lemma replace_externs_extern: forall mu frgSrc' frgTgt',
extern_of (replace_externs mu frgSrc' frgTgt') = extern_of mu.
Lemma replace_externs_foreign: forall mu frgSrc' frgTgt',
foreign_of (replace_externs mu frgSrc' frgTgt') =
fun b : block => if frgSrc' b then extern_of mu b else None.
Lemma replace_externs_local: forall mu frgSrc' frgTgt',
local_of (replace_externs mu frgSrc' frgTgt') = local_of mu.
Lemma replace_externs_priv: forall mu frgSrc' frgTgt',
priv_of (replace_externs mu frgSrc' frgTgt') = priv_of mu.
Lemma replace_externs_pub: forall mu frgSrc' frgTgt',
pub_of (replace_externs mu frgSrc' frgTgt') = pub_of mu.
Lemma replace_externs_as_inj: forall mu frgSrc' frgTgt',
as_inj (replace_externs mu frgSrc' frgTgt') = as_inj mu.
Lemma replace_externs_DOM: forall mu frgSrc' frgTgt',
DOM (replace_externs mu frgSrc' frgTgt') = DOM mu.
Lemma replace_externs_RNG: forall mu frgSrc' frgTgt',
RNG (replace_externs mu frgSrc' frgTgt') = RNG mu.
Lemma replace_externs_DomSrc: forall mu frgSrc' frgTgt',
DomSrc (replace_externs mu frgSrc' frgTgt') = DomSrc mu.
Lemma replace_externs_DomTgt: forall mu frgSrc' frgTgt',
DomTgt (replace_externs mu frgSrc' frgTgt') = DomTgt mu.
Lemma replace_externs_locBlocksSrc: forall mu frgSrc' frgTgt',
locBlocksSrc (replace_externs mu frgSrc' frgTgt') = locBlocksSrc mu.
Lemma replace_externs_locBlocksTgt: forall mu frgSrc' frgTgt',
locBlocksTgt (replace_externs mu frgSrc' frgTgt') = locBlocksTgt mu.
Lemma replace_externs_extBlocksSrc: forall mu frgSrc' frgTgt',
extBlocksSrc (replace_externs mu frgSrc' frgTgt') = extBlocksSrc mu.
Lemma replace_externs_extBlocksTgt: forall mu frgSrc' frgTgt',
extBlocksTgt (replace_externs mu frgSrc' frgTgt') = extBlocksTgt mu.
Lemma replace_externs_frgnBlocksSrc: forall mu fSrc' fTgt',
frgnBlocksSrc (replace_externs mu fSrc' fTgt') = fSrc'.
Lemma replace_externs_frgnBlocksTgt: forall mu fSrc' fTgt',
frgnBlocksTgt (replace_externs mu fSrc' fTgt') = fTgt'.
Lemma replace_externs_pubBlocksSrc: forall mu frgSrc' frgTgt',
pubBlocksSrc (replace_externs mu frgSrc' frgTgt') = pubBlocksSrc mu.
Lemma replace_externs_pubBlocksTgt: forall mu frgSrc' frgTgt',
pubBlocksTgt (replace_externs mu frgSrc' frgTgt') = pubBlocksTgt mu.
Lemma replace_locals_sharedSrc mu pubSrc' pubTgt': forall
(HPUB1: forall b,  pubSrc' b = true -> local_of mu b <> None)
(HPUB2: forall b,  pubBlocksSrc mu b = true -> pubSrc' b = true),
sharedSrc (replace_locals mu pubSrc' pubTgt') =
fun b => pubSrc' b || sharedSrc mu b.
Lemma replace_externs_wd: forall mu (WD: SM_wd mu) fSrc' fTgt'
(SRC: forall b1, fSrc' b1 = true ->
exists b2 d, extern_of mu b1 = Some(b2,d) /\ fTgt' b2=true)
(TGT: forall b, fTgt' b = true -> extBlocksTgt mu b = true),
SM_wd (replace_externs mu fSrc' fTgt').
Lemma replace_externs_extern: forall mu frgSrc' frgTgt',
extern_of (replace_externs mu frgSrc' frgTgt') = extern_of mu.
Lemma replace_externs_foreign: forall mu frgSrc' frgTgt',
foreign_of (replace_externs mu frgSrc' frgTgt') =
fun b : block => if frgSrc' b then extern_of mu b else None.
Lemma replace_externs_local: forall mu frgSrc' frgTgt',
local_of (replace_externs mu frgSrc' frgTgt') = local_of mu.
Lemma replace_externs_priv: forall mu frgSrc' frgTgt',
priv_of (replace_externs mu frgSrc' frgTgt') = priv_of mu.
Lemma replace_externs_pub: forall mu frgSrc' frgTgt',
pub_of (replace_externs mu frgSrc' frgTgt') = pub_of mu.
Lemma replace_externs_as_inj: forall mu frgSrc' frgTgt',
as_inj (replace_externs mu frgSrc' frgTgt') = as_inj mu.
Lemma replace_externs_DOM: forall mu frgSrc' frgTgt',
DOM (replace_externs mu frgSrc' frgTgt') = DOM mu.
Lemma replace_externs_RNG: forall mu frgSrc' frgTgt',
RNG (replace_externs mu frgSrc' frgTgt') = RNG mu.
Lemma replace_externs_DomSrc: forall mu frgSrc' frgTgt',
DomSrc (replace_externs mu frgSrc' frgTgt') = DomSrc mu.
Lemma replace_externs_DomTgt: forall mu frgSrc' frgTgt',
DomTgt (replace_externs mu frgSrc' frgTgt') = DomTgt mu.
Lemma replace_externs_locBlocksSrc: forall mu frgSrc' frgTgt',
locBlocksSrc (replace_externs mu frgSrc' frgTgt') = locBlocksSrc mu.
Lemma replace_externs_locBlocksTgt: forall mu frgSrc' frgTgt',
locBlocksTgt (replace_externs mu frgSrc' frgTgt') = locBlocksTgt mu.
Lemma replace_externs_extBlocksSrc: forall mu frgSrc' frgTgt',
extBlocksSrc (replace_externs mu frgSrc' frgTgt') = extBlocksSrc mu.
Lemma replace_externs_extBlocksTgt: forall mu frgSrc' frgTgt',
extBlocksTgt (replace_externs mu frgSrc' frgTgt') = extBlocksTgt mu.
Lemma replace_externs_frgnBlocksSrc: forall mu fSrc' fTgt',
frgnBlocksSrc (replace_externs mu fSrc' fTgt') = fSrc'.
Lemma replace_externs_frgnBlocksTgt: forall mu fSrc' fTgt',
frgnBlocksTgt (replace_externs mu fSrc' fTgt') = fTgt'.
Lemma replace_externs_pubBlocksSrc: forall mu frgSrc' frgTgt',
pubBlocksSrc (replace_externs mu frgSrc' frgTgt') = pubBlocksSrc mu.
Lemma replace_externs_pubBlocksTgt: forall mu frgSrc' frgTgt',
pubBlocksTgt (replace_externs mu frgSrc' frgTgt') = pubBlocksTgt mu.