Proof fun X A a P Y B b H1 H2 E f => f Y B b H1 H2.
(** ** The collection scheme **)
(** Let (X, A, a) be a pointed graph and R a binary relation over the class of pointed graph (that we suppose compatible) such that each element of the pointed graph (X, A, a) is related to at least one pointed graph via the relation R.  Since the elements of (X, A, a) are (up to a bisimulation) the pointed graphs of the form (X, A, x) where x : X is a vertex such that (A x a), our assumption can be reformulated as  for any x : X such that (A x a), there exists a pointed graph (Y, B, b) such that (R X A x Y B b).  (Of course, the equivalence of both formulations relies on the compatibility of R with respect to its first argument).  Now, let us consider the family of small types  (coll_fam X A a R)  :  X->Code->Typ1  defined by using the choice operator "eps" as follows: *)
Definition coll_fam (X : Typ1) (A : Rel X) (a : X)
(R : REL) (x : X) : Code -> Typ1 :=
eps (fun Y => ex (Rel Y) (fun B => ex Y (fun b => R X A x Y B b))).
(** (Notice that the definition of (coll_fam X A a R) actually does not depend on the root a : X of the pointed graph (X, A, a).)  By construction, the family of small types (coll_fam X A a R) is such that for any x : X, if there exists a pointed graph (Y, B, b) which is related to (X, A, x) via R, then there is a code c : Code such that (coll_fam X A a R x c) is the carrier of one of such pointed graphs, that is, such that  (R X A x (coll_fam X A a R x c) B b)  for some edge relation B and some root b on the carrier given by (coll_fam X A a R x c).  It is now clear that if we take the super-powerset of the family (coll_fam X A a R) : X->Code->Typ1, we obtain a pointed graph that meets the specification of the collection scheme.  Formally, the desired pointed graph  ((coll X A a R), (COLL X A a R), (coll_rt X A a R))  is defined as follows: *)
Definition coll (X : Typ1) (A : Rel X) (a : X) (R : REL) : Typ1 :=
foo X Code (coll_fam X A a R).
Definition COLL (X : Typ1) (A : Rel X) (a : X) (R : REL) :
Rel (coll X A a R) := FOO X Code (coll_fam X A a R).
Definition coll_rt (X : Typ1) (A : Rel X) (a : X) (R : REL) :
coll X A a R := foo_rt X Code (coll_fam X A a R).
(** (Notice that the components of this pointed graph actually do not depend on the root a : X of the pointed graph (X, A, a).)  It is now a simple exercise to check that the pointed graph we have built meets the specification of the collection scheme: *)

(* Specifications: *)
Theorem collection :
forall (X : Typ1) (A : Rel X) (a : X) (R : REL),
LCOMPAT R ->
RCOMPAT R ->
(forall (X' : Typ1) (A' : Rel X') (a' : X'),
ELT X' A' a' X A a -> exG (fun Y' B' b' => R X' A' a' Y' B' b')) ->
forall (X' : Typ1) (A' : Rel X') (a' : X'),
ELT X' A' a' X A a ->
exG_rel (coll X A a R) (COLL X A a R) (coll_rt X A a R)
(fun Y' B' b' => R X' A' a' Y' B' b').