| 27468 |      1 | (*  Title       : NSPrimes.thy
 | 
|  |      2 |     Author      : Jacques D. Fleuriot
 | 
|  |      3 |     Copyright   : 2002 University of Edinburgh
 | 
|  |      4 |     Conversion to Isar and new proofs by Lawrence C Paulson, 2004
 | 
|  |      5 | *)
 | 
|  |      6 | 
 | 
|  |      7 | header{*The Nonstandard Primes as an Extension of the Prime Numbers*}
 | 
|  |      8 | 
 | 
|  |      9 | theory NSPrimes
 | 
| 32479 |     10 | imports "~~/src/HOL/Old_Number_Theory/Factorization" Hyperreal
 | 
| 27468 |     11 | begin
 | 
|  |     12 | 
 | 
|  |     13 | text{*These can be used to derive an alternative proof of the infinitude of
 | 
|  |     14 | primes by considering a property of nonstandard sets.*}
 | 
|  |     15 | 
 | 
| 36999 |     16 | declare dvd_def [transfer_refold]
 | 
| 27468 |     17 | 
 | 
|  |     18 | definition
 | 
|  |     19 |   starprime :: "hypnat set" where
 | 
|  |     20 |   [transfer_unfold]: "starprime = ( *s* {p. prime p})"
 | 
|  |     21 | 
 | 
|  |     22 | definition
 | 
|  |     23 |   choicefun :: "'a set => 'a" where
 | 
|  |     24 |   "choicefun E = (@x. \<exists>X \<in> Pow(E) -{{}}. x : X)"
 | 
|  |     25 | 
 | 
|  |     26 | consts injf_max :: "nat => ('a::{order} set) => 'a"
 | 
|  |     27 | primrec
 | 
|  |     28 |   injf_max_zero: "injf_max 0 E = choicefun E"
 | 
|  |     29 |   injf_max_Suc:  "injf_max (Suc n) E = choicefun({e. e:E & injf_max n E < e})"
 | 
|  |     30 | 
 | 
|  |     31 | 
 | 
|  |     32 | lemma dvd_by_all: "\<forall>M. \<exists>N. 0 < N & (\<forall>m. 0 < m & (m::nat) <= M --> m dvd N)"
 | 
|  |     33 | apply (rule allI)
 | 
|  |     34 | apply (induct_tac "M", auto)
 | 
|  |     35 | apply (rule_tac x = "N * (Suc n) " in exI)
 | 
|  |     36 | apply (safe, force)
 | 
|  |     37 | apply (drule le_imp_less_or_eq, erule disjE)
 | 
|  |     38 | apply (force intro!: dvd_mult2)
 | 
|  |     39 | apply (force intro!: dvd_mult)
 | 
|  |     40 | done
 | 
|  |     41 | 
 | 
|  |     42 | lemmas dvd_by_all2 = dvd_by_all [THEN spec, standard]
 | 
|  |     43 | 
 | 
|  |     44 | lemma hypnat_of_nat_le_zero_iff: "(hypnat_of_nat n <= 0) = (n = 0)"
 | 
|  |     45 | by (transfer, simp)
 | 
|  |     46 | declare hypnat_of_nat_le_zero_iff [simp]
 | 
|  |     47 | 
 | 
|  |     48 | 
 | 
|  |     49 | (* Goldblatt: Exercise 5.11(2) - p. 57 *)
 | 
| 36999 |     50 | lemma hdvd_by_all: "\<forall>M. \<exists>N. 0 < N & (\<forall>m. 0 < m & (m::hypnat) <= M --> m dvd N)"
 | 
| 27468 |     51 | by (transfer, rule dvd_by_all)
 | 
|  |     52 | 
 | 
|  |     53 | lemmas hdvd_by_all2 = hdvd_by_all [THEN spec, standard]
 | 
|  |     54 | 
 | 
|  |     55 | (* Goldblatt: Exercise 5.11(2) - p. 57 *)
 | 
|  |     56 | lemma hypnat_dvd_all_hypnat_of_nat:
 | 
| 36999 |     57 |      "\<exists>(N::hypnat). 0 < N & (\<forall>n \<in> -{0::nat}. hypnat_of_nat(n) dvd N)"
 | 
| 27468 |     58 | apply (cut_tac hdvd_by_all)
 | 
|  |     59 | apply (drule_tac x = whn in spec, auto)
 | 
|  |     60 | apply (rule exI, auto)
 | 
|  |     61 | apply (drule_tac x = "hypnat_of_nat n" in spec)
 | 
|  |     62 | apply (auto simp add: linorder_not_less star_of_eq_0)
 | 
|  |     63 | done
 | 
|  |     64 | 
 | 
|  |     65 | 
 | 
|  |     66 | text{*The nonstandard extension of the set prime numbers consists of precisely
 | 
|  |     67 | those hypernaturals exceeding 1 that have no nontrivial factors*}
 | 
|  |     68 | 
 | 
|  |     69 | (* Goldblatt: Exercise 5.11(3a) - p 57  *)
 | 
|  |     70 | lemma starprime:
 | 
| 36999 |     71 |   "starprime = {p. 1 < p & (\<forall>m. m dvd p --> m = 1 | m = p)}"
 | 
| 27468 |     72 | by (transfer, auto simp add: prime_def)
 | 
|  |     73 | 
 | 
|  |     74 | lemma prime_two:  "prime 2"
 | 
|  |     75 | apply (unfold prime_def, auto)
 | 
|  |     76 | apply (frule dvd_imp_le)
 | 
|  |     77 | apply (auto dest: dvd_0_left)
 | 
|  |     78 | apply (case_tac m, simp, arith)
 | 
|  |     79 | done
 | 
|  |     80 | declare prime_two [simp]
 | 
|  |     81 | 
 | 
|  |     82 | (* proof uses course-of-value induction *)
 | 
|  |     83 | lemma prime_factor_exists [rule_format]: "Suc 0 < n --> (\<exists>k. prime k & k dvd n)"
 | 
|  |     84 | apply (rule_tac n = n in nat_less_induct, auto)
 | 
|  |     85 | apply (case_tac "prime n")
 | 
|  |     86 | apply (rule_tac x = n in exI, auto)
 | 
|  |     87 | apply (drule conjI [THEN not_prime_ex_mk], auto)
 | 
|  |     88 | apply (drule_tac x = m in spec, auto)
 | 
|  |     89 | done
 | 
|  |     90 | 
 | 
|  |     91 | (* Goldblatt Exercise 5.11(3b) - p 57  *)
 | 
|  |     92 | lemma hyperprime_factor_exists [rule_format]:
 | 
| 36999 |     93 |   "!!n. 1 < n ==> (\<exists>k \<in> starprime. k dvd n)"
 | 
| 27468 |     94 | by (transfer, simp add: prime_factor_exists)
 | 
|  |     95 | 
 | 
|  |     96 | (* Goldblatt Exercise 3.10(1) - p. 29 *)
 | 
|  |     97 | lemma NatStar_hypnat_of_nat: "finite A ==> *s* A = hypnat_of_nat ` A"
 | 
|  |     98 | by (rule starset_finite)
 | 
|  |     99 | 
 | 
|  |    100 | 
 | 
|  |    101 | subsection{*Another characterization of infinite set of natural numbers*}
 | 
|  |    102 | 
 | 
|  |    103 | lemma finite_nat_set_bounded: "finite N ==> \<exists>n. (\<forall>i \<in> N. i<(n::nat))"
 | 
|  |    104 | apply (erule_tac F = N in finite_induct, auto)
 | 
|  |    105 | apply (rule_tac x = "Suc n + x" in exI, auto)
 | 
|  |    106 | done
 | 
|  |    107 | 
 | 
|  |    108 | lemma finite_nat_set_bounded_iff: "finite N = (\<exists>n. (\<forall>i \<in> N. i<(n::nat)))"
 | 
|  |    109 | by (blast intro: finite_nat_set_bounded bounded_nat_set_is_finite)
 | 
|  |    110 | 
 | 
|  |    111 | lemma not_finite_nat_set_iff: "(~ finite N) = (\<forall>n. \<exists>i \<in> N. n <= (i::nat))"
 | 
|  |    112 | by (auto simp add: finite_nat_set_bounded_iff not_less)
 | 
|  |    113 | 
 | 
|  |    114 | lemma bounded_nat_set_is_finite2: "(\<forall>i \<in> N. i<=(n::nat)) ==> finite N"
 | 
|  |    115 | apply (rule finite_subset)
 | 
|  |    116 |  apply (rule_tac [2] finite_atMost, auto)
 | 
|  |    117 | done
 | 
|  |    118 | 
 | 
|  |    119 | lemma finite_nat_set_bounded2: "finite N ==> \<exists>n. (\<forall>i \<in> N. i<=(n::nat))"
 | 
|  |    120 | apply (erule_tac F = N in finite_induct, auto)
 | 
|  |    121 | apply (rule_tac x = "n + x" in exI, auto)
 | 
|  |    122 | done
 | 
|  |    123 | 
 | 
|  |    124 | lemma finite_nat_set_bounded_iff2: "finite N = (\<exists>n. (\<forall>i \<in> N. i<=(n::nat)))"
 | 
|  |    125 | by (blast intro: finite_nat_set_bounded2 bounded_nat_set_is_finite2)
 | 
|  |    126 | 
 | 
|  |    127 | lemma not_finite_nat_set_iff2: "(~ finite N) = (\<forall>n. \<exists>i \<in> N. n < (i::nat))"
 | 
|  |    128 | by (auto simp add: finite_nat_set_bounded_iff2 not_le)
 | 
|  |    129 | 
 | 
|  |    130 | 
 | 
|  |    131 | subsection{*An injective function cannot define an embedded natural number*}
 | 
|  |    132 | 
 | 
|  |    133 | lemma lemma_infinite_set_singleton: "\<forall>m n. m \<noteq> n --> f n \<noteq> f m
 | 
|  |    134 |       ==>  {n. f n = N} = {} |  (\<exists>m. {n. f n = N} = {m})"
 | 
|  |    135 | apply auto
 | 
|  |    136 | apply (drule_tac x = x in spec, auto)
 | 
|  |    137 | apply (subgoal_tac "\<forall>n. (f n = f x) = (x = n) ")
 | 
|  |    138 | apply auto
 | 
|  |    139 | done
 | 
|  |    140 | 
 | 
|  |    141 | lemma inj_fun_not_hypnat_in_SHNat:
 | 
|  |    142 |   assumes inj_f: "inj (f::nat=>nat)"
 | 
|  |    143 |   shows "starfun f whn \<notin> Nats"
 | 
|  |    144 | proof
 | 
|  |    145 |   from inj_f have inj_f': "inj (starfun f)"
 | 
|  |    146 |     by (transfer inj_on_def Ball_def UNIV_def)
 | 
|  |    147 |   assume "starfun f whn \<in> Nats"
 | 
|  |    148 |   then obtain N where N: "starfun f whn = hypnat_of_nat N"
 | 
|  |    149 |     by (auto simp add: Nats_def)
 | 
|  |    150 |   hence "\<exists>n. starfun f n = hypnat_of_nat N" ..
 | 
|  |    151 |   hence "\<exists>n. f n = N" by transfer
 | 
|  |    152 |   then obtain n where n: "f n = N" ..
 | 
|  |    153 |   hence "starfun f (hypnat_of_nat n) = hypnat_of_nat N"
 | 
|  |    154 |     by transfer
 | 
|  |    155 |   with N have "starfun f whn = starfun f (hypnat_of_nat n)"
 | 
|  |    156 |     by simp
 | 
|  |    157 |   with inj_f' have "whn = hypnat_of_nat n"
 | 
|  |    158 |     by (rule injD)
 | 
|  |    159 |   thus "False"
 | 
|  |    160 |     by (simp add: whn_neq_hypnat_of_nat)
 | 
|  |    161 | qed
 | 
|  |    162 | 
 | 
|  |    163 | lemma range_subset_mem_starsetNat:
 | 
|  |    164 |    "range f <= A ==> starfun f whn \<in> *s* A"
 | 
|  |    165 | apply (rule_tac x="whn" in spec)
 | 
|  |    166 | apply (transfer, auto)
 | 
|  |    167 | done
 | 
|  |    168 | 
 | 
|  |    169 | (*--------------------------------------------------------------------------------*)
 | 
|  |    170 | (* Gleason Proposition 11-5.5. pg 149, pg 155 (ex. 3) and pg. 360                 *)
 | 
|  |    171 | (* Let E be a nonvoid ordered set with no maximal elements (note: effectively an  *)
 | 
|  |    172 | (* infinite set if we take E = N (Nats)). Then there exists an order-preserving   *)
 | 
|  |    173 | (* injection from N to E. Of course, (as some doofus will undoubtedly point out!  *)
 | 
|  |    174 | (* :-)) can use notion of least element in proof (i.e. no need for choice) if     *)
 | 
|  |    175 | (* dealing with nats as we have well-ordering property                            *)
 | 
|  |    176 | (*--------------------------------------------------------------------------------*)
 | 
|  |    177 | 
 | 
|  |    178 | lemma lemmaPow3: "E \<noteq> {} ==> \<exists>x. \<exists>X \<in> (Pow E - {{}}). x: X"
 | 
|  |    179 | by auto
 | 
|  |    180 | 
 | 
|  |    181 | lemma choicefun_mem_set: "E \<noteq> {} ==> choicefun E \<in> E"
 | 
|  |    182 | apply (unfold choicefun_def)
 | 
|  |    183 | apply (rule lemmaPow3 [THEN someI2_ex], auto)
 | 
|  |    184 | done
 | 
|  |    185 | declare choicefun_mem_set [simp]
 | 
|  |    186 | 
 | 
|  |    187 | lemma injf_max_mem_set: "[| E \<noteq>{}; \<forall>x. \<exists>y \<in> E. x < y |] ==> injf_max n E \<in> E"
 | 
|  |    188 | apply (induct_tac "n", force)
 | 
|  |    189 | apply (simp (no_asm) add: choicefun_def)
 | 
|  |    190 | apply (rule lemmaPow3 [THEN someI2_ex], auto)
 | 
|  |    191 | done
 | 
|  |    192 | 
 | 
|  |    193 | lemma injf_max_order_preserving: "\<forall>x. \<exists>y \<in> E. x < y ==> injf_max n E < injf_max (Suc n) E"
 | 
|  |    194 | apply (simp (no_asm) add: choicefun_def)
 | 
|  |    195 | apply (rule lemmaPow3 [THEN someI2_ex], auto)
 | 
|  |    196 | done
 | 
|  |    197 | 
 | 
|  |    198 | lemma injf_max_order_preserving2: "\<forall>x. \<exists>y \<in> E. x < y
 | 
|  |    199 |       ==> \<forall>n m. m < n --> injf_max m E < injf_max n E"
 | 
|  |    200 | apply (rule allI)
 | 
|  |    201 | apply (induct_tac "n", auto)
 | 
|  |    202 | apply (simp (no_asm) add: choicefun_def)
 | 
|  |    203 | apply (rule lemmaPow3 [THEN someI2_ex])
 | 
|  |    204 | apply (auto simp add: less_Suc_eq)
 | 
|  |    205 | apply (drule_tac x = m in spec)
 | 
|  |    206 | apply (drule subsetD, auto)
 | 
|  |    207 | apply (drule_tac x = "injf_max m E" in order_less_trans, auto)
 | 
|  |    208 | done
 | 
|  |    209 | 
 | 
|  |    210 | lemma inj_injf_max: "\<forall>x. \<exists>y \<in> E. x < y ==> inj (%n. injf_max n E)"
 | 
|  |    211 | apply (rule inj_onI)
 | 
|  |    212 | apply (rule ccontr, auto)
 | 
|  |    213 | apply (drule injf_max_order_preserving2)
 | 
|  |    214 | apply (metis linorder_antisym_conv3 order_less_le)
 | 
|  |    215 | done
 | 
|  |    216 | 
 | 
|  |    217 | lemma infinite_set_has_order_preserving_inj:
 | 
|  |    218 |      "[| (E::('a::{order} set)) \<noteq> {}; \<forall>x. \<exists>y \<in> E. x < y |]
 | 
|  |    219 |       ==> \<exists>f. range f <= E & inj (f::nat => 'a) & (\<forall>m. f m < f(Suc m))"
 | 
|  |    220 | apply (rule_tac x = "%n. injf_max n E" in exI, safe)
 | 
|  |    221 | apply (rule injf_max_mem_set)
 | 
|  |    222 | apply (rule_tac [3] inj_injf_max)
 | 
|  |    223 | apply (rule_tac [4] injf_max_order_preserving, auto)
 | 
|  |    224 | done
 | 
|  |    225 | 
 | 
|  |    226 | text{*Only need the existence of an injective function from N to A for proof*}
 | 
|  |    227 | 
 | 
|  |    228 | lemma hypnat_infinite_has_nonstandard:
 | 
|  |    229 |      "~ finite A ==> hypnat_of_nat ` A < ( *s* A)"
 | 
|  |    230 | apply auto
 | 
|  |    231 | apply (subgoal_tac "A \<noteq> {}")
 | 
|  |    232 | prefer 2 apply force
 | 
|  |    233 | apply (drule infinite_set_has_order_preserving_inj)
 | 
|  |    234 | apply (erule not_finite_nat_set_iff2 [THEN iffD1], auto)
 | 
|  |    235 | apply (drule inj_fun_not_hypnat_in_SHNat)
 | 
|  |    236 | apply (drule range_subset_mem_starsetNat)
 | 
|  |    237 | apply (auto simp add: SHNat_eq)
 | 
|  |    238 | done
 | 
|  |    239 | 
 | 
|  |    240 | lemma starsetNat_eq_hypnat_of_nat_image_finite: "*s* A =  hypnat_of_nat ` A ==> finite A"
 | 
|  |    241 | apply (rule ccontr)
 | 
|  |    242 | apply (auto dest: hypnat_infinite_has_nonstandard)
 | 
|  |    243 | done
 | 
|  |    244 | 
 | 
|  |    245 | lemma finite_starsetNat_iff: "( *s* A = hypnat_of_nat ` A) = (finite A)"
 | 
|  |    246 | by (blast intro!: starsetNat_eq_hypnat_of_nat_image_finite NatStar_hypnat_of_nat)
 | 
|  |    247 | 
 | 
|  |    248 | lemma hypnat_infinite_has_nonstandard_iff: "(~ finite A) = (hypnat_of_nat ` A < *s* A)"
 | 
|  |    249 | apply (rule iffI)
 | 
|  |    250 | apply (blast intro!: hypnat_infinite_has_nonstandard)
 | 
|  |    251 | apply (auto simp add: finite_starsetNat_iff [symmetric])
 | 
|  |    252 | done
 | 
|  |    253 | 
 | 
|  |    254 | subsection{*Existence of Infinitely Many Primes: a Nonstandard Proof*}
 | 
|  |    255 | 
 | 
| 36999 |    256 | lemma lemma_not_dvd_hypnat_one: "~ (\<forall>n \<in> - {0}. hypnat_of_nat n dvd 1)"
 | 
| 27468 |    257 | apply auto
 | 
|  |    258 | apply (rule_tac x = 2 in bexI)
 | 
|  |    259 | apply (transfer, auto)
 | 
|  |    260 | done
 | 
|  |    261 | declare lemma_not_dvd_hypnat_one [simp]
 | 
|  |    262 | 
 | 
| 36999 |    263 | lemma lemma_not_dvd_hypnat_one2: "\<exists>n \<in> - {0}. ~ hypnat_of_nat n dvd 1"
 | 
| 27468 |    264 | apply (cut_tac lemma_not_dvd_hypnat_one)
 | 
|  |    265 | apply (auto simp del: lemma_not_dvd_hypnat_one)
 | 
|  |    266 | done
 | 
|  |    267 | declare lemma_not_dvd_hypnat_one2 [simp]
 | 
|  |    268 | 
 | 
|  |    269 | (* not needed here *)
 | 
|  |    270 | lemma hypnat_gt_zero_gt_one:
 | 
|  |    271 |   "!!N. [| 0 < (N::hypnat); N \<noteq> 1 |] ==> 1 < N"
 | 
|  |    272 | by (transfer, simp)
 | 
|  |    273 | 
 | 
|  |    274 | lemma hypnat_add_one_gt_one:
 | 
|  |    275 |     "!!N. 0 < N ==> 1 < (N::hypnat) + 1"
 | 
|  |    276 | by (transfer, simp)
 | 
|  |    277 | 
 | 
|  |    278 | lemma zero_not_prime: "\<not> prime 0"
 | 
|  |    279 | apply safe
 | 
|  |    280 | apply (drule prime_g_zero, auto)
 | 
|  |    281 | done
 | 
|  |    282 | declare zero_not_prime [simp]
 | 
|  |    283 | 
 | 
|  |    284 | lemma hypnat_of_nat_zero_not_prime: "hypnat_of_nat 0 \<notin> starprime"
 | 
|  |    285 | by (transfer, simp)
 | 
|  |    286 | declare hypnat_of_nat_zero_not_prime [simp]
 | 
|  |    287 | 
 | 
|  |    288 | lemma hypnat_zero_not_prime:
 | 
|  |    289 |    "0 \<notin> starprime"
 | 
|  |    290 | by (cut_tac hypnat_of_nat_zero_not_prime, simp)
 | 
|  |    291 | declare hypnat_zero_not_prime [simp]
 | 
|  |    292 | 
 | 
|  |    293 | lemma one_not_prime: "\<not> prime 1"
 | 
|  |    294 | apply safe
 | 
|  |    295 | apply (drule prime_g_one, auto)
 | 
|  |    296 | done
 | 
|  |    297 | declare one_not_prime [simp]
 | 
|  |    298 | 
 | 
|  |    299 | lemma one_not_prime2: "\<not> prime(Suc 0)"
 | 
|  |    300 | apply safe
 | 
|  |    301 | apply (drule prime_g_one, auto)
 | 
|  |    302 | done
 | 
|  |    303 | declare one_not_prime2 [simp]
 | 
|  |    304 | 
 | 
|  |    305 | lemma hypnat_of_nat_one_not_prime: "hypnat_of_nat 1 \<notin> starprime"
 | 
|  |    306 | by (transfer, simp)
 | 
|  |    307 | declare hypnat_of_nat_one_not_prime [simp]
 | 
|  |    308 | 
 | 
|  |    309 | lemma hypnat_one_not_prime: "1 \<notin> starprime"
 | 
|  |    310 | by (cut_tac hypnat_of_nat_one_not_prime, simp)
 | 
|  |    311 | declare hypnat_one_not_prime [simp]
 | 
|  |    312 | 
 | 
| 36999 |    313 | lemma hdvd_diff: "!!k m n :: hypnat. [| k dvd m; k dvd n |] ==> k dvd (m - n)"
 | 
|  |    314 | by (transfer, rule dvd_diff_nat)
 | 
| 27468 |    315 | 
 | 
|  |    316 | lemma dvd_one_eq_one: "x dvd (1::nat) ==> x = 1"
 | 
|  |    317 | by (unfold dvd_def, auto)
 | 
|  |    318 | 
 | 
| 36999 |    319 | lemma hdvd_one_eq_one: "!!x. x dvd (1::hypnat) ==> x = 1"
 | 
| 27468 |    320 | by (transfer, rule dvd_one_eq_one)
 | 
|  |    321 | 
 | 
|  |    322 | theorem not_finite_prime: "~ finite {p. prime p}"
 | 
|  |    323 | apply (rule hypnat_infinite_has_nonstandard_iff [THEN iffD2])
 | 
|  |    324 | apply (cut_tac hypnat_dvd_all_hypnat_of_nat)
 | 
|  |    325 | apply (erule exE)
 | 
|  |    326 | apply (erule conjE)
 | 
|  |    327 | apply (subgoal_tac "1 < N + 1")
 | 
|  |    328 | prefer 2 apply (blast intro: hypnat_add_one_gt_one)
 | 
|  |    329 | apply (drule hyperprime_factor_exists)
 | 
|  |    330 | apply auto
 | 
|  |    331 | apply (subgoal_tac "k \<notin> hypnat_of_nat ` {p. prime p}")
 | 
|  |    332 | apply (force simp add: starprime_def, safe)
 | 
|  |    333 | apply (drule_tac x = x in bspec)
 | 
|  |    334 | apply (rule ccontr, simp)
 | 
|  |    335 | apply (drule hdvd_diff, assumption)
 | 
|  |    336 | apply (auto dest: hdvd_one_eq_one)
 | 
|  |    337 | done
 | 
|  |    338 | 
 | 
|  |    339 | end
 |