|
1 (* |
|
2 File: HOL/Number_Theory/Prime_Powers.thy |
|
3 Author: Manuel Eberl <eberlm@in.tum.de> |
|
4 |
|
5 Prime powers and the Mangoldt function |
|
6 *) |
|
7 section \<open>Prime powers\<close> |
|
8 theory Prime_Powers |
|
9 imports Complex_Main "~~/src/HOL/Computational_Algebra/Primes" |
|
10 begin |
|
11 |
|
12 definition aprimedivisor :: "'a :: normalization_semidom \<Rightarrow> 'a" where |
|
13 "aprimedivisor q = (SOME p. prime p \<and> p dvd q)" |
|
14 |
|
15 definition primepow :: "'a :: normalization_semidom \<Rightarrow> bool" where |
|
16 "primepow n \<longleftrightarrow> (\<exists>p k. prime p \<and> k > 0 \<and> n = p ^ k)" |
|
17 |
|
18 definition primepow_factors :: "'a :: normalization_semidom \<Rightarrow> 'a set" where |
|
19 "primepow_factors n = {x. primepow x \<and> x dvd n}" |
|
20 |
|
21 lemma primepow_gt_Suc_0: "primepow n \<Longrightarrow> n > Suc 0" |
|
22 using one_less_power[of "p::nat" for p] by (auto simp: primepow_def prime_nat_iff) |
|
23 |
|
24 lemma |
|
25 assumes "prime p" "p dvd n" |
|
26 shows prime_aprimedivisor: "prime (aprimedivisor n)" |
|
27 and aprimedivisor_dvd: "aprimedivisor n dvd n" |
|
28 proof - |
|
29 from assms have "\<exists>p. prime p \<and> p dvd n" by auto |
|
30 from someI_ex[OF this] show "prime (aprimedivisor n)" "aprimedivisor n dvd n" |
|
31 unfolding aprimedivisor_def by (simp_all add: conj_commute) |
|
32 qed |
|
33 |
|
34 lemma |
|
35 assumes "n \<noteq> 0" "\<not>is_unit (n :: 'a :: factorial_semiring)" |
|
36 shows prime_aprimedivisor': "prime (aprimedivisor n)" |
|
37 and aprimedivisor_dvd': "aprimedivisor n dvd n" |
|
38 proof - |
|
39 from someI_ex[OF prime_divisor_exists[OF assms]] |
|
40 show "prime (aprimedivisor n)" "aprimedivisor n dvd n" |
|
41 unfolding aprimedivisor_def by (simp_all add: conj_commute) |
|
42 qed |
|
43 |
|
44 lemma aprimedivisor_of_prime [simp]: |
|
45 assumes "prime p" |
|
46 shows "aprimedivisor p = p" |
|
47 proof - |
|
48 from assms have "\<exists>q. prime q \<and> q dvd p" by auto |
|
49 from someI_ex[OF this, folded aprimedivisor_def] assms show ?thesis |
|
50 by (auto intro: primes_dvd_imp_eq) |
|
51 qed |
|
52 |
|
53 lemma aprimedivisor_pos_nat: "(n::nat) > 1 \<Longrightarrow> aprimedivisor n > 0" |
|
54 using aprimedivisor_dvd'[of n] by (auto elim: dvdE intro!: Nat.gr0I) |
|
55 |
|
56 lemma aprimedivisor_primepow_power: |
|
57 assumes "primepow n" "k > 0" |
|
58 shows "aprimedivisor (n ^ k) = aprimedivisor n" |
|
59 proof - |
|
60 from assms obtain p l where l: "prime p" "l > 0" "n = p ^ l" |
|
61 by (auto simp: primepow_def) |
|
62 from l assms have *: "prime (aprimedivisor (n ^ k))" "aprimedivisor (n ^ k) dvd n ^ k" |
|
63 by (intro prime_aprimedivisor[of p] aprimedivisor_dvd[of p] dvd_power; |
|
64 simp add: power_mult [symmetric])+ |
|
65 from * l have "aprimedivisor (n ^ k) dvd p ^ (l * k)" by (simp add: power_mult) |
|
66 with assms * l have "aprimedivisor (n ^ k) dvd p" |
|
67 by (subst (asm) prime_dvd_power_iff) simp_all |
|
68 with l assms have "aprimedivisor (n ^ k) = p" |
|
69 by (intro primes_dvd_imp_eq prime_aprimedivisor l) (auto simp: power_mult [symmetric]) |
|
70 moreover from l have "aprimedivisor n dvd p ^ l" |
|
71 by (auto intro: aprimedivisor_dvd simp: prime_gt_0_nat) |
|
72 with assms l have "aprimedivisor n dvd p" |
|
73 by (subst (asm) prime_dvd_power_iff) (auto intro!: prime_aprimedivisor simp: prime_gt_0_nat) |
|
74 with l assms have "aprimedivisor n = p" |
|
75 by (intro primes_dvd_imp_eq prime_aprimedivisor l) auto |
|
76 ultimately show ?thesis by simp |
|
77 qed |
|
78 |
|
79 lemma aprimedivisor_prime_power: |
|
80 assumes "prime p" "k > 0" |
|
81 shows "aprimedivisor (p ^ k) = p" |
|
82 proof - |
|
83 from assms have *: "prime (aprimedivisor (p ^ k))" "aprimedivisor (p ^ k) dvd p ^ k" |
|
84 by (intro prime_aprimedivisor[of p] aprimedivisor_dvd[of p]; simp add: prime_nat_iff)+ |
|
85 from assms * have "aprimedivisor (p ^ k) dvd p" |
|
86 by (subst (asm) prime_dvd_power_iff) simp_all |
|
87 with assms * show "aprimedivisor (p ^ k) = p" by (intro primes_dvd_imp_eq) |
|
88 qed |
|
89 |
|
90 lemma prime_factorization_primepow: |
|
91 assumes "primepow n" |
|
92 shows "prime_factorization n = |
|
93 replicate_mset (multiplicity (aprimedivisor n) n) (aprimedivisor n)" |
|
94 using assms |
|
95 by (auto simp: primepow_def aprimedivisor_prime_power prime_factorization_prime_power) |
|
96 |
|
97 lemma primepow_decompose: |
|
98 assumes "primepow n" |
|
99 shows "aprimedivisor n ^ multiplicity (aprimedivisor n) n = n" |
|
100 proof - |
|
101 from assms have "n \<noteq> 0" by (intro notI) (auto simp: primepow_def) |
|
102 hence "n = unit_factor n * prod_mset (prime_factorization n)" |
|
103 by (subst prod_mset_prime_factorization) simp_all |
|
104 also from assms have "unit_factor n = 1" by (auto simp: primepow_def unit_factor_power) |
|
105 also have "prime_factorization n = |
|
106 replicate_mset (multiplicity (aprimedivisor n) n) (aprimedivisor n)" |
|
107 by (intro prime_factorization_primepow assms) |
|
108 also have "prod_mset \<dots> = aprimedivisor n ^ multiplicity (aprimedivisor n) n" by simp |
|
109 finally show ?thesis by simp |
|
110 qed |
|
111 |
|
112 lemma prime_power_not_one: |
|
113 assumes "prime p" "k > 0" |
|
114 shows "p ^ k \<noteq> 1" |
|
115 proof |
|
116 assume "p ^ k = 1" |
|
117 hence "is_unit (p ^ k)" by simp |
|
118 thus False using assms by (simp add: is_unit_power_iff) |
|
119 qed |
|
120 |
|
121 lemma zero_not_primepow [simp]: "\<not>primepow 0" |
|
122 by (auto simp: primepow_def) |
|
123 |
|
124 lemma one_not_primepow [simp]: "\<not>primepow 1" |
|
125 by (auto simp: primepow_def prime_power_not_one) |
|
126 |
|
127 lemma primepow_not_unit [simp]: "primepow p \<Longrightarrow> \<not>is_unit p" |
|
128 by (auto simp: primepow_def is_unit_power_iff) |
|
129 |
|
130 lemma unit_factor_primepow: "primepow p \<Longrightarrow> unit_factor p = 1" |
|
131 by (auto simp: primepow_def unit_factor_power) |
|
132 |
|
133 lemma aprimedivisor_primepow: |
|
134 assumes "prime p" "p dvd n" "primepow (n :: 'a :: factorial_semiring)" |
|
135 shows "aprimedivisor (p * n) = p" "aprimedivisor n = p" |
|
136 proof - |
|
137 from assms have [simp]: "n \<noteq> 0" by auto |
|
138 define q where "q = aprimedivisor n" |
|
139 with assms have q: "prime q" by (auto simp: q_def intro!: prime_aprimedivisor) |
|
140 from \<open>primepow n\<close> have n: "n = q ^ multiplicity q n" |
|
141 by (simp add: primepow_decompose q_def) |
|
142 have nz: "multiplicity q n \<noteq> 0" |
|
143 proof |
|
144 assume "multiplicity q n = 0" |
|
145 with n have n': "n = unit_factor n" by simp |
|
146 have "is_unit n" by (subst n', rule unit_factor_is_unit) (insert assms, auto) |
|
147 with assms show False by auto |
|
148 qed |
|
149 with \<open>prime p\<close> \<open>p dvd n\<close> q have "p dvd q" |
|
150 by (subst (asm) n) (auto intro: prime_dvd_power) |
|
151 with \<open>prime p\<close> q have "p = q" by (intro primes_dvd_imp_eq) |
|
152 thus "aprimedivisor n = p" by (simp add: q_def) |
|
153 |
|
154 define r where "r = aprimedivisor (p * n)" |
|
155 with assms have r: "r dvd (p * n)" "prime r" unfolding r_def |
|
156 by (intro aprimedivisor_dvd[of p] prime_aprimedivisor[of p]; simp)+ |
|
157 hence "r dvd q ^ Suc (multiplicity q n)" |
|
158 by (subst (asm) n) (auto simp: \<open>p = q\<close> dest: dvd_unit_imp_unit) |
|
159 with r have "r dvd q" |
|
160 by (auto intro: prime_dvd_power_nat simp: prime_dvd_mult_iff dest: prime_dvd_power) |
|
161 with r q have "r = q" by (intro primes_dvd_imp_eq) |
|
162 thus "aprimedivisor (p * n) = p" by (simp add: r_def \<open>p = q\<close>) |
|
163 qed |
|
164 |
|
165 lemma power_eq_prime_powerD: |
|
166 fixes p :: "'a :: factorial_semiring" |
|
167 assumes "prime p" "n > 0" "x ^ n = p ^ k" |
|
168 shows "\<exists>i. normalize x = normalize (p ^ i)" |
|
169 proof - |
|
170 have "normalize x = normalize (p ^ multiplicity p x)" |
|
171 proof (rule multiplicity_eq_imp_eq) |
|
172 fix q :: 'a assume "prime q" |
|
173 from assms have "multiplicity q (x ^ n) = multiplicity q (p ^ k)" by simp |
|
174 with \<open>prime q\<close> and assms have "n * multiplicity q x = k * multiplicity q p" |
|
175 by (subst (asm) (1 2) prime_elem_multiplicity_power_distrib) (auto simp: power_0_left) |
|
176 with assms and \<open>prime q\<close> show "multiplicity q x = multiplicity q (p ^ multiplicity p x)" |
|
177 by (cases "p = q") (auto simp: multiplicity_distinct_prime_power prime_multiplicity_other) |
|
178 qed (insert assms, auto simp: power_0_left) |
|
179 thus ?thesis by auto |
|
180 qed |
|
181 |
|
182 |
|
183 lemma primepow_power_iff: |
|
184 assumes "unit_factor p = 1" |
|
185 shows "primepow (p ^ n) \<longleftrightarrow> primepow (p :: 'a :: factorial_semiring) \<and> n > 0" |
|
186 proof safe |
|
187 assume "primepow (p ^ n)" |
|
188 hence n: "n \<noteq> 0" by (auto intro!: Nat.gr0I) |
|
189 thus "n > 0" by simp |
|
190 from assms have [simp]: "normalize p = p" |
|
191 using normalize_mult_unit_factor[of p] by (simp only: mult.right_neutral) |
|
192 from \<open>primepow (p ^ n)\<close> obtain q k where *: "k > 0" "prime q" "p ^ n = q ^ k" |
|
193 by (auto simp: primepow_def) |
|
194 with power_eq_prime_powerD[of q n p k] n |
|
195 obtain i where eq: "normalize p = normalize (q ^ i)" by auto |
|
196 with primepow_not_unit[OF \<open>primepow (p ^ n)\<close>] have "i \<noteq> 0" |
|
197 by (intro notI) (simp add: normalize_1_iff is_unit_power_iff del: primepow_not_unit) |
|
198 with \<open>normalize p = normalize (q ^ i)\<close> \<open>prime q\<close> show "primepow p" |
|
199 by (auto simp: normalize_power primepow_def intro!: exI[of _ q] exI[of _ i]) |
|
200 next |
|
201 assume "primepow p" "n > 0" |
|
202 then obtain q k where *: "k > 0" "prime q" "p = q ^ k" by (auto simp: primepow_def) |
|
203 with \<open>n > 0\<close> show "primepow (p ^ n)" |
|
204 by (auto simp: primepow_def power_mult intro!: exI[of _ q] exI[of _ "k * n"]) |
|
205 qed |
|
206 |
|
207 lemma primepow_prime [simp]: "prime n \<Longrightarrow> primepow n" |
|
208 by (auto simp: primepow_def intro!: exI[of _ n] exI[of _ "1::nat"]) |
|
209 |
|
210 lemma primepow_prime_power [simp]: |
|
211 "prime (p :: 'a :: factorial_semiring) \<Longrightarrow> primepow (p ^ n) \<longleftrightarrow> n > 0" |
|
212 by (subst primepow_power_iff) auto |
|
213 |
|
214 (* TODO Generalise *) |
|
215 lemma primepow_multD: |
|
216 assumes "primepow (a * b :: nat)" |
|
217 shows "a = 1 \<or> primepow a" "b = 1 \<or> primepow b" |
|
218 proof - |
|
219 from assms obtain p k where k: "k > 0" "a * b = p ^ k" "prime p" |
|
220 unfolding primepow_def by auto |
|
221 then obtain i j where "a = p ^ i" "b = p ^ j" |
|
222 using prime_power_mult_nat[of p a b] by blast |
|
223 with \<open>prime p\<close> show "a = 1 \<or> primepow a" "b = 1 \<or> primepow b" by auto |
|
224 qed |
|
225 |
|
226 lemma primepow_mult_aprimedivisorI: |
|
227 assumes "primepow (n :: 'a :: factorial_semiring)" |
|
228 shows "primepow (aprimedivisor n * n)" |
|
229 by (subst (2) primepow_decompose[OF assms, symmetric], subst power_Suc [symmetric], |
|
230 subst primepow_prime_power) |
|
231 (insert assms, auto intro!: prime_aprimedivisor' dest: primepow_gt_Suc_0) |
|
232 |
|
233 lemma aprimedivisor_vimage: |
|
234 assumes "prime (p :: 'a :: factorial_semiring)" |
|
235 shows "aprimedivisor -` {p} \<inter> primepow_factors n = {p ^ k |k. k > 0 \<and> p ^ k dvd n}" |
|
236 proof safe |
|
237 fix q assume q: "q \<in> primepow_factors n" |
|
238 hence q': "q \<noteq> 0" "q \<noteq> 1" by (auto simp: primepow_def primepow_factors_def prime_power_not_one) |
|
239 let ?n = "multiplicity (aprimedivisor q) q" |
|
240 from q q' have "q = aprimedivisor q ^ ?n \<and> ?n > 0 \<and> aprimedivisor q ^ ?n dvd n" |
|
241 using prime_aprimedivisor'[of q] aprimedivisor_dvd'[of q] |
|
242 by (subst primepow_decompose [symmetric]) |
|
243 (auto simp: primepow_factors_def multiplicity_gt_zero_iff unit_factor_primepow |
|
244 intro: dvd_trans[OF multiplicity_dvd]) |
|
245 thus "\<exists>k. q = aprimedivisor q ^ k \<and> k > 0 \<and> aprimedivisor q ^ k dvd n" .. |
|
246 next |
|
247 fix k :: nat assume k: "p ^ k dvd n" "k > 0" |
|
248 with assms show "p ^ k \<in> aprimedivisor -` {p}" |
|
249 by (auto simp: aprimedivisor_prime_power) |
|
250 with assms k show "p ^ k \<in> primepow_factors n" |
|
251 by (auto simp: primepow_factors_def primepow_def aprimedivisor_prime_power intro: Suc_leI) |
|
252 qed |
|
253 |
|
254 lemma primepow_factors_altdef: |
|
255 fixes x :: "'a :: factorial_semiring" |
|
256 assumes "x \<noteq> 0" |
|
257 shows "primepow_factors x = {p ^ k |p k. p \<in> prime_factors x \<and> k \<in> {0<.. multiplicity p x}}" |
|
258 proof (intro equalityI subsetI) |
|
259 fix q assume "q \<in> primepow_factors x" |
|
260 then obtain p k where pk: "prime p" "k > 0" "q = p ^ k" "q dvd x" |
|
261 unfolding primepow_factors_def primepow_def by blast |
|
262 moreover have "k \<le> multiplicity p x" using pk assms by (intro multiplicity_geI) auto |
|
263 ultimately show "q \<in> {p ^ k |p k. p \<in> prime_factors x \<and> k \<in> {0<.. multiplicity p x}}" |
|
264 by (auto simp: prime_factors_multiplicity intro!: exI[of _ p] exI[of _ k]) |
|
265 qed (auto simp: primepow_factors_def prime_factors_multiplicity multiplicity_dvd') |
|
266 |
|
267 lemma finite_primepow_factors: |
|
268 assumes "x \<noteq> (0 :: 'a :: factorial_semiring)" |
|
269 shows "finite (primepow_factors x)" |
|
270 proof - |
|
271 have "finite (SIGMA p:prime_factors x. {0<..multiplicity p x})" |
|
272 by (intro finite_SigmaI) simp_all |
|
273 hence "finite ((\<lambda>(p,k). p ^ k) ` \<dots>)" (is "finite ?A") by (rule finite_imageI) |
|
274 also have "?A = primepow_factors x" |
|
275 using assms by (subst primepow_factors_altdef) fast+ |
|
276 finally show ?thesis . |
|
277 qed |
|
278 |
|
279 |
|
280 definition mangoldt :: "nat \<Rightarrow> 'a :: real_algebra_1" where |
|
281 "mangoldt n = (if primepow n then of_real (ln (real (aprimedivisor n))) else 0)" |
|
282 |
|
283 lemma of_real_mangoldt [simp]: "of_real (mangoldt n) = mangoldt n" |
|
284 by (simp add: mangoldt_def) |
|
285 |
|
286 lemma mangoldt_sum: |
|
287 assumes "n \<noteq> 0" |
|
288 shows "(\<Sum>d | d dvd n. mangoldt d :: 'a :: real_algebra_1) = of_real (ln (real n))" |
|
289 proof - |
|
290 have "(\<Sum>d | d dvd n. mangoldt d :: 'a) = of_real (\<Sum>d | d dvd n. mangoldt d)" by simp |
|
291 also have "(\<Sum>d | d dvd n. mangoldt d) = (\<Sum>d \<in> primepow_factors n. ln (real (aprimedivisor d)))" |
|
292 using assms by (intro sum.mono_neutral_cong_right) (auto simp: primepow_factors_def mangoldt_def) |
|
293 also have "\<dots> = ln (real (\<Prod>d \<in> primepow_factors n. aprimedivisor d))" |
|
294 using assms finite_primepow_factors[of n] |
|
295 by (subst ln_prod [symmetric]) |
|
296 (auto simp: primepow_factors_def intro!: aprimedivisor_pos_nat |
|
297 intro: Nat.gr0I primepow_gt_Suc_0) |
|
298 also have "primepow_factors n = |
|
299 (\<lambda>(p,k). p ^ k) ` (SIGMA p:prime_factors n. {0<..multiplicity p n})" |
|
300 (is "_ = _ ` ?A") by (subst primepow_factors_altdef[OF assms]) fast+ |
|
301 also have "prod aprimedivisor \<dots> = (\<Prod>(p,k)\<in>?A. aprimedivisor (p ^ k))" |
|
302 by (subst prod.reindex) |
|
303 (auto simp: inj_on_def prime_power_inj'' prime_factors_multiplicity |
|
304 prod.Sigma [symmetric] case_prod_unfold) |
|
305 also have "\<dots> = (\<Prod>(p,k)\<in>?A. p)" |
|
306 by (intro prod.cong refl) (auto simp: aprimedivisor_prime_power prime_factors_multiplicity) |
|
307 also have "\<dots> = (\<Prod>x\<in>prime_factors n. \<Prod>k\<in>{0<..multiplicity x n}. x)" |
|
308 by (rule prod.Sigma [symmetric]) auto |
|
309 also have "\<dots> = (\<Prod>x\<in>prime_factors n. x ^ multiplicity x n)" |
|
310 by (intro prod.cong refl) (simp add: prod_constant) |
|
311 also have "\<dots> = n" using assms by (intro prime_factorization_nat [symmetric]) simp |
|
312 finally show ?thesis . |
|
313 qed |
|
314 |
|
315 end |