Skip to content
This repository was archived by the owner on Jul 24, 2024. It is now read-only.

Commit 00b88eb

Browse files
committed
feat(data/polynomial/denominators): add file denominators (#5587)
The main goal of this PR is to establish that `b^deg(f)*f(a/b)` is an expression not involving denominators. The first lemma, `induction_with_nat_degree_le` is an induction principle for polynomials, where the inductive hypothesis has a bound on the degree of the polynomial. This allows to build the proof by tearing apart a polynomial into its monomials, while remembering the overall degree of the polynomial itself. This lemma might be a better fit for the file `data.polynomial.induction`.
1 parent 394d357 commit 00b88eb

File tree

2 files changed

+98
-0
lines changed

2 files changed

+98
-0
lines changed
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
/-
2+
Copyright (c) 2020 Damiano Testa. All rights reserved.
3+
Released under Apache 2.0 license as described in the file LICENSE.
4+
Authors: Damiano Testa
5+
-/
6+
import data.polynomial.erase_lead
7+
/-!
8+
# Denominators of evaluation of polynomials at ratios
9+
10+
Let `i : R → K` be a homomorphism of semirings. Assume that `K` is commutative. If `a` and
11+
`b` are elements of `R` such that `i b ∈ K` is invertible, then for any polynomial
12+
`f ∈ polynomial R` the "mathematical" expression `b ^ f.nat_degree * f (a / b) ∈ K` is in
13+
the image of the homomorphism `i`.
14+
-/
15+
16+
open polynomial finset
17+
18+
section denoms_clearable
19+
20+
variables {R K : Type*} [semiring R] [comm_semiring K] {i : R →+* K}
21+
variables {a b : R} {bi : K}
22+
-- TODO: use hypothesis (ub : is_unit (i b)) to work with localizations.
23+
24+
/-- `denoms_clearable` formalizes the property that `b ^ N * f (a / b)`
25+
does not have denominators, if the inequality `f.nat_degree ≤ N` holds.
26+
27+
In the implementation, we also use provide an inverse in the existential.
28+
-/
29+
def denoms_clearable (a b : R) (N : ℕ) (f : polynomial R) (i : R →+* K) : Prop :=
30+
∃ (D : R) (bi : K), bi * i b = 1 ∧ i D = i b ^ N * eval (i a * bi) (f.map i)
31+
32+
lemma denoms_clearable_zero (N : ℕ) (a : R) (bu : bi * i b = 1) :
33+
denoms_clearable a b N 0 i :=
34+
0, bi, bu, by simp only [eval_zero, ring_hom.map_zero, mul_zero, map_zero]⟩
35+
36+
lemma denoms_clearable_C_mul_X_pow {N : ℕ} (a : R) (bu : bi * i b = 1) {n : ℕ} (r : R)
37+
(nN : n ≤ N) : denoms_clearable a b N (C r * X ^ n) i :=
38+
begin
39+
refine ⟨r * a ^ n * b ^ (N - n), bi, bu, _⟩,
40+
rw [C_mul_X_pow_eq_monomial, map_monomial, ← C_mul_X_pow_eq_monomial, eval_mul, eval_pow, eval_C],
41+
rw [ring_hom.map_mul, ring_hom.map_mul, ring_hom.map_pow, ring_hom.map_pow, eval_X, mul_comm],
42+
rw [← nat.sub_add_cancel nN] {occs := occurrences.pos [2]},
43+
rw [pow_add, mul_assoc, mul_comm (i b ^ n), mul_pow, mul_assoc, mul_assoc (i a ^ n), ← mul_pow],
44+
rw [bu, one_pow, mul_one],
45+
end
46+
47+
lemma denoms_clearable.add {N : ℕ} {f g : polynomial R} :
48+
denoms_clearable a b N f i → denoms_clearable a b N g i → denoms_clearable a b N (f + g) i :=
49+
λ ⟨Df, bf, bfu, Hf⟩ ⟨Dg, bg, bgu, Hg⟩, ⟨Df + Dg, bf, bfu,
50+
begin
51+
rw [ring_hom.map_add, polynomial.map_add, eval_add, mul_add, Hf, Hg],
52+
congr,
53+
refine @inv_unique K _ (i b) bg bf _ _;
54+
rwa mul_comm,
55+
end
56+
57+
lemma denoms_clearable_of_nat_degree_le (N : ℕ) (a : R) (bu : bi * i b = 1) :
58+
∀ (f : polynomial R), f.nat_degree ≤ N → denoms_clearable a b N f i :=
59+
induction_with_nat_degree_le N
60+
(denoms_clearable_zero N a bu)
61+
(λ N_1 r r0, denoms_clearable_C_mul_X_pow a bu r)
62+
(λ f g fN gN df dg, df.add dg)
63+
64+
/-- If `i : R → K` is a ring homomorphism, `f` is a polynomial with coefficients in `R`,
65+
`a, b` are elements of `R`, with `i b` invertible, then there is a `D ∈ R` such that
66+
`b ^ f.nat_degree * f (a / b)` equals `i D`. -/
67+
theorem denoms_clearable_nat_degree
68+
(i : R →+* K) (f : polynomial R) (a : R) (bu : bi * i b = 1) :
69+
denoms_clearable a b f.nat_degree f i :=
70+
denoms_clearable_of_nat_degree_le f.nat_degree a bu f le_rfl
71+
72+
end denoms_clearable

src/data/polynomial/erase_lead.lean

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,4 +159,30 @@ end
159159

160160
end erase_lead
161161

162+
/-- An induction lemma for polynomials. It takes a natural number `N` as a parameter, that is
163+
required to be at least as big as the `nat_degree` of the polynomial. This is useful to prove
164+
results where you want to change each term in a polynomial to something else depending on the
165+
`nat_degree` of the polynomial itself and not on the specific `nat_degree` of each term. -/
166+
lemma induction_with_nat_degree_le {R : Type*} [semiring R] {P : polynomial R → Prop} (N : ℕ)
167+
(P_0 : P 0)
168+
(P_C_mul_pow : ∀ n : ℕ, ∀ r : R, r ≠ 0 → n ≤ N → P (C r * X ^ n))
169+
(P_C_add : ∀ f g : polynomial R, f.nat_degree ≤ N → g.nat_degree ≤ N → P f → P g → P (f + g)) :
170+
∀ f : polynomial R, f.nat_degree ≤ N → P f :=
171+
begin
172+
intros f df,
173+
generalize' hd : card f.support = c,
174+
revert f,
175+
induction c with c hc,
176+
{ exact λ f df f0, by rwa (finsupp.support_eq_empty.mp (card_eq_zero.mp f0)) },
177+
{ intros f df f0,
178+
rw ← erase_lead_add_C_mul_X_pow f,
179+
refine P_C_add f.erase_lead _ (erase_lead_nat_degree_le.trans df) _ _ _,
180+
{ exact (nat_degree_C_mul_X_pow_le f.leading_coeff f.nat_degree).trans df },
181+
{ exact hc _ (erase_lead_nat_degree_le.trans df) (erase_lead_card_support f0) },
182+
{ refine P_C_mul_pow _ _ _ df,
183+
rw [ne.def, leading_coeff_eq_zero],
184+
rintro rfl,
185+
exact not_le.mpr c.succ_pos f0.ge } }
186+
end
187+
162188
end polynomial

0 commit comments

Comments
 (0)