Zulip Chat Archive
Stream: Infinity-Cosmos
Topic: alternate (defeq) `nerve` definition
Thomas Murrills (May 30 2025 at 21:23):
I was working on #25010 and trying to understand the definition of nerve, and realized it could be written directly in terms of the yoneda embedding, with no reference to ComposableArrows. Now, that might not be desirable, since I'm guessing there are lemmas about ComposableArrows! :) But thought I'd share in case it's of any interest or belongs anywhere.
Something of some minor interest here is a universe-polymorphic version of the yoneda embedding specifically for Cat (relying on Functor instead of Hom) which seems necessary for this to work. (Does this exist already somewhere?)
import Mathlib.AlgebraicTopology.SimplicialSet.Basic
import Mathlib.CategoryTheory.ComposableArrows
open CategoryTheory.Category Simplicial
namespace CategoryTheory
def Cat.yoneda.{v', u', v, u} : Cat.{v, u} ⥤ Cat.{v', u'}ᵒᵖ ⥤ Type (max u v u' v') where
obj X :=
{ obj := fun Y => Y.unop ⥤ X
map := fun f g => f.unop ⋙ g
}
map f :=
{ app := fun _ g => g ⋙ f }
universe v u
@[simps!] -- necessary?
def nerveYoneda (C : Type (u)) [Category.{v} C] : SSet.{max u v} :=
SimplexCategory.toCat.op ⋙ Cat.yoneda.obj (.of C)
-- Current definition
/-- The nerve of a category -/
@[simps]
def nerve (C : Type u) [Category.{v} C] : SSet.{max u v} where
obj Δ := ComposableArrows C (Δ.unop.len)
map f x := x.whiskerLeft (SimplexCategory.toCat.map f.unop)
-- `aesop` can prove these but is slow, help it out:
map_id _ := rfl
map_comp _ _ := rfl
theorem nerveYoneda_eq_nerve : nerveYoneda = nerve := rfl
end CategoryTheory
Thomas Murrills (May 30 2025 at 21:32):
Aside: I also wrote down the defs for functorially lifting Cat.{u,v} to Cat.{max u u', max v v'}, planning to insert it as a functor between SimplexCategory.toCat.op and the regular yoneda.
This turned out to be awkward, and rewriting yoneda for Cat was nicer. But I'll put it here in case anyone ever needs it and searches Zulip for inspiration... :)
Note: ULiftCat is similar to ULiftHom, but effectively lifts the whole category, objects and arrows, at once.
ulift for Cat
Emily Riehl (May 31 2025 at 12:27):
Conceptually, it seems simpler to have something like ULiftCat to lift the whole category at once, but maybe there's a design reason I don't know that this is a bad idea? I'd be curious for others to weigh in.
I wonder, though, if the order of your universe arguments should be permuted to match the usual convention for Cat.{v,u} with the v for the homs and the u for the objects.
Emily Riehl (May 31 2025 at 12:29):
I'm quite surprised by
theorem nerveYoneda_eq_nerve : nerveYoneda = nerve := rfl
given how many composites go into SimplexCategory.toCat. @Joël Riou could you comment?
Kevin Buzzard (May 31 2025 at 13:04):
theorem nerveYoneda_eq_nerve : nerveYoneda = nerve := by
unfold nerveYoneda nerve
ext 𝓒 h𝓒
dsimp
unfold ComposableArrows
-- are functors identical?
apply Functor.ext -- just to see what's going on
· -- are morphisms identical?
dsimp
intro X Y f
unfold ComposableArrows.whiskerLeft
unfold Cat.yoneda
dsimp
rw [comp_id, id_comp] -- I am slightly confused about why these are `rfl` here
-- ⊢ (fun g => ⋯.functor ⋙ g) = fun x => ⋯.functor ⋙ x
-- `⋯.functor` means `Monotone.functor` here
rfl
· -- are objects identical?
intro X
dsimp
unfold Cat.yoneda
dsimp
unfold forget₂ HasForget₂.forget₂ PartOrd.hasForgetToPreord
dsimp
unfold Lat.hasForgetToPartOrd
dsimp
unfold LinOrd.hasForgetToLat
dsimp
unfold NonemptyFinLinOrd.hasForgetToLinOrd
dsimp
unfold InducedCategory.hasForget₂
dsimp only
unfold inducedFunctor NonemptyFinLinOrd.toLinOrd NonemptyFinLinOrd.of
-- RHS is `Fin ((Opposite.unop X).len + 1) ⥤ 𝓒`
conv_lhs =>
dsimp -- LHS is also `Fin ((Opposite.unop X).len + 1) ⥤ 𝓒`
You can close any goal at any point with rfl and it gets harder and harder to stop Lean from closing the goal the more you unfold.
Joël Riou (May 31 2025 at 13:15):
In basic concrete categories, compositions with identities are rfl, which makes rfl a quite powerful tactic...
Thomas Murrills (Jun 01 2025 at 22:23):
Emily Riehl said:
I wonder, though, if the order of your universe arguments should be permuted to match the usual convention for
Cat.{v,u}with thevfor the homs and theufor the objects.
They should! :grinning_face_with_smiling_eyes: (I realized that v came before u everywhere only after writing this code, but only went back to edit Cat.yoneda...)
Thomas Murrills (Jun 01 2025 at 23:08):
(Also, I'm realizing that Functor.up should (after swapping the order of universes in ULiftCat) not insist that the universes of the two categories are the same:)
@[simps]
def Functor.up.{v'₁, u'₁, v'₂, u'₂, v₁, u₁, v₂, u₂} {X : Type u₁} {Y : Type u₂}
[Category.{v₁} X] [Category.{v₂} Y] (F : X ⥤ Y) :
ULiftCat.{v'₁, u'₁} X ⥤ ULiftCat.{v'₂, u'₂} Y where
obj := fun ⟨x⟩ => ULift.up <| F.obj x
map := fun ⟨f⟩ => ULift.up <| F.map f
Last updated: Dec 20 2025 at 21:32 UTC