\begin{code} {-# OPTIONS --cubical --safe #-} open import Algebra open import Level module Control.Monad.Weighted.Free {ℓ} {𝑅 : Type ℓ} (rng : Semiring 𝑅) where open Semiring rng open import Level open import Path open import Path.Reasoning open import HLevels open import Data.Sigma open import Control.Monad.Weighted.Definition rng open import Control.Monad.Weighted.Eliminators rng renaming (⟦_⟧ to ⟦_⟧′) open import Control.Monad.Weighted.Union rng using () renaming (_∪_ to _∪′_) open import Control.Monad.Weighted.Cond rng using () renaming (_⋊_ to _⋊′_) open import Control.Monad.Weighted.Semimodule rng open import Control.Monad.Weighted.Functor.TypeDef open import Control.Monad.Weighted.Functor inj : A → Weighted A inj x = 1# ◃ x ∷ [] module Proof {ℓ} {𝑀 : Type ℓ} (mod : LeftSemimodule rng 𝑀) (vIsSet : isSet 𝑀) where module Mod = LeftSemimodule mod open Mod using (_⋊_; _∪_; ∅) \end{code} %<*hom> \begin{code} hom : (A → 𝑀) → Φ A 𝑀 hom h .fst (p ◃ x ∷ _ ⟨ xs ⟩) = (p ⋊ h x) ∪ xs hom h .fst [] = ∅ \end{code} %</hom> \begin{code} hom h .snd .c-set _ = vIsSet hom h .snd .c-dup p q x _ xs = p ⋊ h x ∪ (q ⋊ h x ∪ xs) ≡˘⟨ Mod.∪-assoc _ _ _ ⟩ (p ⋊ h x ∪ q ⋊ h x) ∪ xs ≡˘⟨ cong (_∪ xs) (Mod.⟨+⟩⋊ p q (h x)) ⟩ (p + q) ⋊ h x ∪ xs ∎ hom h .snd .c-com p x q y _ xs = p ⋊ h x ∪ (q ⋊ h y ∪ xs) ≡˘⟨ Mod.∪-assoc _ _ _ ⟩ (p ⋊ h x ∪ q ⋊ h y) ∪ xs ≡⟨ cong (_∪ xs) (Mod.comm _ _) ⟩ (q ⋊ h y ∪ p ⋊ h x) ∪ xs ≡⟨ Mod.∪-assoc _ _ _ ⟩ q ⋊ h y ∪ (p ⋊ h x ∪ xs) ∎ hom h .snd .c-del x _ xs = 0# ⋊ h x ∪ xs ≡⟨ cong (_∪ xs) (Mod.0⋊ _) ⟩ ∅ ∪ xs ≡⟨ Mod.∅∪ xs ⟩ xs ∎ module _ (h : A → 𝑀) where ⟦_⟧ : Weighted A → 𝑀 ⟦ xs ⟧ = ⟦ hom h ⟧′ xs module _ (hom : SemimoduleHomomorphism[ rng ] semimodule {A = A} ⟶ mod) where module Hom = SemimoduleHomomorphism[_]_⟶_ hom open Hom using (f) uniq-alg : (inv : ∀ x → f (inj x) ≡ h x) → Ψ[ xs ⦂ A ] ⟦ xs ⟧ ≡ f xs uniq-alg inv .snd = prop-coh λ _ → vIsSet _ _ uniq-alg inv .fst (p ◃ x ∷ xs ⟨ pxs ⟩) = ⟦ p ◃ x ∷ xs ⟧ ≡⟨⟩ (p ⋊ h x) ∪ ⟦ xs ⟧ ≡˘⟨ cong (_∪ ⟦ xs ⟧) (cong (p ⋊_) (inv x)) ⟩ p ⋊ f (inj x) ∪ ⟦ xs ⟧ ≡˘⟨ cong (_∪ ⟦ xs ⟧) (Hom.⋊-homo p _) ⟩ f (p ⋊′ inj x) ∪ ⟦ xs ⟧ ≡⟨ cong (_∪ ⟦ xs ⟧) (cong f (cong (_◃ x ∷ []) (*1 p))) ⟩ f (p ◃ x ∷ []) ∪ ⟦ xs ⟧ ≡⟨ cong (f (p ◃ x ∷ []) ∪_) pxs ⟩ f (p ◃ x ∷ []) ∪ f xs ≡˘⟨ Hom.∙-homo _ _ ⟩ f (p ◃ x ∷ xs) ∎ uniq-alg inv .fst [] = sym Hom.ε-homo uniq : (inv : ∀ x → f (inj x) ≡ h x) → ∀ xs → ⟦ xs ⟧ ≡ f xs uniq inv = ⟦ uniq-alg inv ⟧′ inv : ∀ x → ⟦ inj x ⟧ ≡ h x inv x = ⟦ inj x ⟧ ≡⟨⟩ ⟦ 1# ◃ x ∷ [] ⟧ ≡⟨⟩ (1# ⋊ h x) ∪ ∅ ≡⟨ Mod.∪∅ _ ⟩ 1# ⋊ h x ≡⟨ Mod.1⋊ _ ⟩ h x ∎ ∪-hom : (ys : Weighted A) → Ψ[ xs ⦂ A ] ⟦ xs ∪′ ys ⟧ ≡ ⟦ xs ⟧ ∪ ⟦ ys ⟧ ∪-hom ys .snd = prop-coh λ _ → vIsSet _ _ ∪-hom ys .fst (p ◃ x ∷ xs ⟨ pxs ⟩) = ⟦ (p ◃ x ∷ xs) ∪′ ys ⟧ ≡⟨⟩ ⟦ p ◃ x ∷ (xs ∪′ ys) ⟧ ≡⟨⟩ p ⋊ h x ∪ ⟦ xs ∪′ ys ⟧ ≡⟨ cong ((p ⋊ h x) ∪_) pxs ⟩ p ⋊ h x ∪ (⟦ xs ⟧ ∪ ⟦ ys ⟧) ≡˘⟨ Mod.∪-assoc (p ⋊ h x) ⟦ xs ⟧ ⟦ ys ⟧ ⟩ p ⋊ h x ∪ ⟦ xs ⟧ ∪ ⟦ ys ⟧ ≡⟨⟩ ⟦ p ◃ x ∷ xs ⟧ ∪ ⟦ ys ⟧ ∎ ∪-hom ys .fst [] = sym (Mod.∅∪ ⟦ ys ⟧) ⋊-hom : (r : 𝑅) → Ψ[ xs ⦂ A ] ⟦ r ⋊′ xs ⟧ ≡ r ⋊ ⟦ xs ⟧ ⋊-hom r .snd = prop-coh λ _ → vIsSet _ _ ⋊-hom r .fst [] = sym (Mod.⋊∅ r) ⋊-hom r .fst (p ◃ x ∷ xs ⟨ pxs ⟩) = ⟦ r ⋊′ (p ◃ x ∷ xs) ⟧ ≡⟨⟩ ⟦ r * p ◃ x ∷ r ⋊′ xs ⟧ ≡⟨⟩ (r * p) ⋊ h x ∪ ⟦ r ⋊′ xs ⟧ ≡⟨ cong ((r * p) ⋊ h x ∪_) pxs ⟩ (r * p) ⋊ h x ∪ r ⋊ ⟦ xs ⟧ ≡⟨ cong (_∪ r ⋊ ⟦ xs ⟧) (Mod.⟨*⟩⋊ _ _ _) ⟩ r ⋊ (p ⋊ h x) ∪ r ⋊ ⟦ xs ⟧ ≡˘⟨ Mod.⋊⟨∪⟩ r _ _ ⟩ r ⋊ (p ⋊ h x ∪ ⟦ xs ⟧) ≡⟨⟩ r ⋊ ⟦ p ◃ x ∷ xs ⟧ ∎ hom′ : SemimoduleHomomorphism[ rng ] semimodule {A = A} ⟶ mod MonoidHomomorphism_⟶_.f (SemimoduleHomomorphism[_]_⟶_.mon-homo hom′) = ⟦_⟧ MonoidHomomorphism_⟶_.∙-homo (SemimoduleHomomorphism[_]_⟶_.mon-homo hom′) x y = ⟦ ∪-hom y ⟧′ x MonoidHomomorphism_⟶_.ε-homo (SemimoduleHomomorphism[_]_⟶_.mon-homo hom′) = refl SemimoduleHomomorphism[_]_⟶_.⋊-homo hom′ r = ⟦ ⋊-hom r ⟧′ \end{code}