Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
| Download
Try doing some basic maths questions in the Lean Theorem Prover. Functions, real numbers, equivalence relations and groups. Click on README.md and then on "Open in CoCalc with one click".
Project: Xena
Views: 18536License: APACHE
/- Copyright (c) 2019 Scott Morrison. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Authors: Scott Morrison -/ import algebra.category.Mon.basic import category_theory.limits.limits /-! # The category of monoids has all colimits. We do this construction knowing nothing about monoids. In particular, I want to claim that this file could be produced by a python script that just looks at the output of `#print monoid`: -- structure monoid : Type u → Type u -- fields: -- monoid.mul : Π {α : Type u} [c : monoid α], α → α → α -- monoid.mul_assoc : ∀ {α : Type u} [c : monoid α] (a b c_1 : α), a * b * c_1 = a * (b * c_1) -- monoid.one : Π (α : Type u) [c : monoid α], α -- monoid.one_mul : ∀ {α : Type u} [c : monoid α] (a : α), 1 * a = a -- monoid.mul_one : ∀ {α : Type u} [c : monoid α] (a : α), a * 1 = a and if we'd fed it the output of `#print comm_ring`, this file would instead build colimits of commutative rings. A slightly bolder claim is that we could do this with tactics, as well. Because this file is "pre-automated", it doesn't meet current documentation standards. Hopefully eventually most of it will be automatically synthesised. -/ universes v open category_theory open category_theory.limits namespace Mon.colimits variables {J : Type v} [small_category J] (F : J ⥤ Mon.{v}) inductive prequotient -- There's always `of` | of : Π (j : J) (x : F.obj j), prequotient -- Then one generator for each operation | one {} : prequotient | mul : prequotient → prequotient → prequotient open prequotient inductive relation : prequotient F → prequotient F → Prop -- Make it an equivalence relation: | refl : Π (x), relation x x | symm : Π (x y) (h : relation x y), relation y x | trans : Π (x y z) (h : relation x y) (k : relation y z), relation x z -- There's always a `map` relation | map : Π (j j' : J) (f : j ⟶ j') (x : F.obj j), relation (of j' ((F.map f) x)) (of j x) -- Then one relation per operation, describing the interaction with `of` | mul : Π (j) (x y : F.obj j), relation (of j (x * y)) (mul (of j x) (of j y)) | one : Π (j), relation (of j 1) one -- Then one relation per argument of each operation | mul_1 : Π (x x' y) (r : relation x x'), relation (mul x y) (mul x' y) | mul_2 : Π (x y y') (r : relation y y'), relation (mul x y) (mul x y') -- And one relation per axiom | mul_assoc : Π (x y z), relation (mul (mul x y) z) (mul x (mul y z)) | one_mul : Π (x), relation (mul one x) x | mul_one : Π (x), relation (mul x one) x def colimit_setoid : setoid (prequotient F) := { r := relation F, iseqv := ⟨relation.refl, relation.symm, relation.trans⟩ } attribute [instance] colimit_setoid def colimit_type : Type v := quotient (colimit_setoid F) instance monoid_colimit_type : monoid (colimit_type F) := { mul := begin fapply @quot.lift _ _ ((colimit_type F) → (colimit_type F)), { intro x, fapply @quot.lift, { intro y, exact quot.mk _ (mul x y) }, { intros y y' r, apply quot.sound, exact relation.mul_2 _ _ _ r } }, { intros x x' r, funext y, induction y, dsimp, apply quot.sound, { exact relation.mul_1 _ _ _ r }, { refl } }, end, one := begin exact quot.mk _ one end, mul_assoc := λ x y z, begin induction x, induction y, induction z, dsimp, apply quot.sound, apply relation.mul_assoc, refl, refl, refl, end, one_mul := λ x, begin induction x, dsimp, apply quot.sound, apply relation.one_mul, refl, end, mul_one := λ x, begin induction x, dsimp, apply quot.sound, apply relation.mul_one, refl, end } @[simp] lemma quot_one : quot.mk setoid.r one = (1 : colimit_type F) := rfl @[simp] lemma quot_mul (x y) : quot.mk setoid.r (mul x y) = ((quot.mk setoid.r x) * (quot.mk setoid.r y) : colimit_type F) := rfl def colimit : Mon := ⟨colimit_type F, by apply_instance⟩ def cocone_fun (j : J) (x : F.obj j) : colimit_type F := quot.mk _ (of j x) def cocone_morphism (j : J) : F.obj j ⟶ colimit F := { to_fun := cocone_fun F j, map_one' := quot.sound (relation.one _ _), map_mul' := λ x y, quot.sound (relation.mul _ _ _) } @[simp] lemma cocone_naturality {j j' : J} (f : j ⟶ j') : F.map f ≫ (cocone_morphism F j') = cocone_morphism F j := begin ext, apply quot.sound, apply relation.map, end @[simp] lemma cocone_naturality_components (j j' : J) (f : j ⟶ j') (x : F.obj j): (cocone_morphism F j') (F.map f x) = (cocone_morphism F j) x := by { rw ←cocone_naturality F f, refl } def colimit_cocone : cocone F := { X := colimit F, ι := { app := cocone_morphism F, } }. @[simp] def desc_fun_lift (s : cocone F) : prequotient F → s.X | (of j x) := (s.ι.app j) x | one := 1 | (mul x y) := desc_fun_lift x * desc_fun_lift y def desc_fun (s : cocone F) : colimit_type F → s.X := begin fapply quot.lift, { exact desc_fun_lift F s }, { intros x y r, induction r; try { dsimp }, -- refl { refl }, -- symm { exact r_ih.symm }, -- trans { exact eq.trans r_ih_h r_ih_k }, -- map { rw cocone.naturality_concrete, }, -- mul { rw is_monoid_hom.map_mul ⇑((s.ι).app r_j) }, -- one { erw is_monoid_hom.map_one ⇑((s.ι).app r), refl }, -- mul_1 { rw r_ih, }, -- mul_2 { rw r_ih, }, -- mul_assoc { rw mul_assoc, }, -- one_mul { rw one_mul, }, -- mul_one { rw mul_one, } } end @[simp] def desc_morphism (s : cocone F) : colimit F ⟶ s.X := { to_fun := desc_fun F s, map_one' := rfl, map_mul' := λ x y, by { induction x; induction y; refl }, } def colimit_is_colimit : is_colimit (colimit_cocone F) := { desc := λ s, desc_morphism F s, uniq' := λ s m w, begin ext, induction x, induction x, { have w' := congr_fun (congr_arg (λ f : F.obj x_j ⟶ s.X, (f : F.obj x_j → s.X)) (w x_j)) x_x, erw w', refl, }, { simp only [desc_morphism, quot_one], erw is_monoid_hom.map_one ⇑m, refl, }, { simp only [desc_morphism, quot_mul], erw is_monoid_hom.map_mul ⇑m, rw [x_ih_a, x_ih_a_1], refl, }, refl end }. instance has_colimits_Mon : has_colimits.{v} Mon.{v} := { has_colimits_of_shape := λ J 𝒥, { has_colimit := λ F, by exactI { cocone := colimit_cocone F, is_colimit := colimit_is_colimit F } } } end Mon.colimits