Definition field_at (sh: Share.t) (t: type) (gfs: list gfield) (v: reptype (nested_field_type t gfs)) (p: val): mpred :=
!! (field_compatible t gfs p) &&
at_offset (data_at_rec sh (nested_field_type t gfs) v) (nested_field_offset t gfs) p.
Arguments field_at sh t gfs v p : simpl never.
Definition field_at_ (sh: Share.t) (t: type) (gfs: list gfield) (p: val): mpred :=
field_at sh t gfs (default_val (nested_field_type t gfs)) p.
Arguments field_at_ sh t gfs p : simpl never.
Definition data_at (sh: Share.t) (t: type) (v: reptype t) := field_at sh t nil v.
Definition data_at_ (sh: Share.t) (t: type) := field_at_ sh t nil.
Definition nested_reptype_structlist t gfs (m: members) :=
compact_prod (map (fun it => reptype (nested_field_type t (StructField (fst it) :: gfs))) m).
Definition nested_reptype_unionlist t gfs (m: members) :=
compact_sum (map (fun it => reptype (nested_field_type t (UnionField (fst it) :: gfs))) m).

Lemma field_at_isptr: forall sh t gfs v p,
field_at sh t gfs v p = (!! isptr p) && field_at sh t gfs v p.