# HG changeset patch # User paulson # Date 1739707061 0 # Node ID fa2c960fb232baf56e9590c4edc000a8cc55acab # Parent 207f2120cc9298f32b49126576f467c2aee3e532# Parent cddce3a4ef84a90b0cd4ac16a804e945042b8805 merged diff -r 207f2120cc92 -r fa2c960fb232 src/HOL/Computational_Algebra/Polynomial.thy --- a/src/HOL/Computational_Algebra/Polynomial.thy Sat Feb 15 22:39:47 2025 +0100 +++ b/src/HOL/Computational_Algebra/Polynomial.thy Sun Feb 16 11:57:41 2025 +0000 @@ -127,7 +127,7 @@ qed lemma le_degree: "coeff p n \ 0 \ n \ degree p" - by (erule contrapos_np, rule coeff_eq_0, simp) + using coeff_eq_0 linorder_le_less_linear by blast lemma degree_le: "\i>n. coeff p i = 0 \ degree p \ n" unfolding degree_def by (erule Least_le) @@ -135,6 +135,11 @@ lemma less_degree_imp: "n < degree p \ \i>n. coeff p i \ 0" unfolding degree_def by (drule not_less_Least, simp) +lemma poly_eqI2: + assumes "degree p = degree q" and "\i. i \ degree p \ coeff p i = coeff q i" + shows "p = q" + by (metis assms le_degree poly_eqI) + subsection \The zero polynomial\ @@ -356,6 +361,36 @@ "[:x, xs:]" \ "CONST pCons x [:xs:]" "[:x:]" \ "CONST pCons x 0" +lemma degree_0_id: + assumes "degree p = 0" + shows "[: coeff p 0 :] = p" + by (metis assms coeff_pCons_0 degree_eq_zeroE) + +lemma degree0_coeffs: "degree p = 0 \ \ a. p = [: a :]" + by (meson degree_eq_zeroE) + +lemma degree1_coeffs: + fixes p :: "'a::zero poly" + assumes "degree p = 1" + obtains a b where "p = [: b, a :]" "a \ 0" +proof - + obtain b a q where "p = pCons b q" "q = pCons a 0" + by (metis assms degree0_coeffs degree_0 degree_pCons_eq_if lessI less_one pCons_cases) + then show thesis + using assms that by force +qed + +lemma degree2_coeffs: + fixes p :: "'a::zero poly" + assumes "degree p = 2" + obtains a b c where "p = [: c, b, a :]" "a \ 0" +proof - + obtain c q where "p = pCons c q" "degree q = 1" + by (metis One_nat_def assms degree_0 degree_pCons_eq_if fact_0 fact_2 nat.inject numeral_2_eq_2 pCons_cases) + then show thesis + by (metis degree1_coeffs that) +qed + subsection \Representation of polynomials by lists of coefficients\ @@ -455,7 +490,10 @@ qed lemma nth_default_coeffs_eq: "nth_default 0 (coeffs p) = coeff p" - by (simp add: fun_eq_iff coeff_Poly_eq [symmetric]) + by (metis Poly_coeffs coeff_Poly_eq) + +lemma range_coeff: "range (coeff p) = insert 0 (set (coeffs p))" + by (metis nth_default_coeffs_eq range_nth_default) lemma [code]: "coeff p = nth_default 0 (coeffs p)" by (simp add: nth_default_coeffs_eq) @@ -592,6 +630,16 @@ lemma poly_0_coeff_0: "poly p 0 = coeff p 0" by (cases p) (auto simp: poly_altdef) +lemma poly_zero: + fixes p :: "'a :: comm_ring_1 poly" + assumes x: "poly p x = 0" shows "p = 0 \ degree p = 0" +proof + assume degp: "degree p = 0" + hence "poly p x = coeff p (degree p)" by(subst degree_0_id[OF degp,symmetric], simp) + hence "coeff p (degree p) = 0" using x by auto + thus "p = 0" by auto +qed auto + subsection \Monomials\ @@ -1132,6 +1180,12 @@ "smult c 1 = [:c:]" by (simp add: one_pCons) +lemma smult_sum: "smult (\i \ S. f i) p = (\i \ S. smult (f i) p)" + by (induct S rule: infinite_finite_induct, auto simp: smult_add_left) + +lemma smult_power: "(smult a p) ^ n = smult (a ^ n) (p ^ n)" + by (induct n, auto simp: field_simps) + lemma monom_eq_1 [simp]: "monom 1 0 = 1" by (simp add: monom_0 one_pCons) @@ -1144,6 +1198,21 @@ "monom c n = smult c ([:0, 1:] ^ n)" by (induct n) (simp_all add: monom_0 monom_Suc) +lemma degree_sum_list_le: "(\ p . p \ set ps \ degree p \ n) + \ degree (sum_list ps) \ n" +proof (induct ps) + case (Cons p ps) + hence "degree (sum_list ps) \ n" "degree p \ n" by auto + thus ?case unfolding sum_list.Cons by (metis degree_add_le) +qed simp + +lemma degree_prod_list_le: "degree (prod_list ps) \ sum_list (map degree ps)" +proof (induct ps) + case (Cons p ps) + show ?case unfolding prod_list.Cons + by (rule order.trans[OF degree_mult_le], insert Cons, auto) +qed simp + instance poly :: ("{comm_semiring_1,semiring_1_no_zero_divisors}") semiring_1_no_zero_divisors .. instance poly :: (comm_ring) comm_ring .. instance poly :: (comm_ring_1) comm_ring_1 .. @@ -1208,6 +1277,9 @@ finally show ?thesis . qed +lemma coeff_monom_Suc: "coeff (monom a (Suc d) * p) (Suc i) = coeff (monom a d * p) i" + by (simp add: monom_Suc) + lemma monom_1_dvd_iff': "monom 1 n dvd p \ (\k d" + shows "coeff (\i\d. monom (f i) i) n = f n" (is "?l = _") +proof - + have "?l = (\i\d. coeff (monom (f i) i) n)" (is "_ = sum ?cmf _") + using coeff_sum. + also have "{..d} = insert n ({..d}-{n})" using n by auto + hence "sum ?cmf {..d} = sum ?cmf ..." by auto + also have "... = sum ?cmf ({..d}-{n}) + ?cmf n" by (subst sum.insert,auto) + also have "sum ?cmf ({..d}-{n}) = 0" by (subst sum.neutral, auto) + finally show ?thesis by simp +qed subsection \Mapping polynomials\ @@ -1878,6 +1962,33 @@ by auto qed +text \A nice extension rule for polynomials.\ +lemma poly_ext: + fixes p q :: "'a :: {ring_char_0, idom} poly" + assumes "\x. poly p x = poly q x" shows "p = q" + unfolding poly_eq_poly_eq_iff[symmetric] + using assms by (rule ext) + +text \Copied from non-negative variants.\ +lemma coeff_linear_power_neg[simp]: + fixes a :: "'a::comm_ring_1" + shows "coeff ([:a, -1:] ^ n) n = (-1)^n" +proof (induct n) + case 0 + then show ?case by simp +next + case (Suc n) + then have "degree ([:a, - 1:] ^ n) < Suc n" + by (auto intro: le_less_trans degree_power_le) + with Suc show ?case + by (simp add: coeff_eq_0) +qed + +lemma degree_linear_power_neg[simp]: + fixes a :: "'a::{idom,comm_ring_1}" + shows "degree ([:a, -1:] ^ n) = n" + by (simp add: degree_power_eq) + lemma poly_all_0_iff_0: "(\x. poly p x = 0) \ p = 0" for p :: "'a::{ring_char_0,comm_ring_1,ring_no_zero_divisors} poly" by (auto simp add: poly_eq_poly_eq_iff [symmetric])