Zulip Chat Archive
Stream: Infinity-Cosmos
Topic: the coherent isomorphism
Emily Riehl (Sep 16 2024 at 21:57):
A preliminary version of the homotopy coherent isomorphism is defined in a branch. We defined everything inductively and then proved a few simple lemmas with very inefficient inductive proofs. Golfing suggestions are very welcome. I'm also trying to determine whether walkingIso
is already in mathlib.
Joël Riou (Sep 17 2024 at 00:43):
I would not think walkingIso
is already in mathlib, but is not it true that in this category, given two objects X
and Y
, there is exactly one morphisms from X
to Y
, in which case the definition of Hom
could be just Unit
:
def category (A : Type u) : Category A where
-- `A` should be replaced by a type-synonym in order to make an instance out of this
Hom _ _ := Unit
id _ := ⟨⟩
comp _ _ := ⟨⟩
Is there a canonical name for such a "contractible" category with a given set of objects A
?
Joël Riou (Sep 17 2024 at 00:53):
Then, the main construction becomes:
inductive WalkingIso : Type where
| zero
| one
instance : Category WalkingIso where
Hom _ _ := Unit
id _ := ⟨⟩
comp _ _ := ⟨⟩
def WalkingIso.ofIso {C : Type u} [Category.{v} C] {X Y : C} (e : X ≅ Y) :
WalkingIso ⥤ C where
obj := fun
| zero => X
| one => Y
map := @fun
| zero, zero, _ => 𝟙 _
| zero, one, _ => e.hom
| one, zero, _ => e.inv
| one, one, _ => 𝟙 _
Emily Riehl (Sep 17 2024 at 16:35):
Joël Riou said:
I would not think
walkingIso
is already in mathlib, but is not it true that in this category, given two objectsX
andY
, there is exactly one morphisms fromX
toY
, in which case the definition ofHom
could be justUnit
:def category (A : Type u) : Category A where -- `A` should be replaced by a type-synonym in order to make an instance out of this Hom _ _ := Unit id _ := ⟨⟩ comp _ _ := ⟨⟩
Is there a canonical name for such a "contractible" category with a given set of objects
A
?
I've seen it called the "indiscrete" or "chaotic" category, though "contractible" is perhaps an even better term. This defines the right adjoint to the forgetful functor ob : Cat -> Set
, whose right adjoint is given by the discrete category construction.
It seems to me that this notion isn't in mathlib either. I have some students who are looking for a beginner project, so I might suggest this to them: define such categories (mirroring the existing definition of discrete categories) and construct these adjunctions.
Adam Topaz (Sep 17 2024 at 16:42):
@Emily Riehl we do have docs#CategoryTheory.Discrete
Adam Topaz (Sep 17 2024 at 16:43):
Oh, I see, you're referring to the adjunction. Yes, you're right, we probably don't have that, although the API for Discrete
does essentially give you the adjunction via docs#CategoryTheory.Discrete.functor docs#CategoryTheory.Discrete.natTrans etc.
Emily Riehl (Sep 17 2024 at 17:14):
Yes, I should have been clearer. Thanks for the suggestion.
Emily Riehl (Sep 17 2024 at 17:30):
Joël Riou said:
Then, the main construction becomes:
inductive WalkingIso : Type where | zero | one instance : Category WalkingIso where Hom _ _ := Unit id _ := ⟨⟩ comp _ _ := ⟨⟩ def WalkingIso.ofIso {C : Type u} [Category.{v} C] {X Y : C} (e : X ≅ Y) : WalkingIso ⥤ C where obj := fun | zero => X | one => Y map := @fun | zero, zero, _ => 𝟙 _ | zero, one, _ => e.hom | one, zero, _ => e.inv | one, one, _ => 𝟙 _
Could you explain @fun
? In general, I don't know how to efficiently induct over multiple parameters, particularly implicit ones like we have here.
Adam Topaz (Sep 17 2024 at 17:31):
@fun
makes all the implicit variables explicit.
Adam Topaz (Sep 17 2024 at 17:32):
in this case (I think) you can just replace map := @fun
with map
(untested)
Emily Riehl (Sep 17 2024 at 17:33):
That's giving me a type mismatch error.
Adam Topaz (Sep 17 2024 at 17:34):
Ok, I was wrong. Anyway, maybe this version is clearer?
def WalkingIso.ofIso {C : Type u} [Category.{v} C] {X Y : C} (e : X ≅ Y) :
WalkingIso ⥤ C where
obj x :=
match x with
| zero => X
| one => Y
map {x y} f :=
match x, y, f with
| zero, zero, _ => 𝟙 _
| zero, one, _ => e.hom
| one, zero, _ => e.inv
| one, one, _ => 𝟙 _
Adam Topaz (Sep 17 2024 at 17:35):
The point is that the map
field only has the morphism as an explicit parameter, with the two objects implicit. Doing @fun
makes everything explicit, or alternatively you can match explicitly on the objects and morphism as I have done above.
Adam Topaz (Sep 17 2024 at 17:46):
One subtle point to note is that you can't use recursion when defining a projection in a structure like this (IMO this is a defect that should be addressed). Here is an example illustrating how to get around this:
structure F where
f : Nat → Nat
def ff : F where
f := aux
where aux
| 0 => 0
| n+1 => aux n
/-
Lean can't show termination for this:
def gg : F where
f | 0 => 0
| n+1 => gg.f n
-/
Emily Riehl (Sep 17 2024 at 17:48):
Thanks this is a helpful explanation. A question I was asked in my tutorial yesterday that I couldn't answer was whether there's a way to get lean to automatically generate the cases for an induction (like Agda does). After I type match blah with I've been typing out the "| case => sorry" stuff manually for each case.
Emily Riehl (Sep 17 2024 at 17:48):
I know if you type "induction X Y" then you see the cases in infoview, but I find proofs written with "match X Y" to be much more readable.
Adam Topaz (Sep 17 2024 at 17:49):
Yes, that's done with code-actions. In vscode if you get the yellow lightbulb to pop up, one of the options would be "generate skeleton for recursive definition" (approx) as one of the options.
Adam Topaz (Sep 17 2024 at 17:49):
We don't have Agda's nice hole commands for case splitting on specific terms as far as I know.
Adam Topaz (Sep 17 2024 at 17:51):
For example, in the following
import Mathlib.Tactic
def f : Nat → Nat := _
if you put the cursor at the _
, you should get such a lightbulb.
Adam Topaz (Sep 17 2024 at 17:52):
And indeed it seems that we don't have a nice code action for matching as in the following example
import Mathlib.Tactic
def f (x : Nat) : Nat :=
match x with
I wish we did have such an action though!
Emily Riehl (Sep 17 2024 at 18:14):
One more (unrelated) question, while you're here. Do you know who accepts pull requests on the Lean blog? @herostrat made an announcement of this project for me, which is ready to go live if it meets with the moderators' approval:
https://github.com/leanprover-community/blog/pull/91
Kevin Buzzard (Sep 17 2024 at 18:32):
I don't know who is allowed to pull the trigger but I left an approving review and raised a minor issue.
Emily Riehl (Sep 23 2024 at 22:01):
There's a new file CoherentIso.lean which incorporates the suggestions made by several folks here. @Alvaro Belmonte just contributed his very first lean code, in the file CodiscreteCat.lean on codiscrete categories.
Emily Riehl (Sep 23 2024 at 22:03):
It would be good to PR the codiscrete stuff to mathlib at some point, so feedback here would be very helpful. In particular, Alvaro gives two proofs that the codiscrete category functor is right adjoint to the object functor. I wasn't sure which is best. He could extract the data of the other and leave it as auxiliary definitions/theorems.
Emily Riehl (Sep 23 2024 at 22:05):
/-- A function induces a functor between codiscrete categories.-/
def funToFunc {A B : Type u} (f : A → B) : Codiscrete A ⥤ Codiscrete B where
obj a := f a
map _ := ⟨⟩
def functor : Type u ⥤ Cat.{0,u} where
obj A := Cat.of (Codiscrete A)
map := funToFunc
open Adjunction Cat
/-- For a category `C` and type `A`, there is an equivalence between functions `objects.obj C ⟶ A`
and functors `C ⥤ Codiscrete A`.-/
def homEquiv' (C : Cat) (A : Type*) : (objects.obj C ⟶ A) ≃ (C ⟶ functor.obj A) where
toFun := lift
invFun := invlift
left_inv _ := rfl
right_inv _ := rfl
/-- The functor that turns a type into a codiscrete category is right adjoint to the objects
functor.-/
def adj : objects ⊣ functor := mkOfHomEquiv
{
homEquiv := homEquiv'
homEquiv_naturality_left_symm := fun _ _ => Eq.refl _
homEquiv_naturality_right := fun _ _ => Eq.refl _
}
/-- A second proof of the same adjunction. -/
def adj' : Cat.objects ⊣ functor where
unit := {
app := fun _ => {
obj := fun _ => _
map := fun _ => ⟨⟩
}
}
counit := {
app := fun _ => id
}
left_triangle_components := by
intro _
simp only [Functor.id_obj, Functor.comp_obj, id_eq]
rfl
right_triangle_components := by
intro _
simp only [Functor.id_obj, Functor.comp_obj, id_eq]
rfl
Dagur Asgeirsson (Sep 23 2024 at 22:08):
adj'
looks like aesop
can take care of the triangle identities (if that's the case the fields can be erased)
Alvaro Belmonte (Sep 26 2024 at 20:35):
I finish doing the PR# #17174 of codiscrete categories to mathlib. Since I am still pretty new to lean I don't know what else I could tackle, if there is anything else I could do for the project any pointers would be greatly appreciated.
Last updated: May 02 2025 at 03:31 UTC