Zulip Chat Archive
Stream: mathlib4
Topic: Encoding of categories and equality of hom-set
Nicolas Rolland (Jul 22 2024 at 14:33):
I am wondering how to use Functor.ext
As a exercise, given F = G
, how can one use Functor.ext
to prove that F = G
?
aesop_cat
succeeds. is there any way to see the steps it takes ? set_option trace.aesop true
import Mathlib.CategoryTheory.Category.Cat
open CategoryTheory
universe v u
variable {C D : Cat.{u,v}}
variable (F G : C ⥤ D)
-- what does F = G mean ?
def usingFunctorEq ( h : F = G) : F = G :=
have h_obj (x : C) : F.obj x = G.obj x := sorry
have h_map (x y : C) (f : x ⟶ y) : F.map f = eqToHom (h_obj x) ≫ G.map f ≫ eqToHom (h_obj y).symm := sorry
Functor.ext h_obj h_map
More discussion :
The encoding of categories creates a type for each hom-set for each pair of object :
Given a category C
, x ⟶ y
is the type of those morphisms in C
which go from x
to y
. With this encoding, any morphism has explicit type level domain and codomain.
While having strong type constraint is very handy in most cases, when proving equality of functors it becomes a bit of a problem :
To prove that two functors are equal, one should prove that objets are sent to the same objects, and morphisms are sent to the same morphism.
Said otherwise, to prove that F = G : C ⥤ D
, one has to prove F.obj x = G.obj x
for every x : C
, and F.map f = G.map f
for every f : x ⟶ y
.
But F.map f = G.map f
is type incorrect : F.map f : F.obj x ⟶ F.obj y
while G.map f : G.obj x ⟶ G.obj y
.
That's why the signature of Functor.ext
is
Functor.ext
(h_obj : ∀ X, F.obj X = G.obj X)
(h_map : ∀ X Y f, F.map f = eqToHom (h_obj X) ≫ G.map f ≫ eqToHom (h_obj Y).symm) : F = G
Taking the equivalent point of view of categories as monad of span(set), with a less typed morphisms for a category, one could go around that problem and equivalently prove F.map f = G.map f
, F.obj (dom f) = G.obj (dom f)
and F.obj (cod f) = G.obj (cod f)
.
Being able to switch between the 2 representations for categories (explicitely typed hom-set VS implicitly typed) might be useful ?
Nicolas Rolland (Jul 22 2024 at 19:00):
With set_option trace.aesop.proof true
one can view the proof for the equality of hom maps given the equality of functors.... and the given proof does not type check unfortunately
This translates, according the the trace
import Mathlib.CategoryTheory.Category.Cat
open CategoryTheory
universe v u
variable {C D : Cat.{u,v}}
variable (F G : C ⥤ D)
set_option trace.aesop true
set_option trace.aesop.proof true
def usingFunctorEq ( h : F = G) : F = G :=
have h_obj (x : C) : F.obj x = G.obj x := by rw [h]
have h_map (x y : C) (f : x ⟶ y) : F.map f = eqToHom (h_obj x) ≫ G.map f ≫ eqToHom (h_obj y).symm := by
aesop
Functor.ext h_obj h_map
to this funky program
import Mathlib.CategoryTheory.Category.Cat
open CategoryTheory
universe v u
variable {C D : Cat.{u,v}}
variable (F G : C ⥤ D)
set_option trace.aesop true
set_option trace.aesop.proof true
def usingFunctorEq ( h : F = G) : F = G :=
have h_obj (x : C) : F.obj x = G.obj x := by rw [h]
have h_map (x y : C) (f : x ⟶ y) : F.map f = eqToHom (h_obj x) ≫ G.map f ≫ eqToHom (h_obj y).symm :=
Eq.ndrec (motive := fun G ↦
∀ (h_obj : ∀ (x : ↑C), F.obj x = G.obj x),
F.map f = CategoryTheory.eqToHom (h_obj x) ≫ G.map f ≫ CategoryTheory.eqToHom (Eq.symm (h_obj y)))
(fun h_obj ↦
of_eq_true
(Eq.trans
(congrArg (Eq (F.map f))
(Eq.trans
(congrArg (CategoryTheory.CategoryStruct.comp (𝟙 (F.obj x)))
(CategoryTheory.Category.comp_id (F.map f)))
(CategoryTheory.Category.id_comp (F.map f))))
(eq_self (F.map f))))
h h_obj
Functor.ext h_obj h_map
How can I get rid of the type error in the solution given, to analyse what's really going on by myself... ?
Kim Morrison (Jul 22 2024 at 23:35):
Does
import Mathlib.CategoryTheory.Category.Cat
open CategoryTheory
universe v u
variable {C D : Cat.{u,v}}
variable (F G : C ⥤ D)
def usingFunctorEq (h : F = G) : F = G := show_term by
fapply Functor.ext
· subst h
simp
· intro X Y f
subst h
simp
help?
Nicolas Rolland (Jul 23 2024 at 07:05):
Thank you :pray:
Would you know why rw [h]
wouldn't work here, while subst h
does ?
It tries to find a motive ?
def usingFunctorEq ( h : F = G) : F = G := show_term by
fapply Functor.ext
. subst h
simp
. intro X Y f
rewrite [h] -- tactic 'rewrite' failed, motive is not type correct
simp
This feels a bit like cheating though, of course equalities cut through everything, like saying exact h
I don't see how to use Functor.ext
in other context
Last updated: May 02 2025 at 03:31 UTC