Section TypeRecFunctions.
Context {cs: compspecs}.
Definition reptype_gen: type -> (sigT (fun x => x)) :=
type_func (fun _ => (sigT (fun x => x)))
(fun t =>
match t with
| Tint => existT (fun x => x) val Vundef
| Tstruct _ => existT (fun x => x) unit tt
end)
(fun id TVs => existT (fun x => x) (list_prod_sigT_type (decay TVs)) (list_prod_sigT_value (decay TVs))).
Definition reptype t: Type := match reptype_gen t with existT t _ => t end.
Definition default_val t: reptype t :=
match reptype_gen t as tv
return match tv with existT t _ => t end
with existT t v => v end.
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)).

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).