{-# OPTIONS --without-K --exact-split --safe #-} module Fragment.Extensions.CSemigroup.Monomial where open import Fragment.Equational.Theory.Bundles open import Fragment.Algebra.Signature open import Fragment.Algebra.Free Σ-magma hiding (_~_) open import Fragment.Algebra.Homomorphism Σ-magma open import Fragment.Algebra.Algebra Σ-magma using (Algebra; IsAlgebra; Interpretation; Congruence) open import Fragment.Equational.Model Θ-csemigroup open import Fragment.Setoid.Morphism using (_↝_) open import Fragment.Extensions.CSemigroup.Nat open import Data.Nat using (ℕ; zero; suc; _≟_) open import Data.Fin using (Fin; #_; zero; suc; toℕ; fromℕ) open import Data.Vec using (Vec; []; _∷_) open import Data.Vec.Relation.Binary.Pointwise.Inductive using ([]; _∷_) open import Relation.Nullary using (yes ; no) open import Relation.Binary.PropositionalEquality as PE using (_≡_) open import Relation.Binary using (Setoid; IsEquivalence) import Relation.Binary.Reasoning.Setoid as Reasoning data Monomial : ℕ → Set where leaf : ∀ {n} → ℕ⁺ → Monomial (suc n) skip : ∀ {n} → Monomial n → Monomial (suc n) cons : ∀ {n} → ℕ⁺ → Monomial n → Monomial (suc n) lift : ∀ {n} → Monomial n → Monomial (suc n) lift (leaf x) = leaf x lift (skip x) = skip (lift x) lift (cons x xs) = cons x (lift xs) _⊗_ : ∀ {n} → Monomial n → Monomial n → Monomial n leaf x ⊗ leaf y = leaf (x + y) leaf x ⊗ skip y = cons x y leaf x ⊗ cons y ys = cons (x + y) ys skip x ⊗ leaf y = cons y x skip x ⊗ skip y = skip (x ⊗ y) skip x ⊗ cons y ys = cons y (x ⊗ ys) cons x xs ⊗ leaf y = cons (x + y) xs cons x xs ⊗ skip y = cons x (xs ⊗ y) cons x xs ⊗ cons y ys = cons (x + y) (xs ⊗ ys) ⊗-cong : ∀ {n} {x y z w : Monomial n} → x ≡ y → z ≡ w → x ⊗ z ≡ y ⊗ w ⊗-cong = PE.cong₂ _⊗_ ⊗-comm : ∀ {n} (x y : Monomial n) → x ⊗ y ≡ y ⊗ x ⊗-comm (leaf x) (leaf y) = PE.cong leaf (+-comm x y) ⊗-comm (leaf x) (skip y) = PE.refl ⊗-comm (leaf x) (cons y ys) = PE.cong₂ cons (+-comm x y) PE.refl ⊗-comm (skip x) (leaf y) = PE.refl ⊗-comm (skip x) (skip y) = PE.cong skip (⊗-comm x y) ⊗-comm (skip x) (cons y ys) = PE.cong (cons y) (⊗-comm x ys) ⊗-comm (cons x xs) (leaf y) = PE.cong₂ cons (+-comm x y) PE.refl ⊗-comm (cons x xs) (skip y) = PE.cong (cons x) (⊗-comm xs y) ⊗-comm (cons x xs) (cons y ys) = PE.cong₂ cons (+-comm x y) (⊗-comm xs ys) ⊗-assoc : ∀ {n} (x y z : Monomial n) → (x ⊗ y) ⊗ z ≡ x ⊗ (y ⊗ z) ⊗-assoc (leaf x) (leaf y) (leaf z) = PE.cong leaf (+-assoc x y z) ⊗-assoc (leaf x) (leaf y) (skip z) = PE.refl ⊗-assoc (leaf x) (leaf y) (cons z zs) = PE.cong₂ cons (+-assoc x y z) PE.refl ⊗-assoc (leaf x) (skip y) (leaf z) = PE.refl ⊗-assoc (leaf x) (skip y) (skip z) = PE.refl ⊗-assoc (leaf x) (skip y) (cons z zs) = PE.refl ⊗-assoc (leaf x) (cons y ys) (leaf z) = PE.cong₂ cons (+-assoc x y z) PE.refl ⊗-assoc (leaf x) (cons y ys) (skip z) = PE.refl ⊗-assoc (leaf x) (cons y ys) (cons z zs) = PE.cong₂ cons (+-assoc x y z) PE.refl ⊗-assoc (skip x) (leaf y) (leaf z) = PE.refl ⊗-assoc (skip x) (leaf y) (skip z) = PE.refl ⊗-assoc (skip x) (leaf y) (cons z zs) = PE.refl ⊗-assoc (skip x) (skip y) (leaf z) = PE.refl ⊗-assoc (skip x) (skip y) (skip z) = PE.cong skip (⊗-assoc x y z) ⊗-assoc (skip x) (skip y) (cons z zs) = PE.cong (cons z) (⊗-assoc x y zs) ⊗-assoc (skip x) (cons y ys) (leaf z) = PE.refl ⊗-assoc (skip x) (cons y ys) (skip z) = PE.cong (cons y) (⊗-assoc x ys z) ⊗-assoc (skip x) (cons y ys) (cons z zs) = PE.cong (cons (y + z)) (⊗-assoc x ys zs) ⊗-assoc (cons x xs) (leaf y) (leaf z) = PE.cong₂ cons (+-assoc x y z) PE.refl ⊗-assoc (cons x xs) (leaf y) (skip z) = PE.refl ⊗-assoc (cons x xs) (leaf y) (cons z zs) = PE.cong₂ cons (+-assoc x y z) PE.refl ⊗-assoc (cons x xs) (skip y) (leaf z) = PE.refl ⊗-assoc (cons x xs) (skip y) (skip z) = PE.cong (cons x) (⊗-assoc xs y z) ⊗-assoc (cons x xs) (skip y) (cons z zs) = PE.cong (cons (x + z)) (⊗-assoc xs y zs) ⊗-assoc (cons x xs) (cons y ys) (leaf z) = PE.cong₂ cons (+-assoc x y z) PE.refl ⊗-assoc (cons x xs) (cons y ys) (skip z) = PE.cong (cons (x + y)) (⊗-assoc xs ys z) ⊗-assoc (cons x xs) (cons y ys) (cons z zs) = PE.cong₂ cons (+-assoc x y z) (⊗-assoc xs ys zs) module _ (n : ℕ) where private Monomial/≡ : Setoid _ _ Monomial/≡ = PE.setoid (Monomial n) Monomial⟦_⟧ : Interpretation Monomial/≡ Monomial⟦ • ⟧ (x ∷ y ∷ []) = x ⊗ y Monomial⟦_⟧-cong : Congruence Monomial/≡ Monomial⟦_⟧ Monomial⟦ • ⟧-cong (p ∷ q ∷ []) = PE.cong₂ _⊗_ p q Monomial/≡-isAlgebra : IsAlgebra (Monomial/≡) Monomial/≡-isAlgebra = record { ⟦_⟧ = Monomial⟦_⟧ ; ⟦⟧-cong = Monomial⟦_⟧-cong } Monomial/≡-algebra : Algebra Monomial/≡-algebra = record { ∥_∥/≈ = Monomial/≡ ; ∥_∥/≈-isAlgebra = Monomial/≡-isAlgebra } Monomial/≡-models : Models Monomial/≡-algebra Monomial/≡-models comm θ = ⊗-comm (θ (# 0)) (θ (# 1)) Monomial/≡-models assoc θ = ⊗-assoc (θ (# 0)) (θ (# 1)) (θ (# 2)) Monomial/≡-isModel : IsModel Monomial/≡ Monomial/≡-isModel = record { isAlgebra = Monomial/≡-isAlgebra ; models = Monomial/≡-models } J' : Model J' = record { ∥_∥/≈ = Monomial/≡ ; isModel = Monomial/≡-isModel } private module _ {n : ℕ} where open Setoid ∥ J n ∥/≈ using (_≈_) _·_ : ∥ J n ∥ → ∥ J n ∥ → ∥ J n ∥ x · y = term • (x ∷ y ∷ []) ·-cong : ∀ {x y z w} → x ≈ y → z ≈ w → x · z ≈ y · w ·-cong p q = cong • (p ∷ q ∷ []) ·-comm : ∀ x y → x · y ≈ y · x ·-comm x y = axiom comm (env {A = ∥ J n ∥ₐ} (x ∷ y ∷ [])) ·-assoc : ∀ x y z → (x · y) · z ≈ x · (y · z) ·-assoc x y z = axiom assoc (env {A = ∥ J n ∥ₐ} (x ∷ y ∷ z ∷ [])) module _ (n : ℕ) where open Setoid ∥ J (suc n) ∥/≈ using (_≈_) exp : ℕ⁺ → ∥ J (suc n) ∥ exp one = atomise n exp (suc k) = atomise n · exp k exp-hom : ∀ {j k} → exp j · exp k ≈ exp (j + k) exp-hom {one} {k} = refl exp-hom {suc j} {k} = begin (atomise n · exp j) · exp k ≈⟨ ·-assoc (atomise n) (exp j) (exp k) ⟩ atomise n · (exp j · exp k) ≈⟨ ·-cong refl exp-hom ⟩ atomise n · exp (j + k) ∎ where open Reasoning ∥ J (suc n) ∥/≈ ∣syn∣ : ∀ {n} → ∥ J' n ∥ → ∥ J n ∥ ∣syn∣ {suc n} (leaf k) = exp n k ∣syn∣ {suc n} (skip x) = ∣ raise ∣ (∣syn∣ x) ∣syn∣ {suc n} (cons k xs) = exp n k · ∣ raise ∣ (∣syn∣ xs) ∣syn∣-cong : ∀ {n} → Congruent _≡_ ≈[ J n ] ∣syn∣ ∣syn∣-cong {n} p = Setoid.reflexive ∥ J n ∥/≈ (PE.cong ∣syn∣ p) ∣syn∣⃗ : ∀ {n} → ∥ J' n ∥/≈ ↝ ∥ J n ∥/≈ ∣syn∣⃗ {n} = record { ∣_∣ = ∣syn∣ {n} ; ∣_∣-cong = ∣syn∣-cong {n} } ∣syn∣-hom : ∀ {n} → Homomorphic ∥ J' n ∥ₐ ∥ J n ∥ₐ ∣syn∣ ∣syn∣-hom {suc n} • (leaf x ∷ leaf y ∷ []) = exp-hom n ∣syn∣-hom {suc n} • (leaf x ∷ skip y ∷ []) = refl ∣syn∣-hom {suc n} • (leaf x ∷ cons y ys ∷ []) = begin exp n x · (exp n y · ∣ raise ∣ (∣syn∣ ys)) ≈⟨ sym (·-assoc (exp n x) (exp n y) _) ⟩ (exp n x · exp n y) · ∣ raise ∣ (∣syn∣ ys) ≈⟨ ·-cong (exp-hom n) refl ⟩ exp n (x + y) · ∣ raise ∣ (∣syn∣ ys) ∎ where open Reasoning ∥ J (suc n) ∥/≈ ∣syn∣-hom {suc n} • (skip x ∷ leaf y ∷ []) = ·-comm _ (exp n y) ∣syn∣-hom {suc n} • (skip x ∷ skip y ∷ []) = begin ∣ raise ∣ (∣syn∣ x) · ∣ raise ∣ (∣syn∣ y) ≈⟨ ∣ raise ∣-hom • (∣syn∣ x ∷ ∣syn∣ y ∷ []) ⟩ ∣ raise ∣ (∣syn∣ x · ∣syn∣ y) ≈⟨ ∣ raise ∣-cong (∣syn∣-hom • (x ∷ y ∷ [])) ⟩ ∣ raise ∣ (∣syn∣ (x ⊗ y)) ∎ where open Reasoning ∥ J (suc n) ∥/≈ ∣syn∣-hom {suc n} • (skip x ∷ cons y ys ∷ []) = begin ∣ raise ∣ (∣syn∣ x) · (exp n y · ∣ raise ∣ (∣syn∣ ys)) ≈⟨ sym (·-assoc _ (exp n y) _) ⟩ (∣ raise ∣ (∣syn∣ x) · exp n y) · ∣ raise ∣ (∣syn∣ ys) ≈⟨ ·-cong (·-comm _ (exp n y)) refl ⟩ (exp n y · ∣ raise ∣ (∣syn∣ x)) · ∣ raise ∣ (∣syn∣ ys) ≈⟨ ·-assoc (exp n y) _ _ ⟩ exp n y · (∣ raise ∣ (∣syn∣ x) · ∣ raise ∣ (∣syn∣ ys)) ≈⟨ ·-cong refl (∣ raise ∣-hom • (∣syn∣ x ∷ ∣syn∣ ys ∷ [])) ⟩ exp n y · ∣ raise ∣ (∣syn∣ x · ∣syn∣ ys) ≈⟨ ·-cong refl (∣ raise ∣-cong (∣syn∣-hom • (x ∷ ys ∷ []))) ⟩ exp n y · ∣ raise ∣ (∣syn∣ (x ⊗ ys)) ∎ where open Reasoning ∥ J (suc n) ∥/≈ ∣syn∣-hom {suc n} • (cons x xs ∷ leaf y ∷ []) = begin (exp n x · ∣ raise ∣ (∣syn∣ xs)) · exp n y ≈⟨ ·-assoc (exp n x) _ (exp n y) ⟩ exp n x · (∣ raise ∣ (∣syn∣ xs) · exp n y) ≈⟨ ·-cong refl (·-comm _ (exp n y)) ⟩ exp n x · (exp n y · ∣ raise ∣ (∣syn∣ xs)) ≈⟨ sym (·-assoc (exp n x) (exp n y) _) ⟩ (exp n x · exp n y) · ∣ raise ∣ (∣syn∣ xs) ≈⟨ ·-cong (exp-hom n) refl ⟩ exp n (x + y) · ∣ raise ∣ (∣syn∣ xs) ∎ where open Reasoning ∥ J (suc n) ∥/≈ ∣syn∣-hom {suc n} • (cons x xs ∷ skip y ∷ []) = begin (exp n x · ∣ raise ∣ (∣syn∣ xs)) · ∣ raise ∣ (∣syn∣ y) ≈⟨ ·-assoc (exp n x) _ _ ⟩ exp n x · (∣ raise ∣ (∣syn∣ xs) · ∣ raise ∣ (∣syn∣ y)) ≈⟨ ·-cong refl (∣ raise ∣-hom • (∣syn∣ xs ∷ ∣syn∣ y ∷ [])) ⟩ exp n x · ∣ raise ∣ (∣syn∣ xs · ∣syn∣ y) ≈⟨ ·-cong refl (∣ raise ∣-cong (∣syn∣-hom • (xs ∷ y ∷ []))) ⟩ exp n x · ∣ raise ∣ (∣syn∣ (xs ⊗ y)) ∎ where open Reasoning ∥ J (suc n) ∥/≈ ∣syn∣-hom {suc n} • (cons x xs ∷ cons y ys ∷ []) = begin (exp n x · ∣ raise ∣ (∣syn∣ xs)) · (exp n y · ∣ raise ∣ (∣syn∣ ys)) ≈⟨ ·-assoc (exp n x) _ _ ⟩ exp n x · (∣ raise ∣ (∣syn∣ xs) · (exp n y · ∣ raise ∣ (∣syn∣ ys))) ≈⟨ ·-cong refl (sym (·-assoc _ (exp n y) _)) ⟩ exp n x · ((∣ raise ∣ (∣syn∣ xs) · exp n y) · ∣ raise ∣ (∣syn∣ ys)) ≈⟨ ·-cong refl (·-cong (·-comm (∣ raise ∣ (∣syn∣ xs)) _) refl) ⟩ exp n x · ((exp n y · ∣ raise ∣ (∣syn∣ xs)) · ∣ raise ∣ (∣syn∣ ys)) ≈⟨ ·-cong refl (·-assoc (exp n y) _ _) ⟩ exp n x · (exp n y · (∣ raise ∣ (∣syn∣ xs) · ∣ raise ∣ (∣syn∣ ys))) ≈⟨ sym (·-assoc (exp n x) (exp n y) _) ⟩ (exp n x · exp n y) · (∣ raise ∣ (∣syn∣ xs) · ∣ raise ∣ (∣syn∣ ys)) ≈⟨ ·-cong (exp-hom n) (∣ raise ∣-hom • (∣syn∣ xs ∷ ∣syn∣ ys ∷ [])) ⟩ exp n (x + y) · ∣ raise ∣ (∣syn∣ xs · ∣syn∣ ys) ≈⟨ ·-cong refl (∣ raise ∣-cong (∣syn∣-hom • (xs ∷ ys ∷ []))) ⟩ exp n (x + y) · ∣ raise ∣ (∣syn∣ (xs ⊗ ys)) ∎ where open Reasoning ∥ J (suc n) ∥/≈ syn : ∀ {n} → ∥ J' n ∥ₐ ⟿ ∥ J n ∥ₐ syn = record { ∣_∣⃗ = ∣syn∣⃗ ; ∣_∣-hom = ∣syn∣-hom } private tab : ∀ {n} → Fin n → ∥ J' n ∥ tab {suc zero} zero = leaf one tab {suc (suc n)} zero = skip (tab {suc n} zero) tab {suc (suc n)} (suc k) = lift (tab {suc n} k) norm : ∀ {n} → ∥ J n ∥ₐ ⟿ ∥ J' n ∥ₐ norm {n} = interp (J' n) tab private step-exp : ∀ {n} → (k : ℕ⁺) → ≈[ J (suc (suc n)) ] (exp (suc n) k) (∣ step ∣ (exp n k)) step-exp one = refl step-exp (suc k) = ·-cong refl (step-exp k) step-lift : ∀ {n} → (x : ∥ J' n ∥) → ≈[ J (suc n) ] (∣ syn ∣ (lift x)) (∣ step ∣ (∣ syn ∣ x)) step-lift {suc n} (leaf x) = step-exp x step-lift {suc n} (skip x) = begin ∣ raise ∣ (∣ syn ∣ (lift x)) ≈⟨ ∣ raise ∣-cong (step-lift x) ⟩ ∣ raise ∣ (∣ step ∣ (∣ syn ∣ x)) ≈⟨ sym (step-raise {x = ∣ syn ∣ x}) ⟩ ∣ step ∣ (∣ raise ∣ (∣ syn ∣ x)) ∎ where open Reasoning ∥ J (suc (suc n)) ∥/≈ step-lift {suc n} (cons x xs) = begin exp (suc n) x · ∣ raise ∣ (∣ syn ∣ (lift xs)) ≈⟨ ·-cong refl (∣ raise ∣-cong (step-lift xs)) ⟩ exp (suc n) x · ∣ raise ∣ (∣ step ∣ (∣ syn ∣ xs)) ≈⟨ ·-cong (step-exp x) (sym (step-raise {x = ∣ syn ∣ xs})) ⟩ ∣ step ∣ (exp n x) · ∣ step ∣ (∣ raise ∣ (∣ syn ∣ xs)) ≈⟨ ∣ step ∣-hom • (exp n x ∷ (∣ raise ∣ (∣ syn ∣ xs)) ∷ []) ⟩ ∣ step ∣ (exp n x · ∣ raise ∣ (∣ syn ∣ xs)) ∎ where open Reasoning ∥ J (suc (suc n)) ∥/≈ syn-tab : ∀ {n} → (k : Fin n) → ≈[ J n ] (∣ syn ∣ (tab k)) (atom (dyn k)) syn-tab {suc zero} zero = refl syn-tab {suc (suc n)} zero = ∣ raise ∣-cong (syn-tab zero) syn-tab {suc (suc n)} (suc k) = begin ∣ syn ∣ (lift (tab {suc n} k)) ≈⟨ step-lift (tab {suc n} k) ⟩ ∣ step ∣ (∣ syn ∣ (tab {suc n} k)) ≈⟨ ∣ step ∣-cong (syn-tab k) ⟩ ∣ step ∣ (atom (dyn k)) ∎ where open Reasoning ∥ J (suc (suc n)) ∥/≈ syn⊙norm≗id : ∀ {n} → syn {n} ⊙ norm {n} ≗ id syn⊙norm≗id {n} {atom (dyn k)} = syn-tab k syn⊙norm≗id {n} {term • (x ∷ y ∷ [])} = begin ∣ syn ∣ (∣ norm ∣ x ⊗ ∣ norm ∣ y) ≈⟨ sym (∣ syn ∣-hom • (∣ norm ∣ x ∷ ∣ norm ∣ y ∷ [])) ⟩ ∣ syn ∣ (∣ norm ∣ x) · ∣ syn ∣ (∣ norm ∣ y) ≈⟨ ·-cong syn⊙norm≗id syn⊙norm≗id ⟩ x · y ∎ where open Reasoning ∥ J n ∥/≈ private tab-diag : ∀ n → tab {suc n} (fromℕ n) ≡ leaf one tab-diag zero = PE.refl tab-diag (suc n) = PE.cong lift (tab-diag n) norm-exp : ∀ {n} (k : ℕ⁺) → ∣ norm ∣ (exp n k) ≡ leaf k norm-exp {n} one = tab-diag n norm-exp {n} (suc k) = begin ∣ norm ∣ (atomise n · exp n k) ≈⟨ PE.sym (∣ norm ∣-hom • (atomise n ∷ exp n k ∷ [])) ⟩ ∣ norm ∣ (atomise n) ⊗ ∣ norm ∣ (exp n k) ≈⟨ ⊗-cong (tab-diag n) (norm-exp k) ⟩ leaf one ⊗ leaf k ∎ where open Reasoning ∥ J' (suc n) ∥/≈ tab-skip : ∀ {n} → (k : Fin n) → tab {suc n} (up k) ≡ skip (tab {n} k) tab-skip {suc zero} zero = PE.refl tab-skip {suc (suc n)} zero = PE.refl tab-skip {suc (suc n)} (suc k) = PE.cong lift (tab-skip k) norm-raise : ∀ {n x} → ∣ norm {suc n} ∣ (∣ raise ∣ x) ≡ skip (∣ norm {n} ∣ x) norm-raise {n} {atom (dyn k)} = tab-skip k norm-raise {n} {term • (x ∷ y ∷ [])} = begin ∣ norm ∣ (∣ raise ∣ (x · y)) ≡⟨ ∣ norm ∣-cong (sym (∣ raise ∣-hom • (x ∷ y ∷ []))) ⟩ ∣ norm ∣ (∣ raise ∣ x · ∣ raise ∣ y) ≡⟨ PE.sym (∣ norm ∣-hom • (∣ raise ∣ x ∷ ∣ raise ∣ y ∷ [])) ⟩ ∣ norm ∣ (∣ raise ∣ x) ⊗ ∣ norm ∣ (∣ raise ∣ y) ≡⟨ ⊗-cong (norm-raise {x = x}) (norm-raise {x = y}) ⟩ skip (∣ norm ∣ x ⊗ ∣ norm ∣ y) ≡⟨ PE.cong skip (∣ norm ∣-hom • (x ∷ y ∷ [])) ⟩ skip (∣ norm ∣ (x · y)) ∎ where open PE.≡-Reasoning norm⊙syn≗id : ∀ {n} → norm {n} ⊙ syn {n} ≗ id norm⊙syn≗id {suc n} {leaf x} = norm-exp x norm⊙syn≗id {suc n} {skip x} = begin ∣ norm ∣ (∣ raise ∣ (∣ syn ∣ x)) ≈⟨ norm-raise {x = ∣ syn ∣ x} ⟩ skip (∣ norm ∣ (∣ syn ∣ x)) ≈⟨ PE.cong skip norm⊙syn≗id ⟩ skip x ∎ where open Reasoning ∥ J' (suc n) ∥/≈ norm⊙syn≗id {suc n} {cons x xs} = begin ∣ norm ∣ (exp n x · ∣ raise ∣ (∣ syn ∣ xs)) ≈⟨ PE.sym (∣ norm ∣-hom • (exp n x ∷ ∣ raise ∣ (∣ syn ∣ xs) ∷ [])) ⟩ ∣ norm ∣ (exp n x) ⊗ ∣ norm ∣ (∣ raise ∣ (∣ syn ∣ xs)) ≈⟨ ⊗-cong (norm-exp x) (norm-raise {x = ∣ syn ∣ xs}) ⟩ leaf x ⊗ skip (∣ norm ∣ (∣ syn ∣ xs)) ≈⟨ ⊗-cong (PE.refl {x = leaf x}) (PE.cong skip (norm⊙syn≗id {x = xs})) ⟩ leaf x ⊗ skip xs ∎ where open Reasoning ∥ J' (suc n) ∥/≈ iso : ∀ {n} → ∥ J n ∥ₐ ≃ ∥ J' n ∥ₐ iso = record { _⃗ = norm ; _⃖ = syn ; invˡ = norm⊙syn≗id ; invʳ = syn⊙norm≗id }