Definition field_at (t: type) (nf: list ident) (v: reptype (nested_field_type t nf)) (p: val) : Pred := data_at_rec (nested_field_type t nf) v (offset_val (nested_field_offset t nf) p).Definition data_at (t: type) (v: reptype t) (p: val) : Pred := field_at t nil v p.Definition field_address (t: type) (nf: list ident) (p: val) : val := offset_val (nested_field_offset t nf) p.

(* Specifications: *)
Lemma data_at_field_at: forall t v p, data_at t v p = field_at t nil v p.
Lemma field_at_Tint: forall t nf v1 v2 p, nested_field_type t nf = Tint -> JMeq v1 v2 -> field_at t nf v1 p = mapsto (field_address t nf p) v2.
Lemma field_at_Tstruct: forall t nf id fs v p, nested_field_type t nf = Tstruct id fs -> members_no_replicate fs -> field_at t nf v p = (fix field_at_struct fs := match fs with | Fnil => emp | Fcons (i0, t0) fs0 => field_at t (i0 :: nf) (proj_reptype _ (i0 :: nil) v) p * field_at_struct fs0 end) fs.
Lemma field_at_Tstruct': forall t nf id fs v p i, nested_field_type t nf = Tstruct id fs -> members_no_replicate fs -> in_members i fs -> field_at t nf v p = field_at t (i :: nf) (proj_reptype _ (i :: nil) v) p * (fix field_at_struct fs := match fs with | Fnil => emp | Fcons (i0, t0) fs0 => (if (ident_eq i0 i) then emp else field_at t (i0 :: nf) (proj_reptype _ (i0 :: nil) v) p) * field_at_struct fs0 end) fs.
Lemma field_at_data_at: forall t nf v p, field_at t nf v p = data_at _ v (field_address t nf p).