theory RRI_Misc imports "HOL-Computational_Algebra.Computational_Algebra" "Budan_Fourier.BF_Misc" "Polynomial_Interpolation.Ring_Hom_Poly" begin
subsection‹Misc›
declare pcompose_pCons[simp del]
lemma Setcompr_subset: "∧f P S. {f x | x. P x} ⊆ S = (∀ x. P x ⟶ f x ∈ S)" by blast
lemma map_cong': assumes"xs = map h ys"and"∧y. y ∈ set ys ==> f (h y) = g y" shows"map f xs = map g ys" using assms map_replicate_trivial by simp
lemma nth_default_replicate_eq: "nth_default dflt (replicate n x) i = (if i < n then x else dflt)" by (auto simp: nth_default_def)
lemma square_bounded_less: fixes a b::"'a :: linordered_ring_strict" shows"-a < b ∧ b < a ==> b*b < a*a" by (metis (no_types, lifting) leD leI minus_less_iff minus_mult_minus mult_strict_mono'
neg_less_eq_nonneg neg_less_pos verit_minus_simplify(4) zero_le_mult_iff zero_le_square)
lemma square_bounded_le: fixes a b::"'a :: linordered_ring_strict" shows"-a ≤ b ∧ b ≤ a ==> b*b ≤ a*a" by (metis le_less minus_mult_minus square_bounded_less)
context vector_space begin
lemma card_le_dim_spanning: assumes BV: "B ⊆ V" and VB: "V ⊆ span B" and fB: "finite B" and dVB: "dim V ≥ card B" shows"independent B" proof -
{ fix a assume a: "a ∈ B""a ∈ span (B - {a})" from a fB have c0: "card B ≠ 0" by auto from a fB have cb: "card (B - {a}) = card B - 1" by auto
{ fix x assume x: "x ∈ V" from a have eq: "insert a (B - {a}) = B" by blast from x VB have x': "x ∈ span B" by blast from span_trans[OF a(2), unfolded eq, OF x'] have"x ∈ span (B - {a})" .
} thenhave th1: "V ⊆ span (B - {a})" by blast have th2: "finite (B - {a})" using fB by auto from dim_le_card[OF th1 th2] have c: "dim V ≤ card (B - {a})" . from c c0 dVB cb have False by simp
} thenshow ?thesis unfolding dependent_def by blast qed
end
subsection‹Misc results about polynomials›
lemma smult_power: "smult (x^n) (p^n) = smult x p ^ n" apply (induction n)
subgoal by fastforce by (metis smult_power)
lemma reflect_poly_monom: "reflect_poly (monom n i) = monom n 0" apply (induction i) by (auto simp: coeffs_eq_iff coeffs_monom coeffs_reflect_poly)
lemma poly_eq_by_eval: fixes P Q :: "'a::{comm_ring_1,ring_no_zero_divisors,ring_char_0} poly" assumes h: "∧x. poly P x = poly Q x"shows"P = Q" proof - have"poly P = poly Q"using h by fast thus ?thesis by (auto simp: poly_eq_poly_eq_iff) qed
lemma degree_0_iff: "degree P = 0 ⟷ (∃a. P = [:a:])" by (meson degree_eq_zeroE degree_pCons_0)
interpretation poly_vs: vector_space smult by (simp add: vector_space_def smult_add_right smult_add_left)
lemma degree_subspace: "poly_vs.subspace {x. degree x ≤ n}" by (auto simp: poly_vs.subspace_def degree_add_le)
lemma monom_span: "poly_vs.span {monom 1 x | x. x ≤ p} = {(x::'a::field poly). degree x ≤ p}"
(is"?L = ?R") proof show"?L ⊆ ?R" proof fix x assume"x ∈ ?L" moreoverhave hfin: "finite {P. ∃x ∈ {..p}. P = monom 1 x}" by auto ultimatelyhave "x ∈ range (λu. ∑v∈{monom 1 x | x. x ∈ {..p}}. smult (u v) v)" by (simp add: poly_vs.span_finite) hence"∃ u. x = (∑v∈{monom 1 x | x. x ∈ {..p}}. smult (u v) v)" by (auto simp: image_iff) thenobtain u where p': "x = (∑v∈{monom 1 x | x. x ∈ {..p}}. smult (u v) v)" by blast have"∧v. v ∈ {monom 1 x | x. x ∈ {..p}} ==> degree (smult (u v) v) ≤ p" by (auto simp add: degree_monom_eq) hence"degree x ≤ p"using hfin apply (subst p') apply (rule degree_sum_le) by auto thus"x ∈ {x. degree x ≤ p}"by force qed next show"?R ⊆ ?L" proof fix x assume"x ∈ ?R" hence"degree x ≤ p"by force hence"x = (∑i≤p. monom (coeff x i) i)" by (simp add: poly_as_sum_of_monoms') alsohave "... = (∑i≤p. smult (coeff x (degree (monom (1::'a) i))) (monom 1 i))" by (auto simp add: smult_monom degree_monom_eq) alsohave "... = (∑v∈{monom 1 x | x. x ∈ {..p}}. smult ((λv. coeff x (degree v)) v) v)" proof (rule sum.reindex_cong) show"inj_on degree {monom (1::'a) x |x. x ∈ {..p}}" proof fix x assume"x ∈ {monom (1::'a) x |x. x ∈ {..p}}" hence"∃ a. x = monom 1 a"by blast thenobtain a where hx: "x = monom 1 a"by blast fix y assume"y ∈ {monom (1::'a) x |x. x ∈ {..p}}" hence"∃ b. y = monom 1 b"by blast thenobtain b where hy: "y = monom 1 b"by blast assume"degree x = degree y" thus"x = y"using hx hy by (simp add: degree_monom_eq) qed show"{..p} = degree ` {monom (1::'a) x |x. x ∈ {..p}}" proof show"{..p} ⊆ degree ` {monom (1::'a) x |x. x ∈ {..p}}" proof fix x assume"x ∈ {..p}" hence"monom (1::'a) x ∈ {monom 1 x |x. x ∈ {..p}}"by force moreoverhave"degree (monom (1::'a) x) = x" by (simp add: degree_monom_eq) ultimatelyshow"x ∈ degree ` {monom (1::'a) x |x. x ∈ {..p}}"by auto qed show"degree ` {monom (1::'a) x |x. x ∈ {..p}} ⊆ {..p}" by (auto simp add: degree_monom_eq) qed next fix y assume"y ∈ {monom (1::'a) x |x. x ∈ {..p}}" hence"∃z ∈ {..p}. y = monom (1::'a) z"by blast thenobtain z where"y = monom (1::'a) z"by blast thus "smult (coeff x (degree (monom (1::'a) (degree y)))) (monom (1::'a) (degree y)) = smult (coeff x (degree y)) y" by (simp add: smult_monom degree_monom_eq) qed finallyhave"x = (∑v∈{monom 1 x | x. x ∈ {..p}}. smult ((λv. coeff x (degree v)) v) v)" . thus"x ∈ ?L"by (auto simp add: poly_vs.span_finite) qed qed
lemma monom_independent: "poly_vs.independent {monom (1::'a::field) x | x. x ≤ p}" proof (rule poly_vs.independent_if_scalars_zero) fix f::"'a poly ==> 'a" assume h: "(∑x∈{monom 1 x |x. x ≤ p}. smult (f x) x) = 0" have h': "(∑i≤p. monom (f (monom (1::'a) i)) i) = (∑x∈{monom (1::'a) x |x. x ≤ p}. smult (f x) x)" proof (rule sum.reindex_cong) show"inj_on degree {monom (1::'a) x |x. x ≤ p}" by (smt (verit) degree_monom_eq inj_on_def mem_Collect_eq zero_neq_one) show"{..p} = degree ` {monom (1::'a) x |x. x ≤ p}" proof show"{..p} ⊆ degree ` {monom (1::'a) x |x. x ≤ p}" proof fix x assume"x ∈ {..p}" thenhave"x = degree (monom (1::'a) x) ∧ x ≤ p" by (auto simp: degree_monom_eq) thus"x ∈ degree ` {monom (1::'a) x |x. x ≤ p}" by blast qed show"degree ` {monom (1::'a) x |x. x ≤ p} ⊆ {..p}" by (force simp: degree_monom_eq) qed qed (auto simp: degree_monom_eq smult_monom)
fix x::"'a poly" assume"x ∈ {monom 1 x |x. x ≤ p}" thenobtain y where"y ≤ p"and"x = monom 1 y"by blast hence"f x = coeff (∑x∈{monom 1 x |x. x ≤ p}. smult (f x) x) y" by (auto simp: coeff_sum h'[symmetric]) thus"f x = 0" using h by auto qed force
lemma dim_degree: "poly_vs.dim {x. degree x ≤ n} = n + 1" using poly_vs.dim_eq_card_independent[OF monom_independent] by (auto simp: monom_span[symmetric] card_image image_Collect[symmetric]
inj_on_def monom_eq_iff')
lemma degree_div: fixes p q::"('a::idom_divide) poly" assumes"q dvd p" shows"degree (p div q) = degree p - degree q"using assms by (metis (no_types, lifting) add_diff_cancel_left' degree_0 degree_mult_eq
diff_add_zero diff_zero div_by_0 dvd_div_eq_0_iff dvd_mult_div_cancel)
lemma lead_coeff_div: fixes p q::"('a::{idom_divide, inverse}) poly" assumes"q dvd p" shows"lead_coeff (p div q) = lead_coeff p / lead_coeff q"using assms by (smt (z3) div_by_0 dvd_div_mult_self lead_coeff_mult leading_coeff_0_iff
nonzero_mult_div_cancel_right)
lemma complex_poly_eq: "r = map_poly of_real (map_poly Re r) + smult i (map_poly of_real (map_poly Im r))" by (auto simp: poly_eq_iff coeff_map_poly complex_eq)
lemma complex_poly_cong: "(map_poly Re p = map_poly Re q ∧ map_poly Im p = map_poly Im q) = (p = q)" by (metis complex_poly_eq)
lemma map_poly_Im_of_real: "map_poly Im (map_poly of_real p) = 0" by (auto simp: poly_eq_iff coeff_map_poly)
lemma mult_map_poly_imp_map_poly: assumes"map_poly complex_of_real q = r * map_poly complex_of_real p" "p ≠ 0" shows"r = map_poly complex_of_real (map_poly Re r)" proof - have h: "Im ∘ (*) i∘ complex_of_real = id"by fastforce have"map_poly complex_of_real q = r * map_poly complex_of_real p" using assms by blast alsohave"... = (map_poly of_real (map_poly Re r) + smult i (map_poly of_real (map_poly Im r))) * map_poly complex_of_real p" using complex_poly_eq by fastforce alsohave"... = map_poly of_real (map_poly Re r * p) + smult i (map_poly of_real (map_poly Im r * p))" by (simp add: mult_poly_add_left) finallyhave"map_poly complex_of_real q = map_poly of_real (map_poly Re r * p) + smult i (map_poly of_real (map_poly Im r * p))" . hence"0 = map_poly Im (map_poly of_real (map_poly Re r * p) + smult i (map_poly of_real (map_poly Im r * p)))" by (auto simp: complex_poly_cong[symmetric] map_poly_Im_of_real) alsohave"... = map_poly of_real (map_poly Im r * p)" apply (rule poly_eqI) by (auto simp: coeff_map_poly coeff_mult) finallyhave"0 = map_poly complex_of_real (map_poly Im r) * map_poly complex_of_real p" by auto hence"map_poly complex_of_real (map_poly Im r) = 0"using assms by fastforce thus ?thesis apply (subst complex_poly_eq) by auto qed
lemma map_poly_dvd: fixes p q::"real poly" assumes hdvd: "map_poly complex_of_real p dvd map_poly complex_of_real q""q ≠ 0" shows"p dvd q" proof - from hdvd obtain r where h:"map_poly complex_of_real q = r * map_poly complex_of_real p" by fastforce hence"r = map_poly complex_of_real (map_poly Re r)" using mult_map_poly_imp_map_poly assms by force hence"map_poly complex_of_real q = map_poly complex_of_real (p * map_poly Re r)" using h by auto hence"q = p * map_poly Re r"using of_real_poly_eq_iff by blast thus"p dvd q"by force qed
lemma div_poly_eq_0: fixes p q::"('a::idom_divide) poly" assumes"q dvd p""poly (p div q) x = 0""q ≠ 0" shows"poly p x = 0" using assms by fastforce
lemma poly_map_poly_of_real_cnj: "poly (map_poly of_real p) (cnj z) = cnj (poly (map_poly of_real p) z)" apply (induction p) by auto
text‹
induction rule on real polynomials, if $P \neq 0$ then either $(X-x)|P$ or
(X-z)(X-cnj z)|P$, we induct by dividing by these polynomials. › lemma real_poly_roots_induct: fixes P::"real poly ==> bool"and p::"real poly" assumes IH_real: "∧p x. P p ==> P (p * [:-x, 1:])" and IH_complex: "∧p a b. b ≠ 0 ==> P p ==> P (p * [: a*a + b*b, -2*a, 1 :])" and H0: "∧a. P [:a:]" defines"d ≡ degree p" shows"P p" using d_def proof (induction d arbitrary: p rule: less_induct) fix p::"real poly" assume IH: "(∧q. degree q < degree p ==> P q)" show"P p" proof (cases "0 = degree p") fix p::"real poly"assume"0 = degree p" hence"∃ a. p = [:a:]" by (simp add: degree_0_iff) thus"P p"using H0 by blast next assume hdeg: "0 ≠ degree p" hence"¬ constant (poly (map_poly of_real p))" by (metis (no_types, opaque_lifting) constant_def constant_degree of_real_eq_iff of_real_poly_map_poly) thenobtain z::complex where h: "poly (map_poly of_real p) z = 0" using fundamental_theorem_of_algebra by blast show"P p" proof cases assume"Im z = 0" hence"z = Re z"by (simp add: complex_is_Real_iff) moreoverhave"[:-z, 1:] dvd map_poly of_real p" using h poly_eq_0_iff_dvd by blast ultimatelyhave"[:-(Re z), 1:] dvd p" by (smt (z3) dvd_iff_poly_eq_0 h of_real_0 of_real_eq_iff of_real_poly_map_poly) hence2:"P (p div [:-Re z, 1:])" apply (subst IH) using hdeg by (auto simp: degree_div) moreoverhave1:"p = (p div [:- Re z, 1:]) * [:-Re z, 1:]" by (metis ‹[:- Re z, 1:] dvd p› dvd_div_mult_self) ultimatelyshow"P p" apply (subst 1) by (rule IH_real[OF 2]) next assume"Im z ≠ 0" hence hcnj: "cnj z ≠ z"by (metis cnj.simps(2) neg_equal_zero) have h2: "poly (map_poly of_real p) (cnj z) = 0" using h poly_map_poly_of_real_cnj by force have"[:-z, 1:] * [:-cnj z, 1:] dvd map_poly of_real p" proof (rule divides_mult) have"∧c. c dvd [:-z, 1:] ==> c dvd [:- cnj z, 1:] ==> is_unit c" proof - fix c assume h:"c dvd [:-z, 1:]"hence"degree c ≤ 1"using divides_degree by fastforce hence"degree c = 0 ∨ degree c = 1"by linarith thus"c dvd [:- cnj z, 1:] ==> is_unit c" proof assume"degree c = 0" moreoverhave"c ≠ 0"using h by fastforce ultimatelyshow"is_unit c"by (simp add: is_unit_iff_degree) next assume hdeg: "degree c = 1" thenobtain x where1:"[:-z, 1:] = x*c"using h by fastforce hence"degree [:-z, 1:] = degree x + degree c" by (metis add.inverse_neutral degree_mult_eq mult_cancel_right
mult_poly_0_left pCons_eq_0_iff zero_neq_neg_one) hence"degree x = 0"using hdeg by auto thenobtain x' where2: "x = [:x':]"using degree_0_iff by auto assume"c dvd [:-cnj z, 1:]" thenobtain y where3: "[:-cnj z, 1:] = y*c"by fastforce hence"degree [:-cnj z, 1:] = degree y + degree c" by (metis add.inverse_neutral degree_mult_eq mult_cancel_right
mult_poly_0_left pCons_eq_0_iff zero_neq_neg_one) hence"degree y = 0"using hdeg by auto thenobtain y' where4: "y = [:y':]"using degree_0_iff by auto moreoverfrom hdeg obtain a b where5:"c = [:a, b:]"and6: "b ≠ 0" by (meson degree_eq_oneE) from1256have"x' = inverse b"by (auto simp: field_simps) moreoverfrom3456have"y' = inverse b"by (auto simp: field_simps) ultimatelyhave"x = y"using24by presburger thenhave"z = cnj z"using13by (metis neg_equal_iff_equal pCons_eq_iff) thus"is_unit c"using hcnj by argo qed qed thus"coprime [:- z, 1:] [:- cnj z, 1:]"by (meson not_coprimeE) show"[:- z, 1:] dvd map_poly complex_of_real p" using h poly_eq_0_iff_dvd by auto show"[:- cnj z, 1:] dvd map_poly complex_of_real p" using h2 poly_eq_0_iff_dvd by blast qed moreoverhave"[:- z, 1:] * [:- cnj z, 1:] = map_poly of_real [:Re z*Re z + Im z*Im z, -2*Re z, 1:]" by (auto simp: complex_eqI) ultimatelyhave hdvd: "map_poly complex_of_real [:Re z*Re z + Im z*Im z, -2*Re z, 1:] dvd map_poly complex_of_real p" by force hence"[:Re z*Re z + Im z*Im z, -2*Re z, 1:] dvd p"using map_poly_dvd by blast hence2:"P (p div [:Re z*Re z + Im z*Im z, -2*Re z, 1:])" apply (subst IH) using hdeg by (auto simp: degree_div) moreoverhave1: "p = (p div [:Re z*Re z + Im z*Im z, -2*Re z, 1:]) * [:Re z*Re z + Im z*Im z, -2*Re z, 1:]" apply (subst dvd_div_mult_self) using‹[:Re z*Re z + Im z*Im z, -2*Re z, 1:] dvd p›by auto ultimatelyshow"P p" apply (subst 1) apply (rule IH_complex[of "Im z" _ "Re z"]) apply (meson ‹Im z ≠ 0›) by blast qed qed qed
subsection‹The reciprocal polynomial›
definition reciprocal_poly :: "nat ==> 'a::zero poly ==> 'a poly" where"reciprocal_poly p P = Poly (rev ((coeffs P) @ (replicate (p - degree P) 0)))"
lemma reciprocal_0: "reciprocal_poly p 0 = 0"by (simp add: reciprocal_poly_def)
lemma reciprocal_1: "reciprocal_poly p 1 = monom 1 p" by (simp add: reciprocal_poly_def monom_altdef Poly_append)
lemma coeff_reciprocal: assumes hi: "i ≤ p"and hP: "degree P ≤ p" shows"coeff (reciprocal_poly p P) i = coeff P (p - i)" proof cases assume"i < p - degree P" hence"degree P < p - i"using hP by linarith thus"coeff (reciprocal_poly p P) i = coeff P (p - i)" by (auto simp: reciprocal_poly_def nth_default_append coeff_eq_0) next assume h: "¬i < p - degree P" show"coeff (reciprocal_poly p P) i = coeff P (p - i)" proof cases assume"P = 0" thus"coeff (reciprocal_poly p P) i = coeff P (p - i)" by (simp add: reciprocal_0) next assume hP': "P ≠ 0" have"degree P ≥ p - i"using h hP by linarith moreoverhence"(i - (p - degree P)) < length (rev (coeffs P))" using hP' hP hi by (auto simp: length_coeffs) thus"coeff (reciprocal_poly p P) i = coeff P (p - i)" by (auto simp: reciprocal_poly_def nth_default_append coeff_eq_0 hP hP'
nth_default_nth rev_nth calculation coeffs_nth length_coeffs_degree) qed qed
lemma coeff_reciprocal_less: assumes hn: "p < i"and hP: "degree P ≤ p" shows"coeff (reciprocal_poly p P) i = 0" proof cases assume"P = 0" thus ?thesis by (auto simp: reciprocal_0) next assume"P ≠ 0" thus ?thesis using hn by (auto simp: reciprocal_poly_def nth_default_append
nth_default_eq_dflt_iff hP length_coeffs) qed
lemma reciprocal_monom: assumes"n ≤ p" shows"reciprocal_poly p (monom a n) = monom a (p-n)" proof (cases "a=0") case True thenshow ?thesis by (simp add: reciprocal_0) next case False with‹n≤p›show ?thesis apply (rule_tac poly_eqI) by (metis coeff_monom coeff_reciprocal coeff_reciprocal_less
diff_diff_cancel diff_le_self lead_coeff_monom not_le_imp_less) qed
lemma reciprocal_degree: "reciprocal_poly (degree P) P = reflect_poly P" by (auto simp add: reciprocal_poly_def reflect_poly_def)
lemma reciprocal_0_iff: assumes hP: "degree P ≤ p" shows"(reciprocal_poly p P = 0) = (P = 0)" proof assume h: "reciprocal_poly p P = 0" show"P = 0" proof (rule poly_eqI) fix n show"coeff P n = coeff 0 n" proof cases assume hn: "n ≤ p" hence"p - n ≤ p"by auto hence"coeff (reciprocal_poly p P) (p - n) = coeff P n" using hP hn by (auto simp: coeff_reciprocal) thus ?thesis using h by auto next assume hn: "¬ n ≤ p" thus ?thesis using hP by (metis coeff_0 dual_order.trans le_degree) qed qed next assume"P = 0" thus"reciprocal_poly p P = 0"using reciprocal_0 by fast qed
lemma poly_reciprocal: fixes P::"'a::field poly" assumes hp: "degree P ≤ p"and hx: "x ≠ 0" shows"poly (reciprocal_poly p P) x = x^p * (poly P (inverse x))" proof - have"poly (reciprocal_poly p P) x = poly ((Poly ((replicate (p - degree P) 0) @ rev (coeffs P)))) x" by (auto simp add: hx reflect_poly_def reciprocal_poly_def) alsohave"... = poly ((monom 1 (p - degree P)) * (reflect_poly P)) x" by (auto simp add: reflect_poly_def Poly_append) alsohave"... = x^(p - degree P) * x ^ degree P * poly P (inverse x)" by (auto simp add: poly_reflect_poly_nz poly_monom hx) alsohave"... = x^p * poly P (inverse x)" by (auto simp add: hp power_add[symmetric]) finallyshow ?thesis . qed
lemma reciprocal_fcompose: fixes P::"('a::{ring_char_0,field}) poly" assumes hP: "degree P ≤ p" shows"reciprocal_poly p P = monom 1 (p - degree P) * fcompose P 1 [:0, 1:]" proof (rule poly_eq_by_eval, cases) fix x::'a assume hx: "x = 0" hence"poly (reciprocal_poly p P) x = coeff P p" using hP by (auto simp: poly_0_coeff_0 coeff_reciprocal) moreoverhave"poly (monom 1 (p - degree P) * fcompose P 1 [:0, 1:]) x = coeff P p" proof cases assume"degree P = p" thus ?thesis apply (induction P arbitrary: p) using hx by (auto simp: poly_monom degree_0_iff fcompose_pCons) next assume"degree P ≠ p" hence"degree P < p"using hP by auto thus ?thesis using hx by (auto simp: poly_monom coeff_eq_0) qed ultimatelyshow"poly (reciprocal_poly p P) x = poly (monom 1 (p - degree P) * fcompose P 1 [:0, 1:]) x" by presburger next fix x::'a assume"x ≠ 0" thus"poly (reciprocal_poly p P) x = poly (monom 1 (p - degree P) * fcompose P 1 [:0, 1:]) x" using hP by (auto simp: poly_reciprocal poly_fcompose inverse_eq_divide
poly_monom power_diff) qed
lemma reciprocal_reciprocal: fixes P :: "'a::{field,ring_char_0} poly" assumes hP: "degree P ≤ p" shows"reciprocal_poly p (reciprocal_poly p P) = P" proof (rule poly_eq_by_eval) fix x show"poly (reciprocal_poly p (reciprocal_poly p P)) x = poly P x" proof cases assume"x = 0" thus"poly (reciprocal_poly p (reciprocal_poly p P)) x = poly P x" using hP by (auto simp: poly_0_coeff_0 coeff_reciprocal degree_reciprocal) next assume hx: "x ≠ 0" hence"poly (reciprocal_poly p (reciprocal_poly p P)) x = x ^ p * (inverse x ^ p * poly P x)"using hP by (auto simp: poly_reciprocal degree_reciprocal) thus"poly (reciprocal_poly p (reciprocal_poly p P)) x = poly P x" using hP hx left_right_inverse_power right_inverse by auto qed qed
lemma reciprocal_smult: fixes P :: "'a::idom poly" assumes h: "degree P ≤ p" shows"reciprocal_poly p (smult n P) = smult n (reciprocal_poly p P)" proof cases assume"n = 0" thus ?thesis by (auto simp add: reciprocal_poly_def) next assume"n ≠ 0" thus ?thesis by (auto simp add: reciprocal_poly_def smult_Poly coeffs_smult
rev_map[symmetric]) qed
lemma reciprocal_add: fixes P Q :: "'a::comm_semiring_0 poly" assumes"degree P ≤ p"and"degree Q ≤ p" shows"reciprocal_poly p (P + Q) = reciprocal_poly p P + reciprocal_poly p Q"
(is"?L = ?R") proof (rule poly_eqI, cases) fix n assume"n ≤ p" thenshow"coeff ?L n = coeff ?R n" using assms by (auto simp: degree_add_le coeff_reciprocal) next fix n assume"¬n ≤ p" thenshow"coeff ?L n = coeff ?R n" using assms by (auto simp: degree_add_le coeff_reciprocal_less) qed
lemma reciprocal_diff: fixes P Q :: "'a::comm_ring poly" assumes"degree P ≤ p"and"degree Q ≤ p" shows"reciprocal_poly p (P - Q) = reciprocal_poly p P - reciprocal_poly p Q" by (metis (no_types, lifting) ab_group_add_class.ab_diff_conv_add_uminus assms
add_diff_cancel degree_add_le degree_minus diff_add_cancel reciprocal_add)
lemma reciprocal_sum: fixes P :: "'a ==> 'b::comm_semiring_0 poly" assumes hP: "∧k. degree (P k) ≤ p" shows"reciprocal_poly p (∑k∈A. P k) = (∑k∈A. reciprocal_poly p (P k))" proof (induct A rule: infinite_finite_induct) case (infinite A) thenshow ?caseby (simp add: reciprocal_0) next case empty thenshow ?caseby (simp add: reciprocal_0) next case (insert x F) assume"x ∉ F" and"reciprocal_poly p (sum P F) = (∑k∈F. reciprocal_poly p (P k))" and"finite F" moreoverhence"reciprocal_poly p (sum P (insert x F)) = reciprocal_poly p (P x) + reciprocal_poly p (sum P F)" by (auto simp add: reciprocal_add hP degree_sum_le) ultimatelyshow"reciprocal_poly p (sum P (insert x F)) = (∑k∈insert x F. reciprocal_poly p (P k))" by (auto simp: Groups_Big.comm_monoid_add_class.sum.insert_if) qed
lemma reciprocal_mult: fixes P Q::"'a::{ring_char_0,field} poly" assumes"degree (P * Q) ≤ p" and"degree P ≤ p"and"degree Q ≤ p" shows"monom 1 p * reciprocal_poly p (P * Q) = reciprocal_poly p P * reciprocal_poly p Q" proof (cases "P=0 ∨ Q=0") case True thenshow ?thesis using assms(1) by (auto simp: reciprocal_fcompose fcompose_mult) next case False thenshow ?thesis using assms by (auto simp: degree_mult_eq mult_monom reciprocal_fcompose fcompose_mult) qed
lemma reciprocal_reflect_poly: fixes P::"'a::{ring_char_0,field} poly" assumes hP: "degree P ≤ p" shows"reciprocal_poly p P = monom 1 (p - degree P) * reflect_poly P" proof (rule poly_eqI) fix n show"coeff (reciprocal_poly p P) n = coeff (monom 1 (p - degree P) * reflect_poly P) n" proof cases assume"n ≤ p" thus ?thesis using hP by (auto simp: coeff_reciprocal coeff_monom_mult coeff_reflect_poly coeff_eq_0) next assume"¬ n ≤ p" thus ?thesis using hP by (auto simp: coeff_reciprocal_less coeff_monom_mult coeff_reflect_poly) qed qed
lemma map_poly_reciprocal: assumes"degree P ≤ p"and"f 0 = 0" shows"map_poly f (reciprocal_poly p P) = reciprocal_poly p (map_poly f P)" proof (rule poly_eqI) fix n show"coeff (map_poly f (reciprocal_poly p P)) n = coeff (reciprocal_poly p (map_poly f P)) n" proof (cases "n≤p") case True thenshow ?thesis apply (subst coeff_reciprocal[OF True])
subgoal by (meson assms(1) assms(2) degree_map_poly_le le_trans) by (simp add: assms(1) assms(2) coeff_map_poly coeff_reciprocal) next case False thenshow ?thesis by (metis assms(1) assms(2) coeff_map_poly coeff_reciprocal_less
degree_map_poly_le dual_order.trans leI) qed qed
subsection‹More about @{term proots_count}›
lemma proots_count_monom: assumes"0 ∉ A" shows"proots_count (monom 1 d) A = 0" using assms by (auto simp: proots_count_def poly_monom)
lemma proots_count_reciprocal: fixes P::"'a::{ring_char_0,field} poly" assumes hP: "degree P ≤ p"and h0: "P ≠ 0"and h0': "0 ∉ A" shows"proots_count (reciprocal_poly p P) A = proots_count P {x. inverse x ∈ A}" proof - have"proots_count (reciprocal_poly p P) A = proots_count (fcompose P 1 [:0, 1:]) A" apply (subst reciprocal_fcompose[OF hP], subst proots_count_times)
subgoal using h0 by (metis hP reciprocal_0_iff reciprocal_fcompose)
subgoal using h0' by (auto simp: proots_count_monom) done
alsohave"... = proots_count P {x. inverse x ∈ A}" proof (rule proots_fcompose_bij_eq[symmetric]) show"bij_betw (λx. poly 1 x / poly [:0, 1:] x) A {x. inverse x ∈ A}" proof (rule bij_betw_imageI) show"inj_on (λx. poly 1 x / poly [:0, 1:] x) A" by (simp add: inj_on_def)
show"(λx. poly 1 x / poly [:0, 1:] x) ` A = {x. inverse x ∈ A}" proof show"(λx. poly 1 x / poly [:0, 1:] x) ` A ⊆ {x. inverse x ∈ A}" by force show"{x. inverse x ∈ A} ⊆ (λx. poly 1 x / poly [:0, 1:] x) ` A" proof fix x assume"x ∈ {x::'a. inverse x ∈ A}" hence"x = poly 1 (inverse x) / poly [:0, 1:] (inverse x) ∧ inverse x ∈ A" by (auto simp: inverse_eq_divide) thus"x ∈ (λx. poly 1 x / poly [:0, 1:] x) ` A"by blast qed qed qed next show"∀c. 1 ≠ smult c [:0, 1:]" by (metis coeff_pCons_0 degree_1 lead_coeff_1 pCons_0_0 pcompose_0'
pcompose_smult smult_0_right zero_neq_one) qed (auto simp: assms infinite_UNIV_char_0) finallyshow ?thesis by linarith qed
lemma proots_count_reciprocal': fixes P::"real poly" assumes hP: "degree P ≤ p"and h0: "P ≠ 0" shows"proots_count P {x. 0 < x ∧ x < 1} = proots_count (reciprocal_poly p P) {x. 1 < x}" proof (subst proots_count_reciprocal) show"proots_count P {x. 0 < x ∧ x < 1} = proots_count P {x. inverse x ∈ Collect ((<) 1)}" apply (rule arg_cong[of _ _ "proots_count P"]) using one_less_inverse_iff by fastforce qed (use assms in auto)
lemma proots_count_pos: assumes"proots_count P S > 0" shows"∃x ∈ S. poly P x = 0" proof (rule ccontr) assume"¬ (∃x∈S. poly P x = 0)" hence"∧x. x ∈ S ==> poly P x ≠ 0"by blast hence"∧x. x ∈ S ==> order x P = 0"using order_0I by blast hence"proots_count P S = 0"by (force simp: proots_count_def) thus False using assms by presburger qed
lemma proots_count_of_root_set: assumes"P ≠ 0""R ⊆ S"and"∧x. x∈R ==> poly P x = 0" shows"proots_count P S ≥ card R" proof - have"card R ≤ card (proots_within P S)" apply (rule card_mono)
subgoal using assms by auto
subgoal using assms(2) assms(3) by (auto simp: proots_within_def) done alsohave"... ≤ proots_count P S" by (rule card_proots_within_leq[OF assms(1)]) finallyshow ?thesis . qed
lemma proots_count_of_root: assumes"P ≠ 0""x∈S""poly P x = 0" shows"proots_count P S > 0" using proots_count_of_root_set[of P "{x}" S] assms by force
lemma changes_replicate_0: shows"changes (replicate n 0) = 0" apply (induction n) by auto
lemma changes_append_replicate_0: "changes (xs @ replicate n 0) = changes xs" proof (induction xs rule: changes.induct) case (2 uu) thenshow ?case apply (induction n) by auto qed (auto simp: changes_replicate_0)
lemma changes_scale_Cons: fixes xs:: "real list"assumes hs: "s > 0" shows"changes (s * x # xs) = changes (x # xs)" apply (induction xs rule: changes.induct) using assms by (auto simp: mult_less_0_iff zero_less_mult_iff)
lemma changes_scale: fixes xs::"('a::linordered_idom) list" assumes hs: "∧i. i < n ==> s i > 0"and hn: "length xs ≤ n" shows"changes [s i * (nth_default 0 xs i). i ← [0..<n]] = changes xs" using assms proof (induction xs arbitrary: s n rule: changes.induct) case1 show ?caseby (auto simp: map_replicate_const changes_replicate_0) next case (2 uu) show ?case proof (cases n) case0 thenshow ?thesis by force next case (Suc m) hence"map (λi. s i * nth_default 0 [uu] i) [0..<n] = [s 0 * uu] @ replicate m 0" proof (induction m arbitrary: n) case (Suc m n) from Suc have"map (λi. s i * nth_default 0 [uu] i) [0..<Suc m] = [s 0 * uu] @ replicate m 0" by meson hence"map (λi. s i * nth_default 0 [uu] i) [0..<n] = [s 0 * uu] @ replicate m 0 @ [0]" using Suc by auto alsohave"... = [s 0 * uu] @ replicate (Suc m) 0" by (simp add: replicate_append_same) finallyshow ?case . qed fastforce thenshow ?thesis by (metis changes.simps(2) changes_append_replicate_0) qed next case (3 a b xs s n) obtain m where hn: "n = m + 2" using3(5) by (metis add_2_eq_Suc' diff_diff_cancel diff_le_self length_Suc_conv
nat_arith.suc1 ordered_cancel_comm_monoid_diff_class.add_diff_inverse) hence h: "map (λi. s i * nth_default 0 (a # b # xs) i) [0..<n] = s 0 * a # s 1 * b # map (λi. (λ i. s (i+2)) i * nth_default 0 (xs) i) [0..<m]" apply (induction m arbitrary: n) by auto
consider (neg)"a*b<0" | (nil)"b=0" | (pos)"¬a*b<0 ∧¬b=0"by linarith thenshow ?case proof (cases) case neg hence "changes (map (λi. s i * nth_default 0 (a # b # xs) i) [0..<n]) = 1 + changes (s 1 * b # map (λi. (λ i. s (i+2)) i * nth_default 0 (xs) i) [0..<m])" apply (subst h) using3(4)[of 0] 3(4)[of 1] hn by (metis (no_types, lifting) changes.simps(3) mult_less_0_iff pos2
mult_pos_pos one_less_numeral_iff semiring_norm(76) trans_less_add2) alsohave "... = 1 + changes (map (λi. s (Suc i) * nth_default 0 (b # xs) i) [0..<Suc m])" apply (rule arg_cong[of _ _ "λ x. 1 + changes x"]) apply (induction m) by auto alsohave"... = changes (a # b # xs)" apply (subst 3(1)[OF neg]) using3 neg hn by auto finallyshow ?thesis . next case nil hence"changes (map (λi. s i * nth_default 0 (a # b # xs) i) [0..<n]) = changes (s 0 * a # map (λi. (λ i. s (i+2)) i * nth_default 0 (xs) i) [0..<m])" apply (subst h) using3(4)[of 0] 3(4)[of 1] hn by auto alsohave "... = changes (map (λi. s (if i = 0 then 0 else Suc i) * nth_default 0 (a # xs) i) [0..<Suc m])" apply (rule arg_cong[of _ _ "λ x. changes x"]) apply (induction m) by auto alsohave"... = changes (a # b # xs)" apply (subst 3(2)) using3 nil hn by auto finallyshow ?thesis . next case pos hence"changes (map (λi. s i * nth_default 0 (a # b # xs) i) [0..<n]) = changes (s 1 * b # map (λi. (λ i. s (i+2)) i * nth_default 0 (xs) i) [0..<m])" apply (subst h) using3(4)[of 0] 3(4)[of 1] hn by (metis (no_types, lifting) changes.simps(3) divisors_zero
mult_less_0_iff nat_1_add_1 not_square_less_zero one_less_numeral_iff
semiring_norm(76) trans_less_add2 zero_less_mult_pos zero_less_two) alsohave "... = changes (map (λi. s (Suc i) * nth_default 0 (b # xs) i) [0..<Suc m])" apply (rule arg_cong[of _ _ "λ x. changes x"]) apply (induction m) by auto alsohave"... = changes (a # b # xs)" apply (subst 3(3)) using3 pos hn by auto finallyshow ?thesis . qed qed
lemma changes_rev_about: fixes xs:: "'a::linordered_idom list" shows"changes (replicate (p - length xs) 0 @ rev xs) = changes xs" proof (induction p) case (Suc p) thenshow ?case proof cases assume"¬Suc p ≤ length xs" hence"Suc p - length xs = Suc (p - length xs)"by linarith thus ?caseusing Suc.IH changes_rev by auto qed (auto simp: changes_rev) qed (auto simp: changes_rev)
lemma changes_add_between: assumes"a ≤ x"and"x ≤ b" shows"changes (as @ [a, b] @ bs) = changes (as @ [a, x, b] @ bs)" proof (induction as rule: changes.induct) case1 thenshow ?caseusing assms apply (induction bs) by (auto simp: mult_less_0_iff) next case (2 c) thenshow ?case apply (induction bs) using assms by (auto simp: mult_less_0_iff) next case (3 y z as) thenshow ?case using assms by (auto simp: mult_less_0_iff) qed
lemma changes_all_nonneg: assumes"∧i. nth_default 0 xs i ≥ 0"shows"changes xs = 0" using assms proof (induction xs rule: changes.induct) case (3 x1 x2 xs) moreoverassume"(∧i. 0 ≤ nth_default 0 (x1 # x2 # xs) i)" moreoverhence"(∧i. 0 ≤ nth_default 0 (x1 # xs) i)" and"(∧i. 0 ≤ nth_default 0 (x2 # xs) i)" and"x1 * x2 ≥ 0" proof - fix i assume h:"(∧i. 0 ≤ nth_default 0 (x1 # x2 # xs) i)" show"0 ≤ nth_default 0 (x1 # xs) i" proof (cases i) case0 thenshow ?thesis using h[of 0] by force next case (Suc nat) thenshow ?thesis using h[of "Suc (Suc nat)"] by force qed show"0 ≤ nth_default 0 (x2 # xs) i"using h[of "Suc i"] by simp show"x1*x2 ≥ 0"using h[of 0] h[of 1] by simp qed ultimatelyshow ?caseby auto qed auto
lemma changes_increasing: assumes"∧i. i < length xs - 1 ==> xs ! (i + 1) ≥ xs ! i" and"length xs > 1" and"hd xs < 0" and"last xs > 0" shows"changes xs = 1" using assms proof (induction xs rule:changes.induct) case (3 x y xs)
consider (neg)"x*y<0" | (nil)"y=0" | (pos)"¬x*y<0 ∧¬y=0"by linarith thenshow ?case proof cases case neg have"changes (y # xs) = 0" proof (rule changes_all_nonneg) fix i show"0 ≤ nth_default 0 (y # xs) i" proof (cases "i < length (y # xs)") case True thenshow ?thesis using3(4)[of i] apply (induction i)
subgoal using3(6) neg by (fastforce simp: mult_less_0_iff)
subgoal using3(4) by (auto simp: nth_default_def) done next case False thenshow ?thesis by (simp add: nth_default_def) qed qed thus"changes (x # y # xs) = 1" using neg by force next case nil hence"xs ≠ []"using3(7) by force have h: "∧i. i < length (x # xs) - 1 ==> (x # xs) ! i ≤ (x # xs) ! (i + 1)" proof - fix i assume"i < length (x # xs) - 1" thus"(x # xs) ! i ≤ (x # xs) ! (i + 1)" apply (cases "i = 0")
subgoal using3(4)[of 0] 3(4)[of 1] ‹xs ≠ []›by force using3(4)[of "i+1"] by simp qed have"changes (x # xs) = 1" apply (rule 3(2)) using nil h ‹xs ≠ []›3(6) 3(7) by auto thus ?thesis using nil by force next case pos hence"xs ≠ []"using3(6) 3(7) by (fastforce simp: mult_less_0_iff) have"changes (y # xs) = 1" proof (rule 3(3)) show"¬ x * y < 0""y ≠ 0" using pos by auto show"∧i. i < length (y # xs) - 1 ==> (y # xs) ! i ≤ (y # xs) ! (i + 1)" using3(4) by force show"1 < length (y # xs)" using‹xs ≠ []›by force show"hd (y # xs) < 0" using3(6) pos by (force simp: mult_less_0_iff) show"0 < last (y # xs)" using3(7) by force qed thus ?thesis using pos by auto qed qed auto
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.