Skip to content

Commit 583dd35

Browse files
feat (RingTheory/PowerSeries/Order) : compute order of power and generalize (#23993)
* compute order of power of power series * generalize `order_mul` * generalize lemmas at the end to `[Semiring R] [NoZeroDivisors R]` by proving (`PowerSeries.X_pow_mul_cancel`) that one can divide out by powers on `X` on both sides of an equality.
1 parent da9d909 commit 583dd35

File tree

3 files changed

+138
-68
lines changed

3 files changed

+138
-68
lines changed

Mathlib/Algebra/Order/Monoid/Unbundled/Basic.lean

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -314,6 +314,18 @@ end PartialOrder
314314
section LinearOrder
315315
variable [LinearOrder α] {a b c d : α}
316316

317+
@[to_additive]
318+
theorem trichotomy_of_mul_eq_mul
319+
[MulLeftStrictMono α] [MulRightStrictMono α]
320+
(h : a * b = c * d) : (a = c ∧ b = d) ∨ a < c ∨ b < d := by
321+
obtain hac | rfl | hca := lt_trichotomy a c
322+
· right; left; exact hac
323+
· left; simpa using mul_right_inj_of_comparable (LinearOrder.le_total d b)|>.1 h
324+
· obtain hbd | rfl | hdb := lt_trichotomy b d
325+
· right; right; exact hbd
326+
· exact False.elim <| ne_of_lt (mul_lt_mul_right' hca b) h.symm
327+
· exact False.elim <| ne_of_lt (mul_lt_mul_of_lt_of_lt hca hdb) h.symm
328+
317329
@[to_additive]
318330
lemma mul_max [CovariantClass α α (· * ·) (· ≤ ·)] (a b c : α) :
319331
a * max b c = max (a * b) (a * c) := mul_left_mono.map_max

Mathlib/RingTheory/PowerSeries/Basic.lean

Lines changed: 71 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,10 @@ and the fact that power series over a local ring form a local ring;
3434
and application to the fact that power series over an integral domain
3535
form an integral domain.
3636
37+
## Instance
38+
39+
If `R` has `NoZeroDivisors`, then so does `R⟦X⟧`.
40+
3741
## Implementation notes
3842
3943
Because of its definition,
@@ -211,6 +215,9 @@ def X : R⟦X⟧ :=
211215
theorem commute_X (φ : R⟦X⟧) : Commute φ X :=
212216
MvPowerSeries.commute_X _ _
213217

218+
theorem commute_X_pow (φ : R⟦X⟧) (n : ℕ) :
219+
Commute φ (X ^ n) := Commute.pow_right (commute_X φ) n
220+
214221
@[simp]
215222
theorem coeff_zero_eq_constantCoeff : ⇑(coeff R 0) = constantCoeff R := by
216223
rw [coeff, Finsupp.single_zero]
@@ -326,6 +333,22 @@ theorem coeff_succ_X_mul (n : ℕ) (φ : R⟦X⟧) : coeff R (n + 1) (X * φ) =
326333
convert φ.coeff_add_monomial_mul (single () 1) (single () n) _
327334
rw [one_mul]
328335

336+
theorem mul_X_cancel {φ ψ : R⟦X⟧} (h : φ * X = ψ * X) : φ = ψ := by
337+
rw [PowerSeries.ext_iff] at h ⊢
338+
intro n
339+
simpa using h (n + 1)
340+
341+
theorem mul_X_inj {φ ψ : R⟦X⟧} : φ * X = ψ * X ↔ φ = ψ :=
342+
⟨mul_X_cancel, fun h ↦ congrFun (congrArg HMul.hMul h) X⟩
343+
344+
theorem X_mul_cancel {φ ψ : R⟦X⟧} (h : X * φ = X * ψ) : φ = ψ := by
345+
rw [PowerSeries.ext_iff] at h ⊢
346+
intro n
347+
simpa using h (n + 1)
348+
349+
theorem X_mul_inj {φ ψ : R⟦X⟧} : X * φ = X * ψ ↔ φ = ψ :=
350+
⟨X_mul_cancel, fun h ↦ congrArg (HMul.hMul X) h⟩
351+
329352
@[simp]
330353
theorem constantCoeff_C (a : R) : constantCoeff R (C R a) = a :=
331354
rfl
@@ -391,6 +414,26 @@ theorem coeff_X_pow_mul (p : R⟦X⟧) (n d : ℕ) :
391414
· rw [add_comm]
392415
exact fun h1 => (h1 (mem_antidiagonal.2 rfl)).elim
393416

417+
theorem mul_X_pow_cancel {k : ℕ} {φ ψ : R⟦X⟧} (h : φ * X ^ k = ψ * X ^ k) :
418+
φ = ψ := by
419+
rw [PowerSeries.ext_iff] at h ⊢
420+
intro n
421+
simpa using h (n + k)
422+
423+
theorem mul_X_pow_inj {k : ℕ} {φ ψ : R⟦X⟧} :
424+
φ * X ^ k = ψ * X ^ k ↔ φ = ψ :=
425+
⟨mul_X_pow_cancel, fun h ↦ congrFun (congrArg HMul.hMul h) (X ^ k)⟩
426+
427+
theorem X_pow_mul_cancel {k : ℕ} {φ ψ : R⟦X⟧} (h : X ^ k * φ = X ^ k * ψ) :
428+
φ = ψ := by
429+
rw [PowerSeries.ext_iff] at h ⊢
430+
intro n
431+
simpa using h (n + k)
432+
433+
theorem X_mul_pow_inj {k : ℕ} {φ ψ : R⟦X⟧} :
434+
X ^ k * φ = X ^ k * ψ ↔ φ = ψ :=
435+
⟨X_pow_mul_cancel, fun h ↦ congrArg (HMul.hMul (X ^ k)) h⟩
436+
394437
theorem coeff_mul_X_pow' (p : R⟦X⟧) (n d : ℕ) :
395438
coeff R d (p * X ^ n) = ite (n ≤ d) (coeff R (d - n) p) 0 := by
396439
split_ifs with h
@@ -502,6 +545,32 @@ theorem X_dvd_iff {φ : R⟦X⟧} : (X : R⟦X⟧) ∣ φ ↔ constantCoeff R φ
502545
· intro m hm
503546
rwa [Nat.eq_zero_of_le_zero (Nat.le_of_succ_le_succ hm)]
504547

548+
instance [NoZeroDivisors R] : NoZeroDivisors R⟦X⟧ where
549+
eq_zero_or_eq_zero_of_mul_eq_zero {φ ψ} h := by
550+
classical
551+
rw [or_iff_not_imp_left]
552+
intro H
553+
have ex : ∃ m, coeff R m φ ≠ 0 := by
554+
contrapose! H
555+
exact ext H
556+
let m := Nat.find ex
557+
ext n
558+
rw [(coeff R n).map_zero]
559+
induction' n using Nat.strong_induction_on with n ih
560+
replace h := congr_arg (coeff R (m + n)) h
561+
rw [LinearMap.map_zero, coeff_mul, Finset.sum_eq_single (m, n)] at h
562+
· simp only [mul_eq_zero] at h
563+
exact Or.resolve_left h (Nat.find_spec ex)
564+
· rintro ⟨i, j⟩ hij hne
565+
rw [mem_antidiagonal] at hij
566+
rcases trichotomy_of_add_eq_add hij with h_eq | hi_lt | hj_lt
567+
· apply False.elim (hne ?_)
568+
simpa using h_eq
569+
· suffices coeff R i φ = 0 by rw [this, zero_mul]
570+
by_contra h; exact Nat.find_min ex hi_lt h
571+
· rw [ih j hj_lt, mul_zero]
572+
· simp
573+
505574
end Semiring
506575

507576
section CommSemiring
@@ -677,59 +746,11 @@ theorem evalNegHom_X : evalNegHom (X : A⟦X⟧) = -X :=
677746

678747
end CommRing
679748

680-
section Domain
681-
682-
variable [Ring R]
683-
684-
theorem eq_zero_or_eq_zero_of_mul_eq_zero [NoZeroDivisors R] (φ ψ : R⟦X⟧) (h : φ * ψ = 0) :
685-
φ = 0 ∨ ψ = 0 := by
686-
classical
687-
rw [or_iff_not_imp_left]
688-
intro H
689-
have ex : ∃ m, coeff R m φ ≠ 0 := by
690-
contrapose! H
691-
exact ext H
692-
let m := Nat.find ex
693-
have hm₁ : coeff R m φ ≠ 0 := Nat.find_spec ex
694-
have hm₂ : ∀ k < m, ¬coeff R k φ ≠ 0 := fun k => Nat.find_min ex
695-
ext n
696-
rw [(coeff R n).map_zero]
697-
induction' n using Nat.strong_induction_on with n ih
698-
replace h := congr_arg (coeff R (m + n)) h
699-
rw [LinearMap.map_zero, coeff_mul, Finset.sum_eq_single (m, n)] at h
700-
· replace h := NoZeroDivisors.eq_zero_or_eq_zero_of_mul_eq_zero h
701-
rw [or_iff_not_imp_left] at h
702-
exact h hm₁
703-
· rintro ⟨i, j⟩ hij hne
704-
by_cases hj : j < n
705-
· rw [ih j hj, mul_zero]
706-
by_cases hi : i < m
707-
· specialize hm₂ _ hi
708-
push_neg at hm₂
709-
rw [hm₂, zero_mul]
710-
rw [mem_antidiagonal] at hij
711-
push_neg at hi hj
712-
suffices m < i by
713-
have : m + n < i + j := add_lt_add_of_lt_of_le this hj
714-
exfalso
715-
exact ne_of_lt this hij.symm
716-
contrapose! hne
717-
obtain rfl := le_antisymm hi hne
718-
simpa [Ne, Prod.mk_inj] using (add_right_inj m).mp hij
719-
· contrapose!
720-
intro
721-
rw [mem_antidiagonal]
722-
723-
instance [NoZeroDivisors R] : NoZeroDivisors R⟦X⟧ where
724-
eq_zero_or_eq_zero_of_mul_eq_zero := eq_zero_or_eq_zero_of_mul_eq_zero _ _
749+
section IsDomain
725750

726-
instance [IsDomain R] : IsDomain R⟦X⟧ :=
751+
instance [Ring R] [IsDomain R] : IsDomain R⟦X⟧ :=
727752
NoZeroDivisors.to_isDomain _
728753

729-
end Domain
730-
731-
section IsDomain
732-
733754
variable [CommRing R] [IsDomain R]
734755

735756
/-- The ideal spanned by the variable in the power series ring

Mathlib/RingTheory/PowerSeries/Order.lean

Lines changed: 55 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,14 @@ theorem le_order_mul (φ ψ : R⟦X⟧) : order φ + order ψ ≤ order (φ * ψ
178178
apply ne_of_lt (lt_of_lt_of_le hn <| add_le_add hi hj)
179179
rw [← Nat.cast_add, hij]
180180

181+
theorem le_order_pow (φ : R⟦X⟧) (n : ℕ) : n • order φ ≤ order (φ ^ n) := by
182+
induction n with
183+
| zero => simp
184+
| succ n hn =>
185+
simp only [add_smul, one_smul, pow_succ]
186+
apply le_trans _ (le_order_mul _ _)
187+
exact add_le_add_right hn φ.order
188+
181189
alias order_mul_ge := le_order_mul
182190

183191
/-- The order of the monomial `a*X^n` is infinite if `a = 0` and `n` otherwise. -/
@@ -303,30 +311,58 @@ theorem order_X_pow (n : ℕ) : order ((X : R⟦X⟧) ^ n) = n := by
303311
rw [X_pow_eq, order_monomial_of_ne_zero]
304312
exact one_ne_zero
305313

314+
@[simp]
315+
theorem divided_by_X_pow_order_of_X_eq_one :
316+
divided_by_X_pow_order X_ne_zero = (1 : R⟦X⟧) := by
317+
apply X_pow_mul_cancel
318+
rw [self_eq_X_pow_order_mul_divided_by_X_pow_order]
319+
simp
320+
306321
end OrderZeroNeOne
307322

308-
section OrderIsDomain
323+
section NoZeroDivisors
309324

310-
-- TODO: generalize to `[Semiring R] [NoZeroDivisors R]`
311-
variable [CommRing R] [IsDomain R]
325+
variable [Semiring R] [NoZeroDivisors R]
312326

313327
/-- The order of the product of two formal power series over an integral domain
314328
is the sum of their orders. -/
315329
theorem order_mul (φ ψ : R⟦X⟧) : order (φ * ψ) = order φ + order ψ := by
316-
classical
317-
simp only [order_eq_emultiplicity_X]
318-
exact emultiplicity_mul X_prime
319-
320-
-- Dividing `X` by the maximal power of `X` dividing it leaves `1`.
321-
@[simp]
322-
theorem divided_by_X_pow_order_of_X_eq_one : divided_by_X_pow_order X_ne_zero = (1 : R⟦X⟧) := by
323-
rw [← mul_eq_left₀ X_ne_zero]
324-
simpa using self_eq_X_pow_order_mul_divided_by_X_pow_order (@X_ne_zero R _ _)
330+
apply le_antisymm _ (le_order_mul _ _)
331+
by_cases h : φ.order = ⊤ ∨ ψ.order = ⊤
332+
· rcases h with h | h <;> simp [h]
333+
· simp only [not_or, ENat.ne_top_iff_exists] at h
334+
obtain ⟨m, hm⟩ := h.1
335+
obtain ⟨n, hn⟩ := h.2
336+
rw [← hm, ← hn, ← ENat.coe_add]
337+
rw [eq_comm, order_eq_nat] at hm hn
338+
apply order_le
339+
rw [coeff_mul, Finset.sum_eq_single ⟨m, n⟩]
340+
· exact mul_ne_zero_iff.mpr ⟨hm.1, hn.1
341+
· intro ij hij h
342+
rcases trichotomy_of_add_eq_add (mem_antidiagonal.mp hij) with h' | h' | h'
343+
· exact False.elim (h (by simp [Prod.ext_iff, h'.1, h'.2]))
344+
· rw [hm.2 ij.1 h', zero_mul]
345+
· rw [hn.2 ij.2 h', mul_zero]
346+
· intro h
347+
apply False.elim (h _)
348+
simp [mem_antidiagonal]
349+
350+
theorem order_pow [Nontrivial R] (φ : R⟦X⟧) (n : ℕ) :
351+
order (φ ^ n) = n • order φ := by
352+
rcases subsingleton_or_nontrivial R with hR | hR
353+
· simp only [Subsingleton.eq_zero φ, order_zero, nsmul_eq_mul]
354+
by_cases hn : n = 0
355+
· simp [hn, pow_zero]
356+
· simp [zero_pow hn, ENat.mul_top', if_neg hn]
357+
induction n with
358+
| zero => simp
359+
| succ n hn =>
360+
simp only [add_smul, one_smul, pow_succ, order_mul, hn]
325361

326362
-- Dividing a power series by the maximal power of `X` dividing it, respects multiplication.
327363
theorem divided_by_X_pow_orderMul {f g : R⟦X⟧} (hf : f ≠ 0) (hg : g ≠ 0) :
328364
divided_by_X_pow_order hf * divided_by_X_pow_order hg =
329-
divided_by_X_pow_order (mul_ne_zero hf hg) := by
365+
divided_by_X_pow_order ((mul_ne_zero_iff_right hg).mpr hf) := by
330366
set df := f.order.lift (order_finite_iff_ne_zero.mpr hf)
331367
set dg := g.order.lift (order_finite_iff_ne_zero.mpr hg)
332368
set dfg := (f * g).order.lift (order_finite_iff_ne_zero.mpr (mul_ne_zero hf hg))
@@ -338,15 +374,16 @@ theorem divided_by_X_pow_orderMul {f g : R⟦X⟧} (hf : f ≠ 0) (hg : g ≠ 0)
338374
f * g = X ^ df * divided_by_X_pow_order hf * (X ^ dg * divided_by_X_pow_order hg) := by
339375
rw [self_eq_X_pow_order_mul_divided_by_X_pow_order,
340376
self_eq_X_pow_order_mul_divided_by_X_pow_order]
341-
_ = X ^ df * X ^ dg * divided_by_X_pow_order hf * divided_by_X_pow_order hg := by ring
377+
_ = X ^ df * X ^ dg * divided_by_X_pow_order hf * divided_by_X_pow_order hg := by
378+
rw [mul_assoc, ← mul_assoc _ (X ^ dg), (commute_iff_eq _ _).mp (commute_X_pow _ _)];
379+
simp [mul_assoc]
342380
_ = X ^ (df + dg) * divided_by_X_pow_order hf * divided_by_X_pow_order hg := by rw [pow_add]
343381
_ = X ^ dfg * divided_by_X_pow_order hf * divided_by_X_pow_order hg := by rw [H_add_d]
344382
_ = X ^ dfg * (divided_by_X_pow_order hf * divided_by_X_pow_order hg) := by rw [mul_assoc]
345-
refine (IsLeftCancelMulZero.mul_left_cancel_of_ne_zero (pow_ne_zero dfg X_ne_zero) ?_).symm
346-
simp only [this] at H
347-
convert H
383+
apply X_pow_mul_cancel
384+
rw [← this, H]
348385

349-
end OrderIsDomain
386+
end NoZeroDivisors
350387

351388
end PowerSeries
352389

0 commit comments

Comments
 (0)