{-# OPTIONS --without-K --safe #-}
module Util.Relation.Binary.LogicalEquivalence where

open import Relation.Binary using (IsEquivalence ; Setoid)

open import Util.Prelude


private
  variable
    α β γ : Level
    A B C : Set α


infix 4 _↔_


record _↔_ (A : Set α) (B : Set β) : Set (α ⊔ℓ β) where
  field
    forth : A  B
    back : B  A

open _↔_ public


↔-refl : A  A
↔-refl .forth = id
↔-refl .back = id


↔-reflexive : A  B  A  B
↔-reflexive refl = ↔-refl


↔-sym : A  B  B  A
↔-sym A↔B .forth = A↔B .back
↔-sym A↔B .back = A↔B .forth


↔-trans : A  B  B  C  A  C
↔-trans A↔B B↔C .forth = B↔C .forth  A↔B .forth
↔-trans A↔B B↔C .back = A↔B .back  B↔C .back


↔-isEquivalence : IsEquivalence (_↔_ {α})
↔-isEquivalence = record
  { refl = ↔-refl
  ; sym = ↔-sym
  ; trans = ↔-trans
  }


↔-setoid :  α  Setoid (lsuc α) α
↔-setoid α .Setoid.Carrier = Set α
↔-setoid α .Setoid._≈_ = _↔_
↔-setoid α .Setoid.isEquivalence = ↔-isEquivalence