{-# OPTIONS --safe #-} module Data.Permutation.Normalised.RoundTrip where open import Prelude hiding (_↔_) open import Data.List hiding ([]; _∷_) open import Data.Nat.Properties renaming (discreteℕ to infix 4 _≟_) open import Data.Permutation.Swap _≟_ open import Data.Permutation.NonNorm _≟_ open import Data.Nat using (_+_) open import Data.Permutation.Normalised.Definition open import Data.List.Properties open import Data.Permutation.Normalised.Unnorm open import Data.Permutation.Normalised.Norm open import Data.Nat.Compare open import Path.Reasoning open import Data.Maybe unf-coalg : ℕ → ℕ → (ℕ → Diffs) → ℕ → Diffs unf-coalg x y k n = k (suc n + x) ∘⟨ n + x , y ⟩ un-diff : Diffs → ℕ → Diffs un-diff = foldr (uncurry unf-coalg) (const ⟨⟩) compare-diff-+ : ∀ x y → compare x (suc x + y) ≡ less y compare-diff-+ zero y = refl compare-diff-+ (suc x) y = compare-diff-+ x y norm-lemma₁ : ∀ xs x y → xs ⊙+ suc x ⊙⟨ x , y ⟩ ≡ xs ∘⟨ x , y ⟩ norm-lemma₁ ⟨⟩ x y = refl norm-lemma₁ (xs ∘⟨ s , t ⟩) x y with compare x (suc x + s) | comparing x (suc x + s) ... | less k | sx+k≡sx+s = cong (λ e → xs ∘⟨ e , t ⟩ ∘⟨ x , y ⟩) (+-inj (suc x) sx+k≡sx+s) ... | equal | x≡sx+s = ⊥-elim (x≢sx+y x s x≡sx+s) ... | greater k | p = ⊥-elim (x≢sx+y x (suc s + k) (sym p ; cong suc (cong suc (+-assoc x s k) ; sym (+-suc x (s + k))))) norm-lemma : ∀ xs n → foldr (flip _⊙⟨_⟩) ⟨⟩ (un-diff xs n) ≡ xs ⊙+ n norm-lemma ⟨⟩ n = refl norm-lemma (xs ∘⟨ x , y ⟩) n = foldr (flip _⊙⟨_⟩) ⟨⟩ (un-diff (xs ∘⟨ x , y ⟩) n) ≡⟨⟩ foldr (flip _⊙⟨_⟩) ⟨⟩ (un-diff xs (suc n + x) ∘⟨ n + x , y ⟩) ≡⟨⟩ foldr (flip _⊙⟨_⟩) ⟨⟩ (un-diff xs (suc n + x)) ⊙⟨ n + x , y ⟩ ≡⟨ cong (_⊙⟨ n + x , y ⟩) (norm-lemma xs (suc n + x)) ⟩ xs ⊙+ suc n + x ⊙⟨ n + x , y ⟩ ≡⟨ norm-lemma₁ xs (n + x) y ⟩ xs ∘⟨ n + x , y ⟩ ∎ norm-inv : ∀ xs → [ [ xs ]↑ ]↓ ≡ xs norm-inv xs = [ [ xs ]↑ ]↓ ≡⟨⟩ [ foldr (uncurry unflatten-alg) (const ⟨⟩) xs 0 ]↓ ≡⟨⟩ foldr (flip _⊙⟨_⟩) ⟨⟩ (catMaybes (uncurry swap-diff) (foldr (uncurry unflatten-alg) (const ⟨⟩) xs 0)) ≡⟨ cong′ {A = ℕ → Swaps} (λ k → foldr (flip _⊙⟨_⟩) ⟨⟩ (k 0)) (foldr-fusion (λ xs n → catMaybes (uncurry swap-diff) (xs n)) (const ⟨⟩) (λ { (x , y) k → funExt λ n → cong (maybe _ _) (cong (mapMaybe (map₁ (bool′ (n + x) _))) (compare-diff-+ (n + x) y)) }) xs) ⟩ foldr (flip _⊙⟨_⟩) ⟨⟩ (un-diff xs 0) ≡⟨ norm-lemma xs 0 ⟩ xs ⊙+ 0 ≡⟨ shift-0 xs ⟩ xs ∎