src/HOL/Computational_Algebra/Polynomial.thy
changeset 71398 e0237f2eb49d
parent 70113 c8deb8ba6d05
child 71586 e30dbfa53b0d
equal deleted inserted replaced
71397:028edb1e5b99 71398:e0237f2eb49d
  3443 next
  3443 next
  3444   fix p :: "'a poly"
  3444   fix p :: "'a poly"
  3445   assume "p \<noteq> 0"
  3445   assume "p \<noteq> 0"
  3446   then show "is_unit (unit_factor p)"
  3446   then show "is_unit (unit_factor p)"
  3447     by (simp add: unit_factor_poly_def monom_0 is_unit_poly_iff unit_factor_is_unit)
  3447     by (simp add: unit_factor_poly_def monom_0 is_unit_poly_iff unit_factor_is_unit)
       
  3448 next
       
  3449   fix a b :: "'a poly" assume "is_unit a" 
       
  3450   thus "unit_factor (a * b) = a * unit_factor b"
       
  3451     by (auto simp: unit_factor_poly_def lead_coeff_mult unit_factor_mult elim!: is_unit_polyE)
  3448 qed (simp_all add: normalize_poly_def unit_factor_poly_def monom_0 lead_coeff_mult unit_factor_mult)
  3452 qed (simp_all add: normalize_poly_def unit_factor_poly_def monom_0 lead_coeff_mult unit_factor_mult)
  3449 
  3453 
  3450 end
  3454 end
       
  3455 
       
  3456 instance poly :: ("{semidom_divide_unit_factor,idom_divide,normalization_semidom_multiplicative}") 
       
  3457   normalization_semidom_multiplicative
       
  3458   by intro_classes (auto simp: unit_factor_poly_def lead_coeff_mult unit_factor_mult)
  3451 
  3459 
  3452 lemma normalize_poly_eq_map_poly: "normalize p = map_poly (\<lambda>x. x div unit_factor (lead_coeff p)) p"
  3460 lemma normalize_poly_eq_map_poly: "normalize p = map_poly (\<lambda>x. x div unit_factor (lead_coeff p)) p"
  3453 proof -
  3461 proof -
  3454   have "[:unit_factor (lead_coeff p):] dvd p"
  3462   have "[:unit_factor (lead_coeff p):] dvd p"
  3455     by (metis unit_factor_poly_def unit_factor_self)
  3463     by (metis unit_factor_poly_def unit_factor_self)
  3487   by (cases "a = 0") (simp_all add: unit_factor_poly_def degree_monom_eq)
  3495   by (cases "a = 0") (simp_all add: unit_factor_poly_def degree_monom_eq)
  3488 
  3496 
  3489 lemma normalize_const_poly: "normalize [:c:] = [:normalize c:]"
  3497 lemma normalize_const_poly: "normalize [:c:] = [:normalize c:]"
  3490   by (simp add: normalize_poly_eq_map_poly map_poly_pCons)
  3498   by (simp add: normalize_poly_eq_map_poly map_poly_pCons)
  3491 
  3499 
  3492 lemma normalize_smult: "normalize (smult c p) = smult (normalize c) (normalize p)"
  3500 lemma normalize_smult:
       
  3501   fixes c :: "'a :: {normalization_semidom_multiplicative, idom_divide}"
       
  3502   shows "normalize (smult c p) = smult (normalize c) (normalize p)"
  3493 proof -
  3503 proof -
  3494   have "smult c p = [:c:] * p" by simp
  3504   have "smult c p = [:c:] * p" by simp
  3495   also have "normalize \<dots> = smult (normalize c) (normalize p)"
  3505   also have "normalize \<dots> = smult (normalize c) (normalize p)"
  3496     by (subst normalize_mult) (simp add: normalize_const_poly)
  3506     by (subst normalize_mult) (simp add: normalize_const_poly)
  3497   finally show ?thesis .
  3507   finally show ?thesis .
  4486   assume "is_unit (content p)"
  4496   assume "is_unit (content p)"
  4487   then have "normalize (content p) = 1" by (simp add: is_unit_normalize del: normalize_content)
  4497   then have "normalize (content p) = 1" by (simp add: is_unit_normalize del: normalize_content)
  4488   then show "content p = 1" by simp
  4498   then show "content p = 1" by simp
  4489 qed auto
  4499 qed auto
  4490 
  4500 
  4491 lemma content_smult [simp]: "content (smult c p) = normalize c * content p"
  4501 lemma content_smult [simp]:
  4492   by (simp add: content_def coeffs_smult Gcd_fin_mult)
  4502   fixes c :: "'a :: {normalization_semidom_multiplicative, semiring_gcd}"
       
  4503   shows "content (smult c p) = normalize c * content p"
       
  4504   by (simp add: content_def coeffs_smult Gcd_fin_mult normalize_mult)
  4493 
  4505 
  4494 lemma content_eq_zero_iff [simp]: "content p = 0 \<longleftrightarrow> p = 0"
  4506 lemma content_eq_zero_iff [simp]: "content p = 0 \<longleftrightarrow> p = 0"
  4495   by (auto simp: content_def simp: poly_eq_iff coeffs_def)
  4507   by (auto simp: content_def simp: poly_eq_iff coeffs_def)
  4496 
  4508 
  4497 definition primitive_part :: "'a :: semiring_gcd poly \<Rightarrow> 'a poly"
  4509 definition primitive_part :: "'a :: semiring_gcd poly \<Rightarrow> 'a poly"
  4526   finally show ?thesis
  4538   finally show ?thesis
  4527     using False by simp
  4539     using False by simp
  4528 qed
  4540 qed
  4529 
  4541 
  4530 lemma content_primitive_part [simp]:
  4542 lemma content_primitive_part [simp]:
       
  4543   fixes p :: "'a :: {normalization_semidom_multiplicative, semiring_gcd} poly"
  4531   assumes "p \<noteq> 0"
  4544   assumes "p \<noteq> 0"
  4532   shows "content (primitive_part p) = 1"
  4545   shows "content (primitive_part p) = 1"
  4533 proof -
  4546 proof -
  4534   have "p = smult (content p) (primitive_part p)"
  4547   have "p = smult (content p) (primitive_part p)"
  4535     by simp
  4548     by simp
  4542   with assms show ?thesis
  4555   with assms show ?thesis
  4543     by simp
  4556     by simp
  4544 qed
  4557 qed
  4545 
  4558 
  4546 lemma content_decompose:
  4559 lemma content_decompose:
  4547   obtains p' :: "'a::semiring_gcd poly"
  4560   obtains p' :: "'a :: {normalization_semidom_multiplicative, semiring_gcd} poly"
  4548   where "p = smult (content p) p'" "content p' = 1"
  4561   where "p = smult (content p) p'" "content p' = 1"
  4549 proof (cases "p = 0")
  4562 proof (cases "p = 0")
  4550   case True
  4563   case True
  4551   then have "p = smult (content p) 1" "content 1 = 1"
  4564   then have "p = smult (content p) 1" "content 1 = 1"
  4552     by simp_all
  4565     by simp_all
  4579     by (subst degree_smult_eq) simp_all
  4592     by (subst degree_smult_eq) simp_all
  4580   finally show ?thesis ..
  4593   finally show ?thesis ..
  4581 qed
  4594 qed
  4582 
  4595 
  4583 lemma smult_content_normalize_primitive_part [simp]:
  4596 lemma smult_content_normalize_primitive_part [simp]:
  4584   "smult (content p) (normalize (primitive_part p)) = normalize p"
  4597   fixes p :: "'a :: {normalization_semidom_multiplicative, semiring_gcd, idom_divide} poly"
       
  4598   shows "smult (content p) (normalize (primitive_part p)) = normalize p"
  4585 proof -
  4599 proof -
  4586   have "smult (content p) (normalize (primitive_part p)) =
  4600   have "smult (content p) (normalize (primitive_part p)) =
  4587       normalize ([:content p:] * primitive_part p)"
  4601       normalize ([:content p:] * primitive_part p)"
  4588     by (subst normalize_mult) (simp_all add: normalize_const_poly)
  4602     by (subst normalize_mult) (simp_all add: normalize_const_poly)
  4589   also have "[:content p:] * primitive_part p = p" by simp
  4603   also have "[:content p:] * primitive_part p = p" by simp
  4621   hence "normalize (content (f * g)) = 1" by (simp add: is_unit_normalize del: normalize_content)
  4635   hence "normalize (content (f * g)) = 1" by (simp add: is_unit_normalize del: normalize_content)
  4622   thus ?thesis by simp
  4636   thus ?thesis by simp
  4623 qed (insert assms, auto)
  4637 qed (insert assms, auto)
  4624 
  4638 
  4625 lemma content_mult:
  4639 lemma content_mult:
  4626   fixes p q :: "'a :: {factorial_semiring, semiring_gcd} poly"
  4640   fixes p q :: "'a :: {factorial_semiring, semiring_gcd, normalization_semidom_multiplicative} poly"
  4627   shows "content (p * q) = content p * content q"
  4641   shows "content (p * q) = content p * content q"
  4628 proof (cases "p * q = 0")
  4642 proof (cases "p * q = 0")
  4629   case False
  4643   case False
  4630   then have "p \<noteq> 0" and "q \<noteq> 0"
  4644   then have "p \<noteq> 0" and "q \<noteq> 0"
  4631     by simp_all
  4645     by simp_all
  4644 qed
  4658 qed
  4645 
  4659 
  4646 end
  4660 end
  4647 
  4661 
  4648 lemma primitive_part_mult:
  4662 lemma primitive_part_mult:
  4649   fixes p q :: "'a :: {factorial_semiring, semiring_Gcd, ring_gcd, idom_divide} poly"
  4663   fixes p q :: "'a :: {factorial_semiring, semiring_Gcd, ring_gcd, idom_divide,
       
  4664                        normalization_semidom_multiplicative} poly"
  4650   shows "primitive_part (p * q) = primitive_part p * primitive_part q"
  4665   shows "primitive_part (p * q) = primitive_part p * primitive_part q"
  4651 proof -
  4666 proof -
  4652   have "primitive_part (p * q) = p * q div [:content (p * q):]"
  4667   have "primitive_part (p * q) = p * q div [:content (p * q):]"
  4653     by (simp add: primitive_part_def div_const_poly_conv_map_poly)
  4668     by (simp add: primitive_part_def div_const_poly_conv_map_poly)
  4654   also have "\<dots> = (p div [:content p:]) * (q div [:content q:])"
  4669   also have "\<dots> = (p div [:content p:]) * (q div [:content q:])"
  4657     by (simp add: primitive_part_def div_const_poly_conv_map_poly)
  4672     by (simp add: primitive_part_def div_const_poly_conv_map_poly)
  4658   finally show ?thesis .
  4673   finally show ?thesis .
  4659 qed
  4674 qed
  4660 
  4675 
  4661 lemma primitive_part_smult:
  4676 lemma primitive_part_smult:
  4662   fixes p :: "'a :: {factorial_semiring, semiring_Gcd, ring_gcd, idom_divide} poly"
  4677   fixes p :: "'a :: {factorial_semiring, semiring_Gcd, ring_gcd, idom_divide,
       
  4678                      normalization_semidom_multiplicative} poly"
  4663   shows "primitive_part (smult a p) = smult (unit_factor a) (primitive_part p)"
  4679   shows "primitive_part (smult a p) = smult (unit_factor a) (primitive_part p)"
  4664 proof -
  4680 proof -
  4665   have "smult a p = [:a:] * p" by simp
  4681   have "smult a p = [:a:] * p" by simp
  4666   also have "primitive_part \<dots> = smult (unit_factor a) (primitive_part p)"
  4682   also have "primitive_part \<dots> = smult (unit_factor a) (primitive_part p)"
  4667     by (subst primitive_part_mult) simp_all
  4683     by (subst primitive_part_mult) simp_all
  4668   finally show ?thesis .
  4684   finally show ?thesis .
  4669 qed  
  4685 qed  
  4670 
  4686 
  4671 lemma primitive_part_dvd_primitive_partI [intro]:
  4687 lemma primitive_part_dvd_primitive_partI [intro]:
  4672   fixes p q :: "'a :: {factorial_semiring, semiring_Gcd, ring_gcd, idom_divide} poly"
  4688   fixes p q :: "'a :: {factorial_semiring, semiring_Gcd, ring_gcd, idom_divide,
       
  4689                        normalization_semidom_multiplicative} poly"
  4673   shows "p dvd q \<Longrightarrow> primitive_part p dvd primitive_part q"
  4690   shows "p dvd q \<Longrightarrow> primitive_part p dvd primitive_part q"
  4674   by (auto elim!: dvdE simp: primitive_part_mult)
  4691   by (auto elim!: dvdE simp: primitive_part_mult)
  4675 
  4692 
  4676 lemma content_prod_mset: 
  4693 lemma content_prod_mset: 
  4677   fixes A :: "'a :: {factorial_semiring, semiring_Gcd} poly multiset"
  4694   fixes A :: "'a :: {factorial_semiring, semiring_Gcd, normalization_semidom_multiplicative}
       
  4695       poly multiset"
  4678   shows "content (prod_mset A) = prod_mset (image_mset content A)"
  4696   shows "content (prod_mset A) = prod_mset (image_mset content A)"
  4679   by (induction A) (simp_all add: content_mult mult_ac)
  4697   by (induction A) (simp_all add: content_mult mult_ac)
  4680 
  4698 
  4681 lemma content_prod_eq_1_iff: 
  4699 lemma content_prod_eq_1_iff: 
  4682   fixes p q :: "'a :: {factorial_semiring, semiring_Gcd} poly"
  4700   fixes p q :: "'a :: {factorial_semiring, semiring_Gcd, normalization_semidom_multiplicative} poly"
  4683   shows "content (p * q) = 1 \<longleftrightarrow> content p = 1 \<and> content q = 1"
  4701   shows "content (p * q) = 1 \<longleftrightarrow> content p = 1 \<and> content q = 1"
  4684 proof safe
  4702 proof safe
  4685   assume A: "content (p * q) = 1"
  4703   assume A: "content (p * q) = 1"
  4686   {
  4704   {
  4687     fix p q :: "'a poly" assume "content p * content q = 1"
  4705     fix p q :: "'a poly" assume "content p * content q = 1"