{-# OPTIONS --without-K --safe #-}
module Categories.Functor.Monoidal.Properties where
import Categories.Category.Monoidal.Reasoning as ⊗-Reasoning
import Categories.Category.Monoidal.Utilities as ⊗-Util
open import Level
open import Data.Product using (_,_)
open import Categories.Category.BinaryProducts using (BinaryProducts)
open import Categories.Category.Core using (Category)
open import Categories.Category.Monoidal.Bundle using (MonoidalCategory)
open import Categories.Category.Cartesian.Bundle using (CartesianCategory)
open import Categories.Category.Cartesian.Monoidal using (module CartesianMonoidal)
open import Categories.Functor using (Functor; _∘F_) renaming (id to idF)
open import Categories.Category.Product using (_⁂_)
open import Categories.Functor.Properties using ([_]-resp-square; [_]-resp-∘; [_]-resp-≅; [_]-resp-Iso)
open import Categories.Functor.Cartesian using (CartesianF)
open import Categories.Functor.Monoidal
using (IsMonoidalFunctor; IsStrongMonoidalFunctor; StrongMonoidalFunctor; MonoidalFunctor)
open import Categories.NaturalTransformation using (NaturalTransformation; ntHelper)
open import Categories.NaturalTransformation.NaturalIsomorphism using (_≃_; niHelper)
import Categories.Object.Terminal as ⊤
import Categories.Morphism as M
import Categories.Morphism.Reasoning as MR
import Categories.Morphism.Properties as MP
private
variable
o o′ o″ ℓ ℓ′ ℓ″ e e′ e″ : Level
A B C : MonoidalCategory o ℓ e
private
module WithShorthands (C : MonoidalCategory o ℓ e) where
open MonoidalCategory C public
open ⊗-Util monoidal using (module Shorthands)
open Shorthands public
module FunctorShorthands
{C : MonoidalCategory o ℓ e}
{D : MonoidalCategory o′ ℓ′ e′}
(let module C = MonoidalCategory C)
(let module D = MonoidalCategory D)
{F : Functor C.U D.U}
where
module Lax (F-IsMonoidal : IsMonoidalFunctor C D F) where
open Functor F public
open IsMonoidalFunctor F-IsMonoidal public
open MonoidalCategory D
φ : {X Y : C.Obj} → F₀ X ⊗₀ F₀ Y ⇒ F₀ (X C.⊗₀ Y)
φ {X} {Y} = ⊗-homo.η (X , Y)
module Strong (F-IsStrongMonoidal : IsStrongMonoidalFunctor C D F) where
open Functor F public
open IsStrongMonoidalFunctor F-IsStrongMonoidal public
open MonoidalCategory D
ε⇒ : unit ⇒ F₀ C.unit
ε⇒ = ε.from
ε⇐ : F₀ C.unit ⇒ unit
ε⇐ = ε.to
φ⇒ : {X Y : C.Obj} → F₀ X ⊗₀ F₀ Y ⇒ F₀ (X C.⊗₀ Y)
φ⇒ {X} {Y} = ⊗-homo.⇒.η (X , Y)
φ⇐ : {X Y : C.Obj} → F₀ (X C.⊗₀ Y) ⇒ F₀ X ⊗₀ F₀ Y
φ⇐ {X} {Y} = ⊗-homo.⇐.η (X , Y)
module _ (C : MonoidalCategory o ℓ e) where
open WithShorthands C
open HomReasoning
open M U
open MR U
open MP U
idF-IsStrongMonoidal : IsStrongMonoidalFunctor C C idF
idF-IsStrongMonoidal = record
{ ε = ≅.refl
; ⊗-homo = ⊗-homomorphism
; associativity = λ {X} {Y} {Z} → associativity X Y Z
; unitaryˡ = elimʳ (elimʳ ⊗.identity)
; unitaryʳ = elimʳ (elimʳ ⊗.identity)
}
where
⊗-homomorphism : ⊗ ∘F (idF ⁂ idF) ≃ idF ∘F ⊗
⊗-homomorphism = niHelper record
{ η = λ _ → id
; η⁻¹ = λ _ → id
; commute = λ _ → id-comm-sym
; iso = λ (X , Y) → id-iso {X ⊗₀ Y}
}
associativity : (X Y Z : Obj) → α⇒ {X} {Y} {Z} ∘ id ∘ id ⊗₁ id ≈ id ∘ id ⊗₁ id ∘ α⇒
associativity X Y Z = begin
α⇒ ∘ id ∘ id ⊗₁ id ≈⟨ refl⟩∘⟨ elimʳ ⊗.identity ⟩
α⇒ ∘ id ≈⟨ id-comm ⟩
id ∘ α⇒ ≈⟨ refl⟩∘⟨ introˡ ⊗.identity ⟩
id ∘ id ⊗₁ id ∘ α⇒ ∎
idF-IsMonoidal : IsMonoidalFunctor C C idF
idF-IsMonoidal = IsStrongMonoidalFunctor.isLaxMonoidal idF-IsStrongMonoidal
idF-Monoidal : MonoidalFunctor C C
idF-Monoidal = record { isMonoidal = idF-IsMonoidal }
idF-StrongMonoidal : StrongMonoidalFunctor C C
idF-StrongMonoidal = record { isStrongMonoidal = idF-IsStrongMonoidal }
module _ (A : MonoidalCategory o ℓ e) (B : MonoidalCategory o′ ℓ′ e′) (C : MonoidalCategory o″ ℓ″ e″) where
private
module A = WithShorthands A
module B = WithShorthands B
module C = WithShorthands C
open M C.U
open MR C.U
∘-IsMonoidal : ∀ {F : Functor A.U B.U} {G : Functor B.U C.U} →
IsMonoidalFunctor B C G → IsMonoidalFunctor A B F →
IsMonoidalFunctor A C (G ∘F F)
∘-IsMonoidal {F} {G} CG CF = record
{ ε = G.₁ F.ε ∘ G.ε
; ⊗-homo = ⊗-homo
; associativity = associativity
; unitaryˡ = unitaryˡ
; unitaryʳ = unitaryʳ
}
where
module F = FunctorShorthands.Lax CF
module G = FunctorShorthands.Lax CG
open C
open ⊗-Reasoning C.monoidal
commute
: {X X′ Y Y′ : A.Obj}
(f : X A.⇒ X′)
(g : Y A.⇒ Y′)
→ (G.₁ F.φ ∘ G.φ) ∘ G.F₁ (F.₁ f) ⊗₁ G.₁ (F.₁ g)
≈ G.₁ (F.₁ (f A.⊗₁ g)) ∘ G.₁ F.φ ∘ G.φ
commute f g = begin
(G.₁ F.φ ∘ G.φ) ∘ G.₁ (F.₁ f) ⊗₁ G.₁ (F.₁ g) ≈⟨ pullʳ (G.⊗-homo.commute _) ⟩
G.₁ F.φ ∘ G.₁ (F.₁ f B.⊗₁ F.₁ g) ∘ G.φ ≈⟨ extendʳ ([ G ]-resp-square (F.⊗-homo.commute _)) ⟩
G.₁ (F.₁ (f A.⊗₁ g)) ∘ G.₁ F.φ ∘ G.φ ∎
⊗-homo : NaturalTransformation (C.⊗ ∘F ((G ∘F F) ⁂ (G ∘F F))) ((G ∘F F) ∘F A.⊗)
⊗-homo = ntHelper record
{ η = λ (X , Y) → G.₁ F.φ ∘ G.φ
; commute = λ (f , g) → commute f g
}
associativity
: {X Y Z : A.Obj}
→ G.F₁ (F.F₁ (A.α⇒ {X} {Y} {Z})) ∘ (G.F₁ F.φ ∘ G.φ) ∘ (G.F₁ F.φ ∘ G.φ) ⊗₁ id
≈ (G.F₁ F.φ ∘ G.φ) ∘ id ⊗₁ (G.F₁ F.φ ∘ G.φ) ∘ α⇒
associativity = begin
G.₁ (F.₁ A.α⇒) ∘ (G.₁ F.φ ∘ G.φ) ∘ (G.₁ F.φ ∘ G.φ) ⊗₁ id ≈⟨ refl⟩∘⟨ refl⟩∘⟨ refl⟩⊗⟨ G.identity ⟨
G.₁ (F.₁ A.α⇒) ∘ (G.₁ F.φ ∘ G.φ) ∘ (G.₁ F.φ ∘ G.φ) ⊗₁ G.₁ B.id ≈⟨ refl⟩∘⟨ pullʳ (refl⟩∘⟨ split₁ʳ) ⟩
G.₁ (F.₁ A.α⇒) ∘ G.₁ F.φ ∘ G.φ ∘ G.₁ F.φ ⊗₁ G.₁ B.id ∘ G.φ ⊗₁ id ≈⟨ refl⟩∘⟨ refl⟩∘⟨ extendʳ (G.⊗-homo.commute _) ⟩
G.₁ (F.₁ A.α⇒) ∘ G.₁ F.φ ∘ G.₁ (F.φ B.⊗₁ B.id) ∘ G.φ ∘ G.φ ⊗₁ id ≈⟨ pull-center (⟺ G.homomorphism) ⟩
G.₁ (F.₁ A.α⇒) ∘ G.₁ (F.φ B.∘ F.φ B.⊗₁ B.id) ∘ G.φ ∘ G.φ ⊗₁ id ≈⟨ extendʳ ([ G ]-resp-square F.associativity) ⟩
G.₁ F.φ ∘ G.₁ (B.id B.⊗₁ F.φ B.∘ B.α⇒) ∘ G.φ ∘ G.φ ⊗₁ id ≈⟨ push-center G.homomorphism ⟩
G.₁ F.φ ∘ G.₁ (B.id B.⊗₁ F.φ) ∘ G.₁ B.α⇒ ∘ G.φ ∘ G.φ ⊗₁ id ≈⟨ refl⟩∘⟨ refl⟩∘⟨ G.associativity ⟩
G.₁ F.φ ∘ G.₁ (B.id B.⊗₁ F.φ) ∘ G.φ ∘ id ⊗₁ G.φ ∘ α⇒ ≈⟨ pushʳ (extendʳ (G.⊗-homo.sym-commute _)) ⟩
(G.₁ F.φ ∘ G.φ) ∘ G.₁ B.id ⊗₁ G.₁ F.φ ∘ id ⊗₁ G.φ ∘ α⇒ ≈⟨ refl⟩∘⟨ pullˡ merge₂ʳ ⟩
(G.₁ F.φ ∘ G.φ) ∘ G.₁ B.id ⊗₁ (G.₁ F.φ ∘ G.φ) ∘ α⇒ ≈⟨ refl⟩∘⟨ G.identity ⟩⊗⟨refl ⟩∘⟨refl ⟩
(G.₁ F.φ ∘ G.φ) ∘ id ⊗₁ (G.F₁ F.φ ∘ G.φ) ∘ α⇒ ∎
unitaryˡ : {X : A.Obj} → G.₁ (F.₁ (A.λ⇒ {X})) ∘ (G.₁ F.φ ∘ G.φ) ∘ (G.₁ F.ε ∘ G.ε) ⊗₁ id ≈ λ⇒
unitaryˡ = begin
G.₁ (F.₁ A.λ⇒) ∘ (G.₁ F.φ ∘ G.φ) ∘ (G.₁ F.ε ∘ G.ε) ⊗₁ id ≈⟨ refl⟩∘⟨ refl⟩∘⟨ refl⟩⊗⟨ G.identity ⟨
G.₁ (F.₁ A.λ⇒) ∘ (G.₁ F.φ ∘ G.φ) ∘ (G.₁ F.ε ∘ G.ε) ⊗₁ G.₁ B.id ≈⟨ refl⟩∘⟨ refl⟩∘⟨ split₁ʳ ⟩
G.₁ (F.₁ A.λ⇒) ∘ (G.₁ F.φ ∘ G.φ) ∘ G.₁ F.ε ⊗₁ G.₁ B.id ∘ G.ε ⊗₁ id ≈⟨ refl⟩∘⟨ pullʳ (extendʳ (G.⊗-homo.commute _)) ⟩
G.₁ (F.₁ A.λ⇒) ∘ G.₁ F.φ ∘ G.₁ (F.ε B.⊗₁ B.id) ∘ G.φ ∘ G.ε ⊗₁ id ≈⟨ refl⟩∘⟨ pullˡ (⟺ G.homomorphism) ⟩
G.₁ (F.₁ A.λ⇒) ∘ G.₁ (F.φ B.∘ F.ε B.⊗₁ B.id) ∘ G.φ ∘ G.ε ⊗₁ id ≈⟨ pullˡ ([ G ]-resp-∘ F.unitaryˡ) ⟩
G.₁ B.λ⇒ ∘ G.φ ∘ G.ε ⊗₁ id ≈⟨ G.unitaryˡ ⟩
λ⇒ ∎
unitaryʳ : {X : A.Obj} → G.F₁ (F.F₁ (A.ρ⇒ {X})) ∘ (G.F₁ F.φ ∘ G.φ) ∘ id ⊗₁ (G.F₁ F.ε ∘ G.ε) ≈ ρ⇒
unitaryʳ = begin
G.₁ (F.₁ A.ρ⇒) ∘ (G.₁ F.φ ∘ G.φ) ∘ id ⊗₁ (G.₁ F.ε ∘ G.ε) ≈⟨ refl⟩∘⟨ refl⟩∘⟨ G.identity ⟩⊗⟨refl ⟨
G.₁ (F.₁ A.ρ⇒) ∘ (G.₁ F.φ ∘ G.φ) ∘ G.₁ B.id ⊗₁ (G.₁ F.ε ∘ G.ε) ≈⟨ refl⟩∘⟨ refl⟩∘⟨ split₂ʳ ⟩
G.₁ (F.₁ A.ρ⇒) ∘ (G.₁ F.φ ∘ G.φ) ∘ G.₁ B.id ⊗₁ G.₁ F.ε ∘ id ⊗₁ G.ε ≈⟨ refl⟩∘⟨ pullʳ (extendʳ (G.⊗-homo.commute _)) ⟩
G.₁ (F.₁ A.ρ⇒) ∘ G.₁ F.φ ∘ G.₁ (B.id B.⊗₁ F.ε) ∘ G.φ ∘ id ⊗₁ G.ε ≈⟨ refl⟩∘⟨ pullˡ (⟺ G.homomorphism) ⟩
G.₁ (F.₁ A.ρ⇒) ∘ G.F₁ (F.φ B.∘ (B.id B.⊗₁ F.ε)) ∘ G.φ ∘ id ⊗₁ G.ε ≈⟨ pullˡ ([ G ]-resp-∘ F.unitaryʳ) ⟩
G.F₁ B.ρ⇒ ∘ G.φ ∘ id ⊗₁ G.ε ≈⟨ G.unitaryʳ ⟩
ρ⇒ ∎
module _ (A : MonoidalCategory o ℓ e) (B : MonoidalCategory o′ ℓ′ e′) (C : MonoidalCategory o″ ℓ″ e″) where
private
module A = WithShorthands A
module B = WithShorthands B
module C = WithShorthands C
open M C.U
open MR C.U
∘-IsStrongMonoidal : ∀ {F : Functor A.U B.U} {G : Functor B.U C.U} →
IsStrongMonoidalFunctor B C G → IsStrongMonoidalFunctor A B F →
IsStrongMonoidalFunctor A C (G ∘F F)
∘-IsStrongMonoidal {F} {G} CG CF = record
{ ε = ε
; ⊗-homo = ⊗-homo
; associativity = G∘F.associativity
; unitaryˡ = G∘F.unitaryˡ
; unitaryʳ = G∘F.unitaryʳ
}
where
module F = FunctorShorthands.Strong CF
module G = FunctorShorthands.Strong CG
module G∘F = FunctorShorthands.Lax (∘-IsMonoidal A B C G.isLaxMonoidal F.isLaxMonoidal)
module G∘F-op = FunctorShorthands.Lax (∘-IsMonoidal A.op B.op C.op G.isOplaxMonoidal F.isOplaxMonoidal)
open MP C.U
ε : C.unit ≅ Functor.F₀ (G ∘F F) A.unit
ε = ≅.trans G.ε ([ G ]-resp-≅ F.ε)
⊗-homo : C.⊗ ∘F (G ∘F F ⁂ G ∘F F) ≃ (G ∘F F) ∘F A.⊗
⊗-homo = record
{ F⇒G = G∘F.⊗-homo
; F⇐G = G∘F-op.⊗-homo.op
; iso = λ (X , Y) → Iso-∘ (G.⊗-homo.iso (F.₀ X , F.₀ Y)) ([ G ]-resp-Iso (F.⊗-homo.iso (X , Y)))
}
module _ {A : MonoidalCategory o ℓ e} {B : MonoidalCategory o′ ℓ′ e′} {C : MonoidalCategory o″ ℓ″ e″} where
∘-StrongMonoidal : StrongMonoidalFunctor B C → StrongMonoidalFunctor A B → StrongMonoidalFunctor A C
∘-StrongMonoidal G F = record
{ isStrongMonoidal = ∘-IsStrongMonoidal A B C (isStrongMonoidal G) (isStrongMonoidal F)
}
where
open StrongMonoidalFunctor using (isStrongMonoidal)
∘-Monoidal : MonoidalFunctor B C → MonoidalFunctor A B → MonoidalFunctor A C
∘-Monoidal G F = record { isMonoidal = ∘-IsMonoidal A B C (isMonoidal G) (isMonoidal F) }
where
open MonoidalFunctor using (isMonoidal)
private
module WithCartesianShorthands (C : CartesianCategory o ℓ e) where
open CartesianCategory C public
open BinaryProducts products public renaming (_⁂_ to infixr 10 _×₁_)
open CartesianMonoidal cartesian using (monoidal)
open ⊗-Reasoning monoidal public
open ⊤.Terminal terminal public
module _ (C : CartesianCategory o ℓ e) (D : CartesianCategory o′ ℓ′ e′) where
private
module C = WithCartesianShorthands C
module D = WithCartesianShorthands D
open D hiding (project₁; project₂; unique)
open MR U
module _ (F : StrongMonoidalFunctor C.monoidalCategory D.monoidalCategory) where
private
module F = StrongMonoidalFunctor F
open FunctorShorthands.Strong F.isStrongMonoidal
F-resp-⊤ : ⊤.IsTerminal U (F₀ C.⊤)
F-resp-⊤ = ⊤.Terminal.⊤-is-terminal (⊤.transport-by-iso D.U D.terminal ε)
module F-resp-⊤ = ⊤.IsTerminal F-resp-⊤
lemma₁ : ∀ {X} → F₁ (C.! {X}) ≈ ε⇒ ∘ !
lemma₁ = Equiv.sym (F-resp-⊤.!-unique _)
π₁-comm : ∀ {X Y} → F₁ C.π₁ ∘ φ⇒ {X} {Y} ≈ π₁
π₁-comm = begin
F₁ C.π₁ ∘ φ⇒ ≈⟨ pullˡ ([ F.F ]-resp-∘ (C.project₁ C.○ C.identityˡ)) ⟨
F₁ C.π₁ ∘ F₁ (C.id C.×₁ C.!) ∘ φ⇒ ≈⟨ refl⟩∘⟨ ⊗-homo.⇒.sym-commute _ ⟩
F₁ C.π₁ ∘ φ⇒ ∘ F₁ C.id ×₁ F₁ C.! ≈⟨ refl⟩∘⟨ refl⟩∘⟨ identity ⟩⊗⟨ lemma₁ ⟩
F₁ C.π₁ ∘ φ⇒ ∘ id ×₁ (ε⇒ ∘ !) ≈⟨ refl⟩∘⟨ pushʳ split₂ʳ ⟩
F₁ C.π₁ ∘ (φ⇒ ∘ id ×₁ ε⇒) ∘ id ×₁ ! ≈⟨ pullˡ unitaryʳ ⟩
π₁ ∘ id ×₁ ! ≈⟨ D.project₁ ○ identityˡ ⟩
π₁ ∎
π₂-comm : ∀ {X Y} → F₁ C.π₂ ∘ φ⇒ {X} {Y} ≈ π₂
π₂-comm {X} {Y} = begin
F₁ C.π₂ ∘ φ⇒ ≈⟨ pullˡ ([ F.F ]-resp-∘ (C.project₂ C.○ C.identityˡ)) ⟨
F₁ C.π₂ ∘ F₁ (C.! C.×₁ C.id) ∘ φ⇒ ≈⟨ refl⟩∘⟨ ⊗-homo.⇒.sym-commute _ ⟩
F₁ C.π₂ ∘ φ⇒ ∘ F₁ C.! ×₁ F₁ C.id ≈⟨ refl⟩∘⟨ refl⟩∘⟨ lemma₁ ⟩⊗⟨ identity ⟩
F₁ C.π₂ ∘ φ⇒ ∘ (ε⇒ ∘ !) ×₁ id ≈⟨ refl⟩∘⟨ pushʳ split₁ʳ ⟩
F₁ C.π₂ ∘ (φ⇒ ∘ ε⇒ ×₁ id) ∘ ! ×₁ id ≈⟨ pullˡ unitaryˡ ⟩
π₂ ∘ ! ×₁ id ≈⟨ D.project₂ ○ identityˡ ⟩
π₂ ∎
unique : ∀ {X A B} {h : X ⇒ F₀ (A C.× B)} {i : X ⇒ F₀ A} {j : X ⇒ F₀ B} →
F₁ C.π₁ ∘ h ≈ i →
F₁ C.π₂ ∘ h ≈ j →
φ⇒ ∘ ⟨ i , j ⟩ ≈ h
unique {h = h} {i} {j} eq₁ eq₂ = ⟺ (switch-tofromˡ ⊗-homo.FX≅GX (⟺ (D.unique eq₁′ eq₂′)))
where
eq₁′ : π₁ ∘ φ⇐ ∘ h ≈ i
eq₁′ = pullˡ (⟺ (switch-fromtoʳ ⊗-homo.FX≅GX π₁-comm)) ○ eq₁
eq₂′ : π₂ ∘ φ⇐ ∘ h ≈ j
eq₂′ = pullˡ (⟺ (switch-fromtoʳ ⊗-homo.FX≅GX π₂-comm)) ○ eq₂
project₁ : {A B : C.Obj} {iA : D.Obj} {h : iA D.⇒ F₀ A} {i : iA ⇒ F₀ B} →
F₁ C.π₁ ∘ φ⇒ ∘ ⟨ h , i ⟩ ≈ h
project₁ {h = h} {i} = begin
F.₁ C.π₁ ∘ φ⇒ ∘ ⟨ h , i ⟩ ≈⟨ pullˡ π₁-comm ⟩
π₁ ∘ ⟨ h , i ⟩ ≈⟨ D.project₁ ⟩
h ∎
project₂ : {A B : C.Obj} {iA : Obj} {h : iA ⇒ F₀ A} {i : iA ⇒ F₀ B} →
F₁ C.π₂ ∘ φ⇒ ∘ ⟨ h , i ⟩ ≈ i
project₂ {h = h} {i} = begin
F₁ C.π₂ ∘ φ⇒ ∘ ⟨ h , i ⟩ ≈⟨ pullˡ π₂-comm ⟩
π₂ ∘ ⟨ h , i ⟩ ≈⟨ D.project₂ ⟩
i ∎
StrongMonoidal⇒Cartesian : CartesianF C D
StrongMonoidal⇒Cartesian = record
{ F = F.F
; isCartesian = record
{ F-resp-⊤ = F-resp-⊤
; F-resp-× = λ {A B} → record
{ ⟨_,_⟩ = λ f g → φ⇒ ∘ ⟨ f , g ⟩
; project₁ = project₁ {A} {B}
; project₂ = project₂ {A} {B}
; unique = unique
}
}
}