{-# OPTIONS --without-K --exact-split --safe #-} open import Fragment.Algebra.Signature module Fragment.Algebra.Quotient (Σ : Signature) where open import Fragment.Algebra.Algebra Σ open import Fragment.Algebra.Homomorphism Σ open import Fragment.Setoid.Morphism using (_↝_) open import Level using (Level; Setω; _⊔_; suc) open import Data.Vec.Properties using (map-id) open import Relation.Binary using (Setoid; IsEquivalence; Rel) import Relation.Binary.PropositionalEquality as PE private variable a b ℓ₁ ℓ₂ ℓ₃ ℓ₄ : Level module _ (A : Algebra {a} {ℓ₁}) (_≈_ : Rel ∥ A ∥ ℓ₂) where private setoid' : IsEquivalence _≈_ → Setoid _ _ setoid' isEquivalence = record { Carrier = ∥ A ∥ ; _≈_ = _≈_ ; isEquivalence = isEquivalence } record IsDenominator : Set (a ⊔ suc ℓ₁ ⊔ suc ℓ₂) where field isEquivalence : IsEquivalence _≈_ isCoarser : ∀ {x y} → x =[ A ] y → x ≈ y isCompatible : Congruence (setoid' isEquivalence) (A ⟦_⟧_) module _ (A : Algebra {a} {ℓ₁}) (_≈_ : Rel ∥ A ∥ ℓ₄) {{isDenom : IsDenominator A _≈_}} where record IsQuotient (A/≈ : Algebra {b} {ℓ₂}) : Setω where field inc : A ⟿ A/≈ factor : ∀ {c ℓ₃} {X : Algebra {c} {ℓ₃}} → (f : A ⟿ X) → (Congruent _≈_ ≈[ X ] ∣ f ∣) → A/≈ ⟿ X commute : ∀ {c ℓ₃} {X : Algebra {c} {ℓ₃}} → (f : A ⟿ X) → (cong : Congruent _≈_ ≈[ X ] ∣ f ∣) → factor f cong ⊙ inc ≗ f universal : ∀ {c ℓ₃} {X : Algebra {c} {ℓ₃}} → (f : A ⟿ X) → (cong : Congruent _≈_ ≈[ X ] ∣ f ∣) → {h : A/≈ ⟿ X} → h ⊙ inc ≗ f → factor f cong ≗ h open IsDenominator isDenom ∥_∥/_ : Setoid _ _ ∥_∥/_ = record { Carrier = ∥ A ∥ ; _≈_ = _≈_ ; isEquivalence = isEquivalence } _/_-isAlgebra : IsAlgebra ∥_∥/_ _/_-isAlgebra = record { ⟦_⟧ = A ⟦_⟧_ ; ⟦⟧-cong = isCompatible } _/_ : Algebra _/_ = record { ∥_∥/≈ = ∥_∥/_ ; ∥_∥/≈-isAlgebra = _/_-isAlgebra } private ∣inc∣⃗ : ∥ A ∥/≈ ↝ ∥_∥/_ ∣inc∣⃗ = record { ∣_∣ = λ x → x ; ∣_∣-cong = isCoarser } ∣inc∣-hom : Homomorphic A _/_ (λ x → x) ∣inc∣-hom f xs = Setoid.reflexive ∥_∥/_ (PE.cong (A ⟦ f ⟧_) (map-id xs)) inc : A ⟿ _/_ inc = record { ∣_∣⃗ = ∣inc∣⃗ ; ∣_∣-hom = ∣inc∣-hom } module _ {c ℓ₃} {X : Algebra {c} {ℓ₃}} (f : A ⟿ X) (cong : Congruent _≈_ ≈[ X ] ∣ f ∣) where private ∣factor∣⃗ : ∥_∥/_ ↝ ∥ X ∥/≈ ∣factor∣⃗ = record { ∣_∣ = ∣ f ∣ ; ∣_∣-cong = cong } factor : _/_ ⟿ X factor = record { ∣_∣⃗ = ∣factor∣⃗ ; ∣_∣-hom = ∣ f ∣-hom } factor-commute : factor ⊙ inc ≗ f factor-commute = Setoid.refl ∥ X ∥/≈ factor-universal : ∀ {h : _/_ ⟿ X} → h ⊙ inc ≗ f → factor ≗ h factor-universal p {x} = sym (p {x}) where open Setoid ∥ X ∥/≈ _/_-isQuotient : IsQuotient (_/_) _/_-isQuotient = record { inc = inc ; factor = factor ; commute = factor-commute ; universal = factor-universal }