|
| 1 | +/- |
| 2 | +Copyright (c) 2019 Scott Morrison. All rights reserved. |
| 3 | +Released under Apache 2.0 license as described in the file LICENSE. |
| 4 | +Authors: Scott Morrison |
| 5 | +
|
| 6 | +! This file was ported from Lean 3 source module algebra.category.Mon.colimits |
| 7 | +! leanprover-community/mathlib commit 70fd9563a21e7b963887c9360bd29b2393e6225a |
| 8 | +! Please do not edit these lines, except to modify the commit id |
| 9 | +! if you have ported upstream changes. |
| 10 | +-/ |
| 11 | +import Mathlib.Algebra.Category.MonCat.Basic |
| 12 | +import Mathlib.CategoryTheory.Limits.HasLimits |
| 13 | +import Mathlib.CategoryTheory.ConcreteCategory.Elementwise |
| 14 | + |
| 15 | +/-! |
| 16 | +# The category of monoids has all colimits. |
| 17 | +
|
| 18 | +We do this construction knowing nothing about monoids. |
| 19 | +In particular, I want to claim that this file could be produced by a python script |
| 20 | +that just looks at the output of `#print monoid`: |
| 21 | +
|
| 22 | + -- structure monoid : Type u → Type u |
| 23 | + -- fields: |
| 24 | + -- monoid.mul : Π {α : Type u} [c : monoid α], α → α → α |
| 25 | + -- monoid.mul_assoc : ∀ {α : Type u} [c : monoid α] (a b c_1 : α), a * b * c_1 = a * (b * c_1) |
| 26 | + -- monoid.one : Π (α : Type u) [c : monoid α], α |
| 27 | + -- monoid.one_mul : ∀ {α : Type u} [c : monoid α] (a : α), 1 * a = a |
| 28 | + -- monoid.mul_one : ∀ {α : Type u} [c : monoid α] (a : α), a * 1 = a |
| 29 | +
|
| 30 | +and if we'd fed it the output of `#print comm_ring`, this file would instead build |
| 31 | +colimits of commutative rings. |
| 32 | +
|
| 33 | +A slightly bolder claim is that we could do this with tactics, as well. |
| 34 | +
|
| 35 | +Note: `Monoid` and `CommRing` are no longer flat structures in Mathlib4 |
| 36 | +
|
| 37 | +-/ |
| 38 | + |
| 39 | + |
| 40 | +universe v |
| 41 | + |
| 42 | +open CategoryTheory |
| 43 | + |
| 44 | +open CategoryTheory.Limits |
| 45 | + |
| 46 | +namespace MonCat.Colimits |
| 47 | + |
| 48 | +/-! |
| 49 | +We build the colimit of a diagram in `MonCat` by constructing the |
| 50 | +free monoid on the disjoint union of all the monoids in the diagram, |
| 51 | +then taking the quotient by the monoid laws within each monoid, |
| 52 | +and the identifications given by the morphisms in the diagram. |
| 53 | +-/ |
| 54 | + |
| 55 | + |
| 56 | +variable {J : Type v} [SmallCategory J] (F : J ⥤ MonCat.{v}) |
| 57 | + |
| 58 | +/-- An inductive type representing all monoid expressions (without relations) |
| 59 | +on a collection of types indexed by the objects of `J`. |
| 60 | +-/ |
| 61 | +inductive Prequotient-- There's always `of` |
| 62 | + | of : ∀ (j : J) (_ : F.obj j), Prequotient-- Then one generator for each operation |
| 63 | + | one : Prequotient |
| 64 | + | mul : Prequotient → Prequotient → Prequotient |
| 65 | +set_option linter.uppercaseLean3 false in |
| 66 | +#align Mon.colimits.prequotient MonCat.Colimits.Prequotient |
| 67 | + |
| 68 | +instance : Inhabited (Prequotient F) := |
| 69 | + ⟨Prequotient.one⟩ |
| 70 | + |
| 71 | +open Prequotient |
| 72 | + |
| 73 | +/-- The relation on `Prequotient` saying when two expressions are equal |
| 74 | +because of the monoid laws, or |
| 75 | +because one element is mapped to another by a morphism in the diagram. |
| 76 | +-/ |
| 77 | +inductive Relation : Prequotient F → Prequotient F → Prop-- Make it an equivalence relation: |
| 78 | + | refl : ∀ x, Relation x x |
| 79 | + | symm : ∀ (x y) (_ : Relation x y), Relation y x |
| 80 | + | trans : ∀ (x y z) (_ : Relation x y) (_ : Relation y z), |
| 81 | + Relation x z-- There's always a `map` relation |
| 82 | + | map : |
| 83 | + ∀ (j j' : J) (f : j ⟶ j') (x : F.obj j), |
| 84 | + Relation (Prequotient.of j' ((F.map f) x)) |
| 85 | + (Prequotient.of j x)-- Then one relation per operation, describing the interaction with `of` |
| 86 | + | mul : ∀ (j) (x y : F.obj j), Relation (Prequotient.of j (x * y)) |
| 87 | + (mul (Prequotient.of j x) (Prequotient.of j y)) |
| 88 | + | one : ∀ j, Relation (Prequotient.of j 1) one-- Then one relation per argument of each operation |
| 89 | + | mul_1 : ∀ (x x' y) (_ : Relation x x'), Relation (mul x y) (mul x' y) |
| 90 | + | mul_2 : ∀ (x y y') (_ : Relation y y'), Relation (mul x y) (mul x y') |
| 91 | + -- And one relation per axiom |
| 92 | + | mul_assoc : ∀ x y z, Relation (mul (mul x y) z) (mul x (mul y z)) |
| 93 | + | one_mul : ∀ x, Relation (mul one x) x |
| 94 | + | mul_one : ∀ x, Relation (mul x one) x |
| 95 | +set_option linter.uppercaseLean3 false in |
| 96 | +#align Mon.colimits.relation MonCat.Colimits.Relation |
| 97 | + |
| 98 | +/-- The setoid corresponding to monoid 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 | +set_option linter.uppercaseLean3 false in |
| 104 | +#align Mon.colimits.colimit_setoid MonCat.Colimits.colimitSetoid |
| 105 | + |
| 106 | +attribute [instance] colimitSetoid |
| 107 | + |
| 108 | +/-- The underlying type of the colimit of a diagram in `Mon`. |
| 109 | +-/ |
| 110 | +def ColimitType : Type v := |
| 111 | + Quotient (colimitSetoid F) |
| 112 | +set_option linter.uppercaseLean3 false in |
| 113 | +#align Mon.colimits.colimit_type MonCat.Colimits.ColimitType |
| 114 | + |
| 115 | +instance : Inhabited (ColimitType F) := by |
| 116 | + dsimp [ColimitType] |
| 117 | + infer_instance |
| 118 | + |
| 119 | +instance monoidColimitType : Monoid (ColimitType F) where |
| 120 | + mul := by |
| 121 | + fapply @Quot.lift _ _ (ColimitType F → ColimitType F) |
| 122 | + · intro x |
| 123 | + fapply @Quot.lift |
| 124 | + · intro y |
| 125 | + exact Quot.mk _ (mul x y) |
| 126 | + · intro y y' r |
| 127 | + apply Quot.sound |
| 128 | + exact Relation.mul_2 _ _ _ r |
| 129 | + · intro x x' r |
| 130 | + funext y |
| 131 | + induction y using Quot.inductionOn |
| 132 | + dsimp |
| 133 | + apply Quot.sound |
| 134 | + apply Relation.mul_1 _ _ _ r |
| 135 | + one := Quot.mk _ one |
| 136 | + mul_assoc x y z := by |
| 137 | + induction x using Quot.inductionOn |
| 138 | + induction y using Quot.inductionOn |
| 139 | + induction z using Quot.inductionOn |
| 140 | + dsimp [HMul.hMul] |
| 141 | + apply Quot.sound |
| 142 | + apply Relation.mul_assoc |
| 143 | + one_mul x := by |
| 144 | + induction x using Quot.inductionOn |
| 145 | + dsimp |
| 146 | + apply Quot.sound |
| 147 | + apply Relation.one_mul |
| 148 | + mul_one x := by |
| 149 | + induction x using Quot.inductionOn |
| 150 | + dsimp |
| 151 | + apply Quot.sound |
| 152 | + apply Relation.mul_one |
| 153 | +set_option linter.uppercaseLean3 false in |
| 154 | +#align Mon.colimits.monoid_colimit_type MonCat.Colimits.monoidColimitType |
| 155 | + |
| 156 | +@[simp] |
| 157 | +theorem quot_one : Quot.mk Setoid.r one = (1 : ColimitType F) := |
| 158 | + rfl |
| 159 | +set_option linter.uppercaseLean3 false in |
| 160 | +#align Mon.colimits.quot_one MonCat.Colimits.quot_one |
| 161 | + |
| 162 | +@[simp] |
| 163 | +theorem quot_mul (x y : Prequotient F) : Quot.mk Setoid.r (mul x y) = |
| 164 | + @HMul.hMul (ColimitType F) (ColimitType F) (ColimitType F) _ |
| 165 | + (Quot.mk Setoid.r x) (Quot.mk Setoid.r y) := |
| 166 | + rfl |
| 167 | +set_option linter.uppercaseLean3 false in |
| 168 | +#align Mon.colimits.quot_mul MonCat.Colimits.quot_mul |
| 169 | + |
| 170 | +/-- The bundled monoid giving the colimit of a diagram. -/ |
| 171 | +def colimit : MonCat := |
| 172 | + ⟨ColimitType F, by infer_instance⟩ |
| 173 | +set_option linter.uppercaseLean3 false in |
| 174 | +#align Mon.colimits.colimit MonCat.Colimits.colimit |
| 175 | + |
| 176 | +/-- The function from a given monoid in the diagram to the colimit monoid. -/ |
| 177 | +def coconeFun (j : J) (x : F.obj j) : ColimitType F := |
| 178 | + Quot.mk _ (Prequotient.of j x) |
| 179 | +set_option linter.uppercaseLean3 false in |
| 180 | +#align Mon.colimits.cocone_fun MonCat.Colimits.coconeFun |
| 181 | + |
| 182 | +/-- The monoid homomorphism from a given monoid in the diagram to the colimit monoid. -/ |
| 183 | +def coconeMorphism (j : J) : F.obj j ⟶ colimit F where |
| 184 | + toFun := coconeFun F j |
| 185 | + map_one' := Quot.sound (Relation.one _) |
| 186 | + map_mul' _ _ := Quot.sound (Relation.mul _ _ _) |
| 187 | +set_option linter.uppercaseLean3 false in |
| 188 | +#align Mon.colimits.cocone_morphism MonCat.Colimits.coconeMorphism |
| 189 | + |
| 190 | +@[simp] |
| 191 | +theorem cocone_naturality {j j' : J} (f : j ⟶ j') : |
| 192 | + F.map f ≫ coconeMorphism F j' = coconeMorphism F j := by |
| 193 | + ext |
| 194 | + apply Quot.sound |
| 195 | + apply Relation.map |
| 196 | +set_option linter.uppercaseLean3 false in |
| 197 | +#align Mon.colimits.cocone_naturality MonCat.Colimits.cocone_naturality |
| 198 | + |
| 199 | +@[simp] |
| 200 | +theorem cocone_naturality_components (j j' : J) (f : j ⟶ j') (x : F.obj j) : |
| 201 | + (coconeMorphism F j') (F.map f x) = (coconeMorphism F j) x := by |
| 202 | + rw [← cocone_naturality F f] |
| 203 | + rfl |
| 204 | +set_option linter.uppercaseLean3 false in |
| 205 | +#align Mon.colimits.cocone_naturality_components MonCat.Colimits.cocone_naturality_components |
| 206 | + |
| 207 | +/-- The cocone over the proposed colimit monoid. -/ |
| 208 | +def colimitCocone : Cocone F where |
| 209 | + pt := colimit F |
| 210 | + ι := { app := coconeMorphism F } |
| 211 | +set_option linter.uppercaseLean3 false in |
| 212 | +#align Mon.colimits.colimit_cocone MonCat.Colimits.colimitCocone |
| 213 | + |
| 214 | +/-- The function from the free monoid on the diagram to the cone point of any other cocone. -/ |
| 215 | +@[simp] |
| 216 | +def descFunLift (s : Cocone F) : Prequotient F → s.pt |
| 217 | + | Prequotient.of j x => (s.ι.app j) x |
| 218 | + | one => 1 |
| 219 | + | mul x y => descFunLift _ x * descFunLift _ y |
| 220 | +set_option linter.uppercaseLean3 false in |
| 221 | +#align Mon.colimits.desc_fun_lift MonCat.Colimits.descFunLift |
| 222 | + |
| 223 | +/-- The function from the colimit monoid to the cone point of any other cocone. -/ |
| 224 | +def descFun (s : Cocone F) : ColimitType F → s.pt := by |
| 225 | + fapply Quot.lift |
| 226 | + · exact descFunLift F s |
| 227 | + · intro x y r |
| 228 | + induction' r with _ _ _ _ h _ _ _ _ _ h₁ h₂ _ _ f x _ _ _ _ _ _ _ _ h _ _ _ _ h <;> try simp |
| 229 | + -- symm |
| 230 | + . exact h.symm |
| 231 | + -- trans |
| 232 | + . exact h₁.trans h₂ |
| 233 | + -- map |
| 234 | + . exact s.w_apply f x |
| 235 | + -- mul_1 |
| 236 | + . rw [h] |
| 237 | + -- mul_2 |
| 238 | + . rw [h] |
| 239 | + -- mul_assoc |
| 240 | + . rw [mul_assoc] |
| 241 | +set_option linter.uppercaseLean3 false in |
| 242 | +#align Mon.colimits.desc_fun MonCat.Colimits.descFun |
| 243 | + |
| 244 | +/-- The monoid homomorphism from the colimit monoid to the cone point of any other cocone. -/ |
| 245 | +def descMorphism (s : Cocone F) : colimit F ⟶ s.pt where |
| 246 | + toFun := descFun F s |
| 247 | + map_one' := rfl |
| 248 | + map_mul' x y := by |
| 249 | + induction x using Quot.inductionOn |
| 250 | + induction y using Quot.inductionOn |
| 251 | + dsimp [descFun] |
| 252 | + rw [← quot_mul] |
| 253 | + simp only [descFunLift] |
| 254 | +set_option linter.uppercaseLean3 false in |
| 255 | +#align Mon.colimits.desc_morphism MonCat.Colimits.descMorphism |
| 256 | + |
| 257 | +/-- Evidence that the proposed colimit is the colimit. -/ |
| 258 | +def colimitIsColimit : IsColimit (colimitCocone F) where |
| 259 | + desc s := descMorphism F s |
| 260 | + uniq s m w := by |
| 261 | + ext x |
| 262 | + induction' x using Quot.inductionOn with x |
| 263 | + induction' x with j x x y hx hy |
| 264 | + . change _ = s.ι.app j _ |
| 265 | + rw [← w j] |
| 266 | + rfl |
| 267 | + . rw [quot_one, map_one] |
| 268 | + rfl |
| 269 | + . rw [quot_mul, map_mul, hx, hy] |
| 270 | + dsimp [descMorphism, FunLike.coe, descFun] |
| 271 | + simp only [← quot_mul, descFunLift] |
| 272 | +set_option linter.uppercaseLean3 false in |
| 273 | +#align Mon.colimits.colimit_is_colimit MonCat.Colimits.colimitIsColimit |
| 274 | + |
| 275 | +instance hasColimits_monCat : HasColimits MonCat |
| 276 | + where has_colimits_of_shape _ _ := |
| 277 | + { has_colimit := fun F => |
| 278 | + HasColimit.mk |
| 279 | + { cocone := colimitCocone F |
| 280 | + isColimit := colimitIsColimit F } } |
| 281 | +set_option linter.uppercaseLean3 false in |
| 282 | +#align Mon.colimits.has_colimits_Mon MonCat.Colimits.hasColimits_monCat |
| 283 | + |
| 284 | +end MonCat.Colimits |
0 commit comments