Definition repinject (t: type): reptype t -> val :=
match t as t_PAT return reptype t_PAT -> val with
| Tint => fun v => v
| _ => fun _ => Vundef
end.
Definition at_offset (P: val -> Pred) (z: Z): val -> Pred :=
fun v => P (offset_val z v).
Fixpoint struct_pred (m: members) {A: ident * type -> Type} (P: forall it, A it -> val -> Pred): list_prod (map A m) -> val -> Pred :=
match m as m_PAT return list_prod (map A m_PAT) -> val -> Pred with
| nil => fun _ _ => emp
| (i0, t0) :: m0 => fun v p => (P _ (fst v) p * struct_pred m0 P (snd v) p)%logic
end.
Definition struct_data_at_rec_aux (m m0: members) (P: ListType (map (fun it => reptype (field_type (fst it) m0) -> (val -> Pred)) m)) (v: list_prod (map (fun it => reptype (field_type (fst it) m0)) m)) : (val -> Pred).
Definition data_at_rec: forall t, reptype t -> val -> Pred :=
type_func (fun t => reptype t -> val -> Pred)
(fun t v p => mapsto p (repinject t v))
(fun id P v => struct_data_at_rec_aux (co_members (get_co id)) (co_members (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 -> Pred with
| Tint => fun v p => mapsto p v
| Tstruct id => struct_pred (co_members (get_co id))
(fun it v => 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))))
end (unfold_reptype v).