Fixpoint init_data_list2pred  (dl: list init_data)
(sh: share) (v: val)  : environ -> pred rmap :=
match dl with
| d::dl' =>
lift2 sepcon (init_data2pred d sh v)
(init_data_list2pred dl' sh (offset_val (init_data_size d) v))
| nil => lift0 emp
end.
Definition readonly2share (rdonly: bool) : share :=
if rdonly then Ers else Ews.
Definition globals_of_env (rho: environ) (i: ident) : val :=
match Map.get (ge_of rho) i with Some b => Vptr b Ptrofs.zero | None => Vundef end.
Definition globvar2pred (gv: ident->val) (idv: ident * globvar type) : assert :=
if (gvar_volatile (snd idv))
then  lift0 TT
else    init_data_list2pred (gvar_init (snd idv))
(readonly2share (gvar_readonly (snd idv))) (gv (fst idv)).
Definition globvars2pred (gv: ident->val) (vl: list (ident * globvar type)) : assert :=
(lift2 andp) (fun rho => prop (gv = globals_of_env rho))
(fold_right (lift2 sepcon) (lift0 emp) (map (globvar2pred gv) vl)).

(* Specifications: *)
Lemma globvars2pred_rev:
forall gv l, globvars2pred gv (rev l) = globvars2pred gv l.
Lemma writable_blocks_rev:
forall rho l, writable_blocks l rho = writable_blocks (rev l) rho.
Lemma add_variables_nextblock:
forall F V vl (ge: Genv.t F V) i g ul, list_norepet (map (@fst _ _) (vl++(i,g)::ul)) ->
Genv.find_symbol (Genv.add_globals ge (vl++(i,g)::ul)) i =
Some (Genv.advance_next vl (Genv.genv_next ge)).