forked from leanprover-community/mathlib
-
Notifications
You must be signed in to change notification settings - Fork 0
/
elements.lean
114 lines (89 loc) · 4.4 KB
/
elements.lean
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
/-
Copyright (c) 2019 Scott Morrison. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Scott Morrison
-/
import category_theory.comma
import category_theory.groupoid
/-!
# The category of elements
This file defines the category of elements, also known as (a special case of) the Grothendieck construction.
Given a functor `F : C ⥤ Type`, an object of `F.elements` is a pair `(X : C, x : F.obj X)`.
A morphism `(X, x) ⟶ (Y, y)` is a morphism `f : X ⟶ Y` in `C`, so `F.map f` takes `x` to `y`.
## Implementation notes
This construction is equivalent to a special case of a comma construction, so this is mostly just
a more convenient API. We prove the equivalence in `category_theory.category_of_elements.comma_equivalence`.
## References
* [Emily Riehl, *Category Theory in Context*, Section 2.4][riehl2017]
* <https://en.wikipedia.org/wiki/Category_of_elements>
* <https://ncatlab.org/nlab/show/category+of+elements>
## Tags
category of elements, Grothendieck construction, comma category
-/
namespace category_theory
universes w v u
variables {C : Type u} [𝒞 : category.{v} C]
include 𝒞
/--
The type of objects for the category of elements of a functor `F : C ⥤ Type`
is a pair `(X : C, x : F.obj X)`.
-/
@[nolint has_inhabited_instance]
def functor.elements (F : C ⥤ Type w) := (Σ c : C, F.obj c)
/-- The category structure on `F.elements`, for `F : C ⥤ Type`.
A morphism `(X, x) ⟶ (Y, y)` is a morphism `f : X ⟶ Y` in `C`, so `F.map f` takes `x` to `y`.
-/
instance category_of_elements (F : C ⥤ Type w) : category F.elements :=
{ hom := λ p q, { f : p.1 ⟶ q.1 // (F.map f) p.2 = q.2 },
id := λ p, ⟨𝟙 p.1, by obviously⟩,
comp := λ p q r f g, ⟨f.val ≫ g.val, by obviously⟩ }
namespace category_of_elements
@[ext]
lemma ext (F : C ⥤ Type w) {x y : F.elements} (f g : x ⟶ y) (w : f.val = g.val) : f = g :=
subtype.ext_val w
@[simp] lemma comp_val {F : C ⥤ Type w} {p q r : F.elements} {f : p ⟶ q} {g : q ⟶ r} :
(f ≫ g).val = f.val ≫ g.val := rfl
@[simp] lemma id_val {F : C ⥤ Type w} {p : F.elements} : (𝟙 p : p ⟶ p).val = 𝟙 p.1 := rfl
end category_of_elements
omit 𝒞 -- We'll assume C has a groupoid structure, so temporarily forget its category structure
-- to avoid conflicts.
instance groupoid_of_elements [groupoid C] (F : C ⥤ Type w) : groupoid F.elements :=
{ inv := λ p q f, ⟨inv f.val,
calc F.map (inv f.val) q.2 = F.map (inv f.val) (F.map f.val p.2) : by rw f.2
... = (F.map f.val ≫ F.map (inv f.val)) p.2 : by simp
... = p.2 : by {rw ←functor.map_comp, simp}⟩ }
include 𝒞
namespace category_of_elements
variable (F : C ⥤ Type w)
/-- The functor out of the category of elements which forgets the element. -/
def π : F.elements ⥤ C :=
{ obj := λ X, X.1,
map := λ X Y f, f.val }
@[simp] lemma π_obj (X : F.elements) : (π F).obj X = X.1 := rfl
@[simp] lemma π_map {X Y : F.elements} (f : X ⟶ Y) : (π F).map f = f.val := rfl
/-- The forward direction of the equivalence `F.elements ≅ (*, F)`. -/
def to_comma : F.elements ⥤ comma ((functor.const punit).obj punit) F :=
{ obj := λ X, { left := punit.star, right := X.1, hom := λ _, X.2 },
map := λ X Y f, { right := f.val } }
@[simp] lemma to_comma_obj (X) :
(to_comma F).obj X = { left := punit.star, right := X.1, hom := λ _, X.2 } := rfl
@[simp] lemma to_comma_map {X Y} (f : X ⟶ Y) :
(to_comma F).map f = { right := f.val } := rfl
/-- The reverse direction of the equivalence `F.elements ≅ (*, F)`. -/
def from_comma : comma ((functor.const punit).obj punit) F ⥤ F.elements :=
{ obj := λ X, ⟨X.right, X.hom (punit.star)⟩,
map := λ X Y f, ⟨f.right, congr_fun f.w'.symm punit.star⟩ }
@[simp] lemma from_comma_obj (X) :
(from_comma F).obj X = ⟨X.right, X.hom (punit.star)⟩ := rfl
@[simp] lemma from_comma_map {X Y} (f : X ⟶ Y) :
(from_comma F).map f = ⟨f.right, congr_fun f.w'.symm punit.star⟩ := rfl
/-- The equivalence between the category of elements `F.elements`
and the comma category `(*, F)`. -/
def comma_equivalence : F.elements ≌ comma ((functor.const punit).obj punit) F :=
equivalence.mk (to_comma F) (from_comma F)
(nat_iso.of_components (λ X, eq_to_iso (by tidy)) (by tidy))
(nat_iso.of_components
(λ X, { hom := { right := 𝟙 _ }, inv := { right := 𝟙 _ } })
(by tidy))
end category_of_elements
end category_theory