module Cat.Functor.WideSubcategory {o h} {C : Precategory o h} where

Wide subcategories🔗

A wide subcategory DC\mathcal{D} \hookrightarrow \mathcal{C} is specified by a predicate PP on the morphisms of C\mathcal{C}, rather than one on the objects. Since PP is nontrivial, we must take care that the result actually form a category: PP must contain the identities and be closed under composition.

To start, we package up all the data required to define a wide subcategory up into a record.

record Wide-subcat (: Level) : Type (o ⊔ h ⊔ lsuc ℓ) where
  no-eta-equality
  field
    P      :  {x y}  C.Hom x y  Type ℓ
    P-prop :  {x y} (f : C.Hom x y)  is-prop (P f)

    P-id :  {x}  P (C.id {x})
    P-∘  :  {x y z} {f : C.Hom y z} {g : C.Hom x y}
          P f  P g  P (f C.∘ g)

open Wide-subcat

Morphisms of wide subcategories are defined as morphisms in C\mathcal{C} where PP holds.

record Wide-hom (sub : Wide-subcat ℓ) (x y : C.Ob) : Type (h ⊔ ℓ) where
  no-eta-equality
  constructor wide
  field
    hom : C.Hom x y
    witness : sub .P hom

We can then use this data to construct a category.

Wide : Wide-subcat ℓ  Precategory o (h ⊔ ℓ)
Wide sub .Ob = C.Ob
Wide sub .Hom         = Wide-hom sub
Wide sub .Hom-set _ _ = Wide-hom-is-set

Wide sub .id .hom     = C.id
Wide sub .id .witness = sub .P-id

Wide sub .__ f g .hom     = f .hom C.∘ g .hom
Wide sub .__ f g .witness = sub .P-∘ (f .witness) (g .witness)

Wide sub .idr _ = ext $ C.idr _
Wide sub .idl _ = ext $ C.idl _
Wide sub .assoc _ _ _ = ext $ C.assoc _ _ _

From split essentially surjective inclusions🔗

There is another way of representing wide subcategories: By giving a pseudomonic split essential surjection F:DCF : \mathcal{D} \twoheadrightarrow \mathcal{C}.

We construct the wide subcategory by restricting to the morphisms in C\mathcal{C} that lie in the image of FF. Since FF is a faithful functor, this is indeed a proposition.

  Split-eso-inclusion→Wide-subcat : Precategory _ _
  Split-eso-inclusion→Wide-subcat = Wide sub where
    sub : Wide-subcat (h ⊔ h')
    sub .P {x = x} {y = y} f =
      Σ[ g ∈ D.Hom (eso x .fst) (eso y .fst) ]
      (eso.to y C.∘ F₁ g C.∘ eso.from x ≡ f)
    sub .P-prop {x} {y} f (g , p) (g' , q) =
      Σ-prop-path  _  C.Hom-set _ _ _ _) $
      is-pseudomonic.faithful pseudomonic   $
      C.iso→epic (eso x .snd C.Iso⁻¹) _ _   $
      C.iso→monic (eso y .snd) _ _ (p ∙ sym q)
    sub .P-id {x} =
      (D.id , ap₂ C.__ refl (C.eliml F-id) ∙ C.invl (eso x .snd))
    sub .P-∘ {x} {y} {z} {f} {g} (f' , p) (g' , q) =
      f' D.∘ g' , (
        eso.to z C.∘ F₁ (f' D.∘ g') C.∘ eso.from x                                    ≡⟨ C.push-inner (F-∘ f' g')
        (eso.to z C.∘ F₁ f') C.(F₁ g' C.∘ eso.from x)                               ≡⟨ C.insert-inner (eso.invr y)
        ((eso.to z C.∘ F₁ f') C.∘ eso.from y) C.(eso.to y C.∘ F₁ g' C.∘ eso.from x) ≡⟨ ap₂ C.__ (sym (C.assoc _ _ _) ∙ p) q ⟩
        f C.∘ g ∎)

This canonical wide subcategory is equivalent to D\mathcal{D}.

  Wide-subcat→Split-eso-domain : Functor (Split-eso-inclusion→Wide-subcat) D
  Wide-subcat→Split-eso-domain .Functor.F₀ x = eso x .fst
  Wide-subcat→Split-eso-domain .Functor.F₁ f = f .witness .fst
  Wide-subcat→Split-eso-domain .Functor.F-id = refl
  Wide-subcat→Split-eso-domain .Functor.F-∘ _ _ = refl

  is-fully-faithful-Wide-subcat→domain : is-fully-faithful Wide-subcat→Split-eso-domain
  is-fully-faithful-Wide-subcat→domain = is-iso→is-equiv $ iso
     f  wide (eso.to _ C.∘ F₁ f C.∘ eso.from _) (f , refl))
     _  refl)
     f  ext (f .witness .snd))

  is-eso-Wide-subcat→domain : is-split-eso Wide-subcat→Split-eso-domain
  is-eso-Wide-subcat→domain x =
    F₀ x , pseudomonic→essentially-injective pseudomonic (eso (F₀ x) .snd)

We did cheat a bit earlier when defining wide subcategories: our predicate isn’t required to respect isomorphisms! This means that we could form a “subcategory” that kills off all the isomorphisms, which allows us to distinguish between isomorphic objects. Therefore, wide subcategories are not invariant under equivalence of categories.

This in turn means that the forgetful functor from a wide subcategory is not pseudomonic! To ensure that it is, we need to require that the predicate holds on all isomorphisms. Arguably this is something that should be part of the definition of a wide subcategory, but it isn’t strictly required, so we opt to leave it as a side condition.

  Forget-wide-subcat : Functor (Wide sub) C
  Forget-wide-subcat .Functor.F₀ x = x
  Forget-wide-subcat .Functor.F₁ f = f .hom
  Forget-wide-subcat .Functor.F-id = refl
  Forget-wide-subcat .Functor.F-∘ _ _ = refl

  is-faithful-Forget-wide-subcat : is-faithful Forget-wide-subcat
  is-faithful-Forget-wide-subcat = Wide-hom-path

  is-pseudomonic-Forget-wide-subcat
    : (P-invert :  {x y} {f : C.Hom x y}  C.is-invertible f  sub .P f)
     is-pseudomonic Forget-wide-subcat
  is-pseudomonic-Forget-wide-subcat P-invert .is-pseudomonic.faithful =
    is-faithful-Forget-wide-subcat
  is-pseudomonic-Forget-wide-subcat P-invert .is-pseudomonic.isos-full f =
    pure $
      Wide.make-iso
        (wide f.to (P-invert (C.iso→invertible f)))
        (wide f.from (P-invert (C.iso→invertible (f C.Iso⁻¹))))
        (ext f.invl)
        (ext f.invr) ,
      C.≅-pathp refl refl refl
    where module f = C.__ f

  is-split-eso-Forget-wide-subcat : is-split-eso Forget-wide-subcat
  is-split-eso-Forget-wide-subcat y = y , C.id-iso