src/HOL/Library/Univ_Poly.thy
changeset 49962 a8cc904a6820
parent 49751 5248806bc7ab
child 53191 14ab2f821e1d
equal deleted inserted replaced
49961:d3d2b78b1c19 49962:a8cc904a6820
   123 apply (case_tac b, simp_all add: add_ac)
   123 apply (case_tac b, simp_all add: add_ac)
   124 done
   124 done
   125 
   125 
   126 lemma (in semiring_0) poly_cmult_distr: "a %* ( p +++ q) = (a %* p +++ a %* q)"
   126 lemma (in semiring_0) poly_cmult_distr: "a %* ( p +++ q) = (a %* p +++ a %* q)"
   127 apply (induct p arbitrary: q, simp)
   127 apply (induct p arbitrary: q, simp)
   128 apply (case_tac q, simp_all add: right_distrib)
   128 apply (case_tac q, simp_all add: distrib_left)
   129 done
   129 done
   130 
   130 
   131 lemma (in ring_1) pmult_by_x[simp]: "[0, 1] *** t = ((0)#t)"
   131 lemma (in ring_1) pmult_by_x[simp]: "[0, 1] *** t = ((0)#t)"
   132 apply (induct "t", simp)
   132 apply (induct "t", simp)
   133 apply (auto simp add: mult_zero_left poly_ident_mult padd_commut)
   133 apply (auto simp add: mult_zero_left poly_ident_mult padd_commut)
   139 lemma (in semiring_0) poly_add: "poly (p1 +++ p2) x = poly p1 x + poly p2 x"
   139 lemma (in semiring_0) poly_add: "poly (p1 +++ p2) x = poly p1 x + poly p2 x"
   140 proof(induct p1 arbitrary: p2)
   140 proof(induct p1 arbitrary: p2)
   141   case Nil thus ?case by simp
   141   case Nil thus ?case by simp
   142 next
   142 next
   143   case (Cons a as p2) thus ?case
   143   case (Cons a as p2) thus ?case
   144     by (cases p2, simp_all  add: add_ac right_distrib)
   144     by (cases p2, simp_all  add: add_ac distrib_left)
   145 qed
   145 qed
   146 
   146 
   147 lemma (in comm_semiring_0) poly_cmult: "poly (c %* p) x = c * poly p x"
   147 lemma (in comm_semiring_0) poly_cmult: "poly (c %* p) x = c * poly p x"
   148 apply (induct "p")
   148 apply (induct "p")
   149 apply (case_tac [2] "x=zero")
   149 apply (case_tac [2] "x=zero")
   150 apply (auto simp add: right_distrib mult_ac)
   150 apply (auto simp add: distrib_left mult_ac)
   151 done
   151 done
   152 
   152 
   153 lemma (in comm_semiring_0) poly_cmult_map: "poly (map (op * c) p) x = c*poly p x"
   153 lemma (in comm_semiring_0) poly_cmult_map: "poly (map (op * c) p) x = c*poly p x"
   154   by (induct p, auto simp add: right_distrib mult_ac)
   154   by (induct p, auto simp add: distrib_left mult_ac)
   155 
   155 
   156 lemma (in comm_ring_1) poly_minus: "poly (-- p) x = - (poly p x)"
   156 lemma (in comm_ring_1) poly_minus: "poly (-- p) x = - (poly p x)"
   157 apply (simp add: poly_minus_def)
   157 apply (simp add: poly_minus_def)
   158 apply (auto simp add: poly_cmult minus_mult_left[symmetric])
   158 apply (auto simp add: poly_cmult minus_mult_left[symmetric])
   159 done
   159 done
   162 proof(induct p1 arbitrary: p2)
   162 proof(induct p1 arbitrary: p2)
   163   case Nil thus ?case by simp
   163   case Nil thus ?case by simp
   164 next
   164 next
   165   case (Cons a as p2)
   165   case (Cons a as p2)
   166   thus ?case by (cases as,
   166   thus ?case by (cases as,
   167     simp_all add: poly_cmult poly_add left_distrib right_distrib mult_ac)
   167     simp_all add: poly_cmult poly_add distrib_right distrib_left mult_ac)
   168 qed
   168 qed
   169 
   169 
   170 class idom_char_0 = idom + ring_char_0
   170 class idom_char_0 = idom + ring_char_0
   171 
   171 
   172 lemma (in comm_ring_1) poly_exp: "poly (p %^ n) x = (poly p x) ^ n"
   172 lemma (in comm_ring_1) poly_exp: "poly (p %^ n) x = (poly p x) ^ n"
   392 
   392 
   393 lemma (in comm_ring_1) poly_add_minus_zero_iff: "(poly (p +++ -- q) = poly []) = (poly p = poly q)"
   393 lemma (in comm_ring_1) poly_add_minus_zero_iff: "(poly (p +++ -- q) = poly []) = (poly p = poly q)"
   394 by (auto simp add: algebra_simps poly_add poly_minus_def fun_eq poly_cmult minus_mult_left[symmetric])
   394 by (auto simp add: algebra_simps poly_add poly_minus_def fun_eq poly_cmult minus_mult_left[symmetric])
   395 
   395 
   396 lemma (in comm_ring_1) poly_add_minus_mult_eq: "poly (p *** q +++ --(p *** r)) = poly (p *** (q +++ -- r))"
   396 lemma (in comm_ring_1) poly_add_minus_mult_eq: "poly (p *** q +++ --(p *** r)) = poly (p *** (q +++ -- r))"
   397 by (auto simp add: poly_add poly_minus_def fun_eq poly_mult poly_cmult right_distrib minus_mult_left[symmetric] minus_mult_right[symmetric])
   397 by (auto simp add: poly_add poly_minus_def fun_eq poly_mult poly_cmult distrib_left minus_mult_left[symmetric] minus_mult_right[symmetric])
   398 
   398 
   399 subclass (in idom_char_0) comm_ring_1 ..
   399 subclass (in idom_char_0) comm_ring_1 ..
   400 lemma (in idom_char_0) poly_mult_left_cancel: "(poly (p *** q) = poly (p *** r)) = (poly p = poly [] | poly q = poly r)"
   400 lemma (in idom_char_0) poly_mult_left_cancel: "(poly (p *** q) = poly (p *** r)) = (poly p = poly [] | poly q = poly r)"
   401 proof-
   401 proof-
   402   have "poly (p *** q) = poly (p *** r) \<longleftrightarrow> poly (p *** q +++ -- (p *** r)) = poly []" by (simp only: poly_add_minus_zero_iff)
   402   have "poly (p *** q) = poly (p *** r) \<longleftrightarrow> poly (p *** q +++ -- (p *** r)) = poly []" by (simp only: poly_add_minus_zero_iff)
   456 
   456 
   457 
   457 
   458 text{*Basics of divisibility.*}
   458 text{*Basics of divisibility.*}
   459 
   459 
   460 lemma (in idom) poly_primes: "([a, 1] divides (p *** q)) = ([a, 1] divides p | [a, 1] divides q)"
   460 lemma (in idom) poly_primes: "([a, 1] divides (p *** q)) = ([a, 1] divides p | [a, 1] divides q)"
   461 apply (auto simp add: divides_def fun_eq poly_mult poly_add poly_cmult left_distrib [symmetric])
   461 apply (auto simp add: divides_def fun_eq poly_mult poly_add poly_cmult distrib_right [symmetric])
   462 apply (drule_tac x = "uminus a" in spec)
   462 apply (drule_tac x = "uminus a" in spec)
   463 apply (simp add: poly_linear_divides poly_add poly_cmult left_distrib [symmetric])
   463 apply (simp add: poly_linear_divides poly_add poly_cmult distrib_right [symmetric])
   464 apply (cases "p = []")
   464 apply (cases "p = []")
   465 apply (rule exI[where x="[]"])
   465 apply (rule exI[where x="[]"])
   466 apply simp
   466 apply simp
   467 apply (cases "q = []")
   467 apply (cases "q = []")
   468 apply (erule allE[where x="[]"], simp)
   468 apply (erule allE[where x="[]"], simp)
   469 
   469 
   470 apply clarsimp
   470 apply clarsimp
   471 apply (cases "\<exists>q\<Colon>'a list. p = a %* q +++ ((0\<Colon>'a) # q)")
   471 apply (cases "\<exists>q\<Colon>'a list. p = a %* q +++ ((0\<Colon>'a) # q)")
   472 apply (clarsimp simp add: poly_add poly_cmult)
   472 apply (clarsimp simp add: poly_add poly_cmult)
   473 apply (rule_tac x="qa" in exI)
   473 apply (rule_tac x="qa" in exI)
   474 apply (simp add: left_distrib [symmetric])
   474 apply (simp add: distrib_right [symmetric])
   475 apply clarsimp
   475 apply clarsimp
   476 
   476 
   477 apply (auto simp add: right_minus poly_linear_divides poly_add poly_cmult left_distrib [symmetric])
   477 apply (auto simp add: right_minus poly_linear_divides poly_add poly_cmult distrib_right [symmetric])
   478 apply (rule_tac x = "pmult qa q" in exI)
   478 apply (rule_tac x = "pmult qa q" in exI)
   479 apply (rule_tac [2] x = "pmult p qa" in exI)
   479 apply (rule_tac [2] x = "pmult p qa" in exI)
   480 apply (auto simp add: poly_add poly_mult poly_cmult mult_ac)
   480 apply (auto simp add: poly_add poly_mult poly_cmult mult_ac)
   481 done
   481 done
   482 
   482 
   507 
   507 
   508 lemma (in comm_semiring_0) poly_divides_add:
   508 lemma (in comm_semiring_0) poly_divides_add:
   509    "[| p divides q; p divides r |] ==> p divides (q +++ r)"
   509    "[| p divides q; p divides r |] ==> p divides (q +++ r)"
   510 apply (simp add: divides_def, auto)
   510 apply (simp add: divides_def, auto)
   511 apply (rule_tac x = "padd qa qaa" in exI)
   511 apply (rule_tac x = "padd qa qaa" in exI)
   512 apply (auto simp add: poly_add fun_eq poly_mult right_distrib)
   512 apply (auto simp add: poly_add fun_eq poly_mult distrib_left)
   513 done
   513 done
   514 
   514 
   515 lemma (in comm_ring_1) poly_divides_diff:
   515 lemma (in comm_ring_1) poly_divides_diff:
   516    "[| p divides q; p divides (q +++ r) |] ==> p divides r"
   516    "[| p divides q; p divides (q +++ r) |] ==> p divides r"
   517 apply (simp add: divides_def, auto)
   517 apply (simp add: divides_def, auto)
   603 apply (drule poly_order_exists_lemma [where a=a], assumption, clarify)
   603 apply (drule poly_order_exists_lemma [where a=a], assumption, clarify)
   604 apply (rule_tac x = n in exI, safe)
   604 apply (rule_tac x = n in exI, safe)
   605 apply (unfold divides_def)
   605 apply (unfold divides_def)
   606 apply (rule_tac x = q in exI)
   606 apply (rule_tac x = q in exI)
   607 apply (induct_tac "n", simp)
   607 apply (induct_tac "n", simp)
   608 apply (simp (no_asm_simp) add: poly_add poly_cmult poly_mult right_distrib mult_ac)
   608 apply (simp (no_asm_simp) add: poly_add poly_cmult poly_mult distrib_left mult_ac)
   609 apply safe
   609 apply safe
   610 apply (subgoal_tac "?poly (?mulexp n [uminus a, one] q) \<noteq> ?poly (pmult (?pexp [uminus a, one] (Suc n)) qa)")
   610 apply (subgoal_tac "?poly (?mulexp n [uminus a, one] q) \<noteq> ?poly (pmult (?pexp [uminus a, one] (Suc n)) qa)")
   611 apply simp
   611 apply simp
   612 apply (induct_tac "n")
   612 apply (induct_tac "n")
   613 apply (simp del: pmult_Cons pexp_Suc)
   613 apply (simp del: pmult_Cons pexp_Suc)
   946   ultimately show ?case by blast
   946   ultimately show ?case by blast
   947 next
   947 next
   948   case (Suc n a p)
   948   case (Suc n a p)
   949   have eq: "poly ([a,1] %^(Suc n) *** p) = poly ([a,1] %^ n *** ([a,1] *** p))"
   949   have eq: "poly ([a,1] %^(Suc n) *** p) = poly ([a,1] %^ n *** ([a,1] *** p))"
   950     apply (rule ext, simp add: poly_mult poly_add poly_cmult)
   950     apply (rule ext, simp add: poly_mult poly_add poly_cmult)
   951     by (simp add: mult_ac add_ac right_distrib)
   951     by (simp add: mult_ac add_ac distrib_left)
   952   note deq = degree_unique[OF eq]
   952   note deq = degree_unique[OF eq]
   953   {assume p: "poly p = poly []"
   953   {assume p: "poly p = poly []"
   954     with eq have eq': "poly ([a,1] %^(Suc n) *** p) = poly []"
   954     with eq have eq': "poly ([a,1] %^(Suc n) *** p) = poly []"
   955       by - (rule ext,simp add: poly_mult poly_cmult poly_add)
   955       by - (rule ext,simp add: poly_mult poly_cmult poly_add)
   956     from degree_unique[OF eq'] p have ?case by (simp add: degree_def)}
   956     from degree_unique[OF eq'] p have ?case by (simp add: degree_def)}