Require Import VST.floyd.base2.
Require Import VST.floyd.client_lemmas.
Require Import VST.floyd.nested_field_lemmas.
Require Import VST.floyd.mapsto_memory_block.
Require Import VST.floyd.reptype_lemmas.
Require Import VST.floyd.data_at_rec_lemmas.
Require Import VST.floyd.field_at.
Require Import VST.floyd.field_compat.
Require Import VST.floyd.closed_lemmas.
Require Import VST.floyd.nested_pred_lemmas.
(*Require Import VST.floyd.unfold_data_at.*)
Local Open Scope logic.

Fixpoint fold_right_sepcon' (l: list(environ->mpred)) : environ -> mpred :=
 match l with
 | nil => emp
 | b::nil => b
 | b::r => b * fold_right_sepcon' r
 end.

Lemma fold_right_sepcon'_eq:
  fold_right_sepcon' = @fold_right (environ->mpred) _ sepcon emp.
Proof.
(* Goal: @eq (forall (_ : list (forall _ : environ, mpred)) (_ : environ), mpred) fold_right_sepcon' (@fold_right (forall _ : environ, mpred) (forall _ : environ, mpred) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric)) (@emp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric))) *)
extensionality l rho.
(* Goal: @eq mpred (fold_right_sepcon' l rho) (@fold_right (forall _ : environ, mpred) (forall _ : environ, mpred) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric)) (@emp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric)) l rho) *)
induction l; auto.
(* Goal: Z.le (init_data_size (Init_space (@sizeof (@cenv_cs cs) t))) (@sizeof (@cenv_cs cs) t) *)
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (locald_denote (gvars gz))) PQR) (globvars2pred gz (@cons (prod ident (globvar type)) (@pair ident (globvar type) i gv) gvs))) SF)) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (LiftEnviron mpred) (@data_at_ cs (readonly2share (@gvar_readonly type gv)) t (gz i))) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (locald_denote (gvars gz))) PQR)) (globvars2pred gz gvs)) SF) *)
simpl.
(* Goal: Z.le (init_data_size (Init_space (@sizeof (@cenv_cs cs) t))) (@sizeof (@cenv_cs cs) t) *)
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (locald_denote (gvars gz))) PQR) (globvars2pred gz (@cons (prod ident (globvar type)) (@pair ident (globvar type) i gv) gvs))) SF)) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (LiftEnviron mpred) (@data_at_ cs (readonly2share (@gvar_readonly type gv)) t (gz i))) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (locald_denote (gvars gz))) PQR)) (globvars2pred gz gvs)) SF) *)
destruct l. simpl. rewrite sepcon_emp. auto.
(* Goal: @eq val match p with | Vundef => Vundef | Vint i => Vundef | Vlong i => Vundef | Vfloat f => Vundef | Vsingle f => Vundef | Vptr b z => Vptr b (Ptrofs.repr (Z.add (Ptrofs.unsigned z) (Ptrofs.unsigned (Ptrofs.repr i)))) end match p with | Vundef => Vundef | Vint i => Vundef | Vlong i => Vundef | Vfloat f => Vundef | Vsingle f => Vundef | Vptr b z => Vptr b (Ptrofs.repr (Z.add (Ptrofs.unsigned z) (Ptrofs.unsigned (Ptrofs.repr i)))) end *)
f_equal; auto.
Qed.


Lemma orp_dup {A}{ND: NatDed A}: forall P: A, P || P = P.
(* Goal: forall (cs : compspecs) (Espec : OracleKind) (Delta : tycontext) (PQR : forall _ : environ, mpred) (gv : globals) (SF : forall _ : environ, mpred) (c : statement) (Post : ret_assert) (_ : semax cs Espec Delta (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) PQR SF) c Post), semax cs Espec Delta (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) PQR (globvars2pred gv (@nil (prod ident (globvar type))))) SF) c Post *)
Proof. intros. apply pred_ext.
(* Goal: @derives A ND (@orp A ND P P) P *)
(* Goal: @derives A ND P (@orp A ND P P) *)
apply orp_left; apply derives_refl.
(* Goal: @derives A ND P (@orp A ND P P) *)
apply orp_right1; apply derives_refl.
Qed.

Lemma unsigned_repr_range: forall i, 0 <= i -> 0 <= Ptrofs.unsigned (Ptrofs.repr i) <= i.
Proof.
(* Goal: forall (cs : compspecs) (Espec : OracleKind) (Delta : tycontext) (PQR : forall _ : environ, mpred) (gv : globals) (SF : forall _ : environ, mpred) (c : statement) (Post : ret_assert) (_ : semax cs Espec Delta (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) PQR SF) c Post), semax cs Espec Delta (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) PQR (globvars2pred gv (@nil (prod ident (globvar type))))) SF) c Post *)
  intros.
(* Goal: and (Z.le Z0 (Ptrofs.unsigned (Ptrofs.repr i))) (Z.le (Ptrofs.unsigned (Ptrofs.repr i)) i) *)
  rewrite Ptrofs.unsigned_repr_eq.
(* Goal: and (Z.le Z0 (Z.modulo i Ptrofs.modulus)) (Z.le (Z.modulo i Ptrofs.modulus) i) *)
  pose proof Z.mod_le i Ptrofs.modulus H.
(* Goal: and (Z.le Z0 (Z.modulo i Ptrofs.modulus)) (Z.le (Z.modulo i Ptrofs.modulus) i) *)
  pose proof Z.mod_bound_pos i Ptrofs.modulus H.
(* Goal: and (Z.le Z0 (Z.modulo i Ptrofs.modulus)) (Z.le (Z.modulo i Ptrofs.modulus) i) *)
  set (x := Ptrofs.modulus) in *.
(* Goal: and (Z.le Z0 (Z.modulo i x)) (Z.le (Z.modulo i x) i) *)
 revert x H0 H1.
(* Goal: let x := Ptrofs.modulus in forall (_ : forall _ : Z.lt Z0 x, Z.le (Z.modulo i x) i) (_ : forall _ : Z.lt Z0 x, and (Z.le Z0 (Z.modulo i x)) (Z.lt (Z.modulo i x) x)), and (Z.le Z0 (Z.modulo i x)) (Z.le (Z.modulo i x) i) *)
  rewrite Ptrofs.modulus_power.
(* Goal: forall (cs : compspecs) (Espec : OracleKind) (Delta : tycontext) (PQR : forall _ : environ, mpred) (gv : globals) (SF : forall _ : environ, mpred) (c : statement) (Post : ret_assert) (_ : semax cs Espec Delta (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) PQR SF) c Post), semax cs Espec Delta (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) PQR (globvars2pred gv (@nil (prod ident (globvar type))))) SF) c Post *)
 intros.
  unfold Ptrofs.zwordsize,  Ptrofs.wordsize, Wordsize_Ptrofs.wordsize in x.
  destruct (Archi.ptr64);
  (compute in x; subst x; spec H0; [omega| ]; spec H1; omega).
Qed.

Lemma tc_globalvar_sound:
  forall Delta i t gz idata rho,
   (var_types Delta) ! i = None ->
   (glob_types Delta) ! i = Some t ->
   gvar_volatile gz = false ->
   gvar_init gz = idata ->
   tc_environ Delta rho ->
   globvar2pred (globals_of_env rho) (i, gz) rho |-- init_data_list2pred idata (readonly2share (gvar_readonly gz)) (eval_var i t rho) rho.
Proof.
(* Goal: forall (cs : compspecs) (Espec : OracleKind) (Delta : tycontext) (PQR : forall _ : environ, mpred) (gv : globals) (SF : forall _ : environ, mpred) (c : statement) (Post : ret_assert) (_ : semax cs Espec Delta (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) PQR SF) c Post), semax cs Espec Delta (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) PQR (globvars2pred gv (@nil (prod ident (globvar type))))) SF) c Post *)
intros.
(* Goal: @derives mpred Nveric (globvar2pred (globals_of_env rho) (@pair positive (globvar type) i gv) rho) (init_data_list2pred idata (readonly2share (@gvar_readonly type gv)) (globals_of_env rho i) rho) *)
unfold globvar2pred.
(* Goal: Z.le (init_data_size (Init_space (@sizeof (@cenv_cs cs) t))) (@sizeof (@cenv_cs cs) t) *)
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (locald_denote (gvars gz))) PQR) (globvars2pred gz (@cons (prod ident (globvar type)) (@pair ident (globvar type) i gv) gvs))) SF)) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (LiftEnviron mpred) (@data_at_ cs (readonly2share (@gvar_readonly type gv)) t (gz i))) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (locald_denote (gvars gz))) PQR)) (globvars2pred gz gvs)) SF) *)
simpl.
(* Goal: @derives mpred Nveric ((if @gvar_volatile type gz then @lift0 mpred (@TT mpred Nveric) else init_data_list2pred (@gvar_init type gz) (readonly2share (@gvar_readonly type gz)) (globals_of_env rho i)) rho) (init_data_list2pred idata (readonly2share (@gvar_readonly type gz)) (eval_var i t rho) rho) *)
destruct_var_types i.
(* Goal: @derives mpred Nveric ((if @gvar_volatile type gv then @lift0 mpred (@TT mpred Nveric) else init_data_list2pred (@gvar_init type gv) (readonly2share (@gvar_readonly type gv)) (globals_of_env rho i)) rho) (init_data_list2pred idata (readonly2share (@gvar_readonly type gv)) (globals_of_env rho i) rho) *)
destruct_glob_types i.
(* Goal: @eq val (offset_val Z0 (globals_of_env rho i)) (globals_of_env rho i) *)
unfold globals_of_env.
(* Goal: @derives mpred Nveric ((if @gvar_volatile type gz then @lift0 mpred (@TT mpred Nveric) else init_data_list2pred (@gvar_init type gz) (readonly2share (@gvar_readonly type gz)) match @Map.get block (ge_of rho) i with | Some b => Vptr b Ptrofs.zero | None => Vundef end) rho) (init_data_list2pred idata (readonly2share (@gvar_readonly type gz)) (eval_var i t rho) rho) *)
unfold eval_var.
(* Goal: @derives mpred Nveric ((if @gvar_volatile type gz then @lift0 mpred (@TT mpred Nveric) else init_data_list2pred (@gvar_init type gz) (readonly2share (@gvar_readonly type gz)) match @Map.get block (ge_of rho) i with | Some b => Vptr b Ptrofs.zero | None => Vundef end) rho) (init_data_list2pred idata (readonly2share (@gvar_readonly type gz)) match @Map.get (prod block type) (ve_of rho) i with | Some (pair b ty' as p) => if eqb_type t ty' then Vptr b Ptrofs.zero else Vundef | None => match @Map.get block (ge_of rho) i with | Some b => Vptr b Ptrofs.zero | None => Vundef end end rho) *)
rewrite Heqo0, Heqo1, H1, H2.
(* Goal: @eq val match p with | Vundef => Vundef | Vint i => Vundef | Vlong i => Vundef | Vfloat f => Vundef | Vsingle f => Vundef | Vptr b z => Vptr b (Ptrofs.repr (Z.add (Ptrofs.unsigned z) (Ptrofs.unsigned (Ptrofs.repr i)))) end match p with | Vundef => Vundef | Vint i => Vundef | Vlong i => Vundef | Vfloat f => Vundef | Vsingle f => Vundef | Vptr b z => Vptr b (Ptrofs.repr (Z.add (Ptrofs.unsigned z) (Ptrofs.unsigned (Ptrofs.repr i)))) end *)
auto.
Qed.

Lemma tc_globalvar_sound':
  forall Delta i t gv idata rho,
   (var_types Delta) ! i = None ->
   (glob_types Delta) ! i = Some t ->
   gvar_volatile gv = false ->
   gvar_init gv = idata ->
   tc_environ Delta rho ->
   globvar2pred (globals_of_env rho)  (i, gv) rho |--
   init_data_list2pred idata (readonly2share (gvar_readonly gv)) (globals_of_env rho i) rho.
Proof.
(* Goal: forall (cs : compspecs) (Espec : OracleKind) (Delta : tycontext) (PQR : forall _ : environ, mpred) (gv : globals) (SF : forall _ : environ, mpred) (c : statement) (Post : ret_assert) (_ : semax cs Espec Delta (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) PQR SF) c Post), semax cs Espec Delta (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) PQR (globvars2pred gv (@nil (prod ident (globvar type))))) SF) c Post *)
intros.
(* Goal: @derives mpred Nveric (globvar2pred (globals_of_env rho) (@pair positive (globvar type) i gv) rho) (init_data_list2pred idata (readonly2share (@gvar_readonly type gv)) (globals_of_env rho i) rho) *)
unfold globvar2pred.
(* Goal: Z.le (init_data_size (Init_space (@sizeof (@cenv_cs cs) t))) (@sizeof (@cenv_cs cs) t) *)
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (locald_denote (gvars gz))) PQR) (globvars2pred gz (@cons (prod ident (globvar type)) (@pair ident (globvar type) i gv) gvs))) SF)) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (LiftEnviron mpred) (@data_at_ cs (readonly2share (@gvar_readonly type gv)) t (gz i))) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (locald_denote (gvars gz))) PQR)) (globvars2pred gz gvs)) SF) *)
simpl.
(* Goal: @derives mpred Nveric ((if @gvar_volatile type gv then @lift0 mpred (@TT mpred Nveric) else init_data_list2pred (@gvar_init type gv) (readonly2share (@gvar_readonly type gv)) (globals_of_env rho i)) rho) (init_data_list2pred idata (readonly2share (@gvar_readonly type gv)) (globals_of_env rho i) rho) *)
destruct_glob_types i.
(* Goal: @eq val (offset_val Z0 (globals_of_env rho i)) (globals_of_env rho i) *)
unfold globals_of_env.
(* Goal: @derives mpred Nveric ((if @gvar_volatile type gv then @lift0 mpred (@TT mpred Nveric) else init_data_list2pred (@gvar_init type gv) (readonly2share (@gvar_readonly type gv)) match @Map.get block (ge_of rho) i with | Some b => Vptr b Ptrofs.zero | None => Vundef end) rho) (init_data_list2pred idata (readonly2share (@gvar_readonly type gv)) match @Map.get block (ge_of rho) i with | Some b => Vptr b Ptrofs.zero | None => Vundef end rho) *)
rewrite Heqo0, H1, H2.
(* Goal: @eq val match p with | Vundef => Vundef | Vint i => Vundef | Vlong i => Vundef | Vfloat f => Vundef | Vsingle f => Vundef | Vptr b z => Vptr b (Ptrofs.repr (Z.add (Ptrofs.unsigned z) (Ptrofs.unsigned (Ptrofs.repr i)))) end match p with | Vundef => Vundef | Vint i => Vundef | Vlong i => Vundef | Vfloat f => Vundef | Vsingle f => Vundef | Vptr b z => Vptr b (Ptrofs.repr (Z.add (Ptrofs.unsigned z) (Ptrofs.unsigned (Ptrofs.repr i)))) end *)
auto.
Qed.

Definition zero_of_type (t: type) : val :=
 match t with
  | Tfloat _ _ => Vfloat Float.zero
  | _ => Vint Int.zero
 end.


Definition eval_sgvar (id: ident) (ty: type) (rho: environ) :=
 match Map.get (ge_of rho) id with
| Some b => Vptr b Ptrofs.zero
| None => Vundef
end.
(*
Lemma eval_sgvar_lemma1:
  forall (F: val -> mpred) ofs id t,
    F Vundef |-- FF ->
   `F (`(offset_val ofs) (eval_sgvar id t)) =
   (EX v:val, local (locald_denote (sgvar id v)) && `(F (offset_val ofs v))).
Proof.
(* Goal: forall (cs : compspecs) (Espec : OracleKind) (Delta : tycontext) (PQR : forall _ : environ, mpred) (gv : globals) (SF : forall _ : environ, mpred) (c : statement) (Post : ret_assert) (_ : semax cs Espec Delta (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) PQR SF) c Post), semax cs Espec Delta (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) PQR (globvars2pred gv (@nil (prod ident (globvar type))))) SF) c Post *)
intros.
(* Goal: @eq (forall _ : environ, mpred) (fun rho : environ => @sepcon mpred Nveric Sveric (@andp mpred Nveric (@prop mpred Nveric (@eq globals gv (globals_of_env rho))) (@fold_right (forall _ : environ, mpred) (forall _ : environ, mpred) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric)) (@emp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric)) (@map (prod ident (globvar type)) (forall _ : environ, mpred) (globvar2pred gv) (prog_vars prog)) rho)) (@has_ext (@OK_ty Espec) ora)) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@fold_right Prop Prop and True (@nil Prop))) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (@fold_right (forall _ : lift_S (LiftEnviron Prop), Prop) (forall _ : lift_S (Tarrow Prop (LiftEnviron Prop)), Prop) (@liftx (Tarrow Prop (Tarrow Prop (LiftEnviron Prop))) and) (@liftx (LiftEnviron Prop) True) (@map localdef (forall _ : environ, Prop) locald_denote (@cons localdef (gvars gv) (@nil localdef))))) (fun _ : environ => fold_right_sepcon (@cons (@predicates_hered.pred compcert_rmaps.RML.R.rmap compcert_rmaps.RML.R.ag_rmap) (@has_ext (@OK_ty Espec) ora) (@nil (@predicates_hered.pred compcert_rmaps.RML.R.rmap compcert_rmaps.RML.R.ag_rmap)))))) (fun rho : environ => @andp mpred Nveric (@prop mpred Nveric (@eq globals gv (globals_of_env rho))) (@fold_right (forall _ : environ, mpred) (forall _ : environ, mpred) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric)) (@emp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric)) (@map (prod ident (globvar type)) (forall _ : environ, mpred) (globvar2pred gv) (prog_vars prog)) rho))) *)
extensionality rho.
(* Goal: @derives mpred Nveric (memory_block (readonly2share (@gvar_readonly type gv)) (@sizeof (@cenv_cs cs) t) (globals_of_env rho i)) (@data_at_ cs (readonly2share (@gvar_readonly type gv)) t (globals_of_env rho i)) *)
unfold_lift. unfold local, lift1.
unfold eval_sgvar.
(* Goal: Z.le (init_data_size (Init_space (@sizeof (@cenv_cs cs) t))) (@sizeof (@cenv_cs cs) t) *)
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (locald_denote (gvars gz))) PQR) (globvars2pred gz (@cons (prod ident (globvar type)) (@pair ident (globvar type) i gv) gvs))) SF)) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (LiftEnviron mpred) (@data_at_ cs (readonly2share (@gvar_readonly type gv)) t (gz i))) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (locald_denote (gvars gz))) PQR)) (globvars2pred gz gvs)) SF) *)
simpl.
(* Goal: @eq A (@orp A ND P P) P *)
apply pred_ext.
unfold sgvar_denote.
destruct (Map.get (ge_of rho) id).
apply exp_right with (Vptr b Ptrofs.zero).
(* Goal: semax cs Espec Delta (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (PROPx P (LOCALx Q (SEPx R))) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) val (fun x : val => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (locald_denote (f x))) (@liftx (LiftEnviron mpred) (g (h x) : mpred)))) S2)) S3) S4) c Post *)
normalize.
eapply derives_trans; [ apply H | ].
(* Goal: @derives mpred Nveric (@FF mpred Nveric) (@prop mpred Nveric (Z.divide (align_chunk ch) (Ptrofs.unsigned z))) *)
(* Goal: @derives mpred Nveric (@andp (@predicates_hered.pred compcert_rmaps.RML.R.rmap compcert_rmaps.RML.R.ag_rmap) Nveric (@prop (@predicates_hered.pred compcert_rmaps.RML.R.rmap compcert_rmaps.RML.R.ag_rmap) Nveric (and (tc_val' t p) (Z.divide (align_chunk ch) (Ptrofs.unsigned z)))) (res_predicates.nonlock_permission_bytes sh (@pair block Z b (Ptrofs.unsigned z)) (size_chunk ch))) (@prop mpred Nveric (Z.divide (align_chunk ch) (Ptrofs.unsigned z))) *)
apply FF_left.
unfold sgvar_denote.
(* Goal: semax cs Espec Delta (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (PROPx P (LOCALx Q (SEPx R))) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) val (fun x : val => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (locald_denote (f x))) (@liftx (LiftEnviron mpred) (g (h x) : mpred)))) S2)) S3) S4) c Post *)
apply exp_left; intro; normalize.
destruct (Map.get (ge_of rho) id).
(* Goal: @eq val match p with | Vundef => Vundef | Vint i => Vundef | Vlong i => Vundef | Vfloat f => Vundef | Vsingle f => Vundef | Vptr b z => Vptr b (Ptrofs.repr (Z.add (Ptrofs.unsigned z) (Ptrofs.unsigned (Ptrofs.repr i)))) end match p with | Vundef => Vundef | Vint i => Vundef | Vlong i => Vundef | Vfloat f => Vundef | Vsingle f => Vundef | Vptr b z => Vptr b (Ptrofs.repr (Z.add (Ptrofs.unsigned z) (Ptrofs.unsigned (Ptrofs.repr i)))) end *)
subst. auto.
contradiction.
Qed.
*)
Definition init_data2pred' {cs: compspecs}
     (Delta: tycontext) (gv: globals) (d: init_data)  (sh: share) (v: val) : mpred :=
 match d with
  | Init_int8 i => mapsto sh tuchar v (Vint (Int.zero_ext 8 i))
  | Init_int16 i => mapsto sh tushort v (Vint (Int.zero_ext 16 i))
  | Init_int32 i => mapsto sh tuint v (Vint i)
  | Init_int64 i => mapsto sh tulong v (Vlong i)
  | Init_float32 r =>  mapsto sh tfloat v (Vsingle r)
  | Init_float64 r =>  mapsto sh tdouble v (Vfloat r)
  | Init_space n =>  memory_block sh n v
  | Init_addrof symb ofs =>
      match (var_types Delta) ! symb, (glob_types Delta) ! symb with
      | None, Some (Tarray t n' att) =>
           mapsto sh (Tpointer t noattr) v (offset_val (Ptrofs.unsigned ofs) (gv symb))
      | None, Some t => mapsto sh (Tpointer t noattr) v (offset_val (Ptrofs.unsigned ofs) (gv symb))
      | Some _, Some _ => mapsto_ sh (Tpointer Tvoid noattr) v
      | _, _ => TT
      end
 end.

Lemma unsigned_repr_le: forall i, 0 <= i -> Int.unsigned (Int.repr i) <= i.
Proof.
(* Goal: forall (cs : compspecs) (Espec : OracleKind) (Delta : tycontext) (PQR : forall _ : environ, mpred) (gv : globals) (SF : forall _ : environ, mpred) (c : statement) (Post : ret_assert) (_ : semax cs Espec Delta (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) PQR SF) c Post), semax cs Espec Delta (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) PQR (globvars2pred gv (@nil (prod ident (globvar type))))) SF) c Post *)
  intros.
(* Goal: Z.le (Int.unsigned (Int.repr i)) i *)
  rewrite Int.unsigned_repr_eq.
(* Goal: Z.le (Z.modulo i Int.modulus) i *)
  apply Zmod_le; try assumption.
(* Goal: Z.lt Z0 Int.modulus *)
  pose proof Int.Z_mod_modulus_range i.
(* Goal: Z.lt (@sizeof (@cenv_cs cs) (@gvar_info type gv)) Ptrofs.modulus *)
  omega.
Qed.

Lemma mapsto_aligned:
 forall t ch, access_mode t = By_value ch ->
  forall  sh b z p,
  mapsto sh t (Vptr b z) p
   |-- !! (Memdata.align_chunk ch | Ptrofs.unsigned z).
Proof.
(* Goal: forall (cs : compspecs) (Espec : OracleKind) (Delta : tycontext) (PQR : forall _ : environ, mpred) (gv : globals) (SF : forall _ : environ, mpred) (c : statement) (Post : ret_assert) (_ : semax cs Espec Delta (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) PQR SF) c Post), semax cs Espec Delta (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) PQR (globvars2pred gv (@nil (prod ident (globvar type))))) SF) c Post *)
intros.
(* Goal: Z.le (init_data_size (Init_space (@sizeof (@cenv_cs cs) t))) (@sizeof (@cenv_cs cs) t) *)
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (locald_denote (gvars gz))) PQR) (globvars2pred gz (@cons (prod ident (globvar type)) (@pair ident (globvar type) i gv) gvs))) SF)) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (LiftEnviron mpred) (@data_at_ cs (readonly2share (@gvar_readonly type gv)) t (gz i))) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (locald_denote (gvars gz))) PQR)) (globvars2pred gz gvs)) SF) *)
unfold mapsto. simpl.
(* Goal: @derives mpred Nveric match access_mode t with | By_value ch => if match access_mode t with | By_value m => attr_volatile (attr_of_type t) | By_reference => false | By_copy => false | By_nothing => false end then @FF mpred Nveric else if readable_share_dec sh then @orp (@predicates_hered.pred compcert_rmaps.RML.R.rmap compcert_rmaps.RML.R.ag_rmap) Nveric (@andp (@predicates_hered.pred compcert_rmaps.RML.R.rmap compcert_rmaps.RML.R.ag_rmap) Nveric (@prop (@predicates_hered.pred compcert_rmaps.RML.R.rmap compcert_rmaps.RML.R.ag_rmap) Nveric (tc_val t p)) (res_predicates.address_mapsto ch p sh (@pair block Z b (Ptrofs.unsigned z)))) (@andp (@predicates_hered.pred compcert_rmaps.RML.R.rmap compcert_rmaps.RML.R.ag_rmap) Nveric (@prop (@predicates_hered.pred compcert_rmaps.RML.R.rmap compcert_rmaps.RML.R.ag_rmap) Nveric (@eq val p Vundef)) (@exp (@predicates_hered.pred compcert_rmaps.RML.R.rmap compcert_rmaps.RML.R.ag_rmap) Nveric val (fun v2' : val => res_predicates.address_mapsto ch v2' sh (@pair block Z b (Ptrofs.unsigned z))))) else @andp (@predicates_hered.pred compcert_rmaps.RML.R.rmap compcert_rmaps.RML.R.ag_rmap) Nveric (@prop (@predicates_hered.pred compcert_rmaps.RML.R.rmap compcert_rmaps.RML.R.ag_rmap) Nveric (and (tc_val' t p) (Z.divide (align_chunk ch) (Ptrofs.unsigned z)))) (res_predicates.nonlock_permission_bytes sh (@pair block Z b (Ptrofs.unsigned z)) (size_chunk ch)) | By_reference => @FF mpred Nveric | By_copy => @FF mpred Nveric | By_nothing => @FF mpred Nveric end (@prop mpred Nveric (Z.divide (align_chunk ch) (Ptrofs.unsigned z))) *)
rewrite H.
(* Goal: @derives mpred Nveric (if attr_volatile (attr_of_type t) then @FF mpred Nveric else if readable_share_dec sh then @orp (@predicates_hered.pred compcert_rmaps.RML.R.rmap compcert_rmaps.RML.R.ag_rmap) Nveric (@andp (@predicates_hered.pred compcert_rmaps.RML.R.rmap compcert_rmaps.RML.R.ag_rmap) Nveric (@prop (@predicates_hered.pred compcert_rmaps.RML.R.rmap compcert_rmaps.RML.R.ag_rmap) Nveric (tc_val t p)) (res_predicates.address_mapsto ch p sh (@pair block Z b (Ptrofs.unsigned z)))) (@andp (@predicates_hered.pred compcert_rmaps.RML.R.rmap compcert_rmaps.RML.R.ag_rmap) Nveric (@prop (@predicates_hered.pred compcert_rmaps.RML.R.rmap compcert_rmaps.RML.R.ag_rmap) Nveric (@eq val p Vundef)) (@exp (@predicates_hered.pred compcert_rmaps.RML.R.rmap compcert_rmaps.RML.R.ag_rmap) Nveric val (fun v2' : val => res_predicates.address_mapsto ch v2' sh (@pair block Z b (Ptrofs.unsigned z))))) else @andp (@predicates_hered.pred compcert_rmaps.RML.R.rmap compcert_rmaps.RML.R.ag_rmap) Nveric (@prop (@predicates_hered.pred compcert_rmaps.RML.R.rmap compcert_rmaps.RML.R.ag_rmap) Nveric (and (tc_val' t p) (Z.divide (align_chunk ch) (Ptrofs.unsigned z)))) (res_predicates.nonlock_permission_bytes sh (@pair block Z b (Ptrofs.unsigned z)) (size_chunk ch))) (@prop mpred Nveric (Z.divide (align_chunk ch) (Ptrofs.unsigned z))) *)
if_tac.
(* Goal: @derives mpred Nveric (if attr_volatile (attr_of_type t) then @FF mpred Nveric else if readable_share_dec sh then @orp (@predicates_hered.pred compcert_rmaps.RML.R.rmap compcert_rmaps.RML.R.ag_rmap) Nveric (@andp (@predicates_hered.pred compcert_rmaps.RML.R.rmap compcert_rmaps.RML.R.ag_rmap) Nveric (@prop (@predicates_hered.pred compcert_rmaps.RML.R.rmap compcert_rmaps.RML.R.ag_rmap) Nveric (tc_val t p)) (res_predicates.address_mapsto ch p sh (@pair block Z b (Ptrofs.unsigned z)))) (@andp (@predicates_hered.pred compcert_rmaps.RML.R.rmap compcert_rmaps.RML.R.ag_rmap) Nveric (@prop (@predicates_hered.pred compcert_rmaps.RML.R.rmap compcert_rmaps.RML.R.ag_rmap) Nveric (@eq val p Vundef)) (@exp (@predicates_hered.pred compcert_rmaps.RML.R.rmap compcert_rmaps.RML.R.ag_rmap) Nveric val (fun v2' : val => res_predicates.address_mapsto ch v2' sh (@pair block Z b (Ptrofs.unsigned z))))) else @andp (@predicates_hered.pred compcert_rmaps.RML.R.rmap compcert_rmaps.RML.R.ag_rmap) Nveric (@prop (@predicates_hered.pred compcert_rmaps.RML.R.rmap compcert_rmaps.RML.R.ag_rmap) Nveric (and (tc_val' t p) (Z.divide (align_chunk ch) (Ptrofs.unsigned z)))) (res_predicates.nonlock_permission_bytes sh (@pair block Z b (Ptrofs.unsigned z)) (size_chunk ch))) (@prop mpred Nveric (Z.divide (align_chunk ch) (Ptrofs.unsigned z))) *)
simple_if_tac.
(* Goal: @derives mpred Nveric (@FF mpred Nveric) (@prop mpred Nveric (Z.divide (align_chunk ch) (Ptrofs.unsigned z))) *)
(* Goal: @derives mpred Nveric (@andp (@predicates_hered.pred compcert_rmaps.RML.R.rmap compcert_rmaps.RML.R.ag_rmap) Nveric (@prop (@predicates_hered.pred compcert_rmaps.RML.R.rmap compcert_rmaps.RML.R.ag_rmap) Nveric (and (tc_val' t p) (Z.divide (align_chunk ch) (Ptrofs.unsigned z)))) (res_predicates.nonlock_permission_bytes sh (@pair block Z b (Ptrofs.unsigned z)) (size_chunk ch))) (@prop mpred Nveric (Z.divide (align_chunk ch) (Ptrofs.unsigned z))) *)
apply FF_left.
(* Goal: @derives mpred Nveric (@orp (@predicates_hered.pred compcert_rmaps.RML.R.rmap compcert_rmaps.RML.R.ag_rmap) Nveric (@andp (@predicates_hered.pred compcert_rmaps.RML.R.rmap compcert_rmaps.RML.R.ag_rmap) Nveric (@prop (@predicates_hered.pred compcert_rmaps.RML.R.rmap compcert_rmaps.RML.R.ag_rmap) Nveric (tc_val t p)) (res_predicates.address_mapsto ch p sh (@pair block Z b (Ptrofs.unsigned z)))) (@andp (@predicates_hered.pred compcert_rmaps.RML.R.rmap compcert_rmaps.RML.R.ag_rmap) Nveric (@prop (@predicates_hered.pred compcert_rmaps.RML.R.rmap compcert_rmaps.RML.R.ag_rmap) Nveric (@eq val p Vundef)) (@exp (@predicates_hered.pred compcert_rmaps.RML.R.rmap compcert_rmaps.RML.R.ag_rmap) Nveric val (fun v2' : val => res_predicates.address_mapsto ch v2' sh (@pair block Z b (Ptrofs.unsigned z)))))) (@prop mpred Nveric (Z.divide (align_chunk ch) (Ptrofs.unsigned z))) *)
(* Goal: @derives mpred Nveric (if attr_volatile (attr_of_type t) then @FF mpred Nveric else @andp (@predicates_hered.pred compcert_rmaps.RML.R.rmap compcert_rmaps.RML.R.ag_rmap) Nveric (@prop (@predicates_hered.pred compcert_rmaps.RML.R.rmap compcert_rmaps.RML.R.ag_rmap) Nveric (and (tc_val' t p) (Z.divide (align_chunk ch) (Ptrofs.unsigned z)))) (res_predicates.nonlock_permission_bytes sh (@pair block Z b (Ptrofs.unsigned z)) (size_chunk ch))) (@prop mpred Nveric (Z.divide (align_chunk ch) (Ptrofs.unsigned z))) *)
apply orp_left. normalize. clear H H0.
(* Goal: @derives mpred Nveric (res_predicates.address_mapsto ch v2' sh (@pair block Z b (Ptrofs.unsigned z))) (@prop mpred Nveric (Z.divide (align_chunk ch) (Ptrofs.unsigned z))) *)
(* Goal: @derives mpred Nveric (if attr_volatile (attr_of_type t) then @FF mpred Nveric else @andp (@predicates_hered.pred compcert_rmaps.RML.R.rmap compcert_rmaps.RML.R.ag_rmap) Nveric (@prop (@predicates_hered.pred compcert_rmaps.RML.R.rmap compcert_rmaps.RML.R.ag_rmap) Nveric (and (tc_val' t p) (Z.divide (align_chunk ch) (Ptrofs.unsigned z)))) (res_predicates.nonlock_permission_bytes sh (@pair block Z b (Ptrofs.unsigned z)) (size_chunk ch))) (@prop mpred Nveric (Z.divide (align_chunk ch) (Ptrofs.unsigned z))) *)
rewrite (res_predicates.address_mapsto_align).
(* Goal: @derives mpred Nveric (@predicates_hered.andp compcert_rmaps.RML.R.rmap compcert_rmaps.RML.R.ag_rmap (res_predicates.address_mapsto ch v2' sh (@pair block Z b (Ptrofs.unsigned z))) (@predicates_hered.prop compcert_rmaps.RML.R.rmap compcert_rmaps.RML.R.ag_rmap (Z.divide (align_chunk ch) (@snd block Z (@pair block Z b (Ptrofs.unsigned z)))))) (@prop mpred Nveric (Z.divide (align_chunk ch) (Ptrofs.unsigned z))) *)
(* Goal: @derives mpred Nveric (if attr_volatile (attr_of_type t) then @FF mpred Nveric else @andp (@predicates_hered.pred compcert_rmaps.RML.R.rmap compcert_rmaps.RML.R.ag_rmap) Nveric (@prop (@predicates_hered.pred compcert_rmaps.RML.R.rmap compcert_rmaps.RML.R.ag_rmap) Nveric (and (tc_val' t p) (Z.divide (align_chunk ch) (Ptrofs.unsigned z)))) (res_predicates.nonlock_permission_bytes sh (@pair block Z b (Ptrofs.unsigned z)) (size_chunk ch))) (@prop mpred Nveric (Z.divide (align_chunk ch) (Ptrofs.unsigned z))) *)
match goal with |- ?A |-- ?B => change (predicates_hered.derives A B) end.
(* Goal: @predicates_hered.derives compcert_rmaps.RML.R.rmap compcert_rmaps.RML.R.ag_rmap (@predicates_hered.andp compcert_rmaps.RML.R.rmap compcert_rmaps.RML.R.ag_rmap (res_predicates.address_mapsto ch v2' sh (@pair block Z b (Ptrofs.unsigned z))) (@predicates_hered.prop compcert_rmaps.RML.R.rmap compcert_rmaps.RML.R.ag_rmap (Z.divide (align_chunk ch) (@snd block Z (@pair block Z b (Ptrofs.unsigned z)))))) (@prop mpred Nveric (Z.divide (align_chunk ch) (Ptrofs.unsigned z))) *)
(* Goal: @derives mpred Nveric (if attr_volatile (attr_of_type t) then @FF mpred Nveric else @andp (@predicates_hered.pred compcert_rmaps.RML.R.rmap compcert_rmaps.RML.R.ag_rmap) Nveric (@prop (@predicates_hered.pred compcert_rmaps.RML.R.rmap compcert_rmaps.RML.R.ag_rmap) Nveric (and (tc_val' t p) (Z.divide (align_chunk ch) (Ptrofs.unsigned z)))) (res_predicates.nonlock_permission_bytes sh (@pair block Z b (Ptrofs.unsigned z)) (size_chunk ch))) (@prop mpred Nveric (Z.divide (align_chunk ch) (Ptrofs.unsigned z))) *)
intros ? ?. destruct H. apply H0.
(* Goal: semax cs Espec Delta (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (PROPx P (LOCALx Q (SEPx R))) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) val (fun x : val => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (locald_denote (f x))) (@liftx (LiftEnviron mpred) (g (h x) : mpred)))) S2)) S3) S4) c Post *)
normalize.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (PROPx P (LOCALx Q (SEPx R))) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (locald_denote (f x))) (@liftx (LiftEnviron mpred) (g (h x)))) S2)) S3) S4) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (PROPx P (LOCALx (@cons localdef (f x) Q) (SEPx (@cons mpred (g (h x)) R)))) S2) S3) S4) *)
clear.
(* Goal: @derives mpred Nveric (res_predicates.address_mapsto ch v2' sh (@pair block Z b (Ptrofs.unsigned z))) (@prop mpred Nveric (Z.divide (align_chunk ch) (Ptrofs.unsigned z))) *)
(* Goal: @derives mpred Nveric (if attr_volatile (attr_of_type t) then @FF mpred Nveric else @andp (@predicates_hered.pred compcert_rmaps.RML.R.rmap compcert_rmaps.RML.R.ag_rmap) Nveric (@prop (@predicates_hered.pred compcert_rmaps.RML.R.rmap compcert_rmaps.RML.R.ag_rmap) Nveric (and (tc_val' t p) (Z.divide (align_chunk ch) (Ptrofs.unsigned z)))) (res_predicates.nonlock_permission_bytes sh (@pair block Z b (Ptrofs.unsigned z)) (size_chunk ch))) (@prop mpred Nveric (Z.divide (align_chunk ch) (Ptrofs.unsigned z))) *)
rewrite (res_predicates.address_mapsto_align).
(* Goal: @derives mpred Nveric (@predicates_hered.andp compcert_rmaps.RML.R.rmap compcert_rmaps.RML.R.ag_rmap (res_predicates.address_mapsto ch v2' sh (@pair block Z b (Ptrofs.unsigned z))) (@predicates_hered.prop compcert_rmaps.RML.R.rmap compcert_rmaps.RML.R.ag_rmap (Z.divide (align_chunk ch) (@snd block Z (@pair block Z b (Ptrofs.unsigned z)))))) (@prop mpred Nveric (Z.divide (align_chunk ch) (Ptrofs.unsigned z))) *)
(* Goal: @derives mpred Nveric (if attr_volatile (attr_of_type t) then @FF mpred Nveric else @andp (@predicates_hered.pred compcert_rmaps.RML.R.rmap compcert_rmaps.RML.R.ag_rmap) Nveric (@prop (@predicates_hered.pred compcert_rmaps.RML.R.rmap compcert_rmaps.RML.R.ag_rmap) Nveric (and (tc_val' t p) (Z.divide (align_chunk ch) (Ptrofs.unsigned z)))) (res_predicates.nonlock_permission_bytes sh (@pair block Z b (Ptrofs.unsigned z)) (size_chunk ch))) (@prop mpred Nveric (Z.divide (align_chunk ch) (Ptrofs.unsigned z))) *)
match goal with |- ?A |-- ?B => change (predicates_hered.derives A B) end.
(* Goal: @predicates_hered.derives compcert_rmaps.RML.R.rmap compcert_rmaps.RML.R.ag_rmap (@predicates_hered.andp compcert_rmaps.RML.R.rmap compcert_rmaps.RML.R.ag_rmap (res_predicates.address_mapsto ch v2' sh (@pair block Z b (Ptrofs.unsigned z))) (@predicates_hered.prop compcert_rmaps.RML.R.rmap compcert_rmaps.RML.R.ag_rmap (Z.divide (align_chunk ch) (@snd block Z (@pair block Z b (Ptrofs.unsigned z)))))) (@prop mpred Nveric (Z.divide (align_chunk ch) (Ptrofs.unsigned z))) *)
(* Goal: @derives mpred Nveric (if attr_volatile (attr_of_type t) then @FF mpred Nveric else @andp (@predicates_hered.pred compcert_rmaps.RML.R.rmap compcert_rmaps.RML.R.ag_rmap) Nveric (@prop (@predicates_hered.pred compcert_rmaps.RML.R.rmap compcert_rmaps.RML.R.ag_rmap) Nveric (and (tc_val' t p) (Z.divide (align_chunk ch) (Ptrofs.unsigned z)))) (res_predicates.nonlock_permission_bytes sh (@pair block Z b (Ptrofs.unsigned z)) (size_chunk ch))) (@prop mpred Nveric (Z.divide (align_chunk ch) (Ptrofs.unsigned z))) *)
intros ? ?. destruct H. apply H0.
(* Goal: @derives mpred Nveric (if attr_volatile (attr_of_type t) then @FF mpred Nveric else if readable_share_dec sh then @orp (@predicates_hered.pred compcert_rmaps.RML.R.rmap compcert_rmaps.RML.R.ag_rmap) Nveric (@andp (@predicates_hered.pred compcert_rmaps.RML.R.rmap compcert_rmaps.RML.R.ag_rmap) Nveric (@prop (@predicates_hered.pred compcert_rmaps.RML.R.rmap compcert_rmaps.RML.R.ag_rmap) Nveric (tc_val t p)) (res_predicates.address_mapsto ch p sh (@pair block Z b (Ptrofs.unsigned z)))) (@andp (@predicates_hered.pred compcert_rmaps.RML.R.rmap compcert_rmaps.RML.R.ag_rmap) Nveric (@prop (@predicates_hered.pred compcert_rmaps.RML.R.rmap compcert_rmaps.RML.R.ag_rmap) Nveric (@eq val p Vundef)) (@exp (@predicates_hered.pred compcert_rmaps.RML.R.rmap compcert_rmaps.RML.R.ag_rmap) Nveric val (fun v2' : val => res_predicates.address_mapsto ch v2' sh (@pair block Z b (Ptrofs.unsigned z))))) else @andp (@predicates_hered.pred compcert_rmaps.RML.R.rmap compcert_rmaps.RML.R.ag_rmap) Nveric (@prop (@predicates_hered.pred compcert_rmaps.RML.R.rmap compcert_rmaps.RML.R.ag_rmap) Nveric (and (tc_val' t p) (Z.divide (align_chunk ch) (Ptrofs.unsigned z)))) (res_predicates.nonlock_permission_bytes sh (@pair block Z b (Ptrofs.unsigned z)) (size_chunk ch))) (@prop mpred Nveric (Z.divide (align_chunk ch) (Ptrofs.unsigned z))) *)
simple_if_tac.
(* Goal: @derives mpred Nveric (@FF mpred Nveric) (@prop mpred Nveric (Z.divide (align_chunk ch) (Ptrofs.unsigned z))) *)
(* Goal: @derives mpred Nveric (@andp (@predicates_hered.pred compcert_rmaps.RML.R.rmap compcert_rmaps.RML.R.ag_rmap) Nveric (@prop (@predicates_hered.pred compcert_rmaps.RML.R.rmap compcert_rmaps.RML.R.ag_rmap) Nveric (and (tc_val' t p) (Z.divide (align_chunk ch) (Ptrofs.unsigned z)))) (res_predicates.nonlock_permission_bytes sh (@pair block Z b (Ptrofs.unsigned z)) (size_chunk ch))) (@prop mpred Nveric (Z.divide (align_chunk ch) (Ptrofs.unsigned z))) *)
apply FF_left.
(* Goal: semax cs Espec Delta (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (PROPx P (LOCALx Q (SEPx R))) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) val (fun x : val => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (locald_denote (f x))) (@liftx (LiftEnviron mpred) (g (h x) : mpred)))) S2)) S3) S4) c Post *)
normalize.
Qed.

Lemma sizeof_Tpointer {cs: compspecs} : forall t, 
       sizeof (Tpointer t noattr) = if Archi.ptr64 then 8 else 4.
Proof.
(* Goal: forall (cs : compspecs) (Espec : OracleKind) (Delta : tycontext) (PQR : forall _ : environ, mpred) (gv : globals) (SF : forall _ : environ, mpred) (c : statement) (Post : ret_assert) (_ : semax cs Espec Delta (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) PQR SF) c Post), semax cs Espec Delta (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) PQR (globvars2pred gv (@nil (prod ident (globvar type))))) SF) c Post *)
intros.
(* Goal: Z.le (init_data_size (Init_space (@sizeof (@cenv_cs cs) t))) (@sizeof (@cenv_cs cs) t) *)
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (locald_denote (gvars gz))) PQR) (globvars2pred gz (@cons (prod ident (globvar type)) (@pair ident (globvar type) i gv) gvs))) SF)) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (LiftEnviron mpred) (@data_at_ cs (readonly2share (@gvar_readonly type gv)) t (gz i))) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (locald_denote (gvars gz))) PQR)) (globvars2pred gz gvs)) SF) *)
simpl. reflexivity.
Qed.

Lemma init_data_size_space {cs: compspecs}:
 forall t, init_data_size (Init_space (sizeof t)) = sizeof t.
(* Goal: forall (cs : compspecs) (Espec : OracleKind) (Delta : tycontext) (PQR : forall _ : environ, mpred) (gv : globals) (SF : forall _ : environ, mpred) (c : statement) (Post : ret_assert) (_ : semax cs Espec Delta (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) PQR SF) c Post), semax cs Espec Delta (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) PQR (globvars2pred gv (@nil (prod ident (globvar type))))) SF) c Post *)
Proof. intros.
(* Goal: Z.le (Z.max (@sizeof (@cenv_cs cs) t) Z0) (@sizeof (@cenv_cs cs) t) *)
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (locald_denote (gvars gz))) PQR) (globvars2pred gz (@cons (prod ident (globvar type)) (@pair ident (globvar type) i gv) gvs))) SF)) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (LiftEnviron mpred) (@data_at_ cs (readonly2share (@gvar_readonly type gv)) t (gz i))) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (locald_denote (gvars gz))) PQR)) (globvars2pred gz gvs)) SF) *)
 pose proof (sizeof_pos t).
(* Goal: @eq val match p with | Vundef => Vundef | Vint i => Vundef | Vlong i => Vundef | Vfloat f => Vundef | Vsingle f => Vundef | Vptr b z => Vptr b (Ptrofs.repr (Z.add (Ptrofs.unsigned z) (Ptrofs.unsigned (Ptrofs.repr i)))) end match p with | Vundef => Vundef | Vint i => Vundef | Vlong i => Vundef | Vfloat f => Vundef | Vsingle f => Vundef | Vptr b z => Vptr b (Ptrofs.repr (Z.add (Ptrofs.unsigned z) (Ptrofs.unsigned (Ptrofs.repr i)))) end *)
 unfold init_data_size. rewrite Z.max_l; auto. omega.
Qed.

Lemma init_data2pred_rejigger {cs: compspecs}:
  forall (Delta : tycontext)  (idata : init_data) (rho : environ)
     (sh : Share.t) (b : block) ofs v,
  tc_environ Delta rho ->
  v = Vptr b (Ptrofs.repr 0) ->
  readable_share sh ->
   init_data2pred idata sh (offset_val ofs v) rho
    |-- init_data2pred' Delta (globals_of_env rho) idata sh (offset_val ofs v).
Proof.
(* Goal: forall (Delta : tycontext) (idata : init_data) (rho : environ) (sh : Share.t) (b : block) (ofs : Z) (v : val) (_ : tc_environ Delta rho) (_ : @eq val v (Vptr b (Ptrofs.repr Z0))) (_ : readable_share sh), @derives mpred Nveric (init_data2pred idata sh (offset_val ofs v) rho) (@init_data2pred' cs Delta (globals_of_env rho) idata sh (offset_val ofs v)) *)
intros until v.
(* Goal: forall (_ : tc_environ Delta rho) (_ : @eq val v (Vptr b (Ptrofs.repr Z0))) (_ : readable_share sh), @derives mpred Nveric (init_data2pred idata sh (offset_val ofs v) rho) (@init_data2pred' cs Delta (globals_of_env rho) idata sh (offset_val ofs v)) *)
intros H7 H8 RS.
(* Goal: @derives mpred Nveric (init_data2pred idata sh (offset_val ofs v) rho) (@init_data2pred' cs Delta (globals_of_env rho) idata sh (offset_val ofs v)) *)
assert (H6:=I).
(* Goal: @derives mpred Nveric (init_data2pred idata sh (offset_val ofs v) rho) (@init_data2pred' cs Delta (globals_of_env rho) idata sh (offset_val ofs v)) *)
 unfold init_data2pred', init_data2pred.
(* Goal: @derives mpred Nveric match idata with | Init_int8 i => mapsto sh (Tint I8 Unsigned noattr) (offset_val ofs v) (Vint (Int.zero_ext (Zpos (xO (xO (xO xH)))) i)) | Init_int16 i => mapsto sh (Tint I16 Unsigned noattr) (offset_val ofs v) (Vint (Int.zero_ext (Zpos (xO (xO (xO (xO xH))))) i)) | Init_int32 i => mapsto sh (Tint I32 Unsigned noattr) (offset_val ofs v) (Vint i) | Init_int64 i => mapsto sh (Tlong Unsigned noattr) (offset_val ofs v) (Vlong i) | Init_float32 r => mapsto sh (Tfloat F32 noattr) (offset_val ofs v) (Vsingle r) | Init_float64 r => mapsto sh (Tfloat F64 noattr) (offset_val ofs v) (Vfloat r) | Init_space n => mapsto_zeros n sh (offset_val ofs v) | Init_addrof symb ofs0 => match @Map.get block (ge_of rho) symb with | Some b => mapsto sh (Tpointer Tvoid noattr) (offset_val ofs v) (Vptr b ofs0) | None => mapsto_ sh (Tpointer Tvoid noattr) (offset_val ofs v) end end match idata with | Init_int8 i => mapsto sh tuchar (offset_val ofs v) (Vint (Int.zero_ext (Zpos (xO (xO (xO xH)))) i)) | Init_int16 i => mapsto sh tushort (offset_val ofs v) (Vint (Int.zero_ext (Zpos (xO (xO (xO (xO xH))))) i)) | Init_int32 i => mapsto sh tuint (offset_val ofs v) (Vint i) | Init_int64 i => mapsto sh tulong (offset_val ofs v) (Vlong i) | Init_float32 r => mapsto sh tfloat (offset_val ofs v) (Vsingle r) | Init_float64 r => mapsto sh tdouble (offset_val ofs v) (Vfloat r) | Init_space n => memory_block sh n (offset_val ofs v) | Init_addrof symb ofs0 => match @PTree.get type symb (var_types Delta) with | Some t => match @PTree.get type symb (glob_types Delta) with | Some t0 => mapsto_ sh (Tpointer Tvoid noattr) (offset_val ofs v) | None => @TT mpred Nveric end | None => match @PTree.get type symb (glob_types Delta) with | Some (Tvoid as t) => mapsto sh (Tpointer t noattr) (offset_val ofs v) (offset_val (Ptrofs.unsigned ofs0) (globals_of_env rho symb)) | Some (Tint i s a as t) => mapsto sh (Tpointer t noattr) (offset_val ofs v) (offset_val (Ptrofs.unsigned ofs0) (globals_of_env rho symb)) | Some (Tlong s a as t) => mapsto sh (Tpointer t noattr) (offset_val ofs v) (offset_val (Ptrofs.unsigned ofs0) (globals_of_env rho symb)) | Some (Tfloat f a as t) => mapsto sh (Tpointer t noattr) (offset_val ofs v) (offset_val (Ptrofs.unsigned ofs0) (globals_of_env rho symb)) | Some (Tpointer t0 a as t) => mapsto sh (Tpointer t noattr) (offset_val ofs v) (offset_val (Ptrofs.unsigned ofs0) (globals_of_env rho symb)) | Some (Tarray t0 n' att as t) => mapsto sh (Tpointer t0 noattr) (offset_val ofs v) (offset_val (Ptrofs.unsigned ofs0) (globals_of_env rho symb)) | Some (Tfunction t0 t1 c as t) => mapsto sh (Tpointer t noattr) (offset_val ofs v) (offset_val (Ptrofs.unsigned ofs0) (globals_of_env rho symb)) | Some (Tstruct i a as t) => mapsto sh (Tpointer t noattr) (offset_val ofs v) (offset_val (Ptrofs.unsigned ofs0) (globals_of_env rho symb)) | Some (Tunion i a as t) => mapsto sh (Tpointer t noattr) (offset_val ofs v) (offset_val (Ptrofs.unsigned ofs0) (globals_of_env rho symb)) | None => @TT mpred Nveric end end end *)
 rename H8 into H8'.
(* Goal: @derives mpred Nveric match idata with | Init_int8 i => mapsto sh (Tint I8 Unsigned noattr) (offset_val ofs v) (Vint (Int.zero_ext (Zpos (xO (xO (xO xH)))) i)) | Init_int16 i => mapsto sh (Tint I16 Unsigned noattr) (offset_val ofs v) (Vint (Int.zero_ext (Zpos (xO (xO (xO (xO xH))))) i)) | Init_int32 i => mapsto sh (Tint I32 Unsigned noattr) (offset_val ofs v) (Vint i) | Init_int64 i => mapsto sh (Tlong Unsigned noattr) (offset_val ofs v) (Vlong i) | Init_float32 r => mapsto sh (Tfloat F32 noattr) (offset_val ofs v) (Vsingle r) | Init_float64 r => mapsto sh (Tfloat F64 noattr) (offset_val ofs v) (Vfloat r) | Init_space n => mapsto_zeros n sh (offset_val ofs v) | Init_addrof symb ofs0 => match @Map.get block (ge_of rho) symb with | Some b => mapsto sh (Tpointer Tvoid noattr) (offset_val ofs v) (Vptr b ofs0) | None => mapsto_ sh (Tpointer Tvoid noattr) (offset_val ofs v) end end match idata with | Init_int8 i => mapsto sh tuchar (offset_val ofs v) (Vint (Int.zero_ext (Zpos (xO (xO (xO xH)))) i)) | Init_int16 i => mapsto sh tushort (offset_val ofs v) (Vint (Int.zero_ext (Zpos (xO (xO (xO (xO xH))))) i)) | Init_int32 i => mapsto sh tuint (offset_val ofs v) (Vint i) | Init_int64 i => mapsto sh tulong (offset_val ofs v) (Vlong i) | Init_float32 r => mapsto sh tfloat (offset_val ofs v) (Vsingle r) | Init_float64 r => mapsto sh tdouble (offset_val ofs v) (Vfloat r) | Init_space n => memory_block sh n (offset_val ofs v) | Init_addrof symb ofs0 => match @PTree.get type symb (var_types Delta) with | Some t => match @PTree.get type symb (glob_types Delta) with | Some t0 => mapsto_ sh (Tpointer Tvoid noattr) (offset_val ofs v) | None => @TT mpred Nveric end | None => match @PTree.get type symb (glob_types Delta) with | Some (Tvoid as t) => mapsto sh (Tpointer t noattr) (offset_val ofs v) (offset_val (Ptrofs.unsigned ofs0) (globals_of_env rho symb)) | Some (Tint i s a as t) => mapsto sh (Tpointer t noattr) (offset_val ofs v) (offset_val (Ptrofs.unsigned ofs0) (globals_of_env rho symb)) | Some (Tlong s a as t) => mapsto sh (Tpointer t noattr) (offset_val ofs v) (offset_val (Ptrofs.unsigned ofs0) (globals_of_env rho symb)) | Some (Tfloat f a as t) => mapsto sh (Tpointer t noattr) (offset_val ofs v) (offset_val (Ptrofs.unsigned ofs0) (globals_of_env rho symb)) | Some (Tpointer t0 a as t) => mapsto sh (Tpointer t noattr) (offset_val ofs v) (offset_val (Ptrofs.unsigned ofs0) (globals_of_env rho symb)) | Some (Tarray t0 n' att as t) => mapsto sh (Tpointer t0 noattr) (offset_val ofs v) (offset_val (Ptrofs.unsigned ofs0) (globals_of_env rho symb)) | Some (Tfunction t0 t1 c as t) => mapsto sh (Tpointer t noattr) (offset_val ofs v) (offset_val (Ptrofs.unsigned ofs0) (globals_of_env rho symb)) | Some (Tstruct i a as t) => mapsto sh (Tpointer t noattr) (offset_val ofs v) (offset_val (Ptrofs.unsigned ofs0) (globals_of_env rho symb)) | Some (Tunion i a as t) => mapsto sh (Tpointer t noattr) (offset_val ofs v) (offset_val (Ptrofs.unsigned ofs0) (globals_of_env rho symb)) | None => @TT mpred Nveric end end end *)
 assert (H8: offset_val ofs v = Vptr b (Ptrofs.repr ofs)).
(* Goal: Z.le (init_data_size (Init_space (@sizeof (@cenv_cs cs) t))) (@sizeof (@cenv_cs cs) t) *)
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (locald_denote (gvars gz))) PQR) (globvars2pred gz (@cons (prod ident (globvar type)) (@pair ident (globvar type) i gv) gvs))) SF)) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (LiftEnviron mpred) (@data_at_ cs (readonly2share (@gvar_readonly type gv)) t (gz i))) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (locald_denote (gvars gz))) PQR)) (globvars2pred gz gvs)) SF) *)
 rewrite H8'; simpl. rewrite Ptrofs.add_zero_l; auto.
(* Goal: @derives mpred Nveric match idata with | Init_int8 i => mapsto sh (Tint I8 Unsigned noattr) (offset_val ofs v) (Vint (Int.zero_ext (Zpos (xO (xO (xO xH)))) i)) | Init_int16 i => mapsto sh (Tint I16 Unsigned noattr) (offset_val ofs v) (Vint (Int.zero_ext (Zpos (xO (xO (xO (xO xH))))) i)) | Init_int32 i => mapsto sh (Tint I32 Unsigned noattr) (offset_val ofs v) (Vint i) | Init_int64 i => mapsto sh (Tlong Unsigned noattr) (offset_val ofs v) (Vlong i) | Init_float32 r => mapsto sh (Tfloat F32 noattr) (offset_val ofs v) (Vsingle r) | Init_float64 r => mapsto sh (Tfloat F64 noattr) (offset_val ofs v) (Vfloat r) | Init_space n => mapsto_zeros n sh (offset_val ofs v) | Init_addrof symb ofs0 => match @Map.get block (ge_of rho) symb with | Some b => mapsto sh (Tpointer Tvoid noattr) (offset_val ofs v) (Vptr b ofs0) | None => mapsto_ sh (Tpointer Tvoid noattr) (offset_val ofs v) end end match idata with | Init_int8 i => mapsto sh tuchar (offset_val ofs v) (Vint (Int.zero_ext (Zpos (xO (xO (xO xH)))) i)) | Init_int16 i => mapsto sh tushort (offset_val ofs v) (Vint (Int.zero_ext (Zpos (xO (xO (xO (xO xH))))) i)) | Init_int32 i => mapsto sh tuint (offset_val ofs v) (Vint i) | Init_int64 i => mapsto sh tulong (offset_val ofs v) (Vlong i) | Init_float32 r => mapsto sh tfloat (offset_val ofs v) (Vsingle r) | Init_float64 r => mapsto sh tdouble (offset_val ofs v) (Vfloat r) | Init_space n => memory_block sh n (offset_val ofs v) | Init_addrof symb ofs0 => match @PTree.get type symb (var_types Delta) with | Some t => match @PTree.get type symb (glob_types Delta) with | Some t0 => mapsto_ sh (Tpointer Tvoid noattr) (offset_val ofs v) | None => @TT mpred Nveric end | None => match @PTree.get type symb (glob_types Delta) with | Some (Tvoid as t) => mapsto sh (Tpointer t noattr) (offset_val ofs v) (offset_val (Ptrofs.unsigned ofs0) (globals_of_env rho symb)) | Some (Tint i s a as t) => mapsto sh (Tpointer t noattr) (offset_val ofs v) (offset_val (Ptrofs.unsigned ofs0) (globals_of_env rho symb)) | Some (Tlong s a as t) => mapsto sh (Tpointer t noattr) (offset_val ofs v) (offset_val (Ptrofs.unsigned ofs0) (globals_of_env rho symb)) | Some (Tfloat f a as t) => mapsto sh (Tpointer t noattr) (offset_val ofs v) (offset_val (Ptrofs.unsigned ofs0) (globals_of_env rho symb)) | Some (Tpointer t0 a as t) => mapsto sh (Tpointer t noattr) (offset_val ofs v) (offset_val (Ptrofs.unsigned ofs0) (globals_of_env rho symb)) | Some (Tarray t0 n' att as t) => mapsto sh (Tpointer t0 noattr) (offset_val ofs v) (offset_val (Ptrofs.unsigned ofs0) (globals_of_env rho symb)) | Some (Tfunction t0 t1 c as t) => mapsto sh (Tpointer t noattr) (offset_val ofs v) (offset_val (Ptrofs.unsigned ofs0) (globals_of_env rho symb)) | Some (Tstruct i a as t) => mapsto sh (Tpointer t noattr) (offset_val ofs v) (offset_val (Ptrofs.unsigned ofs0) (globals_of_env rho symb)) | Some (Tunion i a as t) => mapsto sh (Tpointer t noattr) (offset_val ofs v) (offset_val (Ptrofs.unsigned ofs0) (globals_of_env rho symb)) | None => @TT mpred Nveric end end end *)
 clear H8'.
(* Goal: Z.le (init_data_size (Init_space (@sizeof (@cenv_cs cs) t))) (@sizeof (@cenv_cs cs) t) *)
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (locald_denote (gvars gz))) PQR) (globvars2pred gz (@cons (prod ident (globvar type)) (@pair ident (globvar type) i gv) gvs))) SF)) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (LiftEnviron mpred) (@data_at_ cs (readonly2share (@gvar_readonly type gv)) t (gz i))) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (locald_denote (gvars gz))) PQR)) (globvars2pred gz gvs)) SF) *)
 simpl.
(* Goal: @derives mpred Nveric match idata with | Init_int8 i => mapsto sh (Tint I8 Unsigned noattr) (offset_val ofs v) (Vint (Int.zero_ext (Zpos (xO (xO (xO xH)))) i)) | Init_int16 i => mapsto sh (Tint I16 Unsigned noattr) (offset_val ofs v) (Vint (Int.zero_ext (Zpos (xO (xO (xO (xO xH))))) i)) | Init_int32 i => mapsto sh (Tint I32 Unsigned noattr) (offset_val ofs v) (Vint i) | Init_int64 i => mapsto sh (Tlong Unsigned noattr) (offset_val ofs v) (Vlong i) | Init_float32 r => mapsto sh (Tfloat F32 noattr) (offset_val ofs v) (Vsingle r) | Init_float64 r => mapsto sh (Tfloat F64 noattr) (offset_val ofs v) (Vfloat r) | Init_space n => mapsto_zeros n sh (offset_val ofs v) | Init_addrof symb ofs0 => match @Map.get block (ge_of rho) symb with | Some b => mapsto sh (Tpointer Tvoid noattr) (offset_val ofs v) (Vptr b ofs0) | None => mapsto_ sh (Tpointer Tvoid noattr) (offset_val ofs v) end end match idata with | Init_int8 i => mapsto sh tuchar (offset_val ofs v) (Vint (Int.zero_ext (Zpos (xO (xO (xO xH)))) i)) | Init_int16 i => mapsto sh tushort (offset_val ofs v) (Vint (Int.zero_ext (Zpos (xO (xO (xO (xO xH))))) i)) | Init_int32 i => mapsto sh tuint (offset_val ofs v) (Vint i) | Init_int64 i => mapsto sh tulong (offset_val ofs v) (Vlong i) | Init_float32 r => mapsto sh tfloat (offset_val ofs v) (Vsingle r) | Init_float64 r => mapsto sh tdouble (offset_val ofs v) (Vfloat r) | Init_space n => memory_block sh n (offset_val ofs v) | Init_addrof symb ofs0 => match @PTree.get type symb (var_types Delta) with | Some t => match @PTree.get type symb (glob_types Delta) with | Some t0 => mapsto_ sh (Tpointer Tvoid noattr) (offset_val ofs v) | None => @TT mpred Nveric end | None => match @PTree.get type symb (glob_types Delta) with | Some (Tvoid as t) => mapsto sh (Tpointer t noattr) (offset_val ofs v) (offset_val (Ptrofs.unsigned ofs0) (globals_of_env rho symb)) | Some (Tint i s a as t) => mapsto sh (Tpointer t noattr) (offset_val ofs v) (offset_val (Ptrofs.unsigned ofs0) (globals_of_env rho symb)) | Some (Tlong s a as t) => mapsto sh (Tpointer t noattr) (offset_val ofs v) (offset_val (Ptrofs.unsigned ofs0) (globals_of_env rho symb)) | Some (Tfloat f a as t) => mapsto sh (Tpointer t noattr) (offset_val ofs v) (offset_val (Ptrofs.unsigned ofs0) (globals_of_env rho symb)) | Some (Tpointer t0 a as t) => mapsto sh (Tpointer t noattr) (offset_val ofs v) (offset_val (Ptrofs.unsigned ofs0) (globals_of_env rho symb)) | Some (Tarray t0 n' att as t) => mapsto sh (Tpointer t0 noattr) (offset_val ofs v) (offset_val (Ptrofs.unsigned ofs0) (globals_of_env rho symb)) | Some (Tfunction t0 t1 c as t) => mapsto sh (Tpointer t noattr) (offset_val ofs v) (offset_val (Ptrofs.unsigned ofs0) (globals_of_env rho symb)) | Some (Tstruct i a as t) => mapsto sh (Tpointer t noattr) (offset_val ofs v) (offset_val (Ptrofs.unsigned ofs0) (globals_of_env rho symb)) | Some (Tunion i a as t) => mapsto sh (Tpointer t noattr) (offset_val ofs v) (offset_val (Ptrofs.unsigned ofs0) (globals_of_env rho symb)) | None => @TT mpred Nveric end end end *)
 destruct idata; super_unfold_lift; try apply derives_refl.
*  unfold init_data_size in H6.
(* Goal: @derives mpred Nveric (mapsto_zeros z sh (offset_val ofs v)) (memory_block sh z (offset_val ofs v)) *)
    assert (Ptrofs.max_unsigned = Ptrofs.modulus-1) by computable.
(* Goal: @derives mpred Nveric (mapsto_zeros z sh (offset_val ofs v)) (memory_block sh z (offset_val ofs v)) *)
    pose proof (Z.le_max_l z 0).
(* Goal: @derives mpred Nveric (mapsto sh (Tpointer Tvoid noattr) (offset_val ofs v) (Vptr b1 i0)) (mapsto_ sh (Tpointer Tvoid noattr) (offset_val ofs v)) *)
    rewrite H8.
(* Goal: @eq val match p with | Vundef => Vundef | Vint i => Vundef | Vlong i => Vundef | Vfloat f => Vundef | Vsingle f => Vundef | Vptr b z => Vptr b (Ptrofs.repr (Z.add (Ptrofs.unsigned z) (Ptrofs.unsigned (Ptrofs.repr i)))) end match p with | Vundef => Vundef | Vint i => Vundef | Vlong i => Vundef | Vfloat f => Vundef | Vsingle f => Vundef | Vptr b z => Vptr b (Ptrofs.repr (Z.add (Ptrofs.unsigned z) (Ptrofs.unsigned (Ptrofs.repr i)))) end *)
    apply mapsto_zeros_memory_block; auto.
* destruct_var_types i eqn:Hv&Hv'; rewrite ?Hv, ?Hv';
  destruct_glob_types i eqn:Hg&Hg'; rewrite ?Hg, ?Hg';
try solve [simpl; apply TT_right].
(* Goal: @derives mpred Nveric (mapsto sh (Tpointer Tvoid noattr) (offset_val ofs v) (Vptr b1 i0)) (mapsto_ sh (Tpointer Tvoid noattr) (offset_val ofs v)) *)
 + rewrite H8. cancel.
 + replace (offset_val (Ptrofs.unsigned i0) (globals_of_env rho i)) with (Vptr b0 i0).
   replace (mapsto sh (Tpointer Tvoid noattr) (offset_val ofs v) (Vptr b0 i0))
   with (mapsto sh (Tpointer t noattr) (offset_val ofs v) (Vptr b0 i0)).
(* Goal: @eq val match p with | Vundef => Vundef | Vint i => Vundef | Vlong i => Vundef | Vfloat f => Vundef | Vsingle f => Vundef | Vptr b z => Vptr b (Ptrofs.repr (Z.add (Ptrofs.unsigned z) (Ptrofs.unsigned (Ptrofs.repr i)))) end match p with | Vundef => Vundef | Vint i => Vundef | Vlong i => Vundef | Vfloat f => Vundef | Vsingle f => Vundef | Vptr b z => Vptr b (Ptrofs.repr (Z.add (Ptrofs.unsigned z) (Ptrofs.unsigned (Ptrofs.repr i)))) end *)
   destruct t; auto.
(* Goal: Z.le (init_data_size (Init_space (@sizeof (@cenv_cs cs) t))) (@sizeof (@cenv_cs cs) t) *)
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (locald_denote (gvars gz))) PQR) (globvars2pred gz (@cons (prod ident (globvar type)) (@pair ident (globvar type) i gv) gvs))) SF)) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (LiftEnviron mpred) (@data_at_ cs (readonly2share (@gvar_readonly type gv)) t (gz i))) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (locald_denote (gvars gz))) PQR)) (globvars2pred gz gvs)) SF) *)
   unfold mapsto; simpl.
(* Goal: @eq val match p with | Vundef => Vundef | Vint i => Vundef | Vlong i => Vundef | Vfloat f => Vundef | Vsingle f => Vundef | Vptr b z => Vptr b (Ptrofs.repr (Z.add (Ptrofs.unsigned z) (Ptrofs.unsigned (Ptrofs.repr i)))) end match p with | Vundef => Vundef | Vint i => Vundef | Vlong i => Vundef | Vfloat f => Vundef | Vsingle f => Vundef | Vptr b z => Vptr b (Ptrofs.repr (Z.add (Ptrofs.unsigned z) (Ptrofs.unsigned (Ptrofs.repr i)))) end *)
   destruct (offset_val ofs v); auto. rewrite !if_true by auto. rewrite andb_false_r.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (LiftEnviron mpred) (g (h x))) (PROPx P (LOCALx Q (SEPx R)))) S2) S3) S4) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (LiftEnviron mpred) (g (h x))) (PROPx P (LOCALx Q (SEPx R)))) S2) S3) S4) *)
   apply derives_refl.
(* Goal: Z.le (init_data_size (Init_space (@sizeof (@cenv_cs cs) t))) (@sizeof (@cenv_cs cs) t) *)
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (locald_denote (gvars gz))) PQR) (globvars2pred gz (@cons (prod ident (globvar type)) (@pair ident (globvar type) i gv) gvs))) SF)) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (LiftEnviron mpred) (@data_at_ cs (readonly2share (@gvar_readonly type gv)) t (gz i))) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (locald_denote (gvars gz))) PQR)) (globvars2pred gz gvs)) SF) *)
   unfold mapsto; simpl.
(* Goal: @eq val match p with | Vundef => Vundef | Vint i => Vundef | Vlong i => Vundef | Vfloat f => Vundef | Vsingle f => Vundef | Vptr b z => Vptr b (Ptrofs.repr (Z.add (Ptrofs.unsigned z) (Ptrofs.unsigned (Ptrofs.repr i)))) end match p with | Vundef => Vundef | Vint i => Vundef | Vlong i => Vundef | Vfloat f => Vundef | Vsingle f => Vundef | Vptr b z => Vptr b (Ptrofs.repr (Z.add (Ptrofs.unsigned z) (Ptrofs.unsigned (Ptrofs.repr i)))) end *)
   destruct (offset_val ofs v); auto. rewrite !if_true by auto. rewrite andb_false_r.
(* Goal: @eq (list B) (@cons B (f x) (@map A B f z)) (@map A B f (@cons A x z)) *)
   reflexivity.
(* Goal: Z.le (init_data_size (Init_space (@sizeof (@cenv_cs cs) t))) (@sizeof (@cenv_cs cs) t) *)
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (locald_denote (gvars gz))) PQR) (globvars2pred gz (@cons (prod ident (globvar type)) (@pair ident (globvar type) i gv) gvs))) SF)) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (LiftEnviron mpred) (@data_at_ cs (readonly2share (@gvar_readonly type gv)) t (gz i))) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (locald_denote (gvars gz))) PQR)) (globvars2pred gz gvs)) SF) *)
   unfold globals_of_env. rewrite Hg'. simpl. rewrite Ptrofs.add_zero_l.
(* Goal: @eq val match p with | Vundef => Vundef | Vint i => Vundef | Vlong i => Vundef | Vfloat f => Vundef | Vsingle f => Vundef | Vptr b z => Vptr b (Ptrofs.repr (Z.add (Ptrofs.unsigned z) (Ptrofs.unsigned (Ptrofs.repr i)))) end match p with | Vundef => Vundef | Vint i => Vundef | Vlong i => Vundef | Vfloat f => Vundef | Vsingle f => Vundef | Vptr b z => Vptr b (Ptrofs.repr (Z.add (Ptrofs.unsigned z) (Ptrofs.unsigned (Ptrofs.repr i)))) end *)
   f_equal. rewrite Ptrofs.repr_unsigned; auto.
Qed.

Lemma readable_readonly2share: forall ro, readable_share (readonly2share ro).
Proof.
(* Goal: forall (cs : compspecs) (Espec : OracleKind) (Delta : tycontext) (PQR : forall _ : environ, mpred) (gv : globals) (SF : forall _ : environ, mpred) (c : statement) (Post : ret_assert) (_ : semax cs Espec Delta (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) PQR SF) c Post), semax cs Espec Delta (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) PQR (globvars2pred gv (@nil (prod ident (globvar type))))) SF) c Post *)
intros. apply initialize.readable_readonly2share.
Qed.

Lemma unpack_globvar  {cs: compspecs}:
  forall Delta gz i t gv idata,
   (var_types Delta) ! i = None ->
   (glob_types Delta) ! i = Some t ->
  (complete_legal_cosu_type (gvar_info gv) && is_aligned cenv_cs ha_env_cs la_env_cs (gvar_info gv) 0 = true)%bool ->
   gvar_volatile gv = false ->
   gvar_info gv = t ->
   gvar_init gv = idata :: nil ->
   init_data_size idata <= sizeof t ->
   sizeof t <= Ptrofs.max_unsigned ->
   local (`and (tc_environ Delta) (fun rho =>gz = globals_of_env rho)) && globvar2pred gz (i, gv) |--
       `(init_data2pred' Delta gz idata (readonly2share (gvar_readonly gv)) (gz i)).
Proof.
(* Goal: forall (cs : compspecs) (Espec : OracleKind) (Delta : tycontext) (PQR : forall _ : environ, mpred) (gv : globals) (SF : forall _ : environ, mpred) (c : statement) (Post : ret_assert) (_ : semax cs Espec Delta (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) PQR SF) c Post), semax cs Espec Delta (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) PQR (globvars2pred gv (@nil (prod ident (globvar type))))) SF) c Post *)
intros.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (locald_denote (gvars gz))) PQR) (globvars2pred gz (@cons (prod ident (globvar type)) (@pair ident (globvar type) i gv) gvs))) SF)) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (LiftEnviron mpred) (@data_at_ cs (readonly2share (@gvar_readonly type gv)) t (gz i))) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (locald_denote (gvars gz))) PQR)) (globvars2pred gz gvs)) SF) *)
go_lowerx. subst gz.
eapply derives_trans; [eapply tc_globalvar_sound'; try eassumption | ].
assert (RS:= readable_readonly2share (gvar_readonly gv)).
forget (readonly2share (gvar_readonly gv)) as sh.
(* Goal: semax cs Espec Delta (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (PROPx P (LOCALx Q (SEPx R))) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) val (fun x : val => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (locald_denote (f x))) (@liftx (LiftEnviron mpred) (g (h x) : mpred)))) S2)) S3) S4) c Post *)
autorewrite with subst norm1 norm2; normalize.
unfold init_data_list2pred.
(* Goal: @eq mpred (a rho) (@sepcon mpred Nveric Sveric (a rho) (@emp mpred Nveric Sveric)) *)
(* Goal: @eq mpred (@sepcon mpred Nveric Sveric (a rho) (fold_right_sepcon' (@cons (forall _ : environ, mpred) m l) rho)) (@sepcon mpred Nveric Sveric (a rho) (@fold_right (forall _ : environ, mpred) (forall _ : environ, mpred) (fun (P Q : forall _ : environ, mpred) (rho : environ) => @sepcon mpred Nveric Sveric (P rho) (Q rho)) (fun _ : environ => @emp mpred Nveric Sveric) (@cons (forall _ : environ, mpred) m l) rho)) *)
rewrite sepcon_emp.
destruct (globvar_eval_var _ _ _ _ H7 H H0) as [b [? ?]].
assert (globals_of_env rho i = offset_val 0 (globals_of_env rho i)).
(* Goal: @eq val (offset_val Z0 (globals_of_env rho i)) (globals_of_env rho i) *)
unfold globals_of_env.
(* Goal: @eq (list B) (@cons B (f x) (@map A B f z)) (@map A B f (@cons A x z)) *)
rewrite H9. reflexivity.
rewrite H10 at 1.
 apply derives_trans with
     (init_data2pred' Delta (globals_of_env rho) idata sh
      (offset_val 0 (globals_of_env rho i))).
+ rewrite andb_true_iff in H1; destruct H1.
(* Goal: Z.lt (@sizeof (@cenv_cs cs) (@gvar_info type gv)) Ptrofs.modulus *)
  eapply init_data2pred_rejigger; eauto; try omega.
(* Goal: @eq (list B) (@cons B (f x) (@map A B f z)) (@map A B f (@cons A x z)) *)
  unfold globals_of_env; rewrite H9; reflexivity.
 +
 unfold init_data2pred'.
  rewrite <- H10.
 destruct idata; unfold_lift;
   try (rewrite H8; simpl; rewrite Ptrofs.add_zero_l; auto);
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (LiftEnviron mpred) (g (h x))) (PROPx P (LOCALx Q (SEPx R)))) S2) S3) S4) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (LiftEnviron mpred) (g (h x))) (PROPx P (LOCALx Q (SEPx R)))) S2) S3) S4) *)
 try apply derives_refl.
Qed.

Fixpoint id2pred_star   {cs: compspecs}
   (Delta: tycontext) (gz: globals) (sh: share) (v: val) (dl: list init_data) : environ->mpred :=
 match dl with
 | d::dl' => `(init_data2pred' Delta gz d sh v)
                   * id2pred_star Delta gz sh (offset_val (init_data_size d) v) dl'
 | nil => emp
 end.

Arguments id2pred_star cs Delta gz sh v dl rho  / .

Lemma init_data_size_pos : forall a, init_data_size a >= 0.
Proof.
(* Goal: Z.lt (@sizeof (@cenv_cs cs) (@gvar_info type gv)) Ptrofs.modulus *)
 destruct a; simpl; try omega.
(* Goal: Z.ge (Z.max z Z0) Z0 *)
(* Goal: Z.ge (if Archi.ptr64 then Zpos (xO (xO (xO xH))) else Zpos (xO (xO xH))) Z0 *)
 pose proof (Zmax_spec z 0).
(* Goal: Z.lt (@sizeof (@cenv_cs cs) (@gvar_info type gv)) Ptrofs.modulus *)
 destruct (zlt 0 z); omega.
(* Goal: Z.lt (@sizeof (@cenv_cs cs) (@gvar_info type gv)) Ptrofs.modulus *)
destruct Archi.ptr64; omega.
Qed.

Lemma init_data_list_size_pos : forall a, init_data_list_size a >= 0.
Proof.
(* Goal: Z.le (init_data_size (Init_space (@sizeof (@cenv_cs cs) t))) (@sizeof (@cenv_cs cs) t) *)
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (locald_denote (gvars gz))) PQR) (globvars2pred gz (@cons (prod ident (globvar type)) (@pair ident (globvar type) i gv) gvs))) SF)) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (LiftEnviron mpred) (@data_at_ cs (readonly2share (@gvar_readonly type gv)) t (gz i))) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (locald_denote (gvars gz))) PQR)) (globvars2pred gz gvs)) SF) *)
 induction a; simpl.
(* Goal: Z.lt (@sizeof (@cenv_cs cs) (@gvar_info type gv)) Ptrofs.modulus *)
 omega.
(* Goal: Z.lt (@sizeof (@cenv_cs cs) (@gvar_info type gv)) Ptrofs.modulus *)
 pose proof (init_data_size_pos a); omega.
Qed.

Definition globvar_all_aligned {cs: compspecs} gv : bool :=
  forallb (fun a =>andb
                (init_data_size a mod hardware_alignof ha_env_cs (gvar_info gv) =? 0)
                (init_data_size a mod alignof (gvar_info gv) =? 0))
           (gvar_init gv).

Lemma unpack_globvar_star  {cs: compspecs}:
  forall Delta gz i gv,
   (var_types Delta) ! i = None ->
   (glob_types Delta) ! i = Some (gvar_info gv) ->
  (complete_legal_cosu_type (gvar_info gv) && is_aligned cenv_cs ha_env_cs la_env_cs (gvar_info gv) 0)% bool = true ->
   gvar_volatile gv = false ->
  (globvar_all_aligned gv = true) ->
   init_data_list_size (gvar_init gv) <= sizeof (gvar_info gv) <= Ptrofs.max_unsigned ->
   local (`and (tc_environ Delta) (fun rho =>gz = globals_of_env rho)) && globvar2pred gz (i, gv) |-- 
       id2pred_star Delta gz (readonly2share (gvar_readonly gv)) (gz i) (gvar_init gv).
Proof.
(* Goal: forall (cs : compspecs) (Espec : OracleKind) (Delta : tycontext) (gz : globals) (P : list Prop) (Q : list localdef) (R : list mpred) (i : ident) (gv : globvar type) (gvs : list (prod ident (globvar type))) (SF : forall _ : environ, mpred) (c : statement) (Post : ret_assert) (n : Z) (t : type) (sz : intsize) (sign : signedness) (data : list Int.int) (_ : @eq (option type) (@PTree.get type i (var_types Delta)) (@None type)) (_ : @eq (option type) (@PTree.get type i (glob_types Delta)) (@Some type (@gvar_info type gv))) (_ : @eq type (@gvar_info type gv) (tarray t n)) (_ : @eq bool (@gvar_volatile type gv) false) (_ : @eq bool (@globvar_all_aligned cs gv) true) (_ : @eq type t (Tint sz sign noattr)) (_ : notboolsize sz) (_ : @eq Z n (@Zlength init_data (@gvar_init type gv))) (_ : @eq (list init_data) (@gvar_init type gv) (@map Int.int init_data (inttype2init_data sz) data)) (_ : and (Z.le (init_data_list_size (@gvar_init type gv)) (@sizeof (@cenv_cs cs) (@gvar_info type gv))) (Z.le (@sizeof (@cenv_cs cs) (@gvar_info type gv)) Ptrofs.max_unsigned)) (_ : semax cs Espec Delta (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (PROPx P (LOCALx (@cons localdef (gvars gz) Q) (SEPx (@cons mpred (@data_at cs (readonly2share (@gvar_readonly type gv)) (tarray (Tint sz sign noattr) n) (@map Int.int val (@Basics.compose Int.int Int.int val Vint (Cop.cast_int_int sz sign)) data) (gz i)) R)))) (globvars2pred gz gvs)) SF) c Post), semax cs Espec Delta (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (PROPx P (LOCALx (@cons localdef (gvars gz) Q) (SEPx R))) (globvars2pred gz (@cons (prod ident (globvar type)) (@pair ident (globvar type) i gv) gvs))) SF) c Post *)
intros until 4.
intros H5.
unfold globvar_all_aligned in H5.
remember (gvar_info gv) as t eqn:H3; symmetry in H3.
remember (gvar_init gv) as idata eqn:H4; symmetry in H4.
(* Goal: forall (cs : compspecs) (Espec : OracleKind) (Delta : tycontext) (PQR : forall _ : environ, mpred) (gv : globals) (SF : forall _ : environ, mpred) (c : statement) (Post : ret_assert) (_ : semax cs Espec Delta (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) PQR SF) c Post), semax cs Espec Delta (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) PQR (globvars2pred gv (@nil (prod ident (globvar type))))) SF) c Post *)
intros.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (locald_denote (gvars gz))) PQR) (globvars2pred gz (@cons (prod ident (globvar type)) (@pair ident (globvar type) i gv) gvs))) SF)) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (LiftEnviron mpred) (@data_at_ cs (readonly2share (@gvar_readonly type gv)) t (gz i))) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (locald_denote (gvars gz))) PQR)) (globvars2pred gz gvs)) SF) *)
go_lowerx. subst gz.
eapply derives_trans; [eapply tc_globalvar_sound'; eassumption | ].
(* Goal: semax cs Espec Delta (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (PROPx P (LOCALx Q (SEPx R))) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) val (fun x : val => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (locald_denote (f x))) (@liftx (LiftEnviron mpred) (g (h x) : mpred)))) S2)) S3) S4) c Post *)
normalize.
(* Goal: semax cs Espec Delta (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (PROPx P (LOCALx Q (SEPx R))) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) val (fun x : val => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (locald_denote (f x))) (@liftx (LiftEnviron mpred) (g (h x) : mpred)))) S2)) S3) S4) c Post *)
  autorewrite with subst norm1 norm2; normalize.
match goal with |- _ |-- ?F _ _ _ _ _ _ _  => change F with @id2pred_star end.
(* Goal: semax cs Espec Delta (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (PROPx P (LOCALx Q (SEPx R))) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) val (fun x : val => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (locald_denote (f x))) (@liftx (LiftEnviron mpred) (g (h x) : mpred)))) S2)) S3) S4) c Post *)
normalize.
(* Goal: semax cs Espec Delta (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (PROPx P (LOCALx Q (SEPx R))) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) val (fun x : val => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (locald_denote (f x))) (@liftx (LiftEnviron mpred) (g (h x) : mpred)))) S2)) S3) S4) c Post *)
  autorewrite with subst norm1 norm2; normalize.
assert (RS:= readable_readonly2share (gvar_readonly gv)).
forget (readonly2share (gvar_readonly gv)) as sh.
set (ofs:=0%Z).
assert (alignof t | Ptrofs.unsigned (Ptrofs.repr ofs)) by (subst ofs; simpl; apply Z.divide_0_r).
destruct (globvar_eval_var _ _ _ _ H7 H H0) as [b [_ H9']].
(* Goal: @eq val (offset_val Z0 (globals_of_env rho i)) (globals_of_env rho i) *)
unfold globals_of_env. rewrite H9'.
remember (Vptr b Ptrofs.zero) as x.
assert (H10: x = offset_val ofs x) by (subst ofs x; reflexivity).
rewrite H10 at 1.
clear H10.
assert (H11: init_data_list_size idata + ofs <= sizeof t)  by (unfold ofs; omega).
(* Goal: Z.lt (@sizeof (@cenv_cs cs) (@gvar_info type gv)) Ptrofs.modulus *)
assert (H12:  sizeof t <= Ptrofs.max_unsigned)  by omega.
assert (0 <= ofs) by (unfold ofs; omega).
(* Goal: @eq mpred (@andp mpred Nveric (@prop mpred Nveric (@eq globals gv (globals_of_env rho))) (@sepcon mpred Nveric Sveric (@fold_right (forall _ : environ, mpred) (forall _ : environ, mpred) (fun (P Q : forall _ : environ, mpred) (rho : environ) => @sepcon mpred Nveric Sveric (P rho) (Q rho)) (fun _ : environ => @emp mpred Nveric Sveric) (@map (prod ident (globvar type)) (forall _ : environ, mpred) (globvar2pred gv) (prog_vars prog)) rho) (@has_ext (@OK_ty Espec) ora))) (@andp mpred Nveric (@prop mpred Nveric (and True (@eq globals gv (globals_of_env rho)))) (@sepcon mpred Nveric Sveric (@andp mpred Nveric (@prop mpred Nveric (and (@eq globals gv (fun i : ident => match @Map.get block (ge_of rho) i with | Some b => Vptr b Ptrofs.zero | None => Vundef end)) True)) (@has_ext (@OK_ty Espec) ora)) (@fold_right (forall _ : environ, mpred) (forall _ : environ, mpred) (fun (P Q : forall _ : environ, mpred) (rho : environ) => @sepcon mpred Nveric Sveric (P rho) (Q rho)) (fun _ : environ => @emp mpred Nveric Sveric) (@map (prod ident (globvar type)) (forall _ : environ, mpred) (globvar2pred gv) (prog_vars prog)) rho))) *)
fold (globals_of_env rho).
match goal with |- _ |-- ?F _ _ _ _ _ _ _  => change F with @id2pred_star end.
(* Goal: semax cs Espec Delta (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (PROPx P (LOCALx Q (SEPx R))) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) val (fun x : val => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (locald_denote (f x))) (@liftx (LiftEnviron mpred) (g (h x) : mpred)))) S2)) S3) S4) c Post *)
replace x with (offset_val ofs x) at 2. 2: subst x; normalize.
change 0 with ofs in H1.
clearbody ofs.
revert ofs H1 H5 H8 H9 H9' H11 H12.
clear dependent gv. clear H H0 H6.
(* Goal: forall (cs : compspecs) (Espec : OracleKind) (Delta : tycontext) (PQR : forall _ : environ, mpred) (gv : globals) (SF : forall _ : environ, mpred) (c : statement) (Post : ret_assert) (_ : semax cs Espec Delta (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) PQR SF) c Post), semax cs Espec Delta (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) PQR (globvars2pred gv (@nil (prod ident (globvar type))))) SF) c Post *)
induction idata; simpl; auto; intros. 
match goal with |- _ |-- _ * ?F _ _ _ _ _ _ _  => change F with @id2pred_star end.
apply sepcon_derives.
*
  clear IHidata. 
  rewrite andb_true_iff in H1 by (pose proof (init_data_list_size_pos idata); omega).
  pose proof (init_data_size_pos a).
  pose proof (init_data_list_size_pos idata).
(* Goal: @derives mpred Nveric (mapsto_zeros z sh (offset_val ofs v)) (memory_block sh z (offset_val ofs v)) *)
  assert (Ptrofs.max_unsigned = Ptrofs.modulus-1) by computable.
  destruct H1.
(* Goal: Z.lt (@sizeof (@cenv_cs cs) (@gvar_info type gv)) Ptrofs.modulus *)
  rewrite Ptrofs.unsigned_repr in H8 by omega.
  eapply init_data2pred_rejigger; eauto; try tauto;
  clear x Heqx; clear RS H7 H9' b.
* specialize (IHidata (ofs + init_data_size a)).
rewrite offset_offset_val.
 pose proof (init_data_list_size_pos idata).
pose proof (init_data_size_pos a).
(* Goal: Z.lt (@sizeof (@cenv_cs cs) (@gvar_info type gv)) Ptrofs.modulus *)
 rewrite Ptrofs.unsigned_repr in H8 by omega.
 rewrite !andb_true_iff in H5.
 destruct H5 as [[H5a H5b] H5].
 assert (hardware_alignof ha_env_cs t | init_data_size a). {
   clear - H5a.
   assert (hardware_alignof ha_env_cs t > 0). {
(* Goal: @eq val match p with | Vundef => Vundef | Vint i => Vundef | Vlong i => Vundef | Vfloat f => Vundef | Vsingle f => Vundef | Vptr b z => Vptr b (Ptrofs.repr (Z.add (Ptrofs.unsigned z) (Ptrofs.unsigned (Ptrofs.repr i)))) end match p with | Vundef => Vundef | Vint i => Vundef | Vlong i => Vundef | Vfloat f => Vundef | Vsingle f => Vundef | Vptr b z => Vptr b (Ptrofs.repr (Z.add (Ptrofs.unsigned z) (Ptrofs.unsigned (Ptrofs.repr i)))) end *)
     eapply hardware_alignof_pos; eauto.
     apply cenv_consistent.
     apply ha_env_cs_consistent.
     apply ha_env_cs_complete.
   }
   rewrite Z.eqb_eq in H5a.
(* Goal: @eq val match p with | Vundef => Vundef | Vint i => Vundef | Vlong i => Vundef | Vfloat f => Vundef | Vsingle f => Vundef | Vptr b z => Vptr b (Ptrofs.repr (Z.add (Ptrofs.unsigned z) (Ptrofs.unsigned (Ptrofs.repr i)))) end match p with | Vundef => Vundef | Vint i => Vundef | Vlong i => Vundef | Vfloat f => Vundef | Vsingle f => Vundef | Vptr b z => Vptr b (Ptrofs.repr (Z.add (Ptrofs.unsigned z) (Ptrofs.unsigned (Ptrofs.repr i)))) end *)
   rewrite Z.mod_divide in H5a by omega. auto.
 }   
 assert (alignof t | init_data_size a). {
   clear - H5b.
   pose proof (alignof_pos t).
   rewrite Z.eqb_eq in H5b.
(* Goal: @eq val match p with | Vundef => Vundef | Vint i => Vundef | Vlong i => Vundef | Vfloat f => Vundef | Vsingle f => Vundef | Vptr b z => Vptr b (Ptrofs.repr (Z.add (Ptrofs.unsigned z) (Ptrofs.unsigned (Ptrofs.repr i)))) end match p with | Vundef => Vundef | Vint i => Vundef | Vlong i => Vundef | Vfloat f => Vundef | Vsingle f => Vundef | Vptr b z => Vptr b (Ptrofs.repr (Z.add (Ptrofs.unsigned z) (Ptrofs.unsigned (Ptrofs.repr i)))) end *)
   rewrite Z.mod_divide in H5b by omega. auto.
 }   
 assert (Halign: is_aligned cenv_cs ha_env_cs la_env_cs t (ofs + init_data_size a) = true). {
    clear - H1 H2.
(* Goal: @eq val match p with | Vundef => Vundef | Vint i => Vundef | Vlong i => Vundef | Vfloat f => Vundef | Vsingle f => Vundef | Vptr b z => Vptr b (Ptrofs.repr (Z.add (Ptrofs.unsigned z) (Ptrofs.unsigned (Ptrofs.repr i)))) end match p with | Vundef => Vundef | Vint i => Vundef | Vlong i => Vundef | Vfloat f => Vundef | Vsingle f => Vundef | Vptr b z => Vptr b (Ptrofs.repr (Z.add (Ptrofs.unsigned z) (Ptrofs.unsigned (Ptrofs.repr i)))) end *)
    rewrite andb_true_iff in H1; destruct H1; auto.
    unfold is_aligned, is_aligned_aux in *.
(* Goal: @eq val match p with | Vundef => Vundef | Vint i => Vundef | Vlong i => Vundef | Vfloat f => Vundef | Vsingle f => Vundef | Vptr b z => Vptr b (Ptrofs.repr (Z.add (Ptrofs.unsigned z) (Ptrofs.unsigned (Ptrofs.repr i)))) end match p with | Vundef => Vundef | Vint i => Vundef | Vlong i => Vundef | Vfloat f => Vundef | Vsingle f => Vundef | Vptr b z => Vptr b (Ptrofs.repr (Z.add (Ptrofs.unsigned z) (Ptrofs.unsigned (Ptrofs.repr i)))) end *)
    rewrite andb_true_iff in H0|-*; destruct H0; split; auto.
    rewrite Z.eqb_eq in H1|-*.
   destruct (zeq (hardware_alignof ha_env_cs t) 0).
   rewrite e. apply Zmod_0_r.
(* Goal: @eq val match p with | Vundef => Vundef | Vint i => Vundef | Vlong i => Vundef | Vfloat f => Vundef | Vsingle f => Vundef | Vptr b z => Vptr b (Ptrofs.repr (Z.add (Ptrofs.unsigned z) (Ptrofs.unsigned (Ptrofs.repr i)))) end match p with | Vundef => Vundef | Vint i => Vundef | Vlong i => Vundef | Vfloat f => Vundef | Vsingle f => Vundef | Vptr b z => Vptr b (Ptrofs.repr (Z.add (Ptrofs.unsigned z) (Ptrofs.unsigned (Ptrofs.repr i)))) end *)
   rewrite Z.mod_divide in H1|-* by auto.
(* Goal: @eq val match p with | Vundef => Vundef | Vint i => Vundef | Vlong i => Vundef | Vfloat f => Vundef | Vsingle f => Vundef | Vptr b z => Vptr b (Ptrofs.repr (Z.add (Ptrofs.unsigned z) (Ptrofs.unsigned (Ptrofs.repr i)))) end match p with | Vundef => Vundef | Vint i => Vundef | Vlong i => Vundef | Vfloat f => Vundef | Vsingle f => Vundef | Vptr b z => Vptr b (Ptrofs.repr (Z.add (Ptrofs.unsigned z) (Ptrofs.unsigned (Ptrofs.repr i)))) end *)
   apply Z.divide_add_r; auto.
 }
(* Goal: @eq val match p with | Vundef => Vundef | Vint i => Vundef | Vlong i => Vundef | Vfloat f => Vundef | Vsingle f => Vundef | Vptr b z => Vptr b (Ptrofs.repr (Z.add (Ptrofs.unsigned z) (Ptrofs.unsigned (Ptrofs.repr i)))) end match p with | Vundef => Vundef | Vint i => Vundef | Vlong i => Vundef | Vfloat f => Vundef | Vsingle f => Vundef | Vptr b z => Vptr b (Ptrofs.repr (Z.add (Ptrofs.unsigned z) (Ptrofs.unsigned (Ptrofs.repr i)))) end *)
 apply IHidata; clear IHidata; try omega; auto.
(* Goal: @eq val match p with | Vundef => Vundef | Vint i => Vundef | Vlong i => Vundef | Vfloat f => Vundef | Vsingle f => Vundef | Vptr b z => Vptr b (Ptrofs.repr (Z.add (Ptrofs.unsigned z) (Ptrofs.unsigned (Ptrofs.repr i)))) end match p with | Vundef => Vundef | Vint i => Vundef | Vlong i => Vundef | Vfloat f => Vundef | Vsingle f => Vundef | Vptr b z => Vptr b (Ptrofs.repr (Z.add (Ptrofs.unsigned z) (Ptrofs.unsigned (Ptrofs.repr i)))) end *)
 rewrite andb_true_iff in H1|-*; destruct H1; split; auto.
(* Goal: Z.lt (@sizeof (@cenv_cs cs) (@gvar_info type gv)) Ptrofs.modulus *)
 rewrite Ptrofs.unsigned_repr by omega.
(* Goal: @eq val match p with | Vundef => Vundef | Vint i => Vundef | Vlong i => Vundef | Vfloat f => Vundef | Vsingle f => Vundef | Vptr b z => Vptr b (Ptrofs.repr (Z.add (Ptrofs.unsigned z) (Ptrofs.unsigned (Ptrofs.repr i)))) end match p with | Vundef => Vundef | Vint i => Vundef | Vlong i => Vundef | Vfloat f => Vundef | Vsingle f => Vundef | Vptr b z => Vptr b (Ptrofs.repr (Z.add (Ptrofs.unsigned z) (Ptrofs.unsigned (Ptrofs.repr i)))) end *)
 apply Z.divide_add_r; auto.
Qed.

Definition inttype2init_data (sz: intsize) : (int -> init_data) :=
 match sz with
 | IBool  =>  Init_int8
 | I8  =>  Init_int8
 | I16 =>  Init_int16
 | I32 =>  Init_int32
 end.

Definition notboolsize (sz: intsize) : Prop :=
  match sz with IBool => False | _ => True end.

Lemma id2pred_star_ZnthV_Tint  {cs: compspecs} :
 forall Delta gz sh n (v: val) (data: list int) sz sign mdata
  (NBS: notboolsize sz),
  n = Zlength mdata ->
  mdata = map (inttype2init_data sz) data ->
  !! isptr v && !! align_compatible (Tint sz sign noattr) v &&
  !! (offset_strict_in_range (sizeof (Tint sz sign noattr) * n)) v &&
  id2pred_star Delta gz sh v mdata |--
  `(data_at sh (tarray (Tint sz sign noattr) n)
           (map (Basics.compose Vint (Cop.cast_int_int sz sign)) data) v).
Proof.
(* Goal: forall (cs : compspecs) (Espec : OracleKind) (Delta : tycontext) (PQR : forall _ : environ, mpred) (gv : globals) (SF : forall _ : environ, mpred) (c : statement) (Post : ret_assert) (_ : semax cs Espec Delta (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) PQR SF) c Post), semax cs Espec Delta (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) PQR (globvars2pred gv (@nil (prod ident (globvar type))))) SF) c Post *)
  intros. subst n mdata.
  replace (Zlength (map  (inttype2init_data sz) data)) with (Zlength data)
    by (repeat rewrite Zlength_correct; rewrite map_length; auto).
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (locald_denote (gvars gz))) PQR) (globvars2pred gz (@cons (prod ident (globvar type)) (@pair ident (globvar type) i gv) gvs))) SF)) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (LiftEnviron mpred) (@data_at_ cs (readonly2share (@gvar_readonly type gv)) t (gz i))) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (locald_denote (gvars gz))) PQR)) (globvars2pred gz gvs)) SF) *)
  go_lowerx.
  match goal with |- ?F _ _ _ _ _ _ _ |-- _ => change F with @id2pred_star end.
  change (offset_strict_in_range (sizeof (Tint sz sign noattr) * Zlength data) v) in H1.
  assert (offset_strict_in_range (sizeof (Tint sz sign noattr) * 0) v) by
    (unfold offset_strict_in_range; destruct v; auto; pose proof Ptrofs.unsigned_range i; omega).
unfold tarray.
set (t := Tint sz sign noattr) in *.
(* Goal: forall (cs : compspecs) (Espec : OracleKind) (Delta : tycontext) (PQR : forall _ : environ, mpred) (gv : globals) (SF : forall _ : environ, mpred) (c : statement) (Post : ret_assert) (_ : semax cs Espec Delta (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) PQR SF) c Post), semax cs Espec Delta (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) PQR (globvars2pred gv (@nil (prod ident (globvar type))))) SF) c Post *)
revert v H H0 H1 H2; induction data; intros.
*
(* Goal: Z.le (init_data_size (Init_space (@sizeof (@cenv_cs cs) t))) (@sizeof (@cenv_cs cs) t) *)
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (locald_denote (gvars gz))) PQR) (globvars2pred gz (@cons (prod ident (globvar type)) (@pair ident (globvar type) i gv) gvs))) SF)) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (LiftEnviron mpred) (@data_at_ cs (readonly2share (@gvar_readonly type gv)) t (gz i))) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (locald_denote (gvars gz))) PQR)) (globvars2pred gz gvs)) SF) *)
  rewrite Zlength_nil. unfold data_at, field_at; simpl.
(* Goal: Z.le (init_data_size (Init_space (@sizeof (@cenv_cs cs) t))) (@sizeof (@cenv_cs cs) t) *)
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (locald_denote (gvars gz))) PQR) (globvars2pred gz (@cons (prod ident (globvar type)) (@pair ident (globvar type) i gv) gvs))) SF)) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (LiftEnviron mpred) (@data_at_ cs (readonly2share (@gvar_readonly type gv)) t (gz i))) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (locald_denote (gvars gz))) PQR)) (globvars2pred gz gvs)) SF) *)
  unfold at_offset; simpl.
(* Goal: Z.le (init_data_size (Init_space (@sizeof (@cenv_cs cs) t))) (@sizeof (@cenv_cs cs) t) *)
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (locald_denote (gvars gz))) PQR) (globvars2pred gz (@cons (prod ident (globvar type)) (@pair ident (globvar type) i gv) gvs))) SF)) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (LiftEnviron mpred) (@data_at_ cs (readonly2share (@gvar_readonly type gv)) t (gz i))) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (locald_denote (gvars gz))) PQR)) (globvars2pred gz gvs)) SF) *)
   unfold nested_field_type; simpl.
   rewrite data_at_rec_eq. unfold  aggregate_pred.aggregate_pred.array_pred.
(* Goal: Z.le (init_data_size (Init_space (@sizeof (@cenv_cs cs) t))) (@sizeof (@cenv_cs cs) t) *)
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (locald_denote (gvars gz))) PQR) (globvars2pred gz (@cons (prod ident (globvar type)) (@pair ident (globvar type) i gv) gvs))) SF)) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (LiftEnviron mpred) (@data_at_ cs (readonly2share (@gvar_readonly type gv)) t (gz i))) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (locald_denote (gvars gz))) PQR)) (globvars2pred gz gvs)) SF) *)
  unfold aggregate_pred.array_pred. simpl.
(* Goal: @eq (list B) (@cons B (f x) (@map A B f z)) (@map A B f (@cons A x z)) *)
  repeat apply andp_right; auto; try apply prop_right; try reflexivity.  
(* Goal: Z.le (init_data_size (Init_space (@sizeof (@cenv_cs cs) t))) (@sizeof (@cenv_cs cs) t) *)
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (locald_denote (gvars gz))) PQR) (globvars2pred gz (@cons (prod ident (globvar type)) (@pair ident (globvar type) i gv) gvs))) SF)) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (LiftEnviron mpred) (@data_at_ cs (readonly2share (@gvar_readonly type gv)) t (gz i))) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (locald_denote (gvars gz))) PQR)) (globvars2pred gz gvs)) SF) *)
  hnf. simpl.
(* Goal: @eq val match p with | Vundef => Vundef | Vint i => Vundef | Vlong i => Vundef | Vfloat f => Vundef | Vsingle f => Vundef | Vptr b z => Vptr b (Ptrofs.repr (Z.add (Ptrofs.unsigned z) (Ptrofs.unsigned (Ptrofs.repr i)))) end match p with | Vundef => Vundef | Vint i => Vundef | Vlong i => Vundef | Vfloat f => Vundef | Vsingle f => Vundef | Vptr b z => Vptr b (Ptrofs.repr (Z.add (Ptrofs.unsigned z) (Ptrofs.unsigned (Ptrofs.repr i)))) end *)
  split3; auto.
(* Goal: @eq val match p with | Vundef => Vundef | Vint i => Vundef | Vlong i => Vundef | Vfloat f => Vundef | Vsingle f => Vundef | Vptr b z => Vptr b (Ptrofs.repr (Z.add (Ptrofs.unsigned z) (Ptrofs.unsigned (Ptrofs.repr i)))) end match p with | Vundef => Vundef | Vint i => Vundef | Vlong i => Vundef | Vfloat f => Vundef | Vsingle f => Vundef | Vptr b z => Vptr b (Ptrofs.repr (Z.add (Ptrofs.unsigned z) (Ptrofs.unsigned (Ptrofs.repr i)))) end *)
  split3; auto.
(* Goal: @eq val match p with | Vundef => Vundef | Vint i => Vundef | Vlong i => Vundef | Vfloat f => Vundef | Vsingle f => Vundef | Vptr b z => Vptr b (Ptrofs.repr (Z.add (Ptrofs.unsigned z) (Ptrofs.unsigned (Ptrofs.repr i)))) end match p with | Vundef => Vundef | Vint i => Vundef | Vlong i => Vundef | Vfloat f => Vundef | Vsingle f => Vundef | Vptr b z => Vptr b (Ptrofs.repr (Z.add (Ptrofs.unsigned z) (Ptrofs.unsigned (Ptrofs.repr i)))) end *)
  hnf. destruct v; auto. replace (sizeof (Tarray (Tint sz sign noattr) 0 noattr)) with 0 by (destruct sz; simpl; auto).
(* Goal: Z.lt (@sizeof (@cenv_cs cs) (@gvar_info type gv)) Ptrofs.modulus *)
  pose proof Ptrofs.unsigned_range i; omega.
(* Goal: @eq val match p with | Vundef => Vundef | Vint i => Vundef | Vlong i => Vundef | Vfloat f => Vundef | Vsingle f => Vundef | Vptr b z => Vptr b (Ptrofs.repr (Z.add (Ptrofs.unsigned z) (Ptrofs.unsigned (Ptrofs.repr i)))) end match p with | Vundef => Vundef | Vint i => Vundef | Vlong i => Vundef | Vfloat f => Vundef | Vsingle f => Vundef | Vptr b z => Vptr b (Ptrofs.repr (Z.add (Ptrofs.unsigned z) (Ptrofs.unsigned (Ptrofs.repr i)))) end *)
  hnf; destruct v; auto. apply align_compatible_rec_Tarray. intros. omega.
*
rewrite Zlength_cons.
(* Goal: @derives mpred Nveric (@sepcon mpred Nveric Sveric (@sepcon mpred Nveric Sveric (@andp mpred Nveric (@prop mpred Nveric (gvars_denote gz rho)) (PQR rho)) (@lift2 mpred mpred mpred (@andp mpred Nveric) (fun rho : environ => @prop mpred Nveric (@eq globals gz (globals_of_env rho))) (@fold_right (forall _ : environ, mpred) (forall _ : environ, mpred) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric)) (@emp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric)) (@map (prod ident (globvar type)) (forall _ : environ, mpred) (globvar2pred gz) (@cons (prod ident (globvar type)) (@pair ident (globvar type) i gv) gvs))) rho)) (SF rho)) (@sepcon mpred Nveric Sveric (@sepcon mpred Nveric Sveric (@sepcon mpred Nveric Sveric (@data_at_ cs (readonly2share (@gvar_readonly type gv)) t (gz i)) (@andp mpred Nveric (@prop mpred Nveric (gvars_denote gz rho)) (PQR rho))) (@lift2 mpred mpred mpred (@andp mpred Nveric) (fun rho : environ => @prop mpred Nveric (@eq globals gz (globals_of_env rho))) (@fold_right (forall _ : environ, mpred) (forall _ : environ, mpred) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric)) (@emp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric)) (@map (prod ident (globvar type)) (forall _ : environ, mpred) (globvar2pred gz) gvs)) rho)) (SF rho)) *)
simpl map.
unfold id2pred_star; fold @id2pred_star.
erewrite (split2_data_at_Tarray sh t (Z.succ (Zlength data)) 1).
4: rewrite sublist_same.
4: apply eq_refl.
(* Goal: @eq val match p with | Vundef => Vundef | Vint i => Vundef | Vlong i => Vundef | Vfloat f => Vundef | Vsingle f => Vundef | Vptr b z => Vptr b (Ptrofs.repr (Z.add (Ptrofs.unsigned z) (Ptrofs.unsigned (Ptrofs.repr i)))) end match p with | Vundef => Vundef | Vint i => Vundef | Vlong i => Vundef | Vfloat f => Vundef | Vsingle f => Vundef | Vptr b z => Vptr b (Ptrofs.repr (Z.add (Ptrofs.unsigned z) (Ptrofs.unsigned (Ptrofs.repr i)))) end *)
2: list_solve. 2: list_solve. 2: auto. 2: list_solve. 2: apply eq_refl. 2: apply eq_refl.
rewrite (sublist_one) by list_solve.
autorewrite with sublist.
rewrite sublist_1_cons.
rewrite sublist_same by list_solve.
apply sepcon_derives.
+
clear IHdata.
fold (tarray t 1). erewrite data_at_singleton_array_eq by apply eq_refl.
(* Goal: @eq val match p with | Vundef => Vundef | Vint i => Vundef | Vlong i => Vundef | Vfloat f => Vundef | Vsingle f => Vundef | Vptr b z => Vptr b (Ptrofs.repr (Z.add (Ptrofs.unsigned z) (Ptrofs.unsigned (Ptrofs.repr i)))) end match p with | Vundef => Vundef | Vint i => Vundef | Vlong i => Vundef | Vfloat f => Vundef | Vsingle f => Vundef | Vptr b z => Vptr b (Ptrofs.repr (Z.add (Ptrofs.unsigned z) (Ptrofs.unsigned (Ptrofs.repr i)))) end *)
rewrite <- (mapsto_data_at sh t (Vint (Cop.cast_int_int sz sign a)) (Vint (Cop.cast_int_int sz sign a)) v); try reflexivity; auto.
(* Goal: @eq (list B) (@cons B (f x) (@map A B f z)) (@map A B f (@cons A x z)) *)
2: subst t; destruct sz, sign; reflexivity.
2:{
(* Goal: @eq val match p with | Vundef => Vundef | Vint i => Vundef | Vlong i => Vundef | Vfloat f => Vundef | Vsingle f => Vundef | Vptr b z => Vptr b (Ptrofs.repr (Z.add (Ptrofs.unsigned z) (Ptrofs.unsigned (Ptrofs.repr i)))) end match p with | Vundef => Vundef | Vint i => Vundef | Vlong i => Vundef | Vfloat f => Vundef | Vsingle f => Vundef | Vptr b z => Vptr b (Ptrofs.repr (Z.add (Ptrofs.unsigned z) (Ptrofs.unsigned (Ptrofs.repr i)))) end *)
destruct v; auto. red.
assert (sizeof t > 0).
(* Goal: Z.le (init_data_size (Init_space (@sizeof (@cenv_cs cs) t))) (@sizeof (@cenv_cs cs) t) *)
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (locald_denote (gvars gz))) PQR) (globvars2pred gz (@cons (prod ident (globvar type)) (@pair ident (globvar type) i gv) gvs))) SF)) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (LiftEnviron mpred) (@data_at_ cs (readonly2share (@gvar_readonly type gv)) t (gz i))) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (locald_denote (gvars gz))) PQR)) (globvars2pred gz gvs)) SF) *)
subst t; simpl. destruct sz; computable.
clearbody t.
clear - H1 H3.
rewrite Zlength_cons in H1. simpl in H1.
unfold Z.succ in H1. rewrite Z.mul_add_distr_l in H1.
pose proof (Zlength_nonneg data).
rewrite Z.mul_1_r in H1.
assert (0 <= sizeof t * Zlength data)
  by (apply Z.mul_nonneg_nonneg; omega).
(* Goal: Z.lt (@sizeof (@cenv_cs cs) (@gvar_info type gv)) Ptrofs.modulus *)
 omega.
}
(* Goal: @field_compatible cs t (@nil gfield) (globals_of_env rho i) *)
subst t.
(* Goal: semax cs Espec Delta (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (PROPx P (LOCALx Q (SEPx R))) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) val (fun x : val => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (locald_denote (f x))) (@liftx (LiftEnviron mpred) (g (h x) : mpred)))) S2)) S3) S4) c Post *)
normalize.
unfold init_data2pred', inttype2init_data.
destruct sz; try contradiction NBS;
unfold_lift; unfold tuchar, tushort, tuint;  rewrite <- (mapsto_unsigned_signed Unsigned sign sh);
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (LiftEnviron mpred) (g (h x))) (PROPx P (LOCALx Q (SEPx R)))) S2) S3) S4) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (LiftEnviron mpred) (g (h x))) (PROPx P (LOCALx Q (SEPx R)))) S2) S3) S4) *)
apply derives_refl.
+
  replace (init_data_size (inttype2init_data sz a)) with (sizeof t) 
      by (subst t; destruct sz; simpl; auto).
  assert (H8: align_compatible t (offset_val (sizeof t) v)
                /\  offset_strict_in_range (sizeof t * Zlength data) (offset_val (sizeof t) v)
               /\ offset_strict_in_range (sizeof t * 0) (offset_val (sizeof t) v)).  {
   clear IHdata.
   rewrite Zlength_cons in H1. unfold Z.succ in H1.
   rewrite Z.mul_add_distr_l in H1. rewrite Z.mul_1_r in H1.
   rewrite Z.mul_0_r in H2.
(* Goal: Z.le (Z.max (@sizeof (@cenv_cs cs) t) Z0) (@sizeof (@cenv_cs cs) t) *)
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (locald_denote (gvars gz))) PQR) (globvars2pred gz (@cons (prod ident (globvar type)) (@pair ident (globvar type) i gv) gvs))) SF)) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (LiftEnviron mpred) (@data_at_ cs (readonly2share (@gvar_readonly type gv)) t (gz i))) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (locald_denote (gvars gz))) PQR)) (globvars2pred gz gvs)) SF) *)
   pose proof (sizeof_pos t). pose proof (Zlength_nonneg data).
   destruct v; try contradiction.
   pose proof (Ptrofs.unsigned_range i).
(* Goal: @derives mpred Nveric (mapsto_zeros z sh (offset_val ofs v)) (memory_block sh z (offset_val ofs v)) *)
   assert (Ptrofs.max_unsigned = Ptrofs.modulus-1) by computable.
   rewrite Z.mul_0_r in *.
   assert (0 <= sizeof t * Zlength data) by (apply Z.mul_nonneg_nonneg; omega).
   unfold offset_strict_in_range, offset_val in *.
   unfold align_compatible in H0|-*.
(* Goal: @eq val match p with | Vundef => Vundef | Vint i => Vundef | Vlong i => Vundef | Vfloat f => Vundef | Vsingle f => Vundef | Vptr b z => Vptr b (Ptrofs.add z (Ptrofs.repr (Ptrofs.unsigned (Ptrofs.repr i)))) end match p with | Vundef => Vundef | Vint i => Vundef | Vlong i => Vundef | Vfloat f => Vundef | Vsingle f => Vundef | Vptr b z => Vptr b (Ptrofs.add z (Ptrofs.repr i)) end *)
   unfold Ptrofs.add.
   rewrite (Ptrofs.unsigned_repr (sizeof t)) 
    by (unfold Ptrofs.max_unsigned, Ptrofs.modulus, Ptrofs.wordsize, Wordsize_Ptrofs.wordsize;
          clear; subst t; destruct sz,sign, Archi.ptr64; simpl; omega).
  rewrite Ptrofs.unsigned_repr.
(* Goal: Z.lt (@sizeof (@cenv_cs cs) (@gvar_info type gv)) Ptrofs.modulus *)
  split3; try omega.
   assert (exists ch, access_mode t = By_value ch)
     by (clear; subst t; destruct sz,sign; eexists; reflexivity).
  destruct H8 as [ch ?].
(* Goal: @eq val match p with | Vundef => Vundef | Vint i => Vundef | Vlong i => Vundef | Vfloat f => Vundef | Vsingle f => Vundef | Vptr b z => Vptr b (Ptrofs.repr (Z.add (Ptrofs.unsigned z) (Ptrofs.unsigned (Ptrofs.repr i)))) end match p with | Vundef => Vundef | Vint i => Vundef | Vlong i => Vundef | Vfloat f => Vundef | Vsingle f => Vundef | Vptr b z => Vptr b (Ptrofs.repr (Z.add (Ptrofs.unsigned z) (Ptrofs.unsigned (Ptrofs.repr i)))) end *)
  apply align_compatible_rec_by_value_inv with (ch:=ch) in H0; auto.
(* Goal: @eq val match p with | Vundef => Vundef | Vint i => Vundef | Vlong i => Vundef | Vfloat f => Vundef | Vsingle f => Vundef | Vptr b z => Vptr b (Ptrofs.repr (Z.add (Ptrofs.unsigned z) (Ptrofs.unsigned (Ptrofs.repr i)))) end match p with | Vundef => Vundef | Vint i => Vundef | Vlong i => Vundef | Vfloat f => Vundef | Vsingle f => Vundef | Vptr b z => Vptr b (Ptrofs.repr (Z.add (Ptrofs.unsigned z) (Ptrofs.unsigned (Ptrofs.repr i)))) end *)
  apply align_compatible_rec_by_value with (ch:=ch); auto.
(* Goal: @eq val match p with | Vundef => Vundef | Vint i => Vundef | Vlong i => Vundef | Vfloat f => Vundef | Vsingle f => Vundef | Vptr b z => Vptr b (Ptrofs.repr (Z.add (Ptrofs.unsigned z) (Ptrofs.unsigned (Ptrofs.repr i)))) end match p with | Vundef => Vundef | Vint i => Vundef | Vlong i => Vundef | Vfloat f => Vundef | Vsingle f => Vundef | Vptr b z => Vptr b (Ptrofs.repr (Z.add (Ptrofs.unsigned z) (Ptrofs.unsigned (Ptrofs.repr i)))) end *)
   apply Z.divide_add_r; auto.
(* Goal: @field_compatible cs t (@nil gfield) (globals_of_env rho i) *)
  clear - H8. subst t. destruct sz,sign; inv H8; simpl; apply Z.divide_refl.
  unfold Ptrofs.max_unsigned.
(* Goal: Z.lt (@sizeof (@cenv_cs cs) (@gvar_info type gv)) Ptrofs.modulus *)
  omega.
 }
 destruct H8 as [H8a [H8b H8c]].
(* Goal: @eq val match p with | Vundef => Vundef | Vint i => Vundef | Vlong i => Vundef | Vfloat f => Vundef | Vsingle f => Vundef | Vptr b z => Vptr b (Ptrofs.repr (Z.add (Ptrofs.unsigned z) (Ptrofs.unsigned (Ptrofs.repr i)))) end match p with | Vundef => Vundef | Vint i => Vundef | Vlong i => Vundef | Vfloat f => Vundef | Vsingle f => Vundef | Vptr b z => Vptr b (Ptrofs.repr (Z.add (Ptrofs.unsigned z) (Ptrofs.unsigned (Ptrofs.repr i)))) end *)
  eapply derives_trans; [ apply IHdata | ]; clear IHdata; auto.
  replace (Z.succ (Zlength data) - 1) with (Zlength data) by (clear; omega).
(* Goal: @eq val (Vptr b0 i0) (Vptr b0 (Ptrofs.repr (Ptrofs.unsigned i0))) *)
   apply derives_refl'; f_equal.
 unfold field_address0.
  rewrite if_true.
(* Goal: @eq val match p with | Vundef => Vundef | Vint i => Vundef | Vlong i => Vundef | Vfloat f => Vundef | Vsingle f => Vundef | Vptr b z => Vptr b (Ptrofs.repr (Z.add (Ptrofs.unsigned z) (Ptrofs.unsigned (Ptrofs.repr i)))) end match p with | Vundef => Vundef | Vint i => Vundef | Vlong i => Vundef | Vfloat f => Vundef | Vsingle f => Vundef | Vptr b z => Vptr b (Ptrofs.repr (Z.add (Ptrofs.unsigned z) (Ptrofs.unsigned (Ptrofs.repr i)))) end *)
  unfold offset_val. destruct v; simpl; auto. f_equal.
(* Goal: @eq (list B) (@cons B (f x) (@map A B f z)) (@map A B f (@cons A x z)) *)
  subst t; destruct sz,sign; reflexivity.
  eapply field_compatible0_cons_Tarray.
(* Goal: @eq (list B) (@cons B (f x) (@map A B f z)) (@map A B f (@cons A x z)) *)
  reflexivity.
(* Goal: Z.le (init_data_size (Init_space (@sizeof (@cenv_cs cs) t))) (@sizeof (@cenv_cs cs) t) *)
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (locald_denote (gvars gz))) PQR) (globvars2pred gz (@cons (prod ident (globvar type)) (@pair ident (globvar type) i gv) gvs))) SF)) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (LiftEnviron mpred) (@data_at_ cs (readonly2share (@gvar_readonly type gv)) t (gz i))) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (locald_denote (gvars gz))) PQR)) (globvars2pred gz gvs)) SF) *)
  hnf; simpl. split3; auto. 
  destruct v; try contradiction.
  split3; auto; red.
  unfold sizeof; fold sizeof.
  pose proof (Zlength_nonneg data).
(* Goal: Z.lt (@sizeof (@cenv_cs cs) (@gvar_info type gv)) Ptrofs.modulus *)
  rewrite Z.max_r by omega.
  unfold offset_strict_in_range in H1. rewrite Zlength_cons in H1.
(* Goal: Z.lt (@sizeof (@cenv_cs cs) (@gvar_info type gv)) Ptrofs.modulus *)
  omega.
(* Goal: forall (cs : compspecs) (Espec : OracleKind) (Delta : tycontext) (PQR : forall _ : environ, mpred) (gv : globals) (SF : forall _ : environ, mpred) (c : statement) (Post : ret_assert) (_ : semax cs Espec Delta (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) PQR SF) c Post), semax cs Espec Delta (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) PQR (globvars2pred gv (@nil (prod ident (globvar type))))) SF) c Post *)
  apply align_compatible_rec_Tarray; intros.
  unfold align_compatible, offset_val in H8a.
  assert (exists ch, access_mode t = By_value ch)
     by (clear; subst t; destruct sz,sign; eexists; reflexivity).
   destruct H4 as [ch ?].
  eapply align_compatible_rec_by_value; try eassumption.
  simpl in H0.
  eapply align_compatible_rec_by_value_inv in H0; try eassumption.
(* Goal: @eq val match p with | Vundef => Vundef | Vint i => Vundef | Vlong i => Vundef | Vfloat f => Vundef | Vsingle f => Vundef | Vptr b z => Vptr b (Ptrofs.repr (Z.add (Ptrofs.unsigned z) (Ptrofs.unsigned (Ptrofs.repr i)))) end match p with | Vundef => Vundef | Vint i => Vundef | Vlong i => Vundef | Vfloat f => Vundef | Vsingle f => Vundef | Vptr b z => Vptr b (Ptrofs.repr (Z.add (Ptrofs.unsigned z) (Ptrofs.unsigned (Ptrofs.repr i)))) end *)
  apply Z.divide_add_r; auto.
(* Goal: @eq val match p with | Vundef => Vundef | Vint i => Vundef | Vlong i => Vundef | Vfloat f => Vundef | Vsingle f => Vundef | Vptr b z => Vptr b (Ptrofs.repr (Z.add (Ptrofs.unsigned z) (Ptrofs.unsigned (Ptrofs.repr i)))) end match p with | Vundef => Vundef | Vint i => Vundef | Vlong i => Vundef | Vfloat f => Vundef | Vsingle f => Vundef | Vptr b z => Vptr b (Ptrofs.repr (Z.add (Ptrofs.unsigned z) (Ptrofs.unsigned (Ptrofs.repr i)))) end *)
  apply Z.divide_mul_l; auto.
  clear - t H4.
(* Goal: @field_compatible cs t (@nil gfield) (globals_of_env rho i) *)
  subst t.
  destruct sz,sign; inv H4; try apply Z.divide_refl.
(* Goal: Z.lt (@sizeof (@cenv_cs cs) (@gvar_info type gv)) Ptrofs.modulus *)
  pose proof (Zlength_nonneg data); omega.
Qed.

Lemma id2pred_star_ZnthV_tint  {cs: compspecs}:
 forall Delta gz sh n (v: val) (data: list int) mdata,
  n = Zlength mdata ->
  mdata = map Init_int32 data ->
  !! isptr v && !! align_compatible tint v &&
  !! offset_strict_in_range (sizeof tint * n) v &&
  id2pred_star Delta gz sh v mdata |--
  `(data_at sh (tarray tint n) (map Vint data) v).
(* Goal: forall (Delta : tycontext) (gz : globals) (sh : share) (n : Z) (v : val) (data : list Int.int) (mdata : list init_data) (_ : @eq Z n (@Zlength init_data mdata)) (_ : @eq (list init_data) mdata (@map Int.int init_data Init_int32 data)), @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (isptr v)) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@align_compatible cs tint v))) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (offset_strict_in_range (Z.mul (@sizeof (@cenv_cs cs) tint) n) v))) (@id2pred_star cs Delta gz sh v mdata)) (@liftx (LiftEnviron mpred) (@data_at cs sh (tarray tint n) (@map Int.int val Vint data) v : mpred)) *)
Proof. intros; apply id2pred_star_ZnthV_Tint; auto; apply Coq.Init.Logic.I.
Qed.

Lemma offset_zero_globals_of_env: forall rho i,
   offset_val 0 (globals_of_env rho i) = globals_of_env rho i.
Proof.
(* Goal: forall (cs : compspecs) (Espec : OracleKind) (Delta : tycontext) (PQR : forall _ : environ, mpred) (gv : globals) (SF : forall _ : environ, mpred) (c : statement) (Post : ret_assert) (_ : semax cs Espec Delta (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) PQR SF) c Post), semax cs Espec Delta (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) PQR (globvars2pred gv (@nil (prod ident (globvar type))))) SF) c Post *)
intros.
(* Goal: @eq val (offset_val Z0 (globals_of_env rho i)) (globals_of_env rho i) *)
unfold globals_of_env.
(* Goal: @eq val match p with | Vundef => Vundef | Vint i => Vundef | Vlong i => Vundef | Vfloat f => Vundef | Vsingle f => Vundef | Vptr b z => Vptr b (Ptrofs.repr (Z.add (Ptrofs.unsigned z) (Ptrofs.unsigned (Ptrofs.repr i)))) end match p with | Vundef => Vundef | Vint i => Vundef | Vlong i => Vundef | Vfloat f => Vundef | Vsingle f => Vundef | Vptr b z => Vptr b (Ptrofs.repr (Z.add (Ptrofs.unsigned z) (Ptrofs.unsigned (Ptrofs.repr i)))) end *)
destruct (Map.get (ge_of rho) i); simpl; auto.
Qed.

Lemma unpack_globvar_array  {cs: compspecs}:
  forall t sz sign (data: list int)  n Delta gz i gv,
   (var_types Delta) ! i = None ->
   (glob_types Delta) ! i = Some (gvar_info gv) ->
   gvar_info gv = tarray t n ->
   gvar_volatile gv = false ->
   globvar_all_aligned gv = true ->
   t = Tint sz sign noattr ->
  forall    (NBS: notboolsize sz),
   n = Zlength (gvar_init gv) ->
   gvar_init gv = map (inttype2init_data sz) data ->
   init_data_list_size (gvar_init gv) <= sizeof (gvar_info gv) <= Ptrofs.max_unsigned ->
   local (`and (tc_environ Delta) (fun rho =>gz = globals_of_env rho)) && globvar2pred gz(i, gv) |--
      `(data_at (readonly2share (gvar_readonly gv))
         (tarray (Tint sz sign noattr) n)
         (map (Basics.compose Vint (Cop.cast_int_int sz sign)) data)
         (gz i)).
Proof.
(* Goal: forall (cs : compspecs) (Espec : OracleKind) (Delta : tycontext) (PQR : forall _ : environ, mpred) (gv : globals) (SF : forall _ : environ, mpred) (c : statement) (Post : ret_assert) (_ : semax cs Espec Delta (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) PQR SF) c Post), semax cs Espec Delta (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) PQR (globvars2pred gv (@nil (prod ident (globvar type))))) SF) c Post *)
  intros until 4. intros Hgal; intros. subst t.
  match goal with |- ?A |-- _ =>
    erewrite (add_andp A (local (tc_environ Delta)))
  end.
 2: solve [apply andp_left1; unfold local, lift1; intro rho; apply prop_derives; intros [? ?]; auto].
  match goal with |- ?A |-- _ =>
    erewrite (add_andp A (local (`isptr (eval_var i (tarray (Tint sz sign noattr) n)))))
  end.
  2:{
(* Goal: @eq val match p with | Vundef => Vundef | Vint i => Vundef | Vlong i => Vundef | Vfloat f => Vundef | Vsingle f => Vundef | Vptr b z => Vptr b (Ptrofs.repr (Z.add (Ptrofs.unsigned z) (Ptrofs.unsigned (Ptrofs.repr i)))) end match p with | Vundef => Vundef | Vint i => Vundef | Vlong i => Vundef | Vfloat f => Vundef | Vsingle f => Vundef | Vptr b z => Vptr b (Ptrofs.repr (Z.add (Ptrofs.unsigned z) (Ptrofs.unsigned (Ptrofs.repr i)))) end *)
    go_lowerx. apply prop_right. eapply eval_var_isptr; eauto.
(* Goal: @eq val match p with | Vundef => Vundef | Vint i => Vundef | Vlong i => Vundef | Vfloat f => Vundef | Vsingle f => Vundef | Vptr b z => Vptr b (Ptrofs.repr (Z.add (Ptrofs.unsigned z) (Ptrofs.unsigned (Ptrofs.repr i)))) end match p with | Vundef => Vundef | Vint i => Vundef | Vlong i => Vundef | Vfloat f => Vundef | Vsingle f => Vundef | Vptr b z => Vptr b (Ptrofs.repr (Z.add (Ptrofs.unsigned z) (Ptrofs.unsigned (Ptrofs.repr i)))) end *)
    right; split; auto. rewrite <- H1; auto.
   }
  eapply derives_trans.
  apply andp_right.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (LiftEnviron mpred) (g (h x))) (PROPx P (LOCALx Q (SEPx R)))) S2) S3) S4) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (LiftEnviron mpred) (g (h x))) (PROPx P (LOCALx Q (SEPx R)))) S2) S3) S4) *)
  apply andp_left1. apply andp_left1. apply andp_left1. apply derives_refl.
  apply andp_derives; [ apply andp_derives; [ eapply unpack_globvar_star; try eassumption; try reflexivity | apply derives_refl]  | apply derives_refl].
* rewrite andb_true_iff.
  split; rewrite H1.
(* Goal: @eq (list B) (@cons B (f x) (@map A B f z)) (@map A B f (@cons A x z)) *)
  reflexivity.
  unfold is_aligned, is_aligned_aux. rewrite andb_true_iff; split.
(* Goal: @eq val match p with | Vundef => Vundef | Vint i => Vundef | Vlong i => Vundef | Vfloat f => Vundef | Vsingle f => Vundef | Vptr b z => Vptr b (Ptrofs.repr (Z.add (Ptrofs.unsigned z) (Ptrofs.unsigned (Ptrofs.repr i)))) end match p with | Vundef => Vundef | Vint i => Vundef | Vlong i => Vundef | Vfloat f => Vundef | Vsingle f => Vundef | Vptr b z => Vptr b (Ptrofs.repr (Z.add (Ptrofs.unsigned z) (Ptrofs.unsigned (Ptrofs.repr i)))) end *)
  destruct sz, sign; simpl; auto.
(* Goal: @eq (list B) (@cons B (f x) (@map A B f z)) (@map A B f (@cons A x z)) *)
  rewrite Z.mod_0_l. reflexivity.
  destruct sz, sign; simpl; computable.
*
 (* rewrite H1.*)  (* rewrite H3.*) rewrite H5.
  rewrite <- andp_assoc.
  apply andp_left1.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (locald_denote (gvars gz))) PQR) (globvars2pred gz (@cons (prod ident (globvar type)) (@pair ident (globvar type) i gv) gvs))) SF)) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (LiftEnviron mpred) (@data_at_ cs (readonly2share (@gvar_readonly type gv)) t (gz i))) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (locald_denote (gvars gz))) PQR)) (globvars2pred gz gvs)) SF) *)
  go_lowerx. 
  eapply derives_trans; [| apply (id2pred_star_ZnthV_Tint Delta (globals_of_env rho)); auto].
  instantiate (1 := rho).
(* Goal: @eq val match p with | Vundef => Vundef | Vint i => Vundef | Vlong i => Vundef | Vfloat f => Vundef | Vsingle f => Vundef | Vptr b z => Vptr b (Ptrofs.repr (Z.add (Ptrofs.unsigned z) (Ptrofs.unsigned (Ptrofs.repr i)))) end match p with | Vundef => Vundef | Vint i => Vundef | Vlong i => Vundef | Vfloat f => Vundef | Vsingle f => Vundef | Vptr b z => Vptr b (Ptrofs.repr (Z.add (Ptrofs.unsigned z) (Ptrofs.unsigned (Ptrofs.repr i)))) end *)
 2: rewrite <- H5; auto.
 match goal with |- ?F _ _ _ _ _ _ _ |-- _ => change F with @id2pred_star end.
  subst gz.
(* Goal: semax cs Espec Delta (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (PROPx P (LOCALx Q (SEPx R))) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) val (fun x : val => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (locald_denote (f x))) (@liftx (LiftEnviron mpred) (g (h x) : mpred)))) S2)) S3) S4) c Post *)
  normalize. clear H8.
  rewrite H1 in H6.
  assert (headptr (globals_of_env rho i)). {
(* Goal: @eq val (offset_val Z0 (globals_of_env rho i)) (globals_of_env rho i) *)
    unfold globals_of_env. destruct  (globvar_eval_var _ _ _ _ H3 H H0) as [b [_ H10]]. rewrite H10.
(* Goal: @eq val match p with | Vundef => Vundef | Vint i => Vundef | Vlong i => Vundef | Vfloat f => Vundef | Vsingle f => Vundef | Vptr b z => Vptr b (Ptrofs.repr (Z.add (Ptrofs.unsigned z) (Ptrofs.unsigned (Ptrofs.repr i)))) end match p with | Vundef => Vundef | Vint i => Vundef | Vlong i => Vundef | Vfloat f => Vundef | Vsingle f => Vundef | Vptr b z => Vptr b (Ptrofs.repr (Z.add (Ptrofs.unsigned z) (Ptrofs.unsigned (Ptrofs.repr i)))) end *)
    exists b; auto. 
  }
  assert (align_compatible (Tint sz sign noattr) (globals_of_env rho i)). {
    destruct H7 as [b ?]. rewrite H7.
   assert (exists ch, access_mode (Tint sz sign noattr) = By_value ch)
     by (clear; destruct sz,sign; eexists; reflexivity).
   destruct H8 as [ch ?].
    eapply align_compatible_rec_by_value; try eassumption.
    rewrite Ptrofs.unsigned_zero.
    apply Z.divide_0_r.
  }
 apply headptr_isptr in H7.
 simpl andp. fold (sizeof (Tint sz sign noattr)).
  assert (offset_strict_in_range (sizeof (Tint sz sign noattr) * n) (globals_of_env rho i)). {
    unfold offset_strict_in_range.
(* Goal: @eq val match p with | Vundef => Vundef | Vint i => Vundef | Vlong i => Vundef | Vfloat f => Vundef | Vsingle f => Vundef | Vptr b z => Vptr b (Ptrofs.repr (Z.add (Ptrofs.unsigned z) (Ptrofs.unsigned (Ptrofs.repr i)))) end match p with | Vundef => Vundef | Vint i => Vundef | Vlong i => Vundef | Vfloat f => Vundef | Vsingle f => Vundef | Vptr b z => Vptr b (Ptrofs.repr (Z.add (Ptrofs.unsigned z) (Ptrofs.unsigned (Ptrofs.repr i)))) end *)
    destruct (globals_of_env rho i) eqn:?H; auto.
    rewrite H5 in H6; simpl in H6.
    pose proof initial_world.zlength_nonneg _ (gvar_init gv).
(* Goal: Z.lt (@sizeof (@cenv_cs cs) (@gvar_info type gv)) Ptrofs.modulus *)
    rewrite Z.max_r in H6 by omega.
    fold (sizeof (Tint sz sign noattr)) in H6.
    unfold Ptrofs.max_unsigned in H6.
    pose proof init_data_list_size_pos (gvar_init gv).
(* Goal: @derives mpred Nveric (globvar2pred (globals_of_env rho) (@pair ident (globvar type) i gv) rho) (@data_at cs (readonly2share (@gvar_readonly type gv)) (tarray (Tint sz sign noattr) n) (@map Int.int val (@Basics.compose Int.int Int.int val Vint (Cop.cast_int_int sz sign)) data) (globals_of_env rho i)) *)
    simpl in H8.
    unfold globals_of_env in H9. destruct (Map.get (ge_of rho) i) eqn:?H; inv H9.
    rewrite Ptrofs.unsigned_zero.
(* Goal: Z.lt (@sizeof (@cenv_cs cs) (@gvar_info type gv)) Ptrofs.modulus *)
    split; try omega. 
    rewrite Z.add_0_l.
    apply Z.mul_nonneg_nonneg.
(* Goal: Z.lt (@sizeof (@cenv_cs cs) (@gvar_info type gv)) Ptrofs.modulus *)
    clear; pose proof (sizeof_pos (Tint sz sign noattr)); omega.
    apply Zlength_nonneg.
  }
(* Goal: semax cs Espec Delta (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (PROPx P (LOCALx Q (SEPx R))) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) val (fun x : val => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (locald_denote (f x))) (@liftx (LiftEnviron mpred) (g (h x) : mpred)))) S2)) S3) S4) c Post *)
  normalize.
 match goal with |- _ |-- ?F _ _ _ _ _ _ _ => change F with @id2pred_star end.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (LiftEnviron mpred) (g (h x))) (PROPx P (LOCALx Q (SEPx R)))) S2) S3) S4) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (LiftEnviron mpred) (g (h x))) (PROPx P (LOCALx Q (SEPx R)))) S2) S3) S4) *)
  apply derives_refl.
Qed.

Lemma process_globvar':
  forall {cs: compspecs} {Espec: OracleKind} Delta P Q R (i: ident)
          gz gv gvs SF c Post (idata : init_data) t,
       (var_types Delta) ! i = None ->
       (glob_types Delta) ! i = Some t ->
  (complete_legal_cosu_type (gvar_info gv) && is_aligned cenv_cs ha_env_cs la_env_cs (gvar_info gv) 0)%bool = true ->
       gvar_volatile gv = false ->
       gvar_info gv = t ->
       gvar_init gv = (idata::nil) ->
       init_data_size idata <= sizeof t ->
       sizeof t <= Ptrofs.max_unsigned ->
  semax Delta (PROPx P (LOCALx (gvars gz::Q) (SEPx R))
                       * id2pred_star Delta gz
                         (readonly2share (gvar_readonly gv))
                         (gz i) (idata ::nil) * globvars2pred gz gvs * SF)
     c Post ->
 semax Delta (PROPx P (LOCALx (gvars gz::Q) (SEPx R))
                      * globvars2pred gz ((i,gv)::gvs) * SF)
     c Post.
Proof.
(* Goal: forall (cs : compspecs) (Espec : OracleKind) (Delta : tycontext) (PQR : forall _ : environ, mpred) (gv : globals) (SF : forall _ : environ, mpred) (c : statement) (Post : ret_assert) (_ : semax cs Espec Delta (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) PQR SF) c Post), semax cs Espec Delta (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) PQR (globvars2pred gv (@nil (prod ident (globvar type))))) SF) c Post *)
intros.
(* Goal: semax cs Espec Delta (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (PROPx P (LOCALx (@cons localdef (gvars gz) Q) (SEPx R))) (globvars2pred gz (@cons (prod ident (globvar type)) (@pair ident (globvar type) i gv) gvs))) SF) c Post *)
eapply semax_pre; [ | apply H7]; clear H7.
pose proof  (unpack_globvar Delta gz i t gv idata H H0 H1 H2 H3 H4 H5 H6).
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (PROPx P (LOCALx (@cons localdef (gvars gz) Q) (SEPx R))) (globvars2pred gz (@cons (prod ident (globvar type)) (@pair ident (globvar type) i gv) gvs))) SF)) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (PROPx P (LOCALx (@cons localdef (gvars gz) Q) (SEPx R))) (@id2pred_star cs Delta gz (readonly2share (@gvar_readonly type gv)) (gz i) (@cons init_data idata (@nil init_data)))) (globvars2pred gz gvs)) SF) *)
clear H H0 H1 H2 H3 H4 H5 H6.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (PROPx P (LOCALx Q (SEPx R))) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (locald_denote (f x))) (@liftx (LiftEnviron mpred) (g (h x)))) S2)) S3) S4) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (LiftEnviron mpred) (g (h x))) (PROPx P (LOCALx (@cons localdef (f x) Q) (SEPx R)))) S2) S3) S4) *)
rewrite <- insert_local.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (locald_denote (gvars gz))) (PROPx P (LOCALx Q (SEPx R)))) (globvars2pred gz (@cons (prod ident (globvar type)) (@pair ident (globvar type) i gv) gvs))) SF)) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (LiftEnviron mpred) (@data_at_ cs (readonly2share (@gvar_readonly type gv)) t (gz i))) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (locald_denote (gvars gz))) (PROPx P (LOCALx Q (SEPx R))))) (globvars2pred gz gvs)) SF) *)
forget (PROPx P (LOCALx Q (SEPx R))) as PQR.
unfold globvars2pred.
change (lift_S (LiftEnviron Prop)) with environ in *.
(* Goal: @derives mpred Nveric (@sepcon mpred Nveric Sveric (@sepcon mpred Nveric Sveric (@andp mpred Nveric (@prop mpred Nveric (gvars_denote gz rho)) (PQR rho)) (@lift2 mpred mpred mpred (@andp mpred Nveric) (fun rho : environ => @prop mpred Nveric (@eq globals gz (globals_of_env rho))) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (globvar2pred gz (@pair ident (globvar type) i gv)) (@fold_right (forall _ : environ, mpred) (forall _ : environ, mpred) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric)) (@emp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric)) (@map (prod ident (globvar type)) (forall _ : environ, mpred) (globvar2pred gz) gvs))) rho)) (SF rho)) (@sepcon mpred Nveric Sveric (@sepcon mpred Nveric Sveric (@sepcon mpred Nveric Sveric (@data_at_ cs (readonly2share (@gvar_readonly type gv)) t (gz i)) (@andp mpred Nveric (@prop mpred Nveric (gvars_denote gz rho)) (PQR rho))) (@lift2 mpred mpred mpred (@andp mpred Nveric) (fun rho : environ => @prop mpred Nveric (@eq globals gz (globals_of_env rho))) (@fold_right (forall _ : environ, mpred) (forall _ : environ, mpred) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric)) (@emp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric)) (@map (prod ident (globvar type)) (forall _ : environ, mpred) (globvar2pred gz) gvs)) rho)) (SF rho)) *)
unfold lift2.
change  (fun rho : environ => gz = globals_of_env rho)
  with (locald_denote (gvars gz)) in H7|-*.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (locald_denote (gvars gz))) PQR) (globvars2pred gz (@cons (prod ident (globvar type)) (@pair ident (globvar type) i gv) gvs))) SF)) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (LiftEnviron mpred) (@data_at_ cs (readonly2share (@gvar_readonly type gv)) t (gz i))) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (locald_denote (gvars gz))) PQR)) (globvars2pred gz gvs)) SF) *)
go_lowerx.
(* Goal: semax cs Espec Delta (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (PROPx P (LOCALx Q (SEPx R))) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) val (fun x : val => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (locald_denote (f x))) (@liftx (LiftEnviron mpred) (g (h x) : mpred)))) S2)) S3) S4) c Post *)
normalize.
(* Goal: @eq val match p with | Vundef => Vundef | Vint i => Vundef | Vlong i => Vundef | Vfloat f => Vundef | Vsingle f => Vundef | Vptr b z => Vptr b (Ptrofs.repr (Z.add (Ptrofs.unsigned z) (Ptrofs.unsigned (Ptrofs.repr i)))) end match p with | Vundef => Vundef | Vint i => Vundef | Vlong i => Vundef | Vfloat f => Vundef | Vsingle f => Vundef | Vptr b z => Vptr b (Ptrofs.repr (Z.add (Ptrofs.unsigned z) (Ptrofs.unsigned (Ptrofs.repr i)))) end *)
apply sepcon_derives; auto.
(* Goal: @derives mpred Nveric (@sepcon mpred Nveric Sveric (PQR rho) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (globvar2pred (globals_of_env rho) (@pair ident (globvar type) i gv)) (@fold_right (forall _ : environ, mpred) (forall _ : environ, mpred) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric)) (@emp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric)) (@map (prod ident (globvar type)) (forall _ : environ, mpred) (globvar2pred (globals_of_env rho)) gvs)) rho)) (@sepcon mpred Nveric Sveric (@sepcon mpred Nveric Sveric (PQR rho) (@data_at_ cs (readonly2share (@gvar_readonly type gv)) t (globals_of_env rho i))) (@fold_right (forall _ : environ, mpred) (forall _ : environ, mpred) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric)) (@emp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric)) (@map (prod ident (globvar type)) (forall _ : environ, mpred) (globvar2pred (globals_of_env rho)) gvs) rho)) *)
rewrite sepcon_assoc.
(* Goal: @eq val match p with | Vundef => Vundef | Vint i => Vundef | Vlong i => Vundef | Vfloat f => Vundef | Vsingle f => Vundef | Vptr b z => Vptr b (Ptrofs.repr (Z.add (Ptrofs.unsigned z) (Ptrofs.unsigned (Ptrofs.repr i)))) end match p with | Vundef => Vundef | Vint i => Vundef | Vlong i => Vundef | Vfloat f => Vundef | Vsingle f => Vundef | Vptr b z => Vptr b (Ptrofs.repr (Z.add (Ptrofs.unsigned z) (Ptrofs.unsigned (Ptrofs.repr i)))) end *)
apply sepcon_derives; auto.
(* Goal: @eq val match p with | Vundef => Vundef | Vint i => Vundef | Vlong i => Vundef | Vfloat f => Vundef | Vsingle f => Vundef | Vptr b z => Vptr b (Ptrofs.repr (Z.add (Ptrofs.unsigned z) (Ptrofs.unsigned (Ptrofs.repr i)))) end match p with | Vundef => Vundef | Vint i => Vundef | Vlong i => Vundef | Vfloat f => Vundef | Vsingle f => Vundef | Vptr b z => Vptr b (Ptrofs.repr (Z.add (Ptrofs.unsigned z) (Ptrofs.unsigned (Ptrofs.repr i)))) end *)
apply sepcon_derives; auto.
(* Goal: @derives mpred Nveric (globvar2pred (globals_of_env rho) (@pair ident (globvar type) i gv) rho) (@data_at_ cs (readonly2share (@gvar_readonly type gv)) t (globals_of_env rho i)) *)
unfold local, lift1 in H7. specialize (H7 rho). simpl in H7. rewrite prop_true_andp in H7 by (split; auto).
(* Goal: @derives mpred Nveric (globvar2pred (globals_of_env rho) (@pair ident (globvar type) i gv) rho) (@liftx (LiftEnviron mpred) (@init_data2pred' cs Delta (globals_of_env rho) idata (readonly2share (@gvar_readonly type gv)) (globals_of_env rho i)) rho) *)
apply H7.
Qed.

Lemma process_globvar_array:
  forall {cs: compspecs} {Espec: OracleKind} Delta gz P Q R (i: ident)
          gv gvs SF c Post (n: Z) (t: type)  (sz : intsize) (sign : signedness) (data : list int),
       (var_types Delta) ! i = None ->
       (glob_types Delta) ! i = Some (gvar_info gv) ->
       gvar_info gv = tarray t n ->
       gvar_volatile gv = false ->
       globvar_all_aligned gv = true ->
       t = Tint sz sign noattr ->
       notboolsize sz ->
       n = Zlength (gvar_init gv) ->
       gvar_init gv = map (inttype2init_data sz) data ->
       init_data_list_size (gvar_init gv) <= sizeof (gvar_info gv) <=
       Ptrofs.max_unsigned ->
  semax Delta (PROPx P (LOCALx (gvars gz :: Q)
                      (SEPx ((data_at
                   (readonly2share (gvar_readonly gv))
                   (tarray (Tint sz sign noattr) n)
                   (map (Vint oo Cop.cast_int_int sz sign) data) (gz i))
                    :: R)))
                       * globvars2pred gz gvs * SF)
     c Post ->
 semax Delta (PROPx P (LOCALx (gvars gz :: Q) (SEPx R))
                      * globvars2pred gz ((i,gv)::gvs) * SF)
     c Post.
Proof.
(* Goal: forall (cs : compspecs) (Espec : OracleKind) (Delta : tycontext) (PQR : forall _ : environ, mpred) (gv : globals) (SF : forall _ : environ, mpred) (c : statement) (Post : ret_assert) (_ : semax cs Espec Delta (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) PQR SF) c Post), semax cs Espec Delta (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) PQR (globvars2pred gv (@nil (prod ident (globvar type))))) SF) c Post *)
intros until 4. intro Hgal; intros.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (PROPx P (LOCALx (@cons localdef (gvars gz) Q) (SEPx R))) (globvars2pred gz (@cons (prod ident (globvar type)) (@pair ident (globvar type) i gv) gvs))) SF)) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (PROPx P (LOCALx (@cons localdef (gvars gz) Q) (SEPx (@cons mpred (@data_at cs (readonly2share (@gvar_readonly type gv)) (tarray (Tint sz sign noattr) n) (@map Int.int val (@Basics.compose Int.int Int.int val Vint (Cop.cast_int_int sz sign)) data) (gz i)) R)))) (globvars2pred gz gvs)) SF) *)
eapply semax_pre; [ | apply H8]. clear H8.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (PROPx P (LOCALx (@cons localdef (gvars gz) Q) (SEPx R))) (globvars2pred gz (@cons (prod ident (globvar type)) (@pair ident (globvar type) i gv) gvs))) SF)) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (PROPx P (LOCALx (@cons localdef (gvars gz) Q) (SEPx (@cons mpred (@data_at cs (readonly2share (@gvar_readonly type gv)) (tarray (Tint sz sign noattr) n) (@map Int.int val (@Basics.compose Int.int Int.int val Vint (Cop.cast_int_int sz sign)) data) (gz i)) R)))) (globvars2pred gz gvs)) SF) *)
pose proof (unpack_globvar_array _ _ _ _ _ _ gz _ _ H H0 H1 H2 Hgal H3 H4 H5 H6 H7).
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (PROPx P (LOCALx (@cons localdef (gvars gz) Q) (SEPx R))) (globvars2pred gz (@cons (prod ident (globvar type)) (@pair ident (globvar type) i gv) gvs))) SF)) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (PROPx P (LOCALx (@cons localdef (gvars gz) Q) (SEPx (@cons mpred (@data_at cs (readonly2share (@gvar_readonly type gv)) (tarray (Tint sz sign noattr) n) (@map Int.int val (@Basics.compose Int.int Int.int val Vint (Cop.cast_int_int sz sign)) data) (gz i)) R)))) (globvars2pred gz gvs)) SF) *)
clear H H0 H1 H2 H3 H4 H5 H6 H7.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (PROPx P (LOCALx (@cons localdef (gvars gz) Q) (SEPx R))) (globvars2pred gz (@cons (prod ident (globvar type)) (@pair ident (globvar type) i gv) gvs))) SF)) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (PROPx P (LOCALx (@cons localdef (gvars gz) Q) (SEPx R))) (@id2pred_star cs Delta gz (readonly2share (@gvar_readonly type gv)) (gz i) (@gvar_init type gv))) (globvars2pred gz gvs)) SF) *)
rewrite <- !insert_local.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (PROPx P (LOCALx Q (SEPx R))) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (locald_denote (f x))) (@liftx (LiftEnviron mpred) (g (h x)))) S2)) S3) S4) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (PROPx P (LOCALx (@cons localdef (f x) Q) (SEPx (@cons mpred (g (h x)) R)))) S2) S3) S4) *)
rewrite <- insert_SEP.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (locald_denote (gvars gz))) (PROPx P (LOCALx Q (SEPx R)))) (globvars2pred gz (@cons (prod ident (globvar type)) (@pair ident (globvar type) i gv) gvs))) SF)) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (LiftEnviron mpred) (@data_at_ cs (readonly2share (@gvar_readonly type gv)) t (gz i))) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (locald_denote (gvars gz))) (PROPx P (LOCALx Q (SEPx R))))) (globvars2pred gz gvs)) SF) *)
forget (PROPx P (LOCALx Q (SEPx R))) as PQR.
unfold globvars2pred.
change (lift_S (LiftEnviron Prop)) with environ in *.
(* Goal: @derives mpred Nveric (@sepcon mpred Nveric Sveric (@sepcon mpred Nveric Sveric (@andp mpred Nveric (@prop mpred Nveric (gvars_denote gz rho)) (PQR rho)) (@lift2 mpred mpred mpred (@andp mpred Nveric) (fun rho : environ => @prop mpred Nveric (@eq globals gz (globals_of_env rho))) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (globvar2pred gz (@pair ident (globvar type) i gv)) (@fold_right (forall _ : environ, mpred) (forall _ : environ, mpred) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric)) (@emp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric)) (@map (prod ident (globvar type)) (forall _ : environ, mpred) (globvar2pred gz) gvs))) rho)) (SF rho)) (@sepcon mpred Nveric Sveric (@sepcon mpred Nveric Sveric (@sepcon mpred Nveric Sveric (@data_at_ cs (readonly2share (@gvar_readonly type gv)) t (gz i)) (@andp mpred Nveric (@prop mpred Nveric (gvars_denote gz rho)) (PQR rho))) (@lift2 mpred mpred mpred (@andp mpred Nveric) (fun rho : environ => @prop mpred Nveric (@eq globals gz (globals_of_env rho))) (@fold_right (forall _ : environ, mpred) (forall _ : environ, mpred) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric)) (@emp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric)) (@map (prod ident (globvar type)) (forall _ : environ, mpred) (globvar2pred gz) gvs)) rho)) (SF rho)) *)
unfold lift2.
change  (fun rho : environ => gz = globals_of_env rho)
  with (locald_denote (gvars gz)) in H8|-*.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (locald_denote (gvars gz))) PQR) (globvars2pred gz (@cons (prod ident (globvar type)) (@pair ident (globvar type) i gv) gvs))) SF)) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (LiftEnviron mpred) (@data_at_ cs (readonly2share (@gvar_readonly type gv)) t (gz i))) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (locald_denote (gvars gz))) PQR)) (globvars2pred gz gvs)) SF) *)
go_lowerx.
(* Goal: semax cs Espec Delta (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (PROPx P (LOCALx Q (SEPx R))) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) val (fun x : val => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (locald_denote (f x))) (@liftx (LiftEnviron mpred) (g (h x) : mpred)))) S2)) S3) S4) c Post *)
normalize.
(* Goal: @eq val match p with | Vundef => Vundef | Vint i => Vundef | Vlong i => Vundef | Vfloat f => Vundef | Vsingle f => Vundef | Vptr b z => Vptr b (Ptrofs.repr (Z.add (Ptrofs.unsigned z) (Ptrofs.unsigned (Ptrofs.repr i)))) end match p with | Vundef => Vundef | Vint i => Vundef | Vlong i => Vundef | Vfloat f => Vundef | Vsingle f => Vundef | Vptr b z => Vptr b (Ptrofs.repr (Z.add (Ptrofs.unsigned z) (Ptrofs.unsigned (Ptrofs.repr i)))) end *)
apply sepcon_derives; auto.
(* Goal: @derives mpred Nveric (@sepcon mpred Nveric Sveric (PQR rho) (@sepcon mpred Nveric Sveric (globvar2pred (globals_of_env rho) (@pair ident (globvar type) i gv) rho) (@fold_right (forall _ : environ, mpred) (forall _ : environ, mpred) (fun (P Q : forall _ : environ, mpred) (rho : environ) => @sepcon mpred Nveric Sveric (P rho) (Q rho)) (fun _ : environ => @emp mpred Nveric Sveric) (@map (prod ident (globvar type)) (forall _ : environ, mpred) (globvar2pred (globals_of_env rho)) gvs) rho))) (@sepcon mpred Nveric Sveric (@sepcon mpred Nveric Sveric (PQR rho) ((fix id2pred_star (cs : compspecs) (Delta : tycontext) (gz : globals) (sh : share) (v : val) (dl : list init_data) {struct dl} : forall _ : environ, mpred := match dl with | nil => fun _ : environ => @emp mpred Nveric Sveric | cons d dl' => fun rho : environ => @sepcon mpred Nveric Sveric (@liftx (LiftEnviron mpred) (@init_data2pred' cs Delta gz d sh v) rho) (id2pred_star cs Delta gz sh (offset_val (init_data_size d) v) dl' rho) end) cs Delta (globals_of_env rho) (readonly2share (@gvar_readonly type gv)) (globals_of_env rho i) (@gvar_init type gv) rho)) (@fold_right (forall _ : environ, mpred) (forall _ : environ, mpred) (fun (P Q : forall _ : environ, mpred) (rho : environ) => @sepcon mpred Nveric Sveric (P rho) (Q rho)) (fun _ : environ => @emp mpred Nveric Sveric) (@map (prod ident (globvar type)) (forall _ : environ, mpred) (globvar2pred (globals_of_env rho)) gvs) rho)) *)
pull_right (PQR rho).
(* Goal: @eq val match p with | Vundef => Vundef | Vint i => Vundef | Vlong i => Vundef | Vfloat f => Vundef | Vsingle f => Vundef | Vptr b z => Vptr b (Ptrofs.repr (Z.add (Ptrofs.unsigned z) (Ptrofs.unsigned (Ptrofs.repr i)))) end match p with | Vundef => Vundef | Vint i => Vundef | Vlong i => Vundef | Vfloat f => Vundef | Vsingle f => Vundef | Vptr b z => Vptr b (Ptrofs.repr (Z.add (Ptrofs.unsigned z) (Ptrofs.unsigned (Ptrofs.repr i)))) end *)
apply sepcon_derives; auto.
(* Goal: @eq val match p with | Vundef => Vundef | Vint i => Vundef | Vlong i => Vundef | Vfloat f => Vundef | Vsingle f => Vundef | Vptr b z => Vptr b (Ptrofs.repr (Z.add (Ptrofs.unsigned z) (Ptrofs.unsigned (Ptrofs.repr i)))) end match p with | Vundef => Vundef | Vint i => Vundef | Vlong i => Vundef | Vfloat f => Vundef | Vsingle f => Vundef | Vptr b z => Vptr b (Ptrofs.repr (Z.add (Ptrofs.unsigned z) (Ptrofs.unsigned (Ptrofs.repr i)))) end *)
apply sepcon_derives; auto.
(* Goal: @derives mpred Nveric (globvar2pred (globals_of_env rho) (@pair ident (globvar type) i gv) rho) (@data_at cs (readonly2share (@gvar_readonly type gv)) (tarray (Tint sz sign noattr) n) (@map Int.int val (@Basics.compose Int.int Int.int val Vint (Cop.cast_int_int sz sign)) data) (globals_of_env rho i)) *)
unfold local, lift1 in H8. specialize (H8 rho). simpl in H8. rewrite prop_true_andp in H8 by (split; auto).
(* Goal: @derives mpred Nveric (globvar2pred (globals_of_env rho) (@pair ident (globvar type) i gv) rho) (@data_at cs (readonly2share (@gvar_readonly type gv)) (tarray (Tint sz sign noattr) n) (@map Int.int val (@Basics.compose Int.int Int.int val Vint (Cop.cast_int_int sz sign)) data) (globals_of_env rho i)) *)
apply H8.
Qed.

Lemma process_globvar_star':
  forall {cs: compspecs} {Espec: OracleKind} Delta gz P Q R (i: ident)
          gv gvs SF c Post,
       (var_types Delta) ! i = None ->
       (glob_types Delta) ! i = Some (gvar_info gv) ->
  (complete_legal_cosu_type (gvar_info gv) && is_aligned cenv_cs ha_env_cs la_env_cs (gvar_info gv) 0)%bool = true ->
       gvar_volatile gv = false ->
       globvar_all_aligned gv = true ->
       init_data_list_size (gvar_init gv) <= sizeof (gvar_info gv) <=
       Ptrofs.max_unsigned ->
  semax Delta (PROPx P (LOCALx (gvars gz :: Q)
                      (SEPx R))
                  * (id2pred_star Delta gz (readonly2share (gvar_readonly gv))
                      (gz i) (gvar_init gv))
             * globvars2pred gz gvs * SF)
     c Post ->
 semax Delta (PROPx P (LOCALx (gvars gz :: Q) (SEPx R))
                      * globvars2pred gz ((i,gv)::gvs) * SF)
     c Post.
Proof.
(* Goal: forall (cs : compspecs) (Espec : OracleKind) (Delta : tycontext) (PQR : forall _ : environ, mpred) (gv : globals) (SF : forall _ : environ, mpred) (c : statement) (Post : ret_assert) (_ : semax cs Espec Delta (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) PQR SF) c Post), semax cs Espec Delta (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) PQR (globvars2pred gv (@nil (prod ident (globvar type))))) SF) c Post *)
intros.
(* Goal: semax cs Espec Delta (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (PROPx P (LOCALx (@cons localdef (gvars gz) Q) (SEPx R))) (globvars2pred gz (@cons (prod ident (globvar type)) (@pair ident (globvar type) i gv) gvs))) SF) c Post *)
eapply semax_pre; [ | apply H5]. clear H5.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (PROPx P (LOCALx (@cons localdef (gvars gz) Q) (SEPx R))) (globvars2pred gz (@cons (prod ident (globvar type)) (@pair ident (globvar type) i gv) gvs))) SF)) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (PROPx P (LOCALx (@cons localdef (gvars gz) Q) (SEPx R))) (@id2pred_star cs Delta gz (readonly2share (@gvar_readonly type gv)) (gz i) (@gvar_init type gv))) (globvars2pred gz gvs)) SF) *)
pose proof (unpack_globvar_star _ gz _ _ H H0 H1 H2 H3 H4).
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (PROPx P (LOCALx (@cons localdef (gvars gz) Q) (SEPx R))) (globvars2pred gz (@cons (prod ident (globvar type)) (@pair ident (globvar type) i gv) gvs))) SF)) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (PROPx P (LOCALx (@cons localdef (gvars gz) Q) (SEPx R))) (@id2pred_star cs Delta gz (readonly2share (@gvar_readonly type gv)) (gz i) (@gvar_init type gv))) (globvars2pred gz gvs)) SF) *)
clear H H0 H1 H2 H3 H4.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (PROPx P (LOCALx (@cons localdef (gvars gz) Q) (SEPx R))) (globvars2pred gz (@cons (prod ident (globvar type)) (@pair ident (globvar type) i gv) gvs))) SF)) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (PROPx P (LOCALx (@cons localdef (gvars gz) Q) (SEPx R))) (@id2pred_star cs Delta gz (readonly2share (@gvar_readonly type gv)) (gz i) (@gvar_init type gv))) (globvars2pred gz gvs)) SF) *)
rewrite <- !insert_local.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (locald_denote (gvars gz))) (PROPx P (LOCALx Q (SEPx R)))) (globvars2pred gz (@cons (prod ident (globvar type)) (@pair ident (globvar type) i gv) gvs))) SF)) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (LiftEnviron mpred) (@data_at_ cs (readonly2share (@gvar_readonly type gv)) t (gz i))) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (locald_denote (gvars gz))) (PROPx P (LOCALx Q (SEPx R))))) (globvars2pred gz gvs)) SF) *)
forget (PROPx P (LOCALx Q (SEPx R))) as PQR.
unfold globvars2pred.
change (lift_S (LiftEnviron Prop)) with environ in *.
(* Goal: @derives mpred Nveric (@sepcon mpred Nveric Sveric (@sepcon mpred Nveric Sveric (@andp mpred Nveric (@prop mpred Nveric (gvars_denote gz rho)) (PQR rho)) (@lift2 mpred mpred mpred (@andp mpred Nveric) (fun rho : environ => @prop mpred Nveric (@eq globals gz (globals_of_env rho))) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (globvar2pred gz (@pair ident (globvar type) i gv)) (@fold_right (forall _ : environ, mpred) (forall _ : environ, mpred) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric)) (@emp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric)) (@map (prod ident (globvar type)) (forall _ : environ, mpred) (globvar2pred gz) gvs))) rho)) (SF rho)) (@sepcon mpred Nveric Sveric (@sepcon mpred Nveric Sveric (@sepcon mpred Nveric Sveric (@data_at_ cs (readonly2share (@gvar_readonly type gv)) t (gz i)) (@andp mpred Nveric (@prop mpred Nveric (gvars_denote gz rho)) (PQR rho))) (@lift2 mpred mpred mpred (@andp mpred Nveric) (fun rho : environ => @prop mpred Nveric (@eq globals gz (globals_of_env rho))) (@fold_right (forall _ : environ, mpred) (forall _ : environ, mpred) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric)) (@emp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric)) (@map (prod ident (globvar type)) (forall _ : environ, mpred) (globvar2pred gz) gvs)) rho)) (SF rho)) *)
unfold lift2.
change  (fun rho : environ => gz = globals_of_env rho)
  with (locald_denote (gvars gz)) in H5|-*.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (locald_denote (gvars gz))) PQR) (globvars2pred gz (@cons (prod ident (globvar type)) (@pair ident (globvar type) i gv) gvs))) SF)) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (LiftEnviron mpred) (@data_at_ cs (readonly2share (@gvar_readonly type gv)) t (gz i))) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (locald_denote (gvars gz))) PQR)) (globvars2pred gz gvs)) SF) *)
go_lowerx.
(* Goal: semax cs Espec Delta (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (PROPx P (LOCALx Q (SEPx R))) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) val (fun x : val => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (locald_denote (f x))) (@liftx (LiftEnviron mpred) (g (h x) : mpred)))) S2)) S3) S4) c Post *)
normalize.
(* Goal: @eq val match p with | Vundef => Vundef | Vint i => Vundef | Vlong i => Vundef | Vfloat f => Vundef | Vsingle f => Vundef | Vptr b z => Vptr b (Ptrofs.repr (Z.add (Ptrofs.unsigned z) (Ptrofs.unsigned (Ptrofs.repr i)))) end match p with | Vundef => Vundef | Vint i => Vundef | Vlong i => Vundef | Vfloat f => Vundef | Vsingle f => Vundef | Vptr b z => Vptr b (Ptrofs.repr (Z.add (Ptrofs.unsigned z) (Ptrofs.unsigned (Ptrofs.repr i)))) end *)
apply sepcon_derives; auto.
(* Goal: @derives mpred Nveric (@sepcon mpred Nveric Sveric (PQR rho) (@sepcon mpred Nveric Sveric (globvar2pred (globals_of_env rho) (@pair ident (globvar type) i gv) rho) (@fold_right (forall _ : environ, mpred) (forall _ : environ, mpred) (fun (P Q : forall _ : environ, mpred) (rho : environ) => @sepcon mpred Nveric Sveric (P rho) (Q rho)) (fun _ : environ => @emp mpred Nveric Sveric) (@map (prod ident (globvar type)) (forall _ : environ, mpred) (globvar2pred (globals_of_env rho)) gvs) rho))) (@sepcon mpred Nveric Sveric (@sepcon mpred Nveric Sveric (PQR rho) ((fix id2pred_star (cs : compspecs) (Delta : tycontext) (gz : globals) (sh : share) (v : val) (dl : list init_data) {struct dl} : forall _ : environ, mpred := match dl with | nil => fun _ : environ => @emp mpred Nveric Sveric | cons d dl' => fun rho : environ => @sepcon mpred Nveric Sveric (@liftx (LiftEnviron mpred) (@init_data2pred' cs Delta gz d sh v) rho) (id2pred_star cs Delta gz sh (offset_val (init_data_size d) v) dl' rho) end) cs Delta (globals_of_env rho) (readonly2share (@gvar_readonly type gv)) (globals_of_env rho i) (@gvar_init type gv) rho)) (@fold_right (forall _ : environ, mpred) (forall _ : environ, mpred) (fun (P Q : forall _ : environ, mpred) (rho : environ) => @sepcon mpred Nveric Sveric (P rho) (Q rho)) (fun _ : environ => @emp mpred Nveric Sveric) (@map (prod ident (globvar type)) (forall _ : environ, mpred) (globvar2pred (globals_of_env rho)) gvs) rho)) *)
pull_right (PQR rho).
(* Goal: @eq val match p with | Vundef => Vundef | Vint i => Vundef | Vlong i => Vundef | Vfloat f => Vundef | Vsingle f => Vundef | Vptr b z => Vptr b (Ptrofs.repr (Z.add (Ptrofs.unsigned z) (Ptrofs.unsigned (Ptrofs.repr i)))) end match p with | Vundef => Vundef | Vint i => Vundef | Vlong i => Vundef | Vfloat f => Vundef | Vsingle f => Vundef | Vptr b z => Vptr b (Ptrofs.repr (Z.add (Ptrofs.unsigned z) (Ptrofs.unsigned (Ptrofs.repr i)))) end *)
apply sepcon_derives; auto.
(* Goal: @eq val match p with | Vundef => Vundef | Vint i => Vundef | Vlong i => Vundef | Vfloat f => Vundef | Vsingle f => Vundef | Vptr b z => Vptr b (Ptrofs.repr (Z.add (Ptrofs.unsigned z) (Ptrofs.unsigned (Ptrofs.repr i)))) end match p with | Vundef => Vundef | Vint i => Vundef | Vlong i => Vundef | Vfloat f => Vundef | Vsingle f => Vundef | Vptr b z => Vptr b (Ptrofs.repr (Z.add (Ptrofs.unsigned z) (Ptrofs.unsigned (Ptrofs.repr i)))) end *)
apply sepcon_derives; auto.
(* Goal: @derives mpred Nveric (globvar2pred (globals_of_env rho) (@pair ident (globvar type) i gv) rho) ((fix id2pred_star (cs : compspecs) (Delta : tycontext) (gz : globals) (sh : share) (v : val) (dl : list init_data) {struct dl} : forall _ : environ, mpred := match dl with | nil => fun _ : environ => @emp mpred Nveric Sveric | cons d dl' => fun rho : environ => @sepcon mpred Nveric Sveric (@liftx (LiftEnviron mpred) (@init_data2pred' cs Delta gz d sh v) rho) (id2pred_star cs Delta gz sh (offset_val (init_data_size d) v) dl' rho) end) cs Delta (globals_of_env rho) (readonly2share (@gvar_readonly type gv)) (globals_of_env rho i) (@gvar_init type gv) rho) *)
unfold local, lift1 in H5. specialize (H5 rho). simpl in H5.
(* Goal: @derives mpred Nveric (globvar2pred (globals_of_env rho) (@pair ident (globvar type) i gv) rho) ((fix id2pred_star (cs : compspecs) (Delta : tycontext) (gz : globals) (sh : share) (v : val) (dl : list init_data) {struct dl} : forall _ : environ, mpred := match dl with | nil => fun _ : environ => @emp mpred Nveric Sveric | cons d dl' => fun rho : environ => @sepcon mpred Nveric Sveric (@liftx (LiftEnviron mpred) (@init_data2pred' cs Delta gz d sh v) rho) (id2pred_star cs Delta gz sh (offset_val (init_data_size d) v) dl' rho) end) cs Delta (globals_of_env rho) (readonly2share (@gvar_readonly type gv)) (globals_of_env rho i) (@gvar_init type gv) rho) *)
rewrite prop_true_andp in H5 by (split; auto).
(* Goal: @derives mpred Nveric (globvar2pred (globals_of_env rho) (@pair ident (globvar type) i gv) rho) ((fix id2pred_star (cs : compspecs) (Delta : tycontext) (gz : globals) (sh : share) (v : val) (dl : list init_data) {struct dl} : forall _ : environ, mpred := match dl with | nil => fun _ : environ => @emp mpred Nveric Sveric | cons d dl' => fun rho : environ => @sepcon mpred Nveric Sveric (@liftx (LiftEnviron mpred) (@init_data2pred' cs Delta gz d sh v) rho) (id2pred_star cs Delta gz sh (offset_val (init_data_size d) v) dl' rho) end) cs Delta (globals_of_env rho) (readonly2share (@gvar_readonly type gv)) (globals_of_env rho i) (@gvar_init type gv) rho) *)
apply H5.
Qed.

Fixpoint init_datalist2pred' {cs: compspecs}
     (Delta: tycontext) (gv: globals) (dl: list init_data)  (sh: share) (ofs: Z) (v: val) : mpred :=
 match dl with
 | d::dl' => init_data2pred' Delta gv d sh (offset_val ofs v) 
                * init_datalist2pred' Delta gv dl' sh (ofs + init_data_size d) v
 | nil => emp
 end.

Lemma halfprocess_globvar_star:
  forall {cs: compspecs} {Espec: OracleKind} Delta gz P Q R (i: ident)
          gv gvs SF c Post,
       (var_types Delta) ! i = None ->
       (glob_types Delta) ! i = Some (gvar_info gv) ->
  (complete_legal_cosu_type (gvar_info gv) && is_aligned cenv_cs ha_env_cs la_env_cs (gvar_info gv) 0)%bool = true ->
       gvar_volatile gv = false ->
       init_data_list_size (gvar_init gv) <= sizeof (gvar_info gv) <=
       Ptrofs.max_unsigned ->
  semax Delta (PROPx P (LOCALx (gvars gz :: Q)
                      (SEPx (init_datalist2pred' Delta gz (gvar_init gv) (readonly2share (gvar_readonly gv)) 0 (gz i)
                                 ::R)))
             * globvars2pred gz gvs * SF)
     c Post ->
 semax Delta (PROPx P (LOCALx (gvars gz :: Q) (SEPx R))
                      * globvars2pred gz ((i,gv)::gvs) * SF)
     c Post.
Proof.
(* Goal: forall (cs : compspecs) (Espec : OracleKind) (Delta : tycontext) (PQR : forall _ : environ, mpred) (gv : globals) (SF : forall _ : environ, mpred) (c : statement) (Post : ret_assert) (_ : semax cs Espec Delta (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) PQR SF) c Post), semax cs Espec Delta (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) PQR (globvars2pred gv (@nil (prod ident (globvar type))))) SF) c Post *)
intros.
eapply semax_pre; [ | apply H4]. clear H4.
unfold globvars2pred; fold globvars2pred.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (locald_denote (gvars gz))) PQR) (globvars2pred gz (@cons (prod ident (globvar type)) (@pair ident (globvar type) i gv) gvs))) SF)) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (LiftEnviron mpred) (@data_at_ cs (readonly2share (@gvar_readonly type gv)) t (gz i))) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (locald_denote (gvars gz))) PQR)) (globvars2pred gz gvs)) SF) *)
go_lowerx.
(* Goal: Z.le (init_data_size (Init_space (@sizeof (@cenv_cs cs) t))) (@sizeof (@cenv_cs cs) t) *)
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (locald_denote (gvars gz))) PQR) (globvars2pred gz (@cons (prod ident (globvar type)) (@pair ident (globvar type) i gv) gvs))) SF)) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (LiftEnviron mpred) (@data_at_ cs (readonly2share (@gvar_readonly type gv)) t (gz i))) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (locald_denote (gvars gz))) PQR)) (globvars2pred gz gvs)) SF) *)
unfold lift2. simpl.
(* Goal: semax cs Espec Delta (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (PROPx P (LOCALx Q (SEPx R))) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) val (fun x : val => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (locald_denote (f x))) (@liftx (LiftEnviron mpred) (g (h x) : mpred)))) S2)) S3) S4) c Post *)
normalize.
rewrite prop_true_andp by (split; auto).
(* Goal: @derives mpred Nveric (mapsto sh (Tpointer Tvoid noattr) (Vptr b (Ptrofs.repr ofs)) (Vptr b1 i0)) (mapsto_ sh (Tpointer Tvoid noattr) (Vptr b (Ptrofs.repr ofs))) *)
cancel.
(* Goal: @derives mpred Nveric (globvar2pred (globals_of_env rho) (@pair positive (globvar type) i gv) rho) (init_data_list2pred idata (readonly2share (@gvar_readonly type gv)) (globals_of_env rho i) rho) *)
unfold globvar2pred.
(* Goal: Z.le (init_data_size (Init_space (@sizeof (@cenv_cs cs) t))) (@sizeof (@cenv_cs cs) t) *)
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (locald_denote (gvars gz))) PQR) (globvars2pred gz (@cons (prod ident (globvar type)) (@pair ident (globvar type) i gv) gvs))) SF)) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (LiftEnviron mpred) (@data_at_ cs (readonly2share (@gvar_readonly type gv)) t (gz i))) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (locald_denote (gvars gz))) PQR)) (globvars2pred gz gvs)) SF) *)
simpl.
rewrite H2.
pose proof (readable_readonly2share (gvar_readonly gv)).
forget (readonly2share (gvar_readonly gv)) as sh.
rewrite <- offset_zero_globals_of_env at 1.
set (ofs:=0).
clearbody ofs.
(* Goal: forall (cs : compspecs) (Espec : OracleKind) (Delta : tycontext) (PQR : forall _ : environ, mpred) (gv : globals) (SF : forall _ : environ, mpred) (c : statement) (Post : ret_assert) (_ : semax cs Espec Delta (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) PQR SF) c Post), semax cs Espec Delta (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) PQR (globvars2pred gv (@nil (prod ident (globvar type))))) SF) c Post *)
revert ofs; induction (gvar_init gv); intros.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (LiftEnviron mpred) (g (h x))) (PROPx P (LOCALx Q (SEPx R)))) S2) S3) S4) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (LiftEnviron mpred) (g (h x))) (PROPx P (LOCALx Q (SEPx R)))) S2) S3) S4) *)
apply derives_refl.
apply sepcon_derives.
destruct (globvar_eval_var _ _ _ _ H4 H H0) as [b [? ?]].
(* Goal: @eq val match p with | Vundef => Vundef | Vint i => Vundef | Vlong i => Vundef | Vfloat f => Vundef | Vsingle f => Vundef | Vptr b z => Vptr b (Ptrofs.repr (Z.add (Ptrofs.unsigned z) (Ptrofs.unsigned (Ptrofs.repr i)))) end match p with | Vundef => Vundef | Vint i => Vundef | Vlong i => Vundef | Vfloat f => Vundef | Vsingle f => Vundef | Vptr b z => Vptr b (Ptrofs.repr (Z.add (Ptrofs.unsigned z) (Ptrofs.unsigned (Ptrofs.repr i)))) end *)
eapply init_data2pred_rejigger; eauto.
(* Goal: @eq val (offset_val Z0 (globals_of_env rho i)) (globals_of_env rho i) *)
unfold globals_of_env.
(* Goal: @eq (list B) (@cons B (f x) (@map A B f z)) (@map A B f (@cons A x z)) *)
rewrite H10. reflexivity.
fold init_data_list2pred.
fold init_datalist2pred'.
spec IHl.
simpl in H3.
pose proof (init_data_size_pos a).
(* Goal: Z.lt (@sizeof (@cenv_cs cs) (@gvar_info type gv)) Ptrofs.modulus *)
omega.
eapply derives_trans; [ | apply IHl].
rewrite offset_offset_val.
(* Goal: @eq val match p with | Vundef => Vundef | Vint i => Vundef | Vlong i => Vundef | Vfloat f => Vundef | Vsingle f => Vundef | Vptr b z => Vptr b (Ptrofs.repr (Z.add (Ptrofs.unsigned z) (Ptrofs.unsigned (Ptrofs.repr i)))) end match p with | Vundef => Vundef | Vint i => Vundef | Vlong i => Vundef | Vfloat f => Vundef | Vsingle f => Vundef | Vptr b z => Vptr b (Ptrofs.repr (Z.add (Ptrofs.unsigned z) (Ptrofs.unsigned (Ptrofs.repr i)))) end *)
auto.
Qed.

Lemma map_instantiate:
  forall {A B} (f: A -> B) (x: A) (y: list B) z,
    y = map f z ->  f x :: y = map f (x :: z).
Proof. intros. subst. reflexivity. Qed.

Lemma main_pre_start:
 forall prog u gv,
   main_pre prog u gv = (PROP() LOCAL(gvars gv) SEP())%assert * globvars2pred gv (prog_vars prog).
Proof.
(* Goal: forall (cs : compspecs) (Espec : OracleKind) (Delta : tycontext) (PQR : forall _ : environ, mpred) (gv : globals) (SF : forall _ : environ, mpred) (c : statement) (Post : ret_assert) (_ : semax cs Espec Delta (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) PQR SF) c Post), semax cs Espec Delta (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) PQR (globvars2pred gv (@nil (prod ident (globvar type))))) SF) c Post *)
intros.
(* Goal: @eq (forall _ : environ, mpred) (main_pre prog u gv) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (PROPx (@nil Prop) (LOCALx (@cons localdef (gvars gv) (@nil localdef)) (SEPx (@nil mpred)))) (globvars2pred gv (prog_vars prog))) *)
unfold main_pre.
unfold globvars2pred,  PROPx, LOCALx, SEPx.
(* Goal: @derives mpred Nveric (@sepcon mpred Nveric Sveric (@sepcon mpred Nveric Sveric (@andp mpred Nveric (@prop mpred Nveric (gvars_denote gz rho)) (PQR rho)) (@lift2 mpred mpred mpred (@andp mpred Nveric) (fun rho : environ => @prop mpred Nveric (@eq globals gz (globals_of_env rho))) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (globvar2pred gz (@pair ident (globvar type) i gv)) (@fold_right (forall _ : environ, mpred) (forall _ : environ, mpred) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric)) (@emp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric)) (@map (prod ident (globvar type)) (forall _ : environ, mpred) (globvar2pred gz) gvs))) rho)) (SF rho)) (@sepcon mpred Nveric Sveric (@sepcon mpred Nveric Sveric (@sepcon mpred Nveric Sveric (@data_at_ cs (readonly2share (@gvar_readonly type gv)) t (gz i)) (@andp mpred Nveric (@prop mpred Nveric (gvars_denote gz rho)) (PQR rho))) (@lift2 mpred mpred mpred (@andp mpred Nveric) (fun rho : environ => @prop mpred Nveric (@eq globals gz (globals_of_env rho))) (@fold_right (forall _ : environ, mpred) (forall _ : environ, mpred) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric)) (@emp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric)) (@map (prod ident (globvar type)) (forall _ : environ, mpred) (globvar2pred gz) gvs)) rho)) (SF rho)) *)
unfold lift2.
(* Goal: @eq (forall _ : environ, mpred) (fun rho : environ => @sepcon mpred Nveric Sveric (@andp mpred Nveric (@prop mpred Nveric (@eq globals gv (globals_of_env rho))) (@fold_right (forall _ : environ, mpred) (forall _ : environ, mpred) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric)) (@emp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric)) (@map (prod ident (globvar type)) (forall _ : environ, mpred) (globvar2pred gv) (prog_vars prog)) rho)) (@has_ext (@OK_ty Espec) ora)) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@fold_right Prop Prop and True (@nil Prop))) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (@fold_right (forall _ : lift_S (LiftEnviron Prop), Prop) (forall _ : lift_S (Tarrow Prop (LiftEnviron Prop)), Prop) (@liftx (Tarrow Prop (Tarrow Prop (LiftEnviron Prop))) and) (@liftx (LiftEnviron Prop) True) (@map localdef (forall _ : environ, Prop) locald_denote (@cons localdef (gvars gv) (@nil localdef))))) (fun _ : environ => fold_right_sepcon (@cons (@predicates_hered.pred compcert_rmaps.RML.R.rmap compcert_rmaps.RML.R.ag_rmap) (@has_ext (@OK_ty Espec) ora) (@nil (@predicates_hered.pred compcert_rmaps.RML.R.rmap compcert_rmaps.RML.R.ag_rmap)))))) (fun rho : environ => @andp mpred Nveric (@prop mpred Nveric (@eq globals gv (globals_of_env rho))) (@fold_right (forall _ : environ, mpred) (forall _ : environ, mpred) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric)) (@emp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric)) (@map (prod ident (globvar type)) (forall _ : environ, mpred) (globvar2pred gv) (prog_vars prog)) rho))) *)
extensionality rho.
(* Goal: Z.le (init_data_size (Init_space (@sizeof (@cenv_cs cs) t))) (@sizeof (@cenv_cs cs) t) *)
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (locald_denote (gvars gz))) PQR) (globvars2pred gz (@cons (prod ident (globvar type)) (@pair ident (globvar type) i gv) gvs))) SF)) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (LiftEnviron mpred) (@data_at_ cs (readonly2share (@gvar_readonly type gv)) t (gz i))) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (locald_denote (gvars gz))) PQR)) (globvars2pred gz gvs)) SF) *)
simpl.
(* Goal: semax cs Espec Delta (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (PROPx P (LOCALx Q (SEPx R))) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) val (fun x : val => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (locald_denote (f x))) (@liftx (LiftEnviron mpred) (g (h x) : mpred)))) S2)) S3) S4) c Post *)
normalize.
(* Goal: @eq mpred (@andp mpred Nveric (@prop mpred Nveric (@eq globals gv (globals_of_env rho))) (@sepcon mpred Nveric Sveric (@fold_right (forall _ : environ, mpred) (forall _ : environ, mpred) (fun (P Q : forall _ : environ, mpred) (rho : environ) => @sepcon mpred Nveric Sveric (P rho) (Q rho)) (fun _ : environ => @emp mpred Nveric Sveric) (@map (prod ident (globvar type)) (forall _ : environ, mpred) (globvar2pred gv) (prog_vars prog)) rho) (@has_ext (@OK_ty Espec) ora))) (@andp mpred Nveric (@prop mpred Nveric (and True (@eq globals gv (globals_of_env rho)))) (@sepcon mpred Nveric Sveric (@andp mpred Nveric (local (@liftx (Tarrow Prop (Tarrow Prop (LiftEnviron Prop))) and (gvars_denote gv) (@liftx (LiftEnviron Prop) True)) rho) (@has_ext (@OK_ty Espec) ora)) (@fold_right (forall _ : environ, mpred) (forall _ : environ, mpred) (fun (P Q : forall _ : environ, mpred) (rho : environ) => @sepcon mpred Nveric Sveric (P rho) (Q rho)) (fun _ : environ => @emp mpred Nveric Sveric) (@map (prod ident (globvar type)) (forall _ : environ, mpred) (globvar2pred gv) (prog_vars prog)) rho))) *)
unfold gvars_denote. unfold_lift. unfold local, lift1.
(* Goal: @eq mpred (@andp mpred Nveric (@prop mpred Nveric (@eq globals gv (globals_of_env rho))) (@sepcon mpred Nveric Sveric (@fold_right (forall _ : environ, mpred) (forall _ : environ, mpred) (fun (P Q : forall _ : environ, mpred) (rho : environ) => @sepcon mpred Nveric Sveric (P rho) (Q rho)) (fun _ : environ => @emp mpred Nveric Sveric) (@map (prod ident (globvar type)) (forall _ : environ, mpred) (globvar2pred gv) (prog_vars prog)) rho) (@has_ext (@OK_ty Espec) ora))) (@andp mpred Nveric (@prop mpred Nveric (and True (@eq globals gv (globals_of_env rho)))) (@sepcon mpred Nveric Sveric (@andp mpred Nveric (@prop mpred Nveric (and (@eq globals gv (fun i : ident => match @Map.get block (ge_of rho) i with | Some b => Vptr b Ptrofs.zero | None => Vundef end)) True)) (@has_ext (@OK_ty Espec) ora)) (@fold_right (forall _ : environ, mpred) (forall _ : environ, mpred) (fun (P Q : forall _ : environ, mpred) (rho : environ) => @sepcon mpred Nveric Sveric (P rho) (Q rho)) (fun _ : environ => @emp mpred Nveric Sveric) (@map (prod ident (globvar type)) (forall _ : environ, mpred) (globvar2pred gv) (prog_vars prog)) rho))) *)
fold (globals_of_env rho).
(* Goal: semax cs Espec Delta (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (PROPx P (LOCALx Q (SEPx R))) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) val (fun x : val => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (locald_denote (f x))) (@liftx (LiftEnviron mpred) (g (h x) : mpred)))) S2)) S3) S4) c Post *)
apply pred_ext; intros; normalize.
(* Goal: @eq val match p with | Vundef => Vundef | Vint i => Vundef | Vlong i => Vundef | Vfloat f => Vundef | Vsingle f => Vundef | Vptr b z => Vptr b (Ptrofs.repr (Z.add (Ptrofs.unsigned z) (Ptrofs.unsigned (Ptrofs.repr i)))) end match p with | Vundef => Vundef | Vint i => Vundef | Vlong i => Vundef | Vfloat f => Vundef | Vsingle f => Vundef | Vptr b z => Vptr b (Ptrofs.repr (Z.add (Ptrofs.unsigned z) (Ptrofs.unsigned (Ptrofs.repr i)))) end *)
rewrite prop_true_andp by auto.
(* Goal: @eq val match p with | Vundef => Vundef | Vint i => Vundef | Vlong i => Vundef | Vfloat f => Vundef | Vsingle f => Vundef | Vptr b z => Vptr b (Ptrofs.repr (Z.add (Ptrofs.unsigned z) (Ptrofs.unsigned (Ptrofs.repr i)))) end match p with | Vundef => Vundef | Vint i => Vundef | Vlong i => Vundef | Vfloat f => Vundef | Vsingle f => Vundef | Vptr b z => Vptr b (Ptrofs.repr (Z.add (Ptrofs.unsigned z) (Ptrofs.unsigned (Ptrofs.repr i)))) end *)
auto.
Qed.

Lemma main_pre_ext_start:
 forall {Espec : OracleKind} prog u gv ora,
   main_pre_ext prog ora u gv = (PROP() LOCAL(gvars gv) SEP(has_ext ora))%assert * globvars2pred gv (prog_vars prog).
Proof.
(* Goal: forall (cs : compspecs) (Espec : OracleKind) (Delta : tycontext) (PQR : forall _ : environ, mpred) (gv : globals) (SF : forall _ : environ, mpred) (c : statement) (Post : ret_assert) (_ : semax cs Espec Delta (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) PQR SF) c Post), semax cs Espec Delta (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) PQR (globvars2pred gv (@nil (prod ident (globvar type))))) SF) c Post *)
intros.
(* Goal: @eq (forall _ : environ, mpred) (@main_pre_ext Espec prog ora u gv) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (PROPx (@nil Prop) (LOCALx (@cons localdef (gvars gv) (@nil localdef)) (SEPx (@cons (@predicates_hered.pred compcert_rmaps.RML.R.rmap compcert_rmaps.RML.R.ag_rmap) (@has_ext (@OK_ty Espec) ora) (@nil (@predicates_hered.pred compcert_rmaps.RML.R.rmap compcert_rmaps.RML.R.ag_rmap)))))) (globvars2pred gv (prog_vars prog))) *)
unfold main_pre_ext.
unfold globvars2pred,  PROPx, LOCALx, SEPx.
(* Goal: @derives mpred Nveric (@sepcon mpred Nveric Sveric (@sepcon mpred Nveric Sveric (@andp mpred Nveric (@prop mpred Nveric (gvars_denote gz rho)) (PQR rho)) (@lift2 mpred mpred mpred (@andp mpred Nveric) (fun rho : environ => @prop mpred Nveric (@eq globals gz (globals_of_env rho))) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (globvar2pred gz (@pair ident (globvar type) i gv)) (@fold_right (forall _ : environ, mpred) (forall _ : environ, mpred) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric)) (@emp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric)) (@map (prod ident (globvar type)) (forall _ : environ, mpred) (globvar2pred gz) gvs))) rho)) (SF rho)) (@sepcon mpred Nveric Sveric (@sepcon mpred Nveric Sveric (@sepcon mpred Nveric Sveric (@data_at_ cs (readonly2share (@gvar_readonly type gv)) t (gz i)) (@andp mpred Nveric (@prop mpred Nveric (gvars_denote gz rho)) (PQR rho))) (@lift2 mpred mpred mpred (@andp mpred Nveric) (fun rho : environ => @prop mpred Nveric (@eq globals gz (globals_of_env rho))) (@fold_right (forall _ : environ, mpred) (forall _ : environ, mpred) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric)) (@emp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric)) (@map (prod ident (globvar type)) (forall _ : environ, mpred) (globvar2pred gz) gvs)) rho)) (SF rho)) *)
unfold lift2.
(* Goal: @eq (forall _ : environ, mpred) (fun rho : environ => @sepcon mpred Nveric Sveric (@andp mpred Nveric (@prop mpred Nveric (@eq globals gv (globals_of_env rho))) (@fold_right (forall _ : environ, mpred) (forall _ : environ, mpred) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric)) (@emp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric)) (@map (prod ident (globvar type)) (forall _ : environ, mpred) (globvar2pred gv) (prog_vars prog)) rho)) (@has_ext (@OK_ty Espec) ora)) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@prop (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@fold_right Prop Prop and True (@nil Prop))) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (@fold_right (forall _ : lift_S (LiftEnviron Prop), Prop) (forall _ : lift_S (Tarrow Prop (LiftEnviron Prop)), Prop) (@liftx (Tarrow Prop (Tarrow Prop (LiftEnviron Prop))) and) (@liftx (LiftEnviron Prop) True) (@map localdef (forall _ : environ, Prop) locald_denote (@cons localdef (gvars gv) (@nil localdef))))) (fun _ : environ => fold_right_sepcon (@cons (@predicates_hered.pred compcert_rmaps.RML.R.rmap compcert_rmaps.RML.R.ag_rmap) (@has_ext (@OK_ty Espec) ora) (@nil (@predicates_hered.pred compcert_rmaps.RML.R.rmap compcert_rmaps.RML.R.ag_rmap)))))) (fun rho : environ => @andp mpred Nveric (@prop mpred Nveric (@eq globals gv (globals_of_env rho))) (@fold_right (forall _ : environ, mpred) (forall _ : environ, mpred) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric)) (@emp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric)) (@map (prod ident (globvar type)) (forall _ : environ, mpred) (globvar2pred gv) (prog_vars prog)) rho))) *)
extensionality rho.
(* Goal: Z.le (init_data_size (Init_space (@sizeof (@cenv_cs cs) t))) (@sizeof (@cenv_cs cs) t) *)
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (locald_denote (gvars gz))) PQR) (globvars2pred gz (@cons (prod ident (globvar type)) (@pair ident (globvar type) i gv) gvs))) SF)) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (LiftEnviron mpred) (@data_at_ cs (readonly2share (@gvar_readonly type gv)) t (gz i))) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (locald_denote (gvars gz))) PQR)) (globvars2pred gz gvs)) SF) *)
simpl.
(* Goal: semax cs Espec Delta (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (PROPx P (LOCALx Q (SEPx R))) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) val (fun x : val => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (locald_denote (f x))) (@liftx (LiftEnviron mpred) (g (h x) : mpred)))) S2)) S3) S4) c Post *)
normalize.
(* Goal: @eq mpred (@andp mpred Nveric (@prop mpred Nveric (@eq globals gv (globals_of_env rho))) (@sepcon mpred Nveric Sveric (@fold_right (forall _ : environ, mpred) (forall _ : environ, mpred) (fun (P Q : forall _ : environ, mpred) (rho : environ) => @sepcon mpred Nveric Sveric (P rho) (Q rho)) (fun _ : environ => @emp mpred Nveric Sveric) (@map (prod ident (globvar type)) (forall _ : environ, mpred) (globvar2pred gv) (prog_vars prog)) rho) (@has_ext (@OK_ty Espec) ora))) (@andp mpred Nveric (@prop mpred Nveric (and True (@eq globals gv (globals_of_env rho)))) (@sepcon mpred Nveric Sveric (@andp mpred Nveric (local (@liftx (Tarrow Prop (Tarrow Prop (LiftEnviron Prop))) and (gvars_denote gv) (@liftx (LiftEnviron Prop) True)) rho) (@has_ext (@OK_ty Espec) ora)) (@fold_right (forall _ : environ, mpred) (forall _ : environ, mpred) (fun (P Q : forall _ : environ, mpred) (rho : environ) => @sepcon mpred Nveric Sveric (P rho) (Q rho)) (fun _ : environ => @emp mpred Nveric Sveric) (@map (prod ident (globvar type)) (forall _ : environ, mpred) (globvar2pred gv) (prog_vars prog)) rho))) *)
unfold gvars_denote. unfold_lift. unfold local, lift1.
(* Goal: @eq mpred (@andp mpred Nveric (@prop mpred Nveric (@eq globals gv (globals_of_env rho))) (@sepcon mpred Nveric Sveric (@fold_right (forall _ : environ, mpred) (forall _ : environ, mpred) (fun (P Q : forall _ : environ, mpred) (rho : environ) => @sepcon mpred Nveric Sveric (P rho) (Q rho)) (fun _ : environ => @emp mpred Nveric Sveric) (@map (prod ident (globvar type)) (forall _ : environ, mpred) (globvar2pred gv) (prog_vars prog)) rho) (@has_ext (@OK_ty Espec) ora))) (@andp mpred Nveric (@prop mpred Nveric (and True (@eq globals gv (globals_of_env rho)))) (@sepcon mpred Nveric Sveric (@andp mpred Nveric (@prop mpred Nveric (and (@eq globals gv (fun i : ident => match @Map.get block (ge_of rho) i with | Some b => Vptr b Ptrofs.zero | None => Vundef end)) True)) (@has_ext (@OK_ty Espec) ora)) (@fold_right (forall _ : environ, mpred) (forall _ : environ, mpred) (fun (P Q : forall _ : environ, mpred) (rho : environ) => @sepcon mpred Nveric Sveric (P rho) (Q rho)) (fun _ : environ => @emp mpred Nveric Sveric) (@map (prod ident (globvar type)) (forall _ : environ, mpred) (globvar2pred gv) (prog_vars prog)) rho))) *)
fold (globals_of_env rho).
(* Goal: @eq mpred (@andp mpred Nveric (@prop mpred Nveric (@eq globals gv (globals_of_env rho))) (@sepcon mpred Nveric Sveric (@fold_right (forall _ : environ, mpred) (forall _ : environ, mpred) (fun (P Q : forall _ : environ, mpred) (rho : environ) => @sepcon mpred Nveric Sveric (P rho) (Q rho)) (fun _ : environ => @emp mpred Nveric Sveric) (@map (prod ident (globvar type)) (forall _ : environ, mpred) (globvar2pred gv) (prog_vars prog)) rho) (@has_ext (@OK_ty Espec) ora))) (@andp mpred Nveric (@prop mpred Nveric (and True (@eq globals gv (globals_of_env rho)))) (@sepcon mpred Nveric Sveric (@andp mpred Nveric (@prop mpred Nveric (and (@eq globals gv (globals_of_env rho)) True)) (@has_ext (@OK_ty Espec) ora)) (@fold_right (forall _ : environ, mpred) (forall _ : environ, mpred) (fun (P Q : forall _ : environ, mpred) (rho : environ) => @sepcon mpred Nveric Sveric (P rho) (Q rho)) (fun _ : environ => @emp mpred Nveric Sveric) (@map (prod ident (globvar type)) (forall _ : environ, mpred) (globvar2pred gv) (prog_vars prog)) rho))) *)
rewrite sepcon_comm.
(* Goal: semax cs Espec Delta (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (PROPx P (LOCALx Q (SEPx R))) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) val (fun x : val => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (locald_denote (f x))) (@liftx (LiftEnviron mpred) (g (h x) : mpred)))) S2)) S3) S4) c Post *)
apply pred_ext; intros; normalize.
(* Goal: @eq val match p with | Vundef => Vundef | Vint i => Vundef | Vlong i => Vundef | Vfloat f => Vundef | Vsingle f => Vundef | Vptr b z => Vptr b (Ptrofs.repr (Z.add (Ptrofs.unsigned z) (Ptrofs.unsigned (Ptrofs.repr i)))) end match p with | Vundef => Vundef | Vint i => Vundef | Vlong i => Vundef | Vfloat f => Vundef | Vsingle f => Vundef | Vptr b z => Vptr b (Ptrofs.repr (Z.add (Ptrofs.unsigned z) (Ptrofs.unsigned (Ptrofs.repr i)))) end *)
rewrite prop_true_andp by auto.
(* Goal: @eq val match p with | Vundef => Vundef | Vint i => Vundef | Vlong i => Vundef | Vfloat f => Vundef | Vsingle f => Vundef | Vptr b z => Vptr b (Ptrofs.repr (Z.add (Ptrofs.unsigned z) (Ptrofs.unsigned (Ptrofs.repr i)))) end match p with | Vundef => Vundef | Vint i => Vundef | Vlong i => Vundef | Vfloat f => Vundef | Vsingle f => Vundef | Vptr b z => Vptr b (Ptrofs.repr (Z.add (Ptrofs.unsigned z) (Ptrofs.unsigned (Ptrofs.repr i)))) end *)
auto.
Qed.

Lemma process_globvar_space:
  forall {cs: compspecs} {Espec: OracleKind} Delta P Q R (i: ident)
          gz gv gvs SF c Post t,
       gvar_info gv = t ->
       (var_types Delta) ! i = None ->
       (glob_types Delta) ! i = Some t ->
  (complete_legal_cosu_type (gvar_info gv) && is_aligned cenv_cs ha_env_cs la_env_cs (gvar_info gv) 0)%bool = true ->
       gvar_volatile gv = false ->
       gvar_init gv = (Init_space (sizeof t)::nil) ->
       sizeof t <= Ptrofs.max_unsigned ->
  semax Delta (PROPx P (LOCALx (gvars gz::Q) (SEPx (data_at_  (readonly2share (gvar_readonly gv)) t (gz i) :: R)))
                       * globvars2pred gz gvs * SF)
     c Post ->
 semax Delta (PROPx P (LOCALx (gvars gz::Q) (SEPx R))
                      * globvars2pred gz ((i,gv)::gvs) * SF)
     c Post.
Proof.
(* Goal: forall (cs : compspecs) (Espec : OracleKind) (Delta : tycontext) (PQR : forall _ : environ, mpred) (gv : globals) (SF : forall _ : environ, mpred) (c : statement) (Post : ret_assert) (_ : semax cs Espec Delta (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) PQR SF) c Post), semax cs Espec Delta (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) PQR (globvars2pred gv (@nil (prod ident (globvar type))))) SF) c Post *)
intros until t. intros H3; intros.
(* Goal: semax cs Espec Delta (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (PROPx P (LOCALx (@cons localdef (gvars gz) Q) (SEPx R))) (globvars2pred gz (@cons (prod ident (globvar type)) (@pair ident (globvar type) i gv) gvs))) SF) c Post *)
eapply semax_pre; [ | apply H6]; clear H6.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (PROPx P (LOCALx Q (SEPx R))) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (locald_denote (f x))) (@liftx (LiftEnviron mpred) (g (h x)))) S2)) S3) S4) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (PROPx P (LOCALx (@cons localdef (f x) Q) (SEPx (@cons mpred (g (h x)) R)))) S2) S3) S4) *)
rewrite <- insert_SEP.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (PROPx P (LOCALx Q (SEPx R))) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (locald_denote (f x))) (@liftx (LiftEnviron mpred) (g (h x)))) S2)) S3) S4) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (LiftEnviron mpred) (g (h x))) (PROPx P (LOCALx (@cons localdef (f x) Q) (SEPx R)))) S2) S3) S4) *)
rewrite <- insert_local.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (locald_denote (gvars gz))) (PROPx P (LOCALx Q (SEPx R)))) (globvars2pred gz (@cons (prod ident (globvar type)) (@pair ident (globvar type) i gv) gvs))) SF)) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (LiftEnviron mpred) (@data_at_ cs (readonly2share (@gvar_readonly type gv)) t (gz i))) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (locald_denote (gvars gz))) (PROPx P (LOCALx Q (SEPx R))))) (globvars2pred gz gvs)) SF) *)
forget (PROPx P (LOCALx Q (SEPx R))) as PQR.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (locald_denote (gvars gz))) PQR) (globvars2pred gz (@cons (prod ident (globvar type)) (@pair ident (globvar type) i gv) gvs))) SF)) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (LiftEnviron mpred) (@data_at_ cs (readonly2share (@gvar_readonly type gv)) t (gz i))) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (locald_denote (gvars gz))) PQR)) (globvars2pred gz gvs)) SF) *)
assert (H7 := unpack_globvar Delta gz i t gv _ H H0 H1 H2 H3 H4).
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (locald_denote (gvars gz))) PQR) (globvars2pred gz (@cons (prod ident (globvar type)) (@pair ident (globvar type) i gv) gvs))) SF)) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (LiftEnviron mpred) (@data_at_ cs (readonly2share (@gvar_readonly type gv)) t (gz i))) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (locald_denote (gvars gz))) PQR)) (globvars2pred gz gvs)) SF) *)
spec H7.
(* Goal: Z.le (init_data_size (Init_space (@sizeof (@cenv_cs cs) t))) (@sizeof (@cenv_cs cs) t) *)
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (locald_denote (gvars gz))) PQR) (globvars2pred gz (@cons (prod ident (globvar type)) (@pair ident (globvar type) i gv) gvs))) SF)) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (LiftEnviron mpred) (@data_at_ cs (readonly2share (@gvar_readonly type gv)) t (gz i))) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (locald_denote (gvars gz))) PQR)) (globvars2pred gz gvs)) SF) *)
simpl. pose proof (sizeof_pos t). rewrite Z.max_l by omega. omega.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (locald_denote (gvars gz))) PQR) (globvars2pred gz (@cons (prod ident (globvar type)) (@pair ident (globvar type) i gv) gvs))) SF)) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (LiftEnviron mpred) (@data_at_ cs (readonly2share (@gvar_readonly type gv)) t (gz i))) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (locald_denote (gvars gz))) PQR)) (globvars2pred gz gvs)) SF) *)
specialize (H7 H5).
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (locald_denote (gvars gz))) PQR) (globvars2pred gz (@cons (prod ident (globvar type)) (@pair ident (globvar type) i gv) gvs))) SF)) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (LiftEnviron mpred) (@data_at_ cs (readonly2share (@gvar_readonly type gv)) t (gz i))) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (locald_denote (gvars gz))) PQR)) (globvars2pred gz gvs)) SF) *)
go_lowerx.
unfold globvars2pred; fold globvars2pred.
(* Goal: @derives mpred Nveric (@sepcon mpred Nveric Sveric (@sepcon mpred Nveric Sveric (@andp mpred Nveric (@prop mpred Nveric (gvars_denote gz rho)) (PQR rho)) (@lift2 mpred mpred mpred (@andp mpred Nveric) (fun rho : environ => @prop mpred Nveric (@eq globals gz (globals_of_env rho))) (@fold_right (forall _ : environ, mpred) (forall _ : environ, mpred) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric)) (@emp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric)) (@map (prod ident (globvar type)) (forall _ : environ, mpred) (globvar2pred gz) (@cons (prod ident (globvar type)) (@pair ident (globvar type) i gv) gvs))) rho)) (SF rho)) (@sepcon mpred Nveric Sveric (@sepcon mpred Nveric Sveric (@sepcon mpred Nveric Sveric (@data_at_ cs (readonly2share (@gvar_readonly type gv)) t (gz i)) (@andp mpred Nveric (@prop mpred Nveric (gvars_denote gz rho)) (PQR rho))) (@lift2 mpred mpred mpred (@andp mpred Nveric) (fun rho : environ => @prop mpred Nveric (@eq globals gz (globals_of_env rho))) (@fold_right (forall _ : environ, mpred) (forall _ : environ, mpred) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric)) (@emp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric)) (@map (prod ident (globvar type)) (forall _ : environ, mpred) (globvar2pred gz) gvs)) rho)) (SF rho)) *)
simpl map.
unfold fold_right; fold (fold_right sepcon emp  (map (globvar2pred gz) gvs)).
(* Goal: @derives mpred Nveric (@sepcon mpred Nveric Sveric (@sepcon mpred Nveric Sveric (@andp mpred Nveric (@prop mpred Nveric (gvars_denote gz rho)) (PQR rho)) (@lift2 mpred mpred mpred (@andp mpred Nveric) (fun rho : environ => @prop mpred Nveric (@eq globals gz (globals_of_env rho))) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (globvar2pred gz (@pair ident (globvar type) i gv)) (@fold_right (forall _ : environ, mpred) (forall _ : environ, mpred) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric)) (@emp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric)) (@map (prod ident (globvar type)) (forall _ : environ, mpred) (globvar2pred gz) gvs))) rho)) (SF rho)) (@sepcon mpred Nveric Sveric (@sepcon mpred Nveric Sveric (@sepcon mpred Nveric Sveric (@data_at_ cs (readonly2share (@gvar_readonly type gv)) t (gz i)) (@andp mpred Nveric (@prop mpred Nveric (gvars_denote gz rho)) (PQR rho))) (@lift2 mpred mpred mpred (@andp mpred Nveric) (fun rho : environ => @prop mpred Nveric (@eq globals gz (globals_of_env rho))) (@fold_right (forall _ : environ, mpred) (forall _ : environ, mpred) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric)) (@emp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric)) (@map (prod ident (globvar type)) (forall _ : environ, mpred) (globvar2pred gz) gvs)) rho)) (SF rho)) *)
unfold lift2.
(* Goal: semax cs Espec Delta (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (PROPx P (LOCALx Q (SEPx R))) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) val (fun x : val => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (locald_denote (f x))) (@liftx (LiftEnviron mpred) (g (h x) : mpred)))) S2)) S3) S4) c Post *)
normalize.
(* Goal: @eq val match p with | Vundef => Vundef | Vint i => Vundef | Vlong i => Vundef | Vfloat f => Vundef | Vsingle f => Vundef | Vptr b z => Vptr b (Ptrofs.repr (Z.add (Ptrofs.unsigned z) (Ptrofs.unsigned (Ptrofs.repr i)))) end match p with | Vundef => Vundef | Vint i => Vundef | Vlong i => Vundef | Vfloat f => Vundef | Vsingle f => Vundef | Vptr b z => Vptr b (Ptrofs.repr (Z.add (Ptrofs.unsigned z) (Ptrofs.unsigned (Ptrofs.repr i)))) end *)
apply sepcon_derives; auto.
(* Goal: @derives mpred Nveric (@sepcon mpred Nveric Sveric (PQR rho) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (globvar2pred (globals_of_env rho) (@pair ident (globvar type) i gv)) (@fold_right (forall _ : environ, mpred) (forall _ : environ, mpred) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric)) (@emp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric)) (@map (prod ident (globvar type)) (forall _ : environ, mpred) (globvar2pred (globals_of_env rho)) gvs)) rho)) (@sepcon mpred Nveric Sveric (@sepcon mpred Nveric Sveric (@data_at_ cs (readonly2share (@gvar_readonly type gv)) t (globals_of_env rho i)) (PQR rho)) (@fold_right (forall _ : environ, mpred) (forall _ : environ, mpred) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric)) (@emp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric)) (@map (prod ident (globvar type)) (forall _ : environ, mpred) (globvar2pred (globals_of_env rho)) gvs) rho)) *)
pull_left (PQR rho).
(* Goal: @derives mpred Nveric (@sepcon mpred Nveric Sveric (PQR rho) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (globvar2pred (globals_of_env rho) (@pair ident (globvar type) i gv)) (@fold_right (forall _ : environ, mpred) (forall _ : environ, mpred) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric)) (@emp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric)) (@map (prod ident (globvar type)) (forall _ : environ, mpred) (globvar2pred (globals_of_env rho)) gvs)) rho)) (@sepcon mpred Nveric Sveric (@sepcon mpred Nveric Sveric (PQR rho) (@data_at_ cs (readonly2share (@gvar_readonly type gv)) t (globals_of_env rho i))) (@fold_right (forall _ : environ, mpred) (forall _ : environ, mpred) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric)) (@emp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric)) (@map (prod ident (globvar type)) (forall _ : environ, mpred) (globvar2pred (globals_of_env rho)) gvs) rho)) *)
rewrite sepcon_assoc. 
(* Goal: @eq val match p with | Vundef => Vundef | Vint i => Vundef | Vlong i => Vundef | Vfloat f => Vundef | Vsingle f => Vundef | Vptr b z => Vptr b (Ptrofs.repr (Z.add (Ptrofs.unsigned z) (Ptrofs.unsigned (Ptrofs.repr i)))) end match p with | Vundef => Vundef | Vint i => Vundef | Vlong i => Vundef | Vfloat f => Vundef | Vsingle f => Vundef | Vptr b z => Vptr b (Ptrofs.repr (Z.add (Ptrofs.unsigned z) (Ptrofs.unsigned (Ptrofs.repr i)))) end *)
apply sepcon_derives; auto.
(* Goal: @eq val match p with | Vundef => Vundef | Vint i => Vundef | Vlong i => Vundef | Vfloat f => Vundef | Vsingle f => Vundef | Vptr b z => Vptr b (Ptrofs.repr (Z.add (Ptrofs.unsigned z) (Ptrofs.unsigned (Ptrofs.repr i)))) end match p with | Vundef => Vundef | Vint i => Vundef | Vlong i => Vundef | Vfloat f => Vundef | Vsingle f => Vundef | Vptr b z => Vptr b (Ptrofs.repr (Z.add (Ptrofs.unsigned z) (Ptrofs.unsigned (Ptrofs.repr i)))) end *)
apply sepcon_derives; auto.
(* Goal: @derives mpred Nveric (globvar2pred (globals_of_env rho) (@pair ident (globvar type) i gv) rho) (@data_at_ cs (readonly2share (@gvar_readonly type gv)) t (globals_of_env rho i)) *)
specialize (H7 rho).
(* Goal: @derives mpred Nveric (globvar2pred (globals_of_env rho) (@pair ident (globvar type) i gv) rho) (@data_at_ cs (readonly2share (@gvar_readonly type gv)) t (globals_of_env rho i)) *)
unfold_lift in H7. unfold local, lift1 in H7.
(* Goal: @derives mpred Nveric (globvar2pred (globals_of_env rho) (@pair ident (globvar type) i gv) rho) (@data_at_ cs (readonly2share (@gvar_readonly type gv)) t (globals_of_env rho i)) *)
simpl in H7.
(* Goal: @eq val match p with | Vundef => Vundef | Vint i => Vundef | Vlong i => Vundef | Vfloat f => Vundef | Vsingle f => Vundef | Vptr b z => Vptr b (Ptrofs.repr (Z.add (Ptrofs.unsigned z) (Ptrofs.unsigned (Ptrofs.repr i)))) end match p with | Vundef => Vundef | Vint i => Vundef | Vlong i => Vundef | Vfloat f => Vundef | Vsingle f => Vundef | Vptr b z => Vptr b (Ptrofs.repr (Z.add (Ptrofs.unsigned z) (Ptrofs.unsigned (Ptrofs.repr i)))) end *)
rewrite prop_true_andp in H7 by auto.
eapply derives_trans; [ apply H7  | ].
(* Goal: @derives mpred Nveric (memory_block (readonly2share (@gvar_readonly type gv)) (@sizeof (@cenv_cs cs) t) (globals_of_env rho i)) (@data_at_ cs (readonly2share (@gvar_readonly type gv)) t (globals_of_env rho i)) *)
unfold_lift.
(* Goal: @derives mpred Nveric (memory_block (readonly2share (@gvar_readonly type gv)) (@sizeof (@cenv_cs cs) t) (globals_of_env rho i)) (@data_at_ cs (readonly2share (@gvar_readonly type gv)) t (globals_of_env rho i)) *)
assert_PROP (isptr (globals_of_env rho i)) by (saturate_local; apply prop_right; auto).
(* Goal: @derives mpred Nveric (memory_block (readonly2share (@gvar_readonly type gv)) (@sizeof (@cenv_cs cs) t) (globals_of_env rho i)) (@data_at_ cs (readonly2share (@gvar_readonly type gv)) t (globals_of_env rho i)) *)
assert (headptr (globals_of_env rho i)).
(* Goal: @eq val match p with | Vundef => Vundef | Vint i => Vundef | Vlong i => Vundef | Vfloat f => Vundef | Vsingle f => Vundef | Vptr b z => Vptr b (Ptrofs.repr (Z.add (Ptrofs.unsigned z) (Ptrofs.unsigned (Ptrofs.repr i)))) end match p with | Vundef => Vundef | Vint i => Vundef | Vlong i => Vundef | Vfloat f => Vundef | Vsingle f => Vundef | Vptr b z => Vptr b (Ptrofs.repr (Z.add (Ptrofs.unsigned z) (Ptrofs.unsigned (Ptrofs.repr i)))) end *)
hnf. unfold globals_of_env in H9|-*. destruct (Map.get (ge_of rho) i); try contradiction. eauto.
(* Goal: @eq val match p with | Vundef => Vundef | Vint i => Vundef | Vlong i => Vundef | Vfloat f => Vundef | Vsingle f => Vundef | Vptr b z => Vptr b (Ptrofs.repr (Z.add (Ptrofs.unsigned z) (Ptrofs.unsigned (Ptrofs.repr i)))) end match p with | Vundef => Vundef | Vint i => Vundef | Vlong i => Vundef | Vfloat f => Vundef | Vsingle f => Vundef | Vptr b z => Vptr b (Ptrofs.repr (Z.add (Ptrofs.unsigned z) (Ptrofs.unsigned (Ptrofs.repr i)))) end *)
rewrite memory_block_data_at_; auto.
(* Goal: @field_compatible cs t (@nil gfield) (globals_of_env rho i) *)
subst t.
(* Goal: @field_compatible cs (@gvar_info type gv) (@nil gfield) (globals_of_env rho i) *)
rewrite andb_true_iff in H1; destruct H1.
(* Goal: @field_compatible cs (@gvar_info type gv) (@nil gfield) (globals_of_env rho i) *)
pose proof (la_env_cs_sound 0 (gvar_info gv) H1 H3).
(* Goal: @eq val match p with | Vundef => Vundef | Vint i => Vundef | Vlong i => Vundef | Vfloat f => Vundef | Vsingle f => Vundef | Vptr b z => Vptr b (Ptrofs.repr (Z.add (Ptrofs.unsigned z) (Ptrofs.unsigned (Ptrofs.repr i)))) end match p with | Vundef => Vundef | Vint i => Vundef | Vlong i => Vundef | Vfloat f => Vundef | Vsingle f => Vundef | Vptr b z => Vptr b (Ptrofs.repr (Z.add (Ptrofs.unsigned z) (Ptrofs.unsigned (Ptrofs.repr i)))) end *)
apply headptr_field_compatible; auto.
(* Goal: @legal_nested_field cs (@gvar_info type gv) (@nil gfield) *)
(* Goal: Z.lt (@sizeof (@cenv_cs cs) (@gvar_info type gv)) Ptrofs.modulus *)
apply I.
assert (Ptrofs.modulus = Ptrofs.max_unsigned + 1) by computable.
(* Goal: Z.lt (@sizeof (@cenv_cs cs) (@gvar_info type gv)) Ptrofs.modulus *)
omega.
Qed.

Ltac process_one_globvar :=
 first
  [ simple eapply process_globvar_space;
    [simpl; reflexivity | reflexivity | reflexivity | reflexivity | reflexivity | reflexivity | simpl; computable | ]
  | simple eapply process_globvar';
      [reflexivity | reflexivity | reflexivity | reflexivity | reflexivity | reflexivity
      | reflexivity | compute; congruence | ]
  | simple eapply process_globvar_array;
      [reflexivity | reflexivity | reflexivity | reflexivity | reflexivity | reflexivity | apply Coq.Init.Logic.I
      | compute; clear; congruence
      | repeat eapply map_instantiate; symmetry; apply map_nil
      | compute; split; clear; congruence |  ]
  | simple eapply process_globvar_star';
        [reflexivity | reflexivity | reflexivity | reflexivity
        | reflexivity | compute; split; clear; congruence
       | simpl gvar_info; simpl gvar_readonly; simpl readonly2share;
         change (Share.lub extern_retainer Tsh) with Ews
         ]
  | simple eapply halfprocess_globvar_star;
        [reflexivity | reflexivity | reflexivity | reflexivity|
         simpl; compute; split; clear; congruence | ]
  ];
  change (Share.lub extern_retainer _) with Ews;
  change (Share.lub extern_retainer _) with Ers;
  try change (Vint oo _) with (Vint oo id);
  fold_types;
  rewrite ?Combinators.compose_id_right.

Lemma move_globfield_into_SEP:
 forall {cs: compspecs}{Espec: OracleKind} Delta P Q R
   (S1: mpred) (S2 S3 S4: environ -> mpred) c Post,
 semax Delta (PROPx P (LOCALx Q (SEPx (S1::R))) * S2 * S3 * S4) c Post ->
 semax Delta (PROPx P (LOCALx Q (SEPx R)) * (`S1 * S2) * S3 * S4) c Post.
Proof.
(* Goal: forall (cs : compspecs) (Espec : OracleKind) (Delta : tycontext) (PQR : forall _ : environ, mpred) (gv : globals) (SF : forall _ : environ, mpred) (c : statement) (Post : ret_assert) (_ : semax cs Espec Delta (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) PQR SF) c Post), semax cs Espec Delta (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) PQR (globvars2pred gv (@nil (prod ident (globvar type))))) SF) c Post *)
intros.
(* Goal: semax cs Espec Delta (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (PROPx P (LOCALx Q (SEPx R))) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (LiftEnviron mpred) S1) S2)) S3) S4) c Post *)
eapply semax_pre0; [ | eassumption].
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (PROPx P (LOCALx Q (SEPx R))) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (locald_denote (f x))) (@liftx (LiftEnviron mpred) (g (h x)))) S2)) S3) S4) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (PROPx P (LOCALx (@cons localdef (f x) Q) (SEPx (@cons mpred (g (h x)) R)))) S2) S3) S4) *)
rewrite <- insert_SEP.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (PROPx P (LOCALx Q (SEPx R))) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (LiftEnviron mpred) (g (h x))) S2)) S3) S4) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (LiftEnviron mpred) (g (h x))) (PROPx P (LOCALx Q (SEPx R)))) S2) S3) S4) *)
rewrite <- !sepcon_assoc.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (PROPx P (LOCALx Q (SEPx R))) (@liftx (LiftEnviron mpred) S1)) S2) S3) S4) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (LiftEnviron mpred) S1) (PROPx P (LOCALx Q (SEPx R)))) S2) S3) S4) *)
pull_left (`S1).
(* Goal: @eq val match p with | Vundef => Vundef | Vint i => Vundef | Vlong i => Vundef | Vfloat f => Vundef | Vsingle f => Vundef | Vptr b z => Vptr b (Ptrofs.repr (Z.add (Ptrofs.unsigned z) (Ptrofs.unsigned (Ptrofs.repr i)))) end match p with | Vundef => Vundef | Vint i => Vundef | Vlong i => Vundef | Vfloat f => Vundef | Vsingle f => Vundef | Vptr b z => Vptr b (Ptrofs.repr (Z.add (Ptrofs.unsigned z) (Ptrofs.unsigned (Ptrofs.repr i)))) end *)
auto.
Qed.

Lemma move_globfield_into_SEP':
 forall {cs: compspecs}{Espec: OracleKind} Delta P Q R
   (f: val -> localdef)
   (g: val -> mpred)
   (h: val -> val) (S2 S3 S4: environ -> mpred) c Post,
  (forall x: val,
   semax Delta (PROPx P (LOCALx (f x :: Q) (SEPx ((g (h x))::R))) * S2 * S3 * S4) c Post) ->
 semax Delta (PROPx P (LOCALx Q (SEPx R)) * ((EX x:val, local (locald_denote (f x)) && `(g (h x))) * S2) * S3 * S4) c Post.
Proof.
(* Goal: forall (cs : compspecs) (Espec : OracleKind) (Delta : tycontext) (PQR : forall _ : environ, mpred) (gv : globals) (SF : forall _ : environ, mpred) (c : statement) (Post : ret_assert) (_ : semax cs Espec Delta (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) PQR SF) c Post), semax cs Espec Delta (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) PQR (globvars2pred gv (@nil (prod ident (globvar type))))) SF) c Post *)
intros.
(* Goal: semax cs Espec Delta (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (PROPx P (LOCALx Q (SEPx R))) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) val (fun x : val => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (locald_denote (f x))) (@liftx (LiftEnviron mpred) (g (h x) : mpred)))) S2)) S3) S4) c Post *)
normalize.
(* Goal: semax cs Espec Delta (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) val (fun x : val => @sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (PROPx P (LOCALx Q (SEPx R))) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (locald_denote (f x))) (@liftx (LiftEnviron mpred) (g (h x)))) S2)) S3) S4)) c Post *)
apply extract_exists_pre; intro x.
(* Goal: semax cs Espec Delta (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (PROPx P (LOCALx Q (SEPx R))) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (locald_denote (f x))) (@liftx (LiftEnviron mpred) (g (h x)))) S2)) S3) S4) c Post *)
eapply semax_pre0; [ | apply (H x)].
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (PROPx P (LOCALx Q (SEPx R))) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (locald_denote (f x))) (@liftx (LiftEnviron mpred) (g (h x)))) S2)) S3) S4) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (PROPx P (LOCALx (@cons localdef (f x) Q) (SEPx (@cons mpred (g (h x)) R)))) S2) S3) S4) *)
clear.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (PROPx P (LOCALx Q (SEPx R))) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (locald_denote (f x))) (@liftx (LiftEnviron mpred) (g (h x)))) S2)) S3) S4) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (PROPx P (LOCALx (@cons localdef (f x) Q) (SEPx (@cons mpred (g (h x)) R)))) S2) S3) S4) *)
rewrite <- insert_SEP.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (PROPx P (LOCALx Q (SEPx R))) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (locald_denote (f x))) (@liftx (LiftEnviron mpred) (g (h x)))) S2)) S3) S4) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (LiftEnviron mpred) (g (h x))) (PROPx P (LOCALx (@cons localdef (f x) Q) (SEPx R)))) S2) S3) S4) *)
rewrite <- insert_local.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (PROPx P (LOCALx Q (SEPx R))) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (locald_denote (f x))) (@liftx (LiftEnviron mpred) (g (h x)))) S2)) S3) S4) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (LiftEnviron mpred) (g (h x))) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (locald_denote (f x))) (PROPx P (LOCALx Q (SEPx R))))) S2) S3) S4) *)
rewrite local_sepcon_assoc1.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (PROPx P (LOCALx Q (SEPx R))) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (locald_denote (f x))) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (LiftEnviron mpred) (g (h x))) S2))) S3) S4) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (LiftEnviron mpred) (g (h x))) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (locald_denote (f x))) (PROPx P (LOCALx Q (SEPx R))))) S2) S3) S4) *)
rewrite !local_sepcon_assoc2.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (locald_denote (f x))) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (PROPx P (LOCALx Q (SEPx R))) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (LiftEnviron mpred) (g (h x))) S2))) S3) S4) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (locald_denote (f x))) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (LiftEnviron mpred) (g (h x))) (PROPx P (LOCALx Q (SEPx R))))) S2) S3) S4) *)
rewrite !local_sepcon_assoc1.
(* Goal: @eq val match p with | Vundef => Vundef | Vint i => Vundef | Vlong i => Vundef | Vfloat f => Vundef | Vsingle f => Vundef | Vptr b z => Vptr b (Ptrofs.repr (Z.add (Ptrofs.unsigned z) (Ptrofs.unsigned (Ptrofs.repr i)))) end match p with | Vundef => Vundef | Vint i => Vundef | Vlong i => Vundef | Vfloat f => Vundef | Vsingle f => Vundef | Vptr b z => Vptr b (Ptrofs.repr (Z.add (Ptrofs.unsigned z) (Ptrofs.unsigned (Ptrofs.repr i)))) end *)
apply andp_derives; auto.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (PROPx P (LOCALx Q (SEPx R))) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (LiftEnviron mpred) (g (h x))) S2)) S3) S4) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (LiftEnviron mpred) (g (h x))) (PROPx P (LOCALx Q (SEPx R)))) S2) S3) S4) *)
rewrite <- !sepcon_assoc.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (PROPx P (LOCALx Q (SEPx R))) (@liftx (LiftEnviron mpred) (g (h x)))) S2) S3) S4) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (LiftEnviron mpred) (g (h x))) (PROPx P (LOCALx Q (SEPx R)))) S2) S3) S4) *)
pull_left (`(g (h x))).
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (LiftEnviron mpred) (g (h x))) (PROPx P (LOCALx Q (SEPx R)))) S2) S3) S4) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (LiftEnviron mpred) (g (h x))) (PROPx P (LOCALx Q (SEPx R)))) S2) S3) S4) *)
apply derives_refl.
Qed.
(*
Lemma move_globfield_into_SEP'':
 forall {cs: compspecs}{Espec: OracleKind} Delta P Q R
   (i: ident) (v: val)
   (g: val -> mpred)
   (h: val -> val) (S2 S3 S4: environ -> mpred) c Post,
   In (gvar i v) Q ->
  semax Delta (PROPx P (LOCALx Q (SEPx ((g (h v))::R))) * S2 * S3 * S4) c Post ->
 semax Delta (PROPx P (LOCALx Q (SEPx R)) * ((EX x:val, local (locald_denote (gvar i x)) && `(g (h x))) * S2) * S3 * S4) c Post.
Proof.
(* Goal: forall (cs : compspecs) (Espec : OracleKind) (Delta : tycontext) (PQR : forall _ : environ, mpred) (gv : globals) (SF : forall _ : environ, mpred) (c : statement) (Post : ret_assert) (_ : semax cs Espec Delta (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) PQR SF) c Post), semax cs Espec Delta (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) PQR (globvars2pred gv (@nil (prod ident (globvar type))))) SF) c Post *)
intros.
(* Goal: semax cs Espec Delta (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (PROPx P (LOCALx Q (SEPx R))) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) val (fun x : val => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (locald_denote (f x))) (@liftx (LiftEnviron mpred) (g (h x) : mpred)))) S2)) S3) S4) c Post *)
normalize.
(* Goal: semax cs Espec Delta (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) val (fun x : val => @sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (PROPx P (LOCALx Q (SEPx R))) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (locald_denote (f x))) (@liftx (LiftEnviron mpred) (g (h x)))) S2)) S3) S4)) c Post *)
apply extract_exists_pre; intro x.
eapply semax_pre0; [ | apply H0].
clear - H.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (PROPx P (LOCALx Q (SEPx R))) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (locald_denote (f x))) (@liftx (LiftEnviron mpred) (g (h x)))) S2)) S3) S4) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (PROPx P (LOCALx (@cons localdef (f x) Q) (SEPx (@cons mpred (g (h x)) R)))) S2) S3) S4) *)
rewrite <- insert_SEP.
(* Goal: @derives (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (tc_environ Delta)) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (locald_denote (gvars gz))) PQR) (globvars2pred gz (@cons (prod ident (globvar type)) (@pair ident (globvar type) i gv) gvs))) SF)) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (lifted (LiftEnviron mpred)) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@liftx (LiftEnviron mpred) (@data_at_ cs (readonly2share (@gvar_readonly type gv)) t (gz i))) (@andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (locald_denote (gvars gz))) PQR)) (globvars2pred gz gvs)) SF) *)
go_lowerx.
(* Goal: semax cs Espec Delta (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (PROPx P (LOCALx Q (SEPx R))) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) val (fun x : val => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (locald_denote (f x))) (@liftx (LiftEnviron mpred) (g (h x) : mpred)))) S2)) S3) S4) c Post *)
normalize.
(* Goal: @derives mpred Nveric (mapsto sh (Tpointer Tvoid noattr) (Vptr b (Ptrofs.repr ofs)) (Vptr b1 i0)) (mapsto_ sh (Tpointer Tvoid noattr) (Vptr b (Ptrofs.repr ofs))) *)
cancel.
clear - H2 H H1.
(* Goal: forall (cs : compspecs) (Espec : OracleKind) (Delta : tycontext) (PQR : forall _ : environ, mpred) (gv : globals) (SF : forall _ : environ, mpred) (c : statement) (Post : ret_assert) (_ : semax cs Espec Delta (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) PQR SF) c Post), semax cs Espec Delta (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) PQR (globvars2pred gv (@nil (prod ident (globvar type))))) SF) c Post *)
revert H H1; induction Q; intros.
(* Goal: @predicates_hered.app_pred compcert_rmaps.RML.R.rmap compcert_rmaps.RML.R.ag_rmap (@prop mpred Nveric (Z.divide (align_chunk ch) (Ptrofs.unsigned z))) a *)
(* Goal: @derives mpred Nveric (if attr_volatile (attr_of_type t) then @FF mpred Nveric else @andp (@predicates_hered.pred compcert_rmaps.RML.R.rmap compcert_rmaps.RML.R.ag_rmap) Nveric (@prop (@predicates_hered.pred compcert_rmaps.RML.R.rmap compcert_rmaps.RML.R.ag_rmap) Nveric (and (tc_val' t p) (Z.divide (align_chunk ch) (Ptrofs.unsigned z)))) (res_predicates.nonlock_permission_bytes sh (@pair block Z b (Ptrofs.unsigned z)) (size_chunk ch))) (@prop mpred Nveric (Z.divide (align_chunk ch) (Ptrofs.unsigned z))) *)
inv H. simpl in H. destruct H. subst a.
simpl in H1.
destruct H1.
clear - H2 H.
hnf in H,H2.
destruct (Map.get (ve_of rho) i) as [[? ?]|]. contradiction.
(* Goal: @ex block (fun b : block => @eq val match @Map.get block (ge_of rho) i with | Some b0 => Vptr b0 Ptrofs.zero | None => Vundef end (Vptr b Ptrofs.zero)) *)
(* Goal: @derives mpred Nveric (memory_block (readonly2share (@gvar_readonly type gv)) (@sizeof (@cenv_cs cs) t) (globals_of_env rho i)) (@data_at_ cs (readonly2share (@gvar_readonly type gv)) t (globals_of_env rho i)) *)
destruct (Map.get (ge_of rho) i); try contradiction.
(* Goal: @eq val match p with | Vundef => Vundef | Vint i => Vundef | Vlong i => Vundef | Vfloat f => Vundef | Vsingle f => Vundef | Vptr b z => Vptr b (Ptrofs.repr (Z.add (Ptrofs.unsigned z) (Ptrofs.unsigned (Ptrofs.repr i)))) end match p with | Vundef => Vundef | Vint i => Vundef | Vlong i => Vundef | Vfloat f => Vundef | Vsingle f => Vundef | Vptr b z => Vptr b (Ptrofs.repr (Z.add (Ptrofs.unsigned z) (Ptrofs.unsigned (Ptrofs.repr i)))) end *)
subst. auto.
destruct H1.
(* Goal: @eq val match p with | Vundef => Vundef | Vint i => Vundef | Vlong i => Vundef | Vfloat f => Vundef | Vsingle f => Vundef | Vptr b z => Vptr b (Ptrofs.repr (Z.add (Ptrofs.unsigned z) (Ptrofs.unsigned (Ptrofs.repr i)))) end match p with | Vundef => Vundef | Vint i => Vundef | Vlong i => Vundef | Vfloat f => Vundef | Vsingle f => Vundef | Vptr b z => Vptr b (Ptrofs.repr (Z.add (Ptrofs.unsigned z) (Ptrofs.unsigned (Ptrofs.repr i)))) end *)
auto.
Qed.
*)
Lemma move_globfield_into_SEP0:
 forall {cs: compspecs}{Espec: OracleKind} Delta
   (S0 S3 S4: environ -> mpred) c Post,
 semax Delta (S0 * S3 * S4) c Post ->
 semax Delta (S0 * emp * S3 * S4) c Post.
Proof.
(* Goal: forall (cs : compspecs) (Espec : OracleKind) (Delta : tycontext) (PQR : forall _ : environ, mpred) (gv : globals) (SF : forall _ : environ, mpred) (c : statement) (Post : ret_assert) (_ : semax cs Espec Delta (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) PQR SF) c Post), semax cs Espec Delta (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) PQR (globvars2pred gv (@nil (prod ident (globvar type))))) SF) c Post *)
intros.
(* Goal: @eq val match p with | Vundef => Vundef | Vint i => Vundef | Vlong i => Vundef | Vfloat f => Vundef | Vsingle f => Vundef | Vptr b z => Vptr b (Ptrofs.repr (Z.add (Ptrofs.unsigned z) (Ptrofs.unsigned (Ptrofs.repr i)))) end match p with | Vundef => Vundef | Vint i => Vundef | Vlong i => Vundef | Vfloat f => Vundef | Vsingle f => Vundef | Vptr b z => Vptr b (Ptrofs.repr (Z.add (Ptrofs.unsigned z) (Ptrofs.unsigned (Ptrofs.repr i)))) end *)
rewrite sepcon_emp; auto.
Qed.

Lemma offset_val_unsigned_repr: forall i p,
  offset_val (Ptrofs.unsigned (Ptrofs.repr i)) p = offset_val i p.
Proof.
(* Goal: forall (cs : compspecs) (Espec : OracleKind) (Delta : tycontext) (PQR : forall _ : environ, mpred) (gv : globals) (SF : forall _ : environ, mpred) (c : statement) (Post : ret_assert) (_ : semax cs Espec Delta (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) PQR SF) c Post), semax cs Espec Delta (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) PQR (globvars2pred gv (@nil (prod ident (globvar type))))) SF) c Post *)
  intros.
(* Goal: @eq val (offset_val (Ptrofs.unsigned (Ptrofs.repr i)) p) (offset_val i p) *)
  unfold offset_val.
(* Goal: @eq val match p with | Vundef => Vundef | Vint i => Vundef | Vlong i => Vundef | Vfloat f => Vundef | Vsingle f => Vundef | Vptr b z => Vptr b (Ptrofs.add z (Ptrofs.repr (Ptrofs.unsigned (Ptrofs.repr i)))) end match p with | Vundef => Vundef | Vint i => Vundef | Vlong i => Vundef | Vfloat f => Vundef | Vsingle f => Vundef | Vptr b z => Vptr b (Ptrofs.add z (Ptrofs.repr i)) end *)
  unfold Ptrofs.add.
(* Goal: @eq val match p with | Vundef => Vundef | Vint i => Vundef | Vlong i => Vundef | Vfloat f => Vundef | Vsingle f => Vundef | Vptr b z => Vptr b (Ptrofs.repr (Z.add (Ptrofs.unsigned z) (Ptrofs.unsigned (Ptrofs.repr (Ptrofs.unsigned (Ptrofs.repr i)))))) end match p with | Vundef => Vundef | Vint i => Vundef | Vlong i => Vundef | Vfloat f => Vundef | Vsingle f => Vundef | Vptr b z => Vptr b (Ptrofs.repr (Z.add (Ptrofs.unsigned z) (Ptrofs.unsigned (Ptrofs.repr i)))) end *)
  rewrite Ptrofs.repr_unsigned.
(* Goal: @eq val match p with | Vundef => Vundef | Vint i => Vundef | Vlong i => Vundef | Vfloat f => Vundef | Vsingle f => Vundef | Vptr b z => Vptr b (Ptrofs.repr (Z.add (Ptrofs.unsigned z) (Ptrofs.unsigned (Ptrofs.repr i)))) end match p with | Vundef => Vundef | Vint i => Vundef | Vlong i => Vundef | Vfloat f => Vundef | Vsingle f => Vundef | Vptr b z => Vptr b (Ptrofs.repr (Z.add (Ptrofs.unsigned z) (Ptrofs.unsigned (Ptrofs.repr i)))) end *)
  auto.
Qed.

Ltac process_idstar :=
     process_one_globvar;
     lazymatch goal with |- semax _ (_ * ?A * _ * _) _ _ =>
         let p := fresh "p" in set (p:=A);
         simpl in p;
         unfold id2pred_star, init_data2pred' in p;
         simpl PTree.get in p; simpl zeq in p;
         cbv beta iota zeta in p;
         simpl init_data_size in p;
         revert p; rewrite ?offset_offset_val; intro p; simpl Z.add in p;
         subst p;
       repeat first
        [simple apply move_globfield_into_SEP
(*        | simple eapply move_globfield_into_SEP''; [ now repeat econstructor | ] *)
        | simple apply move_globfield_into_SEP'; intros ?gvar0 (*;
          lazymatch goal with
          | |- semax _ ((PROPx _ (LOCALx (gvar ?A ?B :: _) _)) * _ * _ * _)  _ _ =>
                 let n := fresh "v" A in rename B into n
          | |- _ => idtac
          end*)
        ];
      simple apply move_globfield_into_SEP0
    | |- semax _ (_ * _ * _) _ _ => idtac
     end.

Lemma eliminate_globvars2pred_nil: 
 forall {cs: compspecs}{Espec: OracleKind} Delta PQR gv SF c Post,
  semax Delta (PQR * SF) c Post ->
  semax Delta (PQR * globvars2pred gv nil * SF) c Post.
Proof.
(* Goal: forall (cs : compspecs) (Espec : OracleKind) (Delta : tycontext) (PQR : forall _ : environ, mpred) (gv : globals) (SF : forall _ : environ, mpred) (c : statement) (Post : ret_assert) (_ : semax cs Espec Delta (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) PQR SF) c Post), semax cs Espec Delta (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) PQR (globvars2pred gv (@nil (prod ident (globvar type))))) SF) c Post *)
intros.
(* Goal: semax cs Espec Delta (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) PQR (globvars2pred gv (@nil (prod ident (globvar type))))) SF) c Post *)
eapply semax_pre; [ | apply H].
(* Goal: semax cs Espec Delta (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (PROPx P (LOCALx Q (SEPx R))) (@sepcon (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (@LiftSepLog' mpred Nveric Sveric) (@exp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) val (fun x : val => @andp (forall _ : environ, mpred) (@LiftNatDed' mpred Nveric) (local (locald_denote (f x))) (@liftx (LiftEnviron mpred) (g (h x) : mpred)))) S2)) S3) S4) c Post *)
go_lowerx; normalize.
Qed.

Ltac expand_main_pre :=
 (rewrite main_pre_start || rewrite main_pre_ext_start);
 unfold prog_vars, prog_vars'; simpl globvars2pred;
 repeat  process_idstar;
 apply eliminate_globvars2pred_nil;
 rewrite ?offset_val_unsigned_repr;
 simpl readonly2share.

