{-# OPTIONS --safe #-}
open import Prelude
module Swaps {A : Type a} ⦃ _ : IsDiscrete A ⦄ where
_/→_ : A → A → A → A
(x /→ y) z =
if does (z ≟ x)
then y
else z
_/↔_ : A → A → A → A
(x /↔ y) z =
if does (z ≟ x)
then y
else
if does (z ≟ y)
then x
else z
swap-inv : ∀ x y z → (x /↔ y) ((y /↔ x) z) ≡ z
swap-inv x y z with z ≟ y | z ≟ x
... | yes z≡y | _ = cong (bool′ _ _) (it-does (x ≟ x) refl) ⨾ sym z≡y
... | no z≢y | no z≢x = cong (bool′ _ _) (it-doesn't (z ≟ x) z≢x) ⨾ cong (bool′ _ _) (it-doesn't (z ≟ y) z≢y)
... | no z≢y | yes z≡x = cong (bool′ _ _) (it-doesn't (y ≟ x) (z≢y ∘ (z≡x ⨾_) ∘ sym)) ⨾ cong (bool′ _ _) (it-does (y ≟ y) refl) ⨾ sym z≡x
_/͍_ : A → A → A ⟷ A
(x /͍ y) .fst = x /↔ y
(x /͍ y) .snd = y /↔ x
_/⇔_ : A → A → A ⇔ A
(x /⇔ y) .fun = x /↔ y
(x /⇔ y) .inv = y /↔ x
(x /⇔ y) .rightInv = swap-inv x y
(x /⇔ y) .leftInv = swap-inv y x
swap-leq : ∀ x y → (x /↔ y) x ≡ y
swap-leq x y = cong (bool′ _ _) (it-does (x ≟ x) refl)
swap-req : ∀ x y → (x /↔ y) y ≡ x
swap-req x y with y ≟ x
... | yes y≡x = y≡x
... | no y≢x = cong (bool′ _ _) (it-does (y ≟ y) refl)
swap-neq : ∀ x y z → x ≢ z → y ≢ z → (x /↔ y) z ≡ z
swap-neq x y z x≢z y≢z = cong (bool′ _ _) (it-doesn't (z ≟ x) (x≢z ∘ sym)) ⨾ cong (bool z x) (it-doesn't (z ≟ y) (y≢z ∘ sym))