Skip to content

Commit 0d5e1c8

Browse files
urkudjjaassoonn
andcommitted
feat: port CategoryTheory.Groupoid.FreeGroupoid (#3347)
Co-authored-by: Jujian Zhang <jujian.zhang1998@outlook.com>
1 parent c01ffda commit 0d5e1c8

File tree

2 files changed

+221
-0
lines changed

2 files changed

+221
-0
lines changed

Mathlib.lean

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -539,6 +539,7 @@ import Mathlib.CategoryTheory.GradedObject
539539
import Mathlib.CategoryTheory.Grothendieck
540540
import Mathlib.CategoryTheory.Groupoid
541541
import Mathlib.CategoryTheory.Groupoid.Basic
542+
import Mathlib.CategoryTheory.Groupoid.FreeGroupoid
542543
import Mathlib.CategoryTheory.Groupoid.VertexGroup
543544
import Mathlib.CategoryTheory.Idempotents.Basic
544545
import Mathlib.CategoryTheory.Idempotents.Biproducts
Lines changed: 220 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,220 @@
1+
/-
2+
Copyright (c) 2022 Rémi Bottinelli. All rights reserved.
3+
Released under Apache 2.0 license as described in the file LICENSE.
4+
Authors: Rémi Bottinelli
5+
6+
! This file was ported from Lean 3 source module category_theory.groupoid.free_groupoid
7+
! leanprover-community/mathlib commit 706d88f2b8fdfeb0b22796433d7a6c1a010af9f2
8+
! Please do not edit these lines, except to modify the commit id
9+
! if you have ported upstream changes.
10+
-/
11+
import Mathlib.CategoryTheory.Category.Basic
12+
import Mathlib.CategoryTheory.Functor.Basic
13+
import Mathlib.CategoryTheory.Groupoid
14+
import Mathlib.Tactic.NthRewrite
15+
import Mathlib.CategoryTheory.PathCategory
16+
import Mathlib.CategoryTheory.Quotient
17+
import Mathlib.Combinatorics.Quiver.Symmetric
18+
19+
/-!
20+
# Free groupoid on a quiver
21+
22+
This file defines the free groupoid on a quiver, the lifting of a prefunctor to its unique
23+
extension as a functor from the free groupoid, and proves uniqueness of this extension.
24+
25+
## Main results
26+
27+
Given the type `V` and a quiver instance on `V`:
28+
29+
- `free_groupoid V`: a type synonym for `V`.
30+
- `free_groupoid_groupoid`: the `groupoid` instance on `free_groupoid V`.
31+
- `lift`: the lifting of a prefunctor from `V` to `V'` where `V'` is a groupoid, to a functor.
32+
`free_groupoid V ⥤ V'`.
33+
- `lift_spec` and `lift_unique`: the proofs that, respectively, `lift` indeed is a lifting
34+
and is the unique one.
35+
36+
## Implementation notes
37+
38+
The free groupoid is first defined by symmetrifying the quiver, taking the induced path category
39+
and finally quotienting by the reducibility relation.
40+
41+
-/
42+
43+
44+
open Set Classical Function
45+
46+
attribute [local instance] propDecidable
47+
48+
namespace CategoryTheory
49+
50+
namespace Groupoid
51+
52+
namespace Free
53+
54+
universe u v u' v' u'' v''
55+
56+
variable {V : Type u} [Quiver.{v + 1} V]
57+
58+
/-- Shorthand for the "forward" arrow corresponding to `f` in `paths $ symmetrify V` -/
59+
abbrev _root_.Quiver.Hom.toPosPath {X Y : V} (f : X ⟶ Y) :
60+
(CategoryTheory.Paths.categoryPaths <| Quiver.Symmetrify V).Hom X Y :=
61+
f.toPos.toPath
62+
#align category_theory.groupoid.free.quiver.hom.to_pos_path Quiver.Hom.toPosPath
63+
64+
/-- Shorthand for the "forward" arrow corresponding to `f` in `paths $ symmetrify V` -/
65+
abbrev _root_.Quiver.Hom.toNegPath {X Y : V} (f : X ⟶ Y) :
66+
(CategoryTheory.Paths.categoryPaths <| Quiver.Symmetrify V).Hom Y X :=
67+
f.toNeg.toPath
68+
#align category_theory.groupoid.free.quiver.hom.to_neg_path Quiver.Hom.toNegPath
69+
70+
/-- The "reduction" relation -/
71+
inductive redStep : HomRel (Paths (Quiver.Symmetrify V))
72+
| step (X Z : Quiver.Symmetrify V) (f : X ⟶ Z) :
73+
redStep (𝟙 (Paths.of.obj X)) (f.toPath ≫ (Quiver.reverse f).toPath)
74+
#align category_theory.groupoid.free.red_step CategoryTheory.Groupoid.Free.redStep
75+
76+
/-- The underlying vertices of the free groupoid -/
77+
def _root_.CategoryTheory.FreeGroupoid (V) [Q : Quiver V] :=
78+
Quotient (@redStep V Q)
79+
#align category_theory.free_groupoid CategoryTheory.FreeGroupoid
80+
81+
instance {V} [Quiver V] [Nonempty V] : Nonempty (FreeGroupoid V) := by
82+
inhabit V; exact ⟨⟨@default V _⟩⟩
83+
84+
theorem congr_reverse {X Y : Paths <| Quiver.Symmetrify V} (p q : X ⟶ Y) :
85+
Quotient.CompClosure redStep p q → Quotient.CompClosure redStep p.reverse q.reverse := by
86+
rintro ⟨XW, pp, qq, WY, _, Z, f⟩
87+
have : Quotient.CompClosure redStep (WY.reverse ≫ 𝟙 _ ≫ XW.reverse)
88+
(WY.reverse ≫ (f.toPath ≫ (Quiver.reverse f).toPath) ≫ XW.reverse) := by
89+
constructor
90+
constructor
91+
simpa only [CategoryStruct.comp, CategoryStruct.id, Quiver.Path.reverse, Quiver.Path.nil_comp,
92+
Quiver.Path.reverse_comp, Quiver.reverse_reverse, Quiver.Path.reverse_toPath,
93+
Quiver.Path.comp_assoc] using this
94+
#align category_theory.groupoid.free.congr_reverse CategoryTheory.Groupoid.Free.congr_reverse
95+
96+
theorem congr_comp_reverse {X Y : Paths <| Quiver.Symmetrify V} (p : X ⟶ Y) :
97+
Quot.mk (@Quotient.CompClosure _ _ redStep _ _) (p ≫ p.reverse) =
98+
Quot.mk (@Quotient.CompClosure _ _ redStep _ _) (𝟙 X) := by
99+
apply Quot.EqvGen_sound
100+
induction' p with a b q f ih
101+
· apply EqvGen.refl
102+
· simp only [Quiver.Path.reverse]
103+
fapply EqvGen.trans
104+
-- Porting note : `Quiver.Path.*` and `Quiver.Hom.*` notation not working
105+
· exact q ≫ Quiver.Path.reverse q
106+
· apply EqvGen.symm
107+
apply EqvGen.rel
108+
have : Quotient.CompClosure redStep (q ≫ 𝟙 _ ≫ Quiver.Path.reverse q)
109+
(q ≫ (Quiver.Hom.toPath f ≫ Quiver.Hom.toPath (Quiver.reverse f)) ≫
110+
Quiver.Path.reverse q) := by
111+
apply Quotient.CompClosure.intro
112+
apply redStep.step
113+
simp only [Category.assoc, Category.id_comp] at this ⊢
114+
-- Porting note : `simp` cannot see how `Quiver.Path.comp_assoc` is relevant, so change to
115+
-- category notation
116+
change Quotient.CompClosure redStep (q ≫ Quiver.Path.reverse q)
117+
(Quiver.Path.cons q f ≫ (Quiver.Hom.toPath (Quiver.reverse f)) ≫ (Quiver.Path.reverse q))
118+
simp only [←Category.assoc] at this ⊢
119+
exact this
120+
· exact ih
121+
#align category_theory.groupoid.free.congr_comp_reverse CategoryTheory.Groupoid.Free.congr_comp_reverse
122+
123+
theorem congr_reverse_comp {X Y : Paths <| Quiver.Symmetrify V} (p : X ⟶ Y) :
124+
Quot.mk (@Quotient.CompClosure _ _ redStep _ _) (p.reverse ≫ p) =
125+
Quot.mk (@Quotient.CompClosure _ _ redStep _ _) (𝟙 Y) := by
126+
nth_rw 2 [← Quiver.Path.reverse_reverse p]
127+
apply congr_comp_reverse
128+
#align category_theory.groupoid.free.congr_reverse_comp CategoryTheory.Groupoid.Free.congr_reverse_comp
129+
130+
instance : Category (FreeGroupoid V) :=
131+
Quotient.category redStep
132+
133+
/-- The inverse of an arrow in the free groupoid -/
134+
def quotInv {X Y : FreeGroupoid V} (f : X ⟶ Y) : Y ⟶ X :=
135+
Quot.liftOn f (fun pp => Quot.mk _ <| pp.reverse) fun pp qq con =>
136+
Quot.sound <| congr_reverse pp qq con
137+
#align category_theory.groupoid.free.quot_inv CategoryTheory.Groupoid.Free.quotInv
138+
139+
instance : Groupoid (FreeGroupoid V) where
140+
inv := quotInv
141+
inv_comp p := Quot.inductionOn p fun pp => congr_reverse_comp pp
142+
comp_inv p := Quot.inductionOn p fun pp => congr_comp_reverse pp
143+
144+
/-- The inclusion of the quiver on `V` to the underlying quiver on `free_groupoid V`-/
145+
def of (V) [Quiver V] : V ⥤q FreeGroupoid V where
146+
obj X := ⟨X⟩
147+
map f := Quot.mk _ f.toPosPath
148+
#align category_theory.groupoid.free.of CategoryTheory.Groupoid.Free.of
149+
150+
theorem of_eq :
151+
of V = (Quiver.Symmetrify.of ⋙q Paths.of).comp
152+
(Quotient.functor <| @redStep V _).toPrefunctor := rfl
153+
#align category_theory.groupoid.free.of_eq CategoryTheory.Groupoid.Free.of_eq
154+
155+
section UniversalProperty
156+
157+
variable {V' : Type u'} [Groupoid V'] (φ : V ⥤q V')
158+
159+
/-- The lift of a prefunctor to a groupoid, to a functor from `free_groupoid V` -/
160+
def lift (φ : V ⥤q V') : FreeGroupoid V ⥤ V' :=
161+
Quotient.lift _ (Paths.lift <| Quiver.Symmetrify.lift φ) <| by
162+
rintro _ _ _ _ ⟨X, Y, f⟩
163+
-- Porting note: `simp` does not work, so manually `rewrite`
164+
erw [Paths.lift_nil, Paths.lift_cons, Quiver.Path.comp_nil, Paths.lift_toPath,
165+
Quiver.Symmetrify.lift_reverse]
166+
symm
167+
apply Groupoid.comp_inv
168+
#align category_theory.groupoid.free.lift CategoryTheory.Groupoid.Free.lift
169+
170+
theorem lift_spec (φ : V ⥤q V') : of V ⋙q (lift φ).toPrefunctor = φ := by
171+
rw [of_eq, Prefunctor.comp_assoc, Prefunctor.comp_assoc, Functor.toPrefunctor_comp]
172+
dsimp [lift]
173+
rw [Quotient.lift_spec, Paths.lift_spec, Quiver.Symmetrify.lift_spec]
174+
#align category_theory.groupoid.free.lift_spec CategoryTheory.Groupoid.Free.lift_spec
175+
176+
theorem lift_unique (φ : V ⥤q V') (Φ : FreeGroupoid V ⥤ V') (hΦ : of V ⋙q Φ.toPrefunctor = φ) :
177+
Φ = lift φ := by
178+
apply Quotient.lift_unique
179+
apply Paths.lift_unique
180+
fapply @Quiver.Symmetrify.lift_unique _ _ _ _ _ _ _ _ _
181+
· rw [← Functor.toPrefunctor_comp]
182+
exact hΦ
183+
· rintro X Y f
184+
simp only [← Functor.toPrefunctor_comp, Prefunctor.comp_map, Paths.of_map, inv_eq_inv]
185+
change Φ.map (inv ((Quotient.functor redStep).toPrefunctor.map f.toPath)) =
186+
inv (Φ.map ((Quotient.functor redStep).toPrefunctor.map f.toPath))
187+
have := Functor.map_inv Φ ((Quotient.functor redStep).toPrefunctor.map f.toPath)
188+
convert this <;> simp only [inv_eq_inv]
189+
#align category_theory.groupoid.free.lift_unique CategoryTheory.Groupoid.Free.lift_unique
190+
191+
end UniversalProperty
192+
193+
section Functoriality
194+
195+
variable {V' : Type u'} [Quiver.{v' + 1} V'] {V'' : Type u''} [Quiver.{v'' + 1} V'']
196+
197+
/-- The functor of free groupoid induced by a prefunctor of quivers -/
198+
def _root_.CategoryTheory.freeGroupoidFunctor (φ : V ⥤q V') : FreeGroupoid V ⥤ FreeGroupoid V' :=
199+
lift (φ ⋙q of V')
200+
#align category_theory.free_groupoid_functor CategoryTheory.freeGroupoidFunctor
201+
202+
theorem freeGroupoidFunctor_id :
203+
freeGroupoidFunctor (Prefunctor.id V) = Functor.id (FreeGroupoid V) := by
204+
dsimp only [freeGroupoidFunctor]; symm
205+
apply lift_unique; rfl
206+
#align category_theory.groupoid.free.free_groupoid_functor_id CategoryTheory.Groupoid.Free.freeGroupoidFunctor_id
207+
208+
theorem freeGroupoidFunctor_comp (φ : V ⥤q V') (φ' : V' ⥤q V'') :
209+
freeGroupoidFunctor (φ ⋙q φ') = freeGroupoidFunctor φ ⋙ freeGroupoidFunctor φ' := by
210+
dsimp only [freeGroupoidFunctor]; symm
211+
apply lift_unique; rfl
212+
#align category_theory.groupoid.free.free_groupoid_functor_comp CategoryTheory.Groupoid.Free.freeGroupoidFunctor_comp
213+
214+
end Functoriality
215+
216+
end Free
217+
218+
end Groupoid
219+
220+
end CategoryTheory

0 commit comments

Comments
 (0)