|
| 1 | +/- |
| 2 | +Copyright (c) 2021 Andrew Yang. All rights reserved. |
| 3 | +Released under Apache 2.0 license as described in the file LICENSE. |
| 4 | +Authors: Andrew Yang |
| 5 | +-/ |
| 6 | +import category_theory.limits.shapes.pullbacks |
| 7 | +import ring_theory.tensor_product |
| 8 | +import algebra.category.CommRing.limits |
| 9 | +import algebra.category.CommRing.colimits |
| 10 | +import category_theory.limits.shapes.strict_initial |
| 11 | +import ring_theory.subring.basic |
| 12 | +import ring_theory.ideal.local_ring |
| 13 | +import category_theory.limits.preserves.limits |
| 14 | + |
| 15 | +/-! |
| 16 | +# Constructions of (co)limits in CommRing |
| 17 | +
|
| 18 | +In this file we provide the explicit (co)cones for various (co)limits in `CommRing`, including |
| 19 | +* tensor product is the pushout |
| 20 | +* `Z` is the initial object |
| 21 | +* `0` is the strict terminal object |
| 22 | +* cartesian product is the product |
| 23 | +* `ring_hom.eq_locus` is the equalizer |
| 24 | +
|
| 25 | +-/ |
| 26 | + |
| 27 | +universes u u' |
| 28 | + |
| 29 | +open category_theory category_theory.limits |
| 30 | +open_locale tensor_product |
| 31 | + |
| 32 | +namespace CommRing |
| 33 | + |
| 34 | +section pushout |
| 35 | + |
| 36 | +variables {R A B : CommRing.{u}} (f : R ⟶ A) (g : R ⟶ B) |
| 37 | + |
| 38 | +/-- The explicit cocone with tensor products as the fibered product in `CommRing`. -/ |
| 39 | +def pushout_cocone : limits.pushout_cocone f g := |
| 40 | +begin |
| 41 | + letI := ring_hom.to_algebra f, |
| 42 | + letI := ring_hom.to_algebra g, |
| 43 | + apply limits.pushout_cocone.mk, |
| 44 | + show CommRing, from CommRing.of (A ⊗[R] B), |
| 45 | + show A ⟶ _, from algebra.tensor_product.include_left.to_ring_hom, |
| 46 | + show B ⟶ _, from algebra.tensor_product.include_right.to_ring_hom, |
| 47 | + ext r, |
| 48 | + transitivity algebra_map R (A ⊗[R] B) r, |
| 49 | + { exact algebra.tensor_product.include_left.commutes r }, |
| 50 | + { exact (algebra.tensor_product.include_right.commutes r).symm } |
| 51 | +end |
| 52 | + |
| 53 | +@[simp] |
| 54 | +lemma pushout_cocone_inl : (pushout_cocone f g).inl = (by |
| 55 | +{ letI := f.to_algebra, letI := g.to_algebra, |
| 56 | + exactI algebra.tensor_product.include_left.to_ring_hom }) := rfl |
| 57 | + |
| 58 | +@[simp] |
| 59 | +lemma pushout_cocone_inr : (pushout_cocone f g).inr = (by |
| 60 | +{ letI := f.to_algebra, letI := g.to_algebra, |
| 61 | + exactI algebra.tensor_product.include_right.to_ring_hom }) := rfl |
| 62 | + |
| 63 | +@[simp] |
| 64 | +lemma pushout_cocone_X : (pushout_cocone f g).X = (by |
| 65 | +{ letI := f.to_algebra, letI := g.to_algebra, |
| 66 | + exactI CommRing.of (A ⊗[R] B) }) := rfl |
| 67 | + |
| 68 | +/-- Verify that the `pushout_cocone` is indeed the colimit. -/ |
| 69 | +def pushout_cocone_is_colimit : limits.is_colimit (pushout_cocone f g) := |
| 70 | +limits.pushout_cocone.is_colimit_aux' _ (λ s, |
| 71 | +begin |
| 72 | + letI := ring_hom.to_algebra f, |
| 73 | + letI := ring_hom.to_algebra g, |
| 74 | + letI := ring_hom.to_algebra (f ≫ s.inl), |
| 75 | + let f' : A →ₐ[R] s.X := { commutes' := λ r, by |
| 76 | + { change s.inl.to_fun (f r) = (f ≫ s.inl) r, refl }, ..s.inl }, |
| 77 | + let g' : B →ₐ[R] s.X := { commutes' := λ r, by |
| 78 | + { change (g ≫ s.inr) r = (f ≫ s.inl) r, |
| 79 | + congr' 1, |
| 80 | + exact (s.ι.naturality limits.walking_span.hom.snd).trans |
| 81 | + (s.ι.naturality limits.walking_span.hom.fst).symm }, ..s.inr }, |
| 82 | + /- The factor map is a ⊗ b ↦ f(a) * g(b). -/ |
| 83 | + use alg_hom.to_ring_hom (algebra.tensor_product.product_map f' g'), |
| 84 | + simp only [pushout_cocone_inl, pushout_cocone_inr], |
| 85 | + split, { ext x, exact algebra.tensor_product.product_map_left_apply _ _ x, }, |
| 86 | + split, { ext x, exact algebra.tensor_product.product_map_right_apply _ _ x, }, |
| 87 | + intros h eq1 eq2, |
| 88 | + let h' : (A ⊗[R] B) →ₐ[R] s.X := |
| 89 | + { commutes' := λ r, by |
| 90 | + { change h ((f r) ⊗ₜ[R] 1) = s.inl (f r), |
| 91 | + rw ← eq1, simp }, ..h }, |
| 92 | + suffices : h' = algebra.tensor_product.product_map f' g', |
| 93 | + { ext x, |
| 94 | + change h' x = algebra.tensor_product.product_map f' g' x, |
| 95 | + rw this }, |
| 96 | + apply algebra.tensor_product.ext, |
| 97 | + intros a b, |
| 98 | + simp [← eq1, ← eq2, ← h.map_mul], |
| 99 | +end) |
| 100 | + |
| 101 | +end pushout |
| 102 | + |
| 103 | +section terminal |
| 104 | + |
| 105 | +/-- The trivial ring is the (strict) terminal object of `CommRing`. -/ |
| 106 | +def punit_is_terminal : is_terminal (CommRing.of.{u} punit) := |
| 107 | +begin |
| 108 | + apply_with is_terminal.of_unique { instances := ff }, |
| 109 | + tidy |
| 110 | +end |
| 111 | + |
| 112 | +instance CommRing_has_strict_terminal_objects : has_strict_terminal_objects CommRing.{u} := |
| 113 | +begin |
| 114 | + apply has_strict_terminal_objects_of_terminal_is_strict (CommRing.of punit), |
| 115 | + intros X f, |
| 116 | + refine ⟨⟨by tidy, by ext, _⟩⟩, |
| 117 | + ext, |
| 118 | + have e : (0 : X) = 1 := by { rw [← f.map_one, ← f.map_zero], congr }, |
| 119 | + replace e : 0 * x = 1 * x := congr_arg (λ a, a * x) e, |
| 120 | + rw [one_mul, zero_mul, ← f.map_zero] at e, |
| 121 | + exact e, |
| 122 | +end |
| 123 | + |
| 124 | +/-- `ℤ` is the initial object of `CommRing`. -/ |
| 125 | +def Z_is_initial : is_initial (CommRing.of ℤ) := |
| 126 | +begin |
| 127 | + apply_with is_initial.of_unique { instances := ff }, |
| 128 | + exact λ R, ⟨⟨int.cast_ring_hom R⟩, λ a, a.ext_int _⟩, |
| 129 | +end |
| 130 | + |
| 131 | +end terminal |
| 132 | + |
| 133 | +section product |
| 134 | + |
| 135 | +variables (A B : CommRing.{u}) |
| 136 | + |
| 137 | +/-- The product in `CommRing` is the cartesian product. This is the binary fan. -/ |
| 138 | +@[simps X] |
| 139 | +def prod_fan : binary_fan A B := |
| 140 | +binary_fan.mk (CommRing.of_hom $ ring_hom.fst A B) (CommRing.of_hom $ ring_hom.snd A B) |
| 141 | + |
| 142 | +/-- The product in `CommRing` is the cartesian product. -/ |
| 143 | +def prod_fan_is_limit : is_limit (prod_fan A B) := |
| 144 | +{ lift := λ c, ring_hom.prod (c.π.app walking_pair.left) (c.π.app walking_pair.right), |
| 145 | + fac' := λ c j, by { ext, cases j; simpa [of_hom] }, |
| 146 | + uniq' := λ s m h, by { ext, { simpa using congr_hom (h walking_pair.left) x }, |
| 147 | + { simpa using congr_hom (h walking_pair.right) x } } } |
| 148 | + |
| 149 | +end product |
| 150 | + |
| 151 | +section equalizer |
| 152 | + |
| 153 | +variables {A B : CommRing.{u}} (f g : A ⟶ B) |
| 154 | + |
| 155 | +/-- The equalizer in `CommRing` is the equalizer as sets. This is the equalizer fork. -/ |
| 156 | +def equalizer_fork : fork f g := |
| 157 | +fork.of_ι (CommRing.of_hom (ring_hom.eq_locus f g).subtype) (by { ext ⟨x, e⟩, simpa using e }) |
| 158 | + |
| 159 | +/-- The equalizer in `CommRing` is the equalizer as sets. -/ |
| 160 | +def equalizer_fork_is_limit : is_limit (equalizer_fork f g) := |
| 161 | +begin |
| 162 | + fapply fork.is_limit.mk', |
| 163 | + intro s, |
| 164 | + use s.ι.cod_restrict' _ (λ x, (concrete_category.congr_hom s.condition x : _)), |
| 165 | + split, |
| 166 | + { ext, refl }, |
| 167 | + { intros m hm, ext x, exact concrete_category.congr_hom hm x } |
| 168 | +end |
| 169 | + |
| 170 | +instance : is_local_ring_hom (equalizer_fork f g).ι := |
| 171 | +begin |
| 172 | + constructor, |
| 173 | + rintros ⟨a, (h₁ : _ = _)⟩ (⟨⟨x,y,h₃,h₄⟩,(rfl : x = _)⟩ : is_unit a), |
| 174 | + have : y ∈ ring_hom.eq_locus f g, |
| 175 | + { apply (f.is_unit_map ⟨⟨x,y,h₃,h₄⟩,rfl⟩ : is_unit (f x)).mul_left_inj.mp, |
| 176 | + conv_rhs { rw h₁ }, |
| 177 | + rw [← f.map_mul, ← g.map_mul, h₄, f.map_one, g.map_one] }, |
| 178 | + rw is_unit_iff_exists_inv, |
| 179 | + exact ⟨⟨y, this⟩, subtype.eq h₃⟩, |
| 180 | +end |
| 181 | + |
| 182 | +instance equalizer_ι_is_local_ring_hom (F : walking_parallel_pair.{u} ⥤ CommRing.{u}) : |
| 183 | + is_local_ring_hom (limit.π F walking_parallel_pair.zero) := |
| 184 | +begin |
| 185 | + have := lim_map_π (diagram_iso_parallel_pair F).hom walking_parallel_pair.zero, |
| 186 | + rw ← is_iso.comp_inv_eq at this, |
| 187 | + rw ← this, |
| 188 | + rw ← limit.iso_limit_cone_hom_π ⟨_, equalizer_fork_is_limit |
| 189 | + (F.map walking_parallel_pair_hom.left) (F.map walking_parallel_pair_hom.right)⟩ |
| 190 | + walking_parallel_pair.zero, |
| 191 | + change is_local_ring_hom ((lim.map _ ≫ _ ≫ (equalizer_fork _ _).ι) ≫ _), |
| 192 | + apply_instance |
| 193 | +end |
| 194 | + |
| 195 | +open category_theory.limits.walking_parallel_pair opposite |
| 196 | +open category_theory.limits.walking_parallel_pair_hom |
| 197 | + |
| 198 | +instance equalizer_ι_is_local_ring_hom' (F : walking_parallel_pair.{u}ᵒᵖ ⥤ CommRing.{u}) : |
| 199 | + is_local_ring_hom (limit.π F (opposite.op walking_parallel_pair.one)) := |
| 200 | +begin |
| 201 | + have : _ = limit.π F (walking_parallel_pair_op_equiv.{u u}.functor.obj _) := |
| 202 | + (limit.iso_limit_cone_inv_π ⟨_, is_limit.whisker_equivalence (limit.is_limit F) |
| 203 | + walking_parallel_pair_op_equiv⟩ walking_parallel_pair.zero : _), |
| 204 | + erw ← this, |
| 205 | + apply_instance |
| 206 | +end |
| 207 | + |
| 208 | +end equalizer |
| 209 | + |
| 210 | +end CommRing |
0 commit comments