Remark in_norepet_unique:
  forall id g (gl: list (ident * globdef F V)),
  In (id, g) gl -> list_norepet (map fst gl) ->
  exists gl1 gl2, gl = gl1 ++ (id, g) :: gl2 /\ ~In id (map fst gl2).

(* Specifications: *)
Lemma add_globals_norepet_ensures: forall id g gl ge, (forall ge id1 g1, P ge -> In (id1, g1) gl -> id1 <> id -> P (add_global ge (id1, g1))) -> (forall ge, P (add_global ge (id, g))) -> In (id, g) gl -> list_norepet (map fst gl) -> P (add_globals ge gl).
Theorem public_symbol_exists: forall ge id, public_symbol ge id = true -> exists b, find_symbol ge id = Some b.
Theorem shift_symbol_address: forall ge id ofs delta, symbol_address ge id (Ptrofs.add ofs delta) = Val.offset_ptr (symbol_address ge id ofs) delta.
Theorem shift_symbol_address_32: forall ge id ofs n, Archi.ptr64 = false -> symbol_address ge id (Ptrofs.add ofs (Ptrofs.of_int n)) = Val.add (symbol_address ge id ofs) (Vint n).
Theorem shift_symbol_address_64: forall ge id ofs n, Archi.ptr64 = true -> symbol_address ge id (Ptrofs.add ofs (Ptrofs.of_int64 n)) = Val.addl (symbol_address ge id ofs) (Vlong n).
Theorem find_funct_inv: forall ge v f, find_funct ge v = Some f -> exists b, v = Vptr b Ptrofs.zero.
Theorem find_funct_find_funct_ptr: forall ge b, find_funct ge (Vptr b Ptrofs.zero) = find_funct_ptr ge b.
Theorem find_funct_ptr_iff: forall ge b f, find_funct_ptr ge b = Some f <-> find_def ge b = Some (Gfun f).
Theorem find_var_info_iff: forall ge b v, find_var_info ge b = Some v <-> find_def ge b = Some (Gvar v).
Theorem find_symbol_exists: forall p id g, In (id, g) (prog_defs p) -> exists b, find_symbol (globalenv p) id = Some b.
Theorem find_symbol_inversion : forall p x b, find_symbol (globalenv p) x = Some b -> In x (prog_defs_names p).
Theorem find_def_inversion: forall p b g, find_def (globalenv p) b = Some g -> exists id, In (id, g) (prog_defs p).
Lemma add_globals_norepet_ensures: forall id g gl ge, (forall ge id1 g1, P ge -> In (id1, g1) gl -> id1 <> id -> P (add_global ge (id1, g1))) -> (forall ge, P (add_global ge (id, g))) -> In (id, g) gl -> list_norepet (map fst gl) -> P (add_globals ge gl).
Theorem public_symbol_exists: forall ge id, public_symbol ge id = true -> exists b, find_symbol ge id = Some b.
Theorem shift_symbol_address: forall ge id ofs delta, symbol_address ge id (Ptrofs.add ofs delta) = Val.offset_ptr (symbol_address ge id ofs) delta.
Theorem shift_symbol_address_32: forall ge id ofs n, Archi.ptr64 = false -> symbol_address ge id (Ptrofs.add ofs (Ptrofs.of_int n)) = Val.add (symbol_address ge id ofs) (Vint n).
Theorem shift_symbol_address_64: forall ge id ofs n, Archi.ptr64 = true -> symbol_address ge id (Ptrofs.add ofs (Ptrofs.of_int64 n)) = Val.addl (symbol_address ge id ofs) (Vlong n).
Theorem find_funct_inv: forall ge v f, find_funct ge v = Some f -> exists b, v = Vptr b Ptrofs.zero.
Theorem find_funct_find_funct_ptr: forall ge b, find_funct ge (Vptr b Ptrofs.zero) = find_funct_ptr ge b.
Theorem find_funct_ptr_iff: forall ge b f, find_funct_ptr ge b = Some f <-> find_def ge b = Some (Gfun f).
Theorem find_var_info_iff: forall ge b v, find_var_info ge b = Some v <-> find_def ge b = Some (Gvar v).
Theorem find_symbol_exists: forall p id g, In (id, g) (prog_defs p) -> exists b, find_symbol (globalenv p) id = Some b.
Theorem find_symbol_inversion : forall p x b, find_symbol (globalenv p) x = Some b -> In x (prog_defs_names p).
Theorem find_def_inversion: forall p b g, find_def (globalenv p) b = Some g -> exists id, In (id, g) (prog_defs p).