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_afterExternal: forall (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') (GDE : genvs_domain_eq ge tge) mu st1 st2 m1 e vals1 m2 ef_sig vals2 e' ef_sig' (MemInjMu : Mem.inject (as_inj mu) m1 m2) (MatchMu: MATCH st1 mu st1 m1 st2 m2) (AtExtSrc : at_external (clight_eff_sem FE FE_FWD FE_UNCH) st1 = Some (e, ef_sig, vals1)) (AtExtTgt : at_external csharpmin_eff_sem st2 = Some (e', ef_sig', vals2)) (ValInjMu : Forall2 (val_inject (restrict (as_inj mu) (vis mu))) vals1 vals2) (pubSrc' : block -> bool) (pubSrcHyp : pubSrc' = (fun b : block => locBlocksSrc mu b && REACH m1 (exportedSrc mu vals1) b)) (pubTgt' : block -> bool) (pubTgtHyp: pubTgt' = (fun b : 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' : block -> bool) (frgnSrcHyp: frgnSrc' = (fun b : block => DomSrc nu' b && (negb (locBlocksSrc nu' b) && REACH m1' (exportedSrc nu' (ret1 :: nil)) b))) (frgnTgt' : block -> bool) (frgnTgtHyp: frgnTgt' = (fun b : 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 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' : CL_core) (st2' : CSharpMin_core), after_external (clight_eff_sem FE FE_FWD FE_UNCH) (Some ret1) st1 =Some st1' /\ after_external csharpmin_eff_sem (Some ret2) st2 = Some st2' /\ MATCH st1' mu' st1' m1' st2' m2'.