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 array_at_ext: forall sh t gfs lo hi v0 v1 p,
Zlength v0 = Zlength v1 ->
(forall i u0 u1,
lo <= i < hi ->
JMeq u0 (Znth (i-lo) v0) ->
JMeq u1 (Znth (i-lo) v1) ->
field_at sh t (ArraySubsc i :: gfs) u0 p =
field_at sh t (ArraySubsc i :: gfs) u1 p) ->
array_at sh t gfs lo hi v0 p = array_at sh t gfs lo hi v1 p.