@@ -24,6 +24,286 @@ open CategoryTheory
24
24
25
25
open CategoryTheory.Limits
26
26
27
+
28
+ namespace RingCat.Colimits
29
+
30
+ /-!
31
+ We build the colimit of a diagram in `RingCat` by constructing the
32
+ free ring on the disjoint union of all the rings in the diagram,
33
+ then taking the quotient by the ring laws within each ring,
34
+ and the identifications given by the morphisms in the diagram.
35
+ -/
36
+
37
+
38
+ variable {J : Type v} [SmallCategory J] (F : J ⥤ RingCat.{v})
39
+
40
+ /-- An inductive type representing all ring expressions (without Relations)
41
+ on a collection of types indexed by the objects of `J`.
42
+ -/
43
+ inductive Prequotient -- There's always `of`
44
+ | of : ∀ (j : J) (_ : F.obj j), Prequotient -- Then one generator for each operation
45
+ | zero : Prequotient
46
+ | one : Prequotient
47
+ | neg : Prequotient → Prequotient
48
+ | add : Prequotient → Prequotient → Prequotient
49
+ | mul : Prequotient → Prequotient → Prequotient
50
+ set_option linter.uppercaseLean3 false
51
+
52
+ instance : Inhabited (Prequotient F) :=
53
+ ⟨Prequotient.zero⟩
54
+
55
+ open Prequotient
56
+
57
+ /-- The Relation on `Prequotient` saying when two expressions are equal
58
+ because of the ring laws, or
59
+ because one element is mapped to another by a morphism in the diagram.
60
+ -/
61
+ inductive Relation : Prequotient F → Prequotient F → Prop -- Make it an equivalence Relation:
62
+ | refl : ∀ x, Relation x x
63
+ | symm : ∀ (x y) (_ : Relation x y), Relation y x
64
+ | trans : ∀ (x y z) (_ : Relation x y) (_ : Relation y z), Relation x z
65
+ -- There's always a `map` Relation
66
+ | map : ∀ (j j' : J) (f : j ⟶ j') (x : F.obj j),
67
+ Relation (Prequotient.of j' (F.map f x))
68
+ (Prequotient.of j x)
69
+ -- Then one Relation per operation, describing the interaction with `of`
70
+ | zero : ∀ j, Relation (Prequotient.of j 0 ) zero
71
+ | one : ∀ j, Relation (Prequotient.of j 1 ) one
72
+ | neg : ∀ (j) (x : F.obj j), Relation (Prequotient.of j (-x)) (neg (Prequotient.of j x))
73
+ | add : ∀ (j) (x y : F.obj j), Relation (Prequotient.of j (x + y))
74
+ (add (Prequotient.of j x) (Prequotient.of j y))
75
+ | mul : ∀ (j) (x y : F.obj j),
76
+ Relation (Prequotient.of j (x * y))
77
+ (mul (Prequotient.of j x) (Prequotient.of j y))
78
+ -- Then one Relation per argument of each operation
79
+ | neg_1 : ∀ (x x') (_ : Relation x x'), Relation (neg x) (neg x')
80
+ | add_1 : ∀ (x x' y) (_ : Relation x x'), Relation (add x y) (add x' y)
81
+ | add_2 : ∀ (x y y') (_ : Relation y y'), Relation (add x y) (add x y')
82
+ | mul_1 : ∀ (x x' y) (_ : Relation x x'), Relation (mul x y) (mul x' y)
83
+ | mul_2 : ∀ (x y y') (_ : Relation y y'), Relation (mul x y) (mul x y')
84
+ -- And one Relation per axiom
85
+ | zero_add : ∀ x, Relation (add zero x) x
86
+ | add_zero : ∀ x, Relation (add x zero) x
87
+ | one_mul : ∀ x, Relation (mul one x) x
88
+ | mul_one : ∀ x, Relation (mul x one) x
89
+ | add_left_neg : ∀ x, Relation (add (neg x) x) zero
90
+ | add_comm : ∀ x y, Relation (add x y) (add y x)
91
+ | add_assoc : ∀ x y z, Relation (add (add x y) z) (add x (add y z))
92
+ | mul_assoc : ∀ x y z, Relation (mul (mul x y) z) (mul x (mul y z))
93
+ | left_distrib : ∀ x y z, Relation (mul x (add y z)) (add (mul x y) (mul x z))
94
+ | right_distrib : ∀ x y z, Relation (mul (add x y) z) (add (mul x z) (mul y z))
95
+ | zero_mul : ∀ x, Relation (mul zero x) zero
96
+ | mul_zero : ∀ x, Relation (mul x zero) zero
97
+
98
+ /-- The setoid corresponding to commutative expressions modulo monoid Relations and identifications.
99
+ -/
100
+ def colimitSetoid : Setoid (Prequotient F) where
101
+ r := Relation F
102
+ iseqv := ⟨Relation.refl, Relation.symm _ _, Relation.trans _ _ _⟩
103
+
104
+ attribute [instance] colimitSetoid
105
+
106
+ /-- The underlying type of the colimit of a diagram in `CommRingCat`.
107
+ -/
108
+ def ColimitType : Type v :=
109
+ Quotient (colimitSetoid F)
110
+
111
+ instance ColimitType.instZero : Zero (ColimitType F) where zero := Quotient.mk _ zero
112
+
113
+ instance ColimitType.instAdd : Add (ColimitType F) where
114
+ add := Quotient.map₂ add <| fun _x x' rx y _y' ry =>
115
+ Setoid.trans (Relation.add_1 _ _ y rx) (Relation.add_2 x' _ _ ry)
116
+
117
+ instance ColimitType.instNeg : Neg (ColimitType F) where
118
+ neg := Quotient.map neg Relation.neg_1
119
+
120
+ instance ColimitType.AddGroup : AddGroup (ColimitType F) where
121
+ neg := Quotient.map neg Relation.neg_1
122
+ zero_add := Quotient.ind <| fun _ => Quotient.sound <| Relation.zero_add _
123
+ add_zero := Quotient.ind <| fun _ => Quotient.sound <| Relation.add_zero _
124
+ add_left_neg := Quotient.ind <| fun _ => Quotient.sound <| Relation.add_left_neg _
125
+ add_assoc := Quotient.ind <| fun _ => Quotient.ind₂ <| fun _ _ =>
126
+ Quotient.sound <| Relation.add_assoc _ _ _
127
+ nsmul := nsmulRec
128
+ zsmul := zsmulRec
129
+
130
+ -- Porting note: failed to derive `Inhabited` instance
131
+ instance InhabitedColimitType : Inhabited <| ColimitType F where
132
+ default := 0
133
+
134
+ instance ColimitType.AddGroupWithOne : AddGroupWithOne (ColimitType F) :=
135
+ { ColimitType.AddGroup F with one := Quotient.mk _ one }
136
+
137
+ instance : Ring (ColimitType.{v} F) :=
138
+ { ColimitType.AddGroupWithOne F with
139
+ mul := Quot.map₂ Prequotient.mul Relation.mul_2 Relation.mul_1
140
+ one_mul := fun x => Quot.inductionOn x fun x => Quot.sound <| Relation.one_mul _
141
+ mul_one := fun x => Quot.inductionOn x fun x => Quot.sound <| Relation.mul_one _
142
+ add_comm := fun x y => Quot.induction_on₂ x y fun x y => Quot.sound <| Relation.add_comm _ _
143
+ mul_assoc := fun x y z => Quot.induction_on₃ x y z fun x y z => by
144
+ simp only [(· * ·)]
145
+ exact Quot.sound (Relation.mul_assoc _ _ _)
146
+ mul_zero := fun x => Quot.inductionOn x fun x => Quot.sound <| Relation.mul_zero _
147
+ zero_mul := fun x => Quot.inductionOn x fun x => Quot.sound <| Relation.zero_mul _
148
+ left_distrib := fun x y z => Quot.induction_on₃ x y z fun x y z => by
149
+ simp only [(· + ·), (· * ·), Add.add]
150
+ exact Quot.sound (Relation.left_distrib _ _ _)
151
+ right_distrib := fun x y z => Quot.induction_on₃ x y z fun x y z => by
152
+ simp only [(· + ·), (· * ·), Add.add]
153
+ exact Quot.sound (Relation.right_distrib _ _ _) }
154
+
155
+ @[simp]
156
+ theorem quot_zero : Quot.mk Setoid.r zero = (0 : ColimitType F) :=
157
+ rfl
158
+
159
+ @[simp]
160
+ theorem quot_one : Quot.mk Setoid.r one = (1 : ColimitType F) :=
161
+ rfl
162
+
163
+ @[simp]
164
+ theorem quot_neg (x : Prequotient F) :
165
+ -- Porting note: Lean can't see `Quot.mk Setoid.r x` is a `ColimitType F` even with type
166
+ -- annotation unless we use `by exact` to change the elaboration order.
167
+ (by exact Quot.mk Setoid.r (neg x) : ColimitType F) = -(by exact Quot.mk Setoid.r x) :=
168
+ rfl
169
+
170
+ -- Porting note: Lean can't see `Quot.mk Setoid.r x` is a `ColimitType F` even with type annotation
171
+ -- unless we use `by exact` to change the elaboration order.
172
+ @[simp]
173
+ theorem quot_add (x y) :
174
+ (by exact Quot.mk Setoid.r (add x y) : ColimitType F) =
175
+ (by exact Quot.mk _ x) + (by exact Quot.mk _ y) :=
176
+ rfl
177
+
178
+ -- Porting note: Lean can't see `Quot.mk Setoid.r x` is a `ColimitType F` even with type annotation
179
+ -- unless we use `by exact` to change the elaboration order.
180
+ @[simp]
181
+ theorem quot_mul (x y) :
182
+ (by exact Quot.mk Setoid.r (mul x y) : ColimitType F) =
183
+ (by exact Quot.mk _ x) * (by exact Quot.mk _ y) :=
184
+ rfl
185
+
186
+ /-- The bundled ring giving the colimit of a diagram. -/
187
+ def colimit : RingCat :=
188
+ RingCat.of (ColimitType F)
189
+
190
+ /-- The function from a given ring in the diagram to the colimit ring. -/
191
+ def coconeFun (j : J) (x : F.obj j) : ColimitType F :=
192
+ Quot.mk _ (Prequotient.of j x)
193
+
194
+ /-- The ring homomorphism from a given ring in the diagram to the colimit
195
+ ring. -/
196
+ def coconeMorphism (j : J) : F.obj j ⟶ colimit F where
197
+ toFun := coconeFun F j
198
+ map_one' := by apply Quot.sound; apply Relation.one
199
+ map_mul' := by intros; apply Quot.sound; apply Relation.mul
200
+ map_zero' := by apply Quot.sound; apply Relation.zero
201
+ map_add' := by intros; apply Quot.sound; apply Relation.add
202
+
203
+ @[simp]
204
+ theorem cocone_naturality {j j' : J} (f : j ⟶ j') :
205
+ F.map f ≫ coconeMorphism F j' = coconeMorphism F j := by
206
+ ext
207
+ apply Quot.sound
208
+ apply Relation.map
209
+
210
+ @[simp]
211
+ theorem cocone_naturality_components (j j' : J) (f : j ⟶ j') (x : F.obj j) :
212
+ (coconeMorphism F j') (F.map f x) = (coconeMorphism F j) x := by
213
+ rw [← cocone_naturality F f, comp_apply]
214
+
215
+ /-- The cocone over the proposed colimit ring. -/
216
+ def colimitCocone : Cocone F where
217
+ pt := colimit F
218
+ ι := { app := coconeMorphism F }
219
+
220
+ /-- The function from the free ring on the diagram to the cone point of any other
221
+ cocone. -/
222
+ @[simp]
223
+ def descFunLift (s : Cocone F) : Prequotient F → s.pt
224
+ | Prequotient.of j x => (s.ι.app j) x
225
+ | zero => 0
226
+ | one => 1
227
+ | neg x => -descFunLift s x
228
+ | add x y => descFunLift s x + descFunLift s y
229
+ | mul x y => descFunLift s x * descFunLift s y
230
+
231
+ /-- The function from the colimit ring to the cone point of any other cocone. -/
232
+ def descFun (s : Cocone F) : ColimitType F → s.pt := by
233
+ fapply Quot.lift
234
+ · exact descFunLift F s
235
+ · intro x y r
236
+ induction r with
237
+ | refl => rfl
238
+ | symm x y _ ih => exact ih.symm
239
+ | trans x y z _ _ ih1 ih2 => exact ih1.trans ih2
240
+ | map j j' f x => exact RingHom.congr_fun (s.ι.naturality f) x
241
+ | zero j => simp
242
+ | one j => simp
243
+ | neg j x => simp
244
+ | add j x y => simp
245
+ | mul j x y => simp
246
+ | neg_1 x x' r ih => dsimp; rw [ih]
247
+ | add_1 x x' y r ih => dsimp; rw [ih]
248
+ | add_2 x y y' r ih => dsimp; rw [ih]
249
+ | mul_1 x x' y r ih => dsimp; rw [ih]
250
+ | mul_2 x y y' r ih => dsimp; rw [ih]
251
+ | zero_add x => dsimp; rw [zero_add]
252
+ | add_zero x => dsimp; rw [add_zero]
253
+ | one_mul x => dsimp; rw [one_mul]
254
+ | mul_one x => dsimp; rw [mul_one]
255
+ | add_left_neg x => dsimp; rw [add_left_neg]
256
+ | add_comm x y => dsimp; rw [add_comm]
257
+ | add_assoc x y z => dsimp; rw [add_assoc]
258
+ | mul_assoc x y z => dsimp; rw [mul_assoc]
259
+ | left_distrib x y z => dsimp; rw [mul_add]
260
+ | right_distrib x y z => dsimp; rw [add_mul]
261
+ | zero_mul x => dsimp; rw [zero_mul]
262
+ | mul_zero x => dsimp; rw [mul_zero]
263
+
264
+ /-- The ring homomorphism from the colimit ring to the cone point of any other
265
+ cocone. -/
266
+ def descMorphism (s : Cocone F) : colimit F ⟶ s.pt where
267
+ toFun := descFun F s
268
+ map_one' := rfl
269
+ map_zero' := rfl
270
+ map_add' x y := by
271
+ refine Quot.induction_on₂ x y fun a b => ?_
272
+ dsimp [descFun]
273
+ rw [← quot_add]
274
+ rfl
275
+ map_mul' x y := by exact Quot.induction_on₂ x y fun a b => rfl
276
+
277
+ /-- Evidence that the proposed colimit is the colimit. -/
278
+ def colimitIsColimit : IsColimit (colimitCocone F) where
279
+ desc s := descMorphism F s
280
+ uniq s m w := RingHom.ext fun x => by
281
+ change (colimitCocone F).pt →+* s.pt at m
282
+ refine Quot.inductionOn x ?_
283
+ intro x
284
+ induction x with
285
+ | zero => erw [quot_zero, map_zero (f := m), (descMorphism F s).map_zero]
286
+ | one => erw [quot_one, map_one (f := m), (descMorphism F s).map_one]
287
+ -- extra rfl with leanprover/lean4#2644
288
+ | neg x ih => erw [quot_neg, map_neg (f := m), (descMorphism F s).map_neg, ih]; rfl
289
+ | of j x =>
290
+ exact congr_fun (congr_arg (fun f : F.obj j ⟶ s.pt => (f : F.obj j → s.pt)) (w j)) x
291
+ | add x y ih_x ih_y =>
292
+ -- extra rfl with leanprover/lean4#2644
293
+ erw [quot_add, map_add (f := m), (descMorphism F s).map_add, ih_x, ih_y]; rfl
294
+ | mul x y ih_x ih_y =>
295
+ -- extra rfl with leanprover/lean4#2644
296
+ erw [quot_mul, map_mul (f := m), (descMorphism F s).map_mul, ih_x, ih_y]; rfl
297
+
298
+ instance hasColimits_ringCat : HasColimits RingCat where
299
+ has_colimits_of_shape _ _ :=
300
+ { has_colimit := fun F =>
301
+ HasColimit.mk
302
+ { cocone := colimitCocone F
303
+ isColimit := colimitIsColimit F } }
304
+
305
+ end RingCat.Colimits
306
+
27
307
-- [ROBOT VOICE]:
28
308
-- You should pretend for now that this file was automatically generated.
29
309
-- It follows the same template as colimits in Mon.
0 commit comments