(** * Globals separated *)
(** globals_separate is an invariant enforcing that newly allocated blocks are NOT mapped to global blocks. It is used to re-establish meminj_preserves_globals in the after external diagram. In that sense it replaces sm_inject_separated (jan 2015). *)
Definition globals_separate {F V:Type} (ge: Genv.t F V) mu nu :=
forall b1 b2 d, as_inj mu b1 = None ->
as_inj nu b1 =Some(b2,d) ->
isGlobalBlock ge b2 = false.
intros ? ? mu ge b1 b2 d map1 map2.
rewrite map1 in map2; discriminate.
Qed.
intros ? ? ? ? mu mu' ge1 ge2 gsep geq b1 b2 d map1 map2.
rewrite <- (genvs_domain_eq_isGlobal _ _ geq).
eapply gsep; eauto.
Qed.
intros ? ? ge mu mu' mu'' incr gsep12 gsep23 b1 b3 d3 map1 map3.
destruct (as_inj mu' b1) as [[b2 d2]|] eqn: map2.
+ eapply gsep12.
- eassumption.
- rewrite (incr b1 b2 d2 map2) in map3; inversion map3. subst; eassumption.
+ eapply gsep23; eauto.
Qed.
intros ? ? ge mu mu' mu'' smwd incr gsep12 gsep23 b1 b3 d3 map1 map3.
assert (INCR: Values.inject_incr (as_inj mu') (as_inj mu'')) by (apply intern_incr_as_inj; auto).
eapply gsep_trans; eauto.
Qed.

Lemma intern_incr_globals_separate
{F V:Type} (ge: Genv.t F V) mu nu:
forall (INC: intern_incr mu nu)
(PG: meminj_preserves_globals ge (as_inj mu))
(GF: forall b, isGlobalBlock ge b = true -> frgnBlocksSrc mu b = true)
(WD: SM_wd mu) (WDnu: SM_wd nu),
globals_separate ge mu nu.