{-# OPTIONS --safe #-}
open import Prelude hiding (_↔_)
module Data.Permutation.Swap (_≟_ : Discrete A) where
infixr 4.5 _↔_·_
_↔_·_ : A → A → A → A
x ↔ y · z =
if does (x ≟ z) then y else
if does (y ≟ z) then x else
z
swap-lhs : ∀ x y → x ↔ y · x ≡ y
swap-lhs x y = cong (bool′ _ _) (it-does (x ≟ x) refl)
swap-rhs : ∀ x y → x ↔ y · y ≡ x
swap-rhs x y with does (x ≟ y) | why (x ≟ y)
... | true | x≡y = sym x≡y
... | false | _ = cong (bool′ _ _) (it-does (y ≟ y) refl)
swap-id : ∀ x y → x ↔ x · y ≡ y
swap-id x y with does (x ≟ y) | why (x ≟ y)
... | false | _ = refl
... | true | x≡y = x≡y
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 (x ≟ z) x≢z) ; cong (bool′ _ _) (it-doesn't (y ≟ z) y≢z)
swap-com : ∀ x y z → x ↔ y · z ≡ y ↔ x · z
swap-com x y z with does (x ≟ z) | why (x ≟ z) | does (y ≟ z) | why (y ≟ z)
... | false | _ | false | _ = refl
... | false | _ | true | _ = refl
... | true | _ | false | _ = refl
... | true | x≡z | true | y≡z = y≡z ; sym x≡z
swap-dup : ∀ x y z → x ↔ y · x ↔ y · z ≡ z
swap-dup x y z with does (x ≟ z) | why (x ≟ z) | does (y ≟ z) | why (y ≟ z)
... | false | x≢z | false | y≢z = cong (bool′ _ _) (it-doesn't (x ≟ z) x≢z) ; cong (bool′ _ _) (it-doesn't (y ≟ z) y≢z)
... | true | x≡z | true | y≡z = cong (bool′ _ _) (it-does (x ≟ y) (x≡z ; sym y≡z)) ; y≡z
... | true | x≡z | false | y≢z = cong (bool′ _ _) (it-doesn't (x ≟ y) (y≢z ∘ sym ∘ (sym x≡z ;_))) ; cong (bool′ _ _) (it-does (y ≟ y) refl) ; x≡z
... | false | x≢z | true | y≡z = cong (bool′ _ _) (it-does (x ≟ x) refl) ; y≡z
open import Function.Injective
swap-cong : (f : A ↣ A) (x y z : A)
→ fst f x ↔ fst f y · fst f z ≡ fst f (x ↔ y · z)
swap-cong (f , f-inj) x y z with does (f x ≟ f z) | why (f x ≟ f z) | does (x ≟ z) | why (x ≟ z) | does (f y ≟ f z) | why (f y ≟ f z) | does (y ≟ z) | why (y ≟ z)
... | true | fx≡fz | false | x≢z | _ | _ | _ | _ = ⊥-elim (x≢z (f-inj x z fx≡fz))
... | _ | _ | _ | _ | true | fy≡fz | false | y≢z = ⊥-elim (y≢z (f-inj y z fy≡fz))
... | _ | _ | _ | _ | false | fy≢fz | true | y≡z = ⊥-elim (fy≢fz (cong f y≡z))
... | false | fx≢fz | true | x≡z | _ | _ | _ | _ = ⊥-elim (fx≢fz (cong f x≡z))
... | true | _ | true | _ | _ | _ | _ | _ = refl
... | false | _ | false | _ | false | _ | false | _ = refl
... | false | _ | false | _ | true | _ | true | _ = refl