{-# OPTIONS --safe #-}
open import Prelude hiding (_↔_)
module Data.Permutation.NonNorm {A : Type a} (_≟_ : Discrete A) where
open import Data.Permutation.Swap _≟_
open import Data.List hiding ([]; _∷_)
import Data.List as ConsR
Swaps : Type a
Swaps = List (A × A)
infixl 5 _∘⟨_⟩
pattern _∘⟨_⟩ xs x = x ConsR.∷ xs
pattern ⟨⟩ = ConsR.[]
infixr 4.5 _·_
_·_ : Swaps → A → A
_·_ = flip (foldl (flip (uncurry _↔_·_)))
swap-inj : ∀ x y z₁ z₂ → x ↔ y · z₁ ≡ x ↔ y · z₂ → z₁ ≡ z₂
swap-inj x y z₁ z₂ p with does (x ≟ z₁)
| why (x ≟ z₁)
| does (x ≟ z₂)
| why (x ≟ z₂)
| does (y ≟ z₁)
| why (y ≟ z₁)
| does (y ≟ z₂)
| why (y ≟ z₂)
... | true | x≡z₁ | true | x≡z₂ | _ | _ | _ | _ = sym x≡z₁ ; x≡z₂
... | _ | _ | _ | _ | true | y≡z₁ | true | y≡z₂ = sym y≡z₁ ; y≡z₂
... | false | _ | false | _ | false | _ | false | _ = p
... | false | x≢z₁ | false | _ | false | _ | true | _ = ⊥-elim (x≢z₁ (sym p))
... | false | _ | false | x≢z₂ | true | _ | false | _ = ⊥-elim (x≢z₂ p)
... | false | _ | true | _ | false | y≢z₁ | _ | _ = ⊥-elim (y≢z₁ (sym p))
... | false | x≢z₁ | true | _ | true | y≡z₁ | _ | _ = ⊥-elim (x≢z₁ (p ; y≡z₁))
... | true | _ | false | x≢z₁ | true | _ | false | y≢z₂ = ⊥-elim (y≢z₂ p)
... | true | _ | false | _ | false | _ | false | y≢z₂ = ⊥-elim (y≢z₂ p)
... | true | x≡z₁ | false | x≢z₂ | false | y≢z₁ | true | y≡z₂ = ⊥-elim (y≢z₁ (p ; x≡z₁))
perm-inj : ∀ xs z₁ z₂ → xs · z₁ ≡ xs · z₂ → z₁ ≡ z₂
perm-inj ⟨⟩ z₁ z₂ p = p
perm-inj (xs ∘⟨ x , y ⟩) z₁ z₂ p =
swap-inj x y z₁ z₂ (perm-inj xs (x ↔ y · z₁) (x ↔ y · z₂) p)
infixl 6 _∙_
_∙_ : Swaps → Swaps → Swaps
xs ∙ ys = ys ++ xs
open import Path.Reasoning
open import Data.List.Properties
∙-· : ∀ xs ys n → xs ∙ ys · n ≡ xs · ys · n
∙-· xs ys n = foldl-++ (flip (uncurry _↔_·_)) n ys xs
neg : Swaps → Swaps
neg = reverse
open import Path.Reasoning
neg-id-lemma : ∀ xs n → foldl (flip (uncurry _↔_·_)) (foldr (uncurry _↔_·_) n xs) xs ≡ n
neg-id-lemma ⟨⟩ n = refl
neg-id-lemma (xs ∘⟨ x , y ⟩) n =
foldl (flip (uncurry _↔_·_)) (x ↔ y · x ↔ y · foldr (uncurry _↔_·_) n xs) xs ≡⟨ cong (flip (foldl (flip (uncurry _↔_·_))) xs) (swap-dup x y (foldr (uncurry _↔_·_) n xs)) ⟩
foldl (flip (uncurry _↔_·_)) (foldr (uncurry _↔_·_) n xs) xs ≡⟨ neg-id-lemma xs n ⟩
n ∎
neg-id-lemma₂ : ∀ xs n → foldl (flip (uncurry _↔_·_)) n (foldl _∘⟨_⟩ ⟨⟩ xs) ≡ foldr (uncurry _↔_·_) n xs
neg-id-lemma₂ xs n =
foldl (flip (uncurry _↔_·_)) n (reverse xs) ≡˘⟨ foldr-reverse _ _ (reverse xs) ⟩
foldr (uncurry _↔_·_) n (reverse (reverse xs)) ≡⟨ cong (foldr (uncurry _↔_·_) n) (reverse-reverse xs) ⟩
foldr (uncurry _↔_·_) n xs ∎
neg-id : ∀ xs n → xs ∙ neg xs · n ≡ n
neg-id xs n =
xs ∙ neg xs · n ≡⟨⟩
neg xs ++ xs · n ≡⟨ foldl-++ (flip (uncurry _↔_·_)) n (neg xs) xs ⟩
foldl (flip (uncurry _↔_·_)) (neg xs · n) xs ≡⟨⟩
foldl (flip (uncurry _↔_·_)) (foldl (flip (uncurry _↔_·_)) n (neg xs)) xs ≡⟨⟩
foldl (flip (uncurry _↔_·_)) (foldl (flip (uncurry _↔_·_)) n (foldl _∘⟨_⟩ ⟨⟩ xs)) xs
≡⟨ cong (flip (foldl (flip (uncurry _↔_·_))) xs) (neg-id-lemma₂ xs n) ⟩
foldl (flip (uncurry _↔_·_)) (foldr (uncurry _↔_·_) n xs) xs
≡⟨ neg-id-lemma xs n ⟩
n ∎
∙-assoc : ∀ xs ys zs → (xs ∙ ys) ∙ zs ≡ xs ∙ (ys ∙ zs)
∙-assoc xs ys zs = sym (++-assoc zs ys xs)