src/HOL/Hyperreal/Deriv.thy
changeset 22653 8e016bfdbf2f
parent 22641 a5dc96fad632
child 22984 67d434ad9ef8
equal deleted inserted replaced
22652:c90a3b98473e 22653:8e016bfdbf2f
     7 *)
     7 *)
     8 
     8 
     9 header{* Differentiation *}
     9 header{* Differentiation *}
    10 
    10 
    11 theory Deriv
    11 theory Deriv
    12 imports HLim
    12 imports Lim
    13 begin
    13 begin
    14 
    14 
    15 text{*Standard and Nonstandard Definitions*}
    15 text{*Standard and Nonstandard Definitions*}
    16 
    16 
    17 definition
    17 definition
    19     --{*Differentiation: D is derivative of function f at x*}
    19     --{*Differentiation: D is derivative of function f at x*}
    20           ("(DERIV (_)/ (_)/ :> (_))" [1000, 1000, 60] 60) where
    20           ("(DERIV (_)/ (_)/ :> (_))" [1000, 1000, 60] 60) where
    21   "DERIV f x :> D = ((%h. (f(x + h) - f x) / h) -- 0 --> D)"
    21   "DERIV f x :> D = ((%h. (f(x + h) - f x) / h) -- 0 --> D)"
    22 
    22 
    23 definition
    23 definition
    24   nsderiv :: "['a::real_normed_field \<Rightarrow> 'a, 'a, 'a] \<Rightarrow> bool"
       
    25           ("(NSDERIV (_)/ (_)/ :> (_))" [1000, 1000, 60] 60) where
       
    26   "NSDERIV f x :> D = (\<forall>h \<in> Infinitesimal - {0}.
       
    27       (( *f* f)(star_of x + h)
       
    28        - star_of (f x))/h @= star_of D)"
       
    29 
       
    30 definition
       
    31   differentiable :: "['a::real_normed_field \<Rightarrow> 'a, 'a] \<Rightarrow> bool"
    24   differentiable :: "['a::real_normed_field \<Rightarrow> 'a, 'a] \<Rightarrow> bool"
    32     (infixl "differentiable" 60) where
    25     (infixl "differentiable" 60) where
    33   "f differentiable x = (\<exists>D. DERIV f x :> D)"
    26   "f differentiable x = (\<exists>D. DERIV f x :> D)"
    34 
       
    35 definition
       
    36   NSdifferentiable :: "['a::real_normed_field \<Rightarrow> 'a, 'a] \<Rightarrow> bool"
       
    37     (infixl "NSdifferentiable" 60) where
       
    38   "f NSdifferentiable x = (\<exists>D. NSDERIV f x :> D)"
       
    39 
       
    40 definition
       
    41   increment :: "[real=>real,real,hypreal] => hypreal" where
       
    42   "increment f x h = (@inc. f NSdifferentiable x &
       
    43            inc = ( *f* f)(hypreal_of_real x + h) - hypreal_of_real (f x))"
       
    44 
    27 
    45 
    28 
    46 consts
    29 consts
    47   Bolzano_bisect :: "[real*real=>bool, real, real, nat] => (real*real)"
    30   Bolzano_bisect :: "[real*real=>bool, real, real, nat] => (real*real)"
    48 primrec
    31 primrec
   297     by (rule LIM_mult [OF _ f [unfolded DERIV_iff2]])
   280     by (rule LIM_mult [OF _ f [unfolded DERIV_iff2]])
   298   thus "(\<lambda>z. (g (f z) - g (f x)) / (z - x)) -- x --> E * D"
   281   thus "(\<lambda>z. (g (f z) - g (f x)) / (z - x)) -- x --> E * D"
   299     by (simp add: d dfx real_scaleR_def)
   282     by (simp add: d dfx real_scaleR_def)
   300 qed
   283 qed
   301 
   284 
   302 
       
   303 subsubsection {* Nonstandard proofs *}
       
   304 
       
   305 lemma DERIV_NS_iff:
       
   306       "(DERIV f x :> D) = ((%h. (f(x + h) - f(x))/h) -- 0 --NS> D)"
       
   307 by (simp add: deriv_def LIM_NSLIM_iff)
       
   308 
       
   309 lemma NS_DERIV_D: "DERIV f x :> D ==> (%h. (f(x + h) - f(x))/h) -- 0 --NS> D"
       
   310 by (simp add: deriv_def LIM_NSLIM_iff)
       
   311 
       
   312 lemma hnorm_of_hypreal:
       
   313   "\<And>r. hnorm (( *f* of_real) r::'a::real_normed_div_algebra star) = \<bar>r\<bar>"
       
   314 by transfer (rule norm_of_real)
       
   315 
       
   316 lemma Infinitesimal_of_hypreal:
       
   317   "x \<in> Infinitesimal \<Longrightarrow>
       
   318    (( *f* of_real) x::'a::real_normed_div_algebra star) \<in> Infinitesimal"
       
   319 apply (rule InfinitesimalI2)
       
   320 apply (drule (1) InfinitesimalD2)
       
   321 apply (simp add: hnorm_of_hypreal)
       
   322 done
       
   323 
       
   324 lemma of_hypreal_eq_0_iff:
       
   325   "\<And>x. (( *f* of_real) x = (0::'a::real_algebra_1 star)) = (x = 0)"
       
   326 by transfer (rule of_real_eq_0_iff)
       
   327 
       
   328 lemma NSDeriv_unique:
       
   329      "[| NSDERIV f x :> D; NSDERIV f x :> E |] ==> D = E"
       
   330 apply (subgoal_tac "( *f* of_real) epsilon \<in> Infinitesimal - {0::'a star}")
       
   331 apply (simp only: nsderiv_def)
       
   332 apply (drule (1) bspec)+
       
   333 apply (drule (1) approx_trans3)
       
   334 apply simp
       
   335 apply (simp add: Infinitesimal_of_hypreal Infinitesimal_epsilon)
       
   336 apply (simp add: of_hypreal_eq_0_iff hypreal_epsilon_not_zero)
       
   337 done
       
   338 
       
   339 text {*First NSDERIV in terms of NSLIM*}
       
   340 
       
   341 text{*first equivalence *}
       
   342 lemma NSDERIV_NSLIM_iff:
       
   343       "(NSDERIV f x :> D) = ((%h. (f(x + h) - f(x))/h) -- 0 --NS> D)"
       
   344 apply (simp add: nsderiv_def NSLIM_def, auto)
       
   345 apply (drule_tac x = xa in bspec)
       
   346 apply (rule_tac [3] ccontr)
       
   347 apply (drule_tac [3] x = h in spec)
       
   348 apply (auto simp add: mem_infmal_iff starfun_lambda_cancel)
       
   349 done
       
   350 
       
   351 text{*second equivalence *}
       
   352 lemma NSDERIV_NSLIM_iff2:
       
   353      "(NSDERIV f x :> D) = ((%z. (f(z) - f(x)) / (z-x)) -- x --NS> D)"
       
   354 by (simp add: NSDERIV_NSLIM_iff DERIV_LIM_iff  diff_minus [symmetric]
       
   355               LIM_NSLIM_iff [symmetric])
       
   356 
       
   357 (* while we're at it! *)
       
   358 lemma NSDERIV_iff2:
       
   359      "(NSDERIV f x :> D) =
       
   360       (\<forall>w.
       
   361         w \<noteq> star_of x & w \<approx> star_of x -->
       
   362         ( *f* (%z. (f z - f x) / (z-x))) w \<approx> star_of D)"
       
   363 by (simp add: NSDERIV_NSLIM_iff2 NSLIM_def)
       
   364 
       
   365 (*FIXME DELETE*)
       
   366 lemma hypreal_not_eq_minus_iff:
       
   367   "(x \<noteq> a) = (x - a \<noteq> (0::'a::ab_group_add))"
       
   368 by auto
       
   369 
       
   370 lemma NSDERIVD5:
       
   371   "(NSDERIV f x :> D) ==>
       
   372    (\<forall>u. u \<approx> hypreal_of_real x -->
       
   373      ( *f* (%z. f z - f x)) u \<approx> hypreal_of_real D * (u - hypreal_of_real x))"
       
   374 apply (auto simp add: NSDERIV_iff2)
       
   375 apply (case_tac "u = hypreal_of_real x", auto)
       
   376 apply (drule_tac x = u in spec, auto)
       
   377 apply (drule_tac c = "u - hypreal_of_real x" and b = "hypreal_of_real D" in approx_mult1)
       
   378 apply (drule_tac [!] hypreal_not_eq_minus_iff [THEN iffD1])
       
   379 apply (subgoal_tac [2] "( *f* (%z. z-x)) u \<noteq> (0::hypreal) ")
       
   380 apply (auto simp add:
       
   381          approx_minus_iff [THEN iffD1, THEN mem_infmal_iff [THEN iffD2]]
       
   382          Infinitesimal_subset_HFinite [THEN subsetD])
       
   383 done
       
   384 
       
   385 lemma NSDERIVD4:
       
   386      "(NSDERIV f x :> D) ==>
       
   387       (\<forall>h \<in> Infinitesimal.
       
   388                (( *f* f)(hypreal_of_real x + h) -
       
   389                  hypreal_of_real (f x))\<approx> (hypreal_of_real D) * h)"
       
   390 apply (auto simp add: nsderiv_def)
       
   391 apply (case_tac "h = (0::hypreal) ")
       
   392 apply (auto simp add: diff_minus)
       
   393 apply (drule_tac x = h in bspec)
       
   394 apply (drule_tac [2] c = h in approx_mult1)
       
   395 apply (auto intro: Infinitesimal_subset_HFinite [THEN subsetD]
       
   396             simp add: diff_minus)
       
   397 done
       
   398 
       
   399 lemma NSDERIVD3:
       
   400      "(NSDERIV f x :> D) ==>
       
   401       (\<forall>h \<in> Infinitesimal - {0}.
       
   402                (( *f* f)(hypreal_of_real x + h) -
       
   403                  hypreal_of_real (f x))\<approx> (hypreal_of_real D) * h)"
       
   404 apply (auto simp add: nsderiv_def)
       
   405 apply (rule ccontr, drule_tac x = h in bspec)
       
   406 apply (drule_tac [2] c = h in approx_mult1)
       
   407 apply (auto intro: Infinitesimal_subset_HFinite [THEN subsetD]
       
   408             simp add: mult_assoc diff_minus)
       
   409 done
       
   410 
       
   411 text{*Differentiability implies continuity
       
   412          nice and simple "algebraic" proof*}
       
   413 lemma NSDERIV_isNSCont: "NSDERIV f x :> D ==> isNSCont f x"
       
   414 apply (auto simp add: nsderiv_def isNSCont_NSLIM_iff NSLIM_def)
       
   415 apply (drule approx_minus_iff [THEN iffD1])
       
   416 apply (drule hypreal_not_eq_minus_iff [THEN iffD1])
       
   417 apply (drule_tac x = "xa - star_of x" in bspec)
       
   418  prefer 2 apply (simp add: add_assoc [symmetric])
       
   419 apply (auto simp add: mem_infmal_iff [symmetric] add_commute)
       
   420 apply (drule_tac c = "xa - star_of x" in approx_mult1)
       
   421 apply (auto intro: Infinitesimal_subset_HFinite [THEN subsetD]
       
   422             simp add: mult_assoc nonzero_mult_divide_cancel_right)
       
   423 apply (drule_tac x3=D in
       
   424            HFinite_star_of [THEN [2] Infinitesimal_HFinite_mult,
       
   425              THEN mem_infmal_iff [THEN iffD1]])
       
   426 apply (auto simp add: mult_commute
       
   427             intro: approx_trans approx_minus_iff [THEN iffD2])
       
   428 done
       
   429 
       
   430 text{*Differentiation rules for combinations of functions
       
   431       follow from clear, straightforard, algebraic
       
   432       manipulations*}
       
   433 text{*Constant function*}
       
   434 
       
   435 (* use simple constant nslimit theorem *)
       
   436 lemma NSDERIV_const [simp]: "(NSDERIV (%x. k) x :> 0)"
       
   437 by (simp add: NSDERIV_NSLIM_iff)
       
   438 
       
   439 text{*Sum of functions- proved easily*}
       
   440 
       
   441 lemma NSDERIV_add: "[| NSDERIV f x :> Da;  NSDERIV g x :> Db |]
       
   442       ==> NSDERIV (%x. f x + g x) x :> Da + Db"
       
   443 apply (auto simp add: NSDERIV_NSLIM_iff NSLIM_def)
       
   444 apply (auto simp add: add_divide_distrib diff_divide_distrib dest!: spec)
       
   445 apply (drule_tac b = "star_of Da" and d = "star_of Db" in approx_add)
       
   446 apply (auto simp add: diff_def add_ac)
       
   447 done
       
   448 
       
   449 text{*Product of functions - Proof is trivial but tedious
       
   450   and long due to rearrangement of terms*}
       
   451 
       
   452 lemma lemma_nsderiv1:
       
   453   fixes a b c d :: "'a::comm_ring star"
       
   454   shows "(a*b) - (c*d) = (b*(a - c)) + (c*(b - d))"
       
   455 by (simp add: right_diff_distrib mult_ac)
       
   456 
       
   457 lemma lemma_nsderiv2:
       
   458   fixes x y z :: "'a::real_normed_field star"
       
   459   shows "[| (x - y) / z = star_of D + yb; z \<noteq> 0;
       
   460          z \<in> Infinitesimal; yb \<in> Infinitesimal |]
       
   461       ==> x - y \<approx> 0"
       
   462 apply (simp add: nonzero_divide_eq_eq)
       
   463 apply (auto intro!: Infinitesimal_HFinite_mult2 HFinite_add
       
   464             simp add: mult_assoc mem_infmal_iff [symmetric])
       
   465 apply (erule Infinitesimal_subset_HFinite [THEN subsetD])
       
   466 done
       
   467 
       
   468 lemma NSDERIV_mult: "[| NSDERIV f x :> Da; NSDERIV g x :> Db |]
       
   469       ==> NSDERIV (%x. f x * g x) x :> (Da * g(x)) + (Db * f(x))"
       
   470 apply (auto simp add: NSDERIV_NSLIM_iff NSLIM_def)
       
   471 apply (auto dest!: spec
       
   472       simp add: starfun_lambda_cancel lemma_nsderiv1)
       
   473 apply (simp (no_asm) add: add_divide_distrib diff_divide_distrib)
       
   474 apply (drule bex_Infinitesimal_iff2 [THEN iffD2])+
       
   475 apply (auto simp add: times_divide_eq_right [symmetric]
       
   476             simp del: times_divide_eq)
       
   477 apply (drule_tac D = Db in lemma_nsderiv2, assumption+)
       
   478 apply (drule_tac
       
   479      approx_minus_iff [THEN iffD2, THEN bex_Infinitesimal_iff2 [THEN iffD2]])
       
   480 apply (auto intro!: approx_add_mono1
       
   481             simp add: left_distrib right_distrib mult_commute add_assoc)
       
   482 apply (rule_tac b1 = "star_of Db * star_of (f x)"
       
   483          in add_commute [THEN subst])
       
   484 apply (auto intro!: Infinitesimal_add_approx_self2 [THEN approx_sym]
       
   485                     Infinitesimal_add Infinitesimal_mult
       
   486                     Infinitesimal_star_of_mult
       
   487                     Infinitesimal_star_of_mult2
       
   488           simp add: add_assoc [symmetric])
       
   489 done
       
   490 
       
   491 text{*Multiplying by a constant*}
       
   492 lemma NSDERIV_cmult: "NSDERIV f x :> D
       
   493       ==> NSDERIV (%x. c * f x) x :> c*D"
       
   494 apply (simp only: times_divide_eq_right [symmetric] NSDERIV_NSLIM_iff
       
   495                   minus_mult_right right_diff_distrib [symmetric])
       
   496 apply (erule NSLIM_const [THEN NSLIM_mult])
       
   497 done
       
   498 
       
   499 text{*Negation of function*}
       
   500 lemma NSDERIV_minus: "NSDERIV f x :> D ==> NSDERIV (%x. -(f x)) x :> -D"
       
   501 proof (simp add: NSDERIV_NSLIM_iff)
       
   502   assume "(\<lambda>h. (f (x + h) - f x) / h) -- 0 --NS> D"
       
   503   hence deriv: "(\<lambda>h. - ((f(x+h) - f x) / h)) -- 0 --NS> - D"
       
   504     by (rule NSLIM_minus)
       
   505   have "\<forall>h. - ((f (x + h) - f x) / h) = (- f (x + h) + f x) / h"
       
   506     by (simp add: minus_divide_left diff_def)
       
   507   with deriv
       
   508   show "(\<lambda>h. (- f (x + h) + f x) / h) -- 0 --NS> - D" by simp
       
   509 qed
       
   510 
       
   511 text{*Subtraction*}
       
   512 lemma NSDERIV_add_minus: "[| NSDERIV f x :> Da; NSDERIV g x :> Db |] ==> NSDERIV (%x. f x + -g x) x :> Da + -Db"
       
   513 by (blast dest: NSDERIV_add NSDERIV_minus)
       
   514 
       
   515 lemma NSDERIV_diff:
       
   516      "[| NSDERIV f x :> Da; NSDERIV g x :> Db |]
       
   517       ==> NSDERIV (%x. f x - g x) x :> Da-Db"
       
   518 apply (simp add: diff_minus)
       
   519 apply (blast intro: NSDERIV_add_minus)
       
   520 done
       
   521 
       
   522 text{*  Similarly to the above, the chain rule admits an entirely
       
   523    straightforward derivation. Compare this with Harrison's
       
   524    HOL proof of the chain rule, which proved to be trickier and
       
   525    required an alternative characterisation of differentiability-
       
   526    the so-called Carathedory derivative. Our main problem is
       
   527    manipulation of terms.*}
       
   528 
       
   529 
       
   530 (* lemmas *)
       
   531 lemma NSDERIV_zero:
       
   532       "[| NSDERIV g x :> D;
       
   533                ( *f* g) (star_of x + xa) = star_of (g x);
       
   534                xa \<in> Infinitesimal;
       
   535                xa \<noteq> 0
       
   536             |] ==> D = 0"
       
   537 apply (simp add: nsderiv_def)
       
   538 apply (drule bspec, auto)
       
   539 done
       
   540 
       
   541 (* can be proved differently using NSLIM_isCont_iff *)
       
   542 lemma NSDERIV_approx:
       
   543      "[| NSDERIV f x :> D;  h \<in> Infinitesimal;  h \<noteq> 0 |]
       
   544       ==> ( *f* f) (star_of x + h) - star_of (f x) \<approx> 0"
       
   545 apply (simp add: nsderiv_def)
       
   546 apply (simp add: mem_infmal_iff [symmetric])
       
   547 apply (rule Infinitesimal_ratio)
       
   548 apply (rule_tac [3] approx_star_of_HFinite, auto)
       
   549 done
       
   550 
       
   551 (*---------------------------------------------------------------
       
   552    from one version of differentiability
       
   553 
       
   554                 f(x) - f(a)
       
   555               --------------- \<approx> Db
       
   556                   x - a
       
   557  ---------------------------------------------------------------*)
       
   558 lemma NSDERIVD1: "[| NSDERIV f (g x) :> Da;
       
   559          ( *f* g) (star_of(x) + xa) \<noteq> star_of (g x);
       
   560          ( *f* g) (star_of(x) + xa) \<approx> star_of (g x)
       
   561       |] ==> (( *f* f) (( *f* g) (star_of(x) + xa))
       
   562                    - star_of (f (g x)))
       
   563               / (( *f* g) (star_of(x) + xa) - star_of (g x))
       
   564              \<approx> star_of(Da)"
       
   565 by (auto simp add: NSDERIV_NSLIM_iff2 NSLIM_def diff_minus [symmetric])
       
   566 
       
   567 (*--------------------------------------------------------------
       
   568    from other version of differentiability
       
   569 
       
   570                 f(x + h) - f(x)
       
   571                ----------------- \<approx> Db
       
   572                        h
       
   573  --------------------------------------------------------------*)
       
   574 lemma NSDERIVD2: "[| NSDERIV g x :> Db; xa \<in> Infinitesimal; xa \<noteq> 0 |]
       
   575       ==> (( *f* g) (star_of(x) + xa) - star_of(g x)) / xa
       
   576           \<approx> star_of(Db)"
       
   577 by (auto simp add: NSDERIV_NSLIM_iff NSLIM_def mem_infmal_iff starfun_lambda_cancel)
       
   578 
       
   579 lemma lemma_chain: "(z::'a::real_normed_field star) \<noteq> 0 ==> x*y = (x*inverse(z))*(z*y)"
       
   580 proof -
       
   581   assume z: "z \<noteq> 0"
       
   582   have "x * y = x * (inverse z * z) * y" by (simp add: z)
       
   583   thus ?thesis by (simp add: mult_assoc)
       
   584 qed
       
   585 
       
   586 text{*This proof uses both definitions of differentiability.*}
       
   587 lemma NSDERIV_chain: "[| NSDERIV f (g x) :> Da; NSDERIV g x :> Db |]
       
   588       ==> NSDERIV (f o g) x :> Da * Db"
       
   589 apply (simp (no_asm_simp) add: NSDERIV_NSLIM_iff NSLIM_def
       
   590                 mem_infmal_iff [symmetric])
       
   591 apply clarify
       
   592 apply (frule_tac f = g in NSDERIV_approx)
       
   593 apply (auto simp add: starfun_lambda_cancel2 starfun_o [symmetric])
       
   594 apply (case_tac "( *f* g) (star_of (x) + xa) = star_of (g x) ")
       
   595 apply (drule_tac g = g in NSDERIV_zero)
       
   596 apply (auto simp add: divide_inverse)
       
   597 apply (rule_tac z1 = "( *f* g) (star_of (x) + xa) - star_of (g x) " and y1 = "inverse xa" in lemma_chain [THEN ssubst])
       
   598 apply (erule hypreal_not_eq_minus_iff [THEN iffD1])
       
   599 apply (rule approx_mult_star_of)
       
   600 apply (simp_all add: divide_inverse [symmetric])
       
   601 apply (blast intro: NSDERIVD1 approx_minus_iff [THEN iffD2])
       
   602 apply (blast intro: NSDERIVD2)
       
   603 done
       
   604 
       
   605 text{*Differentiation of natural number powers*}
       
   606 lemma NSDERIV_Id [simp]: "NSDERIV (%x. x) x :> 1"
       
   607 by (simp add: NSDERIV_NSLIM_iff NSLIM_def divide_self del: divide_self_if)
       
   608 
       
   609 lemma NSDERIV_cmult_Id [simp]: "NSDERIV (op * c) x :> c"
       
   610 by (cut_tac c = c and x = x in NSDERIV_Id [THEN NSDERIV_cmult], simp)
       
   611 
       
   612 (*Can't get rid of x \<noteq> 0 because it isn't continuous at zero*)
       
   613 lemma NSDERIV_inverse:
       
   614   fixes x :: "'a::{real_normed_field,recpower}"
       
   615   shows "x \<noteq> 0 ==> NSDERIV (%x. inverse(x)) x :> (- (inverse x ^ Suc (Suc 0)))"
       
   616 apply (simp add: nsderiv_def)
       
   617 apply (rule ballI, simp, clarify)
       
   618 apply (frule (1) Infinitesimal_add_not_zero)
       
   619 apply (simp add: add_commute)
       
   620 (*apply (auto simp add: starfun_inverse_inverse realpow_two
       
   621         simp del: minus_mult_left [symmetric] minus_mult_right [symmetric])*)
       
   622 apply (simp add: inverse_add nonzero_inverse_mult_distrib [symmetric] power_Suc
       
   623               nonzero_inverse_minus_eq [symmetric] add_ac mult_ac diff_def
       
   624             del: inverse_mult_distrib inverse_minus_eq
       
   625                  minus_mult_left [symmetric] minus_mult_right [symmetric])
       
   626 apply (subst mult_commute, simp add: nonzero_mult_divide_cancel_right)
       
   627 apply (simp (no_asm_simp) add: mult_assoc [symmetric] right_distrib
       
   628             del: minus_mult_left [symmetric] minus_mult_right [symmetric])
       
   629 apply (rule_tac y = "inverse (- (star_of x * star_of x))" in approx_trans)
       
   630 apply (rule inverse_add_Infinitesimal_approx2)
       
   631 apply (auto dest!: hypreal_of_real_HFinite_diff_Infinitesimal
       
   632             simp add: inverse_minus_eq [symmetric] HFinite_minus_iff)
       
   633 apply (rule Infinitesimal_HFinite_mult2, auto)
       
   634 done
       
   635 
       
   636 subsubsection {* Equivalence of NS and Standard definitions *}
       
   637 
       
   638 lemma divideR_eq_divide: "x /# y = x / y"
       
   639 by (simp add: real_scaleR_def divide_inverse mult_commute)
       
   640 
       
   641 text{*Now equivalence between NSDERIV and DERIV*}
       
   642 lemma NSDERIV_DERIV_iff: "(NSDERIV f x :> D) = (DERIV f x :> D)"
       
   643 by (simp add: deriv_def NSDERIV_NSLIM_iff LIM_NSLIM_iff)
       
   644 
       
   645 (* let's do the standard proof though theorem *)
   285 (* let's do the standard proof though theorem *)
   646 (* LIM_mult2 follows from a NS proof          *)
   286 (* LIM_mult2 follows from a NS proof          *)
   647 
   287 
   648 lemma DERIV_cmult:
   288 lemma DERIV_cmult:
   649       "DERIV f x :> D ==> DERIV (%x. c * f x) x :> c*D"
   289       "DERIV f x :> D ==> DERIV (%x. c * f x) x :> c*D"
   662 
   302 
   663 lemma DERIV_pow: "DERIV (%x. x ^ n) x :> real n * (x ^ (n - Suc 0))"
   303 lemma DERIV_pow: "DERIV (%x. x ^ n) x :> real n * (x ^ (n - Suc 0))"
   664 apply (cut_tac DERIV_power [OF DERIV_Id])
   304 apply (cut_tac DERIV_power [OF DERIV_Id])
   665 apply (simp add: real_scaleR_def real_of_nat_def)
   305 apply (simp add: real_scaleR_def real_of_nat_def)
   666 done
   306 done
   667 
       
   668 (* NS version *)
       
   669 lemma NSDERIV_pow: "NSDERIV (%x. x ^ n) x :> real n * (x ^ (n - Suc 0))"
       
   670 by (simp add: NSDERIV_DERIV_iff DERIV_pow)
       
   671 
   307 
   672 text{*Power of -1*}
   308 text{*Power of -1*}
   673 
   309 
   674 lemma DERIV_inverse:
   310 lemma DERIV_inverse:
   675   fixes x :: "'a::{real_normed_field,recpower}"
   311   fixes x :: "'a::{real_normed_field,recpower}"
   681   fixes x :: "'a::{real_normed_field,recpower}"
   317   fixes x :: "'a::{real_normed_field,recpower}"
   682   shows "[| DERIV f x :> d; f(x) \<noteq> 0 |]
   318   shows "[| DERIV f x :> d; f(x) \<noteq> 0 |]
   683       ==> DERIV (%x. inverse(f x)) x :> (- (d * inverse(f(x) ^ Suc (Suc 0))))"
   319       ==> DERIV (%x. inverse(f x)) x :> (- (d * inverse(f(x) ^ Suc (Suc 0))))"
   684 by (drule (1) DERIV_inverse') (simp add: mult_ac power_Suc nonzero_inverse_mult_distrib)
   320 by (drule (1) DERIV_inverse') (simp add: mult_ac power_Suc nonzero_inverse_mult_distrib)
   685 
   321 
   686 lemma NSDERIV_inverse_fun:
       
   687   fixes x :: "'a::{real_normed_field,recpower}"
       
   688   shows "[| NSDERIV f x :> d; f(x) \<noteq> 0 |]
       
   689       ==> NSDERIV (%x. inverse(f x)) x :> (- (d * inverse(f(x) ^ Suc (Suc 0))))"
       
   690 by (simp add: NSDERIV_DERIV_iff DERIV_inverse_fun del: realpow_Suc)
       
   691 
       
   692 text{*Derivative of quotient*}
   322 text{*Derivative of quotient*}
   693 lemma DERIV_quotient:
   323 lemma DERIV_quotient:
   694   fixes x :: "'a::{real_normed_field,recpower}"
   324   fixes x :: "'a::{real_normed_field,recpower}"
   695   shows "[| DERIV f x :> d; DERIV g x :> e; g(x) \<noteq> 0 |]
   325   shows "[| DERIV f x :> d; DERIV g x :> e; g(x) \<noteq> 0 |]
   696        ==> DERIV (%y. f(y) / (g y)) x :> (d*g(x) - (e*f(x))) / (g(x) ^ Suc (Suc 0))"
   326        ==> DERIV (%y. f(y) / (g y)) x :> (d*g(x) - (e*f(x))) / (g(x) ^ Suc (Suc 0))"
   697 by (drule (2) DERIV_divide) (simp add: mult_commute power_Suc)
   327 by (drule (2) DERIV_divide) (simp add: mult_commute power_Suc)
   698 
   328 
   699 lemma NSDERIV_quotient:
       
   700   fixes x :: "'a::{real_normed_field,recpower}"
       
   701   shows "[| NSDERIV f x :> d; NSDERIV g x :> e; g(x) \<noteq> 0 |]
       
   702        ==> NSDERIV (%y. f(y) / (g y)) x :> (d*g(x)
       
   703                             - (e*f(x))) / (g(x) ^ Suc (Suc 0))"
       
   704 by (simp add: NSDERIV_DERIV_iff DERIV_quotient del: realpow_Suc)
       
   705 
       
   706 lemma CARAT_NSDERIV: "NSDERIV f x :> l ==>
       
   707       \<exists>g. (\<forall>z. f z - f x = g z * (z-x)) & isNSCont g x & g x = l"
       
   708 by (auto simp add: NSDERIV_DERIV_iff isNSCont_isCont_iff CARAT_DERIV
       
   709                    mult_commute)
       
   710 
       
   711 lemma hypreal_eq_minus_iff3: "(x = y + z) = (x + -z = (y::hypreal))"
       
   712 by auto
       
   713 
       
   714 lemma CARAT_DERIVD:
       
   715   assumes all: "\<forall>z. f z - f x = g z * (z-x)"
       
   716       and nsc: "isNSCont g x"
       
   717   shows "NSDERIV f x :> g x"
       
   718 proof -
       
   719   from nsc
       
   720   have "\<forall>w. w \<noteq> star_of x \<and> w \<approx> star_of x \<longrightarrow>
       
   721          ( *f* g) w * (w - star_of x) / (w - star_of x) \<approx>
       
   722          star_of (g x)"
       
   723     by (simp add: isNSCont_def nonzero_mult_divide_cancel_right)
       
   724   thus ?thesis using all
       
   725     by (simp add: NSDERIV_iff2 starfun_if_eq cong: if_cong)
       
   726 qed
       
   727 
       
   728 subsubsection {* Differentiability predicate *}
   329 subsubsection {* Differentiability predicate *}
   729 
   330 
   730 lemma differentiableD: "f differentiable x ==> \<exists>D. DERIV f x :> D"
   331 lemma differentiableD: "f differentiable x ==> \<exists>D. DERIV f x :> D"
   731 by (simp add: differentiable_def)
   332 by (simp add: differentiable_def)
   732 
   333 
   733 lemma differentiableI: "DERIV f x :> D ==> f differentiable x"
   334 lemma differentiableI: "DERIV f x :> D ==> f differentiable x"
   734 by (force simp add: differentiable_def)
   335 by (force simp add: differentiable_def)
   735 
       
   736 lemma NSdifferentiableD: "f NSdifferentiable x ==> \<exists>D. NSDERIV f x :> D"
       
   737 by (simp add: NSdifferentiable_def)
       
   738 
       
   739 lemma NSdifferentiableI: "NSDERIV f x :> D ==> f NSdifferentiable x"
       
   740 by (force simp add: NSdifferentiable_def)
       
   741 
   336 
   742 lemma differentiable_const: "(\<lambda>z. a) differentiable x"
   337 lemma differentiable_const: "(\<lambda>z. a) differentiable x"
   743   apply (unfold differentiable_def)
   338   apply (unfold differentiable_def)
   744   apply (rule_tac x=0 in exI)
   339   apply (rule_tac x=0 in exI)
   745   apply simp
   340   apply simp
   787   then obtain dg where "DERIV g x :> dg" ..
   382   then obtain dg where "DERIV g x :> dg" ..
   788   ultimately have "DERIV (\<lambda>x. f x * g x) x :> df * g x + dg * f x" by (simp add: DERIV_mult)
   383   ultimately have "DERIV (\<lambda>x. f x * g x) x :> df * g x + dg * f x" by (simp add: DERIV_mult)
   789   hence "\<exists>D. DERIV (\<lambda>x. f x * g x) x :> D" by auto
   384   hence "\<exists>D. DERIV (\<lambda>x. f x * g x) x :> D" by auto
   790   thus ?thesis by (fold differentiable_def)
   385   thus ?thesis by (fold differentiable_def)
   791 qed
   386 qed
   792 
       
   793 subsection {*(NS) Increment*}
       
   794 lemma incrementI:
       
   795       "f NSdifferentiable x ==>
       
   796       increment f x h = ( *f* f) (hypreal_of_real(x) + h) -
       
   797       hypreal_of_real (f x)"
       
   798 by (simp add: increment_def)
       
   799 
       
   800 lemma incrementI2: "NSDERIV f x :> D ==>
       
   801      increment f x h = ( *f* f) (hypreal_of_real(x) + h) -
       
   802      hypreal_of_real (f x)"
       
   803 apply (erule NSdifferentiableI [THEN incrementI])
       
   804 done
       
   805 
       
   806 (* The Increment theorem -- Keisler p. 65 *)
       
   807 lemma increment_thm: "[| NSDERIV f x :> D; h \<in> Infinitesimal; h \<noteq> 0 |]
       
   808       ==> \<exists>e \<in> Infinitesimal. increment f x h = hypreal_of_real(D)*h + e*h"
       
   809 apply (frule_tac h = h in incrementI2, simp add: nsderiv_def)
       
   810 apply (drule bspec, auto)
       
   811 apply (drule bex_Infinitesimal_iff2 [THEN iffD2], clarify)
       
   812 apply (frule_tac b1 = "hypreal_of_real (D) + y"
       
   813         in hypreal_mult_right_cancel [THEN iffD2])
       
   814 apply (erule_tac [2] V = "(( *f* f) (hypreal_of_real (x) + h) - hypreal_of_real (f x)) / h = hypreal_of_real (D) + y" in thin_rl)
       
   815 apply assumption
       
   816 apply (simp add: times_divide_eq_right [symmetric])
       
   817 apply (auto simp add: left_distrib)
       
   818 done
       
   819 
       
   820 lemma increment_thm2:
       
   821      "[| NSDERIV f x :> D; h \<approx> 0; h \<noteq> 0 |]
       
   822       ==> \<exists>e \<in> Infinitesimal. increment f x h =
       
   823               hypreal_of_real(D)*h + e*h"
       
   824 by (blast dest!: mem_infmal_iff [THEN iffD2] intro!: increment_thm)
       
   825 
       
   826 
       
   827 lemma increment_approx_zero: "[| NSDERIV f x :> D; h \<approx> 0; h \<noteq> 0 |]
       
   828       ==> increment f x h \<approx> 0"
       
   829 apply (drule increment_thm2,
       
   830        auto intro!: Infinitesimal_HFinite_mult2 HFinite_add simp add: left_distrib [symmetric] mem_infmal_iff [symmetric])
       
   831 apply (erule Infinitesimal_subset_HFinite [THEN subsetD])
       
   832 done
       
   833 
   387 
   834 subsection {* Nested Intervals and Bisection *}
   388 subsection {* Nested Intervals and Bisection *}
   835 
   389 
   836 text{*Lemmas about nested intervals and proof by bisection (cf.Harrison).
   390 text{*Lemmas about nested intervals and proof by bisection (cf.Harrison).
   837      All considerably tidied by lcp.*}
   391      All considerably tidied by lcp.*}