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__offset_zero: forall sh t gfs p,
field_at_ sh t gfs p = field_at_ sh t gfs (offset_val 0 p).