{-# OPTIONS --without-K --safe #-}
open import Categories.Adjoint
open import Categories.Category
open import Categories.Functor renaming (id to idF)
module Categories.Adjoint.Monadic.Crude {o ℓ e o′ ℓ′ e′} {𝒞 : Category o ℓ e} {𝒟 : Category o′ ℓ′ e′}
{L : Functor 𝒞 𝒟} {R : Functor 𝒟 𝒞} (adjoint : L ⊣ R) where
open import Level
open import Function using (_$_)
open import Data.Product using (Σ-syntax; _,_)
open import Categories.Adjoint.Properties
open import Categories.Adjoint.Monadic
open import Categories.Adjoint.Monadic.Properties
open import Categories.Category.Equivalence using (StrongEquivalence)
open import Categories.Category.Equivalence.Properties using (pointwise-iso-equivalence)
open import Categories.Functor.Properties
open import Categories.NaturalTransformation.NaturalIsomorphism using (NaturalIsomorphism)
open import Categories.NaturalTransformation
open import Categories.Monad
open import Categories.Diagram.Coequalizer
open import Categories.Diagram.ReflexivePair
open import Categories.Adjoint.Construction.EilenbergMoore
open import Categories.Category.Construction.EilenbergMoore
open import Categories.Category.Construction.Properties.EilenbergMoore
open import Categories.Morphism
open import Categories.Morphism.Notation
open import Categories.Morphism.Properties
import Categories.Morphism.Reasoning as MR
private
module L = Functor L
module R = Functor R
module 𝒞 = Category 𝒞
module 𝒟 = Category 𝒟
module adjoint = Adjoint adjoint
T : Monad 𝒞
T = adjoint⇒monad adjoint
𝒞ᵀ : Category _ _ _
𝒞ᵀ = EilenbergMoore T
Comparison : Functor 𝒟 𝒞ᵀ
Comparison = ComparisonF adjoint
module Comparison = Functor Comparison
open Coequalizer
PreservesReflexiveCoequalizers : (F : Functor 𝒟 𝒞) → Set _
PreservesReflexiveCoequalizers F = ∀ {A B} {f g : 𝒟 [ A , B ]} → ReflexivePair 𝒟 f g → (coeq : Coequalizer 𝒟 f g) → IsCoequalizer 𝒞 (F.F₁ f) (F.F₁ g) (F.F₁ (arr coeq))
where
module F = Functor F
module _ {F : Functor 𝒟 𝒞} (preserves-reflexive-coeq : PreservesReflexiveCoequalizers F) where
open Functor F
preserves-coequalizer-unique : ∀ {A B C} {f g : 𝒟 [ A , B ]} {h : 𝒟 [ B , C ]} {eq : 𝒟 [ 𝒟 [ h ∘ f ] ≈ 𝒟 [ h ∘ g ] ]}
→ (reflexive-pair : ReflexivePair 𝒟 f g) → (coe : Coequalizer 𝒟 f g)
→ 𝒞 [ F₁ (coequalize coe eq) ≈ IsCoequalizer.coequalize (preserves-reflexive-coeq reflexive-pair coe) ([ F ]-resp-square eq) ]
preserves-coequalizer-unique reflexive-pair coe = IsCoequalizer.unique (preserves-reflexive-coeq reflexive-pair coe) (F-resp-≈ (universal coe) ○ homomorphism)
where
open 𝒞.HomReasoning
module _ (has-reflexive-coequalizers : ∀ {A B} {f g : 𝒟 [ A , B ]} → ReflexivePair 𝒟 f g → Coequalizer 𝒟 f g) where
private
reflexive-pair : (M : Module T) → ReflexivePair 𝒟 (L.F₁ (Module.action M)) (adjoint.counit.η (L.₀ (Module.A M)))
reflexive-pair M = record
{ s = L.F₁ (adjoint.unit.η (Module.A M))
; isReflexivePair = record
{ sectionₗ = begin
𝒟 [ L.F₁ (Module.action M) ∘ L.F₁ (adjoint.unit.η (Module.A M)) ] ≈˘⟨ L.homomorphism ⟩
L.F₁ (𝒞 [ Module.action M ∘ adjoint.unit.η (Module.A M) ] ) ≈⟨ L.F-resp-≈ (Module.identity M) ⟩
L.F₁ 𝒞.id ≈⟨ L.identity ⟩
𝒟.id ∎
; sectionᵣ = begin
𝒟 [ adjoint.counit.η (L.₀ (Module.A M)) ∘ L.F₁ (adjoint.unit.η (Module.A M)) ] ≈⟨ adjoint.zig ⟩
𝒟.id ∎
}
}
where
open 𝒟.HomReasoning
has-coequalizer : (M : Module T) → Coequalizer 𝒟 (L.F₁ (Module.action M)) (adjoint.counit.η (L.₀ (Module.A M)))
has-coequalizer M = has-reflexive-coequalizers (reflexive-pair M)
module Comparison⁻¹ = Functor (Comparison⁻¹ adjoint has-coequalizer)
module Comparison⁻¹⊣Comparison = Adjoint (Comparison⁻¹⊣Comparison adjoint has-coequalizer)
coequalizer-action : (M : Module T) → Coequalizer 𝒞 (R.F₁ (L.F₁ (Module.action M))) (R.F₁ (adjoint.counit.η (L.₀ (Module.A M))))
coequalizer-action M = record
{ arr = Module.action M
; isCoequalizer = record
{ equality = Module.commute M
; coequalize = λ {X} {h} eq → 𝒞 [ h ∘ adjoint.unit.η (Module.A M) ]
; universal = λ {C} {h} {eq} → begin
h ≈⟨ introʳ adjoint.zag ○ 𝒞.sym-assoc ⟩
𝒞 [ 𝒞 [ h ∘ R.F₁ (adjoint.counit.η (L.₀ (Module.A M))) ] ∘ adjoint.unit.η (R.F₀ (L.F₀ (Module.A M))) ] ≈⟨ pushˡ (⟺ eq) ⟩
𝒞 [ h ∘ 𝒞 [ R.F₁ (L.F₁ (Module.action M)) ∘ adjoint.unit.η (R.F₀ (L.F₀ (Module.A M))) ] ] ≈⟨ pushʳ (adjoint.unit.sym-commute (Module.action M)) ⟩
𝒞 [ 𝒞 [ h ∘ adjoint.unit.η (Module.A M) ] ∘ Module.action M ] ∎
; unique = λ {X} {h} {i} {eq} eq′ → begin
i ≈⟨ introʳ (Module.identity M) ⟩
𝒞 [ i ∘ 𝒞 [ Module.action M ∘ adjoint.unit.η (Module.A M) ] ] ≈⟨ pullˡ (⟺ eq′) ⟩
𝒞 [ h ∘ adjoint.unit.η (Module.A M) ] ∎
}
}
where
open 𝒞.HomReasoning
open MR 𝒞
unit-iso : PreservesReflexiveCoequalizers R → (X : Module T) → Σ[ h ∈ 𝒞ᵀ [ Comparison.F₀ (Comparison⁻¹.F₀ X) , X ] ] (Iso 𝒞ᵀ (Comparison⁻¹⊣Comparison.unit.η X) h)
unit-iso preserves-reflexive-coeq X =
let
coequalizerˣ = has-coequalizer X
coequalizerᴿˣ = ((IsCoequalizer⇒Coequalizer 𝒞 (preserves-reflexive-coeq (reflexive-pair X) (has-coequalizer X))))
coequalizer-iso = up-to-iso 𝒞 (coequalizer-action X) coequalizerᴿˣ
module coequalizer-iso = _≅_ coequalizer-iso
open 𝒞
open 𝒞.HomReasoning
open MR 𝒞
α = record
{ arr = coequalizer-iso.to
; commute = begin
coequalizer-iso.to ∘ R.F₁ (adjoint.counit.η _) ≈⟨ introʳ (R.F-resp-≈ L.identity ○ R.identity) ⟩
(coequalizer-iso.to ∘ R.F₁ (adjoint.counit.η _)) ∘ R.F₁ (L.F₁ 𝒞.id) ≈⟨ pushʳ (R.F-resp-≈ (L.F-resp-≈ (⟺ coequalizer-iso.isoʳ)) ○ R.F-resp-≈ L.homomorphism ○ R.homomorphism) ⟩
((coequalizer-iso.to ∘ R.F₁ (adjoint.counit.η _)) ∘ R.F₁ (L.F₁ (R.F₁ (arr coequalizerˣ) ∘ adjoint.unit.η _))) ∘ R.F₁ (L.F₁ coequalizer-iso.to) ≈⟨ (refl⟩∘⟨ (R.F-resp-≈ L.homomorphism ○ R.homomorphism)) ⟩∘⟨refl ⟩
((coequalizer-iso.to ∘ R.F₁ (adjoint.counit.η _)) ∘ R.F₁ (L.F₁ (R.F₁ (arr coequalizerˣ))) ∘ R.F₁ (L.F₁ (adjoint.unit.η _))) ∘ R.F₁ (L.F₁ coequalizer-iso.to) ≈⟨ center ([ R ]-resp-square (adjoint.counit.commute _)) ⟩∘⟨refl ⟩
((coequalizer-iso.to ∘ (R.F₁ (arr coequalizerˣ) ∘ R.F₁ (adjoint.counit.η (L.F₀ _))) ∘ R.F₁ (L.F₁ (adjoint.unit.η _))) ∘ R.F₁ (L.F₁ coequalizer-iso.to)) ≈⟨ (refl⟩∘⟨ cancelʳ (⟺ R.homomorphism ○ R.F-resp-≈ adjoint.zig ○ R.identity)) ⟩∘⟨refl ⟩
(coequalizer-iso.to ∘ R.F₁ (arr coequalizerˣ)) ∘ R.F₁ (L.F₁ coequalizer-iso.to) ≈˘⟨ universal coequalizerᴿˣ ⟩∘⟨refl ⟩
Module.action X ∘ R.F₁ (L.F₁ coequalizer-iso.to) ∎
}
in α , record { isoˡ = coequalizer-iso.isoˡ ; isoʳ = coequalizer-iso.isoʳ }
counit-iso : PreservesReflexiveCoequalizers R → Conservative R → (X : 𝒟.Obj) → Σ[ h ∈ 𝒟 [ X , Comparison⁻¹.F₀ (Comparison.F₀ X) ] ] Iso 𝒟 (Comparison⁻¹⊣Comparison.counit.η X) h
counit-iso preserves-reflexive-coeq conservative X =
let coequalizerᴿᴷˣ = IsCoequalizer⇒Coequalizer 𝒞 (preserves-reflexive-coeq (reflexive-pair (Comparison.F₀ X)) (has-coequalizer (Comparison.F₀ X)))
coequalizerᴷˣ = has-coequalizer (Comparison.F₀ X)
coequalizer-iso = up-to-iso 𝒞 coequalizerᴿᴷˣ (coequalizer-action (Comparison.F₀ X))
module coequalizer-iso = _≅_ coequalizer-iso
open 𝒞.HomReasoning
open 𝒞.Equiv
in conservative (Iso-resp-≈ 𝒞 coequalizer-iso.iso (⟺ (preserves-coequalizer-unique {R} preserves-reflexive-coeq (reflexive-pair (Comparison.F₀ X)) coequalizerᴷˣ)) refl)
crude-monadicity : PreservesReflexiveCoequalizers R → Conservative R → StrongEquivalence 𝒞ᵀ 𝒟
crude-monadicity preserves-reflexlive-coeq conservative = record
{ F = Comparison⁻¹ adjoint has-coequalizer
; G = Comparison
; weak-inverse = pointwise-iso-equivalence (Comparison⁻¹⊣Comparison adjoint has-coequalizer)
(counit-iso preserves-reflexlive-coeq conservative)
(unit-iso preserves-reflexlive-coeq)
}