Require Export RelDefinitions.
(** ** Union of relations *)
Definition rel_union {A B} (R1 R2: rel A B): rel A B :=
fun x y => R1 x y \/ R2 x y.
Arguments rel_union {_ _} R1%rel R2%rel _ _.
Infix "\/" := rel_union : rel_scope.
Global Instance rel_union_subrel {A B}:
Monotonic (@rel_union A B) (subrel ++> subrel ++> subrel).
Global Instance rel_union_subrel_params:
Params (@rel_union) 4.
Defined.
(** Since we're forced to commit to a branch, we can't use [RIntro], but can still provide [RExists] instances. *)
Hint Extern 0 (RExists _ (_ \/ _) _ _) =>
eapply rel_union_rexists_l : typeclass_instances.
Hint Extern 0 (RExists _ (_ \/ _) _ _) =>
eapply rel_union_rexists_r : typeclass_instances.
(** More often, we can solve a [rel_union] goal using a monotonicity property, and the [subrel] instances below. *)
Hint Extern 0 (RExists _ subrel _ (_ \/ _)%rel) =>
eapply rel_union_subrel_rexists_l : typeclass_instances.
Hint Extern 0 (RExists _ subrel _ (_ \/ _)%rel) =>
eapply rel_union_subrel_rexists_r : typeclass_instances.
Hint Extern 2 (RIntro _ subrel (_ \/ _)%rel _) =>
eapply rel_union_lub : typeclass_instances.
Hint Extern 1 (Reflexive (_ \/ _)) =>
eapply rel_union_refl_l : typeclass_instances.

Lemma rel_union_refl_r {A} (R1 R2: rel A A):
Reflexive R2 ->
Reflexive (R1 \/ R2).