| 13936 |      1 | (*
 | 
|  |      2 |   Title:     Univariate Polynomials
 | 
|  |      3 |   Id:        $Id$
 | 
|  |      4 |   Author:    Clemens Ballarin, started 9 December 1996
 | 
|  |      5 |   Copyright: Clemens Ballarin
 | 
|  |      6 | *)
 | 
|  |      7 | 
 | 
|  |      8 | header {* Univariate Polynomials *}
 | 
|  |      9 | 
 | 
|  |     10 | theory UnivPoly2 = Abstract:
 | 
|  |     11 | 
 | 
|  |     12 | (* already proved in Finite_Set.thy
 | 
|  |     13 | 
 | 
|  |     14 | lemma setsum_cong:
 | 
|  |     15 |   "[| A = B; !!i. i : B ==> f i = g i |] ==> setsum f A = setsum g B"
 | 
|  |     16 | proof -
 | 
|  |     17 |   assume prems: "A = B" "!!i. i : B ==> f i = g i"
 | 
|  |     18 |   show ?thesis
 | 
|  |     19 |   proof (cases "finite B")
 | 
|  |     20 |     case True
 | 
|  |     21 |     then have "!!A. [| A = B; !!i. i : B ==> f i = g i |] ==>
 | 
|  |     22 |       setsum f A = setsum g B"
 | 
|  |     23 |     proof induct
 | 
|  |     24 |       case empty thus ?case by simp
 | 
|  |     25 |     next
 | 
|  |     26 |       case insert thus ?case by simp
 | 
|  |     27 |     qed
 | 
|  |     28 |     with prems show ?thesis by simp
 | 
|  |     29 |   next
 | 
|  |     30 |     case False with prems show ?thesis by (simp add: setsum_def)
 | 
|  |     31 |   qed
 | 
|  |     32 | qed
 | 
|  |     33 | *)
 | 
|  |     34 | 
 | 
|  |     35 | (* Instruct simplifier to simplify assumptions introduced by congs.
 | 
|  |     36 |    This makes setsum_cong more convenient to use, because assumptions
 | 
|  |     37 |    like i:{m..n} get simplified (to m <= i & i <= n). *)
 | 
|  |     38 | 
 | 
| 14590 |     39 | declare setsum_cong [cong]
 | 
| 13936 |     40 | 
 | 
| 14590 |     41 | ML_setup {* 
 | 
|  |     42 |   simpset_ref() := simpset() setsubgoaler asm_full_simp_tac;
 | 
|  |     43 | *}
 | 
| 13936 |     44 | 
 | 
|  |     45 | section {* Definition of type up *}
 | 
|  |     46 | 
 | 
|  |     47 | constdefs
 | 
|  |     48 |   bound  :: "[nat, nat => 'a::zero] => bool"
 | 
|  |     49 |   "bound n f == (ALL i. n < i --> f i = 0)"
 | 
|  |     50 | 
 | 
|  |     51 | lemma boundI [intro!]: "[| !! m. n < m ==> f m = 0 |] ==> bound n f"
 | 
|  |     52 | proof (unfold bound_def)
 | 
|  |     53 | qed fast
 | 
|  |     54 | 
 | 
|  |     55 | lemma boundE [elim?]: "[| bound n f; (!! m. n < m ==> f m = 0) ==> P |] ==> P"
 | 
|  |     56 | proof (unfold bound_def)
 | 
|  |     57 | qed fast
 | 
|  |     58 | 
 | 
|  |     59 | lemma boundD [dest]: "[| bound n f; n < m |] ==> f m = 0"
 | 
|  |     60 | proof (unfold bound_def)
 | 
|  |     61 | qed fast
 | 
|  |     62 | 
 | 
|  |     63 | lemma bound_below:
 | 
|  |     64 |   assumes bound: "bound m f" and nonzero: "f n ~= 0" shows "n <= m"
 | 
|  |     65 | proof (rule classical)
 | 
|  |     66 |   assume "~ ?thesis"
 | 
|  |     67 |   then have "m < n" by arith
 | 
|  |     68 |   with bound have "f n = 0" ..
 | 
|  |     69 |   with nonzero show ?thesis by contradiction
 | 
|  |     70 | qed
 | 
|  |     71 | 
 | 
|  |     72 | typedef (UP)
 | 
|  |     73 |   ('a) up = "{f :: nat => 'a::zero. EX n. bound n f}"
 | 
|  |     74 | by (rule+)   (* Question: what does trace_rule show??? *)
 | 
|  |     75 | 
 | 
|  |     76 | section {* Constants *}
 | 
|  |     77 | 
 | 
|  |     78 | consts
 | 
|  |     79 |   coeff  :: "['a up, nat] => ('a::zero)"
 | 
|  |     80 |   monom  :: "['a::zero, nat] => 'a up"              ("(3_*X^/_)" [71, 71] 70)
 | 
|  |     81 |   "*s"   :: "['a::{zero, times}, 'a up] => 'a up"   (infixl 70)
 | 
|  |     82 | 
 | 
|  |     83 | defs
 | 
|  |     84 |   coeff_def: "coeff p n == Rep_UP p n"
 | 
|  |     85 |   monom_def: "monom a n == Abs_UP (%i. if i=n then a else 0)"
 | 
|  |     86 |   smult_def: "a *s p == Abs_UP (%i. a * Rep_UP p i)"
 | 
|  |     87 | 
 | 
|  |     88 | lemma coeff_bound_ex: "EX n. bound n (coeff p)"
 | 
|  |     89 | proof -
 | 
|  |     90 |   have "(%n. coeff p n) : UP" by (simp add: coeff_def Rep_UP)
 | 
|  |     91 |   then obtain n where "bound n (coeff p)" by (unfold UP_def) fast
 | 
|  |     92 |   then show ?thesis ..
 | 
|  |     93 | qed
 | 
|  |     94 |   
 | 
|  |     95 | lemma bound_coeff_obtain:
 | 
|  |     96 |   assumes prem: "(!!n. bound n (coeff p) ==> P)" shows "P"
 | 
|  |     97 | proof -
 | 
|  |     98 |   have "(%n. coeff p n) : UP" by (simp add: coeff_def Rep_UP)
 | 
|  |     99 |   then obtain n where "bound n (coeff p)" by (unfold UP_def) fast
 | 
|  |    100 |   with prem show P .
 | 
|  |    101 | qed
 | 
|  |    102 | 
 | 
|  |    103 | text {* Ring operations *}
 | 
|  |    104 | 
 | 
|  |    105 | instance up :: (zero) zero ..
 | 
|  |    106 | instance up :: (one) one ..
 | 
|  |    107 | instance up :: (plus) plus ..
 | 
|  |    108 | instance up :: (minus) minus ..
 | 
|  |    109 | instance up :: (times) times ..
 | 
|  |    110 | instance up :: (inverse) inverse ..
 | 
|  |    111 | instance up :: (power) power ..
 | 
|  |    112 | 
 | 
|  |    113 | defs
 | 
|  |    114 |   up_add_def:	"p + q == Abs_UP (%n. Rep_UP p n + Rep_UP q n)"
 | 
|  |    115 |   up_mult_def:  "p * q == Abs_UP (%n::nat. setsum
 | 
|  |    116 | 		     (%i. Rep_UP p i * Rep_UP q (n-i)) {..n})"
 | 
|  |    117 |   up_zero_def:  "0 == monom 0 0"
 | 
|  |    118 |   up_one_def:   "1 == monom 1 0"
 | 
|  |    119 |   up_uminus_def:"- p == (- 1) *s p"
 | 
|  |    120 |                 (* easier to use than "Abs_UP (%i. - Rep_UP p i)" *)
 | 
|  |    121 |                 (* note: - 1 is different from -1; latter is of class number *)
 | 
|  |    122 | 
 | 
|  |    123 |   up_minus_def:   "(a::'a::{plus, minus} up) - b == a + (-b)"
 | 
|  |    124 |   up_inverse_def: "inverse (a::'a::{zero, one, times, inverse} up) == 
 | 
|  |    125 |                      (if a dvd 1 then THE x. a*x = 1 else 0)"
 | 
|  |    126 |   up_divide_def:  "(a::'a::{times, inverse} up) / b == a * inverse b"
 | 
|  |    127 |   up_power_def:   "(a::'a::{one, times, power} up) ^ n ==
 | 
|  |    128 |                      nat_rec 1 (%u b. b * a) n"
 | 
|  |    129 | 
 | 
|  |    130 | subsection {* Effect of operations on coefficients *}
 | 
|  |    131 | 
 | 
|  |    132 | lemma coeff_monom [simp]: "coeff (monom a m) n = (if m=n then a else 0)"
 | 
|  |    133 | proof -
 | 
|  |    134 |   have "(%n. if n = m then a else 0) : UP"
 | 
|  |    135 |     using UP_def by force
 | 
|  |    136 |   from this show ?thesis
 | 
|  |    137 |     by (simp add: coeff_def monom_def Abs_UP_inverse Rep_UP)
 | 
|  |    138 | qed
 | 
|  |    139 | 
 | 
|  |    140 | lemma coeff_zero [simp]: "coeff 0 n = 0"
 | 
|  |    141 | proof (unfold up_zero_def)
 | 
|  |    142 | qed simp
 | 
|  |    143 | 
 | 
|  |    144 | lemma coeff_one [simp]: "coeff 1 n = (if n=0 then 1 else 0)"
 | 
|  |    145 | proof (unfold up_one_def)
 | 
|  |    146 | qed simp
 | 
|  |    147 | 
 | 
|  |    148 | (* term order
 | 
|  |    149 | lemma coeff_smult [simp]: "coeff (a *s p) n = (a::'a::ring) * coeff p n"
 | 
|  |    150 | proof -
 | 
|  |    151 |   have "!!f. f : UP ==> (%n. a * f n) : UP"
 | 
|  |    152 |     by (unfold UP_def) (force simp add: ring_simps)
 | 
|  |    153 | *)      (* this force step is slow *)
 | 
|  |    154 | (*  then show ?thesis
 | 
|  |    155 |     apply (simp add: coeff_def smult_def Abs_UP_inverse Rep_UP)
 | 
|  |    156 | qed
 | 
|  |    157 | *)
 | 
|  |    158 | lemma coeff_smult [simp]: "coeff (a *s p) n = (a::'a::ring) * coeff p n"
 | 
|  |    159 | proof -
 | 
|  |    160 |   have "Rep_UP p : UP ==> (%n. a * Rep_UP p n) : UP"
 | 
|  |    161 |     by (unfold UP_def) (force simp add: ring_simps)
 | 
|  |    162 |       (* this force step is slow *)
 | 
|  |    163 |   then show ?thesis
 | 
|  |    164 |     by (simp add: coeff_def smult_def Abs_UP_inverse Rep_UP)
 | 
|  |    165 | qed
 | 
|  |    166 | 
 | 
|  |    167 | lemma coeff_add [simp]: "coeff (p+q) n = (coeff p n + coeff q n::'a::ring)"
 | 
|  |    168 | proof -
 | 
|  |    169 |   {
 | 
|  |    170 |     fix f g
 | 
|  |    171 |     assume fup: "(f::nat=>'a::ring) : UP" and gup: "(g::nat=>'a::ring) : UP"
 | 
|  |    172 |     have "(%i. f i + g i) : UP"
 | 
|  |    173 |     proof -
 | 
|  |    174 |       from fup obtain n where boundn: "bound n f"
 | 
|  |    175 | 	by (unfold UP_def) fast
 | 
|  |    176 |       from gup obtain m where boundm: "bound m g"
 | 
|  |    177 | 	by (unfold UP_def) fast
 | 
|  |    178 |       have "bound (max n m) (%i. (f i + g i))"
 | 
|  |    179 |       proof
 | 
|  |    180 | 	fix i
 | 
|  |    181 | 	assume "max n m < i"
 | 
|  |    182 | 	with boundn and boundm show "f i + g i = 0"
 | 
|  |    183 |           by (fastsimp simp add: ring_simps)
 | 
|  |    184 |       qed
 | 
|  |    185 |       then show "(%i. (f i + g i)) : UP"
 | 
|  |    186 | 	by (unfold UP_def) fast
 | 
|  |    187 |     qed
 | 
|  |    188 |   }
 | 
|  |    189 |   then show ?thesis
 | 
|  |    190 |     by (simp add: coeff_def up_add_def Abs_UP_inverse Rep_UP)
 | 
|  |    191 | qed
 | 
|  |    192 | 
 | 
|  |    193 | lemma coeff_mult [simp]:
 | 
|  |    194 |   "coeff (p * q) n = (setsum (%i. coeff p i * coeff q (n-i)) {..n}::'a::ring)"
 | 
|  |    195 | proof -
 | 
|  |    196 |   {
 | 
|  |    197 |     fix f g
 | 
|  |    198 |     assume fup: "(f::nat=>'a::ring) : UP" and gup: "(g::nat=>'a::ring) : UP"
 | 
|  |    199 |     have "(%n. setsum (%i. f i * g (n-i)) {..n}) : UP"
 | 
|  |    200 |     proof -
 | 
|  |    201 |       from fup obtain n where "bound n f"
 | 
|  |    202 | 	by (unfold UP_def) fast
 | 
|  |    203 |       from gup obtain m where "bound m g"
 | 
|  |    204 | 	by (unfold UP_def) fast
 | 
|  |    205 |       have "bound (n + m) (%n. setsum (%i. f i * g (n-i)) {..n})"
 | 
|  |    206 |       proof
 | 
|  |    207 | 	fix k
 | 
|  |    208 | 	assume bound: "n + m < k"
 | 
|  |    209 | 	{
 | 
|  |    210 | 	  fix i
 | 
|  |    211 | 	  have "f i * g (k-i) = 0"
 | 
|  |    212 | 	  proof cases
 | 
|  |    213 | 	    assume "n < i"
 | 
|  |    214 | 	    show ?thesis by (auto! simp add: ring_simps)
 | 
|  |    215 | 	  next
 | 
|  |    216 | 	    assume "~ (n < i)"
 | 
|  |    217 | 	    with bound have "m < k-i" by arith
 | 
|  |    218 | 	    then show ?thesis by (auto! simp add: ring_simps)
 | 
|  |    219 | 	  qed
 | 
|  |    220 | 	}
 | 
|  |    221 | 	then show "setsum (%i. f i * g (k-i)) {..k} = 0"
 | 
|  |    222 | 	  by (simp add: ring_simps)
 | 
|  |    223 |       qed
 | 
|  |    224 |       then show "(%n. setsum (%i. f i * g (n-i)) {..n}) : UP"
 | 
|  |    225 | 	by (unfold UP_def) fast
 | 
|  |    226 |     qed
 | 
|  |    227 |   }
 | 
|  |    228 |   then show ?thesis
 | 
|  |    229 |     by (simp add: coeff_def up_mult_def Abs_UP_inverse Rep_UP)
 | 
|  |    230 | qed
 | 
|  |    231 | 
 | 
|  |    232 | lemma coeff_uminus [simp]: "coeff (-p) n = (-coeff p n::'a::ring)"
 | 
|  |    233 | by (unfold up_uminus_def) (simp add: ring_simps)
 | 
|  |    234 | 
 | 
|  |    235 | (* Other lemmas *)
 | 
|  |    236 | 
 | 
|  |    237 | lemma up_eqI: assumes prem: "(!! n. coeff p n = coeff q n)" shows "p = q"
 | 
|  |    238 | proof -
 | 
|  |    239 |   have "p = Abs_UP (%u. Rep_UP p u)" by (simp add: Rep_UP_inverse)
 | 
|  |    240 |   also from prem have "... = Abs_UP (Rep_UP q)" by (simp only: coeff_def)
 | 
|  |    241 |   also have "... = q" by (simp add: Rep_UP_inverse)
 | 
|  |    242 |   finally show ?thesis .
 | 
|  |    243 | qed
 | 
|  |    244 | 
 | 
|  |    245 | (* ML_setup {* Addsimprocs [ring_simproc] *} *)
 | 
|  |    246 | 
 | 
|  |    247 | instance up :: (ring) ring
 | 
|  |    248 | proof
 | 
|  |    249 |   fix p q r :: "'a::ring up"
 | 
|  |    250 |   fix n
 | 
|  |    251 |   show "(p + q) + r = p + (q + r)"
 | 
|  |    252 |     by (rule up_eqI) simp
 | 
|  |    253 |   show "0 + p = p"
 | 
|  |    254 |     by (rule up_eqI) simp
 | 
|  |    255 |   show "(-p) + p = 0"
 | 
|  |    256 |     by (rule up_eqI) simp
 | 
|  |    257 |   show "p + q = q + p"
 | 
|  |    258 |     by (rule up_eqI) simp
 | 
|  |    259 |   show "(p * q) * r = p * (q * r)"
 | 
|  |    260 |   proof (rule up_eqI)
 | 
|  |    261 |     fix n 
 | 
|  |    262 |     {
 | 
|  |    263 |       fix k and a b c :: "nat=>'a::ring"
 | 
|  |    264 |       have "k <= n ==> 
 | 
|  |    265 | 	setsum (%j. setsum (%i. a i * b (j-i)) {..j} * c (n-j)) {..k} = 
 | 
|  |    266 | 	setsum (%j. a j * setsum  (%i. b i * c (n-j-i)) {..k-j}) {..k}"
 | 
|  |    267 | 	(is "_ ==> ?eq k")
 | 
|  |    268 |       proof (induct k)
 | 
|  |    269 | 	case 0 show ?case by simp
 | 
|  |    270 |       next
 | 
|  |    271 | 	case (Suc k)
 | 
|  |    272 | 	then have "k <= n" by arith
 | 
|  |    273 | 	then have "?eq k" by (rule Suc)
 | 
|  |    274 | 	then show ?case
 | 
|  |    275 | 	  by (simp add: Suc_diff_le natsum_ldistr)
 | 
|  |    276 |       qed
 | 
|  |    277 |     }
 | 
|  |    278 |     then show "coeff ((p * q) * r) n = coeff (p * (q * r)) n"
 | 
|  |    279 |       by simp
 | 
|  |    280 |   qed
 | 
|  |    281 |   show "1 * p = p"
 | 
|  |    282 |   proof (rule up_eqI)
 | 
|  |    283 |     fix n
 | 
|  |    284 |     show "coeff (1 * p) n = coeff p n"
 | 
|  |    285 |     proof (cases n)
 | 
|  |    286 |       case 0 then show ?thesis by simp
 | 
|  |    287 |     next
 | 
|  |    288 |       case Suc then show ?thesis by (simp del: natsum_Suc add: natsum_Suc2)
 | 
|  |    289 |     qed
 | 
|  |    290 |   qed
 | 
|  |    291 |   show "(p + q) * r = p * r + q * r"
 | 
|  |    292 |     by (rule up_eqI) simp
 | 
|  |    293 |   show "p * q = q * p"
 | 
|  |    294 |   proof (rule up_eqI)
 | 
|  |    295 |     fix n 
 | 
|  |    296 |     {
 | 
|  |    297 |       fix k
 | 
|  |    298 |       fix a b :: "nat=>'a::ring"
 | 
|  |    299 |       have "k <= n ==> 
 | 
|  |    300 | 	setsum (%i. a i * b (n-i)) {..k} =
 | 
|  |    301 | 	setsum (%i. a (k-i) * b (i+n-k)) {..k}"
 | 
|  |    302 | 	(is "_ ==> ?eq k")
 | 
|  |    303 |       proof (induct k)
 | 
|  |    304 | 	case 0 show ?case by simp
 | 
|  |    305 |       next
 | 
|  |    306 | 	case (Suc k) then show ?case by (subst natsum_Suc2) simp
 | 
|  |    307 |       qed
 | 
|  |    308 |     }
 | 
|  |    309 |     then show "coeff (p * q) n = coeff (q * p) n"
 | 
|  |    310 |       by simp
 | 
|  |    311 |   qed
 | 
|  |    312 | 
 | 
|  |    313 |   show "p - q = p + (-q)"
 | 
|  |    314 |     by (simp add: up_minus_def)
 | 
|  |    315 |   show "inverse p = (if p dvd 1 then THE x. p*x = 1 else 0)"
 | 
|  |    316 |     by (simp add: up_inverse_def)
 | 
|  |    317 |   show "p / q = p * inverse q"
 | 
|  |    318 |     by (simp add: up_divide_def)
 | 
|  |    319 |   show "p ^ n = nat_rec 1 (%u b. b * p) n"
 | 
|  |    320 |     by (simp add: up_power_def)
 | 
|  |    321 |   qed
 | 
|  |    322 | 
 | 
|  |    323 | (* Further properties of monom *)
 | 
|  |    324 | 
 | 
|  |    325 | lemma monom_zero [simp]:
 | 
|  |    326 |   "monom 0 n = 0"
 | 
|  |    327 |   by (simp add: monom_def up_zero_def)
 | 
|  |    328 | (* term order: application of coeff_mult goes wrong: rule not symmetric
 | 
|  |    329 | lemma monom_mult_is_smult:
 | 
|  |    330 |   "monom (a::'a::ring) 0 * p = a *s p"
 | 
|  |    331 | proof (rule up_eqI)
 | 
|  |    332 |   fix k
 | 
|  |    333 |   show "coeff (monom a 0 * p) k = coeff (a *s p) k"
 | 
|  |    334 |   proof (cases k)
 | 
|  |    335 |     case 0 then show ?thesis by simp
 | 
|  |    336 |   next
 | 
|  |    337 |     case Suc then show ?thesis by simp
 | 
|  |    338 |   qed
 | 
|  |    339 | qed
 | 
|  |    340 | *)
 | 
|  |    341 | ML_setup {* Delsimprocs [ring_simproc] *}
 | 
|  |    342 | 
 | 
|  |    343 | lemma monom_mult_is_smult:
 | 
|  |    344 |   "monom (a::'a::ring) 0 * p = a *s p"
 | 
|  |    345 | proof (rule up_eqI)
 | 
|  |    346 |   fix k
 | 
|  |    347 |   have "coeff (p * monom a 0) k = coeff (a *s p) k"
 | 
|  |    348 |   proof (cases k)
 | 
|  |    349 |     case 0 then show ?thesis by simp ring
 | 
|  |    350 |   next
 | 
|  |    351 |     case Suc then show ?thesis by (simp add: ring_simps) ring
 | 
|  |    352 |   qed
 | 
|  |    353 |   then show "coeff (monom a 0 * p) k = coeff (a *s p) k" by ring
 | 
|  |    354 | qed
 | 
|  |    355 | 
 | 
|  |    356 | ML_setup {* Addsimprocs [ring_simproc] *}
 | 
|  |    357 | 
 | 
|  |    358 | lemma monom_add [simp]:
 | 
|  |    359 |   "monom (a + b) n = monom (a::'a::ring) n + monom b n"
 | 
|  |    360 | by (rule up_eqI) simp
 | 
|  |    361 | 
 | 
|  |    362 | lemma monom_mult_smult:
 | 
|  |    363 |   "monom (a * b) n = a *s monom (b::'a::ring) n"
 | 
|  |    364 | by (rule up_eqI) simp
 | 
|  |    365 | 
 | 
|  |    366 | lemma monom_uminus [simp]:
 | 
|  |    367 |   "monom (-a) n = - monom (a::'a::ring) n"
 | 
|  |    368 | by (rule up_eqI) simp
 | 
|  |    369 | 
 | 
|  |    370 | lemma monom_one [simp]:
 | 
|  |    371 |   "monom 1 0 = 1"
 | 
|  |    372 | by (simp add: up_one_def)
 | 
|  |    373 | 
 | 
|  |    374 | lemma monom_inj:
 | 
|  |    375 |   "(monom a n = monom b n) = (a = b)"
 | 
|  |    376 | proof
 | 
|  |    377 |   assume "monom a n = monom b n"
 | 
|  |    378 |   then have "coeff (monom a n) n = coeff (monom b n) n" by simp
 | 
|  |    379 |   then show "a = b" by simp
 | 
|  |    380 | next
 | 
|  |    381 |   assume "a = b" then show "monom a n = monom b n" by simp
 | 
|  |    382 | qed
 | 
|  |    383 | 
 | 
|  |    384 | (* Properties of *s:
 | 
|  |    385 |    Polynomials form a module *)
 | 
|  |    386 | 
 | 
|  |    387 | lemma smult_l_distr:
 | 
|  |    388 |   "(a + b::'a::ring) *s p = a *s p + b *s p"
 | 
|  |    389 | by (rule up_eqI) simp
 | 
|  |    390 | 
 | 
|  |    391 | lemma smult_r_distr:
 | 
|  |    392 |   "(a::'a::ring) *s (p + q) = a *s p + a *s q"
 | 
|  |    393 | by (rule up_eqI) simp
 | 
|  |    394 | 
 | 
|  |    395 | lemma smult_assoc1:
 | 
|  |    396 |   "(a * b::'a::ring) *s p = a *s (b *s p)"
 | 
|  |    397 | by (rule up_eqI) simp
 | 
|  |    398 | 
 | 
|  |    399 | lemma smult_one [simp]:
 | 
|  |    400 |   "(1::'a::ring) *s p = p"
 | 
|  |    401 | by (rule up_eqI) simp
 | 
|  |    402 | 
 | 
|  |    403 | (* Polynomials form an algebra *)
 | 
|  |    404 | 
 | 
|  |    405 | ML_setup {* Delsimprocs [ring_simproc] *}
 | 
|  |    406 | 
 | 
|  |    407 | lemma smult_assoc2:
 | 
|  |    408 |   "(a *s p) * q = (a::'a::ring) *s (p * q)"
 | 
|  |    409 | by (rule up_eqI) (simp add: natsum_rdistr m_assoc)
 | 
|  |    410 | (* Simproc fails. *)
 | 
|  |    411 | 
 | 
|  |    412 | ML_setup {* Addsimprocs [ring_simproc] *}
 | 
|  |    413 | 
 | 
|  |    414 | (* the following can be derived from the above ones,
 | 
|  |    415 |    for generality reasons, it is therefore done *)
 | 
|  |    416 | 
 | 
|  |    417 | lemma smult_l_null [simp]:
 | 
|  |    418 |   "(0::'a::ring) *s p = 0"
 | 
|  |    419 | proof -
 | 
|  |    420 |   fix a
 | 
|  |    421 |   have "0 *s p = (0 *s p + a *s p) + - (a *s p)" by simp
 | 
|  |    422 |   also have "... = (0 + a) *s p + - (a *s p)" by (simp only: smult_l_distr)
 | 
|  |    423 |   also have "... = 0" by simp
 | 
|  |    424 |   finally show ?thesis .
 | 
|  |    425 | qed
 | 
|  |    426 | 
 | 
|  |    427 | lemma smult_r_null [simp]:
 | 
|  |    428 |   "(a::'a::ring) *s 0 = 0";
 | 
|  |    429 | proof -
 | 
|  |    430 |   fix p
 | 
|  |    431 |   have "a *s 0 = (a *s 0 + a *s p) + - (a *s p)" by simp
 | 
|  |    432 |   also have "... = a *s (0 + p) + - (a *s p)" by (simp only: smult_r_distr)
 | 
|  |    433 |   also have "... = 0" by simp
 | 
|  |    434 |   finally show ?thesis .
 | 
|  |    435 | qed
 | 
|  |    436 | 
 | 
|  |    437 | lemma smult_l_minus:
 | 
|  |    438 |   "(-a::'a::ring) *s p = - (a *s p)"
 | 
|  |    439 | proof -
 | 
|  |    440 |   have "(-a) *s p = (-a *s p + a *s p) + -(a *s p)" by simp 
 | 
|  |    441 |   also have "... = (-a + a) *s p + -(a *s p)" by (simp only: smult_l_distr)
 | 
|  |    442 |   also have "... = -(a *s p)" by simp
 | 
|  |    443 |   finally show ?thesis .
 | 
|  |    444 | qed
 | 
|  |    445 | 
 | 
|  |    446 | lemma smult_r_minus:
 | 
|  |    447 |   "(a::'a::ring) *s (-p) = - (a *s p)"
 | 
|  |    448 | proof -
 | 
|  |    449 |   have "a *s (-p) = (a *s -p + a *s p) + -(a *s p)" by simp
 | 
|  |    450 |   also have "... = a *s (-p + p) + -(a *s p)" by (simp only: smult_r_distr)
 | 
|  |    451 |   also have "... = -(a *s p)" by simp
 | 
|  |    452 |   finally show ?thesis .
 | 
|  |    453 | qed
 | 
|  |    454 | 
 | 
|  |    455 | section {* The degree function *}
 | 
|  |    456 | 
 | 
|  |    457 | constdefs
 | 
|  |    458 |   deg :: "('a::zero) up => nat"
 | 
|  |    459 |   "deg p == LEAST n. bound n (coeff p)"
 | 
|  |    460 | 
 | 
|  |    461 | lemma deg_aboveI:
 | 
|  |    462 |   "(!!m. n < m ==> coeff p m = 0) ==> deg p <= n"
 | 
|  |    463 | by (unfold deg_def) (fast intro: Least_le)
 | 
|  |    464 | 
 | 
|  |    465 | lemma deg_aboveD:
 | 
|  |    466 |   assumes prem: "deg p < m" shows "coeff p m = 0"
 | 
|  |    467 | proof -
 | 
|  |    468 |   obtain n where "bound n (coeff p)" by (rule bound_coeff_obtain)
 | 
|  |    469 |   then have "bound (deg p) (coeff p)" by (unfold deg_def, rule LeastI)
 | 
|  |    470 |   then show "coeff p m = 0" by (rule boundD)
 | 
|  |    471 | qed
 | 
|  |    472 | 
 | 
|  |    473 | lemma deg_belowI:
 | 
|  |    474 |   assumes prem: "n ~= 0 ==> coeff p n ~= 0" shows "n <= deg p"
 | 
|  |    475 | (* logically, this is a slightly stronger version of deg_aboveD *)
 | 
|  |    476 | proof (cases "n=0")
 | 
|  |    477 |   case True then show ?thesis by simp
 | 
|  |    478 | next
 | 
|  |    479 |   case False then have "coeff p n ~= 0" by (rule prem)
 | 
|  |    480 |   then have "~ deg p < n" by (fast dest: deg_aboveD)
 | 
|  |    481 |   then show ?thesis by arith
 | 
|  |    482 | qed
 | 
|  |    483 | 
 | 
|  |    484 | lemma lcoeff_nonzero_deg:
 | 
|  |    485 |   assumes deg: "deg p ~= 0" shows "coeff p (deg p) ~= 0"
 | 
|  |    486 | proof -
 | 
|  |    487 |   obtain m where "deg p <= m" and m_coeff: "coeff p m ~= 0"
 | 
|  |    488 |   proof -
 | 
|  |    489 |     have minus: "!!(n::nat) m. n ~= 0 ==> (n - Suc 0 < m) = (n <= m)"
 | 
|  |    490 |       by arith (* make public?, why does proof not work with "1" *)
 | 
|  |    491 |     from deg have "deg p - 1 < (LEAST n. bound n (coeff p))"
 | 
|  |    492 |       by (unfold deg_def) arith
 | 
|  |    493 |     then have "~ bound (deg p - 1) (coeff p)" by (rule not_less_Least)
 | 
|  |    494 |     then have "EX m. deg p - 1 < m & coeff p m ~= 0"
 | 
|  |    495 |       by (unfold bound_def) fast
 | 
|  |    496 |     then have "EX m. deg p <= m & coeff p m ~= 0" by (simp add: deg minus)
 | 
|  |    497 |     then show ?thesis by auto 
 | 
|  |    498 |   qed
 | 
|  |    499 |   with deg_belowI have "deg p = m" by fastsimp
 | 
|  |    500 |   with m_coeff show ?thesis by simp
 | 
|  |    501 | qed
 | 
|  |    502 | 
 | 
|  |    503 | lemma lcoeff_nonzero_nonzero:
 | 
|  |    504 |   assumes deg: "deg p = 0" and nonzero: "p ~= 0" shows "coeff p 0 ~= 0"
 | 
|  |    505 | proof -
 | 
|  |    506 |   have "EX m. coeff p m ~= 0"
 | 
|  |    507 |   proof (rule classical)
 | 
|  |    508 |     assume "~ ?thesis"
 | 
|  |    509 |     then have "p = 0" by (auto intro: up_eqI)
 | 
|  |    510 |     with nonzero show ?thesis by contradiction
 | 
|  |    511 |   qed
 | 
|  |    512 |   then obtain m where coeff: "coeff p m ~= 0" ..
 | 
|  |    513 |   then have "m <= deg p" by (rule deg_belowI)
 | 
|  |    514 |   then have "m = 0" by (simp add: deg)
 | 
|  |    515 |   with coeff show ?thesis by simp
 | 
|  |    516 | qed
 | 
|  |    517 | 
 | 
|  |    518 | lemma lcoeff_nonzero:
 | 
|  |    519 |   "p ~= 0 ==> coeff p (deg p) ~= 0"
 | 
|  |    520 | proof (cases "deg p = 0")
 | 
|  |    521 |   case True
 | 
|  |    522 |   assume "p ~= 0"
 | 
|  |    523 |   with True show ?thesis by (simp add: lcoeff_nonzero_nonzero)
 | 
|  |    524 | next
 | 
|  |    525 |   case False
 | 
|  |    526 |   assume "p ~= 0"
 | 
|  |    527 |   with False show ?thesis by (simp add: lcoeff_nonzero_deg)
 | 
|  |    528 | qed
 | 
|  |    529 | 
 | 
|  |    530 | lemma deg_eqI:
 | 
|  |    531 |   "[| !!m. n < m ==> coeff p m = 0;
 | 
|  |    532 |       !!n. n ~= 0 ==> coeff p n ~= 0|] ==> deg p = n"
 | 
|  |    533 | by (fast intro: le_anti_sym deg_aboveI deg_belowI)
 | 
|  |    534 | 
 | 
|  |    535 | (* Degree and polynomial operations *)
 | 
|  |    536 | 
 | 
|  |    537 | lemma deg_add [simp]:
 | 
|  |    538 |   "deg ((p::'a::ring up) + q) <= max (deg p) (deg q)"
 | 
|  |    539 | proof (cases "deg p <= deg q")
 | 
|  |    540 |   case True show ?thesis by (rule deg_aboveI) (simp add: True deg_aboveD) 
 | 
|  |    541 | next
 | 
|  |    542 |   case False show ?thesis by (rule deg_aboveI) (simp add: False deg_aboveD)
 | 
|  |    543 | qed
 | 
|  |    544 | 
 | 
|  |    545 | lemma deg_monom_ring:
 | 
|  |    546 |   "deg (monom a n::'a::ring up) <= n"
 | 
|  |    547 | by (rule deg_aboveI) simp
 | 
|  |    548 | 
 | 
|  |    549 | lemma deg_monom [simp]:
 | 
|  |    550 |   "a ~= 0 ==> deg (monom a n::'a::ring up) = n"
 | 
|  |    551 | by (fastsimp intro: le_anti_sym deg_aboveI deg_belowI)
 | 
|  |    552 | 
 | 
|  |    553 | lemma deg_const [simp]:
 | 
|  |    554 |   "deg (monom (a::'a::ring) 0) = 0"
 | 
|  |    555 | proof (rule le_anti_sym)
 | 
|  |    556 |   show "deg (monom a 0) <= 0" by (rule deg_aboveI) simp
 | 
|  |    557 | next
 | 
|  |    558 |   show "0 <= deg (monom a 0)" by (rule deg_belowI) simp
 | 
|  |    559 | qed
 | 
|  |    560 | 
 | 
|  |    561 | lemma deg_zero [simp]:
 | 
|  |    562 |   "deg 0 = 0"
 | 
|  |    563 | proof (rule le_anti_sym)
 | 
|  |    564 |   show "deg 0 <= 0" by (rule deg_aboveI) simp
 | 
|  |    565 | next
 | 
|  |    566 |   show "0 <= deg 0" by (rule deg_belowI) simp
 | 
|  |    567 | qed
 | 
|  |    568 | 
 | 
|  |    569 | lemma deg_one [simp]:
 | 
|  |    570 |   "deg 1 = 0"
 | 
|  |    571 | proof (rule le_anti_sym)
 | 
|  |    572 |   show "deg 1 <= 0" by (rule deg_aboveI) simp
 | 
|  |    573 | next
 | 
|  |    574 |   show "0 <= deg 1" by (rule deg_belowI) simp
 | 
|  |    575 | qed
 | 
|  |    576 | 
 | 
|  |    577 | lemma uminus_monom:
 | 
|  |    578 |   "!!a::'a::ring. (-a = 0) = (a = 0)"
 | 
|  |    579 | proof
 | 
|  |    580 |   fix a::"'a::ring"
 | 
|  |    581 |   assume "a = 0"
 | 
|  |    582 |   then show "-a = 0" by simp
 | 
|  |    583 | next
 | 
|  |    584 |   fix a::"'a::ring"
 | 
|  |    585 |   assume "- a = 0"
 | 
|  |    586 |   then have "-(- a) = 0" by simp
 | 
|  |    587 |   then show "a = 0" by simp
 | 
|  |    588 | qed
 | 
|  |    589 | 
 | 
|  |    590 | lemma deg_uminus [simp]:
 | 
|  |    591 |   "deg (-p::('a::ring) up) = deg p"
 | 
|  |    592 | proof (rule le_anti_sym)
 | 
|  |    593 |   show "deg (- p) <= deg p" by (simp add: deg_aboveI deg_aboveD)
 | 
|  |    594 | next
 | 
|  |    595 |   show "deg p <= deg (- p)" 
 | 
|  |    596 |   by (simp add: deg_belowI lcoeff_nonzero_deg uminus_monom)
 | 
|  |    597 | qed
 | 
|  |    598 | 
 | 
|  |    599 | lemma deg_smult_ring:
 | 
|  |    600 |   "deg ((a::'a::ring) *s p) <= (if a = 0 then 0 else deg p)"
 | 
|  |    601 | proof (cases "a = 0")
 | 
|  |    602 | qed (simp add: deg_aboveI deg_aboveD)+
 | 
|  |    603 | 
 | 
|  |    604 | lemma deg_smult [simp]:
 | 
|  |    605 |   "deg ((a::'a::domain) *s p) = (if a = 0 then 0 else deg p)"
 | 
|  |    606 | proof (rule le_anti_sym)
 | 
|  |    607 |   show "deg (a *s p) <= (if a = 0 then 0 else deg p)" by (rule deg_smult_ring)
 | 
|  |    608 | next
 | 
|  |    609 |   show "(if a = 0 then 0 else deg p) <= deg (a *s p)"
 | 
|  |    610 |   proof (cases "a = 0")
 | 
|  |    611 |   qed (simp, simp add: deg_belowI lcoeff_nonzero_deg integral_iff)
 | 
|  |    612 | qed
 | 
|  |    613 | 
 | 
|  |    614 | lemma deg_mult_ring:
 | 
|  |    615 |   "deg (p * q::'a::ring up) <= deg p + deg q"
 | 
|  |    616 | proof (rule deg_aboveI)
 | 
|  |    617 |   fix m
 | 
|  |    618 |   assume boundm: "deg p + deg q < m"
 | 
|  |    619 |   {
 | 
|  |    620 |     fix k i
 | 
|  |    621 |     assume boundk: "deg p + deg q < k"
 | 
|  |    622 |     then have "coeff p i * coeff q (k - i) = 0"
 | 
|  |    623 |     proof (cases "deg p < i")
 | 
|  |    624 |       case True then show ?thesis by (simp add: deg_aboveD)
 | 
|  |    625 |     next
 | 
|  |    626 |       case False with boundk have "deg q < k - i" by arith
 | 
|  |    627 |       then show ?thesis by (simp add: deg_aboveD)
 | 
|  |    628 |     qed
 | 
|  |    629 |   }
 | 
|  |    630 |       (* This is similar to bound_mult_zero and deg_above_mult_zero in the old
 | 
|  |    631 |          proofs. *)
 | 
|  |    632 |   with boundm show "coeff (p * q) m = 0" by simp
 | 
|  |    633 | qed
 | 
|  |    634 | 
 | 
|  |    635 | lemma deg_mult [simp]:
 | 
|  |    636 |   "[| (p::'a::domain up) ~= 0; q ~= 0|] ==> deg (p * q) = deg p + deg q"
 | 
|  |    637 | proof (rule le_anti_sym)
 | 
|  |    638 |   show "deg (p * q) <= deg p + deg q" by (rule deg_mult_ring)
 | 
|  |    639 | next
 | 
|  |    640 |   let ?s = "(%i. coeff p i * coeff q (deg p + deg q - i))"
 | 
|  |    641 |   assume nz: "p ~= 0" "q ~= 0"
 | 
|  |    642 |   have less_add_diff: "!!(k::nat) n m. k < n ==> m < n + m - k" by arith
 | 
|  |    643 |   show "deg p + deg q <= deg (p * q)"
 | 
|  |    644 |   proof (rule deg_belowI, simp)
 | 
|  |    645 |     have "setsum ?s {.. deg p + deg q}
 | 
|  |    646 |       = setsum ?s ({.. deg p(} Un {deg p .. deg p + deg q})"
 | 
|  |    647 |       by (simp only: ivl_disj_un_one)
 | 
|  |    648 |     also have "... = setsum ?s {deg p .. deg p + deg q}"
 | 
|  |    649 |       by (simp add: setsum_Un_disjoint ivl_disj_int_one
 | 
|  |    650 |         setsum_0 deg_aboveD less_add_diff)
 | 
|  |    651 |     also have "... = setsum ?s ({deg p} Un {)deg p .. deg p + deg q})"
 | 
|  |    652 |       by (simp only: ivl_disj_un_singleton)
 | 
|  |    653 |     also have "... = coeff p (deg p) * coeff q (deg q)" 
 | 
|  |    654 |       by (simp add: setsum_Un_disjoint ivl_disj_int_singleton 
 | 
|  |    655 |         setsum_0 deg_aboveD)
 | 
|  |    656 |     finally have "setsum ?s {.. deg p + deg q} 
 | 
|  |    657 |       = coeff p (deg p) * coeff q (deg q)" .
 | 
|  |    658 |     with nz show "setsum ?s {.. deg p + deg q} ~= 0"
 | 
|  |    659 |       by (simp add: integral_iff lcoeff_nonzero)
 | 
|  |    660 |     qed
 | 
|  |    661 |   qed
 | 
|  |    662 | 
 | 
|  |    663 | lemma coeff_natsum:
 | 
|  |    664 |   "((coeff (setsum p A) k)::'a::ring) = 
 | 
|  |    665 |    setsum (%i. coeff (p i) k) A"
 | 
|  |    666 | proof (cases "finite A")
 | 
|  |    667 |   case True then show ?thesis by induct auto
 | 
|  |    668 | next
 | 
|  |    669 |   case False then show ?thesis by (simp add: setsum_def)
 | 
|  |    670 | qed
 | 
|  |    671 | (* Instance of a more general result!!! *)
 | 
|  |    672 | 
 | 
|  |    673 | (*
 | 
|  |    674 | lemma coeff_natsum:
 | 
|  |    675 |   "((coeff (setsum p {..n::nat}) k)::'a::ring) = 
 | 
|  |    676 |    setsum (%i. coeff (p i) k) {..n}"
 | 
|  |    677 | by (induct n) auto
 | 
|  |    678 | *)
 | 
|  |    679 | 
 | 
|  |    680 | lemma up_repr:
 | 
|  |    681 |   "setsum (%i. monom (coeff p i) i) {..deg (p::'a::ring up)} = p"
 | 
|  |    682 | proof (rule up_eqI)
 | 
|  |    683 |   let ?s = "(%i. monom (coeff p i) i)"
 | 
|  |    684 |   fix k
 | 
|  |    685 |   show "coeff (setsum ?s {..deg p}) k = coeff p k"
 | 
|  |    686 |   proof (cases "k <= deg p")
 | 
|  |    687 |     case True
 | 
|  |    688 |     hence "coeff (setsum ?s {..deg p}) k = 
 | 
|  |    689 |           coeff (setsum ?s ({..k} Un {)k..deg p})) k"
 | 
|  |    690 |       by (simp only: ivl_disj_un_one)
 | 
|  |    691 |     also from True
 | 
|  |    692 |     have "... = coeff (setsum ?s {..k}) k"
 | 
|  |    693 |       by (simp add: setsum_Un_disjoint ivl_disj_int_one order_less_imp_not_eq2
 | 
|  |    694 |         setsum_0 coeff_natsum )
 | 
|  |    695 |     also
 | 
|  |    696 |     have "... = coeff (setsum ?s ({..k(} Un {k})) k"
 | 
|  |    697 |       by (simp only: ivl_disj_un_singleton)
 | 
|  |    698 |     also have "... = coeff p k"
 | 
|  |    699 |       by (simp add: setsum_Un_disjoint ivl_disj_int_singleton 
 | 
|  |    700 |         setsum_0 coeff_natsum deg_aboveD)
 | 
|  |    701 |     finally show ?thesis .
 | 
|  |    702 |   next
 | 
|  |    703 |     case False
 | 
|  |    704 |     hence "coeff (setsum ?s {..deg p}) k = 
 | 
|  |    705 |           coeff (setsum ?s ({..deg p(} Un {deg p})) k"
 | 
|  |    706 |       by (simp only: ivl_disj_un_singleton)
 | 
|  |    707 |     also from False have "... = coeff p k"
 | 
|  |    708 |       by (simp add: setsum_Un_disjoint ivl_disj_int_singleton 
 | 
|  |    709 |         setsum_0 coeff_natsum deg_aboveD)
 | 
|  |    710 |     finally show ?thesis .
 | 
|  |    711 |   qed
 | 
|  |    712 | qed
 | 
|  |    713 | 
 | 
|  |    714 | lemma up_repr_le:
 | 
|  |    715 |   "deg (p::'a::ring up) <= n ==> setsum (%i. monom (coeff p i) i) {..n} = p"
 | 
|  |    716 | proof -
 | 
|  |    717 |   let ?s = "(%i. monom (coeff p i) i)"
 | 
|  |    718 |   assume "deg p <= n"
 | 
|  |    719 |   then have "setsum ?s {..n} = setsum ?s ({..deg p} Un {)deg p..n})"
 | 
|  |    720 |     by (simp only: ivl_disj_un_one)
 | 
|  |    721 |   also have "... = setsum ?s {..deg p}"
 | 
|  |    722 |     by (simp add: setsum_Un_disjoint ivl_disj_int_one
 | 
|  |    723 |       setsum_0 deg_aboveD)
 | 
|  |    724 |   also have "... = p" by (rule up_repr)
 | 
|  |    725 |   finally show ?thesis .
 | 
|  |    726 | qed
 | 
|  |    727 | 
 | 
|  |    728 | instance up :: ("domain") "domain"
 | 
|  |    729 | proof
 | 
|  |    730 |   show "1 ~= (0::'a up)"
 | 
|  |    731 |   proof (* notI is applied here *)
 | 
|  |    732 |     assume "1 = (0::'a up)"
 | 
|  |    733 |     hence "coeff 1 0 = (coeff 0 0::'a)" by simp
 | 
|  |    734 |     hence "1 = (0::'a)" by simp
 | 
|  |    735 |     with one_not_zero show "False" by contradiction
 | 
|  |    736 |   qed
 | 
|  |    737 | next
 | 
|  |    738 |   fix p q :: "'a::domain up"
 | 
|  |    739 |   assume pq: "p * q = 0"
 | 
|  |    740 |   show "p = 0 | q = 0"
 | 
|  |    741 |   proof (rule classical)
 | 
|  |    742 |     assume c: "~ (p = 0 | q = 0)"
 | 
|  |    743 |     then have "deg p + deg q = deg (p * q)" by simp
 | 
|  |    744 |     also from pq have "... = 0" by simp
 | 
|  |    745 |     finally have "deg p + deg q = 0" .
 | 
|  |    746 |     then have f1: "deg p = 0 & deg q = 0" by simp
 | 
|  |    747 |     from f1 have "p = setsum (%i. (monom (coeff p i) i)) {..0}"
 | 
|  |    748 |       by (simp only: up_repr_le)
 | 
|  |    749 |     also have "... = monom (coeff p 0) 0" by simp
 | 
|  |    750 |     finally have p: "p = monom (coeff p 0) 0" .
 | 
|  |    751 |     from f1 have "q = setsum (%i. (monom (coeff q i) i)) {..0}"
 | 
|  |    752 |       by (simp only: up_repr_le)
 | 
|  |    753 |     also have "... = monom (coeff q 0) 0" by simp
 | 
|  |    754 |     finally have q: "q = monom (coeff q 0) 0" .
 | 
|  |    755 |     have "coeff p 0 * coeff q 0 = coeff (p * q) 0" by simp
 | 
|  |    756 |     also from pq have "... = 0" by simp
 | 
|  |    757 |     finally have "coeff p 0 * coeff q 0 = 0" .
 | 
|  |    758 |     then have "coeff p 0 = 0 | coeff q 0 = 0" by (simp only: integral_iff)
 | 
|  |    759 |     with p q show "p = 0 | q = 0" by fastsimp
 | 
|  |    760 |   qed
 | 
|  |    761 | qed
 | 
|  |    762 | 
 | 
|  |    763 | lemma monom_inj_zero:
 | 
|  |    764 |   "(monom a n = 0) = (a = 0)"
 | 
|  |    765 | proof -
 | 
|  |    766 |   have "(monom a n = 0) = (monom a n = monom 0 n)" by simp
 | 
|  |    767 |   also have "... = (a = 0)" by (simp add: monom_inj del: monom_zero)
 | 
|  |    768 |   finally show ?thesis .
 | 
|  |    769 | qed
 | 
|  |    770 | (* term order: makes this simpler!!!
 | 
|  |    771 | lemma smult_integral:
 | 
|  |    772 |   "(a::'a::domain) *s p = 0 ==> a = 0 | p = 0"
 | 
|  |    773 | by (simp add: monom_mult_is_smult [THEN sym] integral_iff monom_inj_zero) fast
 | 
|  |    774 | *)
 | 
|  |    775 | lemma smult_integral:
 | 
|  |    776 |   "(a::'a::domain) *s p = 0 ==> a = 0 | p = 0"
 | 
|  |    777 | by (simp add: monom_mult_is_smult [THEN sym] integral_iff monom_inj_zero)
 | 
|  |    778 | 
 | 
| 14590 |    779 | end
 |