Module Type ADR_VAL.
Parameter address : Type.
Parameter some_address:address.
(* Validity of traces.  The "valid" predicate ensures that related addresses don't get split apart from each other.  *)
Parameter kind: Type.
End ADR_VAL.
Inductive TypeTree: Type :=
| ConstType: Type -> TypeTree
| Mpred: TypeTree
| DependentType: nat -> TypeTree
| ProdType: TypeTree -> TypeTree -> TypeTree
| ArrowType: TypeTree -> TypeTree -> TypeTree
| SigType: forall (I : Type), (I -> TypeTree) -> TypeTree
| PiType: forall (I : Type), (I -> TypeTree) -> TypeTree
| ListType: TypeTree -> TypeTree.
Definition dependent_type_functor_rec (ts: list Type): TypeTree -> functor :=
fix dtfr (T: TypeTree): functor :=
match T with
| ConstType A => fconst A
| Mpred => fidentity
| DependentType n => fconst (nth n ts unit)
| ProdType T1 T2 => fpair (dtfr T1) (dtfr T2)
| ArrowType T1 T2 => ffunc (dtfr T1) (dtfr T2)
| SigType _ f => fsig (fun i => dtfr (f i))
| PiType _ f => fpi (fun i => dtfr (f i))
| ListType T => flist (dtfr T)
end.
Opaque dependent_type_functor_rec.
Definition dependent_type_function_rec (ts: list Type) (mpred': Type): TypeTree -> Type :=
fix dtfr (T: TypeTree): Type :=
match T with
| ConstType A => A
| Mpred => mpred'
| DependentType n => nth n ts unit
| ProdType T1 T2 => (dtfr T1 * dtfr T2)%type
| ArrowType T1 T2 => dtfr T1 -> dtfr T2
| SigType A f => sigT (fun a => dtfr (f a))
| PiType A f => forall a, dtfr (f a)
| ListType T => list (dtfr T)
end.
Definition fpreds: functor :=
fsig (fun T: TypeTree =>
fpi (fun ts: list Type => dependent_type_functor_rec ts T)).

Lemma realize_eq: forall {A} (a b: A) P, (exists H: a = b, P H) -> {H: a = b & P H}.