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

Commit c1d80c1

Browse files
committed
feat(algebra/cubic_discriminant): add eq_zero and ne_zero lemmas (#17627)
E.g. to allow `degree_of_c_eq_zero'` instead of `degree_of_c_eq_zero rfl rfl rfl` when the cubic is known to be constant.
1 parent 5fce179 commit c1d80c1

File tree

1 file changed

+106
-51
lines changed

1 file changed

+106
-51
lines changed

src/algebra/cubic_discriminant.lean

Lines changed: 106 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -13,18 +13,18 @@ This file defines cubic polynomials over a semiring and their discriminants over
1313
1414
## Main definitions
1515
16-
* `cubic`: the structure representing a cubic polynomial.
17-
* `disc`: the discriminant of a cubic polynomial.
16+
* `cubic`: the structure representing a cubic polynomial.
17+
* `cubic.disc`: the discriminant of a cubic polynomial.
1818
1919
## Main statements
2020
21-
* `disc_ne_zero_iff_roots_nodup`: the cubic discriminant is not equal to zero if and only if
22-
the cubic has no duplicate roots.
21+
* `cubic.disc_ne_zero_iff_roots_nodup`: the cubic discriminant is not equal to zero if and only if
22+
the cubic has no duplicate roots.
2323
2424
## References
2525
26-
* https://en.wikipedia.org/wiki/Cubic_equation
27-
* https://en.wikipedia.org/wiki/Discriminant
26+
* https://en.wikipedia.org/wiki/Cubic_equation
27+
* https://en.wikipedia.org/wiki/Discriminant
2828
2929
## Tags
3030
@@ -39,6 +39,7 @@ noncomputable theory
3939
namespace cubic
4040

4141
open cubic polynomial
42+
4243
open_locale polynomial
4344

4445
variables {R S F K : Type*}
@@ -49,7 +50,7 @@ instance [has_zero R] : has_zero (cubic R) := ⟨⟨0, 0, 0, 0⟩⟩
4950

5051
section basic
5152

52-
variables {P : cubic R} [semiring R]
53+
variables {P Q : cubic R} {a b c d a' b' c' d' : R} [semiring R]
5354

5455
/-- Convert a cubic polynomial to a polynomial. -/
5556
def to_poly (P : cubic R) : R[X] := C P.a * X ^ 3 + C P.b * X ^ 2 + C P.c * X + C P.d
@@ -70,49 +71,55 @@ begin
7071
repeat { rw [zero_add] }
7172
end
7273

73-
@[simp] lemma coeff_gt_three (n : ℕ) (hn : 3 < n) : P.to_poly.coeff n = 0 := coeffs.1 n hn
74+
@[simp] lemma coeff_eq_zero {n : ℕ} (hn : 3 < n) : P.to_poly.coeff n = 0 := coeffs.1 n hn
75+
76+
@[simp] lemma coeff_eq_a : P.to_poly.coeff 3 = P.a := coeffs.2.1
77+
78+
@[simp] lemma coeff_eq_b : P.to_poly.coeff 2 = P.b := coeffs.2.2.1
7479

75-
@[simp] lemma coeff_three : P.to_poly.coeff 3 = P.a := coeffs.2.1
80+
@[simp] lemma coeff_eq_c : P.to_poly.coeff 1 = P.c := coeffs.2.2.2.1
7681

77-
@[simp] lemma coeff_two : P.to_poly.coeff 2 = P.b := coeffs.2.2.1
82+
@[simp] lemma coeff_eq_d : P.to_poly.coeff 0 = P.d := coeffs.2.2.2.2
7883

79-
@[simp] lemma coeff_one : P.to_poly.coeff 1 = P.c := coeffs.2.2.2.1
84+
lemma a_of_eq (h : P.to_poly = Q.to_poly) : P.a = Q.a := by rw [← coeff_eq_a, h, coeff_eq_a]
8085

81-
@[simp] lemma coeff_zero : P.to_poly.coeff 0 = P.d := coeffs.2.2.2.2
86+
lemma b_of_eq (h : P.to_poly = Q.to_poly) : P.b = Q.b := by rw [← coeff_eq_b, h, coeff_eq_b]
8287

83-
lemma a_of_eq {Q : cubic R} (h : P.to_poly = Q.to_poly) : P.a = Q.a :=
84-
by rw [← coeff_three, h, coeff_three]
88+
lemma c_of_eq (h : P.to_poly = Q.to_poly) : P.c = Q.c := by rw [← coeff_eq_c, h, coeff_eq_c]
8589

86-
lemma b_of_eq {Q : cubic R} (h : P.to_poly = Q.to_poly) : P.b = Q.b :=
87-
by rw [← coeff_two, h, coeff_two]
90+
lemma d_of_eq (h : P.to_poly = Q.to_poly) : P.d = Q.d := by rw [← coeff_eq_d, h, coeff_eq_d]
8891

89-
lemma c_of_eq {Q : cubic R} (h : P.to_poly = Q.to_poly) : P.c = Q.c :=
90-
by rw [← coeff_one, h, coeff_one]
92+
lemma to_poly_injective (P Q : cubic R) : P.to_poly = Q.to_poly ↔ P = Q :=
93+
⟨λ h, ext P Q (a_of_eq h) (b_of_eq h) (c_of_eq h) (d_of_eq h), congr_arg to_poly⟩
9194

92-
lemma d_of_eq {Q : cubic R} (h : P.to_poly = Q.to_poly) : P.d = Q.d :=
93-
by rw [← coeff_zero, h, coeff_zero]
95+
lemma of_a_eq_zero (ha : P.a = 0) : P.to_poly = C P.b * X ^ 2 + C P.c * X + C P.d :=
96+
by rw [to_poly, ha, C_0, zero_mul, zero_add]
9497

95-
@[simp] lemma to_poly_injective (P Q : cubic R) : P.to_poly = Q.to_poly ↔ P = Q :=
96-
⟨λ h, cubic.ext _ _ (a_of_eq h) (b_of_eq h) (c_of_eq h) (d_of_eq h), congr_arg _⟩
98+
lemma of_a_eq_zero' : to_poly ⟨0, b, c, d⟩ = C b * X ^ 2 + C c * X + C d := of_a_eq_zero rfl
9799

98-
@[simp] lemma of_a_eq_zero (ha : P.a = 0) : P.to_poly = C P.b * X ^ 2 + C P.c * X + C P.d :=
99-
by rw [to_poly, C_eq_zero.mpr ha, zero_mul, zero_add]
100+
lemma of_b_eq_zero (ha : P.a = 0) (hb : P.b = 0) : P.to_poly = C P.c * X + C P.d :=
101+
by rw [of_a_eq_zero ha, hb, C_0, zero_mul, zero_add]
100102

101-
@[simp] lemma of_a_b_eq_zero (ha : P.a = 0) (hb : P.b = 0) : P.to_poly = C P.c * X + C P.d :=
102-
by rw [of_a_eq_zero ha, C_eq_zero.mpr hb, zero_mul, zero_add]
103+
lemma of_b_eq_zero' : to_poly ⟨0, 0, c, d⟩ = C c * X + C d := of_b_eq_zero rfl rfl
103104

104-
@[simp] lemma of_a_b_c_eq_zero (ha : P.a = 0) (hb : P.b = 0) (hc : P.c = 0) : P.to_poly = C P.d :=
105-
by rw [of_a_b_eq_zero ha hb, C_eq_zero.mpr hc, zero_mul, zero_add]
105+
lemma of_c_eq_zero (ha : P.a = 0) (hb : P.b = 0) (hc : P.c = 0) : P.to_poly = C P.d :=
106+
by rw [of_b_eq_zero ha hb, hc, C_0, zero_mul, zero_add]
106107

107-
@[simp] lemma of_zero (ha : P.a = 0) (hb : P.b = 0) (hc : P.c = 0) (hd : P.d = 0) : P.to_poly = 0 :=
108-
by rw [of_a_b_c_eq_zero ha hb hc, C_eq_zero.mpr hd]
108+
lemma of_c_eq_zero' : to_poly ⟨0, 0, 0, d⟩ = C d := of_c_eq_zero rfl rfl rfl
109109

110-
@[simp] lemma zero : (0 : cubic R).to_poly = 0 := of_zero rfl rfl rfl rfl
110+
lemma of_d_eq_zero (ha : P.a = 0) (hb : P.b = 0) (hc : P.c = 0) (hd : P.d = 0) :
111+
P.to_poly = 0 :=
112+
by rw [of_c_eq_zero ha hb hc, hd, C_0]
111113

112-
@[simp] lemma eq_zero_iff : P.to_poly = 0 ↔ P = 0 := by rw [← zero, to_poly_injective]
114+
lemma of_d_eq_zero' : (⟨0, 0, 0, 0⟩ : cubic R).to_poly = 0 := of_d_eq_zero rfl rfl rfl rfl
113115

114-
lemma ne_zero (h0 : ¬P.a = 0 ∨ ¬P.b = 0 ∨ ¬P.c = 0 ∨ ¬P.d = 0) : P.to_poly ≠ 0 :=
115-
by { contrapose! h0, rw [eq_zero_iff.mp h0], exact ⟨rfl, rfl, rfl, rfl⟩ }
116+
lemma zero : (0 : cubic R).to_poly = 0 := of_d_eq_zero'
117+
118+
lemma to_poly_eq_zero_iff (P : cubic R) : P.to_poly = 0 ↔ P = 0 :=
119+
by rw [← zero, to_poly_injective]
120+
121+
private lemma ne_zero (h0 : P.a ≠ 0 ∨ P.b ≠ 0 ∨ P.c ≠ 0 ∨ P.d ≠ 0) : P.to_poly ≠ 0 :=
122+
by { contrapose! h0, rw [(to_poly_eq_zero_iff P).mp h0], exact ⟨rfl, rfl, rfl, rfl⟩ }
116123

117124
lemma ne_zero_of_a_ne_zero (ha : P.a ≠ 0) : P.to_poly ≠ 0 := (or_imp_distrib.mp ne_zero).1 ha
118125

@@ -140,38 +147,85 @@ section degree
140147
begin
141148
ext (_ | _ | _ | _ | n); simp only [subtype.coe_mk, coeffs],
142149
have h3 : 3 < n + 4 := by linarith only,
143-
rw [coeff_gt_three _ h3,
150+
rw [coeff_eq_zero h3,
144151
(degree_le_iff_coeff_zero (f : R[X]) 3).mp f.2 _ $ with_bot.coe_lt_coe.mpr h3]
145152
end }
146153

147-
lemma degree (ha : P.a ≠ 0) : P.to_poly.degree = 3 := degree_cubic ha
154+
@[simp] lemma degree_of_a_ne_zero (ha : P.a ≠ 0) : P.to_poly.degree = 3 := degree_cubic ha
155+
156+
@[simp] lemma degree_of_a_ne_zero' (ha : a ≠ 0) : (to_poly ⟨a, b, c, d⟩).degree = 3 :=
157+
degree_of_a_ne_zero ha
148158

149-
lemma degree_of_a_eq_zero (ha : P.a = 0) (hb : P.b ≠ 0) : P.to_poly.degree = 2 :=
159+
lemma degree_of_a_eq_zero (ha : P.a = 0) : P.to_poly.degree ≤ 2 :=
160+
by simpa only [of_a_eq_zero ha] using degree_quadratic_le
161+
162+
lemma degree_of_a_eq_zero' : (to_poly ⟨0, b, c, d⟩).degree ≤ 2 := degree_of_a_eq_zero rfl
163+
164+
@[simp] lemma degree_of_b_ne_zero (ha : P.a = 0) (hb : P.b ≠ 0) : P.to_poly.degree = 2 :=
150165
by rw [of_a_eq_zero ha, degree_quadratic hb]
151166

152-
lemma degree_of_a_b_eq_zero (ha : P.a = 0) (hb : P.b = 0) (hc : P.c ≠ 0) : P.to_poly.degree = 1 :=
153-
by rw [of_a_b_eq_zero ha hb, degree_linear hc]
167+
@[simp] lemma degree_of_b_ne_zero' (hb : b ≠ 0) : (to_poly ⟨0, b, c, d⟩).degree = 2 :=
168+
degree_of_b_ne_zero rfl hb
169+
170+
lemma degree_of_b_eq_zero (ha : P.a = 0) (hb : P.b = 0) : P.to_poly.degree ≤ 1 :=
171+
by simpa only [of_b_eq_zero ha hb] using degree_linear_le
172+
173+
lemma degree_of_b_eq_zero' : (to_poly ⟨0, 0, c, d⟩).degree ≤ 1 := degree_of_b_eq_zero rfl rfl
174+
175+
@[simp] lemma degree_of_c_ne_zero (ha : P.a = 0) (hb : P.b = 0) (hc : P.c ≠ 0) :
176+
P.to_poly.degree = 1 :=
177+
by rw [of_b_eq_zero ha hb, degree_linear hc]
154178

155-
lemma degree_of_a_b_c_eq_zero (ha : P.a = 0) (hb : P.b = 0) (hc : P.c = 0) (hd : P.d ≠ 0) :
179+
@[simp] lemma degree_of_c_ne_zero' (hc : c ≠ 0) : (to_poly ⟨0, 0, c, d⟩).degree = 1 :=
180+
degree_of_c_ne_zero rfl rfl hc
181+
182+
lemma degree_of_c_eq_zero (ha : P.a = 0) (hb : P.b = 0) (hc : P.c = 0) : P.to_poly.degree ≤ 0 :=
183+
by simpa only [of_c_eq_zero ha hb hc] using degree_C_le
184+
185+
lemma degree_of_c_eq_zero' : (to_poly ⟨0, 0, 0, d⟩).degree ≤ 0 := degree_of_c_eq_zero rfl rfl rfl
186+
187+
@[simp] lemma degree_of_d_ne_zero (ha : P.a = 0) (hb : P.b = 0) (hc : P.c = 0) (hd : P.d ≠ 0) :
156188
P.to_poly.degree = 0 :=
157-
by rw [of_a_b_c_eq_zero ha hb hc, degree_C hd]
189+
by rw [of_c_eq_zero ha hb hc, degree_C hd]
158190

159-
lemma degree_of_zero (ha : P.a = 0) (hb : P.b = 0) (hc : P.c = 0) (hd : P.d = 0) :
191+
@[simp] lemma degree_of_d_ne_zero' (hd : d ≠ 0) : (to_poly ⟨0, 0, 0, d⟩).degree = 0 :=
192+
degree_of_d_ne_zero rfl rfl rfl hd
193+
194+
@[simp] lemma degree_of_d_eq_zero (ha : P.a = 0) (hb : P.b = 0) (hc : P.c = 0) (hd : P.d = 0) :
160195
P.to_poly.degree = ⊥ :=
161-
by rw [of_zero ha hb hc hd, degree_zero]
196+
by rw [of_d_eq_zero ha hb hc hd, degree_zero]
197+
198+
@[simp] lemma degree_of_d_eq_zero' : (⟨0, 0, 0, 0⟩ : cubic R).to_poly.degree = ⊥ :=
199+
degree_of_d_eq_zero rfl rfl rfl rfl
162200

163-
lemma leading_coeff (ha : P.a ≠ 0) : P.to_poly.leading_coeff = P.a := leading_coeff_cubic ha
201+
@[simp] lemma degree_of_zero : (0 : cubic R).to_poly.degree = := degree_of_d_eq_zero'
164202

165-
lemma leading_coeff_of_a_eq_zero (ha : P.a = 0) (hb : P.b ≠ 0) : P.to_poly.leading_coeff = P.b :=
203+
@[simp] lemma leading_coeff_of_a_ne_zero (ha : P.a ≠ 0) : P.to_poly.leading_coeff = P.a :=
204+
leading_coeff_cubic ha
205+
206+
@[simp] lemma leading_coeff_of_a_ne_zero' (ha : a ≠ 0) : (to_poly ⟨a, b, c, d⟩).leading_coeff = a :=
207+
leading_coeff_of_a_ne_zero ha
208+
209+
@[simp] lemma leading_coeff_of_b_ne_zero (ha : P.a = 0) (hb : P.b ≠ 0) :
210+
P.to_poly.leading_coeff = P.b :=
166211
by rw [of_a_eq_zero ha, leading_coeff_quadratic hb]
167212

168-
lemma leading_coeff_of_a_b_eq_zero (ha : P.a = 0) (hb : P.b = 0) (hc : P.c ≠ 0) :
213+
@[simp] lemma leading_coeff_of_b_ne_zero' (hb : b ≠ 0) : (to_poly ⟨0, b, c, d⟩).leading_coeff = b :=
214+
leading_coeff_of_b_ne_zero rfl hb
215+
216+
@[simp] lemma leading_coeff_of_c_ne_zero (ha : P.a = 0) (hb : P.b = 0) (hc : P.c ≠ 0) :
169217
P.to_poly.leading_coeff = P.c :=
170-
by rw [of_a_b_eq_zero ha hb, leading_coeff_linear hc]
218+
by rw [of_b_eq_zero ha hb, leading_coeff_linear hc]
171219

172-
lemma leading_coeff_of_a_b_c_eq_zero (ha : P.a = 0) (hb : P.b = 0) (hc : P.c = 0) :
220+
@[simp] lemma leading_coeff_of_c_ne_zero' (hc : c ≠ 0) : (to_poly ⟨0, 0, c, d⟩).leading_coeff = c :=
221+
leading_coeff_of_c_ne_zero rfl rfl hc
222+
223+
@[simp] lemma leading_coeff_of_c_eq_zero (ha : P.a = 0) (hb : P.b = 0) (hc : P.c = 0) :
173224
P.to_poly.leading_coeff = P.d :=
174-
by rw [of_a_b_c_eq_zero ha hb hc, leading_coeff_C]
225+
by rw [of_c_eq_zero ha hb hc, leading_coeff_C]
226+
227+
@[simp] lemma leading_coeff_of_c_eq_zero' : (to_poly ⟨0, 0, 0, d⟩).leading_coeff = d :=
228+
leading_coeff_of_c_eq_zero rfl rfl rfl
175229

176230
end degree
177231

@@ -236,7 +290,8 @@ begin
236290
replace ha : (map φ P).a ≠ 0 := (_root_.map_ne_zero φ).mpr ha,
237291
nth_rewrite_lhs 0 [← ring_hom.id_comp φ],
238292
rw [roots, ← splits_map_iff, ← map_to_poly, splits_iff_card_roots,
239-
← ((degree_eq_iff_nat_degree_eq $ ne_zero_of_a_ne_zero ha).mp $ degree ha : _ = 3)]
293+
← ((degree_eq_iff_nat_degree_eq $ ne_zero_of_a_ne_zero ha).mp $
294+
degree_of_a_ne_zero ha : _ = 3)]
240295
end
241296

242297
theorem splits_iff_roots_eq_three (ha : P.a ≠ 0) :
@@ -247,7 +302,7 @@ theorem eq_prod_three_roots (ha : P.a ≠ 0) (h3 : (map φ P).roots = {x, y, z})
247302
(map φ P).to_poly = C (φ P.a) * (X - C x) * (X - C y) * (X - C z) :=
248303
begin
249304
rw [map_to_poly, eq_prod_roots_of_splits $ (splits_iff_roots_eq_three ha).mpr $ exists.intro x $
250-
exists.intro y $ exists.intro z h3, leading_coeff ha, ← map_roots, h3],
305+
exists.intro y $ exists.intro z h3, leading_coeff_of_a_ne_zero ha, ← map_roots, h3],
251306
change C (φ P.a) * ((X - C x) ::ₘ (X - C y) ::ₘ {X - C z}).prod = _,
252307
rw [prod_cons, prod_cons, prod_singleton, mul_assoc, mul_assoc]
253308
end

0 commit comments

Comments
 (0)