(*FreshS/T: fresh blocks in src/tgt language*)
Definition sm_add_intern (mu: SM_Injection) j FreshS FreshT : SM_Injection :=
Build_SM_Injection (fun b => locBlocksSrc mu b || FreshS b)
(fun b => locBlocksTgt mu b || FreshT b)
(pubBlocksSrc mu) (pubBlocksTgt mu)
(join (local_of mu) (fun b => match extern_of mu b with
None => j b | Some _ => None end))
(extBlocksSrc mu) (extBlocksTgt mu)
(frgnBlocksSrc mu) (frgnBlocksTgt mu) (extern_of mu).

Lemma Match_AfterExternal:
forall mu st1 st2 m1 e vals1 m2 ef_sig vals2 e' ef_sig'
(MemInjMu : Mem.inject (as_inj mu) m1 m2)
(MatchMu : Match_cores st1 mu st1 m1 st2 m2)
(AtExtSrc : at_external cmin_eff_sem st1 = Some (e, ef_sig, vals1))
(AtExtTgt : at_external cminsel_eff_sem st2 = Some (e', ef_sig', vals2))
(ValInjMu : Forall2 (val_inject (restrict (as_inj mu) (vis mu))) vals1 vals2)
(pubSrc' : Values.block -> bool)
(pubSrcHyp : pubSrc' =
(fun b : Values.block =>
locBlocksSrc mu b && REACH m1 (exportedSrc mu vals1) b))
(pubTgt' : Values.block -> bool)
(pubTgtHyp : pubTgt' =
(fun b : Values.block =>
locBlocksTgt mu b && REACH m2 (exportedTgt mu vals2) b))
nu
(NuHyp : nu = replace_locals mu pubSrc' pubTgt')
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' : Values.block -> bool)
(frgnSrcHyp : frgnSrc' =
(fun b : Values.block =>
DomSrc nu' b &&
(negb (locBlocksSrc nu' b) &&
REACH m1' (exportedSrc nu' (ret1 :: nil)) b)))
(frgnTgt' : Values.block -> bool)
(frgnTgtHyp : frgnTgt' =
(fun b : Values.block =>
DomTgt nu' b &&
(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 : Values.block) (_ : Z) =>
locBlocksSrc nu b = true /\ pubBlocksSrc nu b = false) m1
m1')
(UnchLOOR : Mem.unchanged_on (local_out_of_reach nu m1) m2 m2'),
exists (st1' : CMin_core) (st2' : CMinSel_core),
after_external cmin_eff_sem (Some ret1) st1 = Some st1' /\
after_external cminsel_eff_sem (Some ret2) st2 = Some st2' /\
Match_cores st1' mu' st1' m1' st2' m2'.