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

Commit ae10dce

Browse files
feat(algebra/direct_sum/decomposition): add decompositions into a direct sum (#14626)
This is a constructive version of `direct_sum.is_internal`, and generalizes the existing `graded_algebra`. The main user-facing changes are: * `graded_algebra.decompose` is now spelt `direct_sum.decompose_alg_hom` * The simp normal form of decomposition is now `direct_sum.decompose`. * `graded_algebra.support 𝒜 x` is now spelt `(decompose 𝒜 x).support` * `left_inv` and `right_inv` has swapped, now with meaning "the decomposition is the (left|right) inverse of the canonical map" rather than the other way around To keep this from growing even larger, I've left `graded_algebra.proj` alone for a future refactor. Co-authored-by: Jujian Zhang <jujian.zhang1998@outlook.com>
1 parent 67da272 commit ae10dce

File tree

7 files changed

+279
-118
lines changed

7 files changed

+279
-118
lines changed

counterexamples/homogeneous_prime_not_prime.lean

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -83,15 +83,14 @@ def grading.decompose : (R × R) →+ direct_sum two (λ i, grading R i) :=
8383
map_zero' := by { ext1 (_|⟨⟨⟩⟩); refl },
8484
map_add' := begin
8585
rintros ⟨a1, b1⟩ ⟨a2, b2⟩,
86-
have H : b1 + b2 - (a1 + a2) = b1 - a1 + (b2 - a2), by abel,
87-
ext (_|⟨⟨⟩⟩) : 3;
88-
simp only [prod.fst_add, prod.snd_add, add_apply, submodule.coe_add, prod.mk_add_mk, H];
89-
repeat { erw of_eq_same }; repeat { erw of_eq_of_ne }; try { apply option.no_confusion };
90-
dsimp; simp only [zero_add, add_zero]; refl,
86+
rw [add_add_add_comm, ←map_add, ←map_add],
87+
dsimp only [prod.mk_add_mk],
88+
simp_rw [add_sub_add_comm],
89+
congr,
9190
end }
9291

93-
lemma grading.left_inv :
94-
function.left_inverse grading.decompose (coe_linear_map (grading R)) := λ zz,
92+
lemma grading.right_inv :
93+
function.right_inverse (coe_linear_map (grading R)) grading.decompose := λ zz,
9594
begin
9695
induction zz using direct_sum.induction_on with i zz d1 d2 ih1 ih2,
9796
{ simp only [map_zero],},
@@ -100,8 +99,8 @@ begin
10099
{ simp only [map_add, ih1, ih2], },
101100
end
102101

103-
lemma grading.right_inv :
104-
function.right_inverse grading.decompose (coe_linear_map (grading R)) := λ zz,
102+
lemma grading.left_inv :
103+
function.left_inverse (coe_linear_map (grading R)) grading.decompose := λ zz,
105104
begin
106105
cases zz with a b,
107106
unfold grading.decompose,
Lines changed: 180 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,180 @@
1+
/-
2+
Copyright (c) 2022 Eric Wieser. All rights reserved.
3+
Released under Apache 2.0 license as described in the file LICENSE.
4+
Authors: Eric Wieser, Jujian Zhang
5+
-/
6+
import algebra.direct_sum.module
7+
import algebra.module.submodule.basic
8+
9+
/-!
10+
# Decompositions of additive monoids, groups, and modules into direct sums
11+
12+
## Main definitions
13+
14+
* `direct_sum.decomposition ℳ`: A typeclass to provide a constructive decomposition from
15+
an additive monoid `M` into a family of additive submonoids `ℳ`
16+
* `direct_sum.decompose ℳ`: The canonical equivalence provided by the above typeclass
17+
18+
19+
## Main statements
20+
21+
* `direct_sum.decomposition.is_internal`: The link to `direct_sum.is_internal`.
22+
23+
## Implementation details
24+
25+
As we want to talk about different types of decomposition (additive monoids, modules, rings, ...),
26+
we choose to avoid heavily bundling `direct_sum.decompose`, instead making copies for the
27+
`add_equiv`, `linear_equiv`, etc. This means we have to repeat statements that follow from these
28+
bundled homs, but means we don't have to repeat statements for different types of decomposition.
29+
-/
30+
31+
32+
variables {ι R M σ : Type*}
33+
open_locale direct_sum big_operators
34+
namespace direct_sum
35+
36+
section add_comm_monoid
37+
variables [decidable_eq ι] [add_comm_monoid M]
38+
variables [set_like σ M] [add_submonoid_class σ M] (ℳ : ι → σ)
39+
40+
/-- A decomposition is an equivalence between an additive monoid `M` and a direct sum of additive
41+
submonoids `ℳ i` of that `M`, such that the "recomposition" is canonical. This definition also
42+
works for additive groups and modules.
43+
44+
This is a version of `direct_sum.is_internal` which comes with a constructive inverse to the
45+
canonical "recomposition" rather than just a proof that the "recomposition" is bijective. -/
46+
class decomposition :=
47+
(decompose' : M → ⨁ i, ℳ i)
48+
(left_inv : function.left_inverse (direct_sum.coe_add_monoid_hom ℳ) decompose' )
49+
(right_inv : function.right_inverse (direct_sum.coe_add_monoid_hom ℳ) decompose')
50+
51+
include M
52+
53+
/-- `direct_sum.decomposition` instances, while carrying data, are always equal. -/
54+
instance : subsingleton (decomposition ℳ) :=
55+
⟨λ x y, begin
56+
cases x with x xl xr,
57+
cases y with y yl yr,
58+
congr',
59+
exact function.left_inverse.eq_right_inverse xr yl,
60+
end
61+
62+
variables [decomposition ℳ]
63+
64+
protected lemma decomposition.is_internal : direct_sum.is_internal ℳ :=
65+
⟨decomposition.right_inv.injective, decomposition.left_inv.surjective⟩
66+
67+
/-- If `M` is graded by `ι` with degree `i` component `ℳ i`, then it is isomorphic as
68+
to a direct sum of components. This is the canonical spelling of the `decompose'` field. -/
69+
def decompose : M ≃ ⨁ i, ℳ i :=
70+
{ to_fun := decomposition.decompose',
71+
inv_fun := direct_sum.coe_add_monoid_hom ℳ,
72+
left_inv := decomposition.left_inv,
73+
right_inv := decomposition.right_inv }
74+
75+
@[simp] lemma decomposition.decompose'_eq : decomposition.decompose' = decompose ℳ := rfl
76+
77+
@[simp] lemma decompose_symm_of {i : ι} (x : ℳ i) :
78+
(decompose ℳ).symm (direct_sum.of _ i x) = x :=
79+
direct_sum.coe_add_monoid_hom_of ℳ _ _
80+
81+
@[simp] lemma decompose_coe {i : ι} (x : ℳ i) :
82+
decompose ℳ (x : M) = direct_sum.of _ i x :=
83+
by rw [←decompose_symm_of, equiv.apply_symm_apply]
84+
85+
lemma decompose_of_mem {x : M} {i : ι} (hx : x ∈ ℳ i) :
86+
decompose ℳ x = direct_sum.of (λ i, ℳ i) i ⟨x, hx⟩ :=
87+
decompose_coe _ ⟨x, hx⟩
88+
89+
lemma decompose_of_mem_same {x : M} {i : ι} (hx : x ∈ ℳ i) :
90+
(decompose ℳ x i : M) = x :=
91+
by rw [decompose_of_mem _ hx, direct_sum.of_eq_same, subtype.coe_mk]
92+
93+
lemma decompose_of_mem_ne {x : M} {i j : ι} (hx : x ∈ ℳ i) (hij : i ≠ j):
94+
(decompose ℳ x j : M) = 0 :=
95+
by rw [decompose_of_mem _ hx, direct_sum.of_eq_of_ne _ _ _ _ hij,
96+
add_submonoid_class.coe_zero]
97+
98+
/-- If `M` is graded by `ι` with degree `i` component `ℳ i`, then it is isomorphic as
99+
an additive monoid to a direct sum of components. -/
100+
@[simps {fully_applied := ff}]
101+
def decompose_add_equiv : M ≃+ ⨁ i, ℳ i := add_equiv.symm
102+
{ map_add' := map_add (direct_sum.coe_add_monoid_hom ℳ),
103+
..(decompose ℳ).symm }
104+
105+
@[simp] lemma decompose_zero : decompose ℳ (0 : M) = 0 := map_zero (decompose_add_equiv ℳ)
106+
@[simp] lemma decompose_symm_zero : (decompose ℳ).symm 0 = (0 : M) :=
107+
map_zero (decompose_add_equiv ℳ).symm
108+
109+
@[simp] lemma decompose_add (x y : M) : decompose ℳ (x + y) = decompose ℳ x + decompose ℳ y :=
110+
map_add (decompose_add_equiv ℳ) x y
111+
@[simp] lemma decompose_symm_add (x y : ⨁ i, ℳ i) :
112+
(decompose ℳ).symm (x + y) = (decompose ℳ).symm x + (decompose ℳ).symm y :=
113+
map_add (decompose_add_equiv ℳ).symm x y
114+
115+
@[simp] lemma decompose_sum {ι'} (s : finset ι') (f : ι' → M) :
116+
decompose ℳ (∑ i in s, f i) = ∑ i in s, decompose ℳ (f i) :=
117+
map_sum (decompose_add_equiv ℳ) f s
118+
@[simp] lemma decompose_symm_sum {ι'} (s : finset ι') (f : ι' → ⨁ i, ℳ i) :
119+
(decompose ℳ).symm (∑ i in s, f i) = ∑ i in s, (decompose ℳ).symm (f i) :=
120+
map_sum (decompose_add_equiv ℳ).symm f s
121+
122+
lemma sum_support_decompose [Π i (x : ℳ i), decidable (x ≠ 0)] (r : M) :
123+
∑ i in (decompose ℳ r).support, (decompose ℳ r i : M) = r :=
124+
begin
125+
conv_rhs { rw [←(decompose ℳ).symm_apply_apply r,
126+
←sum_support_of (λ i, (ℳ i)) (decompose ℳ r)] },
127+
rw [decompose_symm_sum],
128+
simp_rw decompose_symm_of,
129+
end
130+
131+
end add_comm_monoid
132+
133+
/-- The `-` in the statements below doesn't resolve without this line.
134+
135+
This seems to a be a problem of synthesized vs inferred typeclasses disagreeing. If we replace
136+
the statement of `decompose_neg` with `@eq (⨁ i, ℳ i) (decompose ℳ (-x)) (-decompose ℳ x)`
137+
instead of `decompose ℳ (-x) = -decompose ℳ x`, which forces the typeclasses needed by `⨁ i, ℳ i` to
138+
be found by unification rather than synthesis, then everything works fine without this instance. -/
139+
instance add_comm_group_set_like [add_comm_group M] [set_like σ M] [add_subgroup_class σ M]
140+
(ℳ : ι → σ) : add_comm_group (⨁ i, ℳ i) := by apply_instance
141+
142+
section add_comm_group
143+
variables [decidable_eq ι] [add_comm_group M]
144+
variables [set_like σ M] [add_subgroup_class σ M] (ℳ : ι → σ)
145+
variables [decomposition ℳ]
146+
include M
147+
148+
@[simp] lemma decompose_neg (x : M) : decompose ℳ (-x) = -decompose ℳ x :=
149+
map_neg (decompose_add_equiv ℳ) x
150+
@[simp] lemma decompose_symm_neg (x : ⨁ i, ℳ i) :
151+
(decompose ℳ).symm (-x) = -(decompose ℳ).symm x :=
152+
map_neg (decompose_add_equiv ℳ).symm x
153+
154+
@[simp] lemma decompose_sub (x y : M) : decompose ℳ (x - y) = decompose ℳ x - decompose ℳ y :=
155+
map_sub (decompose_add_equiv ℳ) x y
156+
@[simp] lemma decompose_symm_sub (x y : ⨁ i, ℳ i) :
157+
(decompose ℳ).symm (x - y) = (decompose ℳ).symm x - (decompose ℳ).symm y :=
158+
map_sub (decompose_add_equiv ℳ).symm x y
159+
160+
end add_comm_group
161+
162+
section module
163+
variables [decidable_eq ι] [semiring R] [add_comm_monoid M] [module R M]
164+
variables (ℳ : ι → submodule R M)
165+
variables [decomposition ℳ]
166+
include M
167+
168+
/-- If `M` is graded by `ι` with degree `i` component `ℳ i`, then it is isomorphic as
169+
a module to a direct sum of components. -/
170+
@[simps {fully_applied := ff}]
171+
def decompose_linear_equiv : M ≃ₗ[R] ⨁ i, ℳ i := linear_equiv.symm
172+
{ map_smul' := map_smul (direct_sum.coe_linear_map ℳ),
173+
..(decompose_add_equiv ℳ).symm }
174+
175+
@[simp] lemma decompose_smul (r : R) (x : M) : decompose ℳ (r • x) = r • decompose ℳ x :=
176+
map_smul (decompose_linear_equiv ℳ) r x
177+
178+
end module
179+
180+
end direct_sum

src/algebra/monoid_algebra/grading.lean

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ by apply grade_by.graded_monoid (add_monoid_hom.id _)
113113
variables {R} [add_monoid M] [decidable_eq ι] [add_monoid ι] [comm_semiring R] (f : M →+ ι)
114114

115115
/-- Auxiliary definition; the canonical grade decomposition, used to provide
116-
`graded_algebra.decompose`. -/
116+
`direct_sum.decompose`. -/
117117
def decompose_aux : add_monoid_algebra R M →ₐ[R] ⨁ i : ι, grade_by R f i :=
118118
add_monoid_algebra.lift R M _
119119
{ to_fun := λ m, direct_sum.of (λ i : ι, grade_by R f i) (f m.to_add)
@@ -182,31 +182,39 @@ graded_algebra.of_alg_hom _
182182
end)
183183
(λ i x, by convert (decompose_aux_coe f x : _))
184184

185+
-- Lean can't find this later without us repeating it
186+
instance grade_by.decomposition : direct_sum.decomposition (grade_by R f) :=
187+
by apply_instance
188+
185189
@[simp] lemma decompose_aux_eq_decompose :
186190
⇑(decompose_aux f : add_monoid_algebra R M →ₐ[R] ⨁ i : ι, grade_by R f i) =
187-
(graded_algebra.decompose (grade_by R f)) := rfl
191+
(direct_sum.decompose (grade_by R f)) := rfl
188192

189193
@[simp] lemma grades_by.decompose_single (m : M) (r : R) :
190-
graded_algebra.decompose (grade_by R f) (finsupp.single m r) =
194+
direct_sum.decompose (grade_by R f) (finsupp.single m r) =
191195
direct_sum.of (λ i : ι, grade_by R f i) (f m)
192196
⟨finsupp.single m r, single_mem_grade_by _ _ _⟩ :=
193197
decompose_aux_single _ _ _
194198

195199
instance grade.graded_algebra : graded_algebra (grade R : ι → submodule _ _) :=
196200
add_monoid_algebra.grade_by.graded_algebra (add_monoid_hom.id _)
197201

202+
-- Lean can't find this later without us repeating it
203+
instance grade.decomposition : direct_sum.decomposition (grade R : ι → submodule _ _) :=
204+
by apply_instance
205+
198206
@[simp]
199207
lemma grade.decompose_single (i : ι) (r : R) :
200-
graded_algebra.decompose (grade R : ι → submodule _ _) (finsupp.single i r) =
208+
direct_sum.decompose (grade R : ι → submodule _ _) (finsupp.single i r) =
201209
direct_sum.of (λ i : ι, grade R i) i ⟨finsupp.single i r, single_mem_grade _ _⟩ :=
202210
decompose_aux_single _ _ _
203211

204212
/-- `add_monoid_algebra.gradesby` describe an internally graded algebra -/
205213
lemma grade_by.is_internal : direct_sum.is_internal (grade_by R f) :=
206-
graded_algebra.is_internal _
214+
direct_sum.decomposition.is_internal _
207215

208216
/-- `add_monoid_algebra.grades` describe an internally graded algebra -/
209217
lemma grade.is_internal : direct_sum.is_internal (grade R : ι → submodule R _) :=
210-
graded_algebra.is_internal _
218+
direct_sum.decomposition.is_internal _
211219

212220
end add_monoid_algebra

src/algebraic_geometry/projective_spectrum/topology.lean

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -392,8 +392,8 @@ topological_space.opens.ext $ set.ext $ λ z, begin
392392
split; intros hz,
393393
{ rcases show ∃ i, graded_algebra.proj 𝒜 i f ∉ z.as_homogeneous_ideal, begin
394394
contrapose! hz with H,
395-
haveI : Π (i : ℕ) (x : 𝒜 i), decidable (x ≠ 0) := λ _, classical.dec_pred _,
396-
rw ←graded_algebra.sum_support_decompose 𝒜 f,
395+
classical,
396+
rw ←direct_sum.sum_support_decompose 𝒜 f,
397397
apply ideal.sum_mem _ (λ i hi, H i)
398398
end with ⟨i, hi⟩,
399399
exact ⟨basic_open 𝒜 (graded_algebra.proj 𝒜 i f), ⟨i, rfl⟩, by rwa mem_basic_open⟩ },

0 commit comments

Comments
 (0)