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