src/HOL/Number_Theory/Primes.thy
changeset 63633 2accfb71e33b
parent 63535 6887fda4541a
child 63635 858a225ebb62
equal deleted inserted replaced
63627:6ddb43c6b711 63633:2accfb71e33b
    53 *)
    53 *)
    54 
    54 
    55 declare [[coercion int]]
    55 declare [[coercion int]]
    56 declare [[coercion_enabled]]
    56 declare [[coercion_enabled]]
    57 
    57 
    58 abbreviation (input) "prime \<equiv> is_prime"
    58 lemma prime_elem_nat_iff:
    59 
    59   "prime_elem (n :: nat) \<longleftrightarrow> (1 < n \<and> (\<forall>m. m dvd n \<longrightarrow> m = 1 \<or> m = n))"
    60 lemma is_prime_elem_nat_iff:
       
    61   "is_prime_elem (n :: nat) \<longleftrightarrow> (1 < n \<and> (\<forall>m. m dvd n \<longrightarrow> m = 1 \<or> m = n))"
       
    62 proof safe
    60 proof safe
    63   assume *: "is_prime_elem n"
    61   assume *: "prime_elem n"
    64   from * have "n \<noteq> 0" "n \<noteq> 1" by (intro notI, simp del: One_nat_def)+
    62   from * have "n \<noteq> 0" "n \<noteq> 1" by (intro notI, simp del: One_nat_def)+
    65   thus "n > 1" by (cases n) simp_all
    63   thus "n > 1" by (cases n) simp_all
    66   fix m assume m: "m dvd n" "m \<noteq> n"
    64   fix m assume m: "m dvd n" "m \<noteq> n"
    67   from * \<open>m dvd n\<close> have "n dvd m \<or> is_unit m"
    65   from * \<open>m dvd n\<close> have "n dvd m \<or> is_unit m"
    68     by (intro irreducibleD' prime_imp_irreducible)
    66     by (intro irreducibleD' prime_elem_imp_irreducible)
    69   with m show "m = 1" by (auto dest: dvd_antisym)
    67   with m show "m = 1" by (auto dest: dvd_antisym)
    70 next
    68 next
    71   assume "n > 1" "\<forall>m. m dvd n \<longrightarrow> m = 1 \<or> m = n"
    69   assume "n > 1" "\<forall>m. m dvd n \<longrightarrow> m = 1 \<or> m = n"
    72   thus "is_prime_elem n"
    70   thus "prime_elem n"
    73     by (auto simp: prime_iff_irreducible irreducible_altdef)
    71     by (auto simp: prime_elem_iff_irreducible irreducible_altdef)
    74 qed
    72 qed
    75 
    73 
    76 lemma is_prime_nat_iff_is_prime_elem: "is_prime (n :: nat) \<longleftrightarrow> is_prime_elem n"
    74 lemma prime_nat_iff_prime_elem: "prime (n :: nat) \<longleftrightarrow> prime_elem n"
    77   by (simp add: is_prime_def)
    75   by (simp add: prime_def)
    78 
    76 
    79 lemma is_prime_nat_iff:
    77 lemma prime_nat_iff:
    80   "is_prime (n :: nat) \<longleftrightarrow> (1 < n \<and> (\<forall>m. m dvd n \<longrightarrow> m = 1 \<or> m = n))"
    78   "prime (n :: nat) \<longleftrightarrow> (1 < n \<and> (\<forall>m. m dvd n \<longrightarrow> m = 1 \<or> m = n))"
    81   by (simp add: is_prime_nat_iff_is_prime_elem is_prime_elem_nat_iff)
    79   by (simp add: prime_nat_iff_prime_elem prime_elem_nat_iff)
    82 
    80 
    83 lemma is_prime_elem_int_nat_transfer: "is_prime_elem (n::int) \<longleftrightarrow> is_prime_elem (nat (abs n))"
    81 lemma prime_elem_int_nat_transfer: "prime_elem (n::int) \<longleftrightarrow> prime_elem (nat (abs n))"
    84 proof
    82 proof
    85   assume "is_prime_elem n"
    83   assume "prime_elem n"
    86   thus "is_prime_elem (nat (abs n))" by (auto simp: is_prime_elem_def nat_dvd_iff)
    84   thus "prime_elem (nat (abs n))" by (auto simp: prime_elem_def nat_dvd_iff)
    87 next
    85 next
    88   assume "is_prime_elem (nat (abs n))"
    86   assume "prime_elem (nat (abs n))"
    89   thus "is_prime_elem n"
    87   thus "prime_elem n"
    90     by (auto simp: dvd_int_unfold_dvd_nat is_prime_elem_def abs_mult nat_mult_distrib)
    88     by (auto simp: dvd_int_unfold_dvd_nat prime_elem_def abs_mult nat_mult_distrib)
    91 qed
    89 qed
    92 
    90 
    93 lemma is_prime_elem_nat_int_transfer [simp]: "is_prime_elem (int n) \<longleftrightarrow> is_prime_elem n"
    91 lemma prime_elem_nat_int_transfer [simp]: "prime_elem (int n) \<longleftrightarrow> prime_elem n"
    94   by (auto simp: is_prime_elem_int_nat_transfer)
    92   by (auto simp: prime_elem_int_nat_transfer)
    95 
    93 
    96 lemma is_prime_nat_int_transfer [simp]: "is_prime (int n) \<longleftrightarrow> is_prime n"
    94 lemma prime_nat_int_transfer [simp]: "prime (int n) \<longleftrightarrow> prime n"
    97   by (auto simp: is_prime_elem_int_nat_transfer is_prime_def)
    95   by (auto simp: prime_elem_int_nat_transfer prime_def)
    98 
    96 
    99 lemma is_prime_int_nat_transfer: "is_prime (n::int) \<longleftrightarrow> n \<ge> 0 \<and> is_prime (nat n)"
    97 lemma prime_int_nat_transfer: "prime (n::int) \<longleftrightarrow> n \<ge> 0 \<and> prime (nat n)"
   100   by (auto simp: is_prime_elem_int_nat_transfer is_prime_def)
    98   by (auto simp: prime_elem_int_nat_transfer prime_def)
   101 
    99 
   102 lemma is_prime_int_iff:
   100 lemma prime_int_iff:
   103   "is_prime (n::int) \<longleftrightarrow> (1 < n \<and> (\<forall>m. m \<ge> 0 \<and> m dvd n \<longrightarrow> m = 1 \<or> m = n))"
   101   "prime (n::int) \<longleftrightarrow> (1 < n \<and> (\<forall>m. m \<ge> 0 \<and> m dvd n \<longrightarrow> m = 1 \<or> m = n))"
   104 proof (intro iffI conjI allI impI; (elim conjE)?)
   102 proof (intro iffI conjI allI impI; (elim conjE)?)
   105   assume *: "is_prime n"
   103   assume *: "prime n"
   106   hence irred: "irreducible n" by (simp add: prime_imp_irreducible)
   104   hence irred: "irreducible n" by (simp add: prime_elem_imp_irreducible)
   107   from * have "n \<ge> 0" "n \<noteq> 0" "n \<noteq> 1" 
   105   from * have "n \<ge> 0" "n \<noteq> 0" "n \<noteq> 1" 
   108     by (auto simp: is_prime_def zabs_def not_less split: if_splits)
   106     by (auto simp: prime_def zabs_def not_less split: if_splits)
   109   thus "n > 1" by presburger
   107   thus "n > 1" by presburger
   110   fix m assume "m dvd n" \<open>m \<ge> 0\<close>
   108   fix m assume "m dvd n" \<open>m \<ge> 0\<close>
   111   with irred have "m dvd 1 \<or> n dvd m" by (auto simp: irreducible_altdef)
   109   with irred have "m dvd 1 \<or> n dvd m" by (auto simp: irreducible_altdef)
   112   with \<open>m dvd n\<close> \<open>m \<ge> 0\<close> \<open>n > 1\<close> show "m = 1 \<or> m = n"
   110   with \<open>m dvd n\<close> \<open>m \<ge> 0\<close> \<open>n > 1\<close> show "m = 1 \<or> m = n"
   113     using associated_iff_dvd[of m n] by auto
   111     using associated_iff_dvd[of m n] by auto
   119     fix m assume "m dvd nat n"
   117     fix m assume "m dvd nat n"
   120     with \<open>n > 1\<close> have "int m dvd n" by (auto simp: int_dvd_iff)
   118     with \<open>n > 1\<close> have "int m dvd n" by (auto simp: int_dvd_iff)
   121     with n(2) have "int m = 1 \<or> int m = n" by auto
   119     with n(2) have "int m = 1 \<or> int m = n" by auto
   122     thus "m = 1 \<or> m = nat n" by auto
   120     thus "m = 1 \<or> m = nat n" by auto
   123   qed
   121   qed
   124   ultimately show "is_prime n" 
   122   ultimately show "prime n" 
   125     unfolding is_prime_int_nat_transfer is_prime_nat_iff by auto
   123     unfolding prime_int_nat_transfer prime_nat_iff by auto
   126 qed
   124 qed
   127 
   125 
   128 
   126 
   129 lemma prime_nat_not_dvd:
   127 lemma prime_nat_not_dvd:
   130   assumes "prime p" "p > n" "n \<noteq> (1::nat)"
   128   assumes "prime p" "p > n" "n \<noteq> (1::nat)"
   131   shows   "\<not>n dvd p"
   129   shows   "\<not>n dvd p"
   132 proof
   130 proof
   133   assume "n dvd p"
   131   assume "n dvd p"
   134   from assms(1) have "irreducible p" by (simp add: prime_imp_irreducible)
   132   from assms(1) have "irreducible p" by (simp add: prime_elem_imp_irreducible)
   135   from irreducibleD'[OF this \<open>n dvd p\<close>] \<open>n dvd p\<close> \<open>p > n\<close> assms show False
   133   from irreducibleD'[OF this \<open>n dvd p\<close>] \<open>n dvd p\<close> \<open>p > n\<close> assms show False
   136     by (cases "n = 0") (auto dest!: dvd_imp_le)
   134     by (cases "n = 0") (auto dest!: dvd_imp_le)
   137 qed
   135 qed
   138 
   136 
   139 lemma prime_int_not_dvd:
   137 lemma prime_int_not_dvd:
   140   assumes "prime p" "p > n" "n > (1::int)"
   138   assumes "prime p" "p > n" "n > (1::int)"
   141   shows   "\<not>n dvd p"
   139   shows   "\<not>n dvd p"
   142 proof
   140 proof
   143   assume "n dvd p"
   141   assume "n dvd p"
   144   from assms(1) have "irreducible p" by (simp add: prime_imp_irreducible)
   142   from assms(1) have "irreducible p" by (simp add: prime_elem_imp_irreducible)
   145   from irreducibleD'[OF this \<open>n dvd p\<close>] \<open>n dvd p\<close> \<open>p > n\<close> assms show False
   143   from irreducibleD'[OF this \<open>n dvd p\<close>] \<open>n dvd p\<close> \<open>p > n\<close> assms show False
   146     by (auto dest!: zdvd_imp_le)
   144     by (auto dest!: zdvd_imp_le)
   147 qed
   145 qed
   148 
   146 
   149 lemma prime_odd_nat: "prime p \<Longrightarrow> p > (2::nat) \<Longrightarrow> odd p"
   147 lemma prime_odd_nat: "prime p \<Longrightarrow> p > (2::nat) \<Longrightarrow> odd p"
   151 
   149 
   152 lemma prime_odd_int: "prime p \<Longrightarrow> p > (2::int) \<Longrightarrow> odd p"
   150 lemma prime_odd_int: "prime p \<Longrightarrow> p > (2::int) \<Longrightarrow> odd p"
   153   by (intro prime_int_not_dvd) auto
   151   by (intro prime_int_not_dvd) auto
   154 
   152 
   155 lemma prime_ge_0_int: "prime p \<Longrightarrow> p \<ge> (0::int)"
   153 lemma prime_ge_0_int: "prime p \<Longrightarrow> p \<ge> (0::int)"
   156   unfolding is_prime_int_iff by auto
   154   unfolding prime_int_iff by auto
   157 
   155 
   158 lemma prime_gt_0_nat: "prime p \<Longrightarrow> p > (0::nat)"
   156 lemma prime_gt_0_nat: "prime p \<Longrightarrow> p > (0::nat)"
   159   unfolding is_prime_nat_iff by auto
   157   unfolding prime_nat_iff by auto
   160 
   158 
   161 lemma prime_gt_0_int: "prime p \<Longrightarrow> p > (0::int)"
   159 lemma prime_gt_0_int: "prime p \<Longrightarrow> p > (0::int)"
   162   unfolding is_prime_int_iff by auto
   160   unfolding prime_int_iff by auto
   163 
   161 
   164 lemma prime_ge_1_nat: "prime p \<Longrightarrow> p \<ge> (1::nat)"
   162 lemma prime_ge_1_nat: "prime p \<Longrightarrow> p \<ge> (1::nat)"
   165   unfolding is_prime_nat_iff by auto
   163   unfolding prime_nat_iff by auto
   166 
   164 
   167 lemma prime_ge_Suc_0_nat: "prime p \<Longrightarrow> p \<ge> Suc 0"
   165 lemma prime_ge_Suc_0_nat: "prime p \<Longrightarrow> p \<ge> Suc 0"
   168   unfolding is_prime_nat_iff by auto
   166   unfolding prime_nat_iff by auto
   169 
   167 
   170 lemma prime_ge_1_int: "prime p \<Longrightarrow> p \<ge> (1::int)"
   168 lemma prime_ge_1_int: "prime p \<Longrightarrow> p \<ge> (1::int)"
   171   unfolding is_prime_int_iff by auto
   169   unfolding prime_int_iff by auto
   172 
   170 
   173 lemma prime_gt_1_nat: "prime p \<Longrightarrow> p > (1::nat)"
   171 lemma prime_gt_1_nat: "prime p \<Longrightarrow> p > (1::nat)"
   174   unfolding is_prime_nat_iff by auto
   172   unfolding prime_nat_iff by auto
   175 
   173 
   176 lemma prime_gt_Suc_0_nat: "prime p \<Longrightarrow> p > Suc 0"
   174 lemma prime_gt_Suc_0_nat: "prime p \<Longrightarrow> p > Suc 0"
   177   unfolding is_prime_nat_iff by auto
   175   unfolding prime_nat_iff by auto
   178 
   176 
   179 lemma prime_gt_1_int: "prime p \<Longrightarrow> p > (1::int)"
   177 lemma prime_gt_1_int: "prime p \<Longrightarrow> p > (1::int)"
   180   unfolding is_prime_int_iff by auto
   178   unfolding prime_int_iff by auto
   181 
   179 
   182 lemma prime_ge_2_nat: "prime p \<Longrightarrow> p \<ge> (2::nat)"
   180 lemma prime_ge_2_nat: "prime p \<Longrightarrow> p \<ge> (2::nat)"
   183   unfolding is_prime_nat_iff by auto
   181   unfolding prime_nat_iff by auto
   184 
   182 
   185 lemma prime_ge_2_int: "prime p \<Longrightarrow> p \<ge> (2::int)"
   183 lemma prime_ge_2_int: "prime p \<Longrightarrow> p \<ge> (2::int)"
   186   unfolding is_prime_int_iff by auto
   184   unfolding prime_int_iff by auto
   187 
   185 
   188 lemma prime_int_altdef:
   186 lemma prime_int_altdef:
   189   "prime p = (1 < p \<and> (\<forall>m::int. m \<ge> 0 \<longrightarrow> m dvd p \<longrightarrow>
   187   "prime p = (1 < p \<and> (\<forall>m::int. m \<ge> 0 \<longrightarrow> m dvd p \<longrightarrow>
   190     m = 1 \<or> m = p))"
   188     m = 1 \<or> m = p))"
   191   unfolding is_prime_int_iff by blast
   189   unfolding prime_int_iff by blast
   192 
   190 
   193 lemma not_prime_eq_prod_nat:
   191 lemma not_prime_eq_prod_nat:
   194   assumes "m > 1" "\<not>prime (m::nat)"
   192   assumes "m > 1" "\<not>prime (m::nat)"
   195   shows   "\<exists>n k. n = m * k \<and> 1 < m \<and> m < n \<and> 1 < k \<and> k < n"
   193   shows   "\<exists>n k. n = m * k \<and> 1 < m \<and> m < n \<and> 1 < k \<and> k < n"
   196   using assms irreducible_altdef[of m]
   194   using assms irreducible_altdef[of m]
   197   by (auto simp: prime_iff_irreducible is_prime_def irreducible_altdef)
   195   by (auto simp: prime_elem_iff_irreducible prime_def irreducible_altdef)
   198 
   196 
   199 
   197 
   200 subsubsection \<open>Make prime naively executable\<close>
   198 subsubsection \<open>Make prime naively executable\<close>
   201 
   199 
   202 lemma Suc_0_not_prime_nat [simp]: "~prime (Suc 0)"
   200 lemma Suc_0_not_prime_nat [simp]: "~prime (Suc 0)"
   203   unfolding One_nat_def [symmetric] by (rule not_is_prime_1)
   201   unfolding One_nat_def [symmetric] by (rule not_prime_1)
   204 
   202 
   205 lemma is_prime_nat_iff':
   203 lemma prime_nat_iff':
   206   "prime (p :: nat) \<longleftrightarrow> p > 1 \<and> (\<forall>n \<in> {1<..<p}. ~ n dvd p)"
   204   "prime (p :: nat) \<longleftrightarrow> p > 1 \<and> (\<forall>n \<in> {1<..<p}. ~ n dvd p)"
   207 proof safe
   205 proof safe
   208   assume "p > 1" and *: "\<forall>n\<in>{1<..<p}. \<not>n dvd p"
   206   assume "p > 1" and *: "\<forall>n\<in>{1<..<p}. \<not>n dvd p"
   209   show "is_prime p" unfolding is_prime_nat_iff
   207   show "prime p" unfolding prime_nat_iff
   210   proof (intro conjI allI impI)
   208   proof (intro conjI allI impI)
   211     fix m assume "m dvd p"
   209     fix m assume "m dvd p"
   212     with \<open>p > 1\<close> have "m \<noteq> 0" by (intro notI) auto
   210     with \<open>p > 1\<close> have "m \<noteq> 0" by (intro notI) auto
   213     hence "m \<ge> 1" by simp
   211     hence "m \<ge> 1" by simp
   214     moreover from \<open>m dvd p\<close> and * have "m \<notin> {1<..<p}" by blast
   212     moreover from \<open>m dvd p\<close> and * have "m \<notin> {1<..<p}" by blast
   215     with \<open>m dvd p\<close> and \<open>p > 1\<close> have "m \<le> 1 \<or> m = p" by (auto dest: dvd_imp_le)
   213     with \<open>m dvd p\<close> and \<open>p > 1\<close> have "m \<le> 1 \<or> m = p" by (auto dest: dvd_imp_le)
   216     ultimately show "m = 1 \<or> m = p" by simp
   214     ultimately show "m = 1 \<or> m = p" by simp
   217   qed fact+
   215   qed fact+
   218 qed (auto simp: is_prime_nat_iff)
   216 qed (auto simp: prime_nat_iff)
   219 
   217 
   220 lemma prime_nat_code [code_unfold]:
   218 lemma prime_nat_code [code_unfold]:
   221   "(prime :: nat \<Rightarrow> bool) = (\<lambda>p. p > 1 \<and> (\<forall>n \<in> {1<..<p}. ~ n dvd p))"
   219   "(prime :: nat \<Rightarrow> bool) = (\<lambda>p. p > 1 \<and> (\<forall>n \<in> {1<..<p}. ~ n dvd p))"
   222   by (rule ext, rule is_prime_nat_iff')
   220   by (rule ext, rule prime_nat_iff')
   223 
   221 
   224 lemma is_prime_int_iff':
   222 lemma prime_int_iff':
   225   "prime (p :: int) \<longleftrightarrow> p > 1 \<and> (\<forall>n \<in> {1<..<p}. ~ n dvd p)" (is "?lhs = ?rhs")
   223   "prime (p :: int) \<longleftrightarrow> p > 1 \<and> (\<forall>n \<in> {1<..<p}. ~ n dvd p)" (is "?lhs = ?rhs")
   226 proof
   224 proof
   227   assume "?lhs"
   225   assume "?lhs"
   228   thus "?rhs" by (auto simp: is_prime_int_nat_transfer dvd_int_unfold_dvd_nat prime_nat_code)
   226   thus "?rhs" by (auto simp: prime_int_nat_transfer dvd_int_unfold_dvd_nat prime_nat_code)
   229 next
   227 next
   230   assume "?rhs"
   228   assume "?rhs"
   231   thus "?lhs" by (auto simp: is_prime_int_nat_transfer zdvd_int prime_nat_code)
   229   thus "?lhs" by (auto simp: prime_int_nat_transfer zdvd_int prime_nat_code)
   232 qed
   230 qed
   233 
   231 
   234 lemma prime_int_code [code_unfold]:
   232 lemma prime_int_code [code_unfold]:
   235   "(prime :: int \<Rightarrow> bool) = (\<lambda>p. p > 1 \<and> (\<forall>n \<in> {1<..<p}. ~ n dvd p))" 
   233   "(prime :: int \<Rightarrow> bool) = (\<lambda>p. p > 1 \<and> (\<forall>n \<in> {1<..<p}. ~ n dvd p))" 
   236   by (rule ext, rule is_prime_int_iff')
   234   by (rule ext, rule prime_int_iff')
   237 
   235 
   238 lemma prime_nat_simp:
   236 lemma prime_nat_simp:
   239     "prime p \<longleftrightarrow> p > 1 \<and> (\<forall>n \<in> set [2..<p]. \<not> n dvd p)"
   237     "prime p \<longleftrightarrow> p > 1 \<and> (\<forall>n \<in> set [2..<p]. \<not> n dvd p)"
   240   by (auto simp add: prime_nat_code)
   238   by (auto simp add: prime_nat_code)
   241 
   239 
   243     "prime (p::int) \<longleftrightarrow> p > 1 \<and> (\<forall>n \<in> {2..<p}. \<not> n dvd p)"
   241     "prime (p::int) \<longleftrightarrow> p > 1 \<and> (\<forall>n \<in> {2..<p}. \<not> n dvd p)"
   244   by (auto simp add: prime_int_code)
   242   by (auto simp add: prime_int_code)
   245 
   243 
   246 lemmas prime_nat_simp_numeral [simp] = prime_nat_simp [of "numeral m"] for m
   244 lemmas prime_nat_simp_numeral [simp] = prime_nat_simp [of "numeral m"] for m
   247 
   245 
   248 lemma two_is_prime_nat [simp]: "prime (2::nat)"
   246 lemma two_prime_nat [simp]: "prime (2::nat)"
   249   by simp
   247   by simp
   250 
   248 
   251 declare is_prime_int_nat_transfer[of "numeral m" for m, simp]
   249 declare prime_int_nat_transfer[of "numeral m" for m, simp]
   252 
   250 
   253 
   251 
   254 text\<open>A bit of regression testing:\<close>
   252 text\<open>A bit of regression testing:\<close>
   255 
   253 
   256 lemma "prime(97::nat)" by simp
   254 lemma "prime(97::nat)" by simp
   280     with \<open>p dvd fact n + 1\<close> have "p dvd fact n + 1 - fact n"
   278     with \<open>p dvd fact n + 1\<close> have "p dvd fact n + 1 - fact n"
   281       by (rule dvd_diff_nat)
   279       by (rule dvd_diff_nat)
   282     then have "p dvd 1" by simp
   280     then have "p dvd 1" by simp
   283     then have "p <= 1" by auto
   281     then have "p <= 1" by auto
   284     moreover from \<open>prime p\<close> have "p > 1"
   282     moreover from \<open>prime p\<close> have "p > 1"
   285       using is_prime_nat_iff by blast
   283       using prime_nat_iff by blast
   286     ultimately have False by auto}
   284     ultimately have False by auto}
   287   then have "n < p" by presburger
   285   then have "n < p" by presburger
   288   with \<open>prime p\<close> and \<open>p <= fact n + 1\<close> show ?thesis by auto
   286   with \<open>prime p\<close> and \<open>p <= fact n + 1\<close> show ?thesis by auto
   289 qed
   287 qed
   290 
   288 
   311   assumes "prime (p * q)"
   309   assumes "prime (p * q)"
   312   shows "p = 1 \<or> q = 1"
   310   shows "p = 1 \<or> q = 1"
   313 proof -
   311 proof -
   314   from assms have
   312   from assms have
   315     "1 < p * q" and P: "\<And>m. m dvd p * q \<Longrightarrow> m = 1 \<or> m = p * q"
   313     "1 < p * q" and P: "\<And>m. m dvd p * q \<Longrightarrow> m = 1 \<or> m = p * q"
   316     unfolding is_prime_nat_iff by auto
   314     unfolding prime_nat_iff by auto
   317   from \<open>1 < p * q\<close> have "p \<noteq> 0" by (cases p) auto
   315   from \<open>1 < p * q\<close> have "p \<noteq> 0" by (cases p) auto
   318   then have Q: "p = p * q \<longleftrightarrow> q = 1" by auto
   316   then have Q: "p = p * q \<longleftrightarrow> q = 1" by auto
   319   have "p dvd p * q" by simp
   317   have "p dvd p * q" by simp
   320   then have "p = 1 \<or> p = p * q" by (rule P)
   318   then have "p = 1 \<or> p = p * q" by (rule P)
   321   then show ?thesis by (simp add: Q)
   319   then show ?thesis by (simp add: Q)
   330 proof(induct k arbitrary: x y)
   328 proof(induct k arbitrary: x y)
   331   case 0 thus ?case apply simp by (rule exI[where x="0"], simp)
   329   case 0 thus ?case apply simp by (rule exI[where x="0"], simp)
   332 next
   330 next
   333   case (Suc k x y)
   331   case (Suc k x y)
   334   from Suc.prems have pxy: "p dvd x*y" by auto
   332   from Suc.prems have pxy: "p dvd x*y" by auto
   335   from is_prime_dvd_multD [OF p pxy] have pxyc: "p dvd x \<or> p dvd y" .
   333   from prime_dvd_multD [OF p pxy] have pxyc: "p dvd x \<or> p dvd y" .
   336   from p have p0: "p \<noteq> 0" by - (rule ccontr, simp)
   334   from p have p0: "p \<noteq> 0" by - (rule ccontr, simp)
   337   {assume px: "p dvd x"
   335   {assume px: "p dvd x"
   338     then obtain d where d: "x = p*d" unfolding dvd_def by blast
   336     then obtain d where d: "x = p*d" unfolding dvd_def by blast
   339     from Suc.prems d  have "p*d*y = p^Suc k" by simp
   337     from Suc.prems d  have "p*d*y = p^Suc k" by simp
   340     hence th: "d*y = p^k" using p0 by simp
   338     hence th: "d*y = p^k" using p0 by simp
   444 lemma bezout_prime:
   442 lemma bezout_prime:
   445   assumes p: "prime p" and pa: "\<not> p dvd a"
   443   assumes p: "prime p" and pa: "\<not> p dvd a"
   446   shows "\<exists>x y. a*x = Suc (p*y)"
   444   shows "\<exists>x y. a*x = Suc (p*y)"
   447 proof -
   445 proof -
   448   have ap: "coprime a p"
   446   have ap: "coprime a p"
   449     by (metis gcd.commute p pa is_prime_imp_coprime)
   447     by (metis gcd.commute p pa prime_imp_coprime)
   450   moreover from p have "p \<noteq> 1" by auto
   448   moreover from p have "p \<noteq> 1" by auto
   451   ultimately have "\<exists>x y. a * x = p * y + 1"
   449   ultimately have "\<exists>x y. a * x = p * y + 1"
   452     by (rule coprime_bezout_strong)
   450     by (rule coprime_bezout_strong)
   453   then show ?thesis by simp    
   451   then show ?thesis by simp    
   454 qed
   452 qed
   468 
   466 
   469 lemma prime_factors_ge_0_int [elim]:
   467 lemma prime_factors_ge_0_int [elim]:
   470   fixes n :: int
   468   fixes n :: int
   471   shows "p \<in> prime_factors n \<Longrightarrow> p \<ge> 0"
   469   shows "p \<in> prime_factors n \<Longrightarrow> p \<ge> 0"
   472   unfolding prime_factors_def 
   470   unfolding prime_factors_def 
   473   by (auto split: if_splits simp: is_prime_def dest!: in_prime_factorization_imp_prime)
   471   by (auto split: if_splits simp: prime_def dest!: in_prime_factorization_imp_prime)
   474 
   472 
   475 lemma msetprod_prime_factorization_int:
   473 lemma msetprod_prime_factorization_int:
   476   fixes n :: int
   474   fixes n :: int
   477   assumes "n > 0"
   475   assumes "n > 0"
   478   shows   "msetprod (prime_factorization n) = n"
   476   shows   "msetprod (prime_factorization n) = n"
   479   using assms by (simp add: msetprod_prime_factorization)
   477   using assms by (simp add: msetprod_prime_factorization)
   480 
   478 
   481 lemma prime_factorization_exists_nat:
   479 lemma prime_factorization_exists_nat:
   482   "n > 0 \<Longrightarrow> (\<exists>M. (\<forall>p::nat \<in> set_mset M. prime p) \<and> n = (\<Prod>i \<in># M. i))"
   480   "n > 0 \<Longrightarrow> (\<exists>M. (\<forall>p::nat \<in> set_mset M. prime p) \<and> n = (\<Prod>i \<in># M. i))"
   483   using prime_factorization_exists[of n] by (auto simp: is_prime_def)
   481   using prime_factorization_exists[of n] by (auto simp: prime_def)
   484 
   482 
   485 lemma msetprod_prime_factorization_nat [simp]: 
   483 lemma msetprod_prime_factorization_nat [simp]: 
   486   "(n::nat) > 0 \<Longrightarrow> msetprod (prime_factorization n) = n"
   484   "(n::nat) > 0 \<Longrightarrow> msetprod (prime_factorization n) = n"
   487   by (subst msetprod_prime_factorization) simp_all
   485   by (subst msetprod_prime_factorization) simp_all
   488 
   486 
   497 lemma prime_factorization_unique_nat:
   495 lemma prime_factorization_unique_nat:
   498   fixes f :: "nat \<Rightarrow> _"
   496   fixes f :: "nat \<Rightarrow> _"
   499   assumes S_eq: "S = {p. 0 < f p}"
   497   assumes S_eq: "S = {p. 0 < f p}"
   500     and "finite S"
   498     and "finite S"
   501     and S: "\<forall>p\<in>S. prime p" "n = (\<Prod>p\<in>S. p ^ f p)"
   499     and S: "\<forall>p\<in>S. prime p" "n = (\<Prod>p\<in>S. p ^ f p)"
   502   shows "S = prime_factors n \<and> (\<forall>p. is_prime p \<longrightarrow> f p = multiplicity p n)"
   500   shows "S = prime_factors n \<and> (\<forall>p. prime p \<longrightarrow> f p = multiplicity p n)"
   503   using assms by (intro prime_factorization_unique'') auto
   501   using assms by (intro prime_factorization_unique'') auto
   504 
   502 
   505 lemma prime_factorization_unique_int:
   503 lemma prime_factorization_unique_int:
   506   fixes f :: "int \<Rightarrow> _"
   504   fixes f :: "int \<Rightarrow> _"
   507   assumes S_eq: "S = {p. 0 < f p}"
   505   assumes S_eq: "S = {p. 0 < f p}"
   508     and "finite S"
   506     and "finite S"
   509     and S: "\<forall>p\<in>S. prime p" "abs n = (\<Prod>p\<in>S. p ^ f p)"
   507     and S: "\<forall>p\<in>S. prime p" "abs n = (\<Prod>p\<in>S. p ^ f p)"
   510   shows "S = prime_factors n \<and> (\<forall>p. is_prime p \<longrightarrow> f p = multiplicity p n)"
   508   shows "S = prime_factors n \<and> (\<forall>p. prime p \<longrightarrow> f p = multiplicity p n)"
   511   using assms by (intro prime_factorization_unique'') auto
   509   using assms by (intro prime_factorization_unique'') auto
   512 
   510 
   513 lemma prime_factors_characterization_nat:
   511 lemma prime_factors_characterization_nat:
   514   "S = {p. 0 < f (p::nat)} \<Longrightarrow>
   512   "S = {p. 0 < f (p::nat)} \<Longrightarrow>
   515     finite S \<Longrightarrow> \<forall>p\<in>S. prime p \<Longrightarrow> n = (\<Prod>p\<in>S. p ^ f p) \<Longrightarrow> prime_factors n = S"
   513     finite S \<Longrightarrow> \<forall>p\<in>S. prime p \<Longrightarrow> n = (\<Prod>p\<in>S. p ^ f p) \<Longrightarrow> prime_factors n = S"
   534   "finite {p. p \<ge> 0 \<and> 0 < f (p::int)} \<Longrightarrow> \<forall>p. 0 < f p \<longrightarrow> prime p \<Longrightarrow>
   532   "finite {p. p \<ge> 0 \<and> 0 < f (p::int)} \<Longrightarrow> \<forall>p. 0 < f p \<longrightarrow> prime p \<Longrightarrow>
   535       prime_factors (\<Prod>p | p \<ge> 0 \<and> 0 < f p. p ^ f p) = {p. p \<ge> 0 \<and> 0 < f p}"
   533       prime_factors (\<Prod>p | p \<ge> 0 \<and> 0 < f p. p ^ f p) = {p. p \<ge> 0 \<and> 0 < f p}"
   536   by (rule prime_factors_characterization_int) (auto simp: abs_setprod prime_ge_0_int)
   534   by (rule prime_factors_characterization_int) (auto simp: abs_setprod prime_ge_0_int)
   537 
   535 
   538 lemma multiplicity_characterization_nat:
   536 lemma multiplicity_characterization_nat:
   539   "S = {p. 0 < f (p::nat)} \<Longrightarrow> finite S \<Longrightarrow> \<forall>p\<in>S. prime p \<Longrightarrow> is_prime p \<Longrightarrow>
   537   "S = {p. 0 < f (p::nat)} \<Longrightarrow> finite S \<Longrightarrow> \<forall>p\<in>S. prime p \<Longrightarrow> prime p \<Longrightarrow>
   540     n = (\<Prod>p\<in>S. p ^ f p) \<Longrightarrow> multiplicity p n = f p"
   538     n = (\<Prod>p\<in>S. p ^ f p) \<Longrightarrow> multiplicity p n = f p"
   541   by (frule prime_factorization_unique_nat [of S f n, THEN conjunct2, rule_format, symmetric]) auto
   539   by (frule prime_factorization_unique_nat [of S f n, THEN conjunct2, rule_format, symmetric]) auto
   542 
   540 
   543 lemma multiplicity_characterization'_nat: "finite {p. 0 < f (p::nat)} \<longrightarrow>
   541 lemma multiplicity_characterization'_nat: "finite {p. 0 < f (p::nat)} \<longrightarrow>
   544     (\<forall>p. 0 < f p \<longrightarrow> prime p) \<longrightarrow> is_prime p \<longrightarrow>
   542     (\<forall>p. 0 < f p \<longrightarrow> prime p) \<longrightarrow> prime p \<longrightarrow>
   545       multiplicity p (\<Prod>p | 0 < f p. p ^ f p) = f p"
   543       multiplicity p (\<Prod>p | 0 < f p. p ^ f p) = f p"
   546   by (intro impI, rule multiplicity_characterization_nat) auto
   544   by (intro impI, rule multiplicity_characterization_nat) auto
   547 
   545 
   548 lemma multiplicity_characterization_int: "S = {p. 0 < f (p::int)} \<Longrightarrow>
   546 lemma multiplicity_characterization_int: "S = {p. 0 < f (p::int)} \<Longrightarrow>
   549     finite S \<Longrightarrow> \<forall>p\<in>S. prime p \<Longrightarrow> is_prime p \<Longrightarrow> n = (\<Prod>p\<in>S. p ^ f p) \<Longrightarrow> multiplicity p n = f p"
   547     finite S \<Longrightarrow> \<forall>p\<in>S. prime p \<Longrightarrow> prime p \<Longrightarrow> n = (\<Prod>p\<in>S. p ^ f p) \<Longrightarrow> multiplicity p n = f p"
   550   by (frule prime_factorization_unique_int [of S f n, THEN conjunct2, rule_format, symmetric]) 
   548   by (frule prime_factorization_unique_int [of S f n, THEN conjunct2, rule_format, symmetric]) 
   551      (auto simp: abs_setprod power_abs prime_ge_0_int intro!: setprod.cong)
   549      (auto simp: abs_setprod power_abs prime_ge_0_int intro!: setprod.cong)
   552 
   550 
   553 lemma multiplicity_characterization'_int [rule_format]:
   551 lemma multiplicity_characterization'_int [rule_format]:
   554   "finite {p. p \<ge> 0 \<and> 0 < f (p::int)} \<Longrightarrow>
   552   "finite {p. p \<ge> 0 \<and> 0 < f (p::int)} \<Longrightarrow>
   555     (\<forall>p. 0 < f p \<longrightarrow> prime p) \<Longrightarrow> is_prime p \<Longrightarrow>
   553     (\<forall>p. 0 < f p \<longrightarrow> prime p) \<Longrightarrow> prime p \<Longrightarrow>
   556       multiplicity p (\<Prod>p | p \<ge> 0 \<and> 0 < f p. p ^ f p) = f p"
   554       multiplicity p (\<Prod>p | p \<ge> 0 \<and> 0 < f p. p ^ f p) = f p"
   557   by (rule multiplicity_characterization_int) (auto simp: prime_ge_0_int)
   555   by (rule multiplicity_characterization_int) (auto simp: prime_ge_0_int)
   558 
   556 
   559 lemma multiplicity_one_nat [simp]: "multiplicity p (Suc 0) = 0"
   557 lemma multiplicity_one_nat [simp]: "multiplicity p (Suc 0) = 0"
   560   unfolding One_nat_def [symmetric] by (rule multiplicity_one)
   558   unfolding One_nat_def [symmetric] by (rule multiplicity_one)
   561 
   559 
   562 lemma multiplicity_eq_nat:
   560 lemma multiplicity_eq_nat:
   563   fixes x and y::nat
   561   fixes x and y::nat
   564   assumes "x > 0" "y > 0" "\<And>p. is_prime p \<Longrightarrow> multiplicity p x = multiplicity p y"
   562   assumes "x > 0" "y > 0" "\<And>p. prime p \<Longrightarrow> multiplicity p x = multiplicity p y"
   565   shows "x = y"
   563   shows "x = y"
   566   using multiplicity_eq_imp_eq[of x y] assms by simp
   564   using multiplicity_eq_imp_eq[of x y] assms by simp
   567 
   565 
   568 lemma multiplicity_eq_int:
   566 lemma multiplicity_eq_int:
   569   fixes x y :: int
   567   fixes x y :: int
   570   assumes "x > 0" "y > 0" "\<And>p. is_prime p \<Longrightarrow> multiplicity p x = multiplicity p y"
   568   assumes "x > 0" "y > 0" "\<And>p. prime p \<Longrightarrow> multiplicity p x = multiplicity p y"
   571   shows "x = y"
   569   shows "x = y"
   572   using multiplicity_eq_imp_eq[of x y] assms by simp
   570   using multiplicity_eq_imp_eq[of x y] assms by simp
   573 
   571 
   574 lemma multiplicity_prod_prime_powers:
   572 lemma multiplicity_prod_prime_powers:
   575   assumes "finite S" "\<And>x. x \<in> S \<Longrightarrow> is_prime x" "is_prime p"
   573   assumes "finite S" "\<And>x. x \<in> S \<Longrightarrow> prime x" "prime p"
   576   shows   "multiplicity p (\<Prod>p \<in> S. p ^ f p) = (if p \<in> S then f p else 0)"
   574   shows   "multiplicity p (\<Prod>p \<in> S. p ^ f p) = (if p \<in> S then f p else 0)"
   577 proof -
   575 proof -
   578   define g where "g = (\<lambda>x. if x \<in> S then f x else 0)"
   576   define g where "g = (\<lambda>x. if x \<in> S then f x else 0)"
   579   define A where "A = Abs_multiset g"
   577   define A where "A = Abs_multiset g"
   580   have "{x. g x > 0} \<subseteq> S" by (auto simp: g_def)
   578   have "{x. g x > 0} \<subseteq> S" by (auto simp: g_def)
   590   also from set_mset_A assms have "\<dots> = (\<Prod>p \<in> set_mset A. p ^ g p)"
   588   also from set_mset_A assms have "\<dots> = (\<Prod>p \<in> set_mset A. p ^ g p)"
   591     by (intro setprod.mono_neutral_right) (auto simp: g_def set_mset_A)
   589     by (intro setprod.mono_neutral_right) (auto simp: g_def set_mset_A)
   592   also have "\<dots> = msetprod A"
   590   also have "\<dots> = msetprod A"
   593     by (auto simp: msetprod_multiplicity count_A set_mset_A intro!: setprod.cong)
   591     by (auto simp: msetprod_multiplicity count_A set_mset_A intro!: setprod.cong)
   594   also from assms have "multiplicity p \<dots> = msetsum (image_mset (multiplicity p) A)"
   592   also from assms have "multiplicity p \<dots> = msetsum (image_mset (multiplicity p) A)"
   595     by (subst prime_multiplicity_msetprod_distrib) (auto dest: prime)
   593     by (subst prime_elem_multiplicity_msetprod_distrib) (auto dest: prime)
   596   also from assms have "image_mset (multiplicity p) A = image_mset (\<lambda>x. if x = p then 1 else 0) A"
   594   also from assms have "image_mset (multiplicity p) A = image_mset (\<lambda>x. if x = p then 1 else 0) A"
   597     by (intro image_mset_cong) (auto simp: prime_multiplicity_other dest: prime)
   595     by (intro image_mset_cong) (auto simp: prime_multiplicity_other dest: prime)
   598   also have "msetsum \<dots> = (if p \<in> S then f p else 0)" by (simp add: msetsum_delta count_A g_def)
   596   also have "msetsum \<dots> = (if p \<in> S then f p else 0)" by (simp add: msetsum_delta count_A g_def)
   599   finally show ?thesis .
   597   finally show ?thesis .
   600 qed
   598 qed
   601 
   599 
   602 (* TODO Legacy names *)
   600 (* TODO Legacy names *)
   603 lemmas prime_imp_coprime_nat = is_prime_imp_coprime[where ?'a = nat]
   601 lemmas prime_imp_coprime_nat = prime_imp_coprime[where ?'a = nat]
   604 lemmas prime_imp_coprime_int = is_prime_imp_coprime[where ?'a = int]
   602 lemmas prime_imp_coprime_int = prime_imp_coprime[where ?'a = int]
   605 lemmas prime_dvd_mult_nat = is_prime_dvd_mult_iff[where ?'a = nat]
   603 lemmas prime_dvd_mult_nat = prime_dvd_mult_iff[where ?'a = nat]
   606 lemmas prime_dvd_mult_int = is_prime_dvd_mult_iff[where ?'a = int]
   604 lemmas prime_dvd_mult_int = prime_dvd_mult_iff[where ?'a = int]
   607 lemmas prime_dvd_mult_eq_nat = is_prime_dvd_mult_iff[where ?'a = nat]
   605 lemmas prime_dvd_mult_eq_nat = prime_dvd_mult_iff[where ?'a = nat]
   608 lemmas prime_dvd_mult_eq_int = is_prime_dvd_mult_iff[where ?'a = int]
   606 lemmas prime_dvd_mult_eq_int = prime_dvd_mult_iff[where ?'a = int]
   609 lemmas prime_dvd_power_nat = is_prime_dvd_power[where ?'a = nat]
   607 lemmas prime_dvd_power_nat = prime_dvd_power[where ?'a = nat]
   610 lemmas prime_dvd_power_int = is_prime_dvd_power[where ?'a = int]
   608 lemmas prime_dvd_power_int = prime_dvd_power[where ?'a = int]
   611 lemmas prime_dvd_power_nat_iff = is_prime_dvd_power_iff[where ?'a = nat]
   609 lemmas prime_dvd_power_nat_iff = prime_dvd_power_iff[where ?'a = nat]
   612 lemmas prime_dvd_power_int_iff = is_prime_dvd_power_iff[where ?'a = int]
   610 lemmas prime_dvd_power_int_iff = prime_dvd_power_iff[where ?'a = int]
   613 lemmas prime_imp_power_coprime_nat = is_prime_imp_power_coprime[where ?'a = nat]
   611 lemmas prime_imp_power_coprime_nat = prime_imp_power_coprime[where ?'a = nat]
   614 lemmas prime_imp_power_coprime_int = is_prime_imp_power_coprime[where ?'a = int]
   612 lemmas prime_imp_power_coprime_int = prime_imp_power_coprime[where ?'a = int]
   615 lemmas primes_coprime_nat = primes_coprime[where ?'a = nat]
   613 lemmas primes_coprime_nat = primes_coprime[where ?'a = nat]
   616 lemmas primes_coprime_int = primes_coprime[where ?'a = nat]
   614 lemmas primes_coprime_int = primes_coprime[where ?'a = nat]
   617 lemmas prime_divprod_pow_nat = prime_divprod_pow[where ?'a = nat]
   615 lemmas prime_divprod_pow_nat = prime_elem_divprod_pow[where ?'a = nat]
   618 lemmas prime_exp = is_prime_elem_power_iff[where ?'a = nat]
   616 lemmas prime_exp = prime_elem_power_iff[where ?'a = nat]
   619 
   617 
   620 end
   618 end