------------------------------------------------------------------------
-- Operations on nullary relations (like negation and decidability)
------------------------------------------------------------------------

{-# OPTIONS --universe-polymorphism #-}

-- Some operations on/properties of nullary relations, i.e. sets.

module Relation.Nullary where

open import Data.Product
open import Level
import Relation.Nullary.Core as Core
open import Relation.Binary
open import Relation.Binary.FunctionSetoid
import Relation.Binary.EqReasoning as EqReasoning

------------------------------------------------------------------------
-- Negation

open Core public using (¬_)

------------------------------------------------------------------------
-- Equivalence

infix 3 _⇔_

_⇔_ :  {ℓ₁ ℓ₂}  Set ℓ₁  Set ℓ₂  Set (ℓ₁  ℓ₂)
P  Q = (P  Q) × (Q  P)

------------------------------------------------------------------------
-- Decidable relations

open Core public using (Dec; yes; no)

------------------------------------------------------------------------
-- Injections

Injective :  {a₁ a₂ b₁ b₂} {A : Setoid a₁ a₂} {B : Setoid b₁ b₂} 
            A  B  Set _
Injective {A = A} {B} f =  {x y}  f ⟨$⟩ x ≈₂ f ⟨$⟩ y  x ≈₁ y
  where
  open Setoid A renaming (_≈_ to _≈₁_)
  open Setoid B renaming (_≈_ to _≈₂_)

_LeftInverseOf_ :  {a₁ a₂ b₁ b₂} {A : Setoid a₁ a₂} {B : Setoid b₁ b₂} 
                  B  A  A  B  Set _
_LeftInverseOf_ {A = A} f g =  x  f ⟨$⟩ (g ⟨$⟩ x) ≈₁ x
  where open Setoid A renaming (_≈_ to _≈₁_)

record Injection {f₁ f₂ t₁ t₂}
                 (From : Setoid f₁ f₂) (To : Setoid t₁ t₂) :
                 Set (f₁  f₂  t₁  t₂) where
  field
    to        : From  To
    injective : Injective to

record LeftInverse {f₁ f₂ t₁ t₂}
                   (From : Setoid f₁ f₂) (To : Setoid t₁ t₂) :
                   Set (f₁  f₂  t₁  t₂) where
  field
    to           : From  To
    from         : To  From
    left-inverse : from LeftInverseOf to

  open Setoid      From
  open EqReasoning From

  injective : Injective to
  injective {x} {y} eq = begin
    x                    ≈⟨ sym (left-inverse x) 
    from ⟨$⟩ (to ⟨$⟩ x)  ≈⟨ cong from eq 
    from ⟨$⟩ (to ⟨$⟩ y)  ≈⟨ left-inverse y 
    y                    

  injection : Injection From To
  injection = record { to = to; injective = injective }