Section eqit_h.
Context {E : Type -> Type} {R1 R2 : Type} (RR : R1 -> R2 -> Prop).
(** [eqit] is a congruence for [itree] constructors. *)
(** *** "Up-to" principles for coinduction. *)
Inductive eqit_bind_clo b1 b2 (r : itree E R1 -> itree E R2 -> Prop) :
itree E R1 -> itree E R2 -> Prop :=
| pbc_intro_h U1 U2 (RU : U1 -> U2 -> Prop) t1 t2 k1 k2
(EQV: eqit RU b1 b2 t1 t2)
(REL: forall u1 u2, RU u1 u2 -> r (k1 u1) (k2 u2))
: eqit_bind_clo b1 b2 r (ITree.bind t1 k1) (ITree.bind t2 k2)
.
Hint Constructors eqit_bind_clo.
End eqit_h.
Arguments eqit_clo_bind : clear implicits.
Hint Constructors eqit_bind_clo.
Global Instance eqit_bind {E R S} b1 b2 :
Proper (pointwise_relation _ (eqit eq b1 b2) ==>
eqit eq b1 b2 ==>
eqit eq b1 b2) (@ITree.bind' E R S).
Global Instance eqit_bind_ {E R S} b1 b2 k :
Proper (going (eqit eq b1 b2) ==>
eqit eq b1 b2) (@ITree._bind E R S k (@ITree.bind' E R S k)).

Lemma eqit_map {E R1 R2 S1 S2} (RR : R1 -> R2 -> Prop) b1 b2
(RS : S1 -> S2 -> Prop)
f1 f2 t1 t2 :
(forall r1 r2, RR r1 r2 -> RS (f1 r1) (f2 r2)) ->
@eqit E _ _ RR b1 b2 t1 t2 ->
eqit RS b1 b2 (ITree.map f1 t1) (ITree.map f2 t2).