(** Preservation of a global environment by a memory injection *)
Inductive globalenv_preserved {F V: Type} (ge: Genv.t F V) (j: meminj) (bound: block) : Prop :=
| globalenv_preserved_intro
(DOMAIN: forall b, Plt b bound -> j b = Some(b, 0))
(IMAGE: forall b1 b2 delta, j b1 = Some(b2, delta) -> Plt b2 bound -> b1 = b2)
(SYMBOLS: forall id b, Genv.find_symbol ge id = Some b -> Plt b bound)
(FUNCTIONS: forall b fd, Genv.find_funct_ptr ge b = Some fd -> Plt b bound)
(VARINFOS: forall b gv, Genv.find_var_info ge b = Some gv -> Plt b bound).
Program Definition globalenv_inject {F V: Type} (ge: Genv.t F V) (j: meminj) : massert := {|
m_pred := fun m => exists bound, Ple bound (Mem.nextblock m) /\ globalenv_preserved ge j bound;
m_footprint := fun b ofs => False
|}.
Next Obligation.
rename H into bound. exists bound; split; auto. eapply Ple_trans; eauto. eapply Mem.unchanged_on_nextblock; eauto.
Qed.
Next Obligation.
tauto.
Qed.

Lemma globalenv_inject_incr:
forall j m0 (F V: Type) (ge: Genv.t F V) m j' P,
inject_incr j j' ->
inject_separated j j' m0 m ->
m |= globalenv_inject ge j ** P ->
m |= globalenv_inject ge j' ** P.