6 |
6 |
7 theory Reflected_Multivariate_Polynomial |
7 theory Reflected_Multivariate_Polynomial |
8 imports Complex_Main Rat_Pair Polynomial_List |
8 imports Complex_Main Rat_Pair Polynomial_List |
9 begin |
9 begin |
10 |
10 |
11 subsection\<open>Datatype of polynomial expressions\<close> |
11 subsection \<open>Datatype of polynomial expressions\<close> |
12 |
12 |
13 datatype poly = C Num | Bound nat | Add poly poly | Sub poly poly |
13 datatype poly = C Num | Bound nat | Add poly poly | Sub poly poly |
14 | Mul poly poly| Neg poly| Pw poly nat| CN poly nat poly |
14 | Mul poly poly| Neg poly| Pw poly nat| CN poly nat poly |
15 |
15 |
16 abbreviation poly_0 :: "poly" ("0\<^sub>p") where "0\<^sub>p \<equiv> C (0\<^sub>N)" |
16 abbreviation poly_0 :: "poly" ("0\<^sub>p") where "0\<^sub>p \<equiv> C (0\<^sub>N)" |
64 | "decrpoly (Pw p n) = Pw (decrpoly p) n" |
64 | "decrpoly (Pw p n) = Pw (decrpoly p) n" |
65 | "decrpoly (CN c n p) = CN (decrpoly c) (n - 1) (decrpoly p)" |
65 | "decrpoly (CN c n p) = CN (decrpoly c) (n - 1) (decrpoly p)" |
66 | "decrpoly a = a" |
66 | "decrpoly a = a" |
67 |
67 |
68 |
68 |
69 subsection\<open>Degrees and heads and coefficients\<close> |
69 subsection \<open>Degrees and heads and coefficients\<close> |
70 |
70 |
71 fun degree :: "poly \<Rightarrow> nat" |
71 fun degree :: "poly \<Rightarrow> nat" |
72 where |
72 where |
73 "degree (CN c 0 p) = 1 + degree p" |
73 "degree (CN c 0 p) = 1 + degree p" |
74 | "degree p = 0" |
74 | "degree p = 0" |
76 fun head :: "poly \<Rightarrow> poly" |
76 fun head :: "poly \<Rightarrow> poly" |
77 where |
77 where |
78 "head (CN c 0 p) = head p" |
78 "head (CN c 0 p) = head p" |
79 | "head p = p" |
79 | "head p = p" |
80 |
80 |
81 (* More general notions of degree and head *) |
81 text \<open>More general notions of degree and head.\<close> |
|
82 |
82 fun degreen :: "poly \<Rightarrow> nat \<Rightarrow> nat" |
83 fun degreen :: "poly \<Rightarrow> nat \<Rightarrow> nat" |
83 where |
84 where |
84 "degreen (CN c n p) = (\<lambda>m. if n = m then 1 + degreen p n else 0)" |
85 "degreen (CN c n p) = (\<lambda>m. if n = m then 1 + degreen p n else 0)" |
85 | "degreen p = (\<lambda>m. 0)" |
86 | "degreen p = (\<lambda>m. 0)" |
86 |
87 |
108 where |
109 where |
109 "headconst (CN c n p) = headconst p" |
110 "headconst (CN c n p) = headconst p" |
110 | "headconst (C n) = n" |
111 | "headconst (C n) = n" |
111 |
112 |
112 |
113 |
113 subsection\<open>Operations for normalization\<close> |
114 subsection \<open>Operations for normalization\<close> |
114 |
115 |
115 declare if_cong[fundef_cong del] |
116 declare if_cong[fundef_cong del] |
116 declare let_cong[fundef_cong del] |
117 declare let_cong[fundef_cong del] |
117 |
118 |
118 fun polyadd :: "poly \<Rightarrow> poly \<Rightarrow> poly" (infixl "+\<^sub>p" 60) |
119 fun polyadd :: "poly \<Rightarrow> poly \<Rightarrow> poly" (infixl "+\<^sub>p" 60) |
177 | "polynate (Mul p q) = polynate p *\<^sub>p polynate q" |
178 | "polynate (Mul p q) = polynate p *\<^sub>p polynate q" |
178 | "polynate (Neg p) = ~\<^sub>p (polynate p)" |
179 | "polynate (Neg p) = ~\<^sub>p (polynate p)" |
179 | "polynate (Pw p n) = polynate p ^\<^sub>p n" |
180 | "polynate (Pw p n) = polynate p ^\<^sub>p n" |
180 | "polynate (CN c n p) = polynate (Add c (Mul (Bound n) p))" |
181 | "polynate (CN c n p) = polynate (Add c (Mul (Bound n) p))" |
181 | "polynate (C c) = C (normNum c)" |
182 | "polynate (C c) = C (normNum c)" |
182 by pat_completeness auto |
183 by pat_completeness auto |
183 termination by (relation "measure polysize") auto |
184 termination by (relation "measure polysize") auto |
184 |
185 |
185 fun poly_cmul :: "Num \<Rightarrow> poly \<Rightarrow> poly" |
186 fun poly_cmul :: "Num \<Rightarrow> poly \<Rightarrow> poly" |
186 where |
187 where |
187 "poly_cmul y (C x) = C (y *\<^sub>N x)" |
188 "poly_cmul y (C x) = C (y *\<^sub>N x)" |
231 where |
232 where |
232 "poly_deriv (CN c 0 p) = poly_deriv_aux 1 p" |
233 "poly_deriv (CN c 0 p) = poly_deriv_aux 1 p" |
233 | "poly_deriv p = 0\<^sub>p" |
234 | "poly_deriv p = 0\<^sub>p" |
234 |
235 |
235 |
236 |
236 subsection\<open>Semantics of the polynomial representation\<close> |
237 subsection \<open>Semantics of the polynomial representation\<close> |
237 |
238 |
238 primrec Ipoly :: "'a list \<Rightarrow> poly \<Rightarrow> 'a::{field_char_0,field,power}" |
239 primrec Ipoly :: "'a list \<Rightarrow> poly \<Rightarrow> 'a::{field_char_0,field,power}" |
239 where |
240 where |
240 "Ipoly bs (C c) = INum c" |
241 "Ipoly bs (C c) = INum c" |
241 | "Ipoly bs (Bound n) = bs!n" |
242 | "Ipoly bs (Bound n) = bs!n" |
244 | "Ipoly bs (Sub a b) = Ipoly bs a - Ipoly bs b" |
245 | "Ipoly bs (Sub a b) = Ipoly bs a - Ipoly bs b" |
245 | "Ipoly bs (Mul a b) = Ipoly bs a * Ipoly bs b" |
246 | "Ipoly bs (Mul a b) = Ipoly bs a * Ipoly bs b" |
246 | "Ipoly bs (Pw t n) = Ipoly bs t ^ n" |
247 | "Ipoly bs (Pw t n) = Ipoly bs t ^ n" |
247 | "Ipoly bs (CN c n p) = Ipoly bs c + (bs!n) * Ipoly bs p" |
248 | "Ipoly bs (CN c n p) = Ipoly bs c + (bs!n) * Ipoly bs p" |
248 |
249 |
249 abbreviation Ipoly_syntax :: "poly \<Rightarrow> 'a list \<Rightarrow>'a::{field_char_0,field,power}" |
250 abbreviation Ipoly_syntax :: "poly \<Rightarrow> 'a list \<Rightarrow>'a::{field_char_0,field,power}" ("\<lparr>_\<rparr>\<^sub>p\<^bsup>_\<^esup>") |
250 ("\<lparr>_\<rparr>\<^sub>p\<^bsup>_\<^esup>") |
|
251 where "\<lparr>p\<rparr>\<^sub>p\<^bsup>bs\<^esup> \<equiv> Ipoly bs p" |
251 where "\<lparr>p\<rparr>\<^sub>p\<^bsup>bs\<^esup> \<equiv> Ipoly bs p" |
252 |
252 |
253 lemma Ipoly_CInt: "Ipoly bs (C (i, 1)) = of_int i" |
253 lemma Ipoly_CInt: "Ipoly bs (C (i, 1)) = of_int i" |
254 by (simp add: INum_def) |
254 by (simp add: INum_def) |
255 |
255 |
271 by (induct p rule: isnpolyh.induct) auto |
271 by (induct p rule: isnpolyh.induct) auto |
272 |
272 |
273 definition isnpoly :: "poly \<Rightarrow> bool" |
273 definition isnpoly :: "poly \<Rightarrow> bool" |
274 where "isnpoly p = isnpolyh p 0" |
274 where "isnpoly p = isnpolyh p 0" |
275 |
275 |
276 text\<open>polyadd preserves normal forms\<close> |
276 text \<open>polyadd preserves normal forms\<close> |
277 |
277 |
278 lemma polyadd_normh: "isnpolyh p n0 \<Longrightarrow> isnpolyh q n1 \<Longrightarrow> isnpolyh (polyadd p q) (min n0 n1)" |
278 lemma polyadd_normh: "isnpolyh p n0 \<Longrightarrow> isnpolyh q n1 \<Longrightarrow> isnpolyh (polyadd p q) (min n0 n1)" |
279 proof (induct p q arbitrary: n0 n1 rule: polyadd.induct) |
279 proof (induct p q arbitrary: n0 n1 rule: polyadd.induct) |
280 case (2 ab c' n' p' n0 n1) |
280 case (2 ab c' n' p' n0 n1) |
281 from 2 have th1: "isnpolyh (C ab) (Suc n')" |
281 from 2 have th1: "isnpolyh (C ab) (Suc n')" |
282 by simp |
282 by simp |
283 from 2(3) have th2: "isnpolyh c' (Suc n')" and nplen1: "n' \<ge> n1" |
283 from 2(3) have th2: "isnpolyh c' (Suc n')" and nplen1: "n' \<ge> n1" |
284 by simp_all |
284 by simp_all |
285 with isnpolyh_mono have cp: "isnpolyh c' (Suc n')" |
285 with isnpolyh_mono have cp: "isnpolyh c' (Suc n')" |
286 by simp |
286 by simp |
287 with 2(1)[OF th1 th2] have th3:"isnpolyh (C ab +\<^sub>p c') (Suc n')" |
287 with 2(1)[OF th1 th2] have th3:"isnpolyh (C ab +\<^sub>p c') (Suc n')" |
288 by simp |
288 by simp |
312 by simp_all |
312 by simp_all |
313 from 4 have ngen0: "n \<ge> n0" |
313 from 4 have ngen0: "n \<ge> n0" |
314 by simp |
314 by simp |
315 from 4 have n'gen1: "n' \<ge> n1" |
315 from 4 have n'gen1: "n' \<ge> n1" |
316 by simp |
316 by simp |
317 have "n < n' \<or> n' < n \<or> n = n'" |
317 consider (eq) "n = n'" | (lt) "n < n'" | (gt) "n > n'" |
318 by auto |
318 by arith |
319 moreover |
319 then show ?case |
320 { |
320 proof cases |
321 assume eq: "n = n'" |
321 case eq |
322 with "4.hyps"(3)[OF nc nc'] |
322 with "4.hyps"(3)[OF nc nc'] |
323 have ncc':"isnpolyh (c +\<^sub>p c') (Suc n)" |
323 have ncc':"isnpolyh (c +\<^sub>p c') (Suc n)" |
324 by auto |
324 by auto |
325 then have ncc'n01: "isnpolyh (c +\<^sub>p c') (min n0 n1)" |
325 then have ncc'n01: "isnpolyh (c +\<^sub>p c') (min n0 n1)" |
326 using isnpolyh_mono[where n'="min n0 n1" and n="Suc n"] ngen0 n'gen1 |
326 using isnpolyh_mono[where n'="min n0 n1" and n="Suc n"] ngen0 n'gen1 |
327 by auto |
327 by auto |
328 from eq "4.hyps"(4)[OF np np'] have npp': "isnpolyh (p +\<^sub>p p') n" |
328 from eq "4.hyps"(4)[OF np np'] have npp': "isnpolyh (p +\<^sub>p p') n" |
329 by simp |
329 by simp |
330 have minle: "min n0 n1 \<le> n'" |
330 have minle: "min n0 n1 \<le> n'" |
331 using ngen0 n'gen1 eq by simp |
331 using ngen0 n'gen1 eq by simp |
332 from minle npp' ncc'n01 4 eq ngen0 n'gen1 ncc' have ?case |
332 from minle npp' ncc'n01 4 eq ngen0 n'gen1 ncc' show ?thesis |
333 by (simp add: Let_def) |
333 by (simp add: Let_def) |
334 } |
334 next |
335 moreover |
335 case lt |
336 { |
|
337 assume lt: "n < n'" |
|
338 have "min n0 n1 \<le> n0" |
336 have "min n0 n1 \<le> n0" |
339 by simp |
337 by simp |
340 with 4 lt have th1:"min n0 n1 \<le> n" |
338 with 4 lt have th1:"min n0 n1 \<le> n" |
341 by auto |
339 by auto |
342 from 4 have th21: "isnpolyh c (Suc n)" |
340 from 4 have th21: "isnpolyh c (Suc n)" |
345 by simp |
343 by simp |
346 from lt have th23: "min (Suc n) n' = Suc n" |
344 from lt have th23: "min (Suc n) n' = Suc n" |
347 by arith |
345 by arith |
348 from "4.hyps"(1)[OF th21 th22] have "isnpolyh (polyadd c (CN c' n' p')) (Suc n)" |
346 from "4.hyps"(1)[OF th21 th22] have "isnpolyh (polyadd c (CN c' n' p')) (Suc n)" |
349 using th23 by simp |
347 using th23 by simp |
350 with 4 lt th1 have ?case |
348 with 4 lt th1 show ?thesis |
351 by simp |
349 by simp |
352 } |
350 next |
353 moreover |
351 case gt |
354 { |
|
355 assume gt: "n' < n" |
|
356 then have gt': "n' < n \<and> \<not> n < n'" |
352 then have gt': "n' < n \<and> \<not> n < n'" |
357 by simp |
353 by simp |
358 have "min n0 n1 \<le> n1" |
354 have "min n0 n1 \<le> n1" |
359 by simp |
355 by simp |
360 with 4 gt have th1: "min n0 n1 \<le> n'" |
356 with 4 gt have th1: "min n0 n1 \<le> n'" |
365 by simp |
361 by simp |
366 from gt have th23: "min n (Suc n') = Suc n'" |
362 from gt have th23: "min n (Suc n') = Suc n'" |
367 by arith |
363 by arith |
368 from "4.hyps"(2)[OF th22 th21] have "isnpolyh (polyadd (CN c n p) c') (Suc n')" |
364 from "4.hyps"(2)[OF th22 th21] have "isnpolyh (polyadd (CN c n p) c') (Suc n')" |
369 using th23 by simp |
365 using th23 by simp |
370 with 4 gt th1 have ?case |
366 with 4 gt th1 show ?thesis |
371 by simp |
367 by simp |
372 } |
368 qed |
373 ultimately show ?case by blast |
|
374 qed auto |
369 qed auto |
375 |
370 |
376 lemma polyadd[simp]: "Ipoly bs (polyadd p q) = Ipoly bs p + Ipoly bs q" |
371 lemma polyadd[simp]: "Ipoly bs (polyadd p q) = Ipoly bs p + Ipoly bs q" |
377 by (induct p q rule: polyadd.induct) |
372 by (induct p q rule: polyadd.induct) |
378 (auto simp add: Let_def field_simps distrib_left[symmetric] simp del: distrib_left_NO_MATCH) |
373 (auto simp add: Let_def field_simps distrib_left[symmetric] simp del: distrib_left_NO_MATCH) |
379 |
374 |
380 lemma polyadd_norm: "isnpoly p \<Longrightarrow> isnpoly q \<Longrightarrow> isnpoly (polyadd p q)" |
375 lemma polyadd_norm: "isnpoly p \<Longrightarrow> isnpoly q \<Longrightarrow> isnpoly (polyadd p q)" |
381 using polyadd_normh[of "p" "0" "q" "0"] isnpoly_def by simp |
376 using polyadd_normh[of p 0 q 0] isnpoly_def by simp |
382 |
377 |
383 text\<open>The degree of addition and other general lemmas needed for the normal form of polymul\<close> |
378 text \<open>The degree of addition and other general lemmas needed for the normal form of polymul.\<close> |
384 |
379 |
385 lemma polyadd_different_degreen: |
380 lemma polyadd_different_degreen: |
386 assumes "isnpolyh p n0" |
381 assumes "isnpolyh p n0" |
387 and "isnpolyh q n1" |
382 and "isnpolyh q n1" |
388 and "degreen p m \<noteq> degreen q m" |
383 and "degreen p m \<noteq> degreen q m" |
389 and "m \<le> min n0 n1" |
384 and "m \<le> min n0 n1" |
390 shows "degreen (polyadd p q) m = max (degreen p m) (degreen q m)" |
385 shows "degreen (polyadd p q) m = max (degreen p m) (degreen q m)" |
391 using assms |
386 using assms |
392 proof (induct p q arbitrary: m n0 n1 rule: polyadd.induct) |
387 proof (induct p q arbitrary: m n0 n1 rule: polyadd.induct) |
393 case (4 c n p c' n' p' m n0 n1) |
388 case (4 c n p c' n' p' m n0 n1) |
394 have "n' = n \<or> n < n' \<or> n' < n" by arith |
389 show ?case |
395 then show ?case |
390 proof (cases "n = n'") |
396 proof (elim disjE) |
391 case True |
397 assume [simp]: "n' = n" |
392 with 4(4)[of n n m] 4(3)[of "Suc n" "Suc n" m] 4(5-7) |
398 from 4(4)[of n n m] 4(3)[of "Suc n" "Suc n" m] 4(5-7) |
|
399 show ?thesis by (auto simp: Let_def) |
393 show ?thesis by (auto simp: Let_def) |
400 next |
394 next |
401 assume "n < n'" |
395 case False |
402 with 4 show ?thesis by auto |
|
403 next |
|
404 assume "n' < n" |
|
405 with 4 show ?thesis by auto |
396 with 4 show ?thesis by auto |
406 qed |
397 qed |
407 qed auto |
398 qed auto |
408 |
399 |
409 lemma headnz[simp]: "isnpolyh p n \<Longrightarrow> p \<noteq> 0\<^sub>p \<Longrightarrow> headn p m \<noteq> 0\<^sub>p" |
400 lemma headnz[simp]: "isnpolyh p n \<Longrightarrow> p \<noteq> 0\<^sub>p \<Longrightarrow> headn p m \<noteq> 0\<^sub>p" |
439 case (3 c n p c' n0 n1) |
430 case (3 c n p c' n0 n1) |
440 then show ?case |
431 then show ?case |
441 by (cases n) auto |
432 by (cases n) auto |
442 next |
433 next |
443 case (4 c n p c' n' p' n0 n1 m) |
434 case (4 c n p c' n' p' n0 n1 m) |
444 have "n' = n \<or> n < n' \<or> n' < n" by arith |
435 show ?case |
445 then show ?case |
436 proof (cases "n = n'") |
446 proof (elim disjE) |
437 case True |
447 assume [simp]: "n' = n" |
438 with 4(4)[of n n m] 4(3)[of "Suc n" "Suc n" m] 4(5-7) |
448 from 4(4)[of n n m] 4(3)[of "Suc n" "Suc n" m] 4(5-7) |
|
449 show ?thesis by (auto simp: Let_def) |
439 show ?thesis by (auto simp: Let_def) |
450 qed simp_all |
440 next |
|
441 case False |
|
442 then show ?thesis by simp |
|
443 qed |
451 qed auto |
444 qed auto |
452 |
445 |
453 lemma polyadd_eq_const_degreen: |
446 lemma polyadd_eq_const_degreen: |
454 assumes "isnpolyh p n0" |
447 assumes "isnpolyh p n0" |
455 and "isnpolyh q n1" |
448 and "isnpolyh q n1" |
456 and "polyadd p q = C c" |
449 and "polyadd p q = C c" |
457 shows "degreen p m = degreen q m" |
450 shows "degreen p m = degreen q m" |
458 using assms |
451 using assms |
459 proof (induct p q arbitrary: m n0 n1 c rule: polyadd.induct) |
452 proof (induct p q arbitrary: m n0 n1 c rule: polyadd.induct) |
460 case (4 c n p c' n' p' m n0 n1 x) |
453 case (4 c n p c' n' p' m n0 n1 x) |
461 { |
454 consider "n = n'" | "n > n' \<or> n < n'" by arith |
462 assume nn': "n' < n" |
455 then show ?case |
463 then have ?case using 4 by simp |
456 proof cases |
464 } |
457 case 1 |
465 moreover |
458 with 4 show ?thesis |
466 { |
459 by (cases "p +\<^sub>p p' = 0\<^sub>p") (auto simp add: Let_def) |
467 assume nn': "\<not> n' < n" |
460 next |
468 then have "n < n' \<or> n = n'" by arith |
461 case 2 |
469 moreover { assume "n < n'" with 4 have ?case by simp } |
462 with 4 show ?thesis by auto |
470 moreover |
463 qed |
471 { |
|
472 assume eq: "n = n'" |
|
473 then have ?case using 4 |
|
474 apply (cases "p +\<^sub>p p' = 0\<^sub>p") |
|
475 apply (auto simp add: Let_def) |
|
476 done |
|
477 } |
|
478 ultimately have ?case by blast |
|
479 } |
|
480 ultimately show ?case by blast |
|
481 qed simp_all |
464 qed simp_all |
482 |
465 |
483 lemma polymul_properties: |
466 lemma polymul_properties: |
484 assumes "SORT_CONSTRAINT('a::{field_char_0,field})" |
467 assumes "SORT_CONSTRAINT('a::{field_char_0,field})" |
485 and np: "isnpolyh p n0" |
468 and np: "isnpolyh p n0" |
718 then show "INum (headconst p) = (0::'a) \<longrightarrow> \<lparr>p\<rparr>\<^sub>p\<^bsup>bs\<^esup> = 0" |
701 then show "INum (headconst p) = (0::'a) \<longrightarrow> \<lparr>p\<rparr>\<^sub>p\<^bsup>bs\<^esup> = 0" |
719 by blast |
702 by blast |
720 qed |
703 qed |
721 |
704 |
722 |
705 |
723 text\<open>polyneg is a negation and preserves normal forms\<close> |
706 text \<open>polyneg is a negation and preserves normal forms\<close> |
724 |
707 |
725 lemma polyneg[simp]: "Ipoly bs (polyneg p) = - Ipoly bs p" |
708 lemma polyneg[simp]: "Ipoly bs (polyneg p) = - Ipoly bs p" |
726 by (induct p rule: polyneg.induct) auto |
709 by (induct p rule: polyneg.induct) auto |
727 |
710 |
728 lemma polyneg0: "isnpolyh p n \<Longrightarrow> (~\<^sub>p p) = 0\<^sub>p \<longleftrightarrow> p = 0\<^sub>p" |
711 lemma polyneg0: "isnpolyh p n \<Longrightarrow> (~\<^sub>p p) = 0\<^sub>p \<longleftrightarrow> p = 0\<^sub>p" |
736 |
719 |
737 lemma polyneg_norm: "isnpoly p \<Longrightarrow> isnpoly (polyneg p)" |
720 lemma polyneg_norm: "isnpoly p \<Longrightarrow> isnpoly (polyneg p)" |
738 using isnpoly_def polyneg_normh by simp |
721 using isnpoly_def polyneg_normh by simp |
739 |
722 |
740 |
723 |
741 text\<open>polysub is a substraction and preserves normal forms\<close> |
724 text \<open>polysub is a substraction and preserves normal forms\<close> |
742 |
725 |
743 lemma polysub[simp]: "Ipoly bs (polysub p q) = Ipoly bs p - Ipoly bs q" |
726 lemma polysub[simp]: "Ipoly bs (polysub p q) = Ipoly bs p - Ipoly bs q" |
744 by (simp add: polysub_def) |
727 by (simp add: polysub_def) |
745 |
728 |
746 lemma polysub_normh: "isnpolyh p n0 \<Longrightarrow> isnpolyh q n1 \<Longrightarrow> isnpolyh (polysub p q) (min n0 n1)" |
729 lemma polysub_normh: "isnpolyh p n0 \<Longrightarrow> isnpolyh q n1 \<Longrightarrow> isnpolyh (polysub p q) (min n0 n1)" |
760 shows "isnpolyh p n0 \<Longrightarrow> isnpolyh q n1 \<Longrightarrow> p -\<^sub>p q = 0\<^sub>p \<longleftrightarrow> p = q" |
743 shows "isnpolyh p n0 \<Longrightarrow> isnpolyh q n1 \<Longrightarrow> p -\<^sub>p q = 0\<^sub>p \<longleftrightarrow> p = q" |
761 unfolding polysub_def split_def fst_conv snd_conv |
744 unfolding polysub_def split_def fst_conv snd_conv |
762 by (induct p q arbitrary: n0 n1 rule:polyadd.induct) |
745 by (induct p q arbitrary: n0 n1 rule:polyadd.induct) |
763 (auto simp: Nsub0[simplified Nsub_def] Let_def) |
746 (auto simp: Nsub0[simplified Nsub_def] Let_def) |
764 |
747 |
765 text\<open>polypow is a power function and preserves normal forms\<close> |
748 text \<open>polypow is a power function and preserves normal forms\<close> |
766 |
749 |
767 lemma polypow[simp]: |
750 lemma polypow[simp]: |
768 "Ipoly bs (polypow n p) = (Ipoly bs p :: 'a::{field_char_0,field}) ^ n" |
751 "Ipoly bs (polypow n p) = (Ipoly bs p :: 'a::{field_char_0,field}) ^ n" |
769 proof (induct n rule: polypow.induct) |
752 proof (induct n rule: polypow.induct) |
770 case 1 |
753 case 1 |
828 lemma polypow_norm: |
811 lemma polypow_norm: |
829 assumes "SORT_CONSTRAINT('a::{field_char_0,field})" |
812 assumes "SORT_CONSTRAINT('a::{field_char_0,field})" |
830 shows "isnpoly p \<Longrightarrow> isnpoly (polypow k p)" |
813 shows "isnpoly p \<Longrightarrow> isnpoly (polypow k p)" |
831 by (simp add: polypow_normh isnpoly_def) |
814 by (simp add: polypow_normh isnpoly_def) |
832 |
815 |
833 text\<open>Finally the whole normalization\<close> |
816 text \<open>Finally the whole normalization\<close> |
834 |
817 |
835 lemma polynate [simp]: |
818 lemma polynate [simp]: |
836 "Ipoly bs (polynate p) = (Ipoly bs p :: 'a ::{field_char_0,field})" |
819 "Ipoly bs (polynate p) = (Ipoly bs p :: 'a ::{field_char_0,field})" |
837 by (induct p rule:polynate.induct) auto |
820 by (induct p rule:polynate.induct) auto |
838 |
821 |
841 shows "isnpoly (polynate p)" |
824 shows "isnpoly (polynate p)" |
842 by (induct p rule: polynate.induct) |
825 by (induct p rule: polynate.induct) |
843 (simp_all add: polyadd_norm polymul_norm polysub_norm polyneg_norm polypow_norm, |
826 (simp_all add: polyadd_norm polymul_norm polysub_norm polyneg_norm polypow_norm, |
844 simp_all add: isnpoly_def) |
827 simp_all add: isnpoly_def) |
845 |
828 |
846 text\<open>shift1\<close> |
829 text \<open>shift1\<close> |
847 |
830 |
848 |
831 |
849 lemma shift1: "Ipoly bs (shift1 p) = Ipoly bs (Mul (Bound 0) p)" |
832 lemma shift1: "Ipoly bs (shift1 p) = Ipoly bs (Mul (Bound 0) p)" |
850 by (simp add: shift1_def) |
833 by (simp add: shift1_def) |
851 |
834 |
1252 with isnpolyh_zero_iff[OF polysub_normh[OF np nq]] polysub_0[OF np nq] show "p = q" |
1235 with isnpolyh_zero_iff[OF polysub_normh[OF np nq]] polysub_0[OF np nq] show "p = q" |
1253 by blast |
1236 by blast |
1254 qed |
1237 qed |
1255 |
1238 |
1256 |
1239 |
1257 text\<open>consequences of unicity on the algorithms for polynomial normalization\<close> |
1240 text \<open>consequences of unicity on the algorithms for polynomial normalization\<close> |
1258 |
1241 |
1259 lemma polyadd_commute: |
1242 lemma polyadd_commute: |
1260 assumes "SORT_CONSTRAINT('a::{field_char_0,field})" |
1243 assumes "SORT_CONSTRAINT('a::{field_char_0,field})" |
1261 and np: "isnpolyh p n0" |
1244 and np: "isnpolyh p n0" |
1262 and nq: "isnpolyh q n1" |
1245 and nq: "isnpolyh q n1" |
1326 "poly (poly_nate bs p) = (\<lambda>x:: 'a ::{field_char_0,field}. \<lparr>p\<rparr>\<^sub>p\<^bsup>x # bs\<^esup>)" |
1309 "poly (poly_nate bs p) = (\<lambda>x:: 'a ::{field_char_0,field}. \<lparr>p\<rparr>\<^sub>p\<^bsup>x # bs\<^esup>)" |
1327 using polypoly'_poly[OF polynate_norm[unfolded isnpoly_def], symmetric, of bs p] |
1310 using polypoly'_poly[OF polynate_norm[unfolded isnpoly_def], symmetric, of bs p] |
1328 unfolding poly_nate_polypoly' by auto |
1311 unfolding poly_nate_polypoly' by auto |
1329 |
1312 |
1330 |
1313 |
1331 subsection\<open>heads, degrees and all that\<close> |
1314 subsection \<open>heads, degrees and all that\<close> |
1332 |
1315 |
1333 lemma degree_eq_degreen0: "degree p = degreen p 0" |
1316 lemma degree_eq_degreen0: "degree p = degreen p 0" |
1334 by (induct p rule: degree.induct) simp_all |
1317 by (induct p rule: degree.induct) simp_all |
1335 |
1318 |
1336 lemma degree_polyneg: |
1319 lemma degree_polyneg: |