(* Title: HOL/Proofs/Extraction/Euclid.thy Author: Markus Wenzel, TU Muenchen Author: Freek Wiedijk, Radboud University Nijmegen Author: Stefan Berghofer, TU Muenchen
*)
section‹Euclid's theorem\
theory Euclid imports "HOL-Computational_Algebra.Primes"
Util "HOL-Library.Code_Target_Numeral" "HOL-Library.Realizers" begin
text‹
A constructive version of the proof of Euclid's theorem by
Markus Wenzel and Freek Wiedijk 🍋‹"Wenzel-Wiedijk-JAR2002"›. ›
lemma factor_greater_one1: "n = m * k \ m < n \ k < n \ Suc 0 < m" by (induct m) auto
lemma factor_greater_one2: "n = m * k \ m < n \ k < n \ Suc 0 < k" by (induct k) auto
lemma prod_mn_less_k: "0 < n \ 0 < k \ Suc 0 < m \ m * n = k \ n < k" by (induct m) auto
lemma prime_eq': "prime (p::nat) \ 1 < p \ (\m k. p = m * k \ 1 < m \ m = p)" by (simp add: prime_eq dvd_def HOL.all_simps [symmetric] del: HOL.all_simps)
lemma not_prime_ex_mk: assumes n: "Suc 0 < n" shows"(\m k. Suc 0 < m \ Suc 0 < k \ m < n \ k < n \ n = m * k) \ prime n" proof - from nat_eq_dec have"(\m \ (\mfor k by (rule search) thenhave"(\km \ (\km by (rule search) thenshow ?thesis proof assume"\km thenobtain k m where k: "kand m: "mand nmk: "n = m * k" by iprover from nmk m k have"Suc 0 < m"by (rule factor_greater_one1) moreoverfrom nmk m k have"Suc 0 < k"by (rule factor_greater_one2) ultimatelyshow ?thesis using k m nmk by iprover next assume"\ (\km thenhave A: "\km m * k"by iprover have"\m k. n = m * k \ Suc 0 < m \ m = n" proof (intro allI impI) fix m k assume nmk: "n = m * k" assume m: "Suc 0 < m" from n m nmk have k: "0 < k" by (cases k) auto moreoverfrom n have n: "0 < n"by simp moreovernote m moreoverfrom nmk have"m * k = n"by simp ultimatelyhave kn: "k < n"by (rule prod_mn_less_k) show"m = n" proof (cases "k = Suc 0") case True with nmk show ?thesis by (simp only: mult_Suc_right) next case False from m have"0 < m"by simp moreovernote n moreoverfrom False n nmk k have"Suc 0 < k"by auto moreoverfrom nmk have"k * m = n"by (simp only: ac_simps) ultimatelyhave mn: "m < n"by (rule prod_mn_less_k) with kn A nmk show ?thesis by iprover qed qed with n have"prime n" by (simp only: prime_eq' One_nat_def simp_thms) thenshow ?thesis .. qed qed
lemma dvd_factorial: "0 < m \ m \ n \ m dvd fact n" proof (induct n rule: nat_induct) case 0 thenshow ?caseby simp next case (Suc n) from‹m ≤ Suc n›show ?case proof (rule le_SucE) assume"m \ n" with‹0 < m›have"m dvd fact n"by (rule Suc) thenhave"m dvd (fact n * Suc n)"by (rule dvd_mult2) thenshow ?thesis by (simp add: mult.commute) next assume"m = Suc n" thenhave"m dvd (fact n * Suc n)" by (auto intro: dvdI simp: ac_simps) thenshow ?thesis by (simp add: mult.commute) qed qed
lemma dvd_prod [iff]: "n dvd (\m::nat \# mset (n # ns). m)" by (simp add: prod_mset_Un)
definition all_prime :: "nat list \ bool" where"all_prime ps \ (\p\set ps. prime p)"
lemma all_prime_simps: "all_prime []" "all_prime (p # ps) \ prime p \ all_prime ps" by (simp_all add: all_prime_def)
lemma factor_exists: "Suc 0 < n \ (\ps. all_prime ps \ (\m::nat \# mset ps. m) = n)" proof (induct n rule: nat_wf_ind) case (1 n) from‹Suc 0 < n› have"(\m k. Suc 0 < m \ Suc 0 < k \ m < n \ k < n \ n = m * k) \ prime n" by (rule not_prime_ex_mk) thenshow ?case proof assume"\m k. Suc 0 < m \ Suc 0 < k \ m < n \ k < n \ n = m * k" thenobtain m k where m: "Suc 0 < m"and k: "Suc 0 < k"and mn: "m < n" and kn: "k < n"and nmk: "n = m * k" by iprover from mn and m have"\ps. all_prime ps \ (\m::nat \# mset ps. m) = m" by (rule 1) thenobtain ps1 where"all_prime ps1"and prod_ps1_m: "(\m::nat \# mset ps1. m) = m" by iprover from kn and k have"\ps. all_prime ps \ (\m::nat \# mset ps. m) = k" by (rule 1) thenobtain ps2 where"all_prime ps2"and prod_ps2_k: "(\m::nat \# mset ps2. m) = k" by iprover from‹all_prime ps1›‹all_prime ps2› have"\ps. all_prime ps \ (\m::nat \# mset ps. m) =
(∏m::nat ∈# mset ps1. m) * (∏m::nat ∈# mset ps2. m)" by (rule split_all_prime) with prod_ps1_m prod_ps2_k nmk show ?thesis by simp next assume"prime n"thenhave"all_prime [n]"by (simp add: all_prime_simps) moreoverhave"(\m::nat \# mset [n]. m) = n"by (simp) ultimatelyhave"all_prime [n] \ (\m::nat \# mset [n]. m) = n" .. thenshow ?thesis .. qed qed
lemma prime_factor_exists: assumes N: "(1::nat) < n" shows"\p. prime p \ p dvd n" proof - from N obtain ps where"all_prime ps"and prod_ps: "n = (\m::nat \# mset ps. m)" using factor_exists by simp iprover with N have"ps \ []" by (auto simp add: all_prime_nempty_g_one) thenobtain p qs where ps: "ps = p # qs" by (cases ps) simp with‹all_prime ps›have"prime p" by (simp add: all_prime_simps) moreoverfrom‹all_prime ps› ps prod_ps have"p dvd n" by (simp only: dvd_prod) ultimatelyshow ?thesis by iprover qed
text‹Euclid's theorem: there are infinitely many primes.\
lemma Euclid: "\p::nat. prime p \ n < p" proof - let ?k = "fact n + (1::nat)" have"1 < ?k"by simp thenobtain p where prime: "prime p"and dvd: "p dvd ?k" using prime_factor_exists by iprover have"n < p" proof - have"\ p \ n" proof assume pn: "p \ n" from‹prime p›have"0 < p"by (rule prime_gt_0_nat) thenhave"p dvd fact n"using pn by (rule dvd_factorial) with dvd have"p dvd ?k - fact n"by (rule dvd_diff_nat) thenhave"p dvd 1"by simp with prime show False by auto qed thenshow ?thesis by simp qed with prime show ?thesis by iprover qed
extract Euclid
text‹
The program extracted from the proof of Euclid's theorem looks as follows.
@{thm [display] Euclid_def}
The program corresponding to the proof of the factorization theoremis
@{thm [display] factor_exists_def} ›
instantiation nat :: default begin
definition"default = (0::nat)"
instance ..
end
instantiation list :: (type) default begin
definition"default = []"
instance ..
end
primrec iterate :: "nat \ ('a \ 'a) \ 'a \ 'a list" where "iterate 0 f x = []"
| "iterate (Suc n) f x = (let y = f x in y # iterate n f y)"
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.