module Cat.Functor.FullSubcategory {o h} {C : Precategory o h} where
Full subcategories🔗
A full subcategory of some larger category is the category generated by some predicate on the objects of of : You keep only those objects for which holds, and all the morphisms between them. An example is the category of abelian groups, as a full subcategory of groups: being abelian is a proposition (there’s “at most one way for a group to be abelian”).
We can interpret full subcategories, by analogy, as being the “induced subgraphs” of the categorical world: Keep only some of the vertices (objects), but all of the arrows (arrows) between them.
record Restrict-ob (P : C.Ob → Type ℓ) : Type (o ⊔ ℓ) where
no-eta-equality
constructor restrict
field
: C.Ob
object : P object
witness
open Restrict-ob public
: (P : C.Ob → Type ℓ)
Restrict → Precategory (o ⊔ ℓ) h
.Ob = Restrict-ob P
Restrict P .Hom A B = C.Hom (A .object) (B .object)
Restrict P .Hom-set _ _ = C.Hom-set _ _
Restrict P .id = C.id
Restrict P ._∘_ = C._∘_
Restrict P .idr = C.idr
Restrict P .idl = C.idl
Restrict P .assoc = C.assoc Restrict P
A very important property of full subcategories (Restrict
ions) is that any full
subcategory of a univalent category is
univalent. The argument is roughly as follows: Since
is univalent, an isomorphism
gives us a path
,
so in particular if we know
and
,
then we have
.
But, since the morphisms in the full subcategory coincide with those of
,
any iso in the subcategory is an iso in
,
thus a path!
module _ (P : C.Ob → Type ℓ) where
import Cat.Reasoning (Restrict P) as R
We begin by translating between isomorphisms in the subcategory (called here) and in , which can be done by destructuring and reassembling:
: ∀ {A B : Restrict-ob P} → (A R.≅ B) → (A .object C.≅ B .object)
sub-iso→super-iso = C.make-iso x.to x.from x.invl x.invr
sub-iso→super-iso x where module x = R._≅_ x
: ∀ {A B : Restrict-ob P} → (A .object C.≅ B .object) → (A R.≅ B)
super-iso→sub-iso = R.make-iso y.to y.from y.invl y.invr
super-iso→sub-iso y where module y = C._≅_ y
module _ (P : C.Ob → Type ℓ) (pprop : ∀ x → is-prop (P x))
where
import Cat.Reasoning (Restrict P) as R
We then prove that object-isomorphism pairs in the subcategory (i.e. inhabitants of ) coincide with those in the supercategory; Hence, since is by assumption univalent, so is .
: is-category C → is-category (Restrict P)
Restrict-is-category = λ where
Restrict-is-category cids .to-path im i .object → Univalent.iso→path cids (sub-iso→super-iso P im) i
.to-path {a = a} {b = b} im i .witness → is-prop→pathp
(λ i → pprop (cids .to-path (sub-iso→super-iso P im) i))
(a .witness) (b .witness) i
.to-path-over p → R.≅-pathp _ _ λ i → cids .to-path-over (sub-iso→super-iso P p) i .C.to
From full inclusions🔗
There is another way of representing full subcategories: By giving a full inclusion, i.e. a fully faithful functor . Each full inclusion canonically determines a full subcategory of , namely that consisting of the objects in merely in the image of .
module _ {o' h'} {D : Precategory o' h'} {F : Functor D C} (ff : is-fully-faithful F) where
open Functor F
: Precategory _ _
Full-inclusion→Full-subcat =
Full-inclusion→Full-subcat (λ x → ∃[ d ∈ Ob D ] (F₀ d C.≅ x)) Restrict
This canonical full subcategory is weakly equivalent to , meaning that it admits a fully faithful, essentially surjective functor from . This functor is actually just again:
: Functor D Full-inclusion→Full-subcat
Ff-domain→Full-subcat .Functor.F₀ x = restrict (F₀ x) (inc (x , C.id-iso))
Ff-domain→Full-subcat .Functor.F₁ = F₁
Ff-domain→Full-subcat .Functor.F-id = F-id
Ff-domain→Full-subcat .Functor.F-∘ = F-∘
Ff-domain→Full-subcat
: is-fully-faithful Ff-domain→Full-subcat
is-fully-faithful-domain→Full-subcat = ff
is-fully-faithful-domain→Full-subcat
: is-eso Ff-domain→Full-subcat
is-eso-domain→Full-subcat =
is-eso-domain→Full-subcat yo (λ (preimg , isom) → preimg , super-iso→sub-iso _ isom)
∥-∥-map (yo .witness)
Up to weak equivalence, admitting a full inclusion is equivalent to being a full subcategory: Every full subcategory admits a full inclusion, given on objects by projecting the first component and on morphisms by the identity function.
module _ {P : C.Ob → Type ℓ} where
: Functor (Restrict P) C
Forget-full-subcat .Functor.F₀ = object
Forget-full-subcat .Functor.F₁ f = f
Forget-full-subcat .Functor.F-id = refl
Forget-full-subcat .Functor.F-∘ f g i = f C.∘ g
Forget-full-subcat
: is-fully-faithful Forget-full-subcat
is-fully-faithful-Forget-full-subcat = id-equiv is-fully-faithful-Forget-full-subcat