src/HOL/Decision_Procs/Reflected_Multivariate_Polynomial.thy
changeset 60698 29e8bdc41f90
parent 60580 7e741e22d7fc
child 61166 5976fe402824
equal deleted inserted replaced
60697:e266d5463e9d 60698:29e8bdc41f90
     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"
   498   next
   481   next
   499     case (2 n0 n1)
   482     case (2 n0 n1)
   500     then show ?case by auto
   483     then show ?case by auto
   501   next
   484   next
   502     case (3 n0 n1)
   485     case (3 n0 n1)
   503     then show ?case  using "2.hyps" by auto
   486     then show ?case using "2.hyps" by auto
   504   }
   487   }
   505 next
   488 next
   506   case (3 c n p c')
   489   case (3 c n p c')
   507   {
   490   {
   508     case (1 n0 n1)
   491     case (1 n0 n1)
   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: