Skip to content

Commit 7b31b50

Browse files
committed
feat(RingTheory/HopfAlgebra): delta operators and Rota's classification
Formalize the fundamental theorem of the umbral calculus: the basic sequence of any delta operator is a sequence of binomial type. New definitions: - `Polynomial.IsBinomialType`: binomial convolution for the coalgebra comultiplication - `Polynomial.IsShiftEquivariant`: commutes with Taylor shift - `Polynomial.IsDeltaOperator`: shift-equivariant, kills constants, unit leading term - `Polynomial.forwardDiff`: forward difference operator - `Polynomial.IsBasicSequence`: basic sequence of a delta operator Main results: - `Polynomial.X_pow_isBinomialType`: monomials are of binomial type - `Polynomial.descPochhammer_isBinomialType`: Vandermonde's identity - `Polynomial.IsBasicSequence.isBinomialType`: Rota's classification
1 parent 1980b82 commit 7b31b50

2 files changed

Lines changed: 1119 additions & 0 deletions

File tree

Lines changed: 277 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,277 @@
1+
/-
2+
Copyright (c) 2025 Robin Langer. All rights reserved.
3+
Released under Apache 2.0 license as described in the file LICENSE.
4+
Authors: Robin Langer
5+
-/
6+
module
7+
8+
public import Mathlib.RingTheory.HopfAlgebra.Polynomial
9+
public import Mathlib.Data.Nat.Choose.Sum
10+
public import Mathlib.RingTheory.Polynomial.Pochhammer
11+
public import Mathlib.RingTheory.Coalgebra.Hom
12+
13+
/-!
14+
# Sequences of binomial type
15+
16+
A sequence `p : ℕ → R[X]` is of **binomial type** if the coalgebra comultiplication
17+
satisfies the binomial convolution formula:
18+
19+
`Δ(pₙ) = Σ_{k=0}^{n} C(n,k) • (pₖ ⊗ pₙ₋ₖ)`
20+
21+
This definition captures polynomials whose behaviour under `x ↦ x + x'` factors through
22+
binomial coefficients. The canonical examples are:
23+
* the monomials `X ^ n` (the classical binomial theorem)
24+
* the falling factorials `(x)_n = x(x-1)⋯(x-n+1)` (Vandermonde's identity)
25+
26+
## Main definitions
27+
28+
* `Polynomial.IsBinomialType`: predicate for a sequence satisfying the binomial convolution.
29+
30+
## Main results
31+
32+
* `Polynomial.X_pow_isBinomialType`: the monomial sequence is of binomial type.
33+
* `Polynomial.descPochhammer_isBinomialType`: the falling factorial sequence is of binomial
34+
type (Vandermonde's identity).
35+
36+
## References
37+
38+
* Langer, R., *Macdonald Polynomials and Symmetric Functions*, arXiv:0907.3950, §1.2.2
39+
* Roman, S., *The Umbral Calculus*, Academic Press, 1984
40+
-/
41+
42+
public section
43+
44+
noncomputable section
45+
46+
open Polynomial TensorProduct Finset
47+
48+
open scoped TensorProduct
49+
50+
namespace Polynomial
51+
52+
variable (R : Type*) [CommSemiring R]
53+
54+
/-- A sequence `p : ℕ → R[X]` is of **binomial type** if
55+
`Δ(pₙ) = Σ_{k=0}^{n} C(n,k) • (pₖ ⊗ pₙ₋ₖ)` where `Δ` is the additive group scheme
56+
comultiplication on `R[X]`. -/
57+
abbrev IsBinomialType (p : ℕ → R[X]) : Prop :=
58+
∀ n, CoalgebraStruct.comul (p n) =
59+
(Finset.range (n + 1)).sum fun k =>
60+
(Nat.choose n k) • ((p k) ⊗ₜ[R] (p (n - k)))
61+
62+
/-- The monomial sequence `n ↦ X ^ n` is of binomial type.
63+
This is the binomial theorem `(x + x')ⁿ = Σ C(n,k) xᵏ x'^{n-k}` expressed
64+
coalgebraically. -/
65+
theorem X_pow_isBinomialType : IsBinomialType R (fun n => (X : R[X]) ^ n) := by
66+
unfold IsBinomialType
67+
intro n
68+
-- Δ(X^n) = Δ(X)^n = (X⊗1 + 1⊗X)^n (Δ is an algebra hom)
69+
change comulAdditiveAlgHom R (X ^ n) = _
70+
rw [map_pow, comulAdditiveAlgHom_X]
71+
-- X⊗1 commutes with 1⊗X in the tensor product algebra
72+
have hc : Commute ((X : R[X]) ⊗ₜ[R] (1 : R[X])) ((1 : R[X]) ⊗ₜ[R] (X : R[X])) :=
73+
(Commute.one_right X).tmul (Commute.one_left X)
74+
rw [hc.add_pow]
75+
apply Finset.sum_congr rfl
76+
intro k _
77+
simp only [Algebra.TensorProduct.tmul_pow, one_pow, mul_one, one_mul,
78+
Algebra.TensorProduct.tmul_mul_tmul]
79+
rw [mul_comm, ← nsmul_eq_mul]
80+
81+
/-! ### Basic properties of binomial type sequences -/
82+
83+
/-- The zeroth term of a binomial type sequence is group-like:
84+
`Δ(p₀) = p₀ ⊗ p₀`. This says `p₀` is an idempotent under comultiplication. -/
85+
theorem IsBinomialType.comul_zero {p : ℕ → R[X]} (hp : IsBinomialType R p) :
86+
CoalgebraStruct.comul (p 0) = p 0 ⊗ₜ[R] p 0 := by
87+
suffices CoalgebraStruct.comul (p 0) =
88+
(Finset.range 1).sum fun k => (Nat.choose 0 k) • (p k ⊗ₜ[R] p (0 - k)) from by
89+
simpa using this
90+
exact hp 0
91+
92+
/-! ### Coalgebra endomorphisms preserve binomial type
93+
94+
The key structural theorem connecting coalgebra morphisms to binomial type sequences:
95+
if `φ` is a coalgebra endomorphism of `R[X]` and `{pₙ}` is binomial type, then
96+
`{φ(pₙ)}` is binomial type. This is the abstract engine behind umbral operators. -/
97+
98+
/-- Coalgebra endomorphisms preserve binomial type sequences. If `φ : R[X] →ₗc[R] R[X]`
99+
and `{pₙ}` is binomial type, then `{φ(pₙ)}` is binomial type. -/
100+
theorem IsBinomialType.comp_coalgebraHom {p : ℕ → R[X]} (hp : IsBinomialType R p)
101+
(φ : R[X] →ₗc[R] R[X]) :
102+
IsBinomialType R (fun n => φ (p n)) := by
103+
suffices ∀ n, CoalgebraStruct.comul (φ.toLinearMap (p n)) =
104+
(Finset.range (n + 1)).sum fun k =>
105+
(Nat.choose n k) • (φ.toLinearMap (p k) ⊗ₜ[R] φ.toLinearMap (p (n - k))) from this
106+
intro n
107+
have key := (LinearMap.congr_fun φ.map_comp_comul (p n)).symm
108+
simp only [LinearMap.comp_apply] at key
109+
rw [key, hp n, map_sum]
110+
apply Finset.sum_congr rfl
111+
intro k _
112+
rw [map_nsmul, TensorProduct.map_tmul]
113+
114+
/-- For any coalgebra endomorphism `φ`, the sequence `n ↦ φ(Xⁿ)` is binomial type. -/
115+
theorem IsBinomialType.of_coalgebraHom (φ : R[X] →ₗc[R] R[X]) :
116+
IsBinomialType R (fun n => φ ((X : R[X]) ^ n)) := by
117+
suffices ∀ n, CoalgebraStruct.comul (φ.toLinearMap (X ^ n)) =
118+
(Finset.range (n + 1)).sum fun k =>
119+
(Nat.choose n k) • (φ.toLinearMap ((X : R[X]) ^ k) ⊗ₜ[R]
120+
φ.toLinearMap ((X : R[X]) ^ (n - k))) from this
121+
intro n
122+
have key := (LinearMap.congr_fun φ.map_comp_comul (X ^ n)).symm
123+
simp only [LinearMap.comp_apply] at key
124+
rw [key, (X_pow_isBinomialType R) n, map_sum]
125+
apply Finset.sum_congr rfl
126+
intro k _
127+
rw [map_nsmul, TensorProduct.map_tmul]
128+
129+
end Polynomial
130+
131+
end
132+
133+
/-! ### Falling factorials (CommRing required) -/
134+
135+
public section
136+
137+
noncomputable section
138+
139+
open Polynomial TensorProduct Finset
140+
141+
open scoped TensorProduct
142+
143+
namespace Polynomial
144+
145+
variable (R : Type*) [CommRing R]
146+
147+
/-- The comultiplication of `X - ↑n` in the `𝔾ₐ` coalgebra on `R[X]`. -/
148+
private theorem comul_X_sub_natCast (n : ℕ) :
149+
CoalgebraStruct.comul ((X : R[X]) - (↑n : R[X])) =
150+
((X : R[X]) - (↑n : R[X])) ⊗ₜ[R] 1 + 1 ⊗ₜ[R] (X : R[X]) := by
151+
change comulAdditiveAlgHom R ((X : R[X]) - (↑n : R[X])) = _
152+
have hnat : (↑n : R[X]) = C (↑n : R) := by simp
153+
rw [hnat, map_sub, comulAdditiveAlgHom_X, comulAdditiveAlgHom_C, ← hnat, sub_tmul]
154+
abel
155+
156+
/-- Recurrence: `p_k * (X - ↑n) = p_{k+1} + (↑k - ↑n) * p_k`. -/
157+
private theorem descPochhammer_mul_X_sub (k n : ℕ) :
158+
descPochhammer R k * ((X : R[X]) - (↑n : R[X])) =
159+
descPochhammer R (k + 1) + ((↑k : R[X]) - (↑n : R[X])) * descPochhammer R k := by
160+
have h : (X : R[X]) - (↑n : R[X]) =
161+
(X - (↑k : R[X])) + ((↑k : R[X]) - (↑n : R[X])) := by ring
162+
rw [h, mul_add, ← descPochhammer_succ_right]
163+
ring
164+
165+
/-- Recurrence: `p_m * X = p_{m+1} + ↑m * p_m`. -/
166+
private theorem descPochhammer_mul_X (m : ℕ) :
167+
descPochhammer R m * (X : R[X]) =
168+
descPochhammer R (m + 1) + (↑m : R[X]) * descPochhammer R m := by
169+
have h : (X : R[X]) = (X - (↑m : R[X])) + (↑m : R[X]) := by ring
170+
rw [h, mul_add, ← descPochhammer_succ_right]
171+
ring
172+
173+
/-- Key summand identity: for x ≤ n, distributing `Δ(X - ↑n)` over a binomial-type
174+
summand and applying the descPochhammer recurrence on both tensor factors
175+
produces a clean pair of successor terms.
176+
177+
The cross-terms `(↑x - ↑n) * p_x ⊗ p_{n-x}` and `p_x ⊗ ↑(n-x) * p_{n-x}` cancel
178+
because constant polynomials are R-scalars that move freely in `R[X] ⊗[R] R[X]`,
179+
and `(↑x - ↑n) + ↑(n - x) = 0` in R when `x ≤ n`. -/
180+
private theorem summand_identity (x n : ℕ) (hx : x ≤ n) :
181+
(descPochhammer R x * ((X : R[X]) - (↑n : R[X]))) ⊗ₜ[R]
182+
descPochhammer R (n - x) +
183+
descPochhammer R x ⊗ₜ[R]
184+
(descPochhammer R (n - x) * (X : R[X])) =
185+
descPochhammer R (x + 1) ⊗ₜ[R] descPochhammer R (n - x) +
186+
descPochhammer R x ⊗ₜ[R] descPochhammer R (n + 1 - x) := by
187+
rw [descPochhammer_mul_X_sub R, descPochhammer_mul_X R]
188+
rw [add_tmul, tmul_add]
189+
have hC : ∀ (m : ℕ), (↑m : R[X]) = C (↑m : R) := by intro m; simp
190+
have hnat_l : ((↑x : R[X]) - (↑n : R[X])) * descPochhammer R x =
191+
((↑x : R) - (↑n : R)) • descPochhammer R x := by
192+
rw [hC x, hC n, ← map_sub, ← smul_eq_C_mul]
193+
have hnat_r : (↑(n - x) : R[X]) * descPochhammer R (n - x) =
194+
(↑(n - x) : R) • descPochhammer R (n - x) := by
195+
rw [hC (n - x), ← smul_eq_C_mul]
196+
rw [hnat_l, hnat_r, TensorProduct.smul_tmul]
197+
have h0 :
198+
descPochhammer R x ⊗ₜ[R]
199+
((↑x - ↑n : R) • descPochhammer R (n - x)) +
200+
descPochhammer R x ⊗ₜ[R]
201+
((↑(n - x) : R) • descPochhammer R (n - x)) = 0 := by
202+
rw [← tmul_add, ← add_smul]
203+
have : (↑x : R) - (↑n : R) + (↑(n - x) : R) = 0 := by
204+
rw [Nat.cast_sub hx]; ring
205+
rw [this, zero_smul, tmul_zero]
206+
have hB := eq_neg_of_add_eq_zero_left h0
207+
have hn : n - x + 1 = n + 1 - x := by omega
208+
rw [hB, hn]; abel
209+
210+
/-- The falling factorial sequence `descPochhammer R` is of binomial type.
211+
This is Vandermonde's identity `(x+y)_n = Σ C(n,k) (x)_k (y)_{n-k}`
212+
expressed coalgebraically. -/
213+
theorem descPochhammer_isBinomialType :
214+
IsBinomialType R (fun n => descPochhammer R n) := by
215+
unfold IsBinomialType
216+
intro n
217+
induction n with
218+
| zero =>
219+
simp [descPochhammer_zero, Bialgebra.comul_one,
220+
Algebra.TensorProduct.one_def]
221+
| succ n ih =>
222+
dsimp only at ih ⊢
223+
rw [descPochhammer_succ_right, Bialgebra.comul_mul, ih,
224+
comul_X_sub_natCast R n]
225+
rw [Finset.sum_mul]
226+
simp_rw [smul_mul_assoc, mul_add,
227+
Algebra.TensorProduct.tmul_mul_tmul]
228+
simp only [mul_one]
229+
have h_summand := Finset.sum_congr rfl
230+
(fun x (hx : x ∈ range (n + 1)) => by
231+
have hle : x ≤ n :=
232+
Nat.lt_succ_iff.mp (Finset.mem_range.mp hx)
233+
change n.choose x •
234+
((descPochhammer R x * ((X : R[X]) - ↑n)) ⊗ₜ[R]
235+
descPochhammer R (n - x) +
236+
descPochhammer R x ⊗ₜ[R]
237+
(descPochhammer R (n - x) * X)) =
238+
n.choose x •
239+
(descPochhammer R (x + 1) ⊗ₜ[R]
240+
descPochhammer R (n - x) +
241+
descPochhammer R x ⊗ₜ[R]
242+
descPochhammer R (n + 1 - x))
243+
congr 1
244+
exact summand_identity R x n hle)
245+
rw [h_summand]
246+
have h_split2 : ∀ x, n.choose x •
247+
(descPochhammer R (x + 1) ⊗ₜ[R]
248+
descPochhammer R (n - x) +
249+
descPochhammer R x ⊗ₜ[R]
250+
descPochhammer R (n + 1 - x)) =
251+
n.choose x •
252+
(descPochhammer R (x + 1) ⊗ₜ[R]
253+
descPochhammer R (n - x)) +
254+
n.choose x •
255+
(descPochhammer R x ⊗ₜ[R]
256+
descPochhammer R (n + 1 - x)) :=
257+
fun x => smul_add _ _ _
258+
simp only [h_split2, Finset.sum_add_distrib]
259+
symm
260+
rw [Finset.sum_range_succ']
261+
simp only [Nat.choose_zero_right, one_smul,
262+
Nat.succ_sub_succ_eq_sub]
263+
simp_rw [Nat.choose_succ_succ', add_smul]
264+
rw [Finset.sum_add_distrib]
265+
rw [add_assoc]
266+
congr 1
267+
rw [Finset.sum_range_succ,
268+
show Nat.choose n (n + 1) = 0 from
269+
Nat.choose_eq_zero_of_lt (by omega),
270+
zero_smul, add_zero]
271+
conv_rhs => rw [Finset.sum_range_succ']
272+
simp only [Nat.choose_zero_right, one_smul,
273+
Nat.succ_sub_succ_eq_sub]
274+
275+
end Polynomial
276+
277+
end

0 commit comments

Comments
 (0)