Section PACO3.
Variable T0 : Type.
Variable T1 : forall (x0: @T0), Type.
Variable T2 : forall (x0: @T0) (x1: @T1 x0), Type.
(** ** Signatures *)
Record sig3T  :=
exist3T {
proj3T0: @T0;
proj3T1: @T1 proj3T0;
proj3T2: @T2 proj3T0 proj3T1;
}.
Definition uncurry3  (R: rel3 T0 T1 T2): rel1 sig3T :=
fun x => R (proj3T0 x) (proj3T1 x) (proj3T2 x).
Definition curry3  (R: rel1 sig3T): rel3 T0 T1 T2 :=
fun x0 x1 x2 => R (@exist3T x0 x1 x2).
(** ** Predicates of Arity 3 *)
Definition paco3(gf : rel3 T0 T1 T2 -> rel3 T0 T1 T2)(r: rel3 T0 T1 T2) : rel3 T0 T1 T2 :=
curry3 (paco (fun R0 => uncurry3 (gf (curry3 R0))) (uncurry3 r)).
Definition upaco3(gf : rel3 T0 T1 T2 -> rel3 T0 T1 T2)(r: rel3 T0 T1 T2) := paco3 gf r \3/ r.
Arguments paco3 : clear implicits.
Arguments upaco3 : clear implicits.
Hint Unfold upaco3 : core.
Definition monotone3 (gf: rel3 T0 T1 T2 -> rel3 T0 T1 T2) :=
forall x0 x1 x2 r r' (IN: gf r x0 x1 x2) (LE: r <3= r'), gf r' x0 x1 x2.
Definition _monotone3 (gf: rel3 T0 T1 T2 -> rel3 T0 T1 T2) :=
forall r r'(LE: r <3= r'), gf r <3== gf r'.

Lemma monotone3_compose (gf gf': rel3 T0 T1 T2 -> rel3 T0 T1 T2)
(MON1: monotone3 gf)
(MON2: monotone3 gf'):
monotone3 (compose gf gf').