{-# OPTIONS --safe #-} module Data.Permutation.Normalised.Group 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.Permutation.Normalised.RoundTrip open import Data.Permutation.Normalised.Injective open import Path.Reasoning ⊕-from : Diffs → Diffs → ℕ → Diffs ⊕-from xs ys n = foldr (flip _⊙⟨_⟩) xs (un-diff ys n) infixl 6 _⊕_ _⊕_ : Diffs → Diffs → Diffs xs ⊕ ys = ⊕-from xs ys 0 diffs-comp-lemma : ∀ xs ys m n → foldr (flip _⊙⟨_⟩) xs (un-diff ys m) ⊙ n ≡ xs ⊙ (ys ⊙+ m ⊙ n) diffs-comp-lemma xs ⟨⟩ m n = refl diffs-comp-lemma xs (ys ∘⟨ x , y ⟩) m n = ⊕-from xs (ys ∘⟨ x , y ⟩) m ⊙ n ≡⟨⟩ ⊕-from xs ys (suc m + x) ⊙⟨ m + x , y ⟩ ⊙ n ≡⟨ cons-swap (m + x) y (⊕-from xs ys (suc m + x)) n ⟩ ⊕-from xs ys (suc m + x) ⊙ m + x ↔ y ⊙ n ≡⟨ diffs-comp-lemma xs ys (suc m + x) _ ⟩ (xs ⊙ ys ⊙+ suc m + x ⊙ m + x ↔ y ⊙ n) ≡˘⟨ cong (xs ⊙_) (⊙-alg-com (m + x) y ys n ) ⟩ (xs ⊙ ys ∘⟨ m + x , y ⟩ ⊙ n) ≡⟨⟩ (xs ⊙ ys ∘⟨ x , y ⟩ ⊙+ m ⊙ n) ∎ diffs-comp : ∀ xs ys n → (xs ⊕ ys) ⊙ n ≡ xs ⊙ (ys ⊙ n) diffs-comp xs ys n = xs ⊕ ys ⊙ n ≡⟨ diffs-comp-lemma xs ys 0 n ⟩ xs ⊙ (ys ⊙+ 0 ⊙ n) ≡⟨ cong (λ e → xs ⊙ e ⊙ n) (shift-0 ys) ⟩ xs ⊙ ys ⊙ n ∎ ⊕-hom : ∀ xs ys → [ xs ∙ ys ]↓ ≡ [ xs ]↓ ⊕ [ ys ]↓ ⊕-hom xs ys = inj-⊙ [ xs ∙ ys ]↓ ([ xs ]↓ ⊕ [ ys ]↓) λ n → [ xs ∙ ys ]↓ ⊙ n ≡⟨ ⊙↓-hom (xs ∙ ys) n ⟩ xs ∙ ys · n ≡⟨ ∙-· xs ys n ⟩ xs · ys · n ≡˘⟨ ⊙↓-hom xs (ys · n) ⟩ [ xs ]↓ ⊙ ys · n ≡˘⟨ cong ([ xs ]↓ ⊙_) (⊙↓-hom ys n) ⟩ [ xs ]↓ ⊙ [ ys ]↓ ⊙ n ≡˘⟨ diffs-comp [ xs ]↓ [ ys ]↓ n ⟩ [ xs ]↓ ⊕ [ ys ]↓ ⊙ n ∎ ⊕-assoc : ∀ xs ys zs → (xs ⊕ ys) ⊕ zs ≡ xs ⊕ (ys ⊕ zs) ⊕-assoc xs ys zs = (xs ⊕ ys) ⊕ zs ≡˘⟨ cong₃ (λ x y z → (x ⊕ y) ⊕ z) (norm-inv xs) (norm-inv ys) (norm-inv zs) ⟩ ([ [ xs ]↑ ]↓ ⊕ [ [ ys ]↑ ]↓) ⊕ [ [ zs ]↑ ]↓ ≡˘⟨ cong (_⊕ [ [ zs ]↑ ]↓) (⊕-hom [ xs ]↑ [ ys ]↑) ⟩ [ [ xs ]↑ ∙ [ ys ]↑ ]↓ ⊕ [ [ zs ]↑ ]↓ ≡˘⟨ ⊕-hom ([ xs ]↑ ∙ [ ys ]↑) [ zs ]↑ ⟩ [ ([ xs ]↑ ∙ [ ys ]↑) ∙ [ zs ]↑ ]↓ ≡⟨ cong [_]↓ (∙-assoc [ xs ]↑ [ ys ]↑ [ zs ]↑) ⟩ [ [ xs ]↑ ∙ ([ ys ]↑ ∙ [ zs ]↑) ]↓ ≡⟨ ⊕-hom [ xs ]↑ ([ ys ]↑ ∙ [ zs ]↑) ⟩ [ [ xs ]↑ ]↓ ⊕ ([ [ ys ]↑ ∙ [ zs ]↑ ]↓) ≡⟨ cong ([ [ xs ]↑ ]↓ ⊕_) (⊕-hom [ ys ]↑ [ zs ]↑) ⟩ [ [ xs ]↑ ]↓ ⊕ ([ [ ys ]↑ ]↓ ⊕ [ [ zs ]↑ ]↓) ≡⟨ cong₃ (λ x y z → x ⊕ (y ⊕ z)) (norm-inv xs) (norm-inv ys) (norm-inv zs) ⟩ xs ⊕ (ys ⊕ zs) ∎ negate : Diffs → Diffs negate xs = [ neg [ xs ]↑ ]↓ neg-inv-d : ∀ xs → xs ⊕ negate xs ≡ ⟨⟩ neg-inv-d xs = inj-⊙ _ _ λ n → xs ⊕ negate xs ⊙ n ≡⟨⟩ xs ⊕ [ neg [ xs ]↑ ]↓ ⊙ n ≡˘⟨ cong (λ e → e ⊕ [ neg [ xs ]↑ ]↓ ⊙ n) (norm-inv xs) ⟩ [ [ xs ]↑ ]↓ ⊕ [ neg [ xs ]↑ ]↓ ⊙ n ≡˘⟨ cong (_⊙ n) (⊕-hom [ xs ]↑ (neg [ xs ]↑)) ⟩ [ [ xs ]↑ ∙ neg [ xs ]↑ ]↓ ⊙ n ≡⟨ ⊙↓-hom ([ xs ]↑ ∙ neg [ xs ]↑) n ⟩ [ xs ]↑ ∙ neg [ xs ]↑ · n ≡⟨ neg-id [ xs ]↑ n ⟩ ⟨⟩ ⊙ n ∎