Section type_func.
Context {A: Type}
(f_default: type -> A)
(f_array: A -> type -> Z -> attr -> A)
(f_struct: A -> ident -> attr -> A)
(f_union: A -> ident -> attr -> A)
(f_member: struct_or_union -> list (ident * type * A) -> A).
Fixpoint F (env: PTree.t A) (t: type): A :=
match t with
| Tarray t n a => f_array (F env t) t n a
| Tstruct id a =>
match env ! id with
| Some v => f_struct v id a
| None => f_default t
end
| Tunion id a =>
match env ! id with
| Some v => f_union v id a
| None => f_default t
end
| _ => f_default t
end.
Definition Complete (cenv: composite_env) (env: PTree.t A): Prop :=
forall i,
(exists co, PTree.get i cenv = Some co) <->
(exists a, PTree.get i env = Some a).
Definition Consistent (cenv: composite_env) (env: PTree.t A): Prop :=
forall i co a,
PTree.get i cenv = Some co ->
PTree.get i env = Some a ->
a = f_member (co_su co) (map
(fun it0: positive * type =>
let (i0, t0) := it0 in
(i0, t0, F env t0))
(co_members co)).
Definition env_rec (i: positive) (co: composite) (env: PTree.t A): PTree.t A :=
PTree.set i
(f_member (co_su co) (map
(fun it0: positive * type =>
let (i0, t0) := it0 in (i0, t0, F env t0))
(co_members co)))
env.
Definition Env (l: list (positive * composite)): PTree.t A :=
fold_right
(fun (ic: positive * composite) =>
let (i, co) := ic in env_rec i co)
(PTree.empty A)
l.

Lemma F_PTree_set: forall t env i a,
~ In i (map fst (PTree.elements env)) ->
relative_defined_type (PTree.elements env) t ->
F env t = F (PTree.set i a env) t.