Program Definition empty_genv (pub: list ident): t :=
@mkgenv pub (PTree.empty _) (PTree.empty _) 1%positive _ _ _.
Next Obligation.
rewrite PTree.gempty in H. discriminate.
Qed.
Next Obligation.
rewrite PTree.gempty in H. discriminate.
Qed.
Next Obligation.
rewrite PTree.gempty in H. discriminate.
Qed.
Definition globalenv (p: program F V) :=
add_globals (empty_genv p.(prog_public)) p.(prog_defs).
(** Proof principles *)
Section GLOBALENV_PRINCIPLES.
Variable P: t -> Prop.

(* Specifications: *)
Lemma add_globals_preserves:
forall gl ge,
(forall ge id g, P ge -> In (id, g) gl -> P (add_global ge (id, g))) ->
P ge -> P (add_globals ge gl).
Lemma add_globals_ensures:
forall id g gl ge,
(forall ge id g, P ge -> In (id, g) gl -> P (add_global ge (id, g))) ->
(forall ge, P (add_global ge (id, g))) ->
In (id, g) gl -> P (add_globals ge gl).
Lemma add_globals_unique_preserves:
forall id gl ge,
(forall ge id1 g, P ge -> In (id1, g) gl -> id1 <> id -> P (add_global ge (id1, g))) ->
~In id (map fst gl) -> P ge -> P (add_globals ge gl).
Lemma add_globals_unique_ensures:
forall gl1 id g gl2 ge,
(forall ge id1 g1, P ge -> In (id1, g1) gl2 -> id1 <> id -> P (add_global ge (id1, g1))) ->
(forall ge, P (add_global ge (id, g))) ->
~In id (map fst gl2) -> P (add_globals ge (gl1 ++ (id, g) :: gl2)).
Lemma add_globals_preserves:
forall gl ge,
(forall ge id g, P ge -> In (id, g) gl -> P (add_global ge (id, g))) ->
P ge -> P (add_globals ge gl).
Lemma add_globals_ensures:
forall id g gl ge,
(forall ge id g, P ge -> In (id, g) gl -> P (add_global ge (id, g))) ->
(forall ge, P (add_global ge (id, g))) ->
In (id, g) gl -> P (add_globals ge gl).
Lemma add_globals_unique_preserves:
forall id gl ge,
(forall ge id1 g, P ge -> In (id1, g) gl -> id1 <> id -> P (add_global ge (id1, g))) ->
~In id (map fst gl) -> P ge -> P (add_globals ge gl).
Lemma add_globals_unique_ensures:
forall gl1 id g gl2 ge,
(forall ge id1 g1, P ge -> In (id1, g1) gl2 -> id1 <> id -> P (add_global ge (id1, g1))) ->
(forall ge, P (add_global ge (id, g))) ->
~In id (map fst gl2) -> P (add_globals ge (gl1 ++ (id, g) :: gl2)).