(** * Tests *)

(** ** Reflexivity *)

Goal
  forall A (a: A), a = a.Goal
  forall A (a: A), exists b, b = a.(** ** Setoid rewriting *)

Goal
  forall A (a b: A) `(HR: Equivalence A) (H: R a b),
    sum_rel R R (inl a) (inl b).(** ** Monotonicity tactics *)

(** Basic sanity check. This has actually failed in the past due to
  [context_candidate] being too liberal and selecting the [RB]
  property instead of [RA], then going nowhere with that with no
  backtracking implemented yet. *)

Goal
  forall A B (RA: rel A A) (x y: A) (RB: rel B B) (z t: B),
    RA x y ->
    RB z t ->
    RA x y.Goal
  forall {A B} (RA: rel A A) (RB: rel B B) (x y: A * B) (z: A),
    RA z z ->
    prod_rel RA RB x y ->
    RA (let (a, b) := x in z)
       (let (a, b) := y in z).Goal
  forall {A} (R : rel A A) (b : bool) (x y : A),
    b = b ->
    R x x ->
    R y y ->
    R (if b then x else y)
      (if b then x else y).(** *** Hypotheses from the context *)

(* This used to fail because [Hyy] would
  shadow [Hxy] (the hypothesis we want). *)

Goal
  forall {A} (R: rel A A) (x y: A),
    R x y -> eq y y -> R x y.(* This still fail with Coq 8.5, but Coq 8.6 is able to backtrack and
  try hypothesis from the context beyond the first one it finds. *)

Goal
  forall {A} (R: rel A A) (x y: A),
    R x y -> eq x y -> R x y.(** *** Generic rules *)

(** The [coreflexivity] of [rel_prod] and [eq] makes it possible for
  [pair_rel] to behave in the same way as [f_equal] below, since they
  allow us to deduce that [eq * eq] is a [subrel] of [eq]. *)

Goal
  forall A B (x1 x2 : A) (y1 y2 : B),
    x1 = x2 -> y1 = y2 -> (x1, y1) = (x2, y2).(** ** The [rgraph] tactic *)

Goal
  forall {A} (R S T: rel A A),
    subrel R S ->
    subrel S R ->
    subrel S T ->
    subrel R T.Goal
  forall `(PER) (x y z t : A),
    R x y ->
    R z y ->
    R z t ->
    R t x.(** ** Tests for specific relators *)

(** *** [list_rel] *)

(** [list_subrel] use to not work because of a missing [Params] declaration. *)

Goal
  forall A B (R R': rel A B) l1 l2 x y,
    subrel R R' ->
    list_rel R l1 l2 ->
    R' x y ->
    list_rel R' (x :: l1) (y :: l2).

Lemma rel_ex_1: forall {A} (x: A), (rexists a, req a) x x.