{-# OPTIONS --safe #-} module Cubical.HITs.FreeComMonoids.Properties where open import Cubical.Foundations.Prelude open import Cubical.Foundations.Function open import Cubical.Foundations.Isomorphism open import Cubical.Foundations.Equiv open import Cubical.Foundations.HLevels open import Cubical.Foundations.GroupoidLaws hiding (assoc) open import Cubical.Foundations.Univalence open import Cubical.Data.Nat hiding (_·_ ; _^_) open import Cubical.HITs.FreeComMonoids.Base as FCM open import Cubical.HITs.AssocList as AL private variable ℓ : Level A : Type ℓ multi-· : A → ℕ → FreeComMonoid A → FreeComMonoid A multi-· x zero xs = xs multi-· x (suc n) xs = ⟦ x ⟧ · multi-· x n xs _^_ : A → ℕ → FreeComMonoid A x ^ n = multi-· x n ε ^+≡ : ∀ (p : A) m n → ((p ^ m) · (p ^ n)) ≡ (p ^ (m + n)) ^+≡ p zero n = identityₗ _ ^+≡ p (suc m) n = sym (assoc _ _ _) ∙ cong (_ ·_) (^+≡ _ _ _) AL→FCM : AssocList A → FreeComMonoid A AL→FCM = AL.Rec.f trunc ε (λ a n p → (a ^ n) · p) per* agg* (const identityₗ) where per* : ∀ x y (mon : FreeComMonoid A) → ((⟦ x ⟧ · ε) · ((⟦ y ⟧ · ε) · mon)) ≡ ((⟦ y ⟧ · ε) · ((⟦ x ⟧ · ε) · mon)) per* x y mon = (⟦ x ⟧ · ε) · ((⟦ y ⟧ · ε) · mon) ≡⟨ assoc _ _ _ ⟩ ((⟦ x ⟧ · ε) · (⟦ y ⟧ · ε)) · mon ≡⟨ cong (_· mon) (comm _ _) ⟩ (((⟦ y ⟧ · ε) · (⟦ x ⟧ · ε)) · mon) ≡⟨ sym (assoc _ _ _) ⟩ ((⟦ y ⟧ · ε) · ((⟦ x ⟧ · ε) · mon)) ∎ agg* : ∀ a m n mon → ((a ^ m) · ((a ^ n) · mon)) ≡ ((a ^ (m + n)) · mon) agg* a m n mon = ((a ^ m) · ((a ^ n) · mon)) ≡⟨ assoc _ _ _ ⟩ (((a ^ m) · (a ^ n)) · mon) ≡⟨ cong (_· _) (^+≡ _ _ _) ⟩ ((a ^ (m + n)) · mon) ∎ FCM→AL : FreeComMonoid A → AssocList A FCM→AL = FCM.Rec.f trunc ⟨_⟩ ⟨⟩ _++_ comm-++ unitr-++ (λ _ → refl) assoc-++ ^-id : (x : A) (m : ℕ) (u : FreeComMonoid A) → FCM→AL ((x ^ m) · u) ≡ ⟨ x , m ⟩∷ FCM→AL u ^-id x zero u = cong FCM→AL (identityₗ u) ∙ sym (del _ _) ^-id x (suc m) u = FCM→AL ((⟦ x ⟧ · (x ^ m)) · u) ≡⟨ cong ⟨ x , 1 ⟩∷_ (^-id x m u) ⟩ ⟨ x , 1 ⟩∷ ⟨ x , m ⟩∷ FCM→AL u ≡⟨ agg _ _ _ _ ⟩ ⟨ x , suc m ⟩∷ FCM→AL u ∎ ++-· : (x y : AssocList A) → AL→FCM (x ++ y) ≡ AL→FCM x · AL→FCM y ++-· = AL.ElimProp.f (isPropΠ (λ _ → trunc _ _)) (λ _ → sym (identityₗ _)) λ x n {xs} p ys → AL→FCM (((⟨ x , n ⟩∷ ⟨⟩) ++ xs) ++ ys) ≡⟨ cong AL→FCM (cong (_++ ys) (comm-++ (⟨ x , n ⟩∷ ⟨⟩) xs) ∙ sym (assoc-++ xs _ ys)) ⟩ AL→FCM (xs ++ (⟨ x , n ⟩∷ ys)) ≡⟨ p _ ⟩ (AL→FCM xs · ((x ^ n) · AL→FCM ys)) ≡⟨ assoc (AL→FCM xs) _ _ ⟩ ((AL→FCM xs · (x ^ n)) · AL→FCM ys) ≡⟨ cong (_· AL→FCM ys) (comm _ _) ⟩ ((x ^ n) · AL→FCM xs) · AL→FCM ys ∎ AL→FCM∘FCM→AL≡id : section {A = AssocList A} AL→FCM FCM→AL AL→FCM∘FCM→AL≡id = FCM.ElimProp.f (trunc _ _) (λ x → identityᵣ _ ∙ identityᵣ _) refl λ {x y} p q → ++-· (FCM→AL x) (FCM→AL y) ∙ cong₂ _·_ p q FCM→AL∘AL→FCM≡id : retract {A = AssocList A} AL→FCM FCM→AL FCM→AL∘AL→FCM≡id = AL.ElimProp.f (trunc _ _) refl λ x n {xs} p → ^-id x n (AL→FCM xs) ∙ cong (⟨ _ , _ ⟩∷_) p AssocList≃FreeComMonoid : AssocList A ≃ FreeComMonoid A AssocList≃FreeComMonoid = isoToEquiv (iso AL→FCM FCM→AL AL→FCM∘FCM→AL≡id FCM→AL∘AL→FCM≡id) AssocList≡FreeComMonoid : AssocList A ≡ FreeComMonoid A AssocList≡FreeComMonoid = ua AssocList≃FreeComMonoid