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") |