Skip to content

Commit 5308bb7

Browse files
committed
feat(RingTheory/DividedPowerAlgebra/Init): add universal divided power algebra (leanprover-community#35804)
We define the universal divided power algebra of an `R`-module `M`. Co-authored by @AntoineChambert-Loir Co-authored-by: mariainesdff <mariaines.dff@gmail.com>
1 parent 05af26b commit 5308bb7

2 files changed

Lines changed: 266 additions & 0 deletions

File tree

Mathlib.lean

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6252,6 +6252,7 @@ public import Mathlib.RingTheory.Derivation.ToSquareZero
62526252
public import Mathlib.RingTheory.DiscreteValuationRing.Basic
62536253
public import Mathlib.RingTheory.DiscreteValuationRing.TFAE
62546254
public import Mathlib.RingTheory.Discriminant
6255+
public import Mathlib.RingTheory.DividedPowerAlgebra.Init
62556256
public import Mathlib.RingTheory.DividedPowers.Basic
62566257
public import Mathlib.RingTheory.DividedPowers.DPMorphism
62576258
public import Mathlib.RingTheory.DividedPowers.Padic
Lines changed: 265 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,265 @@
1+
/-
2+
Copyright (c) 2026 Antoine Chambert-Loir & María Inés de Frutos—Fernández. All rights reserved.
3+
Released under Apache 2.0 license as described in the file LICENSE.
4+
Authors: Antoine Chambert-Loir, María Inés de Frutos—Fernández
5+
-/
6+
module
7+
8+
public import Mathlib.Algebra.RingQuot
9+
public import Mathlib.RingTheory.DividedPowers.Basic
10+
11+
/-!
12+
# The universal divided power algebra
13+
14+
Let `R` be a ring and `M` be an `R`-module. In this file we define `Γ_R(M)`, the universal
15+
divided power algebra of `M`, as the ring quotient of the polynomial ring in the variables `ℕ × M`
16+
by the relation `DividedPowerAlgebra.Rel`.
17+
18+
`DividedPowerAlgebra R M` satisfies a weak universal property for morphisms to rings with
19+
divided_powers.
20+
21+
## Main definitions
22+
23+
* `DividedPowerAlgebra.Rel`: the type coding the basic relations that will give rise to the
24+
divided power algebra. The class of `X (n, a)` will be equal to `dpow n a`, for `a ∈ M`.
25+
26+
* `DividedPowerAlgebra R M`: the universal divided power algebra of the `R`-module `M`.
27+
28+
* `DividedPowerAlgebra.dp R n m`: the equivalence class of `X (⟨n, m⟩)` in
29+
`DividedPowerAlgebra R M`.
30+
31+
## TODO
32+
33+
* Add the weak universal property of `DividedPowerAlgebra R M`.
34+
* Show in upcoming files that `DividedPowerAlgebra R M` has divided powers.
35+
36+
-/
37+
38+
@[expose] public section
39+
noncomputable section
40+
41+
open Finset Ideal MvPolynomial RingQuot
42+
43+
variable (R M : Type*) [CommSemiring R] [AddCommMonoid M] [Module R M]
44+
45+
namespace DividedPowerAlgebra
46+
47+
/-- The type coding the basic relations that will give rise to the divided power algebra.
48+
The class of `X (n, a)` will be equal to `dpow n a`, for `a ∈ M`. -/
49+
inductive Rel : (MvPolynomial (ℕ × M) R) → (MvPolynomial (ℕ × M) R) → Prop
50+
| rfl_zero : Rel 0 0 -- Needed for technical reasons.
51+
| zero {a : M} : Rel (X (0, a)) 1
52+
| smul {r : R} {n : ℕ} {a : M} : Rel (X (n, r • a)) (r ^ n • X (n, a))
53+
| mul {m n : ℕ} {a : M} : Rel (X (m, a) * X (n, a)) (Nat.choose (m + n) m • X (m + n, a))
54+
| add {n : ℕ} {a b : M} :
55+
Rel (X (n, a + b)) ((Finset.antidiagonal n).sum fun k => X (k.1, a) * X (k.2, b))
56+
57+
/-- The ideal of `MvPolynomial (ℕ × M) R` generated by `Rel`. -/
58+
def RelI : Ideal (MvPolynomial (ℕ × M) R) := ofRel (DividedPowerAlgebra.Rel R M)
59+
60+
end DividedPowerAlgebra
61+
62+
/-- The divided power algebra of a module M is defined as the ring quotient of the polynomial ring
63+
in the variables `ℕ × M` by the ring relation defined by `DividedPowerAlgebra.Rel`.
64+
We will later show that that `DividedPowerAlgebra R M` has divided powers.
65+
It satisfies a weak universal property for morphisms to rings with divided_powers. -/
66+
abbrev DividedPowerAlgebra := RingQuot (DividedPowerAlgebra.Rel R M)
67+
68+
namespace DividedPowerAlgebra
69+
70+
open MvPolynomial
71+
72+
variable {R M}
73+
74+
lemma mkAlgHom_surjective : Function.Surjective (mkAlgHom R (Rel R M)) :=
75+
RingQuot.mkAlgHom_surjective _ _
76+
77+
lemma mkAlgHom_C (a : R) :
78+
mkAlgHom R (Rel R M) (C a) = algebraMap R (DividedPowerAlgebra R M) a := by
79+
rw [← MvPolynomial.algebraMap_eq, AlgHom.commutes]
80+
81+
lemma mkRingHom_C (a : R) :
82+
mkRingHom (Rel R M) (C a) = algebraMap R (DividedPowerAlgebra R M) a := by
83+
rw [← mkAlgHom_C, mkAlgHom, AlgHom.coe_mk]
84+
85+
variable (R)
86+
87+
/-- `dp R n m` is the equivalence class of `X (⟨n, m⟩)` in `DividedPowerAlgebra R M`. -/
88+
def dp (n : ℕ) (m : M) : DividedPowerAlgebra R M := mkAlgHom R (Rel R M) (X ⟨n, m⟩)
89+
90+
theorem dp_def (n : ℕ) (m : M) :
91+
dp R n m = mkAlgHom R (Rel R M) (X ⟨n, m⟩) := rfl
92+
93+
protected theorem induction_on' {P : DividedPowerAlgebra R M → Prop} (f : DividedPowerAlgebra R M)
94+
(h_C : ∀ a, P (mkAlgHom R (Rel R M) (C a))) (h_add : ∀ f g, P f → P g → P (f + g))
95+
(h_dp : ∀ (f : DividedPowerAlgebra R M) (n : ℕ) (m : M), P f → P (f * dp R n m)) : P f := by
96+
obtain ⟨F, hf⟩ := RingQuot.mkRingHom_surjective (DividedPowerAlgebra.Rel R M) f
97+
rw [← hf]
98+
induction F using MvPolynomial.induction_on generalizing f with
99+
| C a =>
100+
convert h_C a using 1
101+
rw [mkAlgHom, AlgHom.coe_mk]
102+
| add g1 g2 hg1 hg2 =>
103+
rw [map_add]
104+
exact h_add _ _ (hg1 ((mkRingHom (Rel R M)) g1) rfl) (hg2 ((mkRingHom (Rel R M)) g2) rfl)
105+
| mul_X g nm h =>
106+
have h' : (mkRingHom (Rel R M)) (X nm) = dp R nm.1 nm.2 := by
107+
simp only [dp_def, Prod.mk.eta, mkAlgHom, AlgHom.coe_mk]
108+
rw [_root_.map_mul, h']
109+
exact h_dp _ _ _ (h (mkRingHom (Rel R M) g) rfl)
110+
111+
@[elab_as_elim]
112+
protected theorem induction_on {P : DividedPowerAlgebra R M → Prop} (f : DividedPowerAlgebra R M)
113+
(h_C : ∀ a, P (algebraMap R _ a)) (h_add : ∀ f g, P f → P g → P (f + g))
114+
(h_dp : ∀ (f : DividedPowerAlgebra R M) (n : ℕ) (m : M), P f → P (f * dp R n m)) : P f :=
115+
DividedPowerAlgebra.induction_on' R f (fun a => by rw [mkAlgHom_C]; exact h_C a) h_add h_dp
116+
117+
theorem dp_eq_mkRingHom (n : ℕ) (m : M) :
118+
dp R n m = mkRingHom (Rel R M) (X (⟨n, m⟩)) := by
119+
simp [dp, mkRingHom, mkAlgHom]
120+
121+
theorem dp_zero (m : M) : dp R 0 m = 1 := by
122+
rw [dp_def, ← map_one (mkAlgHom R (Rel R M))]
123+
exact RingQuot.mkAlgHom_rel R Rel.zero
124+
125+
theorem dp_smul (r : R) (n : ℕ) (m : M) : dp R n (r • m) = r ^ n • dp R n m := by
126+
rw [dp_def, dp_def, ← map_smul]
127+
exact mkAlgHom_rel R Rel.smul
128+
129+
theorem dp_null (n : ℕ) : dp R n (0 : M) = if n = 0 then 1 else 0 := by
130+
cases Nat.eq_zero_or_pos n with
131+
| inl hn =>
132+
rw [if_pos hn, hn, dp_zero]
133+
| inr hn =>
134+
rw [if_neg (ne_of_gt hn), ← zero_smul R (0 : M), dp_smul]
135+
rw [zero_pow (Nat.pos_iff_ne_zero.mp hn), zero_smul]
136+
137+
theorem dp_null_of_ne_zero {n : ℕ} (hn : n ≠ 0) : dp R n (0 : M) = 0 := by
138+
rw [dp_null R n, if_neg hn]
139+
140+
theorem dp_mul (n p : ℕ) (m : M) :
141+
dp R n m * dp R p m = (n + p).choose n • dp R (n + p) m := by
142+
simp only [dp_def, ← _root_.map_mul, ← map_nsmul]
143+
exact mkAlgHom_rel R Rel.mul
144+
145+
theorem dp_add (n : ℕ) (x y : M) :
146+
dp R n (x + y) = (antidiagonal n).sum fun k => dp R k.1 x * dp R k.2 y := by
147+
simp only [dp_def]
148+
rw [mkAlgHom_rel (A := MvPolynomial (ℕ × M) R) R Rel.add, map_sum,
149+
Finset.sum_congr rfl (fun k _ ↦ by rw [_root_.map_mul])]
150+
151+
theorem dp_sum {ι : Type*} [DecidableEq ι] (s : Finset ι) (q : ℕ) (x : ι → M) :
152+
dp R q (s.sum x) =
153+
(Finset.sym s q).sum fun k => s.prod fun i => dp R (Multiset.count i k) (x i) :=
154+
DividedPowers.dpow_sum' (I := ⊤) _ (fun {m} _ ↦ dp_zero R m)
155+
(fun {n x y} _ _ ↦ dp_add R n x y) (dp_null_of_ne_zero R) (fun _ _ ↦ trivial)
156+
157+
theorem dp_sum_smul {ι : Type*} [DecidableEq ι] (s : Finset ι) (q : ℕ) (a : ι → R) (x : ι → M) :
158+
dp R q (s.sum fun i => a i • x i) =
159+
(Finset.sym s q).sum fun k =>
160+
(s.prod fun i => a i ^ Multiset.count i k) •
161+
s.prod fun i => dp R (Multiset.count i k) (x i) := by
162+
simp_rw [dp_sum, dp_smul, Algebra.smul_def, map_prod, ← Finset.prod_mul_distrib]
163+
164+
open Nat in
165+
lemma prod_dp {ι : Type*} (s : Finset ι) {n : ι → ℕ} (m : M) :
166+
∏ i ∈ s, (dp R (n i) m) = (Nat.multinomial s n) * dp R (s.sum n) m := by
167+
classical
168+
induction s using Finset.induction with
169+
| empty =>
170+
simp only [prod_empty, multinomial_empty, cast_one, sum_empty, one_mul, dp_zero]
171+
| insert _ _ hi hrec =>
172+
rw [prod_insert hi, hrec, ← mul_assoc, mul_comm (dp R (n _) m),
173+
mul_assoc, dp_mul, ← sum_insert hi, nsmul_eq_mul, ← mul_assoc]
174+
congr 1
175+
rw [multinomial_insert hi, mul_comm, cast_mul, sum_insert hi]
176+
177+
open scoped Nat
178+
179+
theorem natFactorial_mul_dp_eq (n : ℕ) (x : M) :
180+
n ! * dp R n x = (dp R 1 x) ^ n := by
181+
induction n with
182+
| zero => simp [dp_zero]
183+
| succ n h =>
184+
rw [pow_succ, ← h, mul_assoc, dp_mul, nsmul_eq_mul, ← mul_assoc, ← Nat.cast_mul]
185+
simp [mul_comm _ (n + 1), Nat.factorial_succ]
186+
187+
variable (M) in
188+
/-- The canonical linear map `M →ₗ[R] DividedPowerAlgebra R M`. -/
189+
def embed : M →ₗ[R] DividedPowerAlgebra R M where
190+
toFun m := dp R 1 m
191+
map_add' _ _ := by simp [dp_add, Nat.antidiagonal_succ, dp_zero, add_comm]
192+
map_smul' _ _ := by simp [dp_smul, pow_one, RingHom.id_apply]
193+
194+
theorem embed_def (m : M) : embed R M m = dp R 1 m := rfl
195+
196+
variable {R}
197+
198+
theorem algHom_ext_iff {A : Type*} [CommSemiring A] [Algebra R A]
199+
{f g : DividedPowerAlgebra R M →ₐ[R] A} :
200+
(f = g) ↔ (∀ n m, f (dp R n m) = g (dp R n m)) := by
201+
refine ⟨fun h _ _ ↦ by rw [h], fun h ↦ ?_⟩
202+
rw [DFunLike.ext'_iff]
203+
apply Function.Surjective.injective_comp_right mkAlgHom_surjective
204+
simpa [← AlgHom.coe_comp] using MvPolynomial.algHom_ext fun ⟨n, m⟩ => h n m
205+
206+
@[ext]
207+
theorem algHom_ext {A : Type*} [CommSemiring A] [Algebra R A]
208+
{f g : DividedPowerAlgebra R M →ₐ[R] A}
209+
(h : ∀ n m, f (dp R n m) = g (dp R n m)) : f = g :=
210+
algHom_ext_iff.mpr h
211+
212+
section
213+
214+
open Submodule
215+
216+
variable {R M ι : Type*} [CommRing R] [AddCommGroup M] [Module R M] {v : ι → M}
217+
218+
/- If the `R`-module is spanned by elements `v i`, then `DividedPowerAlgebra R M`
219+
is linearly spanned by the finite products `∏ i, dp R (k i) (v i)`.
220+
221+
When these `v i` form a `Module.Basis`, these elements are linearly independent,
222+
hence form a `Module.Basis` of `DividedPowerAlgebra R M`, see `DividedPowers.DPAlgebra.Free`. -/
223+
theorem submodule_span_prod_dp_eq_top (hv : span R (Set.range v) = ⊤) :
224+
span R (Set.range fun (n : ι →₀ ℕ) ↦ n.prod fun i k ↦ dp R k (v i)) = ⊤ := by
225+
rw [eq_top_iff]
226+
intro p hp
227+
clear hp
228+
induction p using DividedPowerAlgebra.induction_on with
229+
| h_C r =>
230+
simp only [Algebra.algebraMap_eq_smul_one]
231+
exact smul_mem _ _ (subset_span ⟨0, by simp⟩)
232+
| h_add x y hx hy => exact Submodule.add_mem _ hx hy
233+
| h_dp x k m hx =>
234+
have hm : m ∈ span R (Set.range v) := by simp [hv, mem_top]
235+
induction hm using span_induction generalizing x k with
236+
| zero => rw [dp_null]; split_ifs <;> simp [hx]
237+
| smul r m hm h => simp [dp_smul, smul_mem _ _ (h x k hx)]
238+
| mem y hy =>
239+
obtain ⟨i, rfl⟩ := hy
240+
induction hx using span_induction with
241+
| zero => simp
242+
| mem x hx =>
243+
obtain ⟨n, rfl⟩ := hx
244+
simp only
245+
rw [← n.mul_prod_erase' i _ (fun i ↦ dp_zero R (v i)), mul_comm,
246+
← mul_assoc, dp_mul, nsmul_eq_mul, mul_assoc, ← nsmul_eq_mul]
247+
refine smul_of_tower_mem _ _ (mem_span_of_mem ⟨Finsupp.single i k + n, ?_⟩)
248+
simp only
249+
rw [← (Finsupp.single i k + n).mul_prod_erase' i _ (fun i ↦ dp_zero _ (v i))]
250+
simp
251+
| add x y hxmem hymem hx hy =>
252+
rw [add_mul]
253+
exact Submodule.add_mem _ hx hy
254+
| smul r x hxmem hx =>
255+
rw [smul_mul_assoc]
256+
exact smul_mem _ _ hx
257+
| add m n hm_mem hn_mem hm hn =>
258+
rw [dp_add, mul_sum]
259+
apply sum_mem (fun c hc ↦ ?_)
260+
rw [← mul_assoc]
261+
exact hn (x * dp R c.1 m) c.2 (hm x c.1 hx)
262+
263+
end
264+
265+
end DividedPowerAlgebra

0 commit comments

Comments
 (0)