Definition MATCH (d:CL_core) mu c1 m1 c2 m2:Prop :=
match_states (restrict (as_inj mu) (vis mu)) c1 m1 c2 m2 /\
REACH_closed m1 (vis mu) /\
meminj_preserves_globals ge (as_inj mu) /\
globalfunction_ptr_inject (as_inj mu) /\
(forall b, isGlobalBlock ge b = true -> frgnBlocksSrc mu b = true) /\
sm_valid mu m1 m2 /\ SM_wd mu /\ Mem.inject (as_inj mu) m1 m2.

Lemma MATCH_initial: forall v1 v2 sig entrypoints
(EP: In (v1, v2, sig) entrypoints)
(entry_points_ok : forall (v1 v2 : val) (sig : signature),
In (v1, v2, sig) entrypoints ->
exists b f1 f2,
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 c1 m1 j vals2 m2 (DomS DomT : block -> bool)
(FE : Clight.function -> list val -> mem -> Clight.env -> Clight.temp_env -> mem -> Prop)
(FE_FWD : forall f vargs m e lenv m', FE f vargs m e lenv m' ->
mem_forward m m')
(FE_UNCH : forall f vargs m e lenv m', FE f vargs m e lenv m' ->
Mem.unchanged_on
(fun (b : block) (z : Z) => EmptyEffect b z = false) m m')
(Ini: initial_core (clight_eff_sem FE FE_FWD FE_UNCH) 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 delta, j b1 = Some (b2, delta) ->
(DomS b1 = true /\ DomT b2 = true))
(RCH: forall b, REACH m2
(fun b' : 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 : block, DomS b = true -> Mem.valid_block m1 b)
(HDomT: forall b : block, DomT b = true -> Mem.valid_block m2 b),
exists c2,
initial_core csharpmin_eff_sem tge v2 vals2 = Some c2 /\
MATCH c1
(initial_SM DomS DomT
(REACH m1 (fun b : block => isGlobalBlock ge b || getBlocks vals1 b))
(REACH m2 (fun b : block => isGlobalBlock tge b || getBlocks vals2 b))
j) c1 m1 c2 m2.