Skip to content
This repository was archived by the owner on Jul 24, 2024. It is now read-only.

Commit 03dd404

Browse files
committed
feat(algebra/category): (co)limits in CommRing (#10593)
Co-authored-by: erd1 <the.erd.one@gmail.com>
1 parent 173a21a commit 03dd404

File tree

3 files changed

+214
-90
lines changed

3 files changed

+214
-90
lines changed
Lines changed: 210 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,210 @@
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

src/algebra/category/CommRing/pushout.lean

Lines changed: 0 additions & 90 deletions
This file was deleted.

src/ring_theory/ideal/local_ring.lean

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,10 @@ instance is_local_ring_hom_comp [semiring R] [semiring S] [semiring T]
178178
is_local_ring_hom (g.comp f) :=
179179
{ map_nonunit := λ a, is_local_ring_hom.map_nonunit a ∘ is_local_ring_hom.map_nonunit (f a) }
180180

181+
instance _root_.CommRing.is_local_ring_hom_comp {R S T : CommRing} (f : R ⟶ S) (g : S ⟶ T)
182+
[is_local_ring_hom g] [is_local_ring_hom f] :
183+
is_local_ring_hom (f ≫ g) := is_local_ring_hom_comp _ _
184+
181185
instance is_local_ring_hom_equiv [semiring R] [semiring S] (f : R ≃+* S) :
182186
is_local_ring_hom f.to_ring_hom :=
183187
{ map_nonunit := λ a ha,

0 commit comments

Comments
 (0)