Skip to content

Commit 26ad5ce

Browse files
jjaassoonnzjjj-loreaux
committed
feat(RingTheory/TwoSidedIdeal): add some basic operations on two-sided-ideals (#14460)
Co-authored-by: Jireh Loreaux <oreaujy@gmail.com> Co-authored-by: zjj <zjj@zjj> Co-authored-by: Jireh Loreaux <loreaujy@gmail.com>
1 parent 47ef55c commit 26ad5ce

File tree

4 files changed

+358
-0
lines changed

4 files changed

+358
-0
lines changed

Mathlib.lean

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4069,8 +4069,10 @@ import Mathlib.RingTheory.TensorProduct.MvPolynomial
40694069
import Mathlib.RingTheory.Trace.Basic
40704070
import Mathlib.RingTheory.Trace.Defs
40714071
import Mathlib.RingTheory.TwoSidedIdeal.Basic
4072+
import Mathlib.RingTheory.TwoSidedIdeal.BigOperators
40724073
import Mathlib.RingTheory.TwoSidedIdeal.Instances
40734074
import Mathlib.RingTheory.TwoSidedIdeal.Lattice
4075+
import Mathlib.RingTheory.TwoSidedIdeal.Operations
40744076
import Mathlib.RingTheory.UniqueFactorizationDomain
40754077
import Mathlib.RingTheory.Unramified.Basic
40764078
import Mathlib.RingTheory.Unramified.Derivations

Mathlib/RingTheory/Congruence/Basic.lean

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,16 @@ theorem ext' {c d : RingCon R} (H : ⇑c = ⇑d) : c = d := DFunLike.coe_injecti
126126
theorem ext {c d : RingCon R} (H : ∀ x y, c x y ↔ d x y) : c = d :=
127127
ext' <| by ext; apply H
128128

129+
/--
130+
Pulling back a `RingCon` across a ring homomorphism.
131+
-/
132+
def comap {R R' F : Type*} [Add R] [Add R']
133+
[FunLike F R R'] [AddHomClass F R R'] [Mul R] [Mul R'] [MulHomClass F R R']
134+
(J : RingCon R') (f : F) :
135+
RingCon R where
136+
__ := J.toCon.comap f (map_mul f)
137+
__ := J.toAddCon.comap f (map_add f)
138+
129139
end Basic
130140

131141
section Quotient
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
/-
2+
Copyright (c) 2024 Jujian Zhang. All rights reserved.
3+
Released under Apache 2.0 license as described in the file LICENSE.
4+
Authors: Jujian Zhang
5+
-/
6+
7+
import Mathlib.RingTheory.Congruence.BigOperators
8+
import Mathlib.RingTheory.TwoSidedIdeal.Basic
9+
10+
/-!
11+
# Interactions between `∑, ∏` and two sided ideals
12+
13+
-/
14+
15+
namespace TwoSidedIdeal
16+
17+
section sum
18+
19+
variable {R : Type*} [NonUnitalNonAssocRing R] (I : TwoSidedIdeal R)
20+
21+
lemma listSum_mem {ι : Type*} (l : List ι) (f : ι → R) (hl : ∀ x ∈ l, f x ∈ I) :
22+
(l.map f).sum ∈ I := by
23+
rw [mem_iff, ← List.sum_map_zero]
24+
exact I.ringCon.listSum l hl
25+
26+
lemma multisetSum_mem {ι : Type*} (s : Multiset ι) (f : ι → R) (hs : ∀ x ∈ s, f x ∈ I) :
27+
(s.map f).sum ∈ I := by
28+
rw [mem_iff, ← Multiset.sum_map_zero]
29+
exact I.ringCon.multisetSum s hs
30+
31+
lemma finsetSum_mem {ι : Type*} (s : Finset ι) (f : ι → R) (hs : ∀ x ∈ s, f x ∈ I) :
32+
s.sum f ∈ I := by
33+
rw [mem_iff, ← Finset.sum_const_zero]
34+
exact I.ringCon.finsetSum s hs
35+
36+
end sum
37+
38+
section prod
39+
40+
section ring
41+
42+
variable {R : Type*} [Ring R] (I : TwoSidedIdeal R)
43+
44+
lemma listProd_mem {ι : Type*} (l : List ι) (f : ι → R) (hl : ∃ x ∈ l, f x ∈ I) :
45+
(l.map f).prod ∈ I := by
46+
induction l with
47+
| nil => simp only [List.not_mem_nil, false_and, exists_false] at hl
48+
| cons x l ih =>
49+
simp only [List.mem_cons, exists_eq_or_imp] at hl
50+
rcases hl with h | hal
51+
· simpa only [List.map_cons, List.prod_cons] using I.mul_mem_right _ _ h
52+
· simpa only [List.map_cons, List.prod_cons] using I.mul_mem_left _ _ <| ih hal
53+
54+
end ring
55+
56+
section commRing
57+
58+
variable {R : Type*} [CommRing R] (I : TwoSidedIdeal R)
59+
60+
lemma multiSetProd_mem {ι : Type*} (s : Multiset ι) (f : ι → R) (hs : ∃ x ∈ s, f x ∈ I) :
61+
(s.map f).prod ∈ I := by
62+
rcases s
63+
simpa using listProd_mem (hl := hs)
64+
65+
lemma finsetProd_mem {ι : Type*} (s : Finset ι) (f : ι → R) (hs : ∃ x ∈ s, f x ∈ I) :
66+
s.prod f ∈ I := by
67+
rcases s
68+
simpa using multiSetProd_mem (hs := hs)
69+
70+
end commRing
71+
72+
end prod
73+
74+
end TwoSidedIdeal
Lines changed: 272 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,272 @@
1+
/-
2+
Copyright (c) 2024 Jujian Zhang. All rights reserved.
3+
Released under Apache 2.0 license as described in the file LICENSE.
4+
Authors: Jujian Zhang, Jireh Loreaux
5+
-/
6+
7+
import Mathlib.RingTheory.TwoSidedIdeal.Lattice
8+
import Mathlib.RingTheory.Congruence.Opposite
9+
import Mathlib.Algebra.BigOperators.Ring
10+
import Mathlib.Data.Fintype.BigOperators
11+
import Mathlib.RingTheory.Ideal.Basic
12+
import Mathlib.Order.GaloisConnection
13+
14+
/-!
15+
# Operations on two-sided ideals
16+
17+
This file defines operations on two-sided ideals of a ring `R`.
18+
19+
## Main definitions and results
20+
21+
- `TwoSidedIdeal.span`: the span of `s ⊆ R` is the smallest two-sided ideal containing the set.
22+
- `TwoSidedIdeal.mem_span_iff_mem_addSubgroup_closure_nonunital`: in an associative but non-unital
23+
ring, an element `x` is in the two-sided ideal spanned by `s` if and only if `x` is in the closure
24+
of `s ∪ {y * a | y ∈ s, a ∈ R} ∪ {a * y | y ∈ s, a ∈ R} ∪ {a * y * b | y ∈ s, a, b ∈ R}` as an
25+
additive subgroup.
26+
- `TwoSidedIdeal.mem_span_iff_mem_addSubgroup_closure`: in a unital and associative ring, an
27+
element `x` is in the two-sided ideal spanned by `s` if and only if `x` is in the closure of
28+
`{a*y*b | a, b ∈ R, y ∈ s}` as an additive subgroup.
29+
30+
31+
- `TwoSidedIdeal.comap`: pullback of a two-sided ideal; defined as the preimage of a
32+
two-sided ideal.
33+
- `TwoSidedIdeal.map`: pushforward of a two-sided ideal; defined as the span of the image of a
34+
two-sided ideal.
35+
- `TwoSidedIdeal.ker`: the kernel of a ring homomorphism as a two-sided ideal.
36+
37+
- `TwoSidedIdeal.gc`: `fromIdeal` and `asIdeal` form a Galois connection where
38+
`fromIdeal : Ideal R → TwoSidedIdeal R` is defined as the smallest two-sided ideal containing an
39+
ideal and `asIdeal : TwoSidedIdeal R → Ideal R` the inclusion map.
40+
-/
41+
42+
namespace TwoSidedIdeal
43+
44+
section NonUnitalNonAssocRing
45+
46+
variable {R S : Type*} [NonUnitalNonAssocRing R] [NonUnitalNonAssocRing S]
47+
variable {F : Type*} [FunLike F R S]
48+
variable (f : F)
49+
50+
/--
51+
The smallest two-sided ideal containing a set.
52+
-/
53+
abbrev span (s : Set R) : TwoSidedIdeal R :=
54+
{ ringCon := ringConGen (fun a b ↦ a - b ∈ s) }
55+
56+
lemma subset_span {s : Set R} : s ⊆ (span s : Set R) := by
57+
intro x hx
58+
rw [SetLike.mem_coe, mem_iff]
59+
exact RingConGen.Rel.of _ _ (by simpa using hx)
60+
61+
lemma mem_span_iff {s : Set R} {x} :
62+
x ∈ span s ↔ ∀ (I : TwoSidedIdeal R), s ⊆ I → x ∈ I := by
63+
refine ⟨?_, fun h => h _ subset_span⟩
64+
delta span
65+
rw [RingCon.ringConGen_eq]
66+
intro h I hI
67+
refine sInf_le (α := RingCon R) ?_ h
68+
intro x y hxy
69+
specialize hI hxy
70+
rwa [SetLike.mem_coe, ← rel_iff] at hI
71+
72+
lemma span_mono {s t : Set R} (h : s ⊆ t) : span s ≤ span t := by
73+
intro x hx
74+
rw [mem_span_iff] at hx ⊢
75+
exact fun I hI => hx I <| h.trans hI
76+
77+
/--
78+
Pushout of a two-sided ideal. Defined as the span of the image of a two-sided ideal under a ring
79+
homomorphism.
80+
-/
81+
def map (I : TwoSidedIdeal R) : TwoSidedIdeal S :=
82+
span (f '' I)
83+
84+
lemma map_mono {I J : TwoSidedIdeal R} (h : I ≤ J) :
85+
map f I ≤ map f J :=
86+
span_mono <| Set.image_mono h
87+
88+
variable [NonUnitalRingHomClass F R S]
89+
90+
/--
91+
Preimage of a two-sided ideal, as a two-sided ideal. -/
92+
def comap (I : TwoSidedIdeal S) : TwoSidedIdeal R :=
93+
{ ringCon := I.ringCon.comap f }
94+
95+
lemma mem_comap {I : TwoSidedIdeal S} {x : R} :
96+
x ∈ I.comap f ↔ f x ∈ I := by
97+
simp [comap, RingCon.comap, mem_iff]
98+
99+
/--
100+
The kernel of a ring homomorphism, as a two-sided ideal.
101+
-/
102+
def ker : TwoSidedIdeal R :=
103+
.mk'
104+
{r | f r = 0} (map_zero _) (by rintro _ _ (h1 : f _ = 0) (h2 : f _ = 0); simp [h1, h2])
105+
(by rintro _ (h : f _ = 0); simp [h]) (by rintro _ _ (h : f _ = 0); simp [h])
106+
(by rintro _ _ (h : f _ = 0); simp [h])
107+
108+
lemma mem_ker {x : R} : x ∈ ker f ↔ f x = 0 := by
109+
delta ker; rw [mem_mk']; rfl
110+
· rintro _ _ (h1 : f _ = 0) (h2 : f _ = 0); simp [h1, h2]
111+
· rintro _ (h : f _ = 0); simp [h]
112+
· rintro _ _ (h : f _ = 0); simp [h]
113+
· rintro _ _ (h : f _ = 0); simp [h]
114+
115+
end NonUnitalNonAssocRing
116+
117+
section NonUnitalRing
118+
119+
variable {R : Type*} [NonUnitalRing R]
120+
121+
open AddSubgroup in
122+
/-- If `s : Set R` is absorbing under multiplication, then its `TwoSidedIdeal.span` coincides with
123+
its `AddSubgroup.closure`, as sets. -/
124+
lemma mem_span_iff_mem_addSubgroup_closure_absorbing {s : Set R}
125+
(h_left : ∀ x y, y ∈ s → x * y ∈ s) (h_right : ∀ y x, y ∈ s → y * x ∈ s) {z : R} :
126+
z ∈ span s ↔ z ∈ closure s := by
127+
have h_left' {x y} (hy : y ∈ closure s) : x * y ∈ closure s := by
128+
have := (AddMonoidHom.mulLeft x).map_closure s ▸ mem_map_of_mem _ hy
129+
refine closure_mono ?_ this
130+
rintro - ⟨y, hy, rfl⟩
131+
exact h_left x y hy
132+
have h_right' {y x} (hy : y ∈ closure s) : y * x ∈ closure s := by
133+
have := (AddMonoidHom.mulRight x).map_closure s ▸ mem_map_of_mem _ hy
134+
refine closure_mono ?_ this
135+
rintro - ⟨y, hy, rfl⟩
136+
exact h_right y x hy
137+
let I : TwoSidedIdeal R := .mk' (closure s) (AddSubgroup.zero_mem _)
138+
(AddSubgroup.add_mem _) (AddSubgroup.neg_mem _) h_left' h_right'
139+
suffices z ∈ span s ↔ z ∈ I by simpa only [I, mem_mk', SetLike.mem_coe]
140+
rw [mem_span_iff]
141+
-- Suppose that for every ideal `J` with `s ⊆ J`, then `z ∈ J`. Apply this to `I` to get `z ∈ I`.
142+
refine ⟨fun h ↦ h I fun x hx ↦ ?mem_closure_of_forall, fun hz J hJ ↦ ?mem_ideal_of_subset⟩
143+
case mem_closure_of_forall => simpa only [I, SetLike.mem_coe, mem_mk'] using subset_closure hx
144+
/- Conversely, suppose that `z ∈ I` and that `J` is any ideal containing `s`. Then by the
145+
induction principle for `AddSubgroup`, we must also have `z ∈ J`. -/
146+
case mem_ideal_of_subset =>
147+
simp only [I, SetLike.mem_coe, mem_mk'] at hz
148+
induction hz using closure_induction' with
149+
| mem x hx => exact hJ hx
150+
| one => exact zero_mem _
151+
| mul x _ y _ hx hy => exact J.add_mem hx hy
152+
| inv x _ hx => exact J.neg_mem hx
153+
154+
open Pointwise Set
155+
156+
lemma set_mul_subset {s : Set R} {I : TwoSidedIdeal R} (h : s ⊆ I) (t : Set R):
157+
t * s ⊆ I := by
158+
rintro - ⟨r, -, x, hx, rfl⟩
159+
exact mul_mem_left _ _ _ (h hx)
160+
161+
lemma subset_mul_set {s : Set R} {I : TwoSidedIdeal R} (h : s ⊆ I) (t : Set R):
162+
s * t ⊆ I := by
163+
rintro - ⟨x, hx, r, -, rfl⟩
164+
exact mul_mem_right _ _ _ (h hx)
165+
166+
lemma mem_span_iff_mem_addSubgroup_closure_nonunital {s : Set R} {z : R} :
167+
z ∈ span s ↔ z ∈ AddSubgroup.closure (s ∪ s * univ ∪ univ * s ∪ univ * s * univ) := by
168+
trans z ∈ span (s ∪ s * univ ∪ univ * s ∪ univ * s * univ)
169+
· refine ⟨(span_mono (by simp only [Set.union_assoc, Set.subset_union_left]) ·), fun h ↦ ?_⟩
170+
refine mem_span_iff.mp h (span s) ?_
171+
simp only [union_subset_iff, union_assoc]
172+
exact ⟨subset_span, subset_mul_set subset_span _, set_mul_subset subset_span _,
173+
subset_mul_set (set_mul_subset subset_span _) _⟩
174+
· refine mem_span_iff_mem_addSubgroup_closure_absorbing ?_ ?_
175+
· rintro x y (((hy | ⟨y, hy, r, -, rfl⟩) | ⟨r, -, y, hy, rfl⟩) |
176+
⟨-, ⟨r', -, y, hy, rfl⟩, r, -, rfl⟩)
177+
· exact .inl <| .inr <| ⟨x, mem_univ _, y, hy, rfl⟩
178+
· exact .inr <| ⟨x * y, ⟨x, mem_univ _, y, hy, rfl⟩, r, mem_univ _, mul_assoc ..⟩
179+
· exact .inl <| .inr <| ⟨x * r, mem_univ _, y, hy, mul_assoc ..⟩
180+
· refine .inr <| ⟨x * r' * y, ⟨x * r', mem_univ _, y, hy, ?_⟩, ⟨r, mem_univ _, ?_⟩⟩
181+
all_goals simp [mul_assoc]
182+
· rintro y x (((hy | ⟨y, hy, r, -, rfl⟩) | ⟨r, -, y, hy, rfl⟩) |
183+
⟨-, ⟨r', -, y, hy, rfl⟩, r, -, rfl⟩)
184+
· exact .inl <| .inl <| .inr ⟨y, hy, x, mem_univ _, rfl⟩
185+
· exact .inl <| .inl <| .inr ⟨y, hy, r * x, mem_univ _, (mul_assoc ..).symm⟩
186+
· exact .inr <| ⟨r * y, ⟨r, mem_univ _, y, hy, rfl⟩, x, mem_univ _, rfl⟩
187+
· refine .inr <| ⟨r' * y, ⟨r', mem_univ _, y, hy, rfl⟩, r * x, mem_univ _, ?_⟩
188+
simp [mul_assoc]
189+
190+
end NonUnitalRing
191+
192+
section Ring
193+
194+
variable {R : Type*} [Ring R]
195+
196+
open Pointwise Set in
197+
lemma mem_span_iff_mem_addSubgroup_closure {s : Set R} {z : R} :
198+
z ∈ span s ↔ z ∈ AddSubgroup.closure (univ * s * univ) := by
199+
trans z ∈ span (univ * s * univ)
200+
· refine ⟨(span_mono (fun x hx ↦ ?_) ·), fun hz ↦ ?_⟩
201+
· exact ⟨1 * x, ⟨1, mem_univ _, x, hx, rfl⟩, 1, mem_univ _, by simp⟩
202+
· exact mem_span_iff.mp hz (span s) <| subset_mul_set (set_mul_subset subset_span _) _
203+
· refine mem_span_iff_mem_addSubgroup_closure_absorbing ?_ ?_
204+
· intro x y hy
205+
rw [mul_assoc] at hy ⊢
206+
obtain ⟨r, -, y, hy, rfl⟩ := hy
207+
exact ⟨x * r, mem_univ _, y, hy, mul_assoc ..⟩
208+
· rintro - x ⟨y, hy, r, -, rfl⟩
209+
exact ⟨y, hy, r * x, mem_univ _, (mul_assoc ..).symm⟩
210+
211+
/-- Given an ideal `I`, `span I` is the smallest two-sided ideal containing `I`. -/
212+
def fromIdeal : Ideal R →o TwoSidedIdeal R where
213+
toFun I := span I
214+
monotone' _ _ := span_mono
215+
216+
lemma mem_fromIdeal {I : Ideal R} {x : R} :
217+
x ∈ fromIdeal I ↔ x ∈ span I := by simp [fromIdeal]
218+
219+
/-- Every two-sided ideal is also a left ideal. -/
220+
def asIdeal : TwoSidedIdeal R →o Ideal R where
221+
toFun I :=
222+
{ carrier := I
223+
add_mem' := I.add_mem
224+
zero_mem' := I.zero_mem
225+
smul_mem' := fun r x hx => I.mul_mem_left r x hx }
226+
monotone' _ _ h _ h' := h h'
227+
228+
lemma mem_asIdeal {I : TwoSidedIdeal R} {x : R} :
229+
x ∈ asIdeal I ↔ x ∈ I := by simp [asIdeal]
230+
231+
lemma gc : GaloisConnection fromIdeal (asIdeal (R := R)) :=
232+
fun I J => ⟨fun h x hx ↦ h <| mem_span_iff.2 fun _ H ↦ H hx, fun h x hx ↦ by
233+
simp only [fromIdeal, OrderHom.coe_mk, mem_span_iff] at hx
234+
exact hx _ h⟩
235+
236+
@[simp]
237+
lemma coe_asIdeal {I : TwoSidedIdeal R} : (asIdeal I : Set R) = I := rfl
238+
239+
/-- Every two-sided ideal is also a right ideal. -/
240+
def asIdealOpposite : TwoSidedIdeal R →o Ideal Rᵐᵒᵖ where
241+
toFun I := asIdeal ⟨I.ringCon.op⟩
242+
monotone' I J h x h' := by
243+
simp only [mem_asIdeal, mem_iff, RingCon.op_iff, MulOpposite.unop_zero] at h' ⊢
244+
exact J.rel_iff _ _ |>.2 <| h <| I.rel_iff 0 x.unop |>.1 h'
245+
246+
lemma mem_asIdealOpposite {I : TwoSidedIdeal R} {x : Rᵐᵒᵖ} :
247+
x ∈ asIdealOpposite I ↔ x.unop ∈ I := by
248+
simpa [asIdealOpposite, asIdeal, TwoSidedIdeal.mem_iff, RingCon.op_iff] using
249+
⟨I.ringCon.symm, I.ringCon.symm⟩
250+
251+
end Ring
252+
253+
section CommRing
254+
255+
variable {R : Type*} [CommRing R]
256+
257+
/--
258+
When the ring is commutative, two-sided ideals are exactly the same as left ideals.
259+
-/
260+
def orderIsoIdeal : TwoSidedIdeal R ≃o Ideal R where
261+
toFun := asIdeal
262+
invFun := fromIdeal
263+
map_rel_iff' := ⟨fun h _ hx ↦ h hx, fun h ↦ asIdeal.monotone' h⟩
264+
left_inv _ := SetLike.ext fun _ ↦ mem_span_iff.trans <| by aesop
265+
right_inv J := SetLike.ext fun x ↦ mem_span_iff.trans
266+
fun h ↦ mem_mk' _ _ _ _ _ _ _ |>.1 <| h (mk'
267+
J J.zero_mem J.add_mem J.neg_mem (J.mul_mem_left _) (J.mul_mem_right _))
268+
(fun x => by simp [mem_mk']), by aesop⟩
269+
270+
end CommRing
271+
272+
end TwoSidedIdeal

0 commit comments

Comments
 (0)