(*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_init_cores: forall (v1 v2 : val) (sig : signature) entrypoints
(EP: In (v1, v2, sig) entrypoints)
(entry_points_ok : forall (v1 v2 : val) (sig : signature),
In (v1, v2, sig) entrypoints ->
exists
(b : Values.block) (f1 : Cminor.fundef) (f2 : fundef),
v1 = Vptr b Int.zero /\
v2 = Vptr b Int.zero /\
Genv.find_funct_ptr ge b = Some f1 /\
Genv.find_funct_ptr tge b = Some f2)
(vals1 : list val) (c1 : CMin_core) (m1 : mem) (j : meminj)
(vals2 : list val) (m2 : mem) (DomS DomT : Values.block -> bool)
(CSM_Ini :initial_core cmin_eff_sem ge v1 vals1 = Some c1)
(Inj: Mem.inject j m1 m2)
(VInj: Forall2 (val_inject j) vals1 vals2)
(PG: meminj_preserves_globals ge j)
(R : list_norepet (map fst (prog_defs prog)))
(J: forall b1 b2 d, j b1 = Some (b2, d) ->
DomS b1 = true /\ DomT b2 = true)
(RCH: forall b, REACH m2
(fun b' : Values.block => isGlobalBlock tge b' || getBlocks vals2 b') b =
true -> DomT b = true)
(InitMem : exists m0 : mem, Genv.init_mem prog = Some m0
/\ Ple (Mem.nextblock m0) (Mem.nextblock m1)
/\ Ple (Mem.nextblock m0) (Mem.nextblock m2))
(GDE: genvs_domain_eq ge tge)
(HDomS: forall b : Values.block, DomS b = true -> Mem.valid_block m1 b)
(HDomT: forall b : Values.block, DomT b = true -> Mem.valid_block m2 b),
exists c2 : CMinSel_core,
initial_core cminsel_eff_sem tge v2 vals2 = Some c2 /\
Match_cores c1
(initial_SM DomS DomT
(REACH m1
(fun b : Values.block => isGlobalBlock ge b || getBlocks vals1 b))
(REACH m2
(fun b : Values.block => isGlobalBlock tge b || getBlocks vals2 b))
j) c1 m1 c2 m2.