Section Arg1_def.
Variable T0 : Type.
Variable gf : rel1 T0 -> rel1 T0.
Arguments gf : clear implicits.
Inductive _paco (paco: rel1 T0 -> rel1 T0) ( r: rel1 T0) x0 : Prop :=
| paco_pfold pco
(LE : pco <1= (paco r \1/ r))
(SIM: gf pco x0)
.
CoInductive paco r x0 : Prop := paco_go { paco_observe: _paco paco r x0 }.
Definition upaco( r: rel1 T0) := paco r \1/ r.
End Arg1_def.
Arguments paco [ T0 ] gf r x0.
Arguments upaco [ T0 ] gf r x0.
Hint Unfold upaco : core.
(* Less than or equal - internal use only *)
Notation "p <_paco_1= q" :=
(forall _paco_x0 (PR: p _paco_x0 : Prop), q _paco_x0 : Prop)
(at level 50, no associativity).
(* coinduction automation - internal use only *)
Ltac paco_cofix_auto :=
let CIH := fresh "CIH" in cofix CIH; repeat intro;
match goal with [H: _ |- _] => apply paco_observe in H; destruct H as [] end; do 2 econstructor;
try (match goal with [H: _|-_] => apply H end); intros;
lazymatch goal with [PR: _ |- _] => match goal with [H: _ |- _] => apply H in PR end end;
repeat match goal with [ H : _ \/ _ |- _] => destruct H end; first [eauto; fail|eauto 10].
Definition monotone T0 (gf: rel1 T0 -> rel1 T0) :=
forall x0 r r' (IN: gf r x0) (LE: r <1= r'), gf r' x0.
Definition _monotone T0 (gf: rel1 T0 -> rel1 T0) :=
forall r r'(LE: r <1= r'), gf r <1== gf r'.

Lemma monotone_eq T0 (gf: rel1 T0 -> rel1 T0) :
monotone gf <-> _monotone gf.