src/HOL/Decision_Procs/Reflected_Multivariate_Polynomial.thy
changeset 80103 577a2896ace9
parent 68442 477b3f7067c9
equal deleted inserted replaced
80102:fddf8d9c8083 80103:577a2896ace9
   891 
   891 
   892 lemma decrpoly_zero[simp]: "decrpoly p = 0\<^sub>p \<longleftrightarrow> p = 0\<^sub>p"
   892 lemma decrpoly_zero[simp]: "decrpoly p = 0\<^sub>p \<longleftrightarrow> p = 0\<^sub>p"
   893   by (induct p) auto
   893   by (induct p) auto
   894 
   894 
   895 lemma decrpoly_normh: "isnpolyh p n0 \<Longrightarrow> polybound0 p \<Longrightarrow> isnpolyh (decrpoly p) (n0 - 1)"
   895 lemma decrpoly_normh: "isnpolyh p n0 \<Longrightarrow> polybound0 p \<Longrightarrow> isnpolyh (decrpoly p) (n0 - 1)"
   896   apply (induct p arbitrary: n0)
   896   by (induct p arbitrary: n0) force+
   897          apply auto
       
   898   apply atomize
       
   899   apply (rename_tac nat a b, erule_tac x = "Suc nat" in allE)
       
   900   apply auto
       
   901   done
       
   902 
   897 
   903 lemma head_polybound0: "isnpolyh p n0 \<Longrightarrow> polybound0 (head p)"
   898 lemma head_polybound0: "isnpolyh p n0 \<Longrightarrow> polybound0 (head p)"
   904   by (induct p  arbitrary: n0 rule: head.induct) (auto intro: isnpolyh_polybound0)
   899   by (induct p  arbitrary: n0 rule: head.induct) (auto intro: isnpolyh_polybound0)
   905 
   900 
   906 lemma polybound0_I:
   901 lemma polybound0_I:
  1012 
  1007 
  1013 lemma length_le_list_ex: "length xs \<le> n \<Longrightarrow> \<exists>ys. length (xs @ ys) = n"
  1008 lemma length_le_list_ex: "length xs \<le> n \<Longrightarrow> \<exists>ys. length (xs @ ys) = n"
  1014   by (rule exI[where x="replicate (n - length xs) z" for z]) simp
  1009   by (rule exI[where x="replicate (n - length xs) z" for z]) simp
  1015 
  1010 
  1016 lemma isnpolyh_Suc_const: "isnpolyh p (Suc n) \<Longrightarrow> isconstant p"
  1011 lemma isnpolyh_Suc_const: "isnpolyh p (Suc n) \<Longrightarrow> isconstant p"
  1017   apply (cases p)
  1012   by (simp add: isconstant_polybound0 isnpolyh_polybound0)
  1018          apply auto
       
  1019   apply (rename_tac nat a, case_tac "nat")
       
  1020    apply simp_all
       
  1021   done
       
  1022 
  1013 
  1023 lemma wf_bs_polyadd: "wf_bs bs p \<and> wf_bs bs q \<longrightarrow> wf_bs bs (p +\<^sub>p q)"
  1014 lemma wf_bs_polyadd: "wf_bs bs p \<and> wf_bs bs q \<longrightarrow> wf_bs bs (p +\<^sub>p q)"
  1024   by (induct p q rule: polyadd.induct) (auto simp add: Let_def wf_bs_def)
  1015   by (induct p q rule: polyadd.induct) (auto simp add: Let_def wf_bs_def)
  1025 
  1016 
  1026 lemma wf_bs_polyul: "wf_bs bs p \<Longrightarrow> wf_bs bs q \<Longrightarrow> wf_bs bs (p *\<^sub>p q)"
  1017 lemma wf_bs_polyul: "wf_bs bs p \<Longrightarrow> wf_bs bs q \<Longrightarrow> wf_bs bs (p *\<^sub>p q)"
  1027   apply (induct p q arbitrary: bs rule: polymul.induct)
  1018 proof (induct p q rule: polymul.induct)
  1028                       apply (simp_all add: wf_bs_polyadd wf_bs_def)
  1019   case (4 c n p c' n' p')
  1029   apply clarsimp
  1020   then show ?case
  1030   apply (rule wf_bs_polyadd[unfolded wf_bs_def, rule_format])
  1021     apply (simp add: wf_bs_def)
  1031   apply auto
  1022     by (metis Suc_eq_plus1 max.bounded_iff max_0L maxindex.simps(2) maxindex.simps(8) wf_bs_def wf_bs_polyadd)
  1032   done
  1023 qed (simp_all add: wf_bs_def)
  1033 
  1024 
  1034 lemma wf_bs_polyneg: "wf_bs bs p \<Longrightarrow> wf_bs bs (~\<^sub>p p)"
  1025 lemma wf_bs_polyneg: "wf_bs bs p \<Longrightarrow> wf_bs bs (~\<^sub>p p)"
  1035   by (induct p rule: polyneg.induct) (auto simp: wf_bs_def)
  1026   by (induct p rule: polyneg.induct) (auto simp: wf_bs_def)
  1036 
  1027 
  1037 lemma wf_bs_polysub: "wf_bs bs p \<Longrightarrow> wf_bs bs q \<Longrightarrow> wf_bs bs (p -\<^sub>p q)"
  1028 lemma wf_bs_polysub: "wf_bs bs p \<Longrightarrow> wf_bs bs q \<Longrightarrow> wf_bs bs (p -\<^sub>p q)"
  1098   assumes "isnpolyh p n0"
  1089   assumes "isnpolyh p n0"
  1099     and "polybound0 p"
  1090     and "polybound0 p"
  1100   shows "polypoly bs p = [Ipoly bs p]"
  1091   shows "polypoly bs p = [Ipoly bs p]"
  1101   using assms
  1092   using assms
  1102   unfolding polypoly_def
  1093   unfolding polypoly_def
  1103   apply (cases p)
  1094   by (cases p; use gr0_conv_Suc in force)
  1104          apply auto
       
  1105   apply (rename_tac nat a, case_tac nat)
       
  1106    apply auto
       
  1107   done
       
  1108 
  1095 
  1109 lemma head_isnpolyh: "isnpolyh p n0 \<Longrightarrow> isnpolyh (head p) n0"
  1096 lemma head_isnpolyh: "isnpolyh p n0 \<Longrightarrow> isnpolyh (head p) n0"
  1110   by (induct p rule: head.induct) auto
  1097   by (induct p rule: head.induct) auto
  1111 
  1098 
  1112 lemma headn_nz[simp]: "isnpolyh p n0 \<Longrightarrow> headn p m = 0\<^sub>p \<longleftrightarrow> p = 0\<^sub>p"
  1099 lemma headn_nz[simp]: "isnpolyh p n0 \<Longrightarrow> headn p m = 0\<^sub>p \<longleftrightarrow> p = 0\<^sub>p"
  1289   by (induct p rule: degree.induct) simp_all
  1276   by (induct p rule: degree.induct) simp_all
  1290 
  1277 
  1291 lemma degree_polyneg:
  1278 lemma degree_polyneg:
  1292   assumes "isnpolyh p n"
  1279   assumes "isnpolyh p n"
  1293   shows "degree (polyneg p) = degree p"
  1280   shows "degree (polyneg p) = degree p"
  1294   apply (induct p rule: polyneg.induct)
  1281 proof (induct p rule: polyneg.induct)
  1295   using assms
  1282   case (2 c n p)
  1296          apply simp_all
  1283   then show ?case
  1297   apply (case_tac na)
  1284   by simp (smt (verit) degree.elims degree.simps(1) poly.inject(8))
  1298    apply auto
  1285 qed auto
  1299   done
       
  1300 
  1286 
  1301 lemma degree_polyadd:
  1287 lemma degree_polyadd:
  1302   assumes np: "isnpolyh p n0"
  1288   assumes np: "isnpolyh p n0"
  1303     and nq: "isnpolyh q n1"
  1289     and nq: "isnpolyh q n1"
  1304   shows "degree (p +\<^sub>p q) \<le> max (degree p) (degree q)"
  1290   shows "degree (p +\<^sub>p q) \<le> max (degree p) (degree q)"
  1456 lemma head_head[simp]: "isnpolyh p n0 \<Longrightarrow> head (head p) = head p"
  1442 lemma head_head[simp]: "isnpolyh p n0 \<Longrightarrow> head (head p) = head p"
  1457   by (induct p rule: head.induct) auto
  1443   by (induct p rule: head.induct) auto
  1458 
  1444 
  1459 lemma polyadd_eq_const_degree:
  1445 lemma polyadd_eq_const_degree:
  1460   "isnpolyh p n0 \<Longrightarrow> isnpolyh q n1 \<Longrightarrow> polyadd p q = C c \<Longrightarrow> degree p = degree q"
  1446   "isnpolyh p n0 \<Longrightarrow> isnpolyh q n1 \<Longrightarrow> polyadd p q = C c \<Longrightarrow> degree p = degree q"
  1461   using polyadd_eq_const_degreen degree_eq_degreen0 by simp
  1447   by (metis degree_eq_degreen0 polyadd_eq_const_degreen)
       
  1448 
       
  1449 lemma polyadd_head_aux:
       
  1450   assumes "isnpolyh p n0" "isnpolyh q n1"
       
  1451   shows "head (p +\<^sub>p q)
       
  1452            = (if degree p < degree q then head q 
       
  1453               else if degree p > degree q then head p else head (p +\<^sub>p q))"
       
  1454   using assms
       
  1455 proof (induct p q rule: polyadd.induct)
       
  1456   case (4 c n p c' n' p')
       
  1457   then show ?case
       
  1458     by (auto simp add: degree_eq_degreen0 Let_def; metis head_nz)
       
  1459 qed (auto simp: degree_eq_degreen0)
  1462 
  1460 
  1463 lemma polyadd_head:
  1461 lemma polyadd_head:
  1464   assumes np: "isnpolyh p n0"
  1462   assumes "isnpolyh p n0" and "isnpolyh q n1" and "degree p \<noteq> degree q"
  1465     and nq: "isnpolyh q n1"
  1463   shows "head (p +\<^sub>p q) = (if degree p < degree q then head q  else head p)"
  1466     and deg: "degree p \<noteq> degree q"
  1464   by (meson assms nat_neq_iff polyadd_head_aux)
  1467   shows "head (p +\<^sub>p q) = (if degree p < degree q then head q else head p)"
       
  1468   using np nq deg
       
  1469   apply (induct p q arbitrary: n0 n1 rule: polyadd.induct)
       
  1470                       apply simp_all
       
  1471     apply (case_tac n', simp, simp)
       
  1472    apply (case_tac n, simp, simp)
       
  1473   apply (case_tac n, case_tac n', simp add: Let_def)
       
  1474     apply (auto simp add: polyadd_eq_const_degree)[2]
       
  1475     apply (metis head_nz)
       
  1476    apply (metis head_nz)
       
  1477   apply (metis degree.simps(9) gr0_conv_Suc head.simps(1) less_Suc0 not_less_eq)
       
  1478   done
       
  1479 
  1465 
  1480 lemma polymul_head_polyeq:
  1466 lemma polymul_head_polyeq:
  1481   assumes "SORT_CONSTRAINT('a::field_char_0)"
  1467   assumes "SORT_CONSTRAINT('a::field_char_0)"
  1482   shows "isnpolyh p n0 \<Longrightarrow> isnpolyh q n1 \<Longrightarrow> p \<noteq> 0\<^sub>p \<Longrightarrow> q \<noteq> 0\<^sub>p \<Longrightarrow> head (p *\<^sub>p q) = head p *\<^sub>p head q"
  1468   shows "isnpolyh p n0 \<Longrightarrow> isnpolyh q n1 \<Longrightarrow> p \<noteq> 0\<^sub>p \<Longrightarrow> q \<noteq> 0\<^sub>p \<Longrightarrow> head (p *\<^sub>p q) = head p *\<^sub>p head q"
  1483 proof (induct p q arbitrary: n0 n1 rule: polymul.induct)
  1469 proof (induct p q arbitrary: n0 n1 rule: polymul.induct)
  1501   then show ?case
  1487   then show ?case
  1502   proof cases
  1488   proof cases
  1503     case nn': 1
  1489     case nn': 1
  1504     then show ?thesis
  1490     then show ?thesis
  1505       using norm "4.hyps"(2)[OF norm(1,6)] "4.hyps"(1)[OF norm(2,6)]
  1491       using norm "4.hyps"(2)[OF norm(1,6)] "4.hyps"(1)[OF norm(2,6)]
  1506       apply simp
  1492       by (simp add: head_eq_headn0)
  1507       apply (cases n)
       
  1508        apply simp
       
  1509       apply (cases n')
       
  1510        apply simp_all
       
  1511       done
       
  1512   next
  1493   next
  1513     case nn': 2
  1494     case nn': 2
  1514     then show ?thesis
  1495     then show ?thesis
  1515       using norm "4.hyps"(6) [OF norm(5,3)] "4.hyps"(5)[OF norm(5,4)]
  1496       using norm "4.hyps"(6) [OF norm(5,3)] "4.hyps"(5)[OF norm(5,4)]
  1516       apply simp
  1497       by (simp add: head_eq_headn0)
  1517       apply (cases n')
       
  1518        apply simp
       
  1519       apply (cases n)
       
  1520        apply auto
       
  1521       done
       
  1522   next
  1498   next
  1523     case nn': 3
  1499     case nn': 3
  1524     from nn' polymul_normh[OF norm(5,4)]
  1500     from nn' polymul_normh[OF norm(5,4)]
  1525     have ncnpc': "isnpolyh (CN c n p *\<^sub>p c') n" by (simp add: min_def)
  1501     have ncnpc': "isnpolyh (CN c n p *\<^sub>p c') n" by (simp add: min_def)
  1526     from nn' polymul_normh[OF norm(5,3)] norm
  1502     from nn' polymul_normh[OF norm(5,3)] norm
  1624   show ?ths
  1600   show ?ths
  1625   proof (cases "s = 0\<^sub>p")
  1601   proof (cases "s = 0\<^sub>p")
  1626     case True
  1602     case True
  1627     with np show ?thesis
  1603     with np show ?thesis
  1628       apply (clarsimp simp: polydivide_aux.simps)
  1604       apply (clarsimp simp: polydivide_aux.simps)
  1629       apply (rule exI[where x="0\<^sub>p"])
  1605       by (metis polyadd_0(1) polymul_0(1) zero_normh)
  1630       apply simp
       
  1631       done
       
  1632   next
  1606   next
  1633     case sz: False
  1607     case sz: False
  1634     show ?thesis
  1608     show ?thesis
  1635     proof (cases "degree s < n")
  1609     proof (cases "degree s < n")
  1636       case True
  1610       case True
  1637       then show ?thesis
  1611       then show ?thesis
  1638         using ns ndp np polydivide_aux.simps
  1612         using ns ndp np polydivide_aux.simps
  1639         apply auto
  1613         apply clarsimp
  1640         apply (rule exI[where x="0\<^sub>p"])
  1614         by (metis polyadd_0(2) polymul_0(1) polymul_1(2) zero_normh)
  1641         apply simp
       
  1642         done
       
  1643     next
  1615     next
  1644       case dn': False
  1616       case dn': False
  1645       then have dn: "degree s \<ge> n"
  1617       then have dn: "degree s \<ge> n"
  1646         by arith
  1618         by arith
  1647       have degsp': "degree s = degree ?p'"
  1619       have degsp': "degree s = degree ?p'"
  1894     polydivide_aux_properties[OF np ns trv pnz, where k="0" and k'="k" and r="r"]
  1866     polydivide_aux_properties[OF np ns trv pnz, where k="0" and k'="k" and r="r"]
  1895   have "(degree r = 0 \<or> degree r < degree p) \<and>
  1867   have "(degree r = 0 \<or> degree r < degree p) \<and>
  1896     (\<exists>nr. isnpolyh r nr) \<and> (\<exists>q n1. isnpolyh q n1 \<and> head p ^\<^sub>p k - 0 *\<^sub>p s = p *\<^sub>p q +\<^sub>p r)"
  1868     (\<exists>nr. isnpolyh r nr) \<and> (\<exists>q n1. isnpolyh q n1 \<and> head p ^\<^sub>p k - 0 *\<^sub>p s = p *\<^sub>p q +\<^sub>p r)"
  1897     by blast
  1869     by blast
  1898   with kr show ?thesis
  1870   with kr show ?thesis
  1899     apply -
  1871     by auto
  1900     apply (rule exI[where x="k"])
       
  1901     apply (rule exI[where x="r"])
       
  1902     apply simp
       
  1903     done
       
  1904 qed
  1872 qed
  1905 
  1873 
  1906 
  1874 
  1907 subsection \<open>More about polypoly and pnormal etc\<close>
  1875 subsection \<open>More about polypoly and pnormal etc\<close>
  1908 
  1876 
  1934   from pnormal_last_length[OF lg lz] show "pnormal ?p" .
  1902   from pnormal_last_length[OF lg lz] show "pnormal ?p" .
  1935 qed
  1903 qed
  1936 
  1904 
  1937 lemma isnonconstant_coefficients_length: "isnonconstant p \<Longrightarrow> length (coefficients p) > 1"
  1905 lemma isnonconstant_coefficients_length: "isnonconstant p \<Longrightarrow> length (coefficients p) > 1"
  1938   unfolding isnonconstant_def
  1906   unfolding isnonconstant_def
  1939   apply (cases p)
  1907   using isconstant.elims(3) by fastforce
  1940   apply simp_all
       
  1941   apply (rename_tac nat a, case_tac nat)
       
  1942   apply auto
       
  1943   done
       
  1944 
  1908 
  1945 lemma isnonconstant_nonconstant:
  1909 lemma isnonconstant_nonconstant:
  1946   assumes "isnonconstant p"
  1910   assumes "isnonconstant p"
  1947   shows "nonconstant (polypoly bs p) \<longleftrightarrow> Ipoly bs (head p) \<noteq> 0"
  1911   shows "nonconstant (polypoly bs p) \<longleftrightarrow> Ipoly bs (head p) \<noteq> 0"
  1948 proof
  1912 proof
  1965   then show "nonconstant ?p"
  1929   then show "nonconstant ?p"
  1966     using pn unfolding nonconstant_def by blast
  1930     using pn unfolding nonconstant_def by blast
  1967 qed
  1931 qed
  1968 
  1932 
  1969 lemma pnormal_length: "p \<noteq> [] \<Longrightarrow> pnormal p \<longleftrightarrow> length (pnormalize p) = length p"
  1933 lemma pnormal_length: "p \<noteq> [] \<Longrightarrow> pnormal p \<longleftrightarrow> length (pnormalize p) = length p"
  1970   apply (induct p)
  1934   by (induct p) (auto simp: pnormal_id)
  1971    apply (simp_all add: pnormal_def)
       
  1972   apply (case_tac "p = []")
       
  1973    apply simp_all
       
  1974   done
       
  1975 
  1935 
  1976 lemma degree_degree:
  1936 lemma degree_degree:
  1977   assumes "isnonconstant p"
  1937   assumes "isnonconstant p"
  1978   shows "degree p = Polynomial_List.degree (polypoly bs p) \<longleftrightarrow> \<lparr>head p\<rparr>\<^sub>p\<^bsup>bs\<^esup> \<noteq> 0"
  1938   shows "degree p = Polynomial_List.degree (polypoly bs p) \<longleftrightarrow> \<lparr>head p\<rparr>\<^sub>p\<^bsup>bs\<^esup> \<noteq> 0"
  1979     (is "?lhs \<longleftrightarrow> ?rhs")
  1939     (is "?lhs \<longleftrightarrow> ?rhs")