20 assumes pk: "p*k dvd m*n" and p: "prime p" |
20 assumes pk: "p*k dvd m*n" and p: "prime p" |
21 shows "(\<exists>x. k dvd x*n \<and> m = p*x) \<or> (\<exists>y. k dvd m*y \<and> n = p*y)" |
21 shows "(\<exists>x. k dvd x*n \<and> m = p*x) \<or> (\<exists>y. k dvd m*y \<and> n = p*y)" |
22 proof - |
22 proof - |
23 have "p dvd m*n" using dvd_mult_left pk by blast |
23 have "p dvd m*n" using dvd_mult_left pk by blast |
24 then consider "p dvd m" | "p dvd n" |
24 then consider "p dvd m" | "p dvd n" |
25 using p prime_dvd_mult_eq_nat by blast |
25 using p is_prime_dvd_mult_iff by blast |
26 then show ?thesis |
26 then show ?thesis |
27 proof cases |
27 proof cases |
28 case 1 then obtain a where "m = p * a" by (metis dvd_mult_div_cancel) |
28 case 1 then obtain a where "m = p * a" by (metis dvd_mult_div_cancel) |
29 then have "\<exists>x. k dvd x * n \<and> m = p * x" |
29 then have "\<exists>x. k dvd x * n \<and> m = p * x" |
30 using p pk by auto |
30 using p pk by (auto simp: mult.assoc) |
31 then show ?thesis .. |
31 then show ?thesis .. |
32 next |
32 next |
33 case 2 then obtain b where "n = p * b" by (metis dvd_mult_div_cancel) |
33 case 2 then obtain b where "n = p * b" by (metis dvd_mult_div_cancel) |
34 then have "\<exists>y. k dvd m*y \<and> n = p*y" |
34 with p pk have "\<exists>y. k dvd m*y \<and> n = p*y" |
35 using p pk by auto |
35 by (metis dvd_mult_right dvd_times_left_cancel_iff mult.left_commute mult_zero_left) |
36 then show ?thesis .. |
36 then show ?thesis .. |
37 qed |
37 qed |
38 qed |
38 qed |
39 |
39 |
40 lemma prime_power_dvd_prod: |
40 lemma prime_power_dvd_prod: |
48 consider x where "p^c dvd x*n" "m = p*x" | y where "p^c dvd m*y" "n = p*y" |
48 consider x where "p^c dvd x*n" "m = p*x" | y where "p^c dvd m*y" "n = p*y" |
49 using prime_dvd_cases [of _ "p^c", OF _ p] Suc.prems by force |
49 using prime_dvd_cases [of _ "p^c", OF _ p] Suc.prems by force |
50 then show ?case |
50 then show ?case |
51 proof cases |
51 proof cases |
52 case (1 x) |
52 case (1 x) |
53 with Suc.hyps [of x n] show "\<exists>a b. a + b = Suc c \<and> p ^ a dvd m \<and> p ^ b dvd n" |
53 with Suc.hyps[of x n] obtain a b where "a + b = c \<and> p ^ a dvd x \<and> p ^ b dvd n" by blast |
54 by force |
54 with 1 have "Suc a + b = Suc c \<and> p ^ Suc a dvd m \<and> p ^ b dvd n" |
|
55 by (auto intro: mult_dvd_mono) |
|
56 thus ?thesis by blast |
55 next |
57 next |
56 case (2 y) |
58 case (2 y) |
57 with Suc.hyps [of m y] show "\<exists>a b. a + b = Suc c \<and> p ^ a dvd m \<and> p ^ b dvd n" |
59 with Suc.hyps[of m y] obtain a b where "a + b = c \<and> p ^ a dvd m \<and> p ^ b dvd y" by blast |
|
60 with 2 have "a + Suc b = Suc c \<and> p ^ a dvd m \<and> p ^ Suc b dvd n" |
|
61 by (auto intro: mult_dvd_mono) |
|
62 with Suc.hyps [of m y] show "\<exists>a b. a + b = Suc c \<and> p ^ a dvd m \<and> p ^ b dvd n" |
58 by force |
63 by force |
59 qed |
64 qed |
60 qed |
65 qed |
61 |
66 |
62 lemma add_eq_Suc_lem: "a+b = Suc (x+y) \<Longrightarrow> a \<le> x \<or> b \<le> y" |
67 lemma add_eq_Suc_lem: "a+b = Suc (x+y) \<Longrightarrow> a \<le> x \<or> b \<le> y" |
71 by (metis add_Suc_right mult.commute prime_power_dvd_cases) |
76 by (metis add_Suc_right mult.commute prime_power_dvd_cases) |
72 |
77 |
73 |
78 |
74 subsection\<open>The Exponent Function\<close> |
79 subsection\<open>The Exponent Function\<close> |
75 |
80 |
|
81 abbreviation (input) "exponent \<equiv> multiplicity" |
|
82 |
|
83 (* |
76 definition |
84 definition |
77 exponent :: "nat => nat => nat" |
85 exponent :: "nat => nat => nat" |
78 where "exponent p s = (if prime p then (GREATEST r. p^r dvd s) else 0)" |
86 where "exponent p s = (if prime p then (GREATEST r. p^r dvd s) else 0)" |
79 |
87 *) |
80 lemma exponent_eq_0 [simp]: "\<not> prime p \<Longrightarrow> exponent p s = 0" |
88 |
81 by (simp add: exponent_def) |
89 (*lemma exponent_eq_0 [simp]: "\<not> prime p \<Longrightarrow> exponent p s = 0" |
|
90 by (simp add: exponent_def)*) |
82 |
91 |
83 lemma Suc_le_power: "Suc 0 < p \<Longrightarrow> Suc n \<le> p ^ n" |
92 lemma Suc_le_power: "Suc 0 < p \<Longrightarrow> Suc n \<le> p ^ n" |
84 by (induct n) (auto simp: Suc_le_eq le_less_trans) |
93 by (induct n) (auto simp: Suc_le_eq le_less_trans) |
85 |
94 |
|
95 (* |
86 text\<open>An upper bound for the @{term n} such that @{term"p^n dvd a"}: needed for GREATEST to exist\<close> |
96 text\<open>An upper bound for the @{term n} such that @{term"p^n dvd a"}: needed for GREATEST to exist\<close> |
87 lemma power_dvd_bound: "\<lbrakk>p ^ n dvd a; Suc 0 < p; 0 < a\<rbrakk> \<Longrightarrow> n < a" |
97 lemma power_dvd_bound: "\<lbrakk>p ^ n dvd a; Suc 0 < p; 0 < a\<rbrakk> \<Longrightarrow> n < a" |
88 by (meson Suc_le_lessD Suc_le_power dvd_imp_le le_trans) |
98 by (meson Suc_le_lessD Suc_le_power dvd_imp_le le_trans) |
89 |
99 *) |
|
100 |
|
101 (* |
90 lemma exponent_ge: |
102 lemma exponent_ge: |
91 assumes "p ^ k dvd n" "prime p" "0 < n" |
103 assumes "p ^ k dvd n" "prime p" "0 < n" |
92 shows "k \<le> exponent p n" |
104 shows "k \<le> exponent p n" |
93 proof - |
105 proof - |
94 have "Suc 0 < p" |
106 have "Suc 0 < p" |
95 using \<open>prime p\<close> by (simp add: prime_def) |
107 using \<open>prime p\<close> by (simp add: prime_def) |
96 with assms show ?thesis |
108 with assms show ?thesis |
97 by (simp add: \<open>prime p\<close> exponent_def) (meson Greatest_le power_dvd_bound) |
109 by (simp add: \<open>prime p\<close> exponent_def) (meson Greatest_le power_dvd_bound) |
98 qed |
110 qed |
99 |
111 *) |
|
112 |
|
113 (* |
100 lemma power_exponent_dvd: "p ^ exponent p s dvd s" |
114 lemma power_exponent_dvd: "p ^ exponent p s dvd s" |
101 proof (cases "s = 0") |
115 proof (cases "s = 0") |
102 case True then show ?thesis by simp |
116 case True then show ?thesis by simp |
103 next |
117 next |
104 case False then show ?thesis |
118 case False then show ?thesis |
105 apply (simp add: exponent_def, clarify) |
119 apply (simp add: exponent_def, clarify) |
106 apply (rule GreatestI [where k = 0]) |
120 apply (rule GreatestI [where k = 0]) |
107 apply (auto dest: prime_gt_Suc_0_nat power_dvd_bound) |
121 apply (auto dest: prime_gt_Suc_0_nat power_dvd_bound) |
108 done |
122 done |
109 qed |
123 qed |
110 |
124 *) |
111 lemma power_Suc_exponent_Not_dvd: |
125 |
|
126 (*lemma power_Suc_exponent_Not_dvd: |
112 "\<lbrakk>p * p ^ exponent p s dvd s; prime p\<rbrakk> \<Longrightarrow> s = 0" |
127 "\<lbrakk>p * p ^ exponent p s dvd s; prime p\<rbrakk> \<Longrightarrow> s = 0" |
113 by (metis exponent_ge neq0_conv not_less_eq_eq order_refl power_Suc) |
128 by (metis exponent_ge neq0_conv not_less_eq_eq order_refl power_Suc) |
114 |
129 *) |
|
130 |
|
131 |
|
132 (* |
115 lemma exponent_power_eq [simp]: "prime p \<Longrightarrow> exponent p (p ^ a) = a" |
133 lemma exponent_power_eq [simp]: "prime p \<Longrightarrow> exponent p (p ^ a) = a" |
116 apply (simp add: exponent_def) |
134 apply (simp add: exponent_def) |
117 apply (rule Greatest_equality, simp) |
135 apply (rule Greatest_equality, simp) |
118 apply (simp add: prime_gt_Suc_0_nat power_dvd_imp_le) |
136 apply (simp add: prime_gt_Suc_0_nat power_dvd_imp_le) |
119 done |
137 done |
120 |
138 *) |
|
139 |
|
140 (* |
121 lemma exponent_1_eq_0 [simp]: "exponent p (Suc 0) = 0" |
141 lemma exponent_1_eq_0 [simp]: "exponent p (Suc 0) = 0" |
122 apply (case_tac "prime p") |
142 apply (case_tac "prime p") |
123 apply (metis exponent_power_eq nat_power_eq_Suc_0_iff) |
143 apply (metis exponent_power_eq nat_power_eq_Suc_0_iff) |
124 apply simp |
144 apply simp |
125 done |
145 done |
|
146 *) |
126 |
147 |
127 lemma exponent_equalityI: |
148 lemma exponent_equalityI: |
128 "(\<And>r. p ^ r dvd a \<longleftrightarrow> p ^ r dvd b) \<Longrightarrow> exponent p a = exponent p b" |
149 "(\<And>r. p ^ r dvd a \<longleftrightarrow> p ^ r dvd b) \<Longrightarrow> exponent p a = exponent p b" |
129 by (simp add: exponent_def) |
150 by (simp add: multiplicity_def) |
130 |
151 |
|
152 (* |
131 lemma exponent_mult_add: |
153 lemma exponent_mult_add: |
132 assumes "a > 0" "b > 0" |
154 assumes "a > 0" "b > 0" |
133 shows "exponent p (a * b) = (exponent p a) + (exponent p b)" |
155 shows "exponent p (a * b) = (exponent p a) + (exponent p b)" |
134 proof (cases "prime p") |
156 proof (cases "prime p") |
135 case False then show ?thesis by simp |
157 case False then show ?thesis by simp |
147 by (metis Suc_n_not_le_n True add_Suc add_Suc_right assms exponent_ge) |
169 by (metis Suc_n_not_le_n True add_Suc add_Suc_right assms exponent_ge) |
148 } |
170 } |
149 then show "exponent p (a * b) \<le> exponent p a + exponent p b" by (blast intro: leI) |
171 then show "exponent p (a * b) \<le> exponent p a + exponent p b" by (blast intro: leI) |
150 qed |
172 qed |
151 qed |
173 qed |
152 |
174 *) |
153 lemma not_divides_exponent_0: "~ (p dvd n) \<Longrightarrow> exponent p n = 0" |
175 |
154 apply (case_tac "exponent p n", simp) |
176 lemma not_dvd_imp_multiplicity_0: |
155 by (metis dvd_mult_left power_Suc power_exponent_dvd) |
177 assumes "\<not>p dvd x" |
|
178 shows "multiplicity p x = 0" |
|
179 proof - |
|
180 from assms have "multiplicity p x < 1" |
|
181 by (intro multiplicity_lessI) auto |
|
182 thus ?thesis by simp |
|
183 qed |
156 |
184 |
157 |
185 |
158 subsection\<open>The Main Combinatorial Argument\<close> |
186 subsection\<open>The Main Combinatorial Argument\<close> |
159 |
187 |
160 lemma exponent_p_a_m_k_equation: |
188 lemma exponent_p_a_m_k_equation: |
|
189 fixes p :: nat |
161 assumes "0 < m" "0 < k" "p \<noteq> 0" "k < p^a" |
190 assumes "0 < m" "0 < k" "p \<noteq> 0" "k < p^a" |
162 shows "exponent p (p^a * m - k) = exponent p (p^a - k)" |
191 shows "exponent p (p^a * m - k) = exponent p (p^a - k)" |
163 proof (rule exponent_equalityI [OF iffI]) |
192 proof (rule exponent_equalityI [OF iffI]) |
164 fix r |
193 fix r |
165 assume *: "p ^ r dvd p ^ a * m - k" |
194 assume *: "p ^ r dvd p ^ a * m - k" |
186 by (meson assms * dvd_diffD1 dvd_diff_nat le_imp_power_dvd less_imp_le_nat \<open>r \<le> a\<close>) |
215 by (meson assms * dvd_diffD1 dvd_diff_nat le_imp_power_dvd less_imp_le_nat \<open>r \<le> a\<close>) |
187 qed |
216 qed |
188 qed |
217 qed |
189 |
218 |
190 lemma p_not_div_choose_lemma: |
219 lemma p_not_div_choose_lemma: |
|
220 fixes p :: nat |
191 assumes eeq: "\<And>i. Suc i < K \<Longrightarrow> exponent p (Suc i) = exponent p (Suc (j + i))" |
221 assumes eeq: "\<And>i. Suc i < K \<Longrightarrow> exponent p (Suc i) = exponent p (Suc (j + i))" |
192 and "k < K" |
222 and "k < K" and p: "prime p" |
193 shows "exponent p (j + k choose k) = 0" |
223 shows "exponent p (j + k choose k) = 0" |
194 proof (cases "prime p") |
224 using \<open>k < K\<close> |
195 case False then show ?thesis by simp |
225 proof (induction k) |
196 next |
226 case 0 then show ?case by simp |
197 case True show ?thesis using \<open>k < K\<close> |
227 next |
198 proof (induction k) |
228 case (Suc k) |
199 case 0 then show ?case by simp |
229 then have *: "(Suc (j+k) choose Suc k) > 0" by simp |
200 next |
230 then have "exponent p ((Suc (j+k) choose Suc k) * Suc k) = exponent p (Suc k)" |
201 case (Suc k) |
231 by (subst Suc_times_binomial_eq [symmetric], subst prime_multiplicity_mult_distrib) |
202 then have *: "(Suc (j+k) choose Suc k) > 0" by simp |
232 (insert p Suc.prems, simp_all add: eeq [symmetric] Suc.IH) |
203 then have "exponent p ((Suc (j+k) choose Suc k) * Suc k) = exponent p (Suc k)" |
233 with p * show ?case |
204 by (metis Suc.IH Suc.prems Suc_lessD Suc_times_binomial_eq add.comm_neutral eeq exponent_mult_add |
234 by (subst (asm) prime_multiplicity_mult_distrib) simp_all |
205 mult_pos_pos zero_less_Suc zero_less_mult_pos) |
|
206 then show ?case |
|
207 by (metis * add.commute add_Suc_right add_eq_self_zero exponent_mult_add zero_less_Suc) |
|
208 qed |
|
209 qed |
235 qed |
210 |
236 |
211 text\<open>The lemma above, with two changes of variables\<close> |
237 text\<open>The lemma above, with two changes of variables\<close> |
212 lemma p_not_div_choose: |
238 lemma p_not_div_choose: |
213 assumes "k < K" and "k \<le> n" |
239 assumes "k < K" and "k \<le> n" |
214 and eeq: "\<And>j. \<lbrakk>0<j; j<K\<rbrakk> \<Longrightarrow> exponent p (n - k + (K - j)) = exponent p (K - j)" |
240 and eeq: "\<And>j. \<lbrakk>0<j; j<K\<rbrakk> \<Longrightarrow> exponent p (n - k + (K - j)) = exponent p (K - j)" "is_prime p" |
215 shows "exponent p (n choose k) = 0" |
241 shows "exponent p (n choose k) = 0" |
216 apply (rule p_not_div_choose_lemma [of K p "n-k" k, simplified assms nat_minus_add_max max_absorb1]) |
242 apply (rule p_not_div_choose_lemma [of K p "n-k" k, simplified assms nat_minus_add_max max_absorb1]) |
217 apply (metis add_Suc_right eeq diff_diff_cancel order_less_imp_le zero_less_Suc zero_less_diff) |
243 apply (metis add_Suc_right eeq diff_diff_cancel order_less_imp_le zero_less_Suc zero_less_diff) |
218 apply (rule TrueI) |
244 apply (rule TrueI)+ |
219 done |
245 done |
220 |
246 |
221 proposition const_p_fac: |
247 proposition const_p_fac: |
222 assumes "m>0" |
248 assumes "m>0" and prime: "is_prime p" |
223 shows "exponent p (p^a * m choose p^a) = exponent p m" |
249 shows "exponent p (p^a * m choose p^a) = exponent p m" |
224 proof (cases "prime p") |
250 proof- |
225 case False then show ?thesis by auto |
251 from assms have p: "0 < p ^ a" "0 < p^a * m" "p^a \<le> p^a * m" |
226 next |
|
227 case True |
|
228 with assms have p: "0 < p ^ a" "0 < p^a * m" "p^a \<le> p^a * m" |
|
229 by (auto simp: prime_gt_0_nat) |
252 by (auto simp: prime_gt_0_nat) |
230 have *: "exponent p ((p^a * m - 1) choose (p^a - 1)) = 0" |
253 have *: "exponent p ((p^a * m - 1) choose (p^a - 1)) = 0" |
231 apply (rule p_not_div_choose [where K = "p^a"]) |
254 apply (rule p_not_div_choose [where K = "p^a"]) |
232 using p exponent_p_a_m_k_equation by (auto simp: diff_le_mono) |
255 using p exponent_p_a_m_k_equation by (auto simp: diff_le_mono prime) |
233 have "exponent p ((p ^ a * m choose p ^ a) * p ^ a) = a + exponent p m" |
256 have "exponent p ((p ^ a * m choose p ^ a) * p ^ a) = a + exponent p m" |
234 proof - |
257 proof - |
235 have "p ^ a * m * (p ^ a * m - 1 choose (p ^ a - 1)) = p ^ a * (p ^ a * m choose p ^ a)" |
258 have "(p ^ a * m choose p ^ a) * p ^ a = p ^ a * m * (p ^ a * m - 1 choose (p ^ a - 1))" |
236 using p One_nat_def times_binomial_minus1_eq by presburger |
259 (is "_ = ?rhs") using prime |
237 moreover have "exponent p (p ^ a) = a" |
260 by (subst times_binomial_minus1_eq [symmetric]) (auto simp: prime_gt_0_nat) |
238 by (meson True exponent_power_eq) |
261 also from p have "p ^ a - Suc 0 \<le> p ^ a * m - Suc 0" by linarith |
239 ultimately show ?thesis |
262 with prime * p have "multiplicity p ?rhs = multiplicity p (p ^ a * m)" |
240 using * p |
263 by (subst prime_multiplicity_mult_distrib) auto |
241 by (metis (no_types, lifting) One_nat_def exponent_1_eq_0 exponent_mult_add mult.commute mult.right_neutral nat_0_less_mult_iff zero_less_binomial) |
264 also have "\<dots> = a + multiplicity p m" |
|
265 using prime p by (subst prime_multiplicity_mult_distrib) simp_all |
|
266 finally show ?thesis . |
242 qed |
267 qed |
243 then show ?thesis |
268 then show ?thesis |
244 using True p exponent_mult_add by auto |
269 using prime p by (subst (asm) prime_multiplicity_mult_distrib) simp_all |
245 qed |
270 qed |
246 |
271 |
247 end |
272 end |