src/HOL/Decision_Procs/Reflected_Multivariate_Polynomial.thy
changeset 56198 21dd034523e5
parent 56073 29e308b56d23
child 56207 52d5067ca06a
equal deleted inserted replaced
56197:416f7a00e4cb 56198:21dd034523e5
  1479   by (induct p arbitrary: n0 rule: head.induct) (simp_all add: shift1_def)
  1479   by (induct p arbitrary: n0 rule: head.induct) (simp_all add: shift1_def)
  1480 
  1480 
  1481 lemma funpow_shift1_head: "isnpolyh p n0 \<Longrightarrow> p\<noteq> 0\<^sub>p \<Longrightarrow> head (funpow k shift1 p) = head p"
  1481 lemma funpow_shift1_head: "isnpolyh p n0 \<Longrightarrow> p\<noteq> 0\<^sub>p \<Longrightarrow> head (funpow k shift1 p) = head p"
  1482 proof (induct k arbitrary: n0 p)
  1482 proof (induct k arbitrary: n0 p)
  1483   case 0
  1483   case 0
  1484   then show ?case by auto
  1484   then show ?case
       
  1485     by auto
  1485 next
  1486 next
  1486   case (Suc k n0 p)
  1487   case (Suc k n0 p)
  1487   then have "isnpolyh (shift1 p) 0"
  1488   then have "isnpolyh (shift1 p) 0"
  1488     by (simp add: shift1_isnpolyh)
  1489     by (simp add: shift1_isnpolyh)
  1489   with Suc have "head (funpow k shift1 (shift1 p)) = head (shift1 p)"
  1490   with Suc have "head (funpow k shift1 (shift1 p)) = head (shift1 p)"
  1520     and nq: "isnpolyh q n1"
  1521     and nq: "isnpolyh q n1"
  1521     and deg: "degree p \<noteq> degree q"
  1522     and deg: "degree p \<noteq> degree q"
  1522   shows "head (p +\<^sub>p q) = (if degree p < degree q then head q else head p)"
  1523   shows "head (p +\<^sub>p q) = (if degree p < degree q then head q else head p)"
  1523   using np nq deg
  1524   using np nq deg
  1524   apply (induct p q arbitrary: n0 n1 rule: polyadd.induct)
  1525   apply (induct p q arbitrary: n0 n1 rule: polyadd.induct)
  1525   using np
       
  1526   apply simp_all
  1526   apply simp_all
  1527   apply (case_tac n', simp, simp)
  1527   apply (case_tac n', simp, simp)
  1528   apply (case_tac n, simp, simp)
  1528   apply (case_tac n, simp, simp)
  1529   apply (case_tac n, case_tac n', simp add: Let_def)
  1529   apply (case_tac n, case_tac n', simp add: Let_def)
  1530   apply (auto simp add: polyadd_eq_const_degree)[2]
  1530   apply (auto simp add: polyadd_eq_const_degree)[2]
  1655 lemma polydivide_aux_properties:
  1655 lemma polydivide_aux_properties:
  1656   assumes "SORT_CONSTRAINT('a::{field_char_0,field_inverse_zero})"
  1656   assumes "SORT_CONSTRAINT('a::{field_char_0,field_inverse_zero})"
  1657     and np: "isnpolyh p n0"
  1657     and np: "isnpolyh p n0"
  1658     and ns: "isnpolyh s n1"
  1658     and ns: "isnpolyh s n1"
  1659     and ap: "head p = a"
  1659     and ap: "head p = a"
  1660     and ndp: "degree p = n" and pnz: "p \<noteq> 0\<^sub>p"
  1660     and ndp: "degree p = n"
  1661   shows "polydivide_aux a n p k s = (k',r) \<longrightarrow> k' \<ge> k \<and> (degree r = 0 \<or> degree r < degree p) \<and>
  1661     and pnz: "p \<noteq> 0\<^sub>p"
       
  1662   shows "polydivide_aux a n p k s = (k', r) \<longrightarrow> k' \<ge> k \<and> (degree r = 0 \<or> degree r < degree p) \<and>
  1662     (\<exists>nr. isnpolyh r nr) \<and> (\<exists>q n1. isnpolyh q n1 \<and> (polypow (k' - k) a) *\<^sub>p s = p *\<^sub>p q +\<^sub>p r)"
  1663     (\<exists>nr. isnpolyh r nr) \<and> (\<exists>q n1. isnpolyh q n1 \<and> (polypow (k' - k) a) *\<^sub>p s = p *\<^sub>p q +\<^sub>p r)"
  1663   using ns
  1664   using ns
  1664 proof (induct "degree s" arbitrary: s k k' r n1 rule: less_induct)
  1665 proof (induct "degree s" arbitrary: s k k' r n1 rule: less_induct)
  1665   case less
  1666   case less
  1666   let ?qths = "\<exists>q n1. isnpolyh q n1 \<and> (a ^\<^sub>p (k' - k) *\<^sub>p s = p *\<^sub>p q +\<^sub>p r)"
  1667   let ?qths = "\<exists>q n1. isnpolyh q n1 \<and> (a ^\<^sub>p (k' - k) *\<^sub>p s = p *\<^sub>p q +\<^sub>p r)"
  1977 subsection {* More about polypoly and pnormal etc *}
  1978 subsection {* More about polypoly and pnormal etc *}
  1978 
  1979 
  1979 definition "isnonconstant p \<longleftrightarrow> \<not> isconstant p"
  1980 definition "isnonconstant p \<longleftrightarrow> \<not> isconstant p"
  1980 
  1981 
  1981 lemma isnonconstant_pnormal_iff:
  1982 lemma isnonconstant_pnormal_iff:
  1982   assumes nc: "isnonconstant p"
  1983   assumes "isnonconstant p"
  1983   shows "pnormal (polypoly bs p) \<longleftrightarrow> Ipoly bs (head p) \<noteq> 0"
  1984   shows "pnormal (polypoly bs p) \<longleftrightarrow> Ipoly bs (head p) \<noteq> 0"
  1984 proof
  1985 proof
  1985   let ?p = "polypoly bs p"
  1986   let ?p = "polypoly bs p"
  1986   assume H: "pnormal ?p"
  1987   assume H: "pnormal ?p"
  1987   have csz: "coefficients p \<noteq> []"
  1988   have csz: "coefficients p \<noteq> []"
  1988     using nc by (cases p) auto
  1989     using assms by (cases p) auto
  1989   from coefficients_head[of p] last_map[OF csz, of "Ipoly bs"] pnormal_last_nonzero[OF H]
  1990   from coefficients_head[of p] last_map[OF csz, of "Ipoly bs"] pnormal_last_nonzero[OF H]
  1990   show "Ipoly bs (head p) \<noteq> 0"
  1991   show "Ipoly bs (head p) \<noteq> 0"
  1991     by (simp add: polypoly_def)
  1992     by (simp add: polypoly_def)
  1992 next
  1993 next
  1993   assume h: "\<lparr>head p\<rparr>\<^sub>p\<^bsup>bs\<^esup> \<noteq> 0"
  1994   assume h: "\<lparr>head p\<rparr>\<^sub>p\<^bsup>bs\<^esup> \<noteq> 0"
  1994   let ?p = "polypoly bs p"
  1995   let ?p = "polypoly bs p"
  1995   have csz: "coefficients p \<noteq> []"
  1996   have csz: "coefficients p \<noteq> []"
  1996     using nc by (cases p) auto
  1997     using assms by (cases p) auto
  1997   then have pz: "?p \<noteq> []"
  1998   then have pz: "?p \<noteq> []"
  1998     by (simp add: polypoly_def)
  1999     by (simp add: polypoly_def)
  1999   then have lg: "length ?p > 0"
  2000   then have lg: "length ?p > 0"
  2000     by simp
  2001     by simp
  2001   from h coefficients_head[of p] last_map[OF csz, of "Ipoly bs"]
  2002   from h coefficients_head[of p] last_map[OF csz, of "Ipoly bs"]
  2011   apply (case_tac nat)
  2012   apply (case_tac nat)
  2012   apply auto
  2013   apply auto
  2013   done
  2014   done
  2014 
  2015 
  2015 lemma isnonconstant_nonconstant:
  2016 lemma isnonconstant_nonconstant:
  2016   assumes inc: "isnonconstant p"
  2017   assumes "isnonconstant p"
  2017   shows "nonconstant (polypoly bs p) \<longleftrightarrow> Ipoly bs (head p) \<noteq> 0"
  2018   shows "nonconstant (polypoly bs p) \<longleftrightarrow> Ipoly bs (head p) \<noteq> 0"
  2018 proof
  2019 proof
  2019   let ?p = "polypoly bs p"
  2020   let ?p = "polypoly bs p"
  2020   assume nc: "nonconstant ?p"
  2021   assume nc: "nonconstant ?p"
  2021   from isnonconstant_pnormal_iff[OF inc, of bs] nc
  2022   from isnonconstant_pnormal_iff[OF assms, of bs] nc
  2022   show "\<lparr>head p\<rparr>\<^sub>p\<^bsup>bs\<^esup> \<noteq> 0"
  2023   show "\<lparr>head p\<rparr>\<^sub>p\<^bsup>bs\<^esup> \<noteq> 0"
  2023     unfolding nonconstant_def by blast
  2024     unfolding nonconstant_def by blast
  2024 next
  2025 next
  2025   let ?p = "polypoly bs p"
  2026   let ?p = "polypoly bs p"
  2026   assume h: "\<lparr>head p\<rparr>\<^sub>p\<^bsup>bs\<^esup> \<noteq> 0"
  2027   assume h: "\<lparr>head p\<rparr>\<^sub>p\<^bsup>bs\<^esup> \<noteq> 0"
  2027   from isnonconstant_pnormal_iff[OF inc, of bs] h
  2028   from isnonconstant_pnormal_iff[OF assms, of bs] h
  2028   have pn: "pnormal ?p"
  2029   have pn: "pnormal ?p"
  2029     by blast
  2030     by blast
  2030   {
  2031   {
  2031     fix x
  2032     fix x
  2032     assume H: "?p = [x]"
  2033     assume H: "?p = [x]"
  2033     from H have "length (coefficients p) = 1"
  2034     from H have "length (coefficients p) = 1"
  2034       unfolding polypoly_def by auto
  2035       unfolding polypoly_def by auto
  2035     with isnonconstant_coefficients_length[OF inc]
  2036     with isnonconstant_coefficients_length[OF assms]
  2036       have False by arith
  2037     have False by arith
  2037   }
  2038   }
  2038   then show "nonconstant ?p"
  2039   then show "nonconstant ?p"
  2039     using pn unfolding nonconstant_def by blast
  2040     using pn unfolding nonconstant_def by blast
  2040 qed
  2041 qed
  2041 
  2042 
  2075 section {* Swaps ; Division by a certain variable *}
  2076 section {* Swaps ; Division by a certain variable *}
  2076 
  2077 
  2077 primrec swap :: "nat \<Rightarrow> nat \<Rightarrow> poly \<Rightarrow> poly"
  2078 primrec swap :: "nat \<Rightarrow> nat \<Rightarrow> poly \<Rightarrow> poly"
  2078 where
  2079 where
  2079   "swap n m (C x) = C x"
  2080   "swap n m (C x) = C x"
  2080 | "swap n m (Bound k) = Bound (if k = n then m else if k=m then n else k)"
  2081 | "swap n m (Bound k) = Bound (if k = n then m else if k = m then n else k)"
  2081 | "swap n m (Neg t) = Neg (swap n m t)"
  2082 | "swap n m (Neg t) = Neg (swap n m t)"
  2082 | "swap n m (Add s t) = Add (swap n m s) (swap n m t)"
  2083 | "swap n m (Add s t) = Add (swap n m s) (swap n m t)"
  2083 | "swap n m (Sub s t) = Sub (swap n m s) (swap n m t)"
  2084 | "swap n m (Sub s t) = Sub (swap n m s) (swap n m t)"
  2084 | "swap n m (Mul s t) = Mul (swap n m s) (swap n m t)"
  2085 | "swap n m (Mul s t) = Mul (swap n m s) (swap n m t)"
  2085 | "swap n m (Pw t k) = Pw (swap n m t) k"
  2086 | "swap n m (Pw t k) = Pw (swap n m t) k"