Section PACO4.
Variable T0 : Type.
Variable T1 : forall (x0: @T0), Type.
Variable T2 : forall (x0: @T0) (x1: @T1 x0), Type.
Variable T3 : forall (x0: @T0) (x1: @T1 x0) (x2: @T2 x0 x1), Type.
(** ** Signatures *)
Record sig4T  :=
exist4T {
proj4T0: @T0;
proj4T1: @T1 proj4T0;
proj4T2: @T2 proj4T0 proj4T1;
proj4T3: @T3 proj4T0 proj4T1 proj4T2;
}.
Definition uncurry4  (R: rel4 T0 T1 T2 T3): rel1 sig4T :=
fun x => R (proj4T0 x) (proj4T1 x) (proj4T2 x) (proj4T3 x).
Definition curry4  (R: rel1 sig4T): rel4 T0 T1 T2 T3 :=
fun x0 x1 x2 x3 => R (@exist4T x0 x1 x2 x3).
(** ** Predicates of Arity 4 *)
Definition paco4(gf : rel4 T0 T1 T2 T3 -> rel4 T0 T1 T2 T3)(r: rel4 T0 T1 T2 T3) : rel4 T0 T1 T2 T3 :=
curry4 (paco (fun R0 => uncurry4 (gf (curry4 R0))) (uncurry4 r)).
Definition upaco4(gf : rel4 T0 T1 T2 T3 -> rel4 T0 T1 T2 T3)(r: rel4 T0 T1 T2 T3) := paco4 gf r \4/ r.
Arguments paco4 : clear implicits.
Arguments upaco4 : clear implicits.
Hint Unfold upaco4 : core.
Definition monotone4 (gf: rel4 T0 T1 T2 T3 -> rel4 T0 T1 T2 T3) :=
forall x0 x1 x2 x3 r r' (IN: gf r x0 x1 x2 x3) (LE: r <4= r'), gf r' x0 x1 x2 x3.
Definition _monotone4 (gf: rel4 T0 T1 T2 T3 -> rel4 T0 T1 T2 T3) :=
forall r r'(LE: r <4= r'), gf r <4== gf r'.

Lemma monotone4_eq (gf: rel4 T0 T1 T2 T3 -> rel4 T0 T1 T2 T3) :
monotone4 gf <-> _monotone4 gf.