module Prelude.Category.Pullback where
open import Prelude.Category
open import Prelude.Category.Isomorphism
open import Prelude.Category.Isomorphism.Functor
open import Prelude.Category.Slice
open import Prelude.Category.Span
open import Level
open import Function using (_∘_)
open import Data.Product using (Σ; Σ-syntax; _,_; proj₁; proj₂; _×_)
open import Relation.Binary using (module Setoid)
open import Relation.Binary.PropositionalEquality using (_≡_; refl)
import Relation.Binary.EqReasoning as EqReasoning
open Category
open Functor
SquareCategory : {ℓ₀ ℓ₁ ℓ₂ : Level} (C : Category {ℓ₀} {ℓ₁} {ℓ₂}) {B : Object C} (f g : Slice C B) → Category
SquareCategory C {B} f g = SpanCategory (SliceCategory C B) f g
Square : {ℓ₀ ℓ₁ ℓ₂ : Level} (C : Category {ℓ₀} {ℓ₁} {ℓ₂}) {B : Object C} (f g : Slice C B) → Set (ℓ₀ ⊔ ℓ₁ ⊔ ℓ₂)
Square C f g = Object (SquareCategory C f g)
SquareMorphism : {ℓ₀ ℓ₁ ℓ₂ : Level} (C : Category {ℓ₀} {ℓ₁} {ℓ₂}) {B : Object C} (f g : Slice C B) (q r : Square C f g) → Set (ℓ₁ ⊔ ℓ₂)
SquareMorphism C f g q r = Setoid.Carrier (Morphism (SquareCategory C f g) q r)
Square-T : {ℓ₀ ℓ₁ ℓ₂ : Level} {C : Category {ℓ₀} {ℓ₁} {ℓ₂}} {B : Object C} {f g : Slice C B} → Square C f g → Object C
Square-T = Slice.T ∘ Span.M
SquareMorphism-m : {ℓ₀ ℓ₁ ℓ₂ : Level} {C : Category {ℓ₀} {ℓ₁} {ℓ₂}} {B : Object C} {f g : Slice C B} {q r : Square C f g} →
SquareMorphism C f g q r → Setoid.Carrier (Morphism C (Square-T q) (Square-T r))
SquareMorphism-m = SliceMorphism.m ∘ SpanMorphism.m
SquareMap : {ℓ₀ ℓ₁ ℓ₂ : Level} {C : Category {ℓ₀} {ℓ₁} {ℓ₂}} {B : Object C} {f g : Slice C B} {ℓ₃ ℓ₄ ℓ₅ : Level} {D : Category {ℓ₃} {ℓ₄} {ℓ₅}}
(F : Functor C D) → Functor (SquareCategory C f g) (SquareCategory D (Functor.object (SliceMap F) f) (Functor.object (SliceMap F) g))
SquareMap F = SpanMap (SliceMap F)
Pullback : {ℓ₀ ℓ₁ ℓ₂ : Level} (C : Category {ℓ₀} {ℓ₁} {ℓ₂}) {B : Object C} (f g : Slice C B) → Square C f g → Set (ℓ₀ ⊔ ℓ₁ ⊔ ℓ₂)
Pullback C {B} = Product (SliceCategory C B)
pullback-iso : {ℓ₀ ℓ₁ ℓ₂ : Level} (C : Category {ℓ₀} {ℓ₁} {ℓ₂}) {B : Object C} (f g : Slice C B) →
(s t : Square C f g) → Pullback C f g s → Pullback C f g t → Iso C (Square-T s) (Square-T t)
pullback-iso C {B} f g s t pb-s pb-t =
iso-preserving SliceU (iso-preserving SpanU (terminal-iso (SpanCategory (SliceCategory C B) f g) s t pb-s pb-t))
Pullback-preserving :
{ℓ₀ ℓ₁ ℓ₂ ℓ₃ ℓ₄ ℓ₅ : Level} {C : Category {ℓ₀} {ℓ₁} {ℓ₂}} {D : Category {ℓ₃} {ℓ₄} {ℓ₅}} → (F : Functor C D) → Set (ℓ₀ ⊔ ℓ₁ ⊔ ℓ₂ ⊔ ℓ₃ ⊔ ℓ₄ ⊔ ℓ₅)
Pullback-preserving {C = C} {D} F =
{B : Object C} (f g : Slice C B) (s : Square C f g) → Pullback C f g s →
Pullback D (object (SliceMap F) f) (object (SliceMap F) g) (object (SpanMap (SliceMap F)) s)
particular-pullback-preservation :
{ℓ₀ ℓ₁ ℓ₂ ℓ₃ ℓ₄ ℓ₅ : Level} {C : Category {ℓ₀} {ℓ₁} {ℓ₂}} {D : Category {ℓ₃} {ℓ₄} {ℓ₅}} (F : Functor C D) →
({B : Object C} (f g : Slice C B) → Σ[ s ∈ Square C f g ] (Pullback C f g s × Pullback D (object (SliceMap F) f) (object (SliceMap F) g) (object (SquareMap F) s))) →
Pullback-preserving F
particular-pullback-preservation {C = C} {D} F particular {B} f g s' ps' =
let s = proj₁ (particular f g)
in iso-terminal (SquareCategory D (object (SliceMap F) f) (object (SliceMap F) g))
(object (SquareMap F) s)
(object (SquareMap F) s')
(proj₂ (proj₂ (particular f g)))
(iso-preserving (SquareMap F) (terminal-iso (SquareCategory C f g) s s' (proj₁ (proj₂ (particular f g))) ps'))
Pullback-reflecting :
{ℓ₀ ℓ₁ ℓ₂ ℓ₃ ℓ₄ ℓ₅ : Level} {C : Category {ℓ₀} {ℓ₁} {ℓ₂}} {D : Category {ℓ₃} {ℓ₄} {ℓ₅}} → (F : Functor C D) → Set (ℓ₀ ⊔ ℓ₁ ⊔ ℓ₂ ⊔ ℓ₃ ⊔ ℓ₄ ⊔ ℓ₅)
Pullback-reflecting {C = C} {D} F =
{B : Object C} (f g : Slice C B) (s : Square C f g) →
Pullback D (object (SliceMap F) f) (object (SliceMap F) g) (object (SpanMap (SliceMap F)) s) → Pullback C f g s