Require VST.floyd.aggregate_pred. Import VST.floyd.aggregate_pred.aggregate_pred.
Require Export VST.floyd.fieldlist.
Require Export VST.floyd.aggregate_type.
Opaque alignof.
Local Open Scope logic.
Arguments align !n !amount / .
Arguments Z.max !n !m / .
Definition offset_in_range ofs p :=
match p with
| Vptr b iofs => 0 <= Ptrofs.unsigned iofs + ofs <= Ptrofs.modulus
| _ => True
end.
Definition offset_strict_in_range ofs p :=
match p with
| Vptr b iofs => 0 <= Ptrofs.unsigned iofs + ofs < Ptrofs.modulus
| _ => True
end.
(************************************************  Definition of data_at_rec  Always assume in arguments of data_at_rec has argument pos with alignment criterion.  ************************************************)
Section CENV.
Context {cs: compspecs}.
(* Lemma proj_struct_default: forall i m d, in_members i m -> members_no_replicate m = true -> proj_struct i m (struct_default_val m) d = default_val (field_type i m).  Lemma proj_union_default: forall i m d, i = fst (members_union_inj (union_default_val m)) -> m <> nil -> members_no_replicate m = true -> proj_union i m (union_default_val m) d = default_val (field_type2 i m). *)
Section WITH_SHARE.
Variable sh: share.
Definition data_at_rec: forall t, reptype t -> val -> mpred :=
type_func (fun t => reptype t -> val -> mpred)
(fun t v p =>
if type_is_volatile t
then memory_block sh (sizeof t) p
else mapsto sh t p (repinject t v))
(fun t n a P v => array_pred 0 (Z.max 0 n) (fun i v => at_offset (P v) (sizeof t * i)) (unfold_reptype v))
(fun id a P v => struct_data_at_rec_aux sh (co_members (get_co id)) (co_members (get_co id)) (co_sizeof (get_co id)) P (unfold_reptype v))
(fun id a P v => union_data_at_rec_aux sh (co_members (get_co id)) (co_members (get_co id)) (co_sizeof (get_co id)) P (unfold_reptype v)).

(* Specifications: *)
Lemma data_at_rec_eq: forall t v,
data_at_rec t v =
match t return REPTYPE t -> val -> mpred with
| Tvoid
| Tfunction _ _ _ => fun _ _ => FF
| Tint _ _ _
| Tfloat _ _
| Tlong _ _
| Tpointer _ _ => fun v p =>
if type_is_volatile t
then memory_block sh (sizeof t) p
else mapsto sh t p v
| Tarray t0 n a => array_pred 0 (Z.max 0 n) (fun i v => at_offset (data_at_rec t0 v) (sizeof t0 * i))
| Tstruct id a => struct_pred (co_members (get_co id))
(fun it v => withspacer sh
(field_offset cenv_cs (fst it) (co_members (get_co id)) + sizeof (field_type (fst it) (co_members (get_co id))))
(field_offset_next cenv_cs (fst it) (co_members (get_co id)) (co_sizeof (get_co id)))
(at_offset (data_at_rec (field_type (fst it) (co_members (get_co id))) v) (field_offset cenv_cs (fst it) (co_members (get_co id)))))
| Tunion id a => union_pred (co_members (get_co id))
(fun it v => withspacer sh
(sizeof (field_type (fst it) (co_members (get_co id))))
(co_sizeof (get_co id))
(data_at_rec (field_type (fst it) (co_members (get_co id))) v))
end (unfold_reptype v).