src/HOL/Decision_Procs/Reflected_Multivariate_Polynomial.thy
changeset 41807 ab5d2d81f9fb
parent 41763 8ce56536fda7
child 41816 7a55699805dc
equal deleted inserted replaced
41806:173e1b50d5c5 41807:ab5d2d81f9fb
   251 
   251 
   252 lemma polyadd_normh: "\<lbrakk>isnpolyh p n0 ; isnpolyh q n1\<rbrakk> 
   252 lemma polyadd_normh: "\<lbrakk>isnpolyh p n0 ; isnpolyh q n1\<rbrakk> 
   253       \<Longrightarrow> isnpolyh (polyadd(p,q)) (min n0 n1)"
   253       \<Longrightarrow> isnpolyh (polyadd(p,q)) (min n0 n1)"
   254 proof(induct p q arbitrary: n0 n1 rule: polyadd.induct)
   254 proof(induct p q arbitrary: n0 n1 rule: polyadd.induct)
   255   case (2 a b c' n' p' n0 n1)
   255   case (2 a b c' n' p' n0 n1)
   256   from prems have  th1: "isnpolyh (C (a,b)) (Suc n')" by simp 
   256   from 2 have  th1: "isnpolyh (C (a,b)) (Suc n')" by simp 
   257   from prems(3) have th2: "isnpolyh c' (Suc n')"  and nplen1: "n' \<ge> n1" by simp_all
   257   from 2(3) have th2: "isnpolyh c' (Suc n')"  and nplen1: "n' \<ge> n1" by simp_all
   258   with isnpolyh_mono have cp: "isnpolyh c' (Suc n')" by simp
   258   with isnpolyh_mono have cp: "isnpolyh c' (Suc n')" by simp
   259   with prems(1)[OF th1 th2] have th3:"isnpolyh (C (a,b) +\<^sub>p c') (Suc n')" by simp
   259   with 2(1)[OF th1 th2] have th3:"isnpolyh (C (a,b) +\<^sub>p c') (Suc n')" by simp
   260   from nplen1 have n01len1: "min n0 n1 \<le> n'" by simp 
   260   from nplen1 have n01len1: "min n0 n1 \<le> n'" by simp 
   261   thus ?case using prems th3 by simp
   261   thus ?case using 2 th3 by simp
   262 next
   262 next
   263   case (3 c' n' p' a b n1 n0)
   263   case (3 c' n' p' a b n1 n0)
   264   from prems have  th1: "isnpolyh (C (a,b)) (Suc n')" by simp 
   264   from 3 have  th1: "isnpolyh (C (a,b)) (Suc n')" by simp 
   265   from prems(2) have th2: "isnpolyh c' (Suc n')"  and nplen1: "n' \<ge> n1" by simp_all
   265   from 3(2) have th2: "isnpolyh c' (Suc n')"  and nplen1: "n' \<ge> n1" by simp_all
   266   with isnpolyh_mono have cp: "isnpolyh c' (Suc n')" by simp
   266   with isnpolyh_mono have cp: "isnpolyh c' (Suc n')" by simp
   267   with prems(1)[OF th2 th1] have th3:"isnpolyh (c' +\<^sub>p C (a,b)) (Suc n')" by simp
   267   with 3(1)[OF th2 th1] have th3:"isnpolyh (c' +\<^sub>p C (a,b)) (Suc n')" by simp
   268   from nplen1 have n01len1: "min n0 n1 \<le> n'" by simp 
   268   from nplen1 have n01len1: "min n0 n1 \<le> n'" by simp 
   269   thus ?case using prems th3 by simp
   269   thus ?case using 3 th3 by simp
   270 next
   270 next
   271   case (4 c n p c' n' p' n0 n1)
   271   case (4 c n p c' n' p' n0 n1)
   272   hence nc: "isnpolyh c (Suc n)" and np: "isnpolyh p n" by simp_all
   272   hence nc: "isnpolyh c (Suc n)" and np: "isnpolyh p n" by simp_all
   273   from prems have nc': "isnpolyh c' (Suc n')" and np': "isnpolyh p' n'" by simp_all 
   273   from 4 have nc': "isnpolyh c' (Suc n')" and np': "isnpolyh p' n'" by simp_all 
   274   from prems have ngen0: "n \<ge> n0" by simp
   274   from 4 have ngen0: "n \<ge> n0" by simp
   275   from prems have n'gen1: "n' \<ge> n1" by simp 
   275   from 4 have n'gen1: "n' \<ge> n1" by simp 
   276   have "n < n' \<or> n' < n \<or> n = n'" by auto
   276   have "n < n' \<or> n' < n \<or> n = n'" by auto
   277   moreover {assume eq: "n = n'"
   277   moreover {assume eq: "n = n'"
   278     with prems(2)[OF nc nc'] 
   278     with 4(2)[OF nc nc'] 
   279     have ncc':"isnpolyh (c +\<^sub>p c') (Suc n)" by auto
   279     have ncc':"isnpolyh (c +\<^sub>p c') (Suc n)" by auto
   280     hence ncc'n01: "isnpolyh (c +\<^sub>p c') (min n0 n1)"
   280     hence ncc'n01: "isnpolyh (c +\<^sub>p c') (min n0 n1)"
   281       using isnpolyh_mono[where n'="min n0 n1" and n="Suc n"] ngen0 n'gen1 by auto
   281       using isnpolyh_mono[where n'="min n0 n1" and n="Suc n"] ngen0 n'gen1 by auto
   282     from eq prems(1)[OF np np'] have npp': "isnpolyh (p +\<^sub>p p') n" by simp
   282     from eq 4(1)[OF np np'] have npp': "isnpolyh (p +\<^sub>p p') n" by simp
   283     have minle: "min n0 n1 \<le> n'" using ngen0 n'gen1 eq by simp
   283     have minle: "min n0 n1 \<le> n'" using ngen0 n'gen1 eq by simp
   284     from minle npp' ncc'n01 prems ngen0 n'gen1 ncc' have ?case by (simp add: Let_def)}
   284     from minle npp' ncc'n01 eq ngen0 n'gen1 ncc' have ?case by (simp add: Let_def)}
   285   moreover {assume lt: "n < n'"
   285   moreover {assume lt: "n < n'"
   286     have "min n0 n1 \<le> n0" by simp
   286     have "min n0 n1 \<le> n0" by simp
   287     with prems have th1:"min n0 n1 \<le> n" by auto 
   287     with 4 have th1:"min n0 n1 \<le> n" by auto 
   288     from prems have th21: "isnpolyh c (Suc n)" by simp
   288     from 4 have th21: "isnpolyh c (Suc n)" by simp
   289     from prems have th22: "isnpolyh (CN c' n' p') n'" by simp
   289     from 4 have th22: "isnpolyh (CN c' n' p') n'" by simp
   290     from lt have th23: "min (Suc n) n' = Suc n" by arith
   290     from lt have th23: "min (Suc n) n' = Suc n" by arith
   291     from prems(4)[OF th21 th22]
   291     from 4(4)[OF th21 th22]
   292     have "isnpolyh (polyadd (c, CN c' n' p')) (Suc n)" using th23 by simp
   292     have "isnpolyh (polyadd (c, CN c' n' p')) (Suc n)" using th23 by simp
   293     with prems th1 have ?case by simp } 
   293     with 4 lt th1 have ?case by simp }
   294   moreover {assume gt: "n' < n" hence gt': "n' < n \<and> \<not> n < n'" by simp
   294   moreover {assume gt: "n' < n" hence gt': "n' < n \<and> \<not> n < n'" by simp
   295     have "min n0 n1 \<le> n1"  by simp
   295     have "min n0 n1 \<le> n1"  by simp
   296     with prems have th1:"min n0 n1 \<le> n'" by auto
   296     with 4 have th1:"min n0 n1 \<le> n'" by auto
   297     from prems have th21: "isnpolyh c' (Suc n')" by simp_all
   297     from 4 have th21: "isnpolyh c' (Suc n')" by simp_all
   298     from prems have th22: "isnpolyh (CN c n p) n" by simp
   298     from 4 have th22: "isnpolyh (CN c n p) n" by simp
   299     from gt have th23: "min n (Suc n') = Suc n'" by arith
   299     from gt have th23: "min n (Suc n') = Suc n'" by arith
   300     from prems(3)[OF th22 th21]
   300     from 4(3)[OF th22 th21]
   301     have "isnpolyh (polyadd (CN c n p,c')) (Suc n')" using th23 by simp
   301     have "isnpolyh (polyadd (CN c n p,c')) (Suc n')" using th23 by simp
   302     with prems th1 have ?case by simp}
   302     with 4 gt th1 have ?case by simp}
   303       ultimately show ?case by blast
   303       ultimately show ?case by blast
   304 qed auto
   304 qed auto
   305 
   305 
   306 lemma polyadd[simp]: "Ipoly bs (polyadd (p,q)) = (Ipoly bs p) + (Ipoly bs q)"
   306 lemma polyadd[simp]: "Ipoly bs (polyadd (p,q)) = (Ipoly bs p) + (Ipoly bs q)"
   307 by (induct p q rule: polyadd.induct, auto simp add: Let_def field_simps right_distrib[symmetric] simp del: right_distrib)
   307 by (induct p q rule: polyadd.induct, auto simp add: Let_def field_simps right_distrib[symmetric] simp del: right_distrib)
   368 
   368 
   369 lemma polyadd_eq_const_degreen: "\<lbrakk> isnpolyh p n0 ; isnpolyh q n1 ; polyadd (p,q) = C c\<rbrakk> 
   369 lemma polyadd_eq_const_degreen: "\<lbrakk> isnpolyh p n0 ; isnpolyh q n1 ; polyadd (p,q) = C c\<rbrakk> 
   370   \<Longrightarrow> degreen p m = degreen q m"
   370   \<Longrightarrow> degreen p m = degreen q m"
   371 proof (induct p q arbitrary: m n0 n1 c rule: polyadd.induct)
   371 proof (induct p q arbitrary: m n0 n1 c rule: polyadd.induct)
   372   case (4 c n p c' n' p' m n0 n1 x) 
   372   case (4 c n p c' n' p' m n0 n1 x) 
   373   {assume nn': "n' < n" hence ?case using prems by simp}
   373   {assume nn': "n' < n" hence ?case using 4 by simp}
   374   moreover 
   374   moreover 
   375   {assume nn':"\<not> n' < n" hence "n < n' \<or> n = n'" by arith
   375   {assume nn':"\<not> n' < n" hence "n < n' \<or> n = n'" by arith
   376     moreover {assume "n < n'" with prems have ?case by simp }
   376     moreover {assume "n < n'" with 4 have ?case by simp }
   377     moreover {assume eq: "n = n'" hence ?case using prems 
   377     moreover {assume eq: "n = n'" hence ?case using 4 
   378         apply (cases "p +\<^sub>p p' = 0\<^sub>p")
   378         apply (cases "p +\<^sub>p p' = 0\<^sub>p")
   379         apply (auto simp add: Let_def)
   379         apply (auto simp add: Let_def)
   380         by blast
   380         apply blast
       
   381         done
   381       }
   382       }
   382     ultimately have ?case by blast}
   383     ultimately have ?case by blast}
   383   ultimately show ?case by blast
   384   ultimately show ?case by blast
   384 qed simp_all
   385 qed simp_all
   385 
   386 
   662     finally have ?case using even_nat_div_two_times_two[OF even] by (simp only: th)}
   663     finally have ?case using even_nat_div_two_times_two[OF even] by (simp only: th)}
   663   ultimately show ?case by blast
   664   ultimately show ?case by blast
   664 qed
   665 qed
   665 
   666 
   666 lemma polypow_normh: 
   667 lemma polypow_normh: 
   667     assumes "SORT_CONSTRAINT('a::{field_char_0, field_inverse_zero})"
   668   assumes "SORT_CONSTRAINT('a::{field_char_0, field_inverse_zero})"
   668   shows "isnpolyh p n \<Longrightarrow> isnpolyh (polypow k p) n"
   669   shows "isnpolyh p n \<Longrightarrow> isnpolyh (polypow k p) n"
   669 proof (induct k arbitrary: n rule: polypow.induct)
   670 proof (induct k arbitrary: n rule: polypow.induct)
   670   case (2 k n)
   671   case (2 k n)
   671   let ?q = "polypow (Suc k div 2) p"
   672   let ?q = "polypow (Suc k div 2) p"
   672   let ?d = "polymul (?q,?q)"
   673   let ?d = "polymul (?q,?q)"
   673   from prems have th1:"isnpolyh ?q n" and th2: "isnpolyh p n" by blast+
   674   from 2 have th1:"isnpolyh ?q n" and th2: "isnpolyh p n" by blast+
   674   from polymul_normh[OF th1 th1] have dn: "isnpolyh ?d n" by simp
   675   from polymul_normh[OF th1 th1] have dn: "isnpolyh ?d n" by simp
   675   from polymul_normh[OF th2 dn] have on: "isnpolyh (polymul(p,?d)) n" by simp
   676   from polymul_normh[OF th2 dn] have on: "isnpolyh (polymul(p,?d)) n" by simp
   676   from dn on show ?case by (simp add: Let_def)
   677   from dn on show ?case by (simp add: Let_def)
   677 qed auto 
   678 qed auto 
   678 
   679 
   693 
   694 
   694 text{* shift1 *}
   695 text{* shift1 *}
   695 
   696 
   696 
   697 
   697 lemma shift1: "Ipoly bs (shift1 p) = Ipoly bs (Mul (Bound 0) p)"
   698 lemma shift1: "Ipoly bs (shift1 p) = Ipoly bs (Mul (Bound 0) p)"
   698 by (simp add: shift1_def polymul)
   699   by (simp add: shift1_def)
   699 
   700 
   700 lemma shift1_isnpoly: 
   701 lemma shift1_isnpoly: 
   701   assumes pn: "isnpoly p" and pnz: "p \<noteq> 0\<^sub>p" shows "isnpoly (shift1 p) "
   702   assumes pn: "isnpoly p" and pnz: "p \<noteq> 0\<^sub>p" shows "isnpoly (shift1 p) "
   702   using pn pnz by (simp add: shift1_def isnpoly_def )
   703   using pn pnz by (simp add: shift1_def isnpoly_def )
   703 
   704 
   711   assumes f: "\<And> p. isnpolyh p n \<Longrightarrow> isnpolyh (f p) n "and np: "isnpolyh p n"
   712   assumes f: "\<And> p. isnpolyh p n \<Longrightarrow> isnpolyh (f p) n "and np: "isnpolyh p n"
   712   shows "isnpolyh (funpow k f p) n"
   713   shows "isnpolyh (funpow k f p) n"
   713   using f np by (induct k arbitrary: p, auto)
   714   using f np by (induct k arbitrary: p, auto)
   714 
   715 
   715 lemma funpow_shift1: "(Ipoly bs (funpow n shift1 p) :: 'a :: {field_char_0, field_inverse_zero}) = Ipoly bs (Mul (Pw (Bound 0) n) p)"
   716 lemma funpow_shift1: "(Ipoly bs (funpow n shift1 p) :: 'a :: {field_char_0, field_inverse_zero}) = Ipoly bs (Mul (Pw (Bound 0) n) p)"
   716   by (induct n arbitrary: p, simp_all add: shift1_isnpoly shift1 power_Suc )
   717   by (induct n arbitrary: p) (simp_all add: shift1_isnpoly shift1)
   717 
   718 
   718 lemma shift1_isnpolyh: "isnpolyh p n0 \<Longrightarrow> p\<noteq> 0\<^sub>p \<Longrightarrow> isnpolyh (shift1 p) 0"
   719 lemma shift1_isnpolyh: "isnpolyh p n0 \<Longrightarrow> p\<noteq> 0\<^sub>p \<Longrightarrow> isnpolyh (shift1 p) 0"
   719   using isnpolyh_mono[where n="n0" and n'="0" and p="p"] by (simp add: shift1_def)
   720   using isnpolyh_mono[where n="n0" and n'="0" and p="p"] by (simp add: shift1_def)
   720 
   721 
   721 lemma funpow_shift1_1: 
   722 lemma funpow_shift1_1: 
   729   assumes np: "isnpolyh p n"
   730   assumes np: "isnpolyh p n"
   730   shows "Ipoly bs (Add (Mul (head p) (Pw (Bound 0) (degree p))) (behead p)) = (Ipoly bs p :: 'a :: {field_char_0, field_inverse_zero})"
   731   shows "Ipoly bs (Add (Mul (head p) (Pw (Bound 0) (degree p))) (behead p)) = (Ipoly bs p :: 'a :: {field_char_0, field_inverse_zero})"
   731   using np
   732   using np
   732 proof (induct p arbitrary: n rule: behead.induct)
   733 proof (induct p arbitrary: n rule: behead.induct)
   733   case (1 c p n) hence pn: "isnpolyh p n" by simp
   734   case (1 c p n) hence pn: "isnpolyh p n" by simp
   734   from prems(2)[OF pn] 
   735   from 1(1)[OF pn] 
   735   have th:"Ipoly bs (Add (Mul (head p) (Pw (Bound 0) (degree p))) (behead p)) = Ipoly bs p" . 
   736   have th:"Ipoly bs (Add (Mul (head p) (Pw (Bound 0) (degree p))) (behead p)) = Ipoly bs p" . 
   736   then show ?case using "1.hyps" apply (simp add: Let_def,cases "behead p = 0\<^sub>p")
   737   then show ?case using "1.hyps" apply (simp add: Let_def,cases "behead p = 0\<^sub>p")
   737     by (simp_all add: th[symmetric] field_simps power_Suc)
   738     by (simp_all add: th[symmetric] field_simps)
   738 qed (auto simp add: Let_def)
   739 qed (auto simp add: Let_def)
   739 
   740 
   740 lemma behead_isnpolyh:
   741 lemma behead_isnpolyh:
   741   assumes np: "isnpolyh p n" shows "isnpolyh (behead p) n"
   742   assumes np: "isnpolyh p n" shows "isnpolyh (behead p) n"
   742   using np by (induct p rule: behead.induct, auto simp add: Let_def isnpolyh_mono)
   743   using np by (induct p rule: behead.induct, auto simp add: Let_def isnpolyh_mono)
   745 lemma isnpolyh_polybound0: "isnpolyh p (Suc n) \<Longrightarrow> polybound0 p"
   746 lemma isnpolyh_polybound0: "isnpolyh p (Suc n) \<Longrightarrow> polybound0 p"
   746 proof(induct p arbitrary: n rule: poly.induct, auto)
   747 proof(induct p arbitrary: n rule: poly.induct, auto)
   747   case (goal1 c n p n')
   748   case (goal1 c n p n')
   748   hence "n = Suc (n - 1)" by simp
   749   hence "n = Suc (n - 1)" by simp
   749   hence "isnpolyh p (Suc (n - 1))"  using `isnpolyh p n` by simp
   750   hence "isnpolyh p (Suc (n - 1))"  using `isnpolyh p n` by simp
   750   with prems(2) show ?case by simp
   751   with goal1(2) show ?case by simp
   751 qed
   752 qed
   752 
   753 
   753 lemma isconstant_polybound0: "isnpolyh p n0 \<Longrightarrow> isconstant p \<longleftrightarrow> polybound0 p"
   754 lemma isconstant_polybound0: "isnpolyh p n0 \<Longrightarrow> isconstant p \<longleftrightarrow> polybound0 p"
   754 by (induct p arbitrary: n0 rule: isconstant.induct, auto simp add: isnpolyh_polybound0)
   755 by (induct p arbitrary: n0 rule: isconstant.induct, auto simp add: isnpolyh_polybound0)
   755 
   756 
   836   have eq: "bs = ?tbs @ (drop ?ip bs)" by simp
   837   have eq: "bs = ?tbs @ (drop ?ip bs)" by simp
   837   from wf_bs_I[OF wf', of "drop ?ip bs"] show ?thesis using eq by simp
   838   from wf_bs_I[OF wf', of "drop ?ip bs"] show ?thesis using eq by simp
   838 qed
   839 qed
   839 
   840 
   840 lemma decr_maxindex: "polybound0 p \<Longrightarrow> maxindex (decrpoly p) = maxindex p - 1"
   841 lemma decr_maxindex: "polybound0 p \<Longrightarrow> maxindex (decrpoly p) = maxindex p - 1"
   841   by (induct p, auto)
   842   by (induct p) auto
   842 
   843 
   843 lemma wf_bs_insensitive: "length bs = length bs' \<Longrightarrow> wf_bs bs p = wf_bs bs' p"
   844 lemma wf_bs_insensitive: "length bs = length bs' \<Longrightarrow> wf_bs bs p = wf_bs bs' p"
   844   unfolding wf_bs_def by simp
   845   unfolding wf_bs_def by simp
   845 
   846 
   846 lemma wf_bs_insensitive': "wf_bs (x#bs) p = wf_bs (y#bs) p"
   847 lemma wf_bs_insensitive': "wf_bs (x#bs) p = wf_bs (y#bs) p"
  1031   and np: "isnpolyh p n0" shows "p +\<^sub>p 0\<^sub>p = p" and "0\<^sub>p +\<^sub>p p = p"
  1032   and np: "isnpolyh p n0" shows "p +\<^sub>p 0\<^sub>p = p" and "0\<^sub>p +\<^sub>p p = p"
  1032   using isnpolyh_unique[OF polyadd_normh[OF np zero_normh] np] 
  1033   using isnpolyh_unique[OF polyadd_normh[OF np zero_normh] np] 
  1033     isnpolyh_unique[OF polyadd_normh[OF zero_normh np] np] by simp_all
  1034     isnpolyh_unique[OF polyadd_normh[OF zero_normh np] np] by simp_all
  1034 
  1035 
  1035 lemma polymul_1[simp]: 
  1036 lemma polymul_1[simp]: 
  1036     assumes "SORT_CONSTRAINT('a::{field_char_0, field_inverse_zero})"
  1037   assumes "SORT_CONSTRAINT('a::{field_char_0, field_inverse_zero})"
  1037   and np: "isnpolyh p n0" shows "p *\<^sub>p 1\<^sub>p = p" and "1\<^sub>p *\<^sub>p p = p"
  1038   and np: "isnpolyh p n0" shows "p *\<^sub>p 1\<^sub>p = p" and "1\<^sub>p *\<^sub>p p = p"
  1038   using isnpolyh_unique[OF polymul_normh[OF np one_normh] np] 
  1039   using isnpolyh_unique[OF polymul_normh[OF np one_normh] np] 
  1039     isnpolyh_unique[OF polymul_normh[OF one_normh np] np] by simp_all
  1040     isnpolyh_unique[OF polymul_normh[OF one_normh np] np] by simp_all
  1040 lemma polymul_0[simp]: 
  1041 lemma polymul_0[simp]: 
  1041   assumes "SORT_CONSTRAINT('a::{field_char_0, field_inverse_zero})"
  1042   assumes "SORT_CONSTRAINT('a::{field_char_0, field_inverse_zero})"
  1099 proof(induct p q rule:polyadd.induct)
  1100 proof(induct p q rule:polyadd.induct)
  1100   case (1 a b a' b') thus ?case by (simp add: Nsub_def Nsub0[simplified Nsub_def]) 
  1101   case (1 a b a' b') thus ?case by (simp add: Nsub_def Nsub0[simplified Nsub_def]) 
  1101 next
  1102 next
  1102   case (2 a b c' n' p') 
  1103   case (2 a b c' n' p') 
  1103   let ?c = "(a,b)"
  1104   let ?c = "(a,b)"
  1104   from prems have "degree (C ?c) = degree (CN c' n' p')" by simp
  1105   from 2 have "degree (C ?c) = degree (CN c' n' p')" by simp
  1105   hence nz:"n' > 0" by (cases n', auto)
  1106   hence nz:"n' > 0" by (cases n', auto)
  1106   hence "head (CN c' n' p') = CN c' n' p'" by (cases n', auto)
  1107   hence "head (CN c' n' p') = CN c' n' p'" by (cases n', auto)
  1107   with prems show ?case by simp
  1108   with 2 show ?case by simp
  1108 next
  1109 next
  1109   case (3 c n p a' b') 
  1110   case (3 c n p a' b') 
  1110   let ?c' = "(a',b')"
  1111   let ?c' = "(a',b')"
  1111   from prems have "degree (C ?c') = degree (CN c n p)" by simp
  1112   from 3 have "degree (C ?c') = degree (CN c n p)" by simp
  1112   hence nz:"n > 0" by (cases n, auto)
  1113   hence nz:"n > 0" by (cases n, auto)
  1113   hence "head (CN c n p) = CN c n p" by (cases n, auto)
  1114   hence "head (CN c n p) = CN c n p" by (cases n, auto)
  1114   with prems show ?case by simp
  1115   with 3 show ?case by simp
  1115 next
  1116 next
  1116   case (4 c n p c' n' p')
  1117   case (4 c n p c' n' p')
  1117   hence H: "isnpolyh (CN c n p) n0" "isnpolyh (CN c' n' p') n1" 
  1118   hence H: "isnpolyh (CN c n p) n0" "isnpolyh (CN c' n' p') n1" 
  1118     "head (CN c n p) = head (CN c' n' p')" "degree (CN c n p) = degree (CN c' n' p')" by simp+
  1119     "head (CN c n p) = head (CN c' n' p')" "degree (CN c n p) = degree (CN c' n' p')" by simp+
  1119   hence degc: "degree c = 0" and degc': "degree c' = 0" by simp_all  
  1120   hence degc: "degree c = 0" and degc': "degree c' = 0" by simp_all  
  1124   from H have pnh: "isnpolyh p n" and p'nh: "isnpolyh p' n'" by auto
  1125   from H have pnh: "isnpolyh p n" and p'nh: "isnpolyh p' n'" by auto
  1125   have "n = n' \<or> n < n' \<or> n > n'" by arith
  1126   have "n = n' \<or> n < n' \<or> n > n'" by arith
  1126   moreover
  1127   moreover
  1127   {assume nn': "n = n'"
  1128   {assume nn': "n = n'"
  1128     have "n = 0 \<or> n >0" by arith
  1129     have "n = 0 \<or> n >0" by arith
  1129     moreover {assume nz: "n = 0" hence ?case using prems by (auto simp add: Let_def degcmc')}
  1130     moreover {assume nz: "n = 0" hence ?case using 4 nn' by (auto simp add: Let_def degcmc')}
  1130     moreover {assume nz: "n > 0"
  1131     moreover {assume nz: "n > 0"
  1131       with nn' H(3) have  cc':"c = c'" and pp': "p = p'" by (cases n, auto)+
  1132       with nn' H(3) have  cc': "c = c'" and pp': "p = p'" by (cases n, auto)+
  1132       hence ?case using polysub_same_0[OF p'nh, simplified polysub_def split_def fst_conv snd_conv] polysub_same_0[OF c'nh, simplified polysub_def split_def fst_conv snd_conv] using nn' prems by (simp add: Let_def)}
  1133       hence ?case
       
  1134         using polysub_same_0 [OF p'nh, simplified polysub_def split_def fst_conv snd_conv]
       
  1135           polysub_same_0 [OF c'nh, simplified polysub_def split_def fst_conv snd_conv]
       
  1136         using 4 nn' by (simp add: Let_def) }
  1133     ultimately have ?case by blast}
  1137     ultimately have ?case by blast}
  1134   moreover
  1138   moreover
  1135   {assume nn': "n < n'" hence n'p: "n' > 0" by simp 
  1139   {assume nn': "n < n'" hence n'p: "n' > 0" by simp 
  1136     hence headcnp':"head (CN c' n' p') = CN c' n' p'"  by (cases n', simp_all)
  1140     hence headcnp':"head (CN c' n' p') = CN c' n' p'"  by (cases n', simp_all)
  1137     have degcnp': "degree (CN c' n' p') = 0" and degcnpeq: "degree (CN c n p) = degree (CN c' n' p')" using prems by (cases n', simp_all)
  1141     have degcnp': "degree (CN c' n' p') = 0" and degcnpeq: "degree (CN c n p) = degree (CN c' n' p')"
  1138     hence "n > 0" by (cases n, simp_all)
  1142       using 4 nn' by (cases n', simp_all)
  1139     hence headcnp: "head (CN c n p) = CN c n p" by (cases n, auto)
  1143     hence "n > 0" by (cases n) simp_all
  1140     from H(3) headcnp headcnp' nn' have ?case by auto}
  1144     hence headcnp: "head (CN c n p) = CN c n p" by (cases n) auto
       
  1145     from H(3) headcnp headcnp' nn' have ?case by auto }
  1141   moreover
  1146   moreover
  1142   {assume nn': "n > n'"  hence np: "n > 0" by simp 
  1147   {assume nn': "n > n'"  hence np: "n > 0" by simp 
  1143     hence headcnp:"head (CN c n p) = CN c n p"  by (cases n, simp_all)
  1148     hence headcnp: "head (CN c n p) = CN c n p" by (cases n) simp_all
  1144     from prems have degcnpeq: "degree (CN c' n' p') = degree (CN c n p)" by simp
  1149     from 4 have degcnpeq: "degree (CN c' n' p') = degree (CN c n p)" by simp
  1145     from np have degcnp: "degree (CN c n p) = 0" by (cases n, simp_all)
  1150     from np have degcnp: "degree (CN c n p) = 0" by (cases n) simp_all
  1146     with degcnpeq have "n' > 0" by (cases n', simp_all)
  1151     with degcnpeq have "n' > 0" by (cases n', simp_all)
  1147     hence headcnp': "head (CN c' n' p') = CN c' n' p'" by (cases n', auto)
  1152     hence headcnp': "head (CN c' n' p') = CN c' n' p'" by (cases n') auto
  1148     from H(3) headcnp headcnp' nn' have ?case by auto}
  1153     from H(3) headcnp headcnp' nn' have ?case by auto }
  1149   ultimately show ?case  by blast
  1154   ultimately show ?case  by blast
  1150 qed auto 
  1155 qed auto 
  1151  
  1156  
  1152 lemma shift1_head : "isnpolyh p n0 \<Longrightarrow> head (shift1 p) = head p"
  1157 lemma shift1_head : "isnpolyh p n0 \<Longrightarrow> head (shift1 p) = head p"
  1153 by (induct p arbitrary: n0 rule: head.induct, simp_all add: shift1_def)
  1158   by (induct p arbitrary: n0 rule: head.induct) (simp_all add: shift1_def)
  1154 
  1159 
  1155 lemma funpow_shift1_head: "isnpolyh p n0 \<Longrightarrow> p\<noteq> 0\<^sub>p \<Longrightarrow> head (funpow k shift1 p) = head p"
  1160 lemma funpow_shift1_head: "isnpolyh p n0 \<Longrightarrow> p\<noteq> 0\<^sub>p \<Longrightarrow> head (funpow k shift1 p) = head p"
  1156 proof(induct k arbitrary: n0 p)
  1161 proof(induct k arbitrary: n0 p)
  1157   case (Suc k n0 p) hence "isnpolyh (shift1 p) 0" by (simp add: shift1_isnpolyh)
  1162   case (Suc k n0 p) hence "isnpolyh (shift1 p) 0" by (simp add: shift1_isnpolyh)
  1158   with prems have "head (funpow k shift1 (shift1 p)) = head (shift1 p)"
  1163   with Suc have "head (funpow k shift1 (shift1 p)) = head (shift1 p)"
  1159     and "head (shift1 p) = head p" by (simp_all add: shift1_head) 
  1164     and "head (shift1 p) = head p" by (simp_all add: shift1_head) 
  1160   thus ?case by (simp add: funpow_swap1)
  1165   thus ?case by (simp add: funpow_swap1)
  1161 qed auto  
  1166 qed auto  
  1162 
  1167 
  1163 lemma shift1_degree: "degree (shift1 p) = 1 + degree p"
  1168 lemma shift1_degree: "degree (shift1 p) = 1 + degree p"
  1192 apply (case_tac "pa +\<^sub>p p' = 0\<^sub>p")
  1197 apply (case_tac "pa +\<^sub>p p' = 0\<^sub>p")
  1193 apply (auto simp add: polyadd_eq_const_degree)
  1198 apply (auto simp add: polyadd_eq_const_degree)
  1194 apply (metis head_nz)
  1199 apply (metis head_nz)
  1195 apply (metis head_nz)
  1200 apply (metis head_nz)
  1196 apply (metis degree.simps(9) gr0_conv_Suc head.simps(1) less_Suc0 not_less_eq)
  1201 apply (metis degree.simps(9) gr0_conv_Suc head.simps(1) less_Suc0 not_less_eq)
  1197 by (metis degree.simps(9) gr0_conv_Suc nat_less_le order_le_less_trans)
  1202 apply (metis degree.simps(9) gr0_conv_Suc nat_less_le order_le_less_trans)
       
  1203 done
  1198 
  1204 
  1199 lemma polymul_head_polyeq: 
  1205 lemma polymul_head_polyeq: 
  1200    assumes "SORT_CONSTRAINT('a::{field_char_0, field_inverse_zero})"
  1206   assumes "SORT_CONSTRAINT('a::{field_char_0, field_inverse_zero})"
  1201   shows "\<lbrakk>isnpolyh p n0; isnpolyh q n1 ; p \<noteq> 0\<^sub>p ; q \<noteq> 0\<^sub>p \<rbrakk> \<Longrightarrow> head (p *\<^sub>p q) = head p *\<^sub>p head q"
  1207   shows "\<lbrakk>isnpolyh p n0; isnpolyh q n1 ; p \<noteq> 0\<^sub>p ; q \<noteq> 0\<^sub>p \<rbrakk> \<Longrightarrow> head (p *\<^sub>p q) = head p *\<^sub>p head q"
  1202 proof (induct p q arbitrary: n0 n1 rule: polymul.induct)
  1208 proof (induct p q arbitrary: n0 n1 rule: polymul.induct)
  1203   case (2 a b c' n' p' n0 n1)
  1209   case (2 a b c' n' p' n0 n1)
  1204   hence "isnpolyh (head (CN c' n' p')) n1" "isnormNum (a,b)"  by (simp_all add: head_isnpolyh)
  1210   hence "isnpolyh (head (CN c' n' p')) n1" "isnormNum (a,b)"  by (simp_all add: head_isnpolyh)
  1205   thus ?case using prems by (cases n', auto) 
  1211   thus ?case using 2 by (cases n') auto
  1206 next 
  1212 next 
  1207   case (3 c n p a' b' n0 n1) 
  1213   case (3 c n p a' b' n0 n1) 
  1208   hence "isnpolyh (head (CN c n p)) n0" "isnormNum (a',b')"  by (simp_all add: head_isnpolyh)
  1214   hence "isnpolyh (head (CN c n p)) n0" "isnormNum (a',b')"  by (simp_all add: head_isnpolyh)
  1209   thus ?case using prems by (cases n, auto)
  1215   thus ?case using 3 by (cases n) auto
  1210 next
  1216 next
  1211   case (4 c n p c' n' p' n0 n1)
  1217   case (4 c n p c' n' p' n0 n1)
  1212   hence norm: "isnpolyh p n" "isnpolyh c (Suc n)" "isnpolyh p' n'" "isnpolyh c' (Suc n')"
  1218   hence norm: "isnpolyh p n" "isnpolyh c (Suc n)" "isnpolyh p' n'" "isnpolyh c' (Suc n')"
  1213     "isnpolyh (CN c n p) n" "isnpolyh (CN c' n' p') n'"
  1219     "isnpolyh (CN c n p) n" "isnpolyh (CN c' n' p') n'"
  1214     by simp_all
  1220     by simp_all
  1215   have "n < n' \<or> n' < n \<or> n = n'" by arith
  1221   have "n < n' \<or> n' < n \<or> n = n'" by arith
  1216   moreover 
  1222   moreover 
  1217   {assume nn': "n < n'" hence ?case 
  1223   {assume nn': "n < n'" hence ?case 
  1218       thm prems
  1224     using norm 
  1219       using norm 
  1225     4(5)[rule_format, OF nn' norm(1,6)]
  1220     prems(6)[rule_format, OF nn' norm(1,6)]
  1226     4(6)[rule_format, OF nn' norm(2,6)] by (simp, cases n, simp,cases n', simp_all) }
  1221     prems(7)[rule_format, OF nn' norm(2,6)] by (simp, cases n, simp,cases n', simp_all)}
       
  1222   moreover {assume nn': "n'< n"
  1227   moreover {assume nn': "n'< n"
  1223     hence stupid: "n' < n \<and> \<not> n < n'" by simp
  1228     hence stupid: "n' < n \<and> \<not> n < n'" by simp
  1224     hence ?case using norm prems(4) [rule_format, OF stupid norm(5,3)]
  1229     hence ?case using norm 4(3) [rule_format, OF stupid norm(5,3)]
  1225       prems(5)[rule_format, OF stupid norm(5,4)] 
  1230       4(4)[rule_format, OF stupid norm(5,4)] 
  1226       by (simp,cases n',simp,cases n,auto)}
  1231       by (simp,cases n',simp,cases n,auto) }
  1227   moreover {assume nn': "n' = n"
  1232   moreover {assume nn': "n' = n"
  1228     hence stupid: "\<not> n' < n \<and> \<not> n < n'" by simp
  1233     hence stupid: "\<not> n' < n \<and> \<not> n < n'" by simp
  1229     from nn' polymul_normh[OF norm(5,4)] 
  1234     from nn' polymul_normh[OF norm(5,4)] 
  1230     have ncnpc':"isnpolyh (CN c n p *\<^sub>p c') n" by (simp add: min_def)
  1235     have ncnpc':"isnpolyh (CN c n p *\<^sub>p c') n" by (simp add: min_def)
  1231     from nn' polymul_normh[OF norm(5,3)] norm 
  1236     from nn' polymul_normh[OF norm(5,3)] norm 
  1245         polymul_degreen[OF norm(5,3), where m="0"] nn' nz degree_eq_degreen0
  1250         polymul_degreen[OF norm(5,3), where m="0"] nn' nz degree_eq_degreen0
  1246       norm(5,6) degree_npolyhCN[OF norm(6)]
  1251       norm(5,6) degree_npolyhCN[OF norm(6)]
  1247     have dth:"degree (CN c 0 p *\<^sub>p c') < degree (CN 0\<^sub>p 0 (CN c 0 p *\<^sub>p p'))" by simp
  1252     have dth:"degree (CN c 0 p *\<^sub>p c') < degree (CN 0\<^sub>p 0 (CN c 0 p *\<^sub>p p'))" by simp
  1248     hence dth':"degree (CN c 0 p *\<^sub>p c') \<noteq> degree (CN 0\<^sub>p 0 (CN c 0 p *\<^sub>p p'))" by simp
  1253     hence dth':"degree (CN c 0 p *\<^sub>p c') \<noteq> degree (CN 0\<^sub>p 0 (CN c 0 p *\<^sub>p p'))" by simp
  1249     from polyadd_head[OF ncnpc'[simplified nz] ncnpp0'[simplified nz] dth'] dth
  1254     from polyadd_head[OF ncnpc'[simplified nz] ncnpp0'[simplified nz] dth'] dth
  1250     have ?case   using norm prems(2)[rule_format, OF stupid norm(5,3)]
  1255     have ?case using norm 4(1)[rule_format, OF stupid norm(5,3)]
  1251         prems(3)[rule_format, OF stupid norm(5,4)] nn' nz by simp }
  1256         4(2)[rule_format, OF stupid norm(5,4)] nn' nz by simp }
  1252     ultimately have ?case by (cases n) auto} 
  1257     ultimately have ?case by (cases n) auto} 
  1253   ultimately show ?case by blast
  1258   ultimately show ?case by blast
  1254 qed simp_all
  1259 qed simp_all
  1255 
  1260 
  1256 lemma degree_coefficients: "degree p = length (coefficients p) - 1"
  1261 lemma degree_coefficients: "degree p = length (coefficients p) - 1"
  1601 lemma swap_same_id[simp]: "swap n n t = t"
  1606 lemma swap_same_id[simp]: "swap n n t = t"
  1602   by (induct t, simp_all)
  1607   by (induct t, simp_all)
  1603 
  1608 
  1604 definition "swapnorm n m t = polynate (swap n m t)"
  1609 definition "swapnorm n m t = polynate (swap n m t)"
  1605 
  1610 
  1606 lemma swapnorm: assumes nbs: "n < length bs" and mbs: "m < length bs"
  1611 lemma swapnorm:
       
  1612   assumes nbs: "n < length bs" and mbs: "m < length bs"
  1607   shows "((Ipoly bs (swapnorm n m t) :: 'a\<Colon>{field_char_0, field_inverse_zero})) = Ipoly ((bs[n:= bs!m])[m:= bs!n]) t"
  1613   shows "((Ipoly bs (swapnorm n m t) :: 'a\<Colon>{field_char_0, field_inverse_zero})) = Ipoly ((bs[n:= bs!m])[m:= bs!n]) t"
  1608   using swap[OF prems] swapnorm_def by simp
  1614   using swap[OF assms] swapnorm_def by simp
  1609 
  1615 
  1610 lemma swapnorm_isnpoly[simp]: 
  1616 lemma swapnorm_isnpoly[simp]: 
  1611     assumes "SORT_CONSTRAINT('a::{field_char_0, field_inverse_zero})"
  1617   assumes "SORT_CONSTRAINT('a::{field_char_0, field_inverse_zero})"
  1612   shows "isnpoly (swapnorm n m p)"
  1618   shows "isnpoly (swapnorm n m p)"
  1613   unfolding swapnorm_def by simp
  1619   unfolding swapnorm_def by simp
  1614 
  1620 
  1615 definition "polydivideby n s p = 
  1621 definition "polydivideby n s p = 
  1616     (let ss = swapnorm 0 n s ; sp = swapnorm 0 n p ; h = head sp; (k,r) = polydivide ss sp
  1622     (let ss = swapnorm 0 n s ; sp = swapnorm 0 n p ; h = head sp; (k,r) = polydivide ss sp
  1623   "isweaknpoly (C c) = True"
  1629   "isweaknpoly (C c) = True"
  1624   "isweaknpoly (CN c n p) \<longleftrightarrow> isweaknpoly c \<and> isweaknpoly p"
  1630   "isweaknpoly (CN c n p) \<longleftrightarrow> isweaknpoly c \<and> isweaknpoly p"
  1625   "isweaknpoly p = False"       
  1631   "isweaknpoly p = False"       
  1626 
  1632 
  1627 lemma isnpolyh_isweaknpoly: "isnpolyh p n0 \<Longrightarrow> isweaknpoly p" 
  1633 lemma isnpolyh_isweaknpoly: "isnpolyh p n0 \<Longrightarrow> isweaknpoly p" 
  1628   by (induct p arbitrary: n0, auto)
  1634   by (induct p arbitrary: n0) auto
  1629 
  1635 
  1630 lemma swap_isweanpoly: "isweaknpoly p \<Longrightarrow> isweaknpoly (swap n m p)" 
  1636 lemma swap_isweanpoly: "isweaknpoly p \<Longrightarrow> isweaknpoly (swap n m p)" 
  1631   by (induct p, auto)
  1637   by (induct p) auto
  1632 
  1638 
  1633 end
  1639 end