src/HOL/GCD.thy
changeset 62353 7f927120b5a2
parent 62350 66a381d3f88f
child 62429 25271ff79171
equal deleted inserted replaced
62352:35a9e1cbb5b3 62353:7f927120b5a2
   583   case False with assms show ?thesis
   583   case False with assms show ?thesis
   584     by (induct A rule: finite_ne_induct)
   584     by (induct A rule: finite_ne_induct)
   585       (auto simp add: lcm_eq_0_iff)
   585       (auto simp add: lcm_eq_0_iff)
   586 qed
   586 qed
   587 
   587 
   588 lemma dvd_Gcd: \<comment> \<open>FIXME remove\<close>
       
   589   "\<forall>b\<in>A. a dvd b \<Longrightarrow> a dvd Gcd A"
       
   590   by (blast intro: Gcd_greatest)
       
   591 
       
   592 lemma Gcd_set [code_unfold]:
   588 lemma Gcd_set [code_unfold]:
   593   "Gcd (set as) = foldr gcd as 0"
   589   "Gcd (set as) = foldr gcd as 0"
   594   by (induct as) simp_all
   590   by (induct as) simp_all
   595 
   591 
   596 lemma Lcm_set [code_unfold]:
   592 lemma Lcm_set [code_unfold]:
   713   by (simp add: gcd_int_def)
   709   by (simp add: gcd_int_def)
   714 
   710 
   715 lemma gcd_neg2_int [simp]: "gcd (x::int) (-y) = gcd x y"
   711 lemma gcd_neg2_int [simp]: "gcd (x::int) (-y) = gcd x y"
   716   by (simp add: gcd_int_def)
   712   by (simp add: gcd_int_def)
   717 
   713 
   718 lemma abs_gcd_int[simp]: "\<bar>gcd (x::int) y\<bar> = gcd x y"
   714 lemma abs_gcd_int [simp]: "\<bar>gcd (x::int) y\<bar> = gcd x y"
   719 by(simp add: gcd_int_def)
   715 by(simp add: gcd_int_def)
   720 
   716 
   721 lemma gcd_abs_int: "gcd (x::int) y = gcd \<bar>x\<bar> \<bar>y\<bar>"
   717 lemma gcd_abs_int: "gcd (x::int) y = gcd \<bar>x\<bar> \<bar>y\<bar>"
   722 by (simp add: gcd_int_def)
   718 by (simp add: gcd_int_def)
   723 
   719 
   724 lemma gcd_abs1_int[simp]: "gcd \<bar>x\<bar> (y::int) = gcd x y"
   720 lemma gcd_abs1_int [simp]: "gcd \<bar>x\<bar> (y::int) = gcd x y"
   725 by (metis abs_idempotent gcd_abs_int)
   721 by (metis abs_idempotent gcd_abs_int)
   726 
   722 
   727 lemma gcd_abs2_int[simp]: "gcd x \<bar>y::int\<bar> = gcd x y"
   723 lemma gcd_abs2_int [simp]: "gcd x \<bar>y::int\<bar> = gcd x y"
   728 by (metis abs_idempotent gcd_abs_int)
   724 by (metis abs_idempotent gcd_abs_int)
   729 
   725 
   730 lemma gcd_cases_int:
   726 lemma gcd_cases_int:
   731   fixes x :: int and y
   727   fixes x :: int and y
   732   assumes "x >= 0 \<Longrightarrow> y >= 0 \<Longrightarrow> P (gcd x y)"
   728   assumes "x >= 0 \<Longrightarrow> y >= 0 \<Longrightarrow> P (gcd x y)"
   749   by (simp add: lcm_int_def)
   745   by (simp add: lcm_int_def)
   750 
   746 
   751 lemma abs_lcm_int [simp]: "\<bar>lcm i j::int\<bar> = lcm i j"
   747 lemma abs_lcm_int [simp]: "\<bar>lcm i j::int\<bar> = lcm i j"
   752   by (simp add:lcm_int_def)
   748   by (simp add:lcm_int_def)
   753 
   749 
   754 lemma lcm_abs1_int[simp]: "lcm \<bar>x\<bar> (y::int) = lcm x y"
   750 lemma lcm_abs1_int [simp]: "lcm \<bar>x\<bar> (y::int) = lcm x y"
   755   by (metis abs_idempotent lcm_int_def)
   751   by (metis abs_idempotent lcm_int_def)
   756 
   752 
   757 lemma lcm_abs2_int[simp]: "lcm x \<bar>y::int\<bar> = lcm x y"
   753 lemma lcm_abs2_int [simp]: "lcm x \<bar>y::int\<bar> = lcm x y"
   758   by (metis abs_idempotent lcm_int_def)
   754   by (metis abs_idempotent lcm_int_def)
   759 
   755 
   760 lemma lcm_cases_int:
   756 lemma lcm_cases_int:
   761   fixes x :: int and y
   757   fixes x :: int and y
   762   assumes "x >= 0 \<Longrightarrow> y >= 0 \<Longrightarrow> P (lcm x y)"
   758   assumes "x >= 0 \<Longrightarrow> y >= 0 \<Longrightarrow> P (lcm x y)"
  1045 lemma gcd_dvd_prod_nat: "gcd (m::nat) n dvd k * n"
  1041 lemma gcd_dvd_prod_nat: "gcd (m::nat) n dvd k * n"
  1046   using mult_dvd_mono [of 1] by auto
  1042   using mult_dvd_mono [of 1] by auto
  1047 
  1043 
  1048 (* to do: add the three variations of these, and for ints? *)
  1044 (* to do: add the three variations of these, and for ints? *)
  1049 
  1045 
  1050 lemma finite_divisors_nat[simp]:
  1046 lemma finite_divisors_nat [simp]: -- \<open>FIXME move\<close>
  1051   assumes "(m::nat) ~= 0" shows "finite{d. d dvd m}"
  1047   fixes m :: nat
       
  1048   assumes "m > 0" 
       
  1049   shows "finite {d. d dvd m}"
  1052 proof-
  1050 proof-
  1053   have "finite{d. d <= m}"
  1051   from assms have "{d. d dvd m} \<subseteq> {d. d \<le> m}"
  1054     by (blast intro: bounded_nat_set_is_finite)
  1052     by (auto dest: dvd_imp_le)
  1055   from finite_subset[OF _ this] show ?thesis using assms
  1053   then show ?thesis
  1056     by (metis Collect_mono dvd_imp_le neq0_conv)
  1054     using finite_Collect_le_nat by (rule finite_subset)
  1057 qed
  1055 qed
  1058 
  1056 
  1059 lemma finite_divisors_int[simp]:
  1057 lemma finite_divisors_int [simp]:
  1060   assumes "(i::int) ~= 0" shows "finite{d. d dvd i}"
  1058   fixes i :: int
  1061 proof-
  1059   assumes "i \<noteq> 0"
  1062   have "{d. \<bar>d\<bar> <= \<bar>i\<bar>} = {- \<bar>i\<bar> .. \<bar>i\<bar>}" by(auto simp:abs_if)
  1060   shows "finite {d. d dvd i}"
  1063   hence "finite {d. \<bar>d\<bar> <= \<bar>i\<bar>}" by simp
  1061 proof -
  1064   from finite_subset[OF _ this] show ?thesis using assms
  1062   have "{d. \<bar>d\<bar> \<le> \<bar>i\<bar>} = {- \<bar>i\<bar>..\<bar>i\<bar>}"
       
  1063     by (auto simp: abs_if)
       
  1064   then have "finite {d. \<bar>d\<bar> <= \<bar>i\<bar>}"
       
  1065     by simp
       
  1066   from finite_subset [OF _ this] show ?thesis using assms
  1065     by (simp add: dvd_imp_le_int subset_iff)
  1067     by (simp add: dvd_imp_le_int subset_iff)
  1066 qed
  1068 qed
  1067 
  1069 
  1068 lemma Max_divisors_self_nat[simp]: "n\<noteq>0 \<Longrightarrow> Max{d::nat. d dvd n} = n"
  1070 lemma Max_divisors_self_nat [simp]: "n\<noteq>0 \<Longrightarrow> Max{d::nat. d dvd n} = n"
  1069 apply(rule antisym)
  1071 apply(rule antisym)
  1070  apply (fastforce intro: Max_le_iff[THEN iffD2] simp: dvd_imp_le)
  1072  apply (fastforce intro: Max_le_iff[THEN iffD2] simp: dvd_imp_le)
  1071 apply simp
  1073 apply simp
  1072 done
  1074 done
  1073 
  1075 
  1074 lemma Max_divisors_self_int[simp]: "n\<noteq>0 \<Longrightarrow> Max{d::int. d dvd n} = \<bar>n\<bar>"
  1076 lemma Max_divisors_self_int [simp]: "n\<noteq>0 \<Longrightarrow> Max{d::int. d dvd n} = \<bar>n\<bar>"
  1075 apply(rule antisym)
  1077 apply(rule antisym)
  1076  apply(rule Max_le_iff [THEN iffD2])
  1078  apply(rule Max_le_iff [THEN iffD2])
  1077   apply (auto intro: abs_le_D1 dvd_imp_le_int)
  1079   apply (auto intro: abs_le_D1 dvd_imp_le_int)
  1078 done
  1080 done
  1079 
  1081 
  1080 lemma gcd_is_Max_divisors_nat:
  1082 lemma gcd_is_Max_divisors_nat:
  1081   "m ~= 0 \<Longrightarrow> n ~= 0 \<Longrightarrow> gcd (m::nat) n = (Max {d. d dvd m & d dvd n})"
  1083   "m > 0 \<Longrightarrow> n > 0 \<Longrightarrow> gcd (m::nat) n = Max {d. d dvd m \<and> d dvd n}"
  1082 apply(rule Max_eqI[THEN sym])
  1084 apply(rule Max_eqI[THEN sym])
  1083   apply (metis finite_Collect_conjI finite_divisors_nat)
  1085   apply (metis finite_Collect_conjI finite_divisors_nat)
  1084  apply simp
  1086  apply simp
  1085  apply(metis Suc_diff_1 Suc_neq_Zero dvd_imp_le gcd_greatest_iff gcd_pos_nat)
  1087  apply(metis Suc_diff_1 Suc_neq_Zero dvd_imp_le gcd_greatest_iff gcd_pos_nat)
  1086 apply simp
  1088 apply simp
  1436     hence "a'*?g dvd b'*?g" by simp
  1438     hence "a'*?g dvd b'*?g" by simp
  1437     with ab'(1,2)  have ?thesis by simp }
  1439     with ab'(1,2)  have ?thesis by simp }
  1438   ultimately show ?thesis by blast
  1440   ultimately show ?thesis by blast
  1439 qed
  1441 qed
  1440 
  1442 
  1441 lemma pow_divides_eq_nat [simp]: "n ~= 0 \<Longrightarrow> ((a::nat)^n dvd b^n) = (a dvd b)"
  1443 lemma pow_divides_eq_nat [simp]:
       
  1444   "n > 0 \<Longrightarrow> (a::nat) ^ n dvd b ^ n \<longleftrightarrow> a dvd b"
  1442   by (auto intro: pow_divides_pow_nat dvd_power_same)
  1445   by (auto intro: pow_divides_pow_nat dvd_power_same)
  1443 
  1446 
  1444 lemma pow_divides_eq_int [simp]: "n ~= 0 \<Longrightarrow> ((a::int)^n dvd b^n) = (a dvd b)"
  1447 lemma pow_divides_eq_int [simp]:
       
  1448   "n ~= 0 \<Longrightarrow> (a::int) ^ n dvd b ^ n \<longleftrightarrow> a dvd b"
  1445   by (auto intro: pow_divides_pow_int dvd_power_same)
  1449   by (auto intro: pow_divides_pow_int dvd_power_same)
  1446 
  1450 
  1447 lemma divides_mult_nat:
  1451 context semiring_gcd
  1448   assumes mr: "(m::nat) dvd r" and nr: "n dvd r" and mn:"coprime m n"
  1452 begin
  1449   shows "m * n dvd r"
  1453 
       
  1454 lemma divides_mult:
       
  1455   assumes "a dvd c" and nr: "b dvd c" and "coprime a b"
       
  1456   shows "a * b dvd c"
  1450 proof-
  1457 proof-
  1451   from mr nr obtain m' n' where m': "r = m*m'" and n': "r = n*n'"
  1458   from \<open>b dvd c\<close> obtain b' where"c = b * b'" ..
  1452     unfolding dvd_def by blast
  1459   with \<open>a dvd c\<close> have "a dvd b' * b"
  1453   from mr n' have "m dvd n'*n" by (simp add: mult.commute)
  1460     by (simp add: ac_simps)
  1454   hence "m dvd n'" using coprime_dvd_mult_iff [OF mn] by simp
  1461   with \<open>coprime a b\<close> have "a dvd b'"
  1455   then obtain k where k: "n' = m*k" unfolding dvd_def by blast
  1462     by (simp add: coprime_dvd_mult_iff)
  1456   from n' k show ?thesis unfolding dvd_def by auto
  1463   then obtain a' where "b' = a * a'" ..
  1457 qed
  1464   with \<open>c = b * b'\<close> have "c = (a * b) * a'"
  1458 
  1465     by (simp add: ac_simps)
  1459 lemma divides_mult_int:
  1466   then show ?thesis ..
  1460   assumes mr: "(m::int) dvd r" and nr: "n dvd r" and mn:"coprime m n"
  1467 qed
  1461   shows "m * n dvd r"
  1468 
  1462 proof-
  1469 end
  1463   from mr nr obtain m' n' where m': "r = m*m'" and n': "r = n*n'"
       
  1464     unfolding dvd_def by blast
       
  1465   from mr n' have "m dvd n'*n" by (simp add: mult.commute)
       
  1466   hence "m dvd n'" using coprime_dvd_mult_iff [OF mn] by simp
       
  1467   then obtain k where k: "n' = m*k" unfolding dvd_def by blast
       
  1468   from n' k show ?thesis unfolding dvd_def by auto
       
  1469 qed
       
  1470 
  1470 
  1471 lemma coprime_plus_one_nat [simp]: "coprime ((n::nat) + 1) n"
  1471 lemma coprime_plus_one_nat [simp]: "coprime ((n::nat) + 1) n"
  1472   by (simp add: gcd.commute del: One_nat_def)
  1472   by (simp add: gcd.commute del: One_nat_def)
  1473 
  1473 
  1474 lemma coprime_Suc_nat [simp]: "coprime (Suc n) n"
  1474 lemma coprime_Suc_nat [simp]: "coprime (Suc n) n"
  1771   apply (subst prod_gcd_lcm_nat [symmetric])
  1771   apply (subst prod_gcd_lcm_nat [symmetric])
  1772   apply (subst nat_abs_mult_distrib [symmetric])
  1772   apply (subst nat_abs_mult_distrib [symmetric])
  1773   apply (simp, simp add: abs_mult)
  1773   apply (simp, simp add: abs_mult)
  1774 done
  1774 done
  1775 
  1775 
  1776 lemma lcm_0_nat [simp]: "lcm (m::nat) 0 = 0"
       
  1777   unfolding lcm_nat_def by simp
       
  1778 
       
  1779 lemma lcm_0_int [simp]: "lcm (m::int) 0 = 0"
       
  1780   unfolding lcm_int_def by simp
       
  1781 
       
  1782 lemma lcm_0_left_nat [simp]: "lcm (0::nat) n = 0"
       
  1783   unfolding lcm_nat_def by simp
       
  1784 
       
  1785 lemma lcm_0_left_int [simp]: "lcm (0::int) n = 0"
       
  1786   unfolding lcm_int_def by simp
       
  1787 
       
  1788 lemma lcm_pos_nat:
  1776 lemma lcm_pos_nat:
  1789   "(m::nat) > 0 \<Longrightarrow> n>0 \<Longrightarrow> lcm m n > 0"
  1777   "(m::nat) > 0 \<Longrightarrow> n>0 \<Longrightarrow> lcm m n > 0"
  1790 by (metis gr0I mult_is_0 prod_gcd_lcm_nat)
  1778 by (metis gr0I mult_is_0 prod_gcd_lcm_nat)
  1791 
  1779 
  1792 lemma lcm_pos_int:
  1780 lemma lcm_pos_int:
  1794   apply (subst lcm_abs_int)
  1782   apply (subst lcm_abs_int)
  1795   apply (rule lcm_pos_nat [transferred])
  1783   apply (rule lcm_pos_nat [transferred])
  1796   apply auto
  1784   apply auto
  1797   done
  1785   done
  1798 
  1786 
  1799 lemma dvd_pos_nat:
  1787 lemma dvd_pos_nat: -- \<open>FIXME move\<close>
  1800   fixes n m :: nat
  1788   fixes n m :: nat
  1801   assumes "n > 0" and "m dvd n"
  1789   assumes "n > 0" and "m dvd n"
  1802   shows "m > 0"
  1790   shows "m > 0"
  1803   using assms by (cases m) auto
  1791   using assms by (cases m) auto
  1804 
  1792 
  1826 by (subst lcm.commute, erule lcm_proj2_if_dvd_nat)
  1814 by (subst lcm.commute, erule lcm_proj2_if_dvd_nat)
  1827 
  1815 
  1828 lemma lcm_proj1_if_dvd_int [simp]: "(x::int) dvd y \<Longrightarrow> lcm y x = \<bar>y\<bar>"
  1816 lemma lcm_proj1_if_dvd_int [simp]: "(x::int) dvd y \<Longrightarrow> lcm y x = \<bar>y\<bar>"
  1829 by (subst lcm.commute, erule lcm_proj2_if_dvd_int)
  1817 by (subst lcm.commute, erule lcm_proj2_if_dvd_int)
  1830 
  1818 
  1831 lemma lcm_proj1_iff_nat[simp]: "lcm m n = (m::nat) \<longleftrightarrow> n dvd m"
  1819 lemma lcm_proj1_iff_nat [simp]: "lcm m n = (m::nat) \<longleftrightarrow> n dvd m"
  1832 by (metis lcm_proj1_if_dvd_nat lcm_unique_nat)
  1820 by (metis lcm_proj1_if_dvd_nat lcm_unique_nat)
  1833 
  1821 
  1834 lemma lcm_proj2_iff_nat[simp]: "lcm m n = (n::nat) \<longleftrightarrow> m dvd n"
  1822 lemma lcm_proj2_iff_nat [simp]: "lcm m n = (n::nat) \<longleftrightarrow> m dvd n"
  1835 by (metis lcm_proj2_if_dvd_nat lcm_unique_nat)
  1823 by (metis lcm_proj2_if_dvd_nat lcm_unique_nat)
  1836 
  1824 
  1837 lemma lcm_proj1_iff_int[simp]: "lcm m n = \<bar>m::int\<bar> \<longleftrightarrow> n dvd m"
  1825 lemma lcm_proj1_iff_int [simp]: "lcm m n = \<bar>m::int\<bar> \<longleftrightarrow> n dvd m"
  1838 by (metis dvd_abs_iff lcm_proj1_if_dvd_int lcm_unique_int)
  1826 by (metis dvd_abs_iff lcm_proj1_if_dvd_int lcm_unique_int)
  1839 
  1827 
  1840 lemma lcm_proj2_iff_int[simp]: "lcm m n = \<bar>n::int\<bar> \<longleftrightarrow> m dvd n"
  1828 lemma lcm_proj2_iff_int [simp]: "lcm m n = \<bar>n::int\<bar> \<longleftrightarrow> m dvd n"
  1841 by (metis dvd_abs_iff lcm_proj2_if_dvd_int lcm_unique_int)
  1829 by (metis dvd_abs_iff lcm_proj2_if_dvd_int lcm_unique_int)
  1842 
  1830 
  1843 lemma (in semiring_gcd) comp_fun_idem_gcd:
  1831 lemma (in semiring_gcd) comp_fun_idem_gcd:
  1844   "comp_fun_idem gcd"
  1832   "comp_fun_idem gcd"
  1845   by standard (simp_all add: fun_eq_iff ac_simps)
  1833   by standard (simp_all add: fun_eq_iff ac_simps)
  1846 
  1834 
  1847 lemma (in semiring_gcd) comp_fun_idem_lcm:
  1835 lemma (in semiring_gcd) comp_fun_idem_lcm:
  1848   "comp_fun_idem lcm"
  1836   "comp_fun_idem lcm"
  1849   by standard (simp_all add: fun_eq_iff ac_simps)
  1837   by standard (simp_all add: fun_eq_iff ac_simps)
  1850 
  1838 
  1851 lemma lcm_1_iff_nat [simp]: "lcm (m::nat) n = 1 \<longleftrightarrow> m=1 \<and> n=1"
  1839 lemma lcm_1_iff_nat [simp]:
  1852   by (simp only: lcm_eq_1_iff) simp
  1840   "lcm (m::nat) n = Suc 0 \<longleftrightarrow> m = Suc 0 \<and> n = Suc 0"
       
  1841   using lcm_eq_1_iff [of m n] by simp
  1853   
  1842   
  1854 lemma lcm_1_iff_int [simp]: "lcm (m::int) n = 1 \<longleftrightarrow> (m=1 \<or> m = -1) \<and> (n=1 \<or> n = -1)"
  1843 lemma lcm_1_iff_int [simp]:
       
  1844   "lcm (m::int) n = 1 \<longleftrightarrow> (m=1 \<or> m = -1) \<and> (n=1 \<or> n = -1)"
  1855   by auto
  1845   by auto
  1856 
  1846 
  1857 
  1847 
  1858 subsection \<open>The complete divisibility lattice on @{typ nat} and @{typ int}\<close>
  1848 subsection \<open>The complete divisibility lattice on @{typ nat} and @{typ int}\<close>
  1859 
  1849 
  1895 
  1885 
  1896 lemma Lcm_dvd_nat [simp]:
  1886 lemma Lcm_dvd_nat [simp]:
  1897   fixes M :: "nat set"
  1887   fixes M :: "nat set"
  1898   assumes "\<forall>m\<in>M. m dvd n"
  1888   assumes "\<forall>m\<in>M. m dvd n"
  1899   shows "Lcm M dvd n"
  1889   shows "Lcm M dvd n"
  1900 proof (cases "n = 0")
  1890 proof (cases "n > 0")
  1901   case True then show ?thesis by simp
  1891   case False then show ?thesis by simp
  1902 next
  1892 next
  1903   case False
  1893   case True
  1904   then have "finite {d. d dvd n}" by (rule finite_divisors_nat)
  1894   then have "finite {d. d dvd n}" by (rule finite_divisors_nat)
  1905   moreover have "M \<subseteq> {d. d dvd n}" using assms by fast
  1895   moreover have "M \<subseteq> {d. d dvd n}" using assms by fast
  1906   ultimately have "finite M" by (rule rev_finite_subset)
  1896   ultimately have "finite M" by (rule rev_finite_subset)
  1907   then show ?thesis using assms by (induct M) (simp_all add: Lcm_nat_empty Lcm_nat_insert)
  1897   then show ?thesis using assms
       
  1898     by (induct M) (simp_all add: Lcm_nat_empty Lcm_nat_insert)
  1908 qed
  1899 qed
  1909 
  1900 
  1910 definition
  1901 definition
  1911   "Gcd (M::nat set) = Lcm {d. \<forall>m\<in>M. d dvd m}"
  1902   "Gcd (M::nat set) = Lcm {d. \<forall>m\<in>M. d dvd m}"
  1912 
  1903 
  1931   "1 \<in> N \<Longrightarrow> Gcd N = (1::nat)"
  1922   "1 \<in> N \<Longrightarrow> Gcd N = (1::nat)"
  1932   by (rule Gcd_eq_1_I) auto
  1923   by (rule Gcd_eq_1_I) auto
  1933 
  1924 
  1934 text\<open>Alternative characterizations of Gcd:\<close>
  1925 text\<open>Alternative characterizations of Gcd:\<close>
  1935 
  1926 
  1936 lemma Gcd_eq_Max: "finite(M::nat set) \<Longrightarrow> M \<noteq> {} \<Longrightarrow> 0 \<notin> M \<Longrightarrow> Gcd M = Max(\<Inter>m\<in>M. {d. d dvd m})"
  1927 lemma Gcd_eq_Max:
  1937 apply(rule antisym)
  1928   fixes M :: "nat set"
  1938  apply(rule Max_ge)
  1929   assumes "finite (M::nat set)" and "M \<noteq> {}" and "0 \<notin> M"
  1939   apply (metis all_not_in_conv finite_divisors_nat finite_INT)
  1930   shows "Gcd M = Max (\<Inter>m\<in>M. {d. d dvd m})"
  1940  apply (simp add: Gcd_dvd)
  1931 proof (rule antisym)
  1941 apply (rule Max_le_iff[THEN iffD2])
  1932   from assms obtain m where "m \<in> M" and "m > 0"
  1942   apply (metis all_not_in_conv finite_divisors_nat finite_INT)
  1933     by auto
  1943  apply fastforce
  1934   from \<open>m > 0\<close> have "finite {d. d dvd m}"
  1944 apply clarsimp
  1935     by (blast intro: finite_divisors_nat)
  1945 apply (metis Gcd_dvd Max_in dvd_0_left dvd_Gcd dvd_imp_le linorder_antisym_conv3 not_less0)
  1936   with \<open>m \<in> M\<close> have fin: "finite (\<Inter>m\<in>M. {d. d dvd m})"
  1946 done
  1937     by blast
       
  1938   from fin show "Gcd M \<le> Max (\<Inter>m\<in>M. {d. d dvd m})"
       
  1939     by (auto intro: Max_ge Gcd_dvd)
       
  1940   from fin show "Max (\<Inter>m\<in>M. {d. d dvd m}) \<le> Gcd M"
       
  1941     apply (rule Max.boundedI)
       
  1942     apply auto
       
  1943     apply (meson Gcd_dvd Gcd_greatest \<open>0 < m\<close> \<open>m \<in> M\<close> dvd_imp_le dvd_pos_nat)
       
  1944     done
       
  1945 qed
  1947 
  1946 
  1948 lemma Gcd_remove0_nat: "finite M \<Longrightarrow> Gcd M = Gcd (M - {0::nat})"
  1947 lemma Gcd_remove0_nat: "finite M \<Longrightarrow> Gcd M = Gcd (M - {0::nat})"
  1949 apply(induct pred:finite)
  1948 apply(induct pred:finite)
  1950  apply simp
  1949  apply simp
  1951 apply(case_tac "x=0")
  1950 apply(case_tac "x=0")
  2086   "Gcd (set xs) = fold gcd xs (0::int)"
  2085   "Gcd (set xs) = fold gcd xs (0::int)"
  2087   using Gcd_set [of xs] by (simp_all add: fun_eq_iff ac_simps foldr_fold [symmetric])
  2086   using Gcd_set [of xs] by (simp_all add: fun_eq_iff ac_simps foldr_fold [symmetric])
  2088 
  2087 
  2089 text \<open>Fact aliasses\<close>
  2088 text \<open>Fact aliasses\<close>
  2090 
  2089 
  2091 lemma lcm_0_iff_nat [simp]: "lcm (m::nat) n = 0 \<longleftrightarrow> m = 0 \<or> n= 0"
  2090 lemma lcm_0_iff_nat [simp]: "lcm (m::nat) n = 0 \<longleftrightarrow> m = 0 \<or> n = 0"
  2092   by (fact lcm_eq_0_iff)
  2091   by (fact lcm_eq_0_iff)
  2093 
  2092 
  2094 lemma lcm_0_iff_int [simp]: "lcm (m::int) n = 0 \<longleftrightarrow> m = 0 \<or> n = 0"
  2093 lemma lcm_0_iff_int [simp]: "lcm (m::int) n = 0 \<longleftrightarrow> m = 0 \<or> n = 0"
  2095   by (fact lcm_eq_0_iff)
  2094   by (fact lcm_eq_0_iff)
  2096 
  2095 
  2101   by (fact dvd_lcmI2)
  2100   by (fact dvd_lcmI2)
  2102 
  2101 
  2103 lemma dvd_lcm_I1_int [simp]: "(i::int) dvd m \<Longrightarrow> i dvd lcm m n"
  2102 lemma dvd_lcm_I1_int [simp]: "(i::int) dvd m \<Longrightarrow> i dvd lcm m n"
  2104   by (fact dvd_lcmI1)
  2103   by (fact dvd_lcmI1)
  2105 
  2104 
  2106 lemma dvd_lcm_I2_int[simp]: "(i::int) dvd n \<Longrightarrow> i dvd lcm m n"
  2105 lemma dvd_lcm_I2_int [simp]: "(i::int) dvd n \<Longrightarrow> i dvd lcm m n"
  2107   by (fact dvd_lcmI2)
  2106   by (fact dvd_lcmI2)
  2108 
       
  2109 lemma coprime_dvd_mult_iff_nat: "coprime (k::nat) n \<Longrightarrow>
       
  2110     (k dvd m * n) = (k dvd m)"
       
  2111   by (fact coprime_dvd_mult_iff)
       
  2112 
       
  2113 lemma coprime_dvd_mult_iff_int: "coprime (k::int) n \<Longrightarrow>
       
  2114     (k dvd m * n) = (k dvd m)"
       
  2115   by (fact coprime_dvd_mult_iff)
       
  2116 
  2107 
  2117 lemma coprime_exp2_nat [intro]: "coprime (a::nat) b \<Longrightarrow> coprime (a^n) (b^m)"
  2108 lemma coprime_exp2_nat [intro]: "coprime (a::nat) b \<Longrightarrow> coprime (a^n) (b^m)"
  2118   by (fact coprime_exp2)
  2109   by (fact coprime_exp2)
  2119 
  2110 
  2120 lemma coprime_exp2_int [intro]: "coprime (a::int) b \<Longrightarrow> coprime (a^n) (b^m)"
  2111 lemma coprime_exp2_int [intro]: "coprime (a::int) b \<Longrightarrow> coprime (a^n) (b^m)"
  2121   by (fact coprime_exp2)
  2112   by (fact coprime_exp2)
  2122 
  2113 
  2123 lemmas Gcd_dvd_nat [simp] = Gcd_dvd [where ?'a = nat]
  2114 lemmas Gcd_dvd_nat [simp] = Gcd_dvd [where ?'a = nat]
  2124 lemmas Gcd_dvd_int [simp] = Gcd_dvd [where ?'a = int]
  2115 lemmas Gcd_dvd_int [simp] = Gcd_dvd [where ?'a = int]
  2125 lemmas dvd_Gcd_nat [simp] = dvd_Gcd [where ?'a = nat]
  2116 lemmas Gcd_greatest_nat [simp] = Gcd_greatest [where ?'a = nat]
  2126 lemmas dvd_Gcd_int [simp] = dvd_Gcd [where ?'a = int]
  2117 lemmas Gcd_greatest_int [simp] = Gcd_greatest [where ?'a = int]
  2127 
  2118 
  2128 lemma dvd_Lcm_int [simp]:
  2119 lemma dvd_Lcm_int [simp]:
  2129   fixes M :: "int set" assumes "m \<in> M" shows "m dvd Lcm M"
  2120   fixes M :: "int set" assumes "m \<in> M" shows "m dvd Lcm M"
  2130   using assms by (fact dvd_Lcm)
  2121   using assms by (fact dvd_Lcm)
  2131 
  2122 
  2132 lemma Lcm_empty_nat:
       
  2133   "Lcm {} = (1::nat)"
       
  2134   by (fact Lcm_empty)
       
  2135 
       
  2136 lemma Lcm_empty_int:
       
  2137   "Lcm {} = (1::int)"
       
  2138   by (fact Lcm_empty)
       
  2139 
       
  2140 lemma Lcm_insert_nat:
       
  2141   "Lcm (insert (n::nat) N) = lcm n (Lcm N)"
       
  2142   by (fact Lcm_insert)
       
  2143 
       
  2144 lemma Lcm_insert_int:
       
  2145   "Lcm (insert (n::int) N) = lcm n (Lcm N)"
       
  2146   by (fact Lcm_insert)
       
  2147 
       
  2148 lemma gcd_neg_numeral_1_int [simp]:
  2123 lemma gcd_neg_numeral_1_int [simp]:
  2149   "gcd (- numeral n :: int) x = gcd (numeral n) x"
  2124   "gcd (- numeral n :: int) x = gcd (numeral n) x"
  2150   by (fact gcd_neg1_int)
  2125   by (fact gcd_neg1_int)
  2151 
  2126 
  2152 lemma gcd_neg_numeral_2_int [simp]:
  2127 lemma gcd_neg_numeral_2_int [simp]:
  2157   by (fact gcd_nat.absorb1)
  2132   by (fact gcd_nat.absorb1)
  2158 
  2133 
  2159 lemma gcd_proj2_if_dvd_nat [simp]: "(y::nat) dvd x \<Longrightarrow> gcd x y = y"
  2134 lemma gcd_proj2_if_dvd_nat [simp]: "(y::nat) dvd x \<Longrightarrow> gcd x y = y"
  2160   by (fact gcd_nat.absorb2)
  2135   by (fact gcd_nat.absorb2)
  2161 
  2136 
  2162 lemma comp_fun_idem_gcd_nat: "comp_fun_idem (gcd :: nat\<Rightarrow>nat\<Rightarrow>nat)"
  2137 lemmas Lcm_eq_0_I_nat [simp] = Lcm_eq_0_I [where ?'a = nat]
  2163   by (fact comp_fun_idem_gcd)
  2138 lemmas Lcm_0_iff_nat [simp] = Lcm_0_iff [where ?'a = nat]
  2164 
  2139 lemmas Lcm_least_int [simp] = Lcm_least [where ?'a = int]
  2165 lemma comp_fun_idem_gcd_int: "comp_fun_idem (gcd :: int\<Rightarrow>int\<Rightarrow>int)"
       
  2166   by (fact comp_fun_idem_gcd)
       
  2167 
       
  2168 lemma comp_fun_idem_lcm_nat: "comp_fun_idem (lcm :: nat\<Rightarrow>nat\<Rightarrow>nat)"
       
  2169   by (fact comp_fun_idem_lcm)
       
  2170 
       
  2171 lemma comp_fun_idem_lcm_int: "comp_fun_idem (lcm :: int\<Rightarrow>int\<Rightarrow>int)"
       
  2172   by (fact comp_fun_idem_lcm)
       
  2173 
       
  2174 lemma Lcm_eq_0 [simp]:
       
  2175   "finite (M::nat set) \<Longrightarrow> 0 \<in> M \<Longrightarrow> Lcm M = 0"
       
  2176   by (rule Lcm_eq_0_I)
       
  2177 
       
  2178 lemma Lcm0_iff [simp]:
       
  2179   fixes M :: "nat set"
       
  2180   assumes "finite M" and "M \<noteq> {}"
       
  2181   shows "Lcm M = 0 \<longleftrightarrow> 0 \<in> M"
       
  2182   using assms by (simp add: Lcm_0_iff)
       
  2183 
       
  2184 lemma Lcm_dvd_int [simp]:
       
  2185   fixes M :: "int set"
       
  2186   assumes "\<forall>m\<in>M. m dvd n" shows "Lcm M dvd n"
       
  2187   using assms by (auto intro: Lcm_least)
       
  2188 
       
  2189 lemma dvd_gcd_D1_nat: "k dvd gcd m n \<Longrightarrow> (k::nat) dvd m"
       
  2190   by (fact dvd_gcdD1)
       
  2191 
       
  2192 lemma dvd_gcd_D2_nat: "k dvd gcd m n \<Longrightarrow> (k::nat) dvd n"
       
  2193   by (fact dvd_gcdD2)
       
  2194 
       
  2195 lemma dvd_gcd_D1_int: "i dvd gcd m n \<Longrightarrow> (i::int) dvd m"
       
  2196   by (fact dvd_gcdD1)
       
  2197 
       
  2198 lemma dvd_gcd_D2_int: "i dvd gcd m n \<Longrightarrow> (i::int) dvd n"
       
  2199   by (fact dvd_gcdD2)
       
  2200 
  2140 
  2201 end
  2141 end