138 "all_prime (ps @ qs) \<longleftrightarrow> all_prime ps \<and> all_prime qs" |
138 "all_prime (ps @ qs) \<longleftrightarrow> all_prime ps \<and> all_prime qs" |
139 by (simp add: all_prime_def ball_Un) |
139 by (simp add: all_prime_def ball_Un) |
140 |
140 |
141 lemma split_all_prime: |
141 lemma split_all_prime: |
142 assumes "all_prime ms" and "all_prime ns" |
142 assumes "all_prime ms" and "all_prime ns" |
143 shows "\<exists>qs. all_prime qs \<and> (PROD m::nat:#mset qs. m) = |
143 shows "\<exists>qs. all_prime qs \<and> (\<Prod>m::nat \<in># mset qs. m) = |
144 (PROD m::nat:#mset ms. m) * (PROD m::nat:#mset ns. m)" (is "\<exists>qs. ?P qs \<and> ?Q qs") |
144 (\<Prod>m::nat \<in># mset ms. m) * (\<Prod>m::nat \<in># mset ns. m)" (is "\<exists>qs. ?P qs \<and> ?Q qs") |
145 proof - |
145 proof - |
146 from assms have "all_prime (ms @ ns)" |
146 from assms have "all_prime (ms @ ns)" |
147 by (simp add: all_prime_append) |
147 by (simp add: all_prime_append) |
148 moreover from assms have "(PROD m::nat:#mset (ms @ ns). m) = |
148 moreover from assms have "(\<Prod>m::nat \<in># mset (ms @ ns). m) = |
149 (PROD m::nat:#mset ms. m) * (PROD m::nat:#mset ns. m)" |
149 (\<Prod>m::nat \<in># mset ms. m) * (\<Prod>m::nat \<in># mset ns. m)" |
150 by (simp add: msetprod_Un) |
150 by (simp add: msetprod_Un) |
151 ultimately have "?P (ms @ ns) \<and> ?Q (ms @ ns)" .. |
151 ultimately have "?P (ms @ ns) \<and> ?Q (ms @ ns)" .. |
152 then show ?thesis .. |
152 then show ?thesis .. |
153 qed |
153 qed |
154 |
154 |
155 lemma all_prime_nempty_g_one: |
155 lemma all_prime_nempty_g_one: |
156 assumes "all_prime ps" and "ps \<noteq> []" |
156 assumes "all_prime ps" and "ps \<noteq> []" |
157 shows "Suc 0 < (PROD m::nat:#mset ps. m)" |
157 shows "Suc 0 < (\<Prod>m::nat \<in># mset ps. m)" |
158 using `ps \<noteq> []` `all_prime ps` unfolding One_nat_def [symmetric] by (induct ps rule: list_nonempty_induct) |
158 using `ps \<noteq> []` `all_prime ps` unfolding One_nat_def [symmetric] by (induct ps rule: list_nonempty_induct) |
159 (simp_all add: all_prime_simps msetprod_singleton msetprod_Un prime_gt_1_nat less_1_mult del: One_nat_def) |
159 (simp_all add: all_prime_simps msetprod_singleton msetprod_Un prime_gt_1_nat less_1_mult del: One_nat_def) |
160 |
160 |
161 lemma factor_exists: "Suc 0 < n \<Longrightarrow> (\<exists>ps. all_prime ps \<and> (PROD m::nat:#mset ps. m) = n)" |
161 lemma factor_exists: "Suc 0 < n \<Longrightarrow> (\<exists>ps. all_prime ps \<and> (\<Prod>m::nat \<in># mset ps. m) = n)" |
162 proof (induct n rule: nat_wf_ind) |
162 proof (induct n rule: nat_wf_ind) |
163 case (1 n) |
163 case (1 n) |
164 from `Suc 0 < n` |
164 from `Suc 0 < n` |
165 have "(\<exists>m k. Suc 0 < m \<and> Suc 0 < k \<and> m < n \<and> k < n \<and> n = m * k) \<or> prime n" |
165 have "(\<exists>m k. Suc 0 < m \<and> Suc 0 < k \<and> m < n \<and> k < n \<and> n = m * k) \<or> prime n" |
166 by (rule not_prime_ex_mk) |
166 by (rule not_prime_ex_mk) |
167 then show ?case |
167 then show ?case |
168 proof |
168 proof |
169 assume "\<exists>m k. Suc 0 < m \<and> Suc 0 < k \<and> m < n \<and> k < n \<and> n = m * k" |
169 assume "\<exists>m k. Suc 0 < m \<and> Suc 0 < k \<and> m < n \<and> k < n \<and> n = m * k" |
170 then obtain m k where m: "Suc 0 < m" and k: "Suc 0 < k" and mn: "m < n" |
170 then obtain m k where m: "Suc 0 < m" and k: "Suc 0 < k" and mn: "m < n" |
171 and kn: "k < n" and nmk: "n = m * k" by iprover |
171 and kn: "k < n" and nmk: "n = m * k" by iprover |
172 from mn and m have "\<exists>ps. all_prime ps \<and> (PROD m::nat:#mset ps. m) = m" by (rule 1) |
172 from mn and m have "\<exists>ps. all_prime ps \<and> (\<Prod>m::nat \<in># mset ps. m) = m" by (rule 1) |
173 then obtain ps1 where "all_prime ps1" and prod_ps1_m: "(PROD m::nat:#mset ps1. m) = m" |
173 then obtain ps1 where "all_prime ps1" and prod_ps1_m: "(\<Prod>m::nat \<in># mset ps1. m) = m" |
174 by iprover |
174 by iprover |
175 from kn and k have "\<exists>ps. all_prime ps \<and> (PROD m::nat:#mset ps. m) = k" by (rule 1) |
175 from kn and k have "\<exists>ps. all_prime ps \<and> (\<Prod>m::nat \<in># mset ps. m) = k" by (rule 1) |
176 then obtain ps2 where "all_prime ps2" and prod_ps2_k: "(PROD m::nat:#mset ps2. m) = k" |
176 then obtain ps2 where "all_prime ps2" and prod_ps2_k: "(\<Prod>m::nat \<in># mset ps2. m) = k" |
177 by iprover |
177 by iprover |
178 from `all_prime ps1` `all_prime ps2` |
178 from `all_prime ps1` `all_prime ps2` |
179 have "\<exists>ps. all_prime ps \<and> (PROD m::nat:#mset ps. m) = |
179 have "\<exists>ps. all_prime ps \<and> (\<Prod>m::nat \<in># mset ps. m) = |
180 (PROD m::nat:#mset ps1. m) * (PROD m::nat:#mset ps2. m)" |
180 (\<Prod>m::nat \<in># mset ps1. m) * (\<Prod>m::nat \<in># mset ps2. m)" |
181 by (rule split_all_prime) |
181 by (rule split_all_prime) |
182 with prod_ps1_m prod_ps2_k nmk show ?thesis by simp |
182 with prod_ps1_m prod_ps2_k nmk show ?thesis by simp |
183 next |
183 next |
184 assume "prime n" then have "all_prime [n]" by (simp add: all_prime_simps) |
184 assume "prime n" then have "all_prime [n]" by (simp add: all_prime_simps) |
185 moreover have "(PROD m::nat:#mset [n]. m) = n" by (simp add: msetprod_singleton) |
185 moreover have "(\<Prod>m::nat \<in># mset [n]. m) = n" by (simp add: msetprod_singleton) |
186 ultimately have "all_prime [n] \<and> (PROD m::nat:#mset [n]. m) = n" .. |
186 ultimately have "all_prime [n] \<and> (\<Prod>m::nat \<in># mset [n]. m) = n" .. |
187 then show ?thesis .. |
187 then show ?thesis .. |
188 qed |
188 qed |
189 qed |
189 qed |
190 |
190 |
191 lemma prime_factor_exists: |
191 lemma prime_factor_exists: |
192 assumes N: "(1::nat) < n" |
192 assumes N: "(1::nat) < n" |
193 shows "\<exists>p. prime p \<and> p dvd n" |
193 shows "\<exists>p. prime p \<and> p dvd n" |
194 proof - |
194 proof - |
195 from N obtain ps where "all_prime ps" |
195 from N obtain ps where "all_prime ps" |
196 and prod_ps: "n = (PROD m::nat:#mset ps. m)" using factor_exists |
196 and prod_ps: "n = (\<Prod>m::nat \<in># mset ps. m)" using factor_exists |
197 by simp iprover |
197 by simp iprover |
198 with N have "ps \<noteq> []" |
198 with N have "ps \<noteq> []" |
199 by (auto simp add: all_prime_nempty_g_one msetprod_empty) |
199 by (auto simp add: all_prime_nempty_g_one msetprod_empty) |
200 then obtain p qs where ps: "ps = p # qs" by (cases ps) simp |
200 then obtain p qs where ps: "ps = p # qs" by (cases ps) simp |
201 with `all_prime ps` have "prime p" by (simp add: all_prime_simps) |
201 with `all_prime ps` have "prime p" by (simp add: all_prime_simps) |