|
| 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