Skip to content

Commit 019f853

Browse files
committed
feat(RingTheory/PowerSeries/Derivative): more lemmas (leanprover-community#34616)
Four lemmas leading to the chain rule for power series.
1 parent 2c51483 commit 019f853

2 files changed

Lines changed: 51 additions & 13 deletions

File tree

Mathlib/RingTheory/PowerSeries/Derivative.lean

Lines changed: 41 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,10 @@ Authors: Richard M. Hill
55
-/
66
module
77

8-
public import Mathlib.RingTheory.PowerSeries.Trunc
9-
public import Mathlib.RingTheory.PowerSeries.Inverse
8+
public import Mathlib.Algebra.Polynomial.Derivation
109
public import Mathlib.RingTheory.Derivation.Basic
10+
public import Mathlib.RingTheory.PowerSeries.Inverse
11+
public import Mathlib.RingTheory.PowerSeries.Substitution
1112

1213
/-!
1314
# Definitions
@@ -117,24 +118,16 @@ theorem coeff_derivative (f : R⟦X⟧) (n : ℕ) :
117118
theorem derivative_coe (f : R[X]) : d⁄dX R f = Polynomial.derivative f := derivativeFun_coe f
118119

119120
@[simp] theorem derivative_X : d⁄dX R (X : R⟦X⟧) = 1 := by
120-
ext
121-
rw [coeff_derivative, coeff_one, coeff_X, boole_mul]
122-
simp_rw [add_eq_right]
123-
split_ifs with h
124-
· rw [h, cast_zero, zero_add]
125-
· rfl
121+
ext n; simp only [coeff_derivative, coeff_one, coeff_X, boole_mul, add_eq_right]
122+
split_ifs <;> simp_all
126123

127124
theorem trunc_derivative (f : R⟦X⟧) (n : ℕ) :
128125
trunc n (d⁄dX R f) = Polynomial.derivative (trunc (n + 1) f) :=
129126
trunc_derivativeFun ..
130127

131128
theorem trunc_derivative' (f : R⟦X⟧) (n : ℕ) :
132129
trunc (n - 1) (d⁄dX R f) = Polynomial.derivative (trunc n f) := by
133-
cases n with
134-
| zero =>
135-
simp
136-
| succ n =>
137-
rw [succ_sub_one, trunc_derivative]
130+
cases n <;> simp [trunc_derivative]
138131

139132
end CommutativeSemiring
140133

@@ -175,4 +168,39 @@ there is currently no instance of `Inv R⟦X⟧` for more general base rings `R`
175168
apply Derivation.leibniz_of_mul_eq_one
176169
exact PowerSeries.inv_mul_cancel (h := h)
177170

171+
variable (A : Type*) [CommRing A]
172+
173+
/-- The derivative of g^n equals n * g^(n-1) * g'. -/
174+
theorem derivative_pow (g : A⟦X⟧) (n : ℕ) :
175+
d⁄dX A (g ^ n) = n * g ^ (n - 1) * d⁄dX A g := by
176+
induction n with
177+
| zero => simp
178+
| succ n ih =>
179+
simp only [pow_succ, (derivative A).leibniz, ih, smul_eq_mul, add_tsub_cancel_right]
180+
rcases n with _ | m
181+
· simp
182+
· simp only [add_tsub_cancel_right, pow_succ]; push_cast; ring
183+
184+
/-- Chain rule for polynomials viewed as power series. Use `derivative_subst` instead. -/
185+
private theorem derivative_subst_coe (p : Polynomial A) {g : A⟦X⟧} (hg : HasSubst g) :
186+
d⁄dX A ((p : A⟦X⟧).subst g) = (d⁄dX A (p : A⟦X⟧)).subst g * d⁄dX A g := by
187+
simp [subst_coe hg, derivative_coe, Derivation.comp_aeval_eq (a := g) (derivative A) p,
188+
smul_eq_mul]
189+
190+
theorem derivative_subst {f g : A⟦X⟧} (hg : HasSubst g) :
191+
d⁄dX A (f.subst g) = (d⁄dX A f).subst g * d⁄dX A g := by
192+
ext n
193+
obtain ⟨m, hm⟩ := (hg.eventually_coeff_pow_eq_zero (n + 1)).exists_forall_of_atTop
194+
have : coeff (n + 1) (f.subst g) = coeff (n + 1) ((↑(trunc (m + 1) f) : A⟦X⟧).subst g) := by
195+
rw [coeff_subst' hg, coeff_subst' hg]
196+
refine finsum_congr fun d ↦ ?_
197+
obtain hd | hd := lt_or_ge d m
198+
· rw [coeff_coe_trunc_of_lt (by lia)]
199+
· simp [coeff_trunc, hd, hm]
200+
rw [coeff_derivative, this, ← coeff_derivative, derivative_subst_coe A _ hg, coeff_mul, coeff_mul]
201+
refine Finset.sum_congr rfl fun ⟨i, j⟩ hij ↦ ?_
202+
congr 1
203+
simp only [coeff_subst' hg, coeff_derivative, coeff_coe, coeff_trunc]
204+
exact finsum_congr fun d ↦ by split_ifs <;> simp (disch := grind [Finset.mem_antidiagonal]) [hm]
205+
178206
end PowerSeries

Mathlib/RingTheory/PowerSeries/Substitution.lean

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,16 @@ theorem HasSubst.smul_X (a : A) (t : τ) :
140140
theorem HasSubst.smul_X' (a : A) : HasSubst (a • X : R⟦X⟧) :=
141141
HasSubst.X'.smul' _
142142

143+
lemma HasSubst.eventually_coeff_pow_eq_zero {f : A⟦X⟧} (hf : HasSubst f) (n : ℕ) :
144+
∀ᶠ m in .atTop, ∀ n' ≤ n, coeff n' (f ^ m) = 0 := by
145+
obtain ⟨k, hk⟩ := id hf
146+
refine Filter.eventually_of_mem (Filter.Ici_mem_atTop (k * (n + 1))) fun m hm n' hn' ↦
147+
coeff_of_lt_order _ ?_
148+
obtain ⟨m, rfl⟩ := le_iff_exists_add.mp (Set.mem_Ici.mp hm)
149+
grw [pow_add, ← order_mul_ge, pow_mul, ← le_order_pow_of_constantCoeff_eq_zero _
150+
(by rwa [map_pow]), ← _root_.le_add_right le_rfl, Nat.cast_lt]
151+
lia
152+
143153
variable {υ : Type*} {T : Type*} [CommRing T] [Algebra R S] [Algebra R T] [Algebra S T]
144154

145155
/-- Substitution of power series into a power series. -/

0 commit comments

Comments
 (0)