section"Misc results for polynomials and sign variations"
theory BF_Misc imports "HOL-Computational_Algebra.Polynomial_Factorial" "HOL-Computational_Algebra.Fundamental_Theorem_Algebra"
Sturm_Tarski.Sturm_Tarski begin
subsection‹Induction on polynomial roots›
(*adapted from the poly_root_induct in Polynomial.thy.*) lemma poly_root_induct_alt [case_names 0 no_proots root]: fixes p :: "'a :: idom poly" assumes"Q 0" assumes"∧p. (∧a. poly p a ≠ 0) ==> Q p" assumes"∧a p. Q p ==> Q ([:-a, 1:] * p)" shows"Q p" proof (induction"degree p" arbitrary: p rule: less_induct) case (less p) have ?case when "p=0"using‹Q 0› that by auto moreoverhave ?case when "∄a. poly p a = 0" using assms(2) that by blast moreoverhave ?case when "∃a. poly p a = 0""p≠0" proof - obtain a where"poly p a =0"using‹∃a. poly p a = 0›by auto thenobtain q where pq:"p= [:-a,1:] * q"by (meson dvdE poly_eq_0_iff_dvd) thenhave"q≠0"using‹p≠0›by auto thenhave"degree q<degree p"unfolding pq by (subst degree_mult_eq,auto) thenhave"Q q"using less by auto thenshow ?caseusing assms(3) unfolding pq by auto qed ultimatelyshow ?caseby auto qed
lemma smult_normalize_field_eq: fixes p::"'a::{field,semidom_divide_unit_factor} poly" shows"p = smult (lead_coeff p) (normalize p)" proof (rule poly_eqI) fix n have"unit_factor (lead_coeff p) = lead_coeff p" by (metis dvd_field_iff is_unit_unit_factor unit_factor_0) thenshow"coeff p n = coeff (smult (lead_coeff p) (normalize p)) n" by simp qed
lemma lead_coeff_gcd_field: fixes p q::"'a::field_gcd poly" assumes"p≠0 ∨ q≠0" shows"lead_coeff (gcd p q) = 1" using assms by (metis gcd.normalize_idem gcd_eq_0_iff lead_coeff_normalize_field)
lemma poly_gcd_0_iff: "poly (gcd p q) x = 0 ⟷ poly p x=0 ∧ poly q x=0" by (simp add:poly_eq_0_iff_dvd)
lemma degree_eq_oneE: fixes p :: "'a::zero poly" assumes"degree p = 1" obtains a b where"p = [:a,b:]""b≠0" proof - obtain a b q where p:"p=pCons a (pCons b q)" by (metis pCons_cases) with assms have"q=0"by (cases "q = 0") simp_all with p have"p=[:a,b:]"by auto moreoverthenhave"b≠0"using assms by auto ultimatelyshow ?thesis .. qed
subsection‹More results about sign variations (i.e. @{term changes}›
lemma changes_0[simp]:"changes (0#xs) = changes xs" by (cases xs) auto
lemma changes_Cons:"changes (x#xs) = (if filter (λx. x≠0) xs = [] then 0 else if x* hd (filter (λx. x≠0) xs) < 0 then 1 + changes xs else changes xs)" apply (induct xs) by auto
lemma changes_append: assumes"xs≠ [] ∧ ys≠ [] ⟶ (last xs = hd ys ∧ last xs≠0)" shows"changes (xs@ys) = changes xs + changes ys" using assms proof (induct xs) case Nil thenshow ?caseby simp next case (Cons a xs) have ?case when "xs=[]" using that Cons apply (cases ys) by auto moreoverhave ?case when "ys=[]" using that Cons by auto moreoverhave ?case when "xs≠[]""ys≠[]" proof - have"filter (λx. x ≠ 0) xs ≠[]" using that Cons apply auto by (metis (mono_tags, lifting) filter.simps(1) filter.simps(2) filter_append snoc_eq_iff_butlast) thenhave"changes (a # xs @ ys) = changes (a # xs) + changes ys" apply (subst (12) changes_Cons) using that Cons by auto thenshow ?thesis by auto qed ultimatelyshow ?caseby blast qed
lemma changes_drop_dup: assumes"xs≠ []""ys≠ [] ⟶ last xs=hd ys" shows"changes (xs@ys) = changes (xs@ tl ys)" using assms proof (induct xs) case Nil thenshow ?caseby simp next case (Cons a xs) have ?case when "ys=[]" using that by simp moreoverhave ?case when "ys≠[]""xs=[]" using that Cons apply auto by (metis changes.simps(3) list.exhaust_sel not_square_less_zero) moreoverhave ?case when "ys≠[]""xs≠[]" proof -
define ts ts' where"ts = filter (λx. x ≠ 0) (xs @ ys)" and"ts' = filter (λx. x ≠ 0) (xs @ tl ys)" have"(ts = [] ⟷ ts' = []) ∧ hd ts = hd ts'" proof (cases "filter (λx. x ≠ 0) xs = []") case True thenhave"last xs = 0"using‹xs≠[]› by (metis (mono_tags, lifting) append_butlast_last_id append_is_Nil_conv
filter.simps(2) filter_append list.simps(3)) thenhave"hd ys=0"using Cons(3)[rule_format, OF ‹ys≠[]›] ‹xs≠[]›by auto thenhave"filter (λx. x ≠ 0) ys = filter (λx. x ≠ 0) (tl ys)" by (metis (mono_tags, lifting) filter.simps(2) list.exhaust_sel that(1)) thenshow ?thesis unfolding ts_def ts'_defby auto next case False thenshow ?thesis unfolding ts_def ts'_defby auto qed moreoverhave"changes (xs @ ys) = changes (xs @ tl ys)" apply (rule Cons(1)) using that Cons(3) by auto moreoverhave"changes (a # xs @ ys) = (if ts = [] then 0 else if a * hd ts < 0 then 1 + changes (xs @ ys) else changes (xs @ ys))" using changes_Cons[of a "xs @ ys",folded ts_def] . moreoverhave"changes (a # xs @ tl ys) = (if ts' = [] then 0 else if a * hd ts' < 0 then 1 + changes (xs @ tl ys) else changes (xs @ tl ys))" using changes_Cons[of a "xs @ tl ys",folded ts'_def] . ultimatelyshow ?thesis by auto qed ultimatelyshow ?caseby blast qed
(*FIXME: not duplicate*) lemma of_real_poly_eq_iff [simp]: "map_poly of_real p = map_poly of_real q ⟷ p = q" by (auto simp: poly_eq_iff coeff_map_poly)
(*FIXME: not duplicate*) lemma of_real_poly_eq_0_iff [simp]: "map_poly of_real p = 0 ⟷ p = 0" by (auto simp: poly_eq_iff coeff_map_poly)
subsection‹More about @{term order}›
lemma order_multiplicity_eq: assumes"p≠0" shows"order a p = multiplicity [:-a,1:] p" by (metis assms multiplicity_eqI order_1 order_2)
lemma order_gcd: assumes"p≠0""q≠0" shows"order x (gcd p q) = min (order x p) (order x q)" proof - have"prime [:- x, 1:]" apply (auto simp add: prime_elem_linear_poly normalize_poly_def intro!:primeI) by (simp add: pCons_one) thenshow ?thesis using assms by (auto simp add:order_multiplicity_eq intro:multiplicity_gcd) qed
lemma order_linear[simp]: "order x [:-a,1:] = (if x=a then 1 else 0)" by (auto simp add:order_power_n_n[where n=1,simplified] order_0I)
lemma map_poly_order_of_real: assumes"p≠0" shows"order (of_real t) (map_poly of_real p) = order t p"using assms proof (induct p rule:poly_root_induct_alt) case0 thenshow ?caseby simp next case (no_proots p) thenhave"order t p = 0"using order_root by blast moreoverhave"poly (map_poly of_real p) (of_real x) ≠0"for x apply (subst of_real_poly_map_poly[symmetric]) using no_proots order_root by simp thenhave"order (of_real t) (map_poly of_real p) = 0" using order_root by blast ultimatelyshow ?caseby auto next case (root a p)
define a1 where"a1=[:-a,1:]" have [simp]:"a1≠0""p≠0"unfolding a1_def using root(2) by auto have"order (of_real t) (map_poly of_real a1) = order t a1" unfolding a1_def by simp thenshow ?case apply (fold a1_def) by (simp add:order_mult root) qed
lemma order_pcompose: assumes"pcompose p q≠0" shows"order x (pcompose p q) = order x (q-[:poly q x:]) * order (poly q x) p" using‹pcompose p q≠0› proof (induct p rule:poly_root_induct_alt) case0 thenshow ?caseby simp next case (no_proots p) have"order x (p ∘p q) = 0" apply (rule order_0I) using no_proots by (auto simp:poly_pcompose) moreoverhave"order (poly q x) p = 0" apply (rule order_0I) using no_proots by (auto simp:poly_pcompose) ultimatelyshow ?caseby auto next case (root a p)
define a1 where"a1=[:-a,1:]" have [simp]: "a1≠0""p≠0""a1 ∘p q ≠0""p ∘p q ≠ 0"
subgoal using root(2) unfolding a1_def by simp
subgoal using root(2) by auto using root(2) by (fold a1_def,auto simp:pcompose_mult) have"order x ((a1 * p) ∘p q) = order x (a1 ∘p q) + order x (p ∘p q)" unfolding pcompose_mult by (auto simp: order_mult) alsohave"... = order x (q-[:poly q x:]) * (order (poly q x) a1 + order (poly q x) p)" proof - have"order x (a1 ∘p q) = order x (q-[:poly q x:]) * order (poly q x) a1" unfolding a1_def apply (auto simp: pcompose_pCons algebra_simps diff_conv_add_uminus ) by (simp add: order_0I) moreoverhave"order x (p ∘p q) = order x (q - [:poly q x:]) * order (poly q x) p" apply (rule root.hyps) by auto ultimatelyshow ?thesis by (auto simp:algebra_simps) qed alsohave"... = order x (q - [:poly q x:]) * order (poly q x) (a1 * p)" by (auto simp:order_mult) finallyshow ?caseunfolding a1_def . qed
subsection‹Polynomial roots / zeros›
definition proots_within::"'a::comm_semiring_0 poly ==> 'a set ==> 'a set"where "proots_within p s = {x∈s. poly p x=0}"
abbreviation proots::"'a::comm_semiring_0 poly ==> 'a set"where "proots p ≡ proots_within p UNIV"
lemma proots_def: "proots p = {x. poly p x=0}" unfolding proots_within_def by auto
lemma proots_within_empty[simp]: "proots_within p {} = {}"unfolding proots_within_def by auto
lemma proots_within_0[simp]: "proots_within 0 s = s"unfolding proots_within_def by auto
lemma proots_withinI[intro,simp]: "poly p x=0 ==> x∈s ==> x∈proots_within p s" unfolding proots_within_def by auto
lemma proots_within_iff[simp]: "x∈proots_within p s ⟷ poly p x=0 ∧ x∈s" unfolding proots_within_def by auto
lemma proots_within_union: "proots_within p A ∪ proots_within p B = proots_within p (A ∪ B)" unfolding proots_within_def by auto
lemma proots_within_times: fixes s::"'a::{semiring_no_zero_divisors,comm_semiring_0} set" shows"proots_within (p*q) s = proots_within p s ∪ proots_within q s" unfolding proots_within_def by auto
lemma proots_within_gcd: fixes s::"'a::{factorial_ring_gcd,semiring_gcd_mult_normalize} set" shows"proots_within (gcd p q) s= proots_within p s ∩ proots_within q s" unfolding proots_within_def by (auto simp add: poly_eq_0_iff_dvd)
lemma proots_within_inter: "NO_MATCH UNIV s ==> proots_within p s = proots p ∩ s" unfolding proots_within_def by auto
lemma proots_within_proots[simp]: "proots_within p s ⊆ proots p" unfolding proots_within_def by auto
lemma finite_proots[simp]: fixes p :: "'a::idom poly" shows"p≠0 ==> finite (proots_within p s)" unfolding proots_within_def using poly_roots_finite by fast
lemma proots_within_pCons_1_iff: fixes a::"'a::idom" shows"proots_within [:-a,1:] s = (if a∈s then {a} else {})" "proots_within [:a,-1:] s = (if a∈s then {a} else {})" by (cases "a∈s",auto)
lemma proots_within_uminus[simp]: fixes p :: "'a::comm_ring poly" shows"proots_within (- p) s = proots_within p s" by auto
lemma proots_within_smult: fixes a::"'a::{semiring_no_zero_divisors,comm_semiring_0}" assumes"a≠0" shows"proots_within (smult a p) s = proots_within p s" unfolding proots_within_def using assms by auto
(*counting the number of proots WITH MULTIPLICITIES within a set*) definition proots_count::"'a::idom poly ==> 'a set ==> nat"where "proots_count p s = (∑r∈proots_within p s. order r p)"
lemma proots_count_emtpy[simp]:"proots_count p {} = 0" unfolding proots_count_def by auto
lemma proots_count_times: fixes s :: "'a::idom set" assumes"p*q≠0" shows"proots_count (p*q) s = proots_count p s + proots_count q s" proof -
define pts where"pts=proots_within p s"
define qts where"qts=proots_within q s" have [simp]: "finite pts""finite qts" using‹p*q≠0›unfolding pts_def qts_def by auto have"(∑r∈pts ∪ qts. order r p) = (∑r∈pts. order r p)" proof (rule comm_monoid_add_class.sum.mono_neutral_cong_right,simp_all) show"∀i∈pts ∪ qts - pts. order i p = 0" unfolding pts_def qts_def proots_within_def using order_root by fastforce qed moreoverhave"(∑r∈pts ∪ qts. order r q) = (∑r∈qts. order r q)" proof (rule comm_monoid_add_class.sum.mono_neutral_cong_right,simp_all) show"∀i∈pts ∪ qts - qts. order i q = 0" unfolding pts_def qts_def proots_within_def using order_root by fastforce qed ultimatelyshow ?thesis unfolding proots_count_def apply (simp add:proots_within_times order_mult[OF ‹p*q≠0›] sum.distrib) apply (fold pts_def qts_def) by auto qed
lemma proots_count_power_n_n: shows"proots_count ([:- a, 1:]^n) s = (if a∈s ∧ n>0 then n else 0)" proof - have"proots_within ([:- a, 1:] ^ n) s= (if a∈s ∧ n>0 then {a} else {})" unfolding proots_within_def by auto thus ?thesis unfolding proots_count_def using order_power_n_n by auto qed
lemma degree_proots_count: fixes p::"complex poly" shows"degree p = proots_count p UNIV" proof (induct "degree p" arbitrary:p ) case0 thenobtain c where c_def:"p=[:c:]"using degree_eq_zeroE by auto thenshow ?caseunfolding proots_count_def apply (cases "c=0") by (auto intro!:sum.infinite simp add:infinite_UNIV_char_0 order_0I) next case (Suc n) thenhave"degree p≠0"and"p≠0"by auto obtain z where"poly p z = 0" using Fundamental_Theorem_Algebra.fundamental_theorem_of_algebra ‹degree p≠0› constant_degree[of p] by auto
define onez where"onez=[:-z,1:]" have [simp]: "onez≠0""degree onez = 1"unfolding onez_def by auto obtain q where q_def:"p= onez * q" using poly_eq_0_iff_dvd ‹poly p z = 0› dvdE unfolding onez_def by blast hence"q≠0"using‹p≠0›by auto hence"n=degree q"using degree_mult_eq[of onez q] ‹Suc n = degree p› apply (fold q_def) by auto hence"degree q = proots_count q UNIV"using Suc.hyps(1) by simp moreoverhave" Suc 0 = proots_count onez UNIV" unfolding onez_def using proots_count_power_n_n[of z 1 UNIV] by auto ultimatelyshow ?case unfolding q_def using degree_mult_eq[of onez q] proots_count_times[of onez q UNIV] ‹q≠0› by auto qed
lemma proots_count_smult: fixes a::"'a::{semiring_no_zero_divisors,idom}" assumes"a≠0" shows"proots_count (smult a p) s= proots_count p s" proof (cases "p=0") case True thenshow ?thesis by auto next case False thenshow ?thesis unfolding proots_count_def using order_smult[OF assms] proots_within_smult[OF assms] by auto qed
lemma proots_count_pCons_1_iff: fixes a::"'a::idom" shows"proots_count [:-a,1:] s = (if a∈s then 1 else 0)" unfolding proots_count_def by (cases "a∈s",auto simp add:proots_within_pCons_1_iff order_power_n_n[of _ 1,simplified])
lemma proots_count_uminus[simp]: "proots_count (- p) s = proots_count p s" unfolding proots_count_def by simp
lemma card_proots_within_leq: assumes"p≠0" shows"proots_count p s ≥ card (proots_within p s)"using assms proof (induct rule:poly_root_induct[of _ "λx. x∈s"]) case0 thenshow ?caseunfolding proots_within_def proots_count_def by auto next case (no_roots p) thenhave"proots_within p s = {}"by auto thenshow ?caseunfolding proots_count_def by auto next case (root a p) have"card (proots_within ([:- a, 1:] * p) s) ≤ card (proots_within [:- a, 1:] s)+card (proots_within p s)" unfolding proots_within_times by (auto simp add:card_Un_le) alsohave"... ≤ 1+ proots_count p s" proof - have"card (proots_within [:- a, 1:] s) ≤ 1" proof (cases "a∈s") case True thenhave"proots_within [:- a, 1:] s = {a}"by auto thenshow ?thesis by auto next case False thenhave"proots_within [:- a, 1:] s = {}"by auto thenshow ?thesis by auto qed moreoverhave"card (proots_within p s) ≤ proots_count p s" apply (rule root.hyps) using root by auto ultimatelyshow ?thesis by auto qed alsohave"... = proots_count ([:- a,1:] * p) s" apply (subst proots_count_times)
subgoal by (metis mult_eq_0_iff pCons_eq_0_iff root.prems zero_neq_one) using root by (auto simp add:proots_count_pCons_1_iff) finallyhave"card (proots_within ([:- a, 1:] * p) s) ≤ proots_count ([:- a, 1:] * p) s" . thenshow ?case by (metis (no_types, opaque_lifting) add.inverse_inverse add.inverse_neutral minus_pCons
mult_minus_left proots_count_uminus proots_within_uminus) qed
(*FIXME: not duplicate*) lemma proots_count_0_imp_empty: assumes"proots_count p s=0""p≠0" shows"proots_within p s = {}" proof - have"card (proots_within p s) = 0" using card_proots_within_leq[OF ‹p≠0›,of s] ‹proots_count p s=0›by auto moreoverhave"finite (proots_within p s)"using‹p≠0›by auto ultimatelyshow ?thesis by auto qed
lemma proots_count_leq_degree: assumes"p≠0" shows"proots_count p s≤ degree p"using assms proof (induct rule:poly_root_induct[of _ "λx. x∈s"]) case0 thenshow ?caseby auto next case (no_roots p) thenhave"proots_within p s = {}"by auto thenshow ?caseunfolding proots_count_def by auto next case (root a p) have"proots_count ([:a, - 1:] * p) s = proots_count [:a, - 1:] s + proots_count p s" apply (subst proots_count_times) using root by auto alsohave"... = 1 + proots_count p s" proof - have"proots_count [:a, - 1:] s =1" by (metis (no_types, lifting) add.inverse_inverse add.inverse_neutral minus_pCons
proots_count_pCons_1_iff proots_count_uminus root.hyps(1)) thenshow ?thesis by auto qed alsohave"... ≤ degree ([:a,-1:] * p)" apply (subst degree_mult_eq)
subgoal by auto
subgoal using root by auto
subgoal using root by (simp add: ‹p ≠ 0›) done finallyshow ?case . qed
(*TODO: not a duplicate*) lemma proots_count_union_disjoint: assumes"A ∩ B = {}""p≠0" shows"proots_count p (A ∪ B) = proots_count p A + proots_count p B" unfolding proots_count_def apply (subst proots_within_union[symmetric]) apply (subst sum.union_disjoint) using assms by auto
lemma proots_count_cong: assumes order_eq:"∀x∈s. order x p = order x q"and"p≠0"and"q≠0" shows"proots_count p s = proots_count q s"unfolding proots_count_def proof (rule sum.cong) have"poly p x = 0 ⟷ poly q x = 0" when "x∈s"for x using order_eq that by (simp add: assms(2) assms(3) order_root) thenshow"proots_within p s = proots_within q s"by auto show"∧x. x ∈ proots_within q s ==> order x p = order x q" using order_eq by auto qed
lemma proots_count_of_real: assumes"p≠0" shows"proots_count (map_poly of_real p) ((of_real::_==>'a::{real_algebra_1,idom}) ` s) = proots_count p s" proof -
define k where"k=(of_real::_==>'a)" have"proots_within (map_poly of_real p) (k ` s) =k ` (proots_within p s)" unfolding proots_within_def k_def by (auto simp add:of_real_poly_map_poly[symmetric]) thenhave"proots_count (map_poly of_real p) (k ` s) = (∑r∈k ` (proots_within p s). order r (map_poly of_real p))" unfolding proots_count_def by simp alsohave"... = sum ((λr. order r (map_poly of_real p)) ∘ k) (proots_within p s)" apply (subst sum.reindex) unfolding k_def by (auto simp add: inj_on_def) alsohave"... = proots_count p s"unfolding proots_count_def apply (rule sum.cong) unfolding k_def comp_def using‹p≠0›by (auto simp add:map_poly_order_of_real) finallyshow ?thesis unfolding k_def . qed
(*Is field really necessary here?*) lemma proots_pcompose: fixes p q::"'a::field poly" assumes"p≠0""degree q=1" shows"proots_count (pcompose p q) s = proots_count p (poly q ` s)" proof - obtain a b where ab:"q=[:a,b:]""b≠0" using‹degree q=1› degree_eq_oneE by metis
define f where"f=(λy. (y-a)/b)" have f_eq:"f (poly q x) = x""poly q (f x) = x"for x unfolding f_def using ab by auto have"proots_count (p ∘p q) s = (∑r∈ f ` proots_within p (poly q ` s). order r (p∘p q))" unfolding proots_count_def apply (rule arg_cong2[where f =sum]) apply (auto simp:poly_pcompose proots_within_def f_eq) by (metis (mono_tags, lifting) f_eq(1) image_eqI mem_Collect_eq) alsohave"... = (∑x∈proots_within p (poly q ` s). order (f x) (p ∘p q))" apply (subst sum.reindex)
subgoal unfolding f_def inj_on_def using‹b≠0›by auto by simp alsohave"... = (∑x∈proots_within p (poly q ` s). order x p)" proof - have"p ∘p q ≠ 0"using assms(1) assms(2) pcompose_eq_0 by force moreoverhave"order (f x) (q - [:x:]) = 1"for x proof - have"order (f x) (q - [:x:]) = order (f x) (smult b [:-((x - a) / b),1:])" unfolding f_def using ab by auto alsohave"... = 1" apply (subst order_smult) using‹b≠0›unfolding f_def by auto finallyshow ?thesis . qed ultimatelyhave"order (f x) (p ∘p q) = order x p"for x apply (subst order_pcompose) using f_eq by auto thenshow ?thesis by auto qed alsohave"... = proots_count p (poly q ` s)" unfolding proots_count_def by auto finallyshow ?thesis . qed
subsection‹Composition of a polynomial and a rational function›
(*composition of a polynomial and a rational function. Maybe a more general version in the future?*) definition fcompose::"'a ::field poly ==> 'a poly ==> 'a poly ==> 'a poly"where "fcompose p q r = fst (fold_coeffs (λa (c,d). (d*[:a:] + q * c,r*d)) p (0,1))"
lemma fcompose_0 [simp]: "fcompose 0 q r = 0" by (simp add: fcompose_def)
lemma fcompose_const[simp]:"fcompose [:a:] q r = [:a:]" unfolding fcompose_def by (cases "a=0") auto
lemma fcompose_pCons: "fcompose (pCons a p) q1 q2 = smult a (q2^(degree (pCons a p))) + q1 * fcompose p q1 q2" proof (cases "p=0") case False
define ff where"ff=(λa (c, d). (d * [:a:] + q1 * c, q2 * d))"
define fc where"fc=fold_coeffs ff p (0, 1)" have snd_ff:"snd fc = (if p=0 then 1 else q2^(degree p + 1))"unfolding fc_def apply (induct p)
subgoal by simp
subgoal for a p by (auto simp add:ff_def split:if_splits prod.splits) done
have"fcompose (pCons a p) q1 q2 = fst (fold_coeffs ff (pCons a p) (0, 1))" unfolding fcompose_def ff_def by simp alsohave"... = fst (ff a fc)" using False unfolding fc_def by auto alsohave"... = snd fc * [:a:] + q1 * fst fc" unfolding ff_def by (auto split:prod.splits) alsohave"... = smult a (q2^(degree (pCons a p))) + q1 * fst fc" using snd_ff False by auto alsohave"... = smult a (q2^(degree (pCons a p))) + q1 * fcompose p q1 q2" unfolding fc_def ff_def fcompose_def by simp finallyshow ?thesis . qed simp
lemma fcompose_uminus: "fcompose (-p) q r = - fcompose p q r" by (induct p) (auto simp:fcompose_pCons)
lemma fcompose_add_less: assumes"degree p1 > degree p2" shows"fcompose (p1+p2) q1 q2 = fcompose p1 q1 q2 + q2^(degree p1-degree p2) * fcompose p2 q1 q2" using assms proof (induction p1 p2 rule: poly_induct2) case (pCons a1 p1 a2 p2) have ?case when "p2=0" using that by (simp add:fcompose_pCons smult_add_left) moreoverhave ?case when "p2≠0""¬ degree p2 < degree p1" using that pCons(2) by auto moreoverhave ?case when "p2≠0""degree p2< degree p1" proof -
define d1 d2 where"d1=degree (pCons a1 p1)"and"d2=degree (pCons a2 p2) "
define fp1 fp2 where"fp1= fcompose p1 q1 q2"and"fp2=fcompose p2 q1 q2"
have"fcompose (pCons a1 p1 + pCons a2 p2) q1 q2 = fcompose (pCons (a1+a2) (p1+p2)) q1 q2" by simp alsohave"... = smult (a1 + a2) (q2 ^ d1) + q1 * fcompose (p1 + p2) q1 q2" proof - have"degree (pCons (a1 + a2) (p1 + p2)) = d1" unfolding d1_def using that degree_add_eq_left by fastforce thenshow ?thesis unfolding fcompose_pCons by simp qed alsohave"... = smult (a1 + a2) (q2 ^ d1) + q1 * (fp1 + q2 ^ (d1 - d2) * fp2)" proof - have"degree p1 - degree p2 = d1 - d2" unfolding d1_def d2_def using that by simp thenshow ?thesis unfolding pCons(1)[OF that(2),folded fp1_def fp2_def] by simp qed alsohave"... = fcompose (pCons a1 p1) q1 q2 + q2 ^ (d1 - d2) * fcompose (pCons a2 p2) q1 q2" proof - have"d1 > d2"unfolding d1_def d2_def using that by auto thenshow ?thesis unfolding fcompose_pCons apply (fold d1_def d2_def fp1_def fp2_def) by (simp add:algebra_simps smult_add_left power_add[symmetric]) qed finallyshow ?thesis unfolding d1_def d2_def . qed ultimatelyshow ?caseby blast qed simp
lemma fcompose_add_eq: assumes"degree p1 = degree p2" shows"q2^(degree p1 - degree (p1+p2)) * fcompose (p1+p2) q1 q2 = fcompose p1 q1 q2 + fcompose p2 q1 q2" using assms proof (induction p1 p2 rule: poly_induct2) case (pCons a1 p1 a2 p2) have ?case when "p1+p2=0" proof - have"p2=-p1"using that by algebra thenshow ?thesis by (simp add:fcompose_pCons fcompose_uminus smult_add_left) qed moreoverhave ?case when "p1=0" proof - have"p2=0" using pCons(2) that by (auto split:if_splits) thenshow ?thesis using that by simp qed moreoverhave ?case when "p1≠0""p1+p2≠0" proof -
define d1 d2 dp where"d1=degree (pCons a1 p1)"and"d2=degree (pCons a2 p2)" and"dp = degree p1 - degree (p1+p2)"
define fp1 fp2 where"fp1= fcompose p1 q1 q2"and"fp2=fcompose p2 q1 q2"
have"q2 ^ (degree (pCons a1 p1) - degree (pCons a1 p1 + pCons a2 p2)) * fcompose (pCons a1 p1 + pCons a2 p2) q1 q2 = q2 ^ dp * fcompose (pCons (a1+a2) (p1 +p2)) q1 q2" unfolding dp_def using that by auto alsohave"... = smult (a1 + a2) (q2 ^ d1) + q1 * (q2 ^ dp * fcompose (p1 + p2) q1 q2)" proof - have"degree p1 ≥ degree (p1 + p2)" by (metis degree_add_le degree_pCons_eq_if not_less_eq_eq order_refl pCons.prems zero_le) thenshow ?thesis unfolding fcompose_pCons dp_def d1_def using that by (simp add:algebra_simps power_add[symmetric]) qed alsohave"... = smult (a1 + a2) (q2 ^ d1) + q1 * (fp1 + fp2)" apply (subst pCons(1)[folded dp_def fp1_def fp2_def])
subgoal by (metis degree_pCons_eq_if diff_Suc_Suc diff_zero not_less_eq_eq pCons.prems zero_le)
subgoal by simp done alsohave"... = fcompose (pCons a1 p1) q1 q2 + fcompose (pCons a2 p2) q1 q2" proof - have *:"d1 = degree (pCons a2 p2)" unfolding d1_def using pCons(2) by simp show ?thesis unfolding fcompose_pCons apply (fold d1_def fp1_def fp2_def *) by (simp add:smult_add_left algebra_simps) qed finallyshow ?thesis . qed ultimatelyshow ?caseby blast qed simp
lemma fcompose_add_const: "fcompose ([:a:] + p) q1 q2 = smult a (q2 ^ degree p) + fcompose p q1 q2" apply (cases p) by (auto simp add:fcompose_pCons smult_add_left)
lemma fcompose_smult: "fcompose (smult a p) q1 q2 = smult a (fcompose p q1 q2)" by (induct p) (simp_all add:fcompose_pCons smult_add_right)
lemma fcompose_mult: "fcompose (p1*p2) q1 q2 = fcompose p1 q1 q2 * fcompose p2 q1 q2" proof (induct p1) case0 thenshow ?caseby simp next case (pCons a p1) have ?case when "p1=0 ∨ p2=0" using that by (auto simp add:fcompose_smult) moreoverhave ?case when "p1≠0""p2≠0""a=0" using that by (simp add:fcompose_pCons pCons) moreoverhave ?case when "p1≠0""p2≠0""a≠0" proof - have"fcompose (pCons a p1 * p2) q1 q2 = fcompose (pCons 0 (p1 * p2) + smult a p2) q1 q2" by (simp add:algebra_simps) alsohave"... = fcompose (pCons 0 (p1 * p2)) q1 q2 + q2 ^ (degree p1 +1) * fcompose (smult a p2) q1 q2" proof - have"degree (pCons 0 (p1 * p2)) > degree (smult a p2)" using that by (simp add: degree_mult_eq) from fcompose_add_less[OF this,of q1 q2] that show ?thesis by (simp add:degree_mult_eq) qed alsohave"... = fcompose (pCons a p1) q1 q2 * fcompose p2 q1 q2" using that by (simp add:fcompose_pCons fcompose_smult pCons algebra_simps) finallyshow ?thesis . qed ultimatelyshow ?caseby blast qed
lemma fcompose_poly: assumes"poly q2 x≠0" shows"poly p (poly q1 x/poly q2 x) = poly (fcompose p q1 q2) x / poly (q2^(degree p)) x" apply (induct p) using assms by (simp_all add:fcompose_pCons field_simps)
lemma poly_fcompose: assumes"poly q2 x≠0" shows"poly (fcompose p q1 q2) x = poly p (poly q1 x/poly q2 x) * (poly q2 x)^(degree p)" using fcompose_poly[OF assms] assms by (auto simp add:field_simps) lemma poly_fcompose_0_denominator: assumes"poly q2 x=0" shows"poly (fcompose p q1 q2) x = poly q1 x ^ degree p * lead_coeff p" apply (induct p) using assms by (auto simp add:fcompose_pCons)
lemma fcompose_0_denominator:"fcompose p q1 0 = smult (lead_coeff p) (q1^degree p)" apply (induct p) by (auto simp:fcompose_pCons)
lemma fcompose_nzero: fixes p::"'a::field poly" assumes"p≠0"and"q2≠0"and nconst:"∀c. q1 ≠ smult c q2" and infi:"infinite (UNIV::'a set)" shows"fcompose p q1 q2 ≠ 0"using‹p≠0› proof (induct p rule:poly_root_induct_alt) case0 thenshow ?caseby simp next case (no_proots p) have False when "fcompose p q1 q2 = 0" proof - obtain x where"poly q2 x≠0" proof - have"finite (proots q2)"using‹q2≠0›by auto thenhave"∃x. poly q2 x≠0" by (meson UNIV_I ex_new_if_finite infi proots_withinI) thenshow ?thesis using that by auto qed
define y where"y = poly q1 x / poly q2 x" have"poly p y = 0" using‹fcompose p q1 q2 = 0› fcompose_poly[OF ‹poly q2 x≠0›,of p q1,folded y_def] by simp thenshow False using no_proots(1) by auto qed thenshow ?caseby auto next case (root a p) have"fcompose [:- a, 1:] q1 q2 ≠ 0" unfolding fcompose_def using nconst[rule_format,of a] by simp moreoverhave"fcompose p q1 q2 ≠ 0" using root by fastforce ultimatelyshow ?caseunfolding fcompose_mult by auto qed
subsection‹Bijection (@{term bij_betw}) and the number of polynomial roots›
lemma proots_fcompose_bij_eq: fixes p::"'a::field poly" assumes bij:"bij_betw (λx. poly q1 x/poly q2 x) A B"and"p≠0" and nzero:"∀x∈A. poly q2 x≠0" and max_deg: "max (degree q1) (degree q2) ≤ 1" and nconst:"∀c. q1 ≠ smult c q2" and infi:"infinite (UNIV::'a set)" shows"proots_count p B = proots_count (fcompose p q1 q2) A" using‹p≠0› proof (induct p rule:poly_root_induct_alt) case0 thenshow ?caseby simp next case (no_proots p) have"proots_count p B = 0" proof - have"proots_within p B = {}" using no_proots by auto thenshow ?thesis unfolding proots_count_def by auto qed moreoverhave"proots_count (fcompose p q1 q2) A = 0" proof - have"proots_within (fcompose p q1 q2) A = {}" using no_proots unfolding proots_within_def by (smt (verit) div_0 empty_Collect_eq fcompose_poly nzero) thenshow ?thesis unfolding proots_count_def by auto qed ultimatelyshow ?caseby auto next case (root b p) have"proots_count ([:- b, 1:] * p) B = proots_count [:- b, 1:] B + proots_count p B" using proots_count_times[OF ‹[:- b, 1:] * p ≠ 0›] by simp alsohave"... = proots_count (fcompose [:- b, 1:] q1 q2) A + proots_count (fcompose p q1 q2) A" proof -
define g where"g=(λx. poly q1 x/poly q2 x)"
have"proots_count [:- b, 1:] B = proots_count (fcompose [:- b, 1:] q1 q2) A" proof (cases "b∈B") case True thenhave"proots_count [:- b, 1:] B = 1" unfolding proots_count_pCons_1_iff by simp moreoverhave"proots_count (fcompose [:- b, 1:] q1 q2) A = 1" proof - obtain a where"b=g a""a∈A" using bij[folded g_def] True by (metis bij_betwE bij_betw_the_inv_into f_the_inv_into_f_bij_betw)
define qq where"qq=q1 - smult b q2" have qq_0:"poly qq a=0"and qq_deg: "degree qq≤1"and‹qq≠0› unfolding qq_def
subgoal using‹b=g a› nzero[rule_format,OF ‹a∈A›] unfolding g_def by auto
subgoal using max_deg by (simp add: degree_diff_le)
subgoal using nconst[rule_format,of b] by auto done have"proots_within qq A = {a}" proof - have"a∈proots_within qq A" using qq_0 ‹a∈A›by auto moreoverhave"card (proots_within qq A) = 1" proof - have"finite (proots_within qq A)"using‹qq≠0›by simp moreoverhave"proots_within qq A ≠ {}" using‹a∈proots_within qq A›by auto ultimatelyhave"card (proots_within qq A) ≠0"by auto moreoverhave"card (proots_within qq A) ≤ 1" by (meson ‹qq ≠ 0› card_proots_within_leq le_trans proots_count_leq_degree qq_deg) ultimatelyshow ?thesis by auto qed ultimatelyshow ?thesis by (metis card_1_singletonE singletonD) qed moreoverhave"order a qq=1" by (metis One_nat_def ‹qq ≠ 0› le_antisym le_zero_eq not_less_eq_eq order_degree
order_root qq_0 qq_deg) ultimatelyshow ?thesis unfolding fcompose_def proots_count_def qq_def by auto qed ultimatelyshow ?thesis by auto next case False thenhave"proots_count [:- b, 1:] B = 0" unfolding proots_count_pCons_1_iff by simp moreoverhave"proots_count (fcompose [:- b, 1:] q1 q2) A = 0" proof - have"proots_within (fcompose [:- b, 1:] q1 q2) A = {}" proof (rule ccontr) assume"proots_within (fcompose [:- b, 1:] q1 q2) A ≠ {}" thenobtain a where"a∈A""poly q1 a = b * poly q2 a" unfolding fcompose_def proots_within_def by auto thenhave"b = g a" unfolding g_def using nzero[rule_format,OF ‹a∈A›] by auto thenhave"b∈B"using‹a∈A› bij[folded g_def] using bij_betwE by blast thenshow False using False by auto qed thenshow ?thesis unfolding proots_count_def by auto qed ultimatelyshow ?thesis by simp qed moreoverhave"proots_count p B = proots_count (fcompose p q1 q2) A" apply (rule root.hyps) using mult_eq_0_iff root.prems by blast ultimatelyshow ?thesis by auto qed alsohave"... = proots_count (fcompose ([:- b, 1:] * p) q1 q2) A" proof (cases "A={}") case False have"fcompose [:- b, 1:] q1 q2 ≠0" using nconst[rule_format,of b] unfolding fcompose_def by auto moreoverhave"fcompose p q1 q2 ≠ 0" apply (rule fcompose_nzero[OF _ _ nconst infi])
subgoal using‹[:- b, 1:] * p ≠ 0›by auto
subgoal using nzero False by auto done ultimatelyshow ?thesis unfolding fcompose_mult apply (subst proots_count_times) by auto qed auto finallyshow ?case . qed
lemma proots_card_fcompose_bij_eq: fixes p::"'a::field poly" assumes bij:"bij_betw (λx. poly q1 x/poly q2 x) A B"and"p≠0" and nzero:"∀x∈A. poly q2 x≠0" and max_deg: "max (degree q1) (degree q2) ≤ 1" and nconst:"∀c. q1 ≠ smult c q2" and infi:"infinite (UNIV::'a set)" shows"card (proots_within p B) = card (proots_within (fcompose p q1 q2) A)" using‹p≠0› proof (induct p rule:poly_root_induct_alt) case0 thenshow ?caseby simp next case (no_proots p) have"proots_within p B = {}"using no_proots by auto moreoverhave"proots_within (fcompose p q1 q2) A = {}" using no_proots fcompose_poly by (smt (verit) Collect_empty_eq divide_eq_0_iff nzero proots_within_def) ultimatelyshow ?caseby auto next case (root b p) thenhave [simp]:"p≠0"by auto
have ?case when "b∉B ∨ poly p b=0" proof - have"proots_within ([:- b, 1:] * p) B = proots_within p B" using that by auto moreoverhave"proots_within (fcompose ([:- b, 1:] * p) q1 q2) A = proots_within (fcompose p q1 q2) A" using that nzero unfolding fcompose_mult proots_within_times apply (auto simp add: poly_fcompose) using bij bij_betwE by blast ultimatelyshow ?thesis using root by auto qed moreoverhave ?case when "b∈B""poly p b≠0" proof -
define bb where"bb=[:- b, 1:]" have"card (proots_within (bb * p) B) = card {b} + card (proots_within p B)" proof - have"proots_within bb B = {b}" using that unfolding bb_def by auto thenshow ?thesis unfolding proots_within_times apply (subst card_Un_disjoint) by (use that in auto) qed alsohave"... = 1 + card (proots_within (fcompose p q1 q2) A)" using root.hyps by simp alsohave"... = card (proots_within (fcompose (bb * p) q1 q2) A)" unfolding proots_within_times fcompose_mult proof (subst card_Un_disjoint) obtain a where b_poly:"b=poly q1 a / poly q2 a"and"a∈A" by (metis (no_types, lifting) ‹b ∈ B› bij bij_betwE bij_betw_the_inv_into
f_the_inv_into_f_bij_betw)
define bbq pq where"bbq=fcompose bb q1 q2"and"pq=fcompose p q1 q2" have bbq_0:"poly bbq a=0"and bbq_deg: "degree bbq≤1"and"bbq≠0" unfolding bbq_def bb_def
subgoal using‹a ∈ A› b_poly nzero poly_fcompose by fastforce
subgoal by (metis (no_types, lifting) degree_add_le degree_pCons_eq_if degree_smult_le
dual_order.trans fcompose_const fcompose_pCons max.boundedE max_deg mult_cancel_left2
one_neq_zero one_poly_eq_simps(1) power.simps)
subgoal by (metis ‹a ∈ A›‹poly (fcompose [:- b, 1:] q1 q2) a = 0› fcompose_nzero infi
nconst nzero one_neq_zero pCons_eq_0_iff) done show"finite (proots_within bbq A)"using‹bbq≠0›by simp show"finite (proots_within pq A)"unfolding pq_def by (metis ‹a ∈ A›‹p ≠ 0› fcompose_nzero finite_proots infi nconst nzero poly_0 pq_def) have bbq_a:"proots_within bbq A = {a}" proof - have"a∈proots_within bbq A" by (simp add: ‹a ∈ A› bbq_0) moreoverhave"card (proots_within bbq A) = 1" proof - have"card (proots_within bbq A) ≠0" using‹a∈proots_within bbq A›‹finite (proots_within bbq A)› by auto moreoverhave"card (proots_within bbq A) ≤ 1" by (meson ‹bbq ≠ 0› card_proots_within_leq le_trans proots_count_leq_degree bbq_deg) ultimatelyshow ?thesis by auto qed ultimatelyshow ?thesis by (metis card_1_singletonE singletonD) qed show"proots_within (bbq) A ∩ proots_within (pq) A = {}" using b_poly bbq_a fcompose_poly nzero pq_def that(2) by fastforce show"1 + card (proots_within pq A) = card (proots_within bbq A) + card (proots_within pq A)" using bbq_a by simp qed finallyshow ?thesis unfolding bb_def . qed ultimatelyshow ?caseby auto qed
lemma proots_pcompose_bij_eq: fixes p::"'a::idom poly" assumes bij:"bij_betw (λx. poly q x) A B"and"p≠0" and q_deg: "degree q = 1" shows"proots_count p B = proots_count (p ∘p q) A"using‹p≠0› proof (induct p rule:poly_root_induct_alt) case0 thenshow ?caseby simp next case (no_proots p) have"proots_count p B = 0" proof - have"proots_within p B = {}" using no_proots by auto thenshow ?thesis unfolding proots_count_def by auto qed moreoverhave"proots_count (p ∘p q) A = 0" proof - have"proots_within (p ∘p q) A = {}" using no_proots unfolding proots_within_def by (auto simp:poly_pcompose) thenshow ?thesis unfolding proots_count_def by auto qed ultimatelyshow ?caseby auto next case (root b p) have"proots_count ([:- b, 1:] * p) B = proots_count [:- b, 1:] B + proots_count p B" using proots_count_times[OF ‹[:- b, 1:] * p ≠ 0›] by simp alsohave"... = proots_count ([:- b, 1:] ∘p q) A + proots_count (p ∘p q) A" proof - have"proots_count [:- b, 1:] B = proots_count ([:- b, 1:] ∘p q) A" proof (cases "b∈B") case True thenhave"proots_count [:- b, 1:] B = 1" unfolding proots_count_pCons_1_iff by simp moreoverhave"proots_count ([:- b, 1:] ∘p q) A = 1" proof - obtain a where"b=poly q a""a∈A" using True bij by (metis bij_betwE bij_betw_the_inv_into f_the_inv_into_f_bij_betw)
define qq where"qq=[:- b:] + q" have qq_0:"poly qq a=0"and qq_deg: "degree qq≤1"and‹qq≠0› unfolding qq_def
subgoal using‹b=poly q a›by auto
subgoal using q_deg by (simp add: degree_add_le)
subgoal using q_deg add.inverse_unique by force done have"proots_within qq A = {a}" proof - have"a∈proots_within qq A" using qq_0 ‹a∈A›by auto moreoverhave"card (proots_within qq A) = 1" proof - have"finite (proots_within qq A)"using‹qq≠0›by simp moreoverhave"proots_within qq A ≠ {}" using‹a∈proots_within qq A›by auto ultimatelyhave"card (proots_within qq A) ≠0"by auto moreoverhave"card (proots_within qq A) ≤ 1" by (meson ‹qq ≠ 0› card_proots_within_leq le_trans proots_count_leq_degree qq_deg) ultimatelyshow ?thesis by auto qed ultimatelyshow ?thesis by (metis card_1_singletonE singletonD) qed moreoverhave"order a qq=1" by (metis One_nat_def ‹qq ≠ 0› le_antisym le_zero_eq not_less_eq_eq order_degree
order_root qq_0 qq_deg) ultimatelyshow ?thesis unfolding pcompose_def proots_count_def qq_def by auto qed ultimatelyshow ?thesis by auto next case False thenhave"proots_count [:- b, 1:] B = 0" unfolding proots_count_pCons_1_iff by simp moreoverhave"proots_count ([:- b, 1:] ∘p q) A = 0" proof - have"proots_within ([:- b, 1:] ∘p q) A = {}" unfolding pcompose_def apply auto using False bij bij_betwE by blast thenshow ?thesis unfolding proots_count_def by auto qed ultimatelyshow ?thesis by simp qed moreoverhave"proots_count p B = proots_count (p ∘p q) A" apply (rule root.hyps) using‹[:- b, 1:] * p ≠ 0›by auto ultimatelyshow ?thesis by auto qed alsohave"... = proots_count (([:- b, 1:] * p) ∘p q) A" unfolding pcompose_mult apply (subst proots_count_times)
subgoal by (metis (no_types, lifting) One_nat_def add.right_neutral degree_0 degree_mult_eq
degree_pCons_eq_if degree_pcompose mult_eq_0_iff one_neq_zero one_pCons pcompose_mult
q_deg root.prems) by simp finallyshow ?case . qed
lemma proots_card_pcompose_bij_eq: fixes p::"'a::idom poly" assumes bij:"bij_betw (λx. poly q x) A B"and"p≠0" and q_deg: "degree q = 1" shows"card (proots_within p B) = card (proots_within (p ∘p q) A)"using‹p≠0› proof (induct p rule:poly_root_induct_alt) case0 thenshow ?caseby auto next case (no_proots p) have"proots_within p B = {}"using no_proots by auto moreoverhave"proots_within (p ∘p q) A = {}"using no_proots by (simp add: poly_pcompose proots_within_def) ultimatelyshow ?caseby auto next case (root b p) thenhave [simp]:"p≠0"by auto have ?case when "b∉B ∨ poly p b=0" proof - have"proots_within ([:- b, 1:] * p) B = proots_within p B" using that by auto moreoverhave"proots_within (([:- b, 1:] * p) ∘p q) A = proots_within (p ∘p q) A" using that unfolding pcompose_mult proots_within_times apply (auto simp add: poly_pcompose) using bij bij_betwE by blast ultimatelyshow ?thesis using root.hyps[OF ‹p≠0›] by auto qed moreoverhave ?case when "b∈B""poly p b≠0" proof -
define bb where"bb=[:- b, 1:]" have"card (proots_within (bb * p) B) = card {b} + card (proots_within p B)" proof - have"proots_within bb B = {b}" using that unfolding bb_def by auto thenshow ?thesis unfolding proots_within_times apply (subst card_Un_disjoint) by (use that in auto) qed alsohave"... = 1 + card (proots_within (p ∘p q) A)" using root.hyps by simp alsohave"... = card (proots_within ((bb * p) ∘p q) A)" unfolding proots_within_times pcompose_mult proof (subst card_Un_disjoint) obtain a where"b=poly q a""a∈A" by (metis ‹b ∈ B› bij bij_betwE bij_betw_the_inv_into f_the_inv_into_f_bij_betw)
define bbq pq where"bbq=bb ∘p q"and"pq=p ∘p q" have bbq_0:"poly bbq a=0"and bbq_deg: "degree bbq≤1"and"bbq≠0" unfolding bbq_def bb_def poly_pcompose
subgoal using‹b=poly q a›by auto
subgoal using q_deg by (simp add: degree_add_le degree_pcompose)
subgoal using pcompose_eq_0 q_deg by fastforce done show"finite (proots_within bbq A)"using‹bbq≠0›by simp show"finite (proots_within pq A)"unfolding pq_def by (metis ‹p ≠ 0› finite_proots pcompose_eq_0 q_deg zero_less_one) have bbq_a:"proots_within bbq A = {a}" proof - have"a∈proots_within bbq A" unfolding bb_def proots_within_def poly_pcompose bbq_def using‹b=poly q a›‹a∈A›by simp moreoverhave"card (proots_within bbq A) = 1" proof - have"card (proots_within bbq A) ≠0" using‹a∈proots_within bbq A›‹finite (proots_within bbq A)› by auto moreoverhave"card (proots_within bbq A) ≤ 1" by (meson ‹bbq ≠ 0› card_proots_within_leq le_trans proots_count_leq_degree bbq_deg) ultimatelyshow ?thesis by auto qed ultimatelyshow ?thesis by (metis card_1_singletonE singletonD) qed show"proots_within (bbq) A ∩ proots_within (pq) A = {}" using bbq_a ‹b = poly q a› that(2) unfolding pq_def by (simp add:poly_pcompose) show"1 + card (proots_within pq A) = card (proots_within bbq A) + card (proots_within pq A)" using bbq_a by simp qed finallyshow ?thesis unfolding bb_def . qed ultimatelyshow ?caseby auto qed
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.