{-# OPTIONS --without-K --safe #-}
open import Categories.Category.Core
module Categories.Object.Product.Limit {o ℓ e} (C : Category o ℓ e) where
open import Level
open import Data.Nat.Base using (ℕ)
open import Data.Fin.Base using (Fin)
open import Data.Fin.Patterns
open import Categories.Category.Lift
open import Categories.Category.Finite.Fin
open import Categories.Category.Finite.Fin.Construction.Discrete
open import Categories.Object.Product 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
module _ {o′ ℓ′ e′} {F : Functor (liftC o′ ℓ′ e′ (Discrete 2)) C} where
private
module F = Functor F
open F
limit⇒product : Limit F → Product (F₀ (lift 0F)) (F₀ (lift 1F))
limit⇒product L = record
{ A×B = apex
; π₁ = proj (lift 0F)
; π₂ = proj (lift 1F)
; ⟨_,_⟩ = λ f g → rep record
{ apex = record
{ ψ = λ { (lift 0F) → f
; (lift 1F) → g }
; commute = λ { {lift 0F} {lift 0F} (lift 0F) → elimˡ identity
; {lift 1F} {lift 1F} (lift 0F) → elimˡ identity }
}
}
; project₁ = commute
; project₂ = commute
; unique = λ {_} {h} eq eq′ → terminal.!-unique record
{ arr = h
; commute = λ { {lift 0F} → eq
; {lift 1F} → eq′ }
}
}
where open Limit L
module _ o′ ℓ′ e′ A B where
open Equiv
product⇒limit-F : Functor (liftC o′ ℓ′ e′ (Discrete 2)) C
product⇒limit-F = record
{ F₀ = λ { (lift 0F) → A
; (lift 1F) → B }
; F₁ = λ { {lift 0F} {lift 0F} _ → C.id
; {lift 1F} {lift 1F} _ → C.id }
; identity = λ { {lift 0F} → refl
; {lift 1F} → refl }
; homomorphism = λ { {lift 0F} {lift 0F} {lift 0F} → sym identity²
; {lift 1F} {lift 1F} {lift 1F} → sym identity² }
; F-resp-≈ = λ { {lift 0F} {lift 0F} _ → refl
; {lift 1F} {lift 1F} _ → refl }
}
module _ o′ ℓ′ e′ {A B} (p : Product A B) where
open Product p
private
F = product⇒limit-F o′ ℓ′ e′ A B
open Functor F
product⇒limit : Limit F
product⇒limit = record
{ terminal = record
{ ⊤ = record
{ N = A×B
; apex = record
{ ψ = λ { (lift 0F) → π₁
; (lift 1F) → π₂ }
; commute = λ { {lift 0F} {lift 0F} (lift 0F) → identityˡ
; {lift 1F} {lift 1F} (lift 0F) → identityˡ }
}
}
; ⊤-is-terminal = record
{ ! = λ {K} →
let open Co.Cone F K
in record
{ arr = ⟨ ψ (lift 0F) , ψ (lift 1F) ⟩
; commute = λ { {lift 0F} → project₁
; {lift 1F} → project₂ }
}
; !-unique = λ {K} f →
let module K = Co.Cone F K
module f = Co.Cone⇒ F f
in begin
⟨ K.ψ (lift 0F) , K.ψ (lift 1F) ⟩ ≈˘⟨ ⟨⟩-cong₂ f.commute f.commute ⟩
⟨ π₁ ∘ f.arr , π₂ ∘ f.arr ⟩ ≈⟨ g-η ⟩
f.arr ∎
}
}
}