module Relation.Binary.Core where
open import Data.Product
open import Data.Sum
open import Data.Function
open import Relation.Nullary.Core
Rel : Set → Set₁
Rel a = a → a → Set
infixr 4 _⇒_ _=[_]⇒_
_⇒_ : ∀ {a} → Rel a → Rel a → Set
P ⇒ Q = ∀ {i j} → P i j → Q i j
_=[_]⇒_ : ∀ {a b} → Rel a → (a → b) → Rel b → Set
P =[ f ]⇒ Q = P ⇒ (Q on₁ f)
_Preserves_⟶_ : ∀ {a₁ a₂} → (a₁ → a₂) → Rel a₁ → Rel a₂ → Set
f Preserves P ⟶ Q = P =[ f ]⇒ Q
_Preserves₂_⟶_⟶_ : ∀ {a₁ a₂ a₃} →
                   (a₁ → a₂ → a₃) → Rel a₁ → Rel a₂ → Rel a₃ → Set
_+_ Preserves₂ P ⟶ Q ⟶ R =
  ∀ {x y u v} → P x y → Q u v → R (x + u) (y + v)
Reflexive : {a : Set} → (_∼_ : Rel a) → Set
Reflexive _∼_ = ∀ {x} → x ∼ x
Irreflexive : {a : Set} → (_≈_ _<_ : Rel a) → Set
Irreflexive _≈_ _<_ = ∀ {x y} → x ≈ y → ¬ (x < y)
Sym : ∀ {a} → Rel a → Rel a → Set
Sym P Q = P ⇒ flip₁ Q
Symmetric : {a : Set} → Rel a → Set
Symmetric _∼_ = Sym _∼_ _∼_
Trans : ∀ {a} → Rel a → Rel a → Rel a → Set
Trans P Q R = ∀ {i j k} → P i j → Q j k → R i k
Transitive : {a : Set} → Rel a → Set
Transitive _∼_ = Trans _∼_ _∼_ _∼_
Antisymmetric : {a : Set} → (_≈_ _≤_ : Rel a) → Set
Antisymmetric _≈_ _≤_ = ∀ {x y} → x ≤ y → y ≤ x → x ≈ y
Asymmetric : {a : Set} → (_<_ : Rel a) → Set
Asymmetric _<_ = ∀ {x y} → x < y → ¬ (y < x)
_Respects_ : {a : Set} → (a → Set) → Rel a → Set
P Respects _∼_ = ∀ {x y} → x ∼ y → P x → P y
_Respects₂_ : {a : Set} → Rel a → Rel a → Set
P Respects₂ _∼_ =
  (∀ {x} → P x       Respects _∼_) ×
  (∀ {y} → flip₁ P y Respects _∼_)
Substitutive : {a : Set} → Rel a → Set₁
Substitutive _∼_ = ∀ P → P Respects _∼_
Congruential : ({a : Set} → Rel a) → Set₁
Congruential ∼ = ∀ {a b} → (f : a → b) → f Preserves ∼ ⟶ ∼
Congruential₂ : ({a : Set} → Rel a) → Set₁
Congruential₂ ∼ =
  ∀ {a b c} → (f : a → b → c) → f Preserves₂ ∼ ⟶ ∼ ⟶ ∼
Decidable : {a : Set} → Rel a → Set
Decidable _∼_ = ∀ x y → Dec (x ∼ y)
Total : {a : Set} → Rel a → Set
Total _∼_ = ∀ x y → (x ∼ y) ⊎ (y ∼ x)
data Tri (A B C : Set) : Set where
  tri< : ( a :   A) (¬b : ¬ B) (¬c : ¬ C) → Tri A B C
  tri≈ : (¬a : ¬ A) ( b :   B) (¬c : ¬ C) → Tri A B C
  tri> : (¬a : ¬ A) (¬b : ¬ B) ( c :   C) → Tri A B C
Trichotomous : {a : Set} → Rel a → Rel a → Set
Trichotomous _≈_ _<_ = ∀ x y → Tri (x < y) (x ≈ y) (x > y)
  where _>_ = flip₁ _<_
record NonEmpty {I : Set} (T : Rel I) : Set where
  field
    i     : I
    j     : I
    proof : T i j
nonEmpty : ∀ {I} {T : Rel I} {i j} → T i j → NonEmpty T
nonEmpty p = record { i = _; j = _; proof = p }
private
 module Dummy where
  infix 4 _≡_ _≢_
  data _≡_ {a : Set} (x : a) : a → Set where
    refl : x ≡ x
  
  _≢_ : {a : Set} → a → a → Set
  x ≢ y = ¬ x ≡ y
record IsEquivalence {a : Set} (_≈_ : Rel a) : Set where
  field
    refl  : Reflexive _≈_
    sym   : Symmetric _≈_
    trans : Transitive _≈_
  reflexive : Dummy._≡_ ⇒ _≈_
  reflexive Dummy.refl = refl
open Dummy public