src/HOL/Hyperreal/NatStar.thy
author paulson
Wed Sep 01 15:04:01 2004 +0200 (2004-09-01)
changeset 15169 2b5da07a0b89
parent 15140 322485b816ac
child 15360 300e09825d8b
permissions -rw-r--r--
new "respects" syntax for quotienting
     1 (*  Title       : NatStar.thy
     2     Author      : Jacques D. Fleuriot
     3     Copyright   : 1998  University of Cambridge
     4 
     5 Converted to Isar and polished by lcp
     6 *)
     7 
     8 header{*Star-transforms for the Hypernaturals*}
     9 
    10 theory NatStar
    11 imports "../Real/RealPow" HyperPow
    12 begin
    13 
    14 text{*Extends sets of nats, and functions from the nats to nats or reals*}
    15 
    16 
    17 constdefs
    18 
    19   (* internal sets and nonstandard extensions -- see Star.thy as well *)
    20 
    21     starsetNat :: "nat set => hypnat set"          ("*sNat* _" [80] 80)
    22     "*sNat* A ==
    23        {x. \<forall>X\<in>Rep_hypnat(x). {n::nat. X n \<in> A}: FreeUltrafilterNat}"
    24 
    25    starsetNat_n :: "(nat => nat set) => hypnat set"      ("*sNatn* _" [80] 80)
    26     "*sNatn* As ==
    27        {x. \<forall>X\<in>Rep_hypnat(x). {n::nat. X n \<in> (As n)}: FreeUltrafilterNat}"
    28 
    29    InternalNatSets :: "hypnat set set"
    30     "InternalNatSets == {X. \<exists>As. X = *sNatn* As}"
    31 
    32     (* star transform of functions f:Nat --> Real *)
    33 
    34     starfunNat :: "(nat => real) => hypnat => hypreal"
    35                   ("*fNat* _" [80] 80)
    36     "*fNat* f  == (%x. Abs_hypreal(\<Union>X\<in>Rep_hypnat(x). hyprel``{%n. f (X n)}))"
    37 
    38    starfunNat_n :: "(nat => (nat => real)) => hypnat => hypreal"
    39                    ("*fNatn* _" [80] 80)
    40     "*fNatn* F ==
    41       (%x. Abs_hypreal(\<Union>X\<in>Rep_hypnat(x). hyprel``{%n. (F n)(X n)}))"
    42 
    43    InternalNatFuns :: "(hypnat => hypreal) set"
    44     "InternalNatFuns == {X. \<exists>F. X = *fNatn* F}"
    45 
    46     (* star transform of functions f:Nat --> Nat *)
    47 
    48    starfunNat2 :: "(nat => nat) => hypnat => hypnat"
    49                    ("*fNat2* _" [80] 80)
    50     "*fNat2* f == %x. Abs_hypnat(\<Union>X\<in>Rep_hypnat(x). hypnatrel``{%n. f (X n)})"
    51 
    52    starfunNat2_n :: "(nat => (nat => nat)) => hypnat => hypnat"
    53                      ("*fNat2n* _" [80] 80)
    54     "*fNat2n* F == 
    55         %x. Abs_hypnat(\<Union>X\<in>Rep_hypnat(x). hypnatrel``{%n. (F n)(X n)})"
    56 
    57    InternalNatFuns2 :: "(hypnat => hypnat) set"
    58     "InternalNatFuns2 == {X. \<exists>F. X = *fNat2n* F}"
    59 
    60 
    61 lemma NatStar_real_set: "*sNat*(UNIV::nat set) = (UNIV::hypnat set)"
    62 by (simp add: starsetNat_def)
    63 
    64 lemma NatStar_empty_set [simp]: "*sNat* {} = {}"
    65 by (simp add: starsetNat_def)
    66 
    67 lemma NatStar_Un: "*sNat* (A Un B) = *sNat* A Un *sNat* B"
    68 apply (auto simp add: starsetNat_def)
    69  prefer 2 apply (blast intro: FreeUltrafilterNat_subset)
    70  prefer 2 apply (blast intro: FreeUltrafilterNat_subset)
    71 apply (drule FreeUltrafilterNat_Compl_mem)
    72 apply (drule bspec, assumption)
    73 apply (rule_tac z = x in eq_Abs_hypnat, auto, ultra)
    74 done
    75 
    76 lemma starsetNat_n_Un: "*sNatn* (%n. (A n) Un (B n)) = *sNatn* A Un *sNatn* B"
    77 apply (auto simp add: starsetNat_n_def)
    78 apply (drule_tac x = Xa in bspec)
    79 apply (rule_tac [2] z = x in eq_Abs_hypnat)
    80 apply (auto dest!: bspec, ultra+)
    81 done
    82 
    83 lemma InternalNatSets_Un:
    84      "[| X \<in> InternalNatSets; Y \<in> InternalNatSets |]
    85       ==> (X Un Y) \<in> InternalNatSets"
    86 by (auto simp add: InternalNatSets_def starsetNat_n_Un [symmetric])
    87 
    88 lemma NatStar_Int: "*sNat* (A Int B) = *sNat* A Int *sNat* B"
    89 apply (auto simp add: starsetNat_def)
    90 prefer 3 apply (blast intro: FreeUltrafilterNat_Int FreeUltrafilterNat_subset)
    91 apply (blast intro: FreeUltrafilterNat_subset)+
    92 done
    93 
    94 lemma starsetNat_n_Int:
    95       "*sNatn* (%n. (A n) Int (B n)) = *sNatn* A Int *sNatn* B"
    96 apply (auto simp add: starsetNat_n_def)
    97 apply (auto dest!: bspec, ultra+)
    98 done
    99 
   100 lemma InternalNatSets_Int:
   101      "[| X \<in> InternalNatSets; Y \<in> InternalNatSets |]
   102       ==> (X Int Y) \<in> InternalNatSets"
   103 by (auto simp add: InternalNatSets_def starsetNat_n_Int [symmetric])
   104 
   105 lemma NatStar_Compl: "*sNat* (-A) = -( *sNat* A)"
   106 apply (auto simp add: starsetNat_def)
   107 apply (rule_tac z = x in eq_Abs_hypnat)
   108 apply (rule_tac [2] z = x in eq_Abs_hypnat)
   109 apply (auto dest!: bspec, ultra+)
   110 done
   111 
   112 lemma starsetNat_n_Compl: "*sNatn* ((%n. - A n)) = -( *sNatn* A)"
   113 apply (auto simp add: starsetNat_n_def)
   114 apply (rule_tac z = x in eq_Abs_hypnat)
   115 apply (rule_tac [2] z = x in eq_Abs_hypnat)
   116 apply (auto dest!: bspec, ultra+)
   117 done
   118 
   119 lemma InternalNatSets_Compl: "X \<in> InternalNatSets ==> -X \<in> InternalNatSets"
   120 by (auto simp add: InternalNatSets_def starsetNat_n_Compl [symmetric])
   121 
   122 lemma starsetNat_n_diff: "*sNatn* (%n. (A n) - (B n)) = *sNatn* A - *sNatn* B"
   123 apply (auto simp add: starsetNat_n_def)
   124 apply (rule_tac [2] z = x in eq_Abs_hypnat)
   125 apply (rule_tac [3] z = x in eq_Abs_hypnat)
   126 apply (auto dest!: bspec, ultra+)
   127 done
   128 
   129 lemma InternalNatSets_diff:
   130      "[| X \<in> InternalNatSets; Y \<in> InternalNatSets |]
   131       ==> (X - Y) \<in> InternalNatSets"
   132 by (auto simp add: InternalNatSets_def starsetNat_n_diff [symmetric])
   133 
   134 lemma NatStar_subset: "A \<le> B ==> *sNat* A \<le> *sNat* B"
   135 apply (simp add: starsetNat_def)
   136 apply (blast intro: FreeUltrafilterNat_subset)
   137 done
   138 
   139 lemma NatStar_mem: "a \<in> A ==> hypnat_of_nat a \<in> *sNat* A"
   140 by (auto intro: FreeUltrafilterNat_subset 
   141          simp add: starsetNat_def hypnat_of_nat_eq)
   142 
   143 lemma NatStar_hypreal_of_real_image_subset: "hypnat_of_nat ` A \<le> *sNat* A"
   144 apply (auto simp add: starsetNat_def hypnat_of_nat_eq)
   145 apply (blast intro: FreeUltrafilterNat_subset)
   146 done
   147 
   148 lemma NatStar_SHNat_subset: "Nats \<le> *sNat* (UNIV:: nat set)"
   149 by (simp add: starsetNat_def SHNat_eq hypnat_of_nat_eq)
   150 
   151 lemma NatStar_hypreal_of_real_Int:
   152      "*sNat* X Int Nats = hypnat_of_nat ` X"
   153 apply (auto simp add: starsetNat_def hypnat_of_nat_eq SHNat_eq)
   154 apply (simp add: hypnat_of_nat_eq [symmetric])
   155 apply (rule imageI, rule ccontr)
   156 apply (drule bspec)
   157 apply (rule lemma_hypnatrel_refl)
   158 prefer 2 apply (blast intro: FreeUltrafilterNat_subset, auto)
   159 done
   160 
   161 lemma starsetNat_starsetNat_n_eq: "*sNat* X = *sNatn* (%n. X)"
   162 by (simp add: starsetNat_n_def starsetNat_def)
   163 
   164 lemma InternalNatSets_starsetNat_n [simp]: "( *sNat* X) \<in> InternalNatSets"
   165 by (auto simp add: InternalNatSets_def starsetNat_starsetNat_n_eq)
   166 
   167 lemma InternalNatSets_UNIV_diff:
   168      "X \<in> InternalNatSets ==> UNIV - X \<in> InternalNatSets"
   169 by (auto intro: InternalNatSets_Compl)
   170 
   171 text{*Nonstandard extension of a set (defined using a constant
   172    sequence) as a special case of an internal set*}
   173 lemma starsetNat_n_starsetNat: "\<forall>n. (As n = A) ==> *sNatn* As = *sNat* A"
   174 by (simp add: starsetNat_n_def starsetNat_def)
   175 
   176 
   177 subsection{*Nonstandard Extensions of Functions*}
   178 
   179 text{* Nonstandard extension of a function (defined using a constant
   180    sequence) as a special case of an internal function*}
   181 
   182 lemma starfunNat_n_starfunNat: "\<forall>n. (F n = f) ==> *fNatn* F = *fNat* f"
   183 by (simp add: starfunNat_n_def starfunNat_def)
   184 
   185 lemma starfunNat2_n_starfunNat2: "\<forall>n. (F n = f) ==> *fNat2n* F = *fNat2* f"
   186 by (simp add: starfunNat2_n_def starfunNat2_def)
   187 
   188 lemma starfunNat_congruent: "(%X. hypnatrel``{%n. f (X n)}) respects hypnatrel"
   189 apply (simp add: congruent_def, safe)
   190 apply (ultra+)
   191 done
   192 
   193 (* f::nat=>real *)
   194 lemma starfunNat:
   195       "( *fNat* f) (Abs_hypnat(hypnatrel``{%n. X n})) =
   196        Abs_hypreal(hyprel `` {%n. f (X n)})"
   197 apply (simp add: starfunNat_def)
   198 apply (rule arg_cong [where f = Abs_hypreal])
   199 apply (auto, ultra)
   200 done
   201 
   202 (* f::nat=>nat *)
   203 lemma starfunNat2:
   204       "( *fNat2* f) (Abs_hypnat(hypnatrel``{%n. X n})) =
   205        Abs_hypnat(hypnatrel `` {%n. f (X n)})"
   206 apply (simp add: starfunNat2_def)
   207 apply (rule arg_cong [where f = Abs_hypnat])
   208 apply (simp add: hypnatrel_in_hypnat [THEN Abs_hypnat_inverse]
   209          UN_equiv_class [OF equiv_hypnatrel starfunNat_congruent])
   210 done
   211 
   212 subsubsection{*Multiplication: @{text "( *f) x ( *g) = *(f x g)"}*}
   213 
   214 lemma starfunNat_mult:
   215      "( *fNat* f) z * ( *fNat* g) z = ( *fNat* (%x. f x * g x)) z"
   216 apply (cases z)
   217 apply (simp add: starfunNat hypreal_mult)
   218 done
   219 
   220 lemma starfunNat2_mult:
   221      "( *fNat2* f) z * ( *fNat2* g) z = ( *fNat2* (%x. f x * g x)) z"
   222 apply (cases z)
   223 apply (simp add: starfunNat2 hypnat_mult)
   224 done
   225 
   226 subsubsection{*Addition: @{text "( *f) + ( *g) = *(f + g)"}*}
   227 
   228 lemma starfunNat_add:
   229      "( *fNat* f) z + ( *fNat* g) z = ( *fNat* (%x. f x + g x)) z"
   230 apply (cases z)
   231 apply (simp add: starfunNat hypreal_add)
   232 done
   233 
   234 lemma starfunNat2_add:
   235      "( *fNat2* f) z + ( *fNat2* g) z = ( *fNat2* (%x. f x + g x)) z"
   236 apply (cases z)
   237 apply (simp add: starfunNat2 hypnat_add)
   238 done
   239 
   240 lemma starfunNat2_minus:
   241      "( *fNat2* f) z - ( *fNat2* g) z = ( *fNat2* (%x. f x - g x)) z"
   242 apply (cases z)
   243 apply (simp add: starfunNat2 hypnat_minus)
   244 done
   245 
   246 subsubsection{*Composition: @{text "( *f) o ( *g) = *(f o g)"}*}
   247 
   248 (***** ( *f::nat=>real) o ( *g::nat=>nat) = *(f o g) *****)
   249 
   250 lemma starfunNatNat2_o:
   251      "( *fNat* f) o ( *fNat2* g) = ( *fNat* (f o g))"
   252 apply (rule ext)
   253 apply (rule_tac z = x in eq_Abs_hypnat)
   254 apply (simp add: starfunNat2 starfunNat)
   255 done
   256 
   257 lemma starfunNatNat2_o2:
   258      "(%x. ( *fNat* f) (( *fNat2* g) x)) = ( *fNat* (%x. f(g x)))"
   259 apply (insert starfunNatNat2_o [of f g]) 
   260 apply (simp add: o_def) 
   261 done
   262 
   263 (***** ( *f::nat=>nat) o ( *g::nat=>nat) = *(f o g) *****)
   264 lemma starfunNat2_o: "( *fNat2* f) o ( *fNat2* g) = ( *fNat2* (f o g))"
   265 apply (rule ext)
   266 apply (rule_tac z = x in eq_Abs_hypnat)
   267 apply (simp add: starfunNat2)
   268 done
   269 
   270 (***** ( *f::real=>real) o ( *g::nat=>real) = *(f o g) *****)
   271 
   272 lemma starfun_stafunNat_o: "( *f* f) o ( *fNat* g) = ( *fNat* (f o g))"
   273 apply (rule ext)
   274 apply (rule_tac z = x in eq_Abs_hypnat)
   275 apply (simp add: starfunNat starfun)
   276 done
   277 
   278 lemma starfun_stafunNat_o2:
   279      "(%x. ( *f* f) (( *fNat* g) x)) = ( *fNat* (%x. f (g x)))"
   280 apply (insert starfun_stafunNat_o [of f g]) 
   281 apply (simp add: o_def) 
   282 done
   283 
   284 
   285 text{*NS extension of constant function*}
   286 
   287 lemma starfunNat_const_fun [simp]: "( *fNat* (%x. k)) z = hypreal_of_real k"
   288 apply (cases z)
   289 apply (simp add: starfunNat hypreal_of_real_def)
   290 done
   291 
   292 lemma starfunNat2_const_fun [simp]: "( *fNat2* (%x. k)) z = hypnat_of_nat  k"
   293 apply (cases z)
   294 apply (simp add: starfunNat2 hypnat_of_nat_eq)
   295 done
   296 
   297 lemma starfunNat_minus: "- ( *fNat* f) x = ( *fNat* (%x. - f x)) x"
   298 apply (cases x)
   299 apply (simp add: starfunNat hypreal_minus)
   300 done
   301 
   302 lemma starfunNat_inverse:
   303      "inverse (( *fNat* f) x) = ( *fNat* (%x. inverse (f x))) x"
   304 apply (cases x)
   305 apply (simp add: starfunNat hypreal_inverse)
   306 done
   307 
   308 text{* Extended function has same solution as its standard
   309    version for natural arguments. i.e they are the same
   310    for all natural arguments (c.f. Hoskins pg. 107- SEQ)*}
   311 
   312 lemma starfunNat_eq [simp]:
   313      "( *fNat* f) (hypnat_of_nat a) = hypreal_of_real (f a)"
   314 by (simp add: starfunNat hypnat_of_nat_eq hypreal_of_real_def)
   315 
   316 lemma starfunNat2_eq [simp]:
   317      "( *fNat2* f) (hypnat_of_nat a) = hypnat_of_nat (f a)"
   318 by (simp add: starfunNat2 hypnat_of_nat_eq)
   319 
   320 lemma starfunNat_approx:
   321      "( *fNat* f) (hypnat_of_nat a) @= hypreal_of_real (f a)"
   322 by auto
   323 
   324 
   325 text{* Example of transfer of a property from reals to hyperreals
   326     --- used for limit comparison of sequences*}
   327 
   328 lemma starfun_le_mono:
   329      "\<forall>n. N \<le> n --> f n \<le> g n
   330       ==> \<forall>n. hypnat_of_nat N \<le> n --> ( *fNat* f) n \<le> ( *fNat* g) n"
   331 apply safe
   332 apply (rule_tac z = n in eq_Abs_hypnat)
   333 apply (auto simp add: starfunNat hypnat_of_nat_eq hypreal_le hypreal_less hypnat_le hypnat_less, ultra, auto)
   334 done
   335 
   336 (*****----- and another -----*****)
   337 lemma starfun_less_mono:
   338      "\<forall>n. N \<le> n --> f n < g n
   339       ==> \<forall>n. hypnat_of_nat N \<le> n --> ( *fNat* f) n < ( *fNat* g) n"
   340 apply safe
   341 apply (rule_tac z = n in eq_Abs_hypnat)
   342 apply (auto simp add: starfunNat hypnat_of_nat_eq hypreal_le hypreal_less hypnat_le hypnat_less, ultra, auto)
   343 done
   344 
   345 text{*Nonstandard extension when we increment the argument by one*}
   346 
   347 lemma starfunNat_shift_one:
   348      "( *fNat* (%n. f (Suc n))) N = ( *fNat* f) (N + (1::hypnat))"
   349 apply (cases N)
   350 apply (simp add: starfunNat hypnat_one_def hypnat_add)
   351 done
   352 
   353 text{*Nonstandard extension with absolute value*}
   354 
   355 lemma starfunNat_rabs: "( *fNat* (%n. abs (f n))) N = abs(( *fNat* f) N)"
   356 apply (cases N)
   357 apply (simp add: starfunNat hypreal_hrabs)
   358 done
   359 
   360 text{*The hyperpow function as a nonstandard extension of realpow*}
   361 
   362 lemma starfunNat_pow: "( *fNat* (%n. r ^ n)) N = (hypreal_of_real r) pow N"
   363 apply (cases N)
   364 apply (simp add: hyperpow hypreal_of_real_def starfunNat)
   365 done
   366 
   367 lemma starfunNat_pow2:
   368      "( *fNat* (%n. (X n) ^ m)) N = ( *fNat* X) N pow hypnat_of_nat m"
   369 apply (cases N)
   370 apply (simp add: hyperpow hypnat_of_nat_eq starfunNat)
   371 done
   372 
   373 lemma starfun_pow: "( *f* (%r. r ^ n)) R = (R) pow hypnat_of_nat n"
   374 apply (rule_tac z = R in eq_Abs_hypreal)
   375 apply (simp add: hyperpow starfun hypnat_of_nat_eq)
   376 done
   377 
   378 text{*The @{term hypreal_of_hypnat} function as a nonstandard extension of
   379   @{term real_of_nat} *}
   380 
   381 lemma starfunNat_real_of_nat: "( *fNat* real) = hypreal_of_hypnat"
   382 apply (rule ext)
   383 apply (rule_tac z = x in eq_Abs_hypnat)
   384 apply (simp add: hypreal_of_hypnat starfunNat)
   385 done
   386 
   387 lemma starfunNat_inverse_real_of_nat_eq:
   388      "N \<in> HNatInfinite
   389    ==> ( *fNat* (%x::nat. inverse(real x))) N = inverse(hypreal_of_hypnat N)"
   390 apply (rule_tac f1 = inverse in starfun_stafunNat_o2 [THEN subst])
   391 apply (subgoal_tac "hypreal_of_hypnat N ~= 0")
   392 apply (simp_all add: HNatInfinite_not_eq_zero starfunNat_real_of_nat starfun_inverse_inverse)
   393 done
   394 
   395 text{*Internal functions - some redundancy with *fNat* now*}
   396 
   397 lemma starfunNat_n_congruent:
   398       "(%X. hypnatrel``{%n. f n (X n)}) respects hypnatrel"
   399 by (auto simp add: congruent_def, ultra+)
   400 
   401 lemma starfunNat_n:
   402      "( *fNatn* f) (Abs_hypnat(hypnatrel``{%n. X n})) =
   403       Abs_hypreal(hyprel `` {%n. f n (X n)})"
   404 apply (simp add: starfunNat_n_def)
   405 apply (rule_tac f = Abs_hypreal in arg_cong, auto, ultra)
   406 done
   407 
   408 text{*Multiplication: @{text "( *fn) x ( *gn) = *(fn x gn)"}*}
   409 
   410 lemma starfunNat_n_mult:
   411      "( *fNatn* f) z * ( *fNatn* g) z = ( *fNatn* (% i x. f i x * g i x)) z"
   412 apply (cases z)
   413 apply (simp add: starfunNat_n hypreal_mult)
   414 done
   415 
   416 text{*Addition: @{text "( *fn) + ( *gn) = *(fn + gn)"}*}
   417 
   418 lemma starfunNat_n_add:
   419      "( *fNatn* f) z + ( *fNatn* g) z = ( *fNatn* (%i x. f i x + g i x)) z"
   420 apply (cases z)
   421 apply (simp add: starfunNat_n hypreal_add)
   422 done
   423 
   424 text{*Subtraction: @{text "( *fn) - ( *gn) = *(fn + - gn)"}*}
   425 
   426 lemma starfunNat_n_add_minus:
   427      "( *fNatn* f) z + -( *fNatn* g) z = ( *fNatn* (%i x. f i x + -g i x)) z"
   428 apply (cases z)
   429 apply (simp add: starfunNat_n hypreal_minus hypreal_add)
   430 done
   431 
   432 
   433 text{*Composition: @{text "( *fn) o ( *gn) = *(fn o gn)"}*}
   434 
   435 lemma starfunNat_n_const_fun [simp]:
   436      "( *fNatn* (%i x. k)) z = hypreal_of_real  k"
   437 apply (cases z)
   438 apply (simp add: starfunNat_n hypreal_of_real_def)
   439 done
   440 
   441 lemma starfunNat_n_minus: "- ( *fNatn* f) x = ( *fNatn* (%i x. - (f i) x)) x"
   442 apply (cases x)
   443 apply (simp add: starfunNat_n hypreal_minus)
   444 done
   445 
   446 lemma starfunNat_n_eq [simp]:
   447      "( *fNatn* f) (hypnat_of_nat n) = Abs_hypreal(hyprel `` {%i. f i n})"
   448 by (simp add: starfunNat_n hypnat_of_nat_eq)
   449 
   450 lemma starfun_eq_iff: "(( *fNat* f) = ( *fNat* g)) = (f = g)"
   451 apply auto
   452 apply (rule ext, rule ccontr)
   453 apply (drule_tac x = "hypnat_of_nat (x) " in fun_cong)
   454 apply (simp add: starfunNat hypnat_of_nat_eq)
   455 done
   456 
   457 
   458 lemma starfunNat_inverse_real_of_nat_Infinitesimal [simp]:
   459      "N \<in> HNatInfinite ==> ( *fNat* (%x. inverse (real x))) N \<in> Infinitesimal"
   460 apply (rule_tac f1 = inverse in starfun_stafunNat_o2 [THEN subst])
   461 apply (subgoal_tac "hypreal_of_hypnat N ~= 0")
   462 apply (simp_all add: HNatInfinite_not_eq_zero starfunNat_real_of_nat)
   463 done
   464 
   465 ML
   466 {*
   467 val starsetNat_def = thm "starsetNat_def";
   468 
   469 val NatStar_real_set = thm "NatStar_real_set";
   470 val NatStar_empty_set = thm "NatStar_empty_set";
   471 val NatStar_Un = thm "NatStar_Un";
   472 val starsetNat_n_Un = thm "starsetNat_n_Un";
   473 val InternalNatSets_Un = thm "InternalNatSets_Un";
   474 val NatStar_Int = thm "NatStar_Int";
   475 val starsetNat_n_Int = thm "starsetNat_n_Int";
   476 val InternalNatSets_Int = thm "InternalNatSets_Int";
   477 val NatStar_Compl = thm "NatStar_Compl";
   478 val starsetNat_n_Compl = thm "starsetNat_n_Compl";
   479 val InternalNatSets_Compl = thm "InternalNatSets_Compl";
   480 val starsetNat_n_diff = thm "starsetNat_n_diff";
   481 val InternalNatSets_diff = thm "InternalNatSets_diff";
   482 val NatStar_subset = thm "NatStar_subset";
   483 val NatStar_mem = thm "NatStar_mem";
   484 val NatStar_hypreal_of_real_image_subset = thm "NatStar_hypreal_of_real_image_subset";
   485 val NatStar_SHNat_subset = thm "NatStar_SHNat_subset";
   486 val NatStar_hypreal_of_real_Int = thm "NatStar_hypreal_of_real_Int";
   487 val starsetNat_starsetNat_n_eq = thm "starsetNat_starsetNat_n_eq";
   488 val InternalNatSets_starsetNat_n = thm "InternalNatSets_starsetNat_n";
   489 val InternalNatSets_UNIV_diff = thm "InternalNatSets_UNIV_diff";
   490 val starsetNat_n_starsetNat = thm "starsetNat_n_starsetNat";
   491 val starfunNat_n_starfunNat = thm "starfunNat_n_starfunNat";
   492 val starfunNat2_n_starfunNat2 = thm "starfunNat2_n_starfunNat2";
   493 val starfunNat_congruent = thm "starfunNat_congruent";
   494 val starfunNat = thm "starfunNat";
   495 val starfunNat2 = thm "starfunNat2";
   496 val starfunNat_mult = thm "starfunNat_mult";
   497 val starfunNat2_mult = thm "starfunNat2_mult";
   498 val starfunNat_add = thm "starfunNat_add";
   499 val starfunNat2_add = thm "starfunNat2_add";
   500 val starfunNat2_minus = thm "starfunNat2_minus";
   501 val starfunNatNat2_o = thm "starfunNatNat2_o";
   502 val starfunNatNat2_o2 = thm "starfunNatNat2_o2";
   503 val starfunNat2_o = thm "starfunNat2_o";
   504 val starfun_stafunNat_o = thm "starfun_stafunNat_o";
   505 val starfun_stafunNat_o2 = thm "starfun_stafunNat_o2";
   506 val starfunNat_const_fun = thm "starfunNat_const_fun";
   507 val starfunNat2_const_fun = thm "starfunNat2_const_fun";
   508 val starfunNat_minus = thm "starfunNat_minus";
   509 val starfunNat_inverse = thm "starfunNat_inverse";
   510 val starfunNat_eq = thm "starfunNat_eq";
   511 val starfunNat2_eq = thm "starfunNat2_eq";
   512 val starfunNat_approx = thm "starfunNat_approx";
   513 val starfun_le_mono = thm "starfun_le_mono";
   514 val starfun_less_mono = thm "starfun_less_mono";
   515 val starfunNat_shift_one = thm "starfunNat_shift_one";
   516 val starfunNat_rabs = thm "starfunNat_rabs";
   517 val starfunNat_pow = thm "starfunNat_pow";
   518 val starfunNat_pow2 = thm "starfunNat_pow2";
   519 val starfun_pow = thm "starfun_pow";
   520 val starfunNat_real_of_nat = thm "starfunNat_real_of_nat";
   521 val starfunNat_inverse_real_of_nat_eq = thm "starfunNat_inverse_real_of_nat_eq";
   522 val starfunNat_n_congruent = thm "starfunNat_n_congruent";
   523 val starfunNat_n = thm "starfunNat_n";
   524 val starfunNat_n_mult = thm "starfunNat_n_mult";
   525 val starfunNat_n_add = thm "starfunNat_n_add";
   526 val starfunNat_n_add_minus = thm "starfunNat_n_add_minus";
   527 val starfunNat_n_const_fun = thm "starfunNat_n_const_fun";
   528 val starfunNat_n_minus = thm "starfunNat_n_minus";
   529 val starfunNat_n_eq = thm "starfunNat_n_eq";
   530 val starfun_eq_iff = thm "starfun_eq_iff";
   531 val starfunNat_inverse_real_of_nat_Infinitesimal = thm "starfunNat_inverse_real_of_nat_Infinitesimal";
   532 *}
   533 
   534 
   535 
   536 subsection{*Nonstandard Characterization of Induction*}
   537 
   538 constdefs
   539 
   540   starPNat :: "(nat => bool) => hypnat => bool"  ("*pNat* _" [80] 80)
   541   "*pNat* P == (%x. \<exists>X. (X \<in> Rep_hypnat(x) &
   542                       {n. P(X n)} \<in> FreeUltrafilterNat))"
   543 
   544 
   545   starPNat2 :: "(nat => nat => bool) => hypnat =>hypnat => bool"
   546                ("*pNat2* _" [80] 80)
   547   "*pNat2* P == (%x y. \<exists>X. \<exists>Y. (X \<in> Rep_hypnat(x) & Y \<in> Rep_hypnat(y) &
   548                       {n. P(X n) (Y n)} \<in> FreeUltrafilterNat))"
   549 
   550   hSuc :: "hypnat => hypnat"
   551   "hSuc n == n + 1"
   552 
   553 
   554 lemma starPNat:
   555      "(( *pNat* P) (Abs_hypnat(hypnatrel``{%n. X n}))) =
   556       ({n. P (X n)} \<in> FreeUltrafilterNat)"
   557 by (auto simp add: starPNat_def, ultra)
   558 
   559 lemma starPNat_hypnat_of_nat [simp]: "( *pNat* P) (hypnat_of_nat n) = P n"
   560 by (auto simp add: starPNat hypnat_of_nat_eq)
   561 
   562 lemma hypnat_induct_obj:
   563     "(( *pNat* P) 0 &
   564             (\<forall>n. ( *pNat* P)(n) --> ( *pNat* P)(n + 1)))
   565        --> ( *pNat* P)(n)"
   566 apply (cases n)
   567 apply (auto simp add: hypnat_zero_def hypnat_one_def starPNat, ultra)
   568 apply (erule nat_induct)
   569 apply (drule_tac x = "hypnat_of_nat n" in spec)
   570 apply (rule ccontr)
   571 apply (auto simp add: starPNat hypnat_of_nat_eq hypnat_add)
   572 done
   573 
   574 lemma hypnat_induct:
   575   "[| ( *pNat* P) 0;
   576       !!n. ( *pNat* P)(n) ==> ( *pNat* P)(n + 1)|]
   577      ==> ( *pNat* P)(n)"
   578 by (insert hypnat_induct_obj [of P n], auto)
   579 
   580 lemma starPNat2:
   581 "(( *pNat2* P) (Abs_hypnat(hypnatrel``{%n. X n}))
   582              (Abs_hypnat(hypnatrel``{%n. Y n}))) =
   583       ({n. P (X n) (Y n)} \<in> FreeUltrafilterNat)"
   584 by (auto simp add: starPNat2_def, ultra)
   585 
   586 lemma starPNat2_eq_iff: "( *pNat2* (op =)) = (op =)"
   587 apply (simp add: starPNat2_def)
   588 apply (rule ext)
   589 apply (rule ext)
   590 apply (rule_tac z = x in eq_Abs_hypnat)
   591 apply (rule_tac z = y in eq_Abs_hypnat)
   592 apply (auto, ultra)
   593 done
   594 
   595 lemma starPNat2_eq_iff2: "( *pNat2* (%x y. x = y)) X Y = (X = Y)"
   596 by (simp add: starPNat2_eq_iff)
   597 
   598 lemma lemma_hyp: "(\<exists>h. P(h::hypnat)) = (\<exists>x. P(Abs_hypnat(hypnatrel `` {x})))"
   599 apply auto
   600 apply (rule_tac z = h in eq_Abs_hypnat, auto)
   601 done
   602 
   603 lemma hSuc_not_zero [iff]: "hSuc m \<noteq> 0"
   604 by (simp add: hSuc_def)
   605 
   606 lemmas zero_not_hSuc = hSuc_not_zero [THEN not_sym, standard, iff]
   607 
   608 lemma hSuc_hSuc_eq [iff]: "(hSuc m = hSuc n) = (m = n)"
   609 by (simp add: hSuc_def hypnat_one_def)
   610 
   611 lemma nonempty_nat_set_Least_mem: "c \<in> (S :: nat set) ==> (LEAST n. n  \<in> S)  \<in> S"
   612 by (erule LeastI)
   613 
   614 lemma nonempty_InternalNatSet_has_least:
   615     "[| S \<in> InternalNatSets; S \<noteq> {} |] ==> \<exists>n \<in> S. \<forall>m \<in> S. n \<le> m"
   616 apply (auto simp add: InternalNatSets_def starsetNat_n_def lemma_hyp)
   617 apply (rule_tac z = x in eq_Abs_hypnat)
   618 apply (auto dest!: bspec simp add: hypnat_le)
   619 apply (drule_tac x = "%m. LEAST n. n \<in> As m" in spec, auto)
   620 apply (ultra, force dest: nonempty_nat_set_Least_mem)
   621 apply (drule_tac x = x in bspec, auto)
   622 apply (ultra, auto intro: Least_le)
   623 done
   624 
   625 text{* Goldblatt page 129 Thm 11.3.2*}
   626 lemma internal_induct:
   627      "[| X \<in> InternalNatSets; 0 \<in> X; \<forall>n. n \<in> X --> n + 1 \<in> X |]
   628       ==> X = (UNIV:: hypnat set)"
   629 apply (rule ccontr)
   630 apply (frule InternalNatSets_Compl)
   631 apply (drule_tac S = "- X" in nonempty_InternalNatSet_has_least, auto)
   632 apply (subgoal_tac "1 \<le> n")
   633 apply (drule_tac x = "n - 1" in bspec, safe)
   634 apply (drule_tac x = "n - 1" in spec)
   635 apply (drule_tac [2] c = 1 and a = n in add_right_mono)
   636 apply (auto simp add: linorder_not_less [symmetric] iff del: hypnat_neq0_conv)
   637 done
   638 
   639 
   640 end
   641 
   642