{-# OPTIONS --without-K --safe #-} open import Categories.Category module Categories.Diagram.Equalizer.Limit {o ℓ e} (C : Category o ℓ e) where open import Level open import Data.Nat.Base using (ℕ) open import Data.Fin.Base hiding (lift) open import Data.Fin.Patterns open import Categories.Category.Lift open import Categories.Category.Finite.Fin open import Categories.Category.Finite.Fin.Instance.Parallel open import Categories.Category.Complete open import Categories.Diagram.Equalizer C open import Categories.Diagram.Limit open import Categories.Functor.Core import Categories.Category.Construction.Cones as Co import Categories.Morphism.Reasoning as MR private module C = Category C open C open MR C open HomReasoning open Equiv module _ {o′ ℓ′ e′} {F : Functor (liftC o′ ℓ′ e′ Parallel) C} where private module F = Functor F open F limit⇒equalizer : Limit F → Equalizer {B = F₀ (lift 1F)} (F₁ (lift 0F)) (F₁ (lift 1F)) limit⇒equalizer L = record { obj = apex ; arr = proj (lift 0F) ; isEqualizer = record { equality = limit-commute (lift 0F) ○ ⟺ (limit-commute (lift 1F)) ; equalize = λ {_} {h} eq → rep record { apex = record { ψ = λ { (lift 0F) → h ; (lift 1F) → F₁ (lift 1F) ∘ h } ; commute = λ { {lift 0F} {lift 0F} (lift 0F) → elimˡ identity ; {lift 0F} {lift 1F} (lift 0F) → eq ; {lift 0F} {lift 1F} (lift 1F) → refl ; {lift 1F} {lift 1F} (lift 0F) → elimˡ identity } } } ; universal = ⟺ commute ; unique = λ {_} {h i} eq → ⟺ (terminal.!-unique record { arr = i ; commute = λ { {lift 0F} → ⟺ eq ; {lift 1F} → begin proj (lift 1F) ∘ i ≈˘⟨ pullˡ (limit-commute (lift 1F)) ⟩ F₁ (lift 1F) ∘ proj (lift 0F) ∘ i ≈˘⟨ refl⟩∘⟨ eq ⟩ F₁ (lift 1F) ∘ h ∎ } }) } } where open Limit L module _ o′ ℓ′ e′ {X Y} (f g : X ⇒ Y) where equalizer⇒limit-F : Functor (liftC o′ ℓ′ e′ Parallel) C equalizer⇒limit-F = record { F₀ = λ { (lift 0F) → X ; (lift 1F) → Y } ; F₁ = λ { {lift 0F} {lift 0F} (lift 0F) → C.id ; {lift 0F} {lift 1F} (lift 0F) → f ; {lift 0F} {lift 1F} (lift 1F) → g ; {lift 1F} {lift 1F} (lift 0F) → C.id } ; identity = λ { {lift 0F} → refl ; {lift 1F} → refl } ; homomorphism = λ { {lift 0F} {lift 0F} {lift 0F} {lift 0F} {lift 0F} → ⟺ identity² ; {lift 0F} {lift 0F} {lift 1F} {lift 0F} {lift 0F} → ⟺ identityʳ ; {lift 0F} {lift 0F} {lift 1F} {lift 0F} {lift 1F} → ⟺ identityʳ ; {lift 0F} {lift 1F} {lift 1F} {lift 0F} {lift 0F} → ⟺ identityˡ ; {lift 0F} {lift 1F} {lift 1F} {lift 1F} {lift 0F} → ⟺ identityˡ ; {lift 1F} {lift 1F} {lift 1F} {lift 0F} {lift 0F} → ⟺ identity² } ; F-resp-≈ = λ { {lift 0F} {lift 0F} {lift 0F} {lift 0F} _ → refl ; {lift 0F} {lift 1F} {lift 0F} {lift 0F} _ → refl ; {lift 0F} {lift 1F} {lift 1F} {lift 1F} _ → refl ; {lift 1F} {lift 1F} {lift 0F} {lift 0F} _ → refl } } module _ o′ ℓ′ e′ {X Y} {f g : X ⇒ Y} (e : Equalizer f g) where open Equalizer e private F = equalizer⇒limit-F o′ ℓ′ e′ f g equalizer⇒limit : Limit F equalizer⇒limit = record { terminal = record { ⊤ = record { N = obj ; apex = record { ψ = λ { (lift 0F) → arr ; (lift 1F) → g ∘ arr } ; commute = λ { {lift 0F} {lift 0F} (lift 0F) → identityˡ ; {lift 0F} {lift 1F} (lift 0F) → equality ; {lift 0F} {lift 1F} (lift 1F) → refl ; {lift 1F} {lift 1F} (lift 0F) → identityˡ } } } ; ⊤-is-terminal = record { ! = λ {K} → let open Co.Cone F K in record { arr = equalize (commute (lift 0F) ○ ⟺ (commute (lift 1F))) ; commute = λ { {lift 0F} → ⟺ universal ; {lift 1F} → pullʳ (⟺ universal) ○ commute (lift 1F) } } ; !-unique = λ f → let open Co.Cone⇒ F f in ⟺ (unique (⟺ commute)) } } } module _ {o′ ℓ′ e′} (Com : Complete o′ ℓ′ e′ C) where complete⇒equalizer : ∀ {A B} (f g : A ⇒ B) → Equalizer f g complete⇒equalizer f g = limit⇒equalizer (Com (equalizer⇒limit-F _ _ _ f g))