src/HOL/Hyperreal/Lim.ML
author nipkow
Fri Feb 07 16:40:23 2003 +0100 (2003-02-07)
changeset 13810 c3fbfd472365
parent 13630 a013a9dd370f
child 14262 e7db45b74b3a
permissions -rw-r--r--
(*f -> ( *f because of new comments
paulson@10751
     1
(*  Title       : Lim.ML
paulson@10751
     2
    Author      : Jacques D. Fleuriot
paulson@10751
     3
    Copyright   : 1998  University of Cambridge
paulson@10751
     4
    Description : Theory of limits, continuity and 
paulson@10751
     5
                  differentiation of real=>real functions
paulson@10751
     6
*)
paulson@10751
     7
paulson@10751
     8
fun ARITH_PROVE str = prove_goal thy str 
paulson@10751
     9
                      (fn prems => [cut_facts_tac prems 1,arith_tac 1]);
paulson@10751
    10
paulson@10751
    11
paulson@10751
    12
(*---------------------------------------------------------------
paulson@10751
    13
   Theory of limits, continuity and differentiation of 
paulson@10751
    14
   real=>real functions 
paulson@10751
    15
 ----------------------------------------------------------------*)
paulson@10751
    16
paulson@10751
    17
Goalw [LIM_def] "(%x. k) -- x --> k";
paulson@10751
    18
by Auto_tac;
paulson@10751
    19
qed "LIM_const";
paulson@10751
    20
Addsimps [LIM_const];
paulson@10751
    21
paulson@10751
    22
(***-----------------------------------------------------------***)
paulson@10751
    23
(***  Some Purely Standard Proofs - Can be used for comparison ***)
paulson@10751
    24
(***-----------------------------------------------------------***)
paulson@10751
    25
 
paulson@10751
    26
(*--------------- 
paulson@10751
    27
    LIM_add    
paulson@10751
    28
 ---------------*)
paulson@10751
    29
Goalw [LIM_def] 
paulson@10778
    30
     "[| f -- x --> l; g -- x --> m |] ==> (%x. f(x) + g(x)) -- x --> (l + m)";
paulson@10778
    31
by (Clarify_tac 1);
wenzelm@11704
    32
by (REPEAT(dres_inst_tac [("x","r/2")] spec 1));
paulson@10751
    33
by (Asm_full_simp_tac 1);
paulson@10751
    34
by (Clarify_tac 1);
paulson@10751
    35
by (res_inst_tac [("R1.0","s"),("R2.0","sa")] 
paulson@10751
    36
    real_linear_less2 1);
paulson@10751
    37
by (res_inst_tac [("x","s")] exI 1);
paulson@10751
    38
by (res_inst_tac [("x","sa")] exI 2);
paulson@10751
    39
by (res_inst_tac [("x","sa")] exI 3);
paulson@11176
    40
by Safe_tac;
paulson@10751
    41
by (REPEAT(dres_inst_tac [("x","xa")] spec 1) 
paulson@10751
    42
    THEN step_tac (claset() addSEs [order_less_trans]) 1);
paulson@10751
    43
by (REPEAT(dres_inst_tac [("x","xa")] spec 2) 
paulson@10751
    44
    THEN step_tac (claset() addSEs [order_less_trans]) 2);
paulson@10751
    45
by (REPEAT(dres_inst_tac [("x","xa")] spec 3) 
paulson@10751
    46
    THEN step_tac (claset() addSEs [order_less_trans]) 3);
paulson@10751
    47
by (ALLGOALS(rtac (abs_sum_triangle_ineq RS order_le_less_trans)));
paulson@10751
    48
by (ALLGOALS(rtac (real_sum_of_halves RS subst)));
paulson@10751
    49
by (auto_tac (claset() addIs [real_add_less_mono],simpset()));
paulson@10751
    50
qed "LIM_add";
paulson@10751
    51
paulson@10751
    52
Goalw [LIM_def] "f -- a --> L ==> (%x. -f(x)) -- a --> -L";
paulson@10751
    53
by (full_simp_tac (simpset() addsimps [real_minus_add_distrib RS sym] 
paulson@10751
    54
                    delsimps [real_minus_add_distrib, real_minus_minus]) 1);
paulson@10751
    55
qed "LIM_minus";
paulson@10751
    56
paulson@10751
    57
(*----------------------------------------------
paulson@10751
    58
     LIM_add_minus
paulson@10751
    59
 ----------------------------------------------*)
paulson@10751
    60
Goal "[| f -- x --> l; g -- x --> m |] \
paulson@10751
    61
\     ==> (%x. f(x) + -g(x)) -- x --> (l + -m)";
paulson@10751
    62
by (blast_tac (claset() addDs [LIM_add,LIM_minus]) 1);
paulson@10751
    63
qed "LIM_add_minus";
paulson@10751
    64
paulson@10751
    65
(*----------------------------------------------
paulson@10751
    66
     LIM_zero
paulson@10751
    67
 ----------------------------------------------*)
paulson@12018
    68
Goal "f -- a --> l ==> (%x. f(x) + -l) -- a --> 0";
paulson@12018
    69
by (res_inst_tac [("z1","l")] ((real_add_minus RS subst)) 1);
paulson@10751
    70
by (rtac LIM_add_minus 1 THEN Auto_tac);
paulson@10751
    71
qed "LIM_zero";
paulson@10751
    72
paulson@10751
    73
(*--------------------------
paulson@10751
    74
   Limit not zero
paulson@10751
    75
 --------------------------*)
paulson@12018
    76
Goalw [LIM_def] "k \\<noteq> 0 ==> ~ ((%x. k) -- x --> 0)";
paulson@12018
    77
by (res_inst_tac [("R1.0","k"),("R2.0","0")] real_linear_less2 1);
paulson@10751
    78
by (auto_tac (claset(), simpset() addsimps [real_abs_def]));
paulson@10751
    79
by (res_inst_tac [("x","-k")] exI 1);
paulson@10751
    80
by (res_inst_tac [("x","k")] exI 2);
paulson@10751
    81
by Auto_tac;
paulson@10751
    82
by (ALLGOALS(dres_inst_tac [("y","s")] real_dense));
paulson@10751
    83
by Safe_tac;
paulson@10751
    84
by (ALLGOALS(res_inst_tac [("x","r + x")] exI));
paulson@10751
    85
by Auto_tac;  
paulson@10751
    86
qed "LIM_not_zero";
paulson@10751
    87
paulson@12018
    88
(* [| k \\<noteq> 0; (%x. k) -- x --> 0 |] ==> R *)
paulson@10751
    89
bind_thm("LIM_not_zeroE", LIM_not_zero RS notE);
paulson@10751
    90
paulson@10751
    91
Goal "(%x. k) -- x --> L ==> k = L";
paulson@10751
    92
by (rtac ccontr 1);
paulson@10751
    93
by (dtac LIM_zero 1);
paulson@10751
    94
by (rtac LIM_not_zeroE 1 THEN assume_tac 2);
paulson@10751
    95
by (arith_tac 1);
paulson@10751
    96
qed "LIM_const_eq";
paulson@10751
    97
paulson@10751
    98
(*------------------------
paulson@10751
    99
     Limit is Unique
paulson@10751
   100
 ------------------------*)
paulson@10751
   101
Goal "[| f -- x --> L; f -- x --> M |] ==> L = M";
paulson@10751
   102
by (dtac LIM_minus 1);
paulson@10751
   103
by (dtac LIM_add 1 THEN assume_tac 1);
paulson@10751
   104
by (auto_tac (claset() addSDs [LIM_const_eq RS sym],  simpset()));
paulson@10751
   105
qed "LIM_unique";
paulson@10751
   106
paulson@10751
   107
(*-------------
paulson@10751
   108
    LIM_mult_zero
paulson@10751
   109
 -------------*)
paulson@11383
   110
Goalw [LIM_def]
paulson@12018
   111
     "[| f -- x --> 0; g -- x --> 0 |] ==> (%x. f(x)*g(x)) -- x --> 0";
paulson@11176
   112
by Safe_tac;
paulson@12018
   113
by (dres_inst_tac [("x","1")] spec 1);
paulson@10751
   114
by (dres_inst_tac [("x","r")] spec 1);
paulson@10751
   115
by (cut_facts_tac [real_zero_less_one] 1);
paulson@10751
   116
by (asm_full_simp_tac (simpset() addsimps 
paulson@10751
   117
    [abs_mult]) 1);
paulson@10751
   118
by (Clarify_tac 1);
paulson@10751
   119
by (res_inst_tac [("R1.0","s"),("R2.0","sa")] 
paulson@10751
   120
    real_linear_less2 1);
paulson@10751
   121
by (res_inst_tac [("x","s")] exI 1);
paulson@10751
   122
by (res_inst_tac [("x","sa")] exI 2);
paulson@10751
   123
by (res_inst_tac [("x","sa")] exI 3);
paulson@11176
   124
by Safe_tac;
paulson@10751
   125
by (REPEAT(dres_inst_tac [("x","xa")] spec 1) 
paulson@10751
   126
    THEN step_tac (claset() addSEs [order_less_trans]) 1);
paulson@10751
   127
by (REPEAT(dres_inst_tac [("x","xa")] spec 2) 
paulson@10751
   128
    THEN step_tac (claset() addSEs [order_less_trans]) 2);
paulson@10751
   129
by (REPEAT(dres_inst_tac [("x","xa")] spec 3) 
paulson@10751
   130
    THEN step_tac (claset() addSEs [order_less_trans]) 3);
paulson@10751
   131
by (ALLGOALS(res_inst_tac [("t","r")] (real_mult_1 RS subst)));
paulson@10751
   132
by (ALLGOALS(rtac abs_mult_less2));
paulson@10751
   133
by Auto_tac;
paulson@10751
   134
qed "LIM_mult_zero";
paulson@10751
   135
paulson@10751
   136
Goalw [LIM_def] "(%x. x) -- a --> a";
paulson@10751
   137
by Auto_tac;
paulson@10751
   138
qed "LIM_self";
paulson@10751
   139
paulson@10751
   140
(*--------------------------------------------------------------
paulson@10751
   141
   Limits are equal for functions equal except at limit point
paulson@10751
   142
 --------------------------------------------------------------*)
paulson@10751
   143
Goalw [LIM_def] 
paulson@11383
   144
     "[| \\<forall>x. x \\<noteq> a --> (f x = g x) |] \
paulson@11383
   145
\     ==> (f -- a --> l) = (g -- a --> l)";
paulson@10751
   146
by (auto_tac (claset(), simpset() addsimps [real_add_minus_iff]));
paulson@10751
   147
qed "LIM_equal";
paulson@10751
   148
paulson@12018
   149
Goal "[| (%x. f(x) + -g(x)) -- a --> 0;  g -- a --> l |] \
paulson@11383
   150
\     ==> f -- a --> l";
paulson@10751
   151
by (dtac LIM_add 1 THEN assume_tac 1);
paulson@10751
   152
by (auto_tac (claset(), simpset() addsimps [real_add_assoc]));
paulson@10751
   153
qed "LIM_trans";
paulson@10751
   154
paulson@10751
   155
(***-------------------------------------------------------------***)
paulson@10751
   156
(***           End of Purely Standard Proofs                     ***)
paulson@10751
   157
(***-------------------------------------------------------------***)
paulson@10751
   158
(*--------------------------------------------------------------
paulson@10751
   159
       Standard and NS definitions of Limit
paulson@10751
   160
 --------------------------------------------------------------*)
paulson@10919
   161
Goalw [LIM_def,NSLIM_def,approx_def] 
paulson@10751
   162
      "f -- x --> L ==> f -- x --NS> L";
paulson@10751
   163
by (asm_full_simp_tac
paulson@10751
   164
    (simpset() addsimps [Infinitesimal_FreeUltrafilterNat_iff]) 1);
paulson@11176
   165
by Safe_tac;
paulson@10751
   166
by (res_inst_tac [("z","xa")] eq_Abs_hypreal 1);
paulson@10751
   167
by (auto_tac (claset(),
paulson@10751
   168
      simpset() addsimps [real_add_minus_iff, starfun, hypreal_minus, 
paulson@10751
   169
                          hypreal_of_real_def, hypreal_add]));
paulson@10751
   170
by (rtac bexI 1 THEN rtac lemma_hyprel_refl 2 THEN Step_tac 1);
paulson@10751
   171
by (dres_inst_tac [("x","u")] spec 1 THEN Clarify_tac 1);
paulson@10751
   172
by (dres_inst_tac [("x","s")] spec 1 THEN Clarify_tac 1);
paulson@11383
   173
by (subgoal_tac "\\<forall>n::nat. (xa n) \\<noteq> x & \
paulson@10751
   174
\                    abs ((xa n) + - x) < s --> abs (f (xa n) + - L) < u" 1);
paulson@10751
   175
by (Blast_tac 2);
paulson@10751
   176
by (dtac FreeUltrafilterNat_all 1);
paulson@10751
   177
by (Ultra_tac 1);
paulson@10751
   178
qed "LIM_NSLIM";
paulson@10751
   179
 
paulson@10751
   180
(*---------------------------------------------------------------------
paulson@10751
   181
    Limit: NS definition ==> standard definition
paulson@10751
   182
 ---------------------------------------------------------------------*)
paulson@10751
   183
paulson@12018
   184
Goal "\\<forall>s. 0 < s --> (\\<exists>xa.  xa \\<noteq> x & \
paulson@11383
   185
\        abs (xa + - x) < s  & r \\<le> abs (f xa + -L)) \
paulson@11383
   186
\     ==> \\<forall>n::nat. \\<exists>xa.  xa \\<noteq> x & \
paulson@11383
   187
\             abs(xa + -x) < inverse(real(Suc n)) & r \\<le> abs(f xa + -L)";
paulson@10778
   188
by (Clarify_tac 1); 
paulson@10751
   189
by (cut_inst_tac [("n1","n")]
paulson@12018
   190
    (real_of_nat_Suc_gt_zero RS real_inverse_gt_0) 1);
paulson@10751
   191
by Auto_tac;
paulson@10751
   192
val lemma_LIM = result();
paulson@10751
   193
paulson@12018
   194
Goal "\\<forall>s. 0 < s --> (\\<exists>xa.  xa \\<noteq> x & \
paulson@11383
   195
\        abs (xa + - x) < s  & r \\<le> abs (f xa + -L)) \
paulson@11383
   196
\     ==> \\<exists>X. \\<forall>n::nat. X n \\<noteq> x & \
paulson@11383
   197
\               abs(X n + -x) < inverse(real(Suc n)) & r \\<le> abs(f (X n) + -L)";
paulson@10751
   198
by (dtac lemma_LIM 1);
paulson@10751
   199
by (dtac choice 1);
paulson@10751
   200
by (Blast_tac 1);
paulson@10751
   201
val lemma_skolemize_LIM2 = result();
paulson@10751
   202
paulson@11383
   203
Goal "\\<forall>n. X n \\<noteq> x & \
paulson@10919
   204
\         abs (X n + - x) < inverse (real(Suc n)) & \
paulson@11383
   205
\         r \\<le> abs (f (X n) + - L) ==> \
paulson@11383
   206
\         \\<forall>n. abs (X n + - x) < inverse (real(Suc n))";
paulson@10751
   207
by (Auto_tac );
paulson@10751
   208
val lemma_simp = result();
paulson@10751
   209
 
paulson@10751
   210
(*-------------------
paulson@10751
   211
    NSLIM => LIM
paulson@10751
   212
 -------------------*)
paulson@10751
   213
paulson@10919
   214
Goalw [LIM_def,NSLIM_def,approx_def] 
paulson@10778
   215
     "f -- x --NS> L ==> f -- x --> L";
paulson@10751
   216
by (asm_full_simp_tac
paulson@10751
   217
    (simpset() addsimps [Infinitesimal_FreeUltrafilterNat_iff]) 1);
paulson@10751
   218
by (EVERY1[Step_tac, rtac ccontr, Asm_full_simp_tac]);
paulson@10751
   219
by (fold_tac [real_le_def]);
paulson@10751
   220
by (dtac lemma_skolemize_LIM2 1);
paulson@11176
   221
by Safe_tac;
nipkow@10834
   222
by (dres_inst_tac [("x","Abs_hypreal(hyprel``{X})")] spec 1);
paulson@10751
   223
by (asm_full_simp_tac
paulson@10751
   224
    (simpset() addsimps [starfun, hypreal_minus, 
paulson@10751
   225
                         hypreal_of_real_def,hypreal_add]) 1);
paulson@11176
   226
by Safe_tac;
paulson@10751
   227
by (dtac (lemma_simp RS real_seq_to_hypreal_Infinitesimal) 1);
paulson@10751
   228
by (asm_full_simp_tac
paulson@10751
   229
    (simpset() addsimps 
paulson@10751
   230
       [Infinitesimal_FreeUltrafilterNat_iff,hypreal_of_real_def,
paulson@10751
   231
        hypreal_minus, hypreal_add]) 1);
paulson@10751
   232
by (Blast_tac 1); 
paulson@10751
   233
by (rotate_tac 2 1);
paulson@10751
   234
by (dres_inst_tac [("x","r")] spec 1);
paulson@10751
   235
by (Clarify_tac 1);
paulson@10751
   236
by (dtac FreeUltrafilterNat_all 1);
paulson@10751
   237
by (Ultra_tac 1);
paulson@10751
   238
qed "NSLIM_LIM";
paulson@10751
   239
paulson@10751
   240
paulson@10751
   241
(**** Key result ****)
paulson@10751
   242
Goal "(f -- x --> L) = (f -- x --NS> L)";
paulson@10751
   243
by (blast_tac (claset() addIs [LIM_NSLIM,NSLIM_LIM]) 1);
paulson@10751
   244
qed "LIM_NSLIM_iff";
paulson@10751
   245
paulson@10751
   246
(*-------------------------------------------------------------------*)
paulson@10751
   247
(*   Proving properties of limits using nonstandard definition and   *)
paulson@10751
   248
(*   hence, the properties hold for standard limits as well          *)
paulson@10751
   249
(*-------------------------------------------------------------------*)
paulson@10751
   250
(*------------------------------------------------
paulson@10751
   251
      NSLIM_mult and hence (trivially) LIM_mult
paulson@10751
   252
 ------------------------------------------------*)
paulson@10751
   253
paulson@10751
   254
Goalw [NSLIM_def]
paulson@10751
   255
     "[| f -- x --NS> l; g -- x --NS> m |] \
paulson@10751
   256
\     ==> (%x. f(x) * g(x)) -- x --NS> (l * m)";
paulson@10919
   257
by (auto_tac (claset() addSIs [approx_mult_HFinite],  simpset()));
paulson@10751
   258
qed "NSLIM_mult";
paulson@10751
   259
paulson@10751
   260
Goal "[| f -- x --> l; g -- x --> m |] \
paulson@10751
   261
\     ==> (%x. f(x) * g(x)) -- x --> (l * m)";
paulson@10751
   262
by (asm_full_simp_tac (simpset() addsimps [LIM_NSLIM_iff, NSLIM_mult]) 1);
paulson@10751
   263
qed "LIM_mult2";
paulson@10751
   264
paulson@10751
   265
(*----------------------------------------------
paulson@10751
   266
      NSLIM_add and hence (trivially) LIM_add
paulson@10751
   267
      Note the much shorter proof
paulson@10751
   268
 ----------------------------------------------*)
paulson@10751
   269
Goalw [NSLIM_def]
paulson@10751
   270
     "[| f -- x --NS> l; g -- x --NS> m |] \
paulson@10751
   271
\     ==> (%x. f(x) + g(x)) -- x --NS> (l + m)";
paulson@10919
   272
by (auto_tac (claset() addSIs [approx_add], simpset()));
paulson@10751
   273
qed "NSLIM_add";
paulson@10751
   274
paulson@10751
   275
Goal "[| f -- x --> l; g -- x --> m |] \
paulson@10751
   276
\     ==> (%x. f(x) + g(x)) -- x --> (l + m)";
paulson@10751
   277
by (asm_full_simp_tac (simpset() addsimps [LIM_NSLIM_iff, NSLIM_add]) 1);
paulson@10751
   278
qed "LIM_add2";
paulson@10751
   279
paulson@10751
   280
(*----------------------------------------------
paulson@10751
   281
     NSLIM_const
paulson@10751
   282
 ----------------------------------------------*)
paulson@10751
   283
Goalw [NSLIM_def] "(%x. k) -- x --NS> k";
paulson@10751
   284
by Auto_tac;
paulson@10751
   285
qed "NSLIM_const";
paulson@10751
   286
paulson@10751
   287
Addsimps [NSLIM_const];
paulson@10751
   288
paulson@10751
   289
Goal "(%x. k) -- x --> k";
paulson@10751
   290
by (asm_full_simp_tac (simpset() addsimps [LIM_NSLIM_iff]) 1);
paulson@10751
   291
qed "LIM_const2";
paulson@10751
   292
paulson@10751
   293
(*----------------------------------------------
paulson@10751
   294
     NSLIM_minus
paulson@10751
   295
 ----------------------------------------------*)
paulson@10751
   296
Goalw [NSLIM_def] 
paulson@10751
   297
      "f -- a --NS> L ==> (%x. -f(x)) -- a --NS> -L";
paulson@10751
   298
by Auto_tac;  
paulson@10751
   299
qed "NSLIM_minus";
paulson@10751
   300
paulson@10751
   301
Goal "f -- a --> L ==> (%x. -f(x)) -- a --> -L";
paulson@10751
   302
by (asm_full_simp_tac (simpset() addsimps [LIM_NSLIM_iff, NSLIM_minus]) 1);
paulson@10751
   303
qed "LIM_minus2";
paulson@10751
   304
paulson@10751
   305
(*----------------------------------------------
paulson@10751
   306
     NSLIM_add_minus
paulson@10751
   307
 ----------------------------------------------*)
paulson@10751
   308
Goal "[| f -- x --NS> l; g -- x --NS> m |] \
paulson@10751
   309
\     ==> (%x. f(x) + -g(x)) -- x --NS> (l + -m)";
paulson@10751
   310
by (blast_tac (claset() addDs [NSLIM_add,NSLIM_minus]) 1);
paulson@10751
   311
qed "NSLIM_add_minus";
paulson@10751
   312
paulson@10751
   313
Goal "[| f -- x --> l; g -- x --> m |] \
paulson@10751
   314
\     ==> (%x. f(x) + -g(x)) -- x --> (l + -m)";
paulson@10751
   315
by (asm_full_simp_tac (simpset() addsimps [LIM_NSLIM_iff,
paulson@10751
   316
    NSLIM_add_minus]) 1);
paulson@10751
   317
qed "LIM_add_minus2";
paulson@10751
   318
paulson@10751
   319
(*-----------------------------
paulson@10751
   320
    NSLIM_inverse
paulson@10751
   321
 -----------------------------*)
paulson@10751
   322
Goalw [NSLIM_def] 
paulson@12018
   323
     "[| f -- a --NS> L;  L \\<noteq> 0 |] \
paulson@10751
   324
\     ==> (%x. inverse(f(x))) -- a --NS> (inverse L)";
paulson@10751
   325
by (Clarify_tac 1);
paulson@10751
   326
by (dtac spec 1);
paulson@10751
   327
by (auto_tac (claset(), 
paulson@10919
   328
              simpset() addsimps [hypreal_of_real_approx_inverse]));  
paulson@10751
   329
qed "NSLIM_inverse";
paulson@10751
   330
paulson@10751
   331
Goal "[| f -- a --> L; \
paulson@12018
   332
\        L \\<noteq> 0 |] ==> (%x. inverse(f(x))) -- a --> (inverse L)";
paulson@10751
   333
by (asm_full_simp_tac (simpset() addsimps [LIM_NSLIM_iff, NSLIM_inverse]) 1);
paulson@10751
   334
qed "LIM_inverse";
paulson@10751
   335
paulson@10751
   336
(*------------------------------
paulson@10751
   337
    NSLIM_zero
paulson@10751
   338
 ------------------------------*)
paulson@12018
   339
Goal "f -- a --NS> l ==> (%x. f(x) + -l) -- a --NS> 0";
paulson@12018
   340
by (res_inst_tac [("z1","l")] ((real_add_minus RS subst)) 1);
paulson@10751
   341
by (rtac NSLIM_add_minus 1 THEN Auto_tac);
paulson@10751
   342
qed "NSLIM_zero";
paulson@10751
   343
paulson@12018
   344
Goal "f -- a --> l ==> (%x. f(x) + -l) -- a --> 0";
paulson@10751
   345
by (asm_full_simp_tac (simpset() addsimps [LIM_NSLIM_iff, NSLIM_zero]) 1);
paulson@10751
   346
qed "LIM_zero2";
paulson@10751
   347
paulson@12018
   348
Goal "(%x. f(x) - l) -- x --NS> 0 ==> f -- x --NS> l";
paulson@10751
   349
by (dres_inst_tac [("g","%x. l"),("m","l")] NSLIM_add 1);
paulson@10751
   350
by (auto_tac (claset(),simpset() addsimps [real_diff_def, real_add_assoc]));
paulson@10751
   351
qed "NSLIM_zero_cancel";
paulson@10751
   352
paulson@12018
   353
Goal "(%x. f(x) - l) -- x --> 0 ==> f -- x --> l";
paulson@10751
   354
by (dres_inst_tac [("g","%x. l"),("m","l")] LIM_add 1);
paulson@10751
   355
by (auto_tac (claset(),simpset() addsimps [real_diff_def, real_add_assoc]));
paulson@10751
   356
qed "LIM_zero_cancel";
paulson@10751
   357
paulson@10751
   358
paulson@10751
   359
(*--------------------------
paulson@10751
   360
   NSLIM_not_zero
paulson@10751
   361
 --------------------------*)
paulson@12018
   362
Goalw [NSLIM_def] "k \\<noteq> 0 ==> ~ ((%x. k) -- x --NS> 0)";
paulson@10751
   363
by Auto_tac;
paulson@10919
   364
by (res_inst_tac [("x","hypreal_of_real x + epsilon")] exI 1);
paulson@10919
   365
by (auto_tac (claset() addIs [Infinitesimal_add_approx_self RS approx_sym],
paulson@12018
   366
              simpset() addsimps [hypreal_epsilon_not_zero]));
paulson@10751
   367
qed "NSLIM_not_zero";
paulson@10751
   368
paulson@12018
   369
(* [| k \\<noteq> 0; (%x. k) -- x --NS> 0 |] ==> R *)
paulson@10751
   370
bind_thm("NSLIM_not_zeroE", NSLIM_not_zero RS notE);
paulson@10751
   371
paulson@12018
   372
Goal "k \\<noteq> 0 ==> ~ ((%x. k) -- x --> 0)";
paulson@10751
   373
by (asm_full_simp_tac (simpset() addsimps [LIM_NSLIM_iff, NSLIM_not_zero]) 1);
paulson@10751
   374
qed "LIM_not_zero2";
paulson@10751
   375
paulson@10751
   376
(*-------------------------------------
paulson@10751
   377
   NSLIM of constant function
paulson@10751
   378
 -------------------------------------*)
paulson@10751
   379
Goal "(%x. k) -- x --NS> L ==> k = L";
paulson@10751
   380
by (rtac ccontr 1);
paulson@10751
   381
by (dtac NSLIM_zero 1);
paulson@10751
   382
by (rtac NSLIM_not_zeroE 1 THEN assume_tac 2);
paulson@10751
   383
by (arith_tac 1);
paulson@10751
   384
qed "NSLIM_const_eq";
paulson@10751
   385
paulson@10751
   386
Goal "(%x. k) -- x --> L ==> k = L";
paulson@10751
   387
by (asm_full_simp_tac (simpset() addsimps [LIM_NSLIM_iff,
paulson@10751
   388
    NSLIM_const_eq]) 1);
paulson@10751
   389
qed "LIM_const_eq2";
paulson@10751
   390
paulson@10751
   391
(*------------------------
paulson@10751
   392
     NS Limit is Unique
paulson@10751
   393
 ------------------------*)
paulson@10751
   394
(* can actually be proved more easily by unfolding def! *)
paulson@10751
   395
Goal "[| f -- x --NS> L; f -- x --NS> M |] ==> L = M";
paulson@10751
   396
by (dtac NSLIM_minus 1);
paulson@10751
   397
by (dtac NSLIM_add 1 THEN assume_tac 1);
paulson@10751
   398
by (auto_tac (claset() addSDs [NSLIM_const_eq RS sym], simpset()));
paulson@10751
   399
qed "NSLIM_unique";
paulson@10751
   400
paulson@10751
   401
Goal "[| f -- x --> L; f -- x --> M |] ==> L = M";
paulson@10751
   402
by (asm_full_simp_tac (simpset() addsimps [LIM_NSLIM_iff, NSLIM_unique]) 1);
paulson@10751
   403
qed "LIM_unique2";
paulson@10751
   404
paulson@10751
   405
(*--------------------
paulson@10751
   406
    NSLIM_mult_zero
paulson@10751
   407
 --------------------*)
paulson@12018
   408
Goal "[| f -- x --NS> 0; g -- x --NS> 0 |] \
paulson@12018
   409
\         ==> (%x. f(x)*g(x)) -- x --NS> 0";
paulson@10751
   410
by (dtac NSLIM_mult 1 THEN Auto_tac);
paulson@10751
   411
qed "NSLIM_mult_zero";
paulson@10751
   412
paulson@10751
   413
(* we can use the corresponding thm LIM_mult2 *)
paulson@10751
   414
(* for standard definition of limit           *)
paulson@10751
   415
paulson@12018
   416
Goal "[| f -- x --> 0; g -- x --> 0 |] \
paulson@12018
   417
\     ==> (%x. f(x)*g(x)) -- x --> 0";
paulson@10751
   418
by (dtac LIM_mult2 1 THEN Auto_tac);
paulson@10751
   419
qed "LIM_mult_zero2";
paulson@10751
   420
paulson@10751
   421
(*----------------------------
paulson@10751
   422
    NSLIM_self
paulson@10751
   423
 ----------------------------*)
paulson@10751
   424
Goalw [NSLIM_def] "(%x. x) -- a --NS> a";
paulson@10919
   425
by (auto_tac (claset() addIs [starfun_Idfun_approx],simpset()));
paulson@10751
   426
qed "NSLIM_self";
paulson@10751
   427
paulson@10751
   428
Goal "(%x. x) -- a --> a";
paulson@10751
   429
by (simp_tac (simpset() addsimps [LIM_NSLIM_iff,NSLIM_self]) 1);
paulson@10751
   430
qed "LIM_self2";
paulson@10751
   431
paulson@10751
   432
(*-----------------------------------------------------------------------------
paulson@10751
   433
   Derivatives and Continuity - NS and Standard properties
paulson@10751
   434
 -----------------------------------------------------------------------------*)
paulson@10751
   435
(*---------------
paulson@10751
   436
    Continuity 
paulson@10751
   437
 ---------------*)
paulson@10751
   438
paulson@10751
   439
Goalw [isNSCont_def] 
paulson@11383
   440
      "[| isNSCont f a; y \\<approx> hypreal_of_real a |] \
nipkow@13810
   441
\           ==> ( *f* f) y \\<approx> hypreal_of_real (f a)";
paulson@10751
   442
by (Blast_tac 1);
paulson@10751
   443
qed "isNSContD";
paulson@10751
   444
paulson@10751
   445
Goalw [isNSCont_def,NSLIM_def] 
paulson@10751
   446
      "isNSCont f a ==> f -- a --NS> (f a) ";
paulson@10751
   447
by (Blast_tac 1);
paulson@10751
   448
qed "isNSCont_NSLIM";
paulson@10751
   449
paulson@10751
   450
Goalw [isNSCont_def,NSLIM_def] 
paulson@10751
   451
      "f -- a --NS> (f a) ==> isNSCont f a";
paulson@10751
   452
by Auto_tac;
paulson@10751
   453
by (res_inst_tac [("Q","y = hypreal_of_real a")] 
paulson@10751
   454
    (excluded_middle RS disjE) 1);
paulson@10751
   455
by Auto_tac;
paulson@10751
   456
qed "NSLIM_isNSCont";
paulson@10751
   457
paulson@10751
   458
(*-----------------------------------------------------
paulson@10751
   459
    NS continuity can be defined using NS Limit in
paulson@10751
   460
    similar fashion to standard def of continuity
paulson@10751
   461
 -----------------------------------------------------*)
paulson@10751
   462
Goal "(isNSCont f a) = (f -- a --NS> (f a))";
paulson@10751
   463
by (blast_tac (claset() addIs [isNSCont_NSLIM,NSLIM_isNSCont]) 1);
paulson@10751
   464
qed "isNSCont_NSLIM_iff";
paulson@10751
   465
paulson@10751
   466
(*----------------------------------------------
paulson@10751
   467
  Hence, NS continuity can be given
paulson@10751
   468
  in terms of standard limit
paulson@10751
   469
 ---------------------------------------------*)
paulson@10751
   470
Goal "(isNSCont f a) = (f -- a --> (f a))";
paulson@10751
   471
by (asm_full_simp_tac (simpset() addsimps 
paulson@10751
   472
    [LIM_NSLIM_iff,isNSCont_NSLIM_iff]) 1);
paulson@10751
   473
qed "isNSCont_LIM_iff";
paulson@10751
   474
paulson@10751
   475
(*-----------------------------------------------
paulson@10751
   476
  Moreover, it's trivial now that NS continuity 
paulson@10751
   477
  is equivalent to standard continuity
paulson@10751
   478
 -----------------------------------------------*)
paulson@10751
   479
Goalw [isCont_def] "(isNSCont f a) = (isCont f a)";
paulson@10751
   480
by (rtac isNSCont_LIM_iff 1);
paulson@10751
   481
qed "isNSCont_isCont_iff";
paulson@10751
   482
paulson@10751
   483
(*----------------------------------------
paulson@10751
   484
  Standard continuity ==> NS continuity 
paulson@10751
   485
 ----------------------------------------*)
paulson@10751
   486
Goal "isCont f a ==> isNSCont f a";
paulson@10751
   487
by (etac (isNSCont_isCont_iff RS iffD2) 1);
paulson@10751
   488
qed "isCont_isNSCont";
paulson@10751
   489
paulson@10751
   490
(*----------------------------------------
paulson@10751
   491
  NS continuity ==> Standard continuity 
paulson@10751
   492
 ----------------------------------------*)
paulson@10751
   493
Goal "isNSCont f a ==> isCont f a";
paulson@10751
   494
by (etac (isNSCont_isCont_iff RS iffD1) 1);
paulson@10751
   495
qed "isNSCont_isCont";
paulson@10751
   496
paulson@10751
   497
(*--------------------------------------------------------------------------
paulson@10751
   498
                 Alternative definition of continuity
paulson@10751
   499
 --------------------------------------------------------------------------*)
paulson@10751
   500
(* Prove equivalence between NS limits - *)
paulson@10751
   501
(* seems easier than using standard def  *)
paulson@12018
   502
Goalw [NSLIM_def] "(f -- a --NS> L) = ((%h. f(a + h)) -- 0 --NS> L)";
paulson@12018
   503
by Auto_tac;
paulson@10751
   504
by (dres_inst_tac [("x","hypreal_of_real a + x")] spec 1);
paulson@10751
   505
by (dres_inst_tac [("x","-hypreal_of_real a + x")] spec 2);
paulson@11176
   506
by Safe_tac;
paulson@10751
   507
by (Asm_full_simp_tac 1);
paulson@10751
   508
by (rtac ((mem_infmal_iff RS iffD2) RS 
paulson@10919
   509
    (Infinitesimal_add_approx_self RS approx_sym)) 1);
paulson@10919
   510
by (rtac (approx_minus_iff2 RS iffD1) 4);
paulson@10751
   511
by (asm_full_simp_tac (simpset() addsimps [hypreal_add_commute]) 3);
paulson@10751
   512
by (res_inst_tac [("z","x")] eq_Abs_hypreal 2);
paulson@10751
   513
by (res_inst_tac [("z","x")] eq_Abs_hypreal 4);
paulson@10751
   514
by (auto_tac (claset(),
paulson@10751
   515
       simpset() addsimps [starfun, hypreal_of_real_def, hypreal_minus,
paulson@10919
   516
              hypreal_add, real_add_assoc, approx_refl, hypreal_zero_def]));
paulson@10751
   517
qed "NSLIM_h_iff";
paulson@10751
   518
paulson@12018
   519
Goal "(f -- a --NS> f a) = ((%h. f(a + h)) -- 0 --NS> f a)";
paulson@10751
   520
by (rtac NSLIM_h_iff 1);
paulson@10751
   521
qed "NSLIM_isCont_iff";
paulson@10751
   522
paulson@12018
   523
Goal "(f -- a --> f a) = ((%h. f(a + h)) -- 0 --> f(a))";
paulson@10751
   524
by (simp_tac (simpset() addsimps [LIM_NSLIM_iff, NSLIM_isCont_iff]) 1);
paulson@10751
   525
qed "LIM_isCont_iff";
paulson@10751
   526
paulson@12018
   527
Goalw [isCont_def] "(isCont f x) = ((%h. f(x + h)) -- 0 --> f(x))";
paulson@10751
   528
by (simp_tac (simpset() addsimps [LIM_isCont_iff]) 1);
paulson@10751
   529
qed "isCont_iff";
paulson@10751
   530
paulson@10751
   531
(*--------------------------------------------------------------------------
paulson@10751
   532
   Immediate application of nonstandard criterion for continuity can offer 
paulson@10751
   533
   very simple proofs of some standard property of continuous functions
paulson@10751
   534
 --------------------------------------------------------------------------*)
paulson@10751
   535
(*------------------------
paulson@10751
   536
     sum continuous
paulson@10751
   537
 ------------------------*)
paulson@10751
   538
Goal "[| isCont f a; isCont g a |] ==> isCont (%x. f(x) + g(x)) a";
paulson@10919
   539
by (auto_tac (claset() addIs [approx_add],
paulson@10751
   540
              simpset() addsimps [isNSCont_isCont_iff RS sym, isNSCont_def]));
paulson@10751
   541
qed "isCont_add";
paulson@10751
   542
paulson@10751
   543
(*------------------------
paulson@10751
   544
     mult continuous
paulson@10751
   545
 ------------------------*)
paulson@10751
   546
Goal "[| isCont f a; isCont g a |] ==> isCont (%x. f(x) * g(x)) a";
paulson@10919
   547
by (auto_tac (claset() addSIs [starfun_mult_HFinite_approx],
paulson@10751
   548
              simpset() delsimps [starfun_mult RS sym]
paulson@10751
   549
			addsimps [isNSCont_isCont_iff RS sym, isNSCont_def]));
paulson@10751
   550
qed "isCont_mult";
paulson@10751
   551
paulson@10751
   552
(*-------------------------------------------
paulson@10751
   553
     composition of continuous functions
paulson@10751
   554
     Note very short straightforard proof!
paulson@10751
   555
 ------------------------------------------*)
paulson@10751
   556
Goal "[| isCont f a; isCont g (f a) |] \
paulson@10751
   557
\     ==> isCont (g o f) a";
paulson@10751
   558
by (auto_tac (claset(),simpset() addsimps [isNSCont_isCont_iff RS sym,
paulson@10751
   559
              isNSCont_def,starfun_o RS sym]));
paulson@10751
   560
qed "isCont_o";
paulson@10751
   561
paulson@10751
   562
Goal "[| isCont f a; isCont g (f a) |] \
paulson@10751
   563
\     ==> isCont (%x. g (f x)) a";
paulson@10751
   564
by (auto_tac (claset() addDs [isCont_o],simpset() addsimps [o_def]));
paulson@10751
   565
qed "isCont_o2";
paulson@10751
   566
paulson@10751
   567
Goalw [isNSCont_def] "isNSCont f a ==> isNSCont (%x. - f x) a";
paulson@10751
   568
by Auto_tac; 
paulson@10751
   569
qed "isNSCont_minus";
paulson@10751
   570
paulson@10751
   571
Goal "isCont f a ==> isCont (%x. - f x) a";
paulson@10751
   572
by (auto_tac (claset(),simpset() addsimps [isNSCont_isCont_iff RS sym,
paulson@10751
   573
              isNSCont_minus]));
paulson@10751
   574
qed "isCont_minus";
paulson@10751
   575
paulson@10751
   576
Goalw [isCont_def]  
paulson@12018
   577
      "[| isCont f x; f x \\<noteq> 0 |] ==> isCont (%x. inverse (f x)) x";
paulson@10751
   578
by (blast_tac (claset() addIs [LIM_inverse]) 1);
paulson@10751
   579
qed "isCont_inverse";
paulson@10751
   580
paulson@12018
   581
Goal "[| isNSCont f x; f x \\<noteq> 0 |] ==> isNSCont (%x. inverse (f x)) x";
paulson@10751
   582
by (auto_tac (claset() addIs [isCont_inverse],simpset() addsimps 
paulson@10751
   583
    [isNSCont_isCont_iff]));
paulson@10751
   584
qed "isNSCont_inverse";
paulson@10751
   585
paulson@10751
   586
Goalw [real_diff_def] 
paulson@10751
   587
      "[| isCont f a; isCont g a |] ==> isCont (%x. f(x) - g(x)) a";
paulson@10751
   588
by (auto_tac (claset() addIs [isCont_add,isCont_minus],simpset()));
paulson@10751
   589
qed "isCont_diff";
paulson@10751
   590
paulson@10751
   591
Goalw [isCont_def]  "isCont (%x. k) a";
paulson@10751
   592
by (Simp_tac 1);
paulson@10751
   593
qed "isCont_const";
paulson@10751
   594
Addsimps [isCont_const];
paulson@10751
   595
paulson@10751
   596
Goalw [isNSCont_def]  "isNSCont (%x. k) a";
paulson@10751
   597
by (Simp_tac 1);
paulson@10751
   598
qed "isNSCont_const";
paulson@10751
   599
Addsimps [isNSCont_const];
paulson@10751
   600
paulson@10751
   601
Goalw [isNSCont_def]  "isNSCont abs a";
paulson@10919
   602
by (auto_tac (claset() addIs [approx_hrabs],
paulson@10751
   603
              simpset() addsimps [hypreal_of_real_hrabs RS sym,
paulson@10751
   604
                                  starfun_rabs_hrabs]));
paulson@10751
   605
qed "isNSCont_rabs";
paulson@10751
   606
Addsimps [isNSCont_rabs];
paulson@10751
   607
paulson@10751
   608
Goal "isCont abs a";
paulson@10751
   609
by (auto_tac (claset(), simpset() addsimps [isNSCont_isCont_iff RS sym]));
paulson@10751
   610
qed "isCont_rabs";
paulson@10751
   611
Addsimps [isCont_rabs];
paulson@10751
   612
paulson@10751
   613
(****************************************************************
paulson@10751
   614
(%* Leave as commented until I add topology theory or remove? *%)
paulson@10751
   615
(%*------------------------------------------------------------
paulson@10751
   616
  Elementary topology proof for a characterisation of 
paulson@10751
   617
  continuity now: a function f is continuous if and only 
paulson@11383
   618
  if the inverse image, {x. f(x) \\<in> A}, of any open set A 
paulson@10751
   619
  is always an open set
paulson@10751
   620
 ------------------------------------------------------------*%)
paulson@11383
   621
Goal "[| isNSopen A; \\<forall>x. isNSCont f x |] \
paulson@11383
   622
\              ==> isNSopen {x. f x \\<in> A}";
paulson@10751
   623
by (auto_tac (claset(),simpset() addsimps [isNSopen_iff1]));
paulson@10919
   624
by (dtac (mem_monad_approx RS approx_sym) 1);
paulson@10751
   625
by (dres_inst_tac [("x","a")] spec 1);
paulson@10751
   626
by (dtac isNSContD 1 THEN assume_tac 1);
paulson@10751
   627
by (dtac bspec 1 THEN assume_tac 1);
paulson@10919
   628
by (dres_inst_tac [("x","( *f* f) x")] approx_mem_monad2 1);
paulson@10751
   629
by (blast_tac (claset() addIs [starfun_mem_starset]) 1);
paulson@10751
   630
qed "isNSCont_isNSopen";
paulson@10751
   631
paulson@10751
   632
Goalw [isNSCont_def]
paulson@11383
   633
          "\\<forall>A. isNSopen A --> isNSopen {x. f x \\<in> A} \
paulson@10751
   634
\              ==> isNSCont f x";
paulson@10751
   635
by (auto_tac (claset() addSIs [(mem_infmal_iff RS iffD1) RS 
paulson@10919
   636
     (approx_minus_iff RS iffD2)],simpset() addsimps 
paulson@10751
   637
      [Infinitesimal_def,SReal_iff]));
paulson@10751
   638
by (dres_inst_tac [("x","{z. abs(z + -f(x)) < ya}")] spec 1);
paulson@10751
   639
by (etac (isNSopen_open_interval RSN (2,impE)) 1);
paulson@10751
   640
by (auto_tac (claset(),simpset() addsimps [isNSopen_def,isNSnbhd_def]));
paulson@10751
   641
by (dres_inst_tac [("x","x")] spec 1);
paulson@10919
   642
by (auto_tac (claset() addDs [approx_sym RS approx_mem_monad],
paulson@10751
   643
    simpset() addsimps [hypreal_of_real_zero RS sym,STAR_starfun_rabs_add_minus]));
paulson@10751
   644
qed "isNSopen_isNSCont";
paulson@10751
   645
paulson@11383
   646
Goal "(\\<forall>x. isNSCont f x) = \
paulson@11383
   647
\     (\\<forall>A. isNSopen A --> isNSopen {x. f(x) \\<in> A})";
paulson@10751
   648
by (blast_tac (claset() addIs [isNSCont_isNSopen,
paulson@10751
   649
    isNSopen_isNSCont]) 1);
paulson@10751
   650
qed "isNSCont_isNSopen_iff";
paulson@10751
   651
paulson@10751
   652
(%*------- Standard version of same theorem --------*%)
paulson@11383
   653
Goal "(\\<forall>x. isCont f x) = \
paulson@11383
   654
\         (\\<forall>A. isopen A --> isopen {x. f(x) \\<in> A})";
paulson@10751
   655
by (auto_tac (claset() addSIs [isNSCont_isNSopen_iff],
paulson@10751
   656
              simpset() addsimps [isNSopen_isopen_iff RS sym,
paulson@10751
   657
              isNSCont_isCont_iff RS sym]));
paulson@10751
   658
qed "isCont_isopen_iff";
paulson@10751
   659
*******************************************************************)
paulson@10751
   660
paulson@10751
   661
(*-----------------------------------------------------------------
paulson@10751
   662
                        Uniform continuity
paulson@10751
   663
 ------------------------------------------------------------------*)
paulson@10751
   664
Goalw [isNSUCont_def] 
nipkow@13810
   665
      "[| isNSUCont f; x \\<approx> y|] ==> ( *f* f) x \\<approx> ( *f* f) y";
paulson@10751
   666
by (Blast_tac 1);
paulson@10751
   667
qed "isNSUContD";
paulson@10751
   668
paulson@10751
   669
Goalw [isUCont_def,isCont_def,LIM_def]
paulson@12018
   670
     "isUCont f ==> isCont f x";
paulson@12018
   671
by (Clarify_tac 1);
paulson@12018
   672
by (dtac spec 1); 
paulson@12018
   673
by (Blast_tac 1); 
paulson@10751
   674
qed "isUCont_isCont";
paulson@10751
   675
paulson@10919
   676
Goalw [isNSUCont_def,isUCont_def,approx_def] 
paulson@10751
   677
     "isUCont f ==> isNSUCont f";
paulson@10751
   678
by (asm_full_simp_tac (simpset() addsimps 
paulson@10751
   679
    [Infinitesimal_FreeUltrafilterNat_iff]) 1);
paulson@11176
   680
by Safe_tac;
paulson@10751
   681
by (res_inst_tac [("z","x")] eq_Abs_hypreal 1);
paulson@10751
   682
by (res_inst_tac [("z","y")] eq_Abs_hypreal 1);
paulson@10751
   683
by (auto_tac (claset(),simpset() addsimps [starfun,
paulson@10751
   684
    hypreal_minus, hypreal_add]));
paulson@10751
   685
by (rtac bexI 1 THEN rtac lemma_hyprel_refl 2 THEN Step_tac 1);
paulson@10751
   686
by (dres_inst_tac [("x","u")] spec 1 THEN Clarify_tac 1);
paulson@10751
   687
by (dres_inst_tac [("x","s")] spec 1 THEN Clarify_tac 1);
paulson@11383
   688
by (subgoal_tac "\\<forall>n::nat. abs ((xa n) + - (xb n)) < s --> abs (f (xa n) + - f (xb n)) < u" 1);
paulson@10751
   689
by (Blast_tac 2);
paulson@11383
   690
by (thin_tac "\\<forall>x y. abs (x + - y) < s --> abs (f x + - f y) < u" 1);
paulson@10751
   691
by (dtac FreeUltrafilterNat_all 1);
paulson@10751
   692
by (Ultra_tac 1);
paulson@10751
   693
qed "isUCont_isNSUCont";
paulson@10751
   694
paulson@12018
   695
Goal "\\<forall>s. 0 < s --> (\\<exists>z y. abs (z + - y) < s & r \\<le> abs (f z + -f y)) \
paulson@11383
   696
\     ==> \\<forall>n::nat. \\<exists>z y.  \
paulson@10919
   697
\              abs(z + -y) < inverse(real(Suc n)) & \
paulson@11383
   698
\              r \\<le> abs(f z + -f y)";
paulson@10778
   699
by (Clarify_tac 1); 
paulson@10778
   700
by (cut_inst_tac [("n1","n")]
paulson@12018
   701
    (real_of_nat_Suc_gt_zero RS real_inverse_gt_0) 1);
paulson@10751
   702
by Auto_tac;
paulson@10751
   703
val lemma_LIMu = result();
paulson@10751
   704
paulson@12018
   705
Goal "\\<forall>s. 0 < s --> (\\<exists>z y. abs (z + - y) < s  & r \\<le> abs (f z + -f y)) \
paulson@11383
   706
\     ==> \\<exists>X Y. \\<forall>n::nat. \
paulson@10919
   707
\              abs(X n + -(Y n)) < inverse(real(Suc n)) & \
paulson@11383
   708
\              r \\<le> abs(f (X n) + -f (Y n))";
paulson@10751
   709
by (dtac lemma_LIMu 1);
paulson@10751
   710
by (dtac choice 1);
paulson@11176
   711
by Safe_tac;
paulson@10751
   712
by (dtac choice 1);
paulson@10751
   713
by (Blast_tac 1);
paulson@10751
   714
val lemma_skolemize_LIM2u = result();
paulson@10751
   715
paulson@11383
   716
Goal "\\<forall>n. abs (X n + -Y n) < inverse (real(Suc n)) & \
paulson@11383
   717
\         r \\<le> abs (f (X n) + - f(Y n)) ==> \
paulson@11383
   718
\         \\<forall>n. abs (X n + - Y n) < inverse (real(Suc n))";
paulson@10751
   719
by (Auto_tac );
paulson@10751
   720
val lemma_simpu = result();
paulson@10751
   721
paulson@10919
   722
Goalw [isNSUCont_def,isUCont_def,approx_def] 
paulson@10751
   723
     "isNSUCont f ==> isUCont f";
paulson@10751
   724
by (asm_full_simp_tac (simpset() addsimps 
paulson@10751
   725
                       [Infinitesimal_FreeUltrafilterNat_iff]) 1);
paulson@10751
   726
by (EVERY1[Step_tac, rtac ccontr, Asm_full_simp_tac]);
paulson@10751
   727
by (fold_tac [real_le_def]);
paulson@10751
   728
by (dtac lemma_skolemize_LIM2u 1);
paulson@11176
   729
by Safe_tac;
nipkow@10834
   730
by (dres_inst_tac [("x","Abs_hypreal(hyprel``{X})")] spec 1);
nipkow@10834
   731
by (dres_inst_tac [("x","Abs_hypreal(hyprel``{Y})")] spec 1);
paulson@10751
   732
by (asm_full_simp_tac
paulson@10751
   733
    (simpset() addsimps [starfun, hypreal_minus,hypreal_add]) 1);
paulson@10751
   734
by Auto_tac;
paulson@10751
   735
by (dtac (lemma_simpu RS real_seq_to_hypreal_Infinitesimal2) 1);
paulson@10751
   736
by (asm_full_simp_tac (simpset() addsimps 
paulson@10751
   737
     [Infinitesimal_FreeUltrafilterNat_iff, hypreal_minus,hypreal_add]) 1);
paulson@10751
   738
by (Blast_tac 1);
paulson@10751
   739
by (rotate_tac 2 1);
paulson@10751
   740
by (dres_inst_tac [("x","r")] spec 1);
paulson@10751
   741
by (Clarify_tac 1);
paulson@10751
   742
by (dtac FreeUltrafilterNat_all 1);
paulson@10751
   743
by (Ultra_tac 1);
paulson@10751
   744
qed "isNSUCont_isUCont";
paulson@10751
   745
paulson@10751
   746
(*------------------------------------------------------------------
paulson@10751
   747
                         Derivatives
paulson@10751
   748
 ------------------------------------------------------------------*)
paulson@10751
   749
Goalw [deriv_def] 
paulson@12018
   750
      "(DERIV f x :> D) = ((%h. (f(x + h) + - f(x))/h) -- 0 --> D)";
paulson@10751
   751
by (Blast_tac 1);        
paulson@10751
   752
qed "DERIV_iff";
paulson@10751
   753
paulson@10751
   754
Goalw [deriv_def] 
paulson@12018
   755
      "(DERIV f x :> D) = ((%h. (f(x + h) + - f(x))/h) -- 0 --NS> D)";
paulson@10751
   756
by (simp_tac (simpset() addsimps [LIM_NSLIM_iff]) 1);
paulson@10751
   757
qed "DERIV_NS_iff";
paulson@10751
   758
paulson@10751
   759
Goalw [deriv_def] 
paulson@10751
   760
      "DERIV f x :> D \
paulson@12018
   761
\      ==> (%h. (f(x + h) + - f(x))/h) -- 0 --> D";
paulson@10751
   762
by (Blast_tac 1);        
paulson@10751
   763
qed "DERIVD";
paulson@10751
   764
paulson@10751
   765
Goalw [deriv_def] "DERIV f x :> D ==> \
paulson@12018
   766
\          (%h. (f(x + h) + - f(x))/h) -- 0 --NS> D";
paulson@10751
   767
by (asm_full_simp_tac (simpset() addsimps [LIM_NSLIM_iff]) 1);
paulson@10751
   768
qed "NS_DERIVD";
paulson@10751
   769
paulson@10751
   770
(* Uniqueness *)
paulson@10751
   771
Goalw [deriv_def] 
paulson@10751
   772
      "[| DERIV f x :> D; DERIV f x :> E |] ==> D = E";
paulson@10751
   773
by (blast_tac (claset() addIs [LIM_unique]) 1);
paulson@10751
   774
qed "DERIV_unique";
paulson@10751
   775
paulson@10751
   776
Goalw [nsderiv_def] 
paulson@10751
   777
     "[| NSDERIV f x :> D; NSDERIV f x :> E |] ==> D = E";
paulson@10751
   778
by (cut_facts_tac [Infinitesimal_epsilon, hypreal_epsilon_not_zero] 1);
paulson@10919
   779
by (auto_tac (claset() addSDs [inst "x" "epsilon" bspec] 
paulson@10751
   780
                       addSIs [inj_hypreal_of_real RS injD] 
paulson@10919
   781
                       addDs [approx_trans3],
paulson@10751
   782
              simpset()));
paulson@10751
   783
qed "NSDeriv_unique";
paulson@10751
   784
paulson@10751
   785
(*------------------------------------------------------------------------
paulson@10751
   786
                          Differentiable
paulson@10751
   787
 ------------------------------------------------------------------------*)
paulson@10751
   788
paulson@10751
   789
Goalw [differentiable_def] 
paulson@11383
   790
      "f differentiable x ==> \\<exists>D. DERIV f x :> D";
paulson@10751
   791
by (assume_tac 1);
paulson@10751
   792
qed "differentiableD";
paulson@10751
   793
paulson@10751
   794
Goalw [differentiable_def] 
paulson@10751
   795
      "DERIV f x :> D ==> f differentiable x";
paulson@10751
   796
by (Blast_tac 1);
paulson@10751
   797
qed "differentiableI";
paulson@10751
   798
paulson@10751
   799
Goalw [NSdifferentiable_def] 
paulson@11383
   800
      "f NSdifferentiable x ==> \\<exists>D. NSDERIV f x :> D";
paulson@10751
   801
by (assume_tac 1);
paulson@10751
   802
qed "NSdifferentiableD";
paulson@10751
   803
paulson@10751
   804
Goalw [NSdifferentiable_def] 
paulson@10751
   805
      "NSDERIV f x :> D ==> f NSdifferentiable x";
paulson@10751
   806
by (Blast_tac 1);
paulson@10751
   807
qed "NSdifferentiableI";
paulson@10751
   808
paulson@10751
   809
(*--------------------------------------------------------
paulson@10751
   810
      Alternative definition for differentiability
paulson@10751
   811
 -------------------------------------------------------*)
paulson@10751
   812
paulson@10751
   813
Goalw [LIM_def] 
paulson@12018
   814
 "((%h. (f(a + h) + - f(a))/h) -- 0 --> D) = \
paulson@10751
   815
\ ((%x. (f(x) + -f(a)) / (x + -a)) -- a --> D)";
paulson@11176
   816
by Safe_tac;
paulson@10751
   817
by (ALLGOALS(dtac spec));
paulson@11176
   818
by Safe_tac;
paulson@10751
   819
by (Blast_tac 1 THEN Blast_tac 2);
paulson@10751
   820
by (ALLGOALS(res_inst_tac [("x","s")] exI));
paulson@11176
   821
by Safe_tac;
paulson@10751
   822
by (dres_inst_tac [("x","x + -a")] spec 1);
paulson@10751
   823
by (dres_inst_tac [("x","x + a")] spec 2);
paulson@10751
   824
by (auto_tac (claset(), simpset() addsimps real_add_ac));
paulson@10751
   825
qed "DERIV_LIM_iff";
paulson@10751
   826
paulson@10751
   827
Goalw [deriv_def] "(DERIV f x :> D) = \
paulson@10751
   828
\         ((%z. (f(z) + -f(x)) / (z + -x)) -- x --> D)";
paulson@10751
   829
by (simp_tac (simpset() addsimps [DERIV_LIM_iff]) 1);
paulson@10751
   830
qed "DERIV_iff2";
paulson@10751
   831
paulson@10751
   832
(*--------------------------------------------------------
paulson@10751
   833
  Equivalence of NS and standard defs of differentiation
paulson@10751
   834
 -------------------------------------------------------*)
paulson@10751
   835
(*-------------------------------------------
paulson@10751
   836
   First NSDERIV in terms of NSLIM 
paulson@10751
   837
 -------------------------------------------*)
paulson@10751
   838
paulson@10751
   839
(*--- first equivalence ---*)
paulson@10751
   840
Goalw [nsderiv_def,NSLIM_def] 
paulson@12018
   841
      "(NSDERIV f x :> D) = ((%h. (f(x + h) + - f(x))/h) -- 0 --NS> D)";
paulson@12018
   842
by Auto_tac;
paulson@10751
   843
by (dres_inst_tac [("x","xa")] bspec 1);
paulson@10751
   844
by (rtac ccontr 3);
paulson@10751
   845
by (dres_inst_tac [("x","h")] spec 3);
paulson@10751
   846
by (auto_tac (claset(),
paulson@10751
   847
              simpset() addsimps [mem_infmal_iff, starfun_lambda_cancel]));
paulson@10751
   848
qed "NSDERIV_NSLIM_iff";
paulson@10751
   849
paulson@10751
   850
(*--- second equivalence ---*)
paulson@10751
   851
Goal "(NSDERIV f x :> D) = \
paulson@10751
   852
\         ((%z. (f(z) + -f(x)) / (z + -x)) -- x --NS> D)";
paulson@10751
   853
by (full_simp_tac (simpset() addsimps 
paulson@10751
   854
     [NSDERIV_NSLIM_iff, DERIV_LIM_iff, LIM_NSLIM_iff RS sym]) 1);
paulson@10751
   855
qed "NSDERIV_NSLIM_iff2";
paulson@10751
   856
paulson@10751
   857
(* while we're at it! *)
paulson@10751
   858
Goalw [real_diff_def]
paulson@10751
   859
     "(NSDERIV f x :> D) = \
paulson@11383
   860
\     (\\<forall>xa. \
paulson@11383
   861
\       xa \\<noteq> hypreal_of_real x & xa \\<approx> hypreal_of_real x --> \
nipkow@13810
   862
\       ( *f* (%z. (f z - f x) / (z - x))) xa \\<approx> hypreal_of_real D)";
paulson@10751
   863
by (auto_tac (claset(), simpset() addsimps [NSDERIV_NSLIM_iff2, NSLIM_def]));
paulson@10751
   864
qed "NSDERIV_iff2";
paulson@10751
   865
paulson@10751
   866
paulson@10751
   867
Goal "(NSDERIV f x :> D) ==> \
paulson@11383
   868
\    (\\<forall>u. \
paulson@11383
   869
\       u \\<approx> hypreal_of_real x --> \
nipkow@13810
   870
\       ( *f* (%z. f z - f x)) u \\<approx> hypreal_of_real D * (u - hypreal_of_real x))";
paulson@10751
   871
by (auto_tac (claset(), simpset() addsimps [NSDERIV_iff2]));
paulson@10751
   872
by (case_tac "u = hypreal_of_real x" 1);
paulson@12018
   873
by (auto_tac (claset(), simpset() addsimps [hypreal_diff_def]));
paulson@10751
   874
by (dres_inst_tac [("x","u")] spec 1);
paulson@10751
   875
by Auto_tac;
paulson@10751
   876
by (dres_inst_tac [("c","u - hypreal_of_real x"),("b","hypreal_of_real D")]
paulson@10919
   877
     approx_mult1 1);
paulson@10751
   878
by (ALLGOALS(dtac (hypreal_not_eq_minus_iff RS iffD1)));
nipkow@13810
   879
by (subgoal_tac "( *f* (%z. z - x)) u \\<noteq> (0::hypreal)" 2);
paulson@10751
   880
by (auto_tac (claset(),
paulson@10751
   881
    simpset() addsimps [real_diff_def, hypreal_diff_def, 
paulson@10919
   882
		(approx_minus_iff RS iffD1) RS (mem_infmal_iff RS iffD2),  
paulson@10751
   883
			Infinitesimal_subset_HFinite RS subsetD]));
paulson@10751
   884
qed "NSDERIVD5";
paulson@10751
   885
paulson@10751
   886
Goal "(NSDERIV f x :> D) ==> \
paulson@11383
   887
\     (\\<forall>h \\<in> Infinitesimal. \
nipkow@13810
   888
\              (( *f* f)(hypreal_of_real x + h) - \
paulson@11383
   889
\                hypreal_of_real (f x))\\<approx> (hypreal_of_real D) * h)";
paulson@10751
   890
by (auto_tac (claset(),simpset() addsimps [nsderiv_def]));
paulson@10751
   891
by (case_tac "h = (0::hypreal)" 1);
paulson@10751
   892
by (auto_tac (claset(),simpset() addsimps [hypreal_diff_def]));
paulson@10751
   893
by (dres_inst_tac [("x","h")] bspec 1);
paulson@10919
   894
by (dres_inst_tac [("c","h")] approx_mult1 2);
paulson@10751
   895
by (auto_tac (claset() addIs [Infinitesimal_subset_HFinite RS subsetD],
paulson@10751
   896
              simpset() addsimps [hypreal_diff_def]));
paulson@10751
   897
qed "NSDERIVD4";
paulson@10751
   898
paulson@10751
   899
Goal "(NSDERIV f x :> D) ==> \
paulson@11383
   900
\     (\\<forall>h \\<in> Infinitesimal - {0}. \
nipkow@13810
   901
\              (( *f* f)(hypreal_of_real x + h) - \
paulson@11383
   902
\                hypreal_of_real (f x))\\<approx> (hypreal_of_real D) * h)";
paulson@10751
   903
by (auto_tac (claset(),simpset() addsimps [nsderiv_def]));
paulson@10751
   904
by (rtac ccontr 1 THEN dres_inst_tac [("x","h")] bspec 1);
paulson@10919
   905
by (dres_inst_tac [("c","h")] approx_mult1 2);
paulson@10751
   906
by (auto_tac (claset() addIs [Infinitesimal_subset_HFinite RS subsetD],
paulson@10751
   907
              simpset() addsimps [hypreal_mult_assoc, hypreal_diff_def]));
paulson@10751
   908
qed "NSDERIVD3";
paulson@10751
   909
paulson@10751
   910
(*--------------------------------------------------------------
paulson@10751
   911
          Now equivalence between NSDERIV and DERIV
paulson@10751
   912
 -------------------------------------------------------------*)
paulson@10751
   913
Goalw [deriv_def] "(NSDERIV f x :> D) = (DERIV f x :> D)";
paulson@10751
   914
by (simp_tac (simpset() addsimps [NSDERIV_NSLIM_iff,LIM_NSLIM_iff]) 1);
paulson@10751
   915
qed "NSDERIV_DERIV_iff";
paulson@10751
   916
paulson@10751
   917
(*---------------------------------------------------
paulson@10751
   918
         Differentiability implies continuity 
paulson@10751
   919
         nice and simple "algebraic" proof
paulson@10751
   920
 --------------------------------------------------*)
paulson@10751
   921
Goalw [nsderiv_def]
paulson@10751
   922
      "NSDERIV f x :> D ==> isNSCont f x";
paulson@10751
   923
by (auto_tac (claset(),simpset() addsimps 
paulson@10751
   924
        [isNSCont_NSLIM_iff,NSLIM_def]));
paulson@10919
   925
by (dtac (approx_minus_iff RS iffD1) 1);
paulson@10751
   926
by (dtac (hypreal_not_eq_minus_iff RS iffD1) 1);
paulson@10751
   927
by (dres_inst_tac [("x","-hypreal_of_real x + xa")] bspec 1);
paulson@10751
   928
by (asm_full_simp_tac (simpset() addsimps 
paulson@10751
   929
    [hypreal_add_assoc RS sym]) 2);
paulson@10751
   930
by (auto_tac (claset(),simpset() addsimps 
paulson@10751
   931
    [mem_infmal_iff RS sym,hypreal_add_commute]));
paulson@10919
   932
by (dres_inst_tac [("c","xa + -hypreal_of_real x")] approx_mult1 1);
paulson@10751
   933
by (auto_tac (claset() addIs [Infinitesimal_subset_HFinite
paulson@10751
   934
    RS subsetD],simpset() addsimps [hypreal_mult_assoc]));
paulson@10751
   935
by (dres_inst_tac [("x3","D")] (HFinite_hypreal_of_real RSN
paulson@10751
   936
    (2,Infinitesimal_HFinite_mult) RS (mem_infmal_iff RS iffD1)) 1);
paulson@10919
   937
by (blast_tac (claset() addIs [approx_trans,
paulson@10751
   938
    hypreal_mult_commute RS subst,
paulson@10919
   939
    (approx_minus_iff RS iffD2)]) 1);
paulson@10751
   940
qed "NSDERIV_isNSCont";
paulson@10751
   941
paulson@10751
   942
(* Now Sandard proof *)
paulson@10751
   943
Goal "DERIV f x :> D ==> isCont f x";
paulson@10751
   944
by (asm_full_simp_tac (simpset() addsimps 
paulson@10751
   945
    [NSDERIV_DERIV_iff RS sym, isNSCont_isCont_iff RS sym,
paulson@10751
   946
     NSDERIV_isNSCont]) 1);
paulson@10751
   947
qed "DERIV_isCont";
paulson@10751
   948
paulson@10751
   949
(*----------------------------------------------------------------------------
paulson@10751
   950
      Differentiation rules for combinations of functions
paulson@10751
   951
      follow from clear, straightforard, algebraic 
paulson@10751
   952
      manipulations
paulson@10751
   953
 ----------------------------------------------------------------------------*)
paulson@10751
   954
(*-------------------------
paulson@10751
   955
    Constant function
paulson@10751
   956
 ------------------------*)
paulson@10751
   957
paulson@10751
   958
(* use simple constant nslimit theorem *)
paulson@12018
   959
Goal "(NSDERIV (%x. k) x :> 0)";
paulson@10751
   960
by (simp_tac (simpset() addsimps [NSDERIV_NSLIM_iff]) 1);
paulson@10751
   961
qed "NSDERIV_const";
paulson@10751
   962
Addsimps [NSDERIV_const];
paulson@10751
   963
paulson@12018
   964
Goal "(DERIV (%x. k) x :> 0)";
paulson@10751
   965
by (simp_tac (simpset() addsimps [NSDERIV_DERIV_iff RS sym]) 1);
paulson@10751
   966
qed "DERIV_const";
paulson@10751
   967
Addsimps [DERIV_const];
paulson@10751
   968
paulson@10751
   969
(*-----------------------------------------------------
paulson@10751
   970
    Sum of functions- proved easily
paulson@10751
   971
 ----------------------------------------------------*)
paulson@10751
   972
paulson@10751
   973
paulson@10751
   974
Goal "[| NSDERIV f x :> Da;  NSDERIV g x :> Db |] \
paulson@10751
   975
\     ==> NSDERIV (%x. f x + g x) x :> Da + Db";
paulson@10751
   976
by (asm_full_simp_tac (simpset() addsimps [NSDERIV_NSLIM_iff,
paulson@11176
   977
           NSLIM_def]) 1 THEN REPEAT (Step_tac 1));
paulson@10751
   978
by (auto_tac (claset(),
paulson@10751
   979
       simpset() addsimps [hypreal_add_divide_distrib]));
paulson@10751
   980
by (dres_inst_tac [("b","hypreal_of_real Da"),
paulson@10919
   981
                   ("d","hypreal_of_real Db")] approx_add 1);
paulson@10751
   982
by (auto_tac (claset(), simpset() addsimps hypreal_add_ac));
paulson@10751
   983
qed "NSDERIV_add";
paulson@10751
   984
paulson@10751
   985
(* Standard theorem *)
paulson@10751
   986
Goal "[| DERIV f x :> Da; DERIV g x :> Db |] \
paulson@10751
   987
\     ==> DERIV (%x. f x + g x) x :> Da + Db";
paulson@10751
   988
by (asm_full_simp_tac (simpset() addsimps [NSDERIV_add,
paulson@10751
   989
                                     NSDERIV_DERIV_iff RS sym]) 1);
paulson@10751
   990
qed "DERIV_add";
paulson@10751
   991
paulson@10751
   992
(*-----------------------------------------------------
paulson@10751
   993
  Product of functions - Proof is trivial but tedious
paulson@10751
   994
  and long due to rearrangement of terms  
paulson@10751
   995
 ----------------------------------------------------*)
paulson@10751
   996
paulson@10751
   997
Goal "((a::hypreal)*b) + -(c*d) = (b*(a + -c)) + (c*(b + -d))";
paulson@10751
   998
by (simp_tac (simpset() addsimps [hypreal_add_mult_distrib2]) 1);
paulson@10751
   999
val lemma_nsderiv1 = result();
paulson@10751
  1000
paulson@11383
  1001
Goal "[| (x + y) / z = hypreal_of_real D + yb; z \\<noteq> 0; \
paulson@11383
  1002
\        z \\<in> Infinitesimal; yb \\<in> Infinitesimal |] \
paulson@12018
  1003
\     ==> x + y \\<approx> 0";
paulson@10751
  1004
by (forw_inst_tac [("c1","z")] (hypreal_mult_right_cancel RS iffD2) 1 
paulson@10751
  1005
    THEN assume_tac 1);
paulson@10751
  1006
by (thin_tac "(x + y) / z = hypreal_of_real D + yb" 1);
paulson@10751
  1007
by (auto_tac (claset() addSIs [Infinitesimal_HFinite_mult2, HFinite_add],
paulson@10751
  1008
              simpset() addsimps [hypreal_mult_assoc, mem_infmal_iff RS sym]));
paulson@10751
  1009
by (etac (Infinitesimal_subset_HFinite RS subsetD) 1);
paulson@10751
  1010
val lemma_nsderiv2 = result();
paulson@10751
  1011
paulson@10751
  1012
paulson@10751
  1013
Goal "[| NSDERIV f x :> Da; NSDERIV g x :> Db |] \
paulson@10751
  1014
\     ==> NSDERIV (%x. f x * g x) x :> (Da * g(x)) + (Db * f(x))";
paulson@11176
  1015
by (asm_full_simp_tac (simpset() addsimps [NSDERIV_NSLIM_iff, NSLIM_def]) 1);
paulson@11176
  1016
by (REPEAT (Step_tac 1));
paulson@10751
  1017
by (auto_tac (claset(),
paulson@12018
  1018
       simpset() addsimps [starfun_lambda_cancel, lemma_nsderiv1]));
paulson@10751
  1019
by (simp_tac (simpset() addsimps [hypreal_add_divide_distrib]) 1); 
paulson@10751
  1020
by (REPEAT(dtac (bex_Infinitesimal_iff2 RS iffD2) 1));
paulson@10751
  1021
by (auto_tac (claset(),
paulson@10751
  1022
        simpset() delsimps [hypreal_times_divide1_eq]
paulson@10751
  1023
		  addsimps [hypreal_times_divide1_eq RS sym]));
paulson@10751
  1024
by (dres_inst_tac [("D","Db")] lemma_nsderiv2 1);
paulson@10919
  1025
by (dtac (approx_minus_iff RS iffD2 RS (bex_Infinitesimal_iff2 RS iffD2)) 4);
paulson@10919
  1026
by (auto_tac (claset() addSIs [approx_add_mono1],
paulson@10751
  1027
      simpset() addsimps [hypreal_add_mult_distrib, hypreal_add_mult_distrib2, 
paulson@10751
  1028
			  hypreal_mult_commute, hypreal_add_assoc]));
paulson@10751
  1029
by (res_inst_tac [("w1","hypreal_of_real Db * hypreal_of_real (f x)")]
paulson@10751
  1030
    (hypreal_add_commute RS subst) 1);
paulson@10919
  1031
by (auto_tac (claset() addSIs [Infinitesimal_add_approx_self2 RS approx_sym,
paulson@10751
  1032
			       Infinitesimal_add, Infinitesimal_mult,
paulson@10751
  1033
			       Infinitesimal_hypreal_of_real_mult,
paulson@10751
  1034
			       Infinitesimal_hypreal_of_real_mult2],
paulson@10751
  1035
	      simpset() addsimps [hypreal_add_assoc RS sym]));
paulson@10751
  1036
qed "NSDERIV_mult";
paulson@10751
  1037
paulson@10751
  1038
Goal "[| DERIV f x :> Da; DERIV g x :> Db |] \
paulson@10751
  1039
\     ==> DERIV (%x. f x * g x) x :> (Da * g(x)) + (Db * f(x))";
paulson@10751
  1040
by (asm_full_simp_tac (simpset() addsimps [NSDERIV_mult,
paulson@10751
  1041
                                           NSDERIV_DERIV_iff RS sym]) 1);
paulson@10751
  1042
qed "DERIV_mult";
paulson@10751
  1043
paulson@10751
  1044
(*----------------------------
paulson@10751
  1045
   Multiplying by a constant
paulson@10751
  1046
 ---------------------------*)
paulson@10751
  1047
Goal "NSDERIV f x :> D \
paulson@10751
  1048
\     ==> NSDERIV (%x. c * f x) x :> c*D";
paulson@10751
  1049
by (asm_full_simp_tac 
paulson@10751
  1050
    (simpset() addsimps [real_times_divide1_eq RS sym, NSDERIV_NSLIM_iff,
paulson@10751
  1051
                         real_minus_mult_eq2, real_add_mult_distrib2 RS sym] 
nipkow@12481
  1052
             delsimps [real_times_divide1_eq, real_mult_minus_eq2]) 1);
paulson@10751
  1053
by (etac (NSLIM_const RS NSLIM_mult) 1);
paulson@10751
  1054
qed "NSDERIV_cmult";
paulson@10751
  1055
paulson@10751
  1056
(* let's do the standard proof though theorem *)
paulson@10751
  1057
(* LIM_mult2 follows from a NS proof          *)
paulson@10751
  1058
paulson@10751
  1059
Goalw [deriv_def] 
paulson@10751
  1060
      "DERIV f x :> D \
paulson@10751
  1061
\      ==> DERIV (%x. c * f x) x :> c*D";
paulson@10751
  1062
by (asm_full_simp_tac 
paulson@10751
  1063
    (simpset() addsimps [real_times_divide1_eq RS sym, NSDERIV_NSLIM_iff,
paulson@10751
  1064
                         real_minus_mult_eq2, real_add_mult_distrib2 RS sym] 
nipkow@12481
  1065
             delsimps [real_times_divide1_eq, real_mult_minus_eq2]) 1);
paulson@10751
  1066
by (etac (LIM_const RS LIM_mult2) 1);
paulson@10751
  1067
qed "DERIV_cmult";
paulson@10751
  1068
paulson@10751
  1069
(*--------------------------------
paulson@10751
  1070
   Negation of function
paulson@10751
  1071
 -------------------------------*)
paulson@10751
  1072
Goal "NSDERIV f x :> D ==> NSDERIV (%x. -(f x)) x :> -D";
paulson@10751
  1073
by (asm_full_simp_tac (simpset() addsimps [NSDERIV_NSLIM_iff]) 1);
paulson@10751
  1074
by (res_inst_tac [("t","f x")] (real_minus_minus RS subst) 1);
paulson@10751
  1075
by (asm_simp_tac (simpset() addsimps [real_minus_add_distrib RS sym,
nipkow@12481
  1076
                                      real_mult_minus_eq1] 
paulson@10751
  1077
                   delsimps [real_minus_add_distrib, real_minus_minus]) 1);
paulson@10751
  1078
by (etac NSLIM_minus 1);
paulson@10751
  1079
qed "NSDERIV_minus";
paulson@10751
  1080
paulson@10751
  1081
Goal "DERIV f x :> D \
paulson@10751
  1082
\     ==> DERIV (%x. -(f x)) x :> -D";
paulson@10751
  1083
by (asm_full_simp_tac (simpset() addsimps 
paulson@10751
  1084
    [NSDERIV_minus,NSDERIV_DERIV_iff RS sym]) 1);
paulson@10751
  1085
qed "DERIV_minus";
paulson@10751
  1086
paulson@10751
  1087
(*-------------------------------
paulson@10751
  1088
   Subtraction
paulson@10751
  1089
 ------------------------------*)
paulson@10751
  1090
Goal "[| NSDERIV f x :> Da; NSDERIV g x :> Db |] \
paulson@10751
  1091
\     ==> NSDERIV (%x. f x + -g x) x :> Da + -Db";
paulson@10751
  1092
by (blast_tac (claset() addDs [NSDERIV_add,NSDERIV_minus]) 1);
paulson@10751
  1093
qed "NSDERIV_add_minus";
paulson@10751
  1094
paulson@10751
  1095
Goal "[| DERIV f x :> Da; DERIV g x :> Db |] \
paulson@10751
  1096
\     ==> DERIV (%x. f x + -g x) x :> Da + -Db";
paulson@10751
  1097
by (blast_tac (claset() addDs [DERIV_add,DERIV_minus]) 1);
paulson@10751
  1098
qed "DERIV_add_minus";
paulson@10751
  1099
paulson@10751
  1100
Goalw [real_diff_def]
paulson@10751
  1101
     "[| NSDERIV f x :> Da; NSDERIV g x :> Db |] \
paulson@10751
  1102
\     ==> NSDERIV (%x. f x - g x) x :> Da - Db";
paulson@10751
  1103
by (blast_tac (claset() addIs [NSDERIV_add_minus]) 1);
paulson@10751
  1104
qed "NSDERIV_diff";
paulson@10751
  1105
paulson@10751
  1106
Goalw [real_diff_def]
paulson@10751
  1107
     "[| DERIV f x :> Da; DERIV g x :> Db |] \
paulson@10751
  1108
\      ==> DERIV (%x. f x - g x) x :> Da - Db";
paulson@10751
  1109
by (blast_tac (claset() addIs [DERIV_add_minus]) 1);
paulson@10751
  1110
qed "DERIV_diff";
paulson@10751
  1111
paulson@10751
  1112
(*---------------------------------------------------------------
paulson@10751
  1113
                     (NS) Increment
paulson@10751
  1114
 ---------------------------------------------------------------*)
paulson@10751
  1115
Goalw [increment_def] 
paulson@10751
  1116
      "f NSdifferentiable x ==> \
nipkow@13810
  1117
\     increment f x h = ( *f* f) (hypreal_of_real(x) + h) + \
paulson@10751
  1118
\     -hypreal_of_real (f x)";
paulson@10751
  1119
by (Blast_tac 1);
paulson@10751
  1120
qed "incrementI";
paulson@10751
  1121
paulson@10751
  1122
Goal "NSDERIV f x :> D ==> \
nipkow@13810
  1123
\    increment f x h = ( *f* f) (hypreal_of_real(x) + h) + \
paulson@10751
  1124
\    -hypreal_of_real (f x)";
paulson@10751
  1125
by (etac (NSdifferentiableI RS incrementI) 1);
paulson@10751
  1126
qed "incrementI2";
paulson@10751
  1127
paulson@10751
  1128
(* The Increment theorem -- Keisler p. 65 *)
paulson@12018
  1129
Goal "[| NSDERIV f x :> D; h \\<in> Infinitesimal; h \\<noteq> 0 |] \
paulson@11383
  1130
\     ==> \\<exists>e \\<in> Infinitesimal. increment f x h = hypreal_of_real(D)*h + e*h";
paulson@10751
  1131
by (forw_inst_tac [("h","h")] incrementI2 1 THEN rewtac nsderiv_def);
paulson@10751
  1132
by (dtac bspec 1 THEN Auto_tac);
paulson@10751
  1133
by (dtac (bex_Infinitesimal_iff2 RS iffD2) 1 THEN Step_tac 1);
paulson@10751
  1134
by (forw_inst_tac [("b1","hypreal_of_real(D) + y")] 
paulson@12018
  1135
    ((hypreal_mult_right_cancel RS iffD2)) 1);
nipkow@13810
  1136
by (thin_tac "(( *f* f) (hypreal_of_real(x) + h) + \
paulson@10751
  1137
\   - hypreal_of_real (f x)) / h = hypreal_of_real(D) + y" 2);
paulson@10751
  1138
by (assume_tac 1);
paulson@10751
  1139
by (asm_full_simp_tac (simpset() addsimps [hypreal_times_divide1_eq RS sym]
paulson@10751
  1140
             delsimps [hypreal_times_divide1_eq]) 1);
paulson@10751
  1141
by (auto_tac (claset(),
paulson@10751
  1142
              simpset() addsimps [hypreal_add_mult_distrib]));
paulson@10751
  1143
qed "increment_thm";
paulson@10751
  1144
paulson@12018
  1145
Goal "[| NSDERIV f x :> D; h \\<approx> 0; h \\<noteq> 0 |] \
paulson@11383
  1146
\     ==> \\<exists>e \\<in> Infinitesimal. increment f x h = \
paulson@10751
  1147
\             hypreal_of_real(D)*h + e*h";
paulson@10751
  1148
by (blast_tac (claset() addSDs [mem_infmal_iff RS iffD2] 
paulson@10751
  1149
                        addSIs [increment_thm]) 1);
paulson@10751
  1150
qed "increment_thm2";
paulson@10751
  1151
paulson@12018
  1152
Goal "[| NSDERIV f x :> D; h \\<approx> 0; h \\<noteq> 0 |] \
paulson@12018
  1153
\     ==> increment f x h \\<approx> 0";
paulson@10751
  1154
by (dtac increment_thm2 1 THEN auto_tac (claset() addSIs 
paulson@10751
  1155
    [Infinitesimal_HFinite_mult2,HFinite_add],simpset() addsimps 
paulson@10751
  1156
    [hypreal_add_mult_distrib RS sym,mem_infmal_iff RS sym]));
paulson@10751
  1157
by (etac (Infinitesimal_subset_HFinite RS subsetD) 1);
paulson@10919
  1158
qed "increment_approx_zero";
paulson@10751
  1159
paulson@10751
  1160
(*---------------------------------------------------------------
paulson@10751
  1161
   Similarly to the above, the chain rule admits an entirely
paulson@10751
  1162
   straightforward derivation. Compare this with Harrison's
paulson@10751
  1163
   HOL proof of the chain rule, which proved to be trickier and
paulson@10751
  1164
   required an alternative characterisation of differentiability- 
paulson@10751
  1165
   the so-called Carathedory derivative. Our main problem is
paulson@10751
  1166
   manipulation of terms.
paulson@10751
  1167
 --------------------------------------------------------------*)
paulson@10751
  1168
paulson@10751
  1169
(* lemmas *)
paulson@10751
  1170
Goalw [nsderiv_def] 
paulson@10751
  1171
      "[| NSDERIV g x :> D; \
nipkow@13810
  1172
\              ( *f* g) (hypreal_of_real(x) + xa) = hypreal_of_real(g x);\
paulson@11383
  1173
\              xa \\<in> Infinitesimal;\
paulson@12018
  1174
\              xa \\<noteq> 0 \
paulson@12018
  1175
\           |] ==> D = 0";
paulson@10751
  1176
by (dtac bspec 1);
paulson@10751
  1177
by Auto_tac;
paulson@10751
  1178
qed "NSDERIV_zero";
paulson@10751
  1179
paulson@10751
  1180
(* can be proved differently using NSLIM_isCont_iff *)
paulson@10751
  1181
Goalw [nsderiv_def] 
paulson@12018
  1182
     "[| NSDERIV f x :> D;  h \\<in> Infinitesimal;  h \\<noteq> 0 |]  \
nipkow@13810
  1183
\     ==> ( *f* f) (hypreal_of_real(x) + h) + -hypreal_of_real(f x) \\<approx> 0";    
paulson@10751
  1184
by (asm_full_simp_tac (simpset() addsimps 
paulson@10751
  1185
    [mem_infmal_iff RS sym]) 1);
paulson@10751
  1186
by (rtac Infinitesimal_ratio 1);
paulson@10919
  1187
by (rtac approx_hypreal_of_real_HFinite 3);
paulson@10751
  1188
by Auto_tac;
paulson@10919
  1189
qed "NSDERIV_approx";
paulson@10751
  1190
paulson@10751
  1191
(*--------------------------------------------------------------- 
paulson@10751
  1192
   from one version of differentiability 
paulson@10751
  1193
 
paulson@10751
  1194
                f(x) - f(a)
paulson@11383
  1195
              --------------- \\<approx> Db
paulson@10751
  1196
                  x - a
paulson@10751
  1197
 ---------------------------------------------------------------*)
paulson@10751
  1198
Goal "[| NSDERIV f (g x) :> Da; \
nipkow@13810
  1199
\        ( *f* g) (hypreal_of_real(x) + xa) \\<noteq> hypreal_of_real (g x); \
nipkow@13810
  1200
\        ( *f* g) (hypreal_of_real(x) + xa) \\<approx> hypreal_of_real (g x) \
nipkow@13810
  1201
\     |] ==> (( *f* f) (( *f* g) (hypreal_of_real(x) + xa)) \
paulson@10751
  1202
\                  + - hypreal_of_real (f (g x))) \
nipkow@13810
  1203
\             / (( *f* g) (hypreal_of_real(x) + xa) + - hypreal_of_real (g x)) \
paulson@11383
  1204
\            \\<approx> hypreal_of_real(Da)";
paulson@10751
  1205
by (auto_tac (claset(),
paulson@10751
  1206
       simpset() addsimps [NSDERIV_NSLIM_iff2, NSLIM_def]));
paulson@10751
  1207
qed "NSDERIVD1";
paulson@10751
  1208
paulson@10751
  1209
(*-------------------------------------------------------------- 
paulson@10751
  1210
   from other version of differentiability 
paulson@10751
  1211
paulson@10751
  1212
                f(x + h) - f(x)
paulson@11383
  1213
               ----------------- \\<approx> Db
paulson@10751
  1214
                       h
paulson@10751
  1215
 --------------------------------------------------------------*)
paulson@12018
  1216
Goal "[| NSDERIV g x :> Db; xa \\<in> Infinitesimal; xa \\<noteq> 0 |] \
nipkow@13810
  1217
\     ==> (( *f* g) (hypreal_of_real(x) + xa) + - hypreal_of_real(g x)) / xa \
paulson@11383
  1218
\         \\<approx> hypreal_of_real(Db)";
paulson@10751
  1219
by (auto_tac (claset(),
paulson@10751
  1220
    simpset() addsimps [NSDERIV_NSLIM_iff, NSLIM_def, 
paulson@12018
  1221
		        mem_infmal_iff, starfun_lambda_cancel]));
paulson@10751
  1222
qed "NSDERIVD2";
paulson@10751
  1223
paulson@11383
  1224
Goal "(z::hypreal) \\<noteq> 0 ==> x*y = (x*inverse(z))*(z*y)";
paulson@10751
  1225
by Auto_tac;  
paulson@10751
  1226
qed "lemma_chain";
paulson@10751
  1227
paulson@10751
  1228
(*------------------------------------------------------
paulson@10751
  1229
  This proof uses both definitions of differentiability.
paulson@10751
  1230
 ------------------------------------------------------*)
paulson@10751
  1231
Goal "[| NSDERIV f (g x) :> Da; NSDERIV g x :> Db |] \
paulson@10751
  1232
\     ==> NSDERIV (f o g) x :> Da * Db";
paulson@10751
  1233
by (asm_simp_tac (simpset() addsimps [NSDERIV_NSLIM_iff,
paulson@12018
  1234
    NSLIM_def,mem_infmal_iff RS sym]) 1 THEN Step_tac 1);
paulson@10919
  1235
by (forw_inst_tac [("f","g")] NSDERIV_approx 1);
paulson@10751
  1236
by (auto_tac (claset(),
paulson@10751
  1237
              simpset() addsimps [starfun_lambda_cancel2, starfun_o RS sym]));
nipkow@13810
  1238
by (case_tac "( *f* g) (hypreal_of_real(x) + xa) = hypreal_of_real (g x)" 1);
paulson@10751
  1239
by (dres_inst_tac [("g","g")] NSDERIV_zero 1);
paulson@12018
  1240
by (auto_tac (claset(), simpset() addsimps [hypreal_divide_def]));
nipkow@13810
  1241
by (res_inst_tac [("z1","( *f* g) (hypreal_of_real(x) + xa) + -hypreal_of_real (g x)"),
paulson@10751
  1242
    ("y1","inverse xa")] (lemma_chain RS ssubst) 1);
paulson@10751
  1243
by (etac (hypreal_not_eq_minus_iff RS iffD1) 1);
paulson@10919
  1244
by (rtac approx_mult_hypreal_of_real 1);
paulson@10751
  1245
by (fold_tac [hypreal_divide_def]);
paulson@10751
  1246
by (blast_tac (claset() addIs [NSDERIVD1,
paulson@10919
  1247
    approx_minus_iff RS iffD2]) 1);
paulson@10751
  1248
by (blast_tac (claset() addIs [NSDERIVD2]) 1);
paulson@10751
  1249
qed "NSDERIV_chain";
paulson@10751
  1250
paulson@10751
  1251
(* standard version *)
paulson@10751
  1252
Goal "[| DERIV f (g x) :> Da; \
paulson@10751
  1253
\                 DERIV g x :> Db \
paulson@10751
  1254
\              |] ==> DERIV (f o g) x :> Da * Db";
paulson@10751
  1255
by (asm_full_simp_tac (simpset() addsimps [NSDERIV_DERIV_iff RS sym,
paulson@10751
  1256
    NSDERIV_chain]) 1);
paulson@10751
  1257
qed "DERIV_chain";
paulson@10751
  1258
paulson@10751
  1259
Goal "[| DERIV f (g x) :> Da; DERIV g x :> Db |] \
paulson@10751
  1260
\     ==> DERIV (%x. f (g x)) x :> Da * Db";
paulson@10751
  1261
by (auto_tac (claset() addDs [DERIV_chain], simpset() addsimps [o_def]));
paulson@10751
  1262
qed "DERIV_chain2";
paulson@10751
  1263
paulson@10751
  1264
(*------------------------------------------------------------------
paulson@10751
  1265
           Differentiation of natural number powers
paulson@10751
  1266
 ------------------------------------------------------------------*)
paulson@12018
  1267
Goal "NSDERIV (%x. x) x :> 1";
paulson@10751
  1268
by (auto_tac (claset(),
paulson@12018
  1269
     simpset() addsimps [NSDERIV_NSLIM_iff, NSLIM_def ,starfun_Id]));
paulson@10751
  1270
qed "NSDERIV_Id";
paulson@10751
  1271
Addsimps [NSDERIV_Id];
paulson@10751
  1272
paulson@10751
  1273
(*derivative of the identity function*)
paulson@12018
  1274
Goal "DERIV (%x. x) x :> 1";
paulson@10751
  1275
by (simp_tac (simpset() addsimps [NSDERIV_DERIV_iff RS sym]) 1);
paulson@10751
  1276
qed "DERIV_Id";
paulson@10751
  1277
Addsimps [DERIV_Id];
paulson@10751
  1278
paulson@10751
  1279
bind_thm ("isCont_Id", DERIV_Id RS DERIV_isCont);
paulson@10751
  1280
paulson@10751
  1281
(*derivative of linear multiplication*)
paulson@10751
  1282
Goal "DERIV (op * c) x :> c";
paulson@10751
  1283
by (cut_inst_tac [("c","c"),("x","x")] (DERIV_Id RS DERIV_cmult) 1);
paulson@10751
  1284
by (Asm_full_simp_tac 1);
paulson@10751
  1285
qed "DERIV_cmult_Id";
paulson@10751
  1286
Addsimps [DERIV_cmult_Id];
paulson@10751
  1287
paulson@10751
  1288
Goal "NSDERIV (op * c) x :> c";
paulson@10751
  1289
by (simp_tac (simpset() addsimps [NSDERIV_DERIV_iff]) 1);
paulson@10751
  1290
qed "NSDERIV_cmult_Id";
paulson@10751
  1291
Addsimps [NSDERIV_cmult_Id];
paulson@10751
  1292
wenzelm@11701
  1293
Goal "DERIV (%x. x ^ n) x :> real n * (x ^ (n - Suc 0))";
paulson@10751
  1294
by (induct_tac "n" 1);
paulson@10751
  1295
by (dtac (DERIV_Id RS DERIV_mult) 2);
paulson@10778
  1296
by (auto_tac (claset(), 
paulson@10778
  1297
              simpset() addsimps [real_of_nat_Suc, real_add_mult_distrib]));
paulson@10751
  1298
by (case_tac "0 < n" 1);
paulson@10751
  1299
by (dres_inst_tac [("x","x")] realpow_minus_mult 1);
paulson@10778
  1300
by (auto_tac (claset(), 
paulson@10778
  1301
              simpset() addsimps [real_mult_assoc, real_add_commute]));
paulson@10751
  1302
qed "DERIV_pow";
paulson@10751
  1303
paulson@10751
  1304
(* NS version *)
wenzelm@11701
  1305
Goal "NSDERIV (%x. x ^ n) x :> real n * (x ^ (n - Suc 0))";
paulson@10778
  1306
by (simp_tac (simpset() addsimps [NSDERIV_DERIV_iff, DERIV_pow]) 1);
paulson@10751
  1307
qed "NSDERIV_pow";
paulson@10751
  1308
paulson@10751
  1309
(*---------------------------------------------------------------
paulson@10751
  1310
                    Power of -1 
paulson@10751
  1311
 ---------------------------------------------------------------*)
paulson@10751
  1312
paulson@12018
  1313
(*Can't get rid of x \\<noteq> 0 because it isn't continuous at zero*)
paulson@10751
  1314
Goalw [nsderiv_def]
paulson@12018
  1315
     "x \\<noteq> 0 ==> NSDERIV (%x. inverse(x)) x :> (- (inverse x ^ Suc (Suc 0)))";
paulson@10751
  1316
by (rtac ballI 1 THEN Asm_full_simp_tac 1 THEN Step_tac 1);
wenzelm@12486
  1317
by (ftac Infinitesimal_add_not_zero 1);
paulson@10751
  1318
by (asm_full_simp_tac (simpset() addsimps [hypreal_add_commute]) 2); 
paulson@10751
  1319
by (auto_tac (claset(),
paulson@10751
  1320
     simpset() addsimps [starfun_inverse_inverse, realpow_two] 
paulson@10751
  1321
               delsimps [hypreal_minus_mult_eq1 RS sym,
paulson@10751
  1322
                         hypreal_minus_mult_eq2 RS sym]));
paulson@10751
  1323
by (asm_full_simp_tac
paulson@10751
  1324
     (simpset() addsimps [hypreal_inverse_add,
paulson@10751
  1325
          hypreal_inverse_distrib RS sym, hypreal_minus_inverse RS sym] 
paulson@10751
  1326
          @ hypreal_add_ac @ hypreal_mult_ac 
paulson@10751
  1327
       delsimps [hypreal_minus_mult_eq1 RS sym,
paulson@10751
  1328
                 hypreal_minus_mult_eq2 RS sym] ) 1);
paulson@10751
  1329
by (asm_simp_tac (simpset() addsimps [hypreal_mult_assoc RS sym,
paulson@10751
  1330
                                      hypreal_add_mult_distrib2] 
paulson@10751
  1331
         delsimps [hypreal_minus_mult_eq1 RS sym, 
paulson@10751
  1332
                   hypreal_minus_mult_eq2 RS sym]) 1);
paulson@10751
  1333
by (res_inst_tac [("y"," inverse(- hypreal_of_real x * hypreal_of_real x)")] 
paulson@10919
  1334
                 approx_trans 1);
paulson@10919
  1335
by (rtac inverse_add_Infinitesimal_approx2 1);
paulson@10751
  1336
by (auto_tac (claset() addSDs [hypreal_of_real_HFinite_diff_Infinitesimal], 
paulson@10751
  1337
         simpset() addsimps [hypreal_minus_inverse RS sym,
paulson@10751
  1338
                             HFinite_minus_iff]));
paulson@10751
  1339
by (rtac Infinitesimal_HFinite_mult2 1); 
paulson@10751
  1340
by Auto_tac;  
paulson@10751
  1341
qed "NSDERIV_inverse";
paulson@10751
  1342
paulson@10751
  1343
paulson@12018
  1344
Goal "x \\<noteq> 0 ==> DERIV (%x. inverse(x)) x :> (-(inverse x ^ Suc (Suc 0)))";
paulson@10751
  1345
by (asm_simp_tac (simpset() addsimps [NSDERIV_inverse,
paulson@10751
  1346
         NSDERIV_DERIV_iff RS sym] delsimps [realpow_Suc]) 1);
paulson@10751
  1347
qed "DERIV_inverse";
paulson@10751
  1348
paulson@10751
  1349
(*--------------------------------------------------------------
paulson@10751
  1350
        Derivative of inverse 
paulson@10751
  1351
 -------------------------------------------------------------*)
paulson@12018
  1352
Goal "[| DERIV f x :> d; f(x) \\<noteq> 0 |] \
wenzelm@11701
  1353
\     ==> DERIV (%x. inverse(f x)) x :> (- (d * inverse(f(x) ^ Suc (Suc 0))))";
paulson@10751
  1354
by (rtac (real_mult_commute RS subst) 1);
paulson@10751
  1355
by (asm_simp_tac (simpset() addsimps [real_minus_mult_eq1,
nipkow@12481
  1356
    realpow_inverse] delsimps [realpow_Suc, real_mult_minus_eq1]) 1);
paulson@10751
  1357
by (fold_goals_tac [o_def]);
paulson@10751
  1358
by (blast_tac (claset() addSIs [DERIV_chain,DERIV_inverse]) 1);
paulson@10751
  1359
qed "DERIV_inverse_fun";
paulson@10751
  1360
paulson@12018
  1361
Goal "[| NSDERIV f x :> d; f(x) \\<noteq> 0 |] \
wenzelm@11701
  1362
\     ==> NSDERIV (%x. inverse(f x)) x :> (- (d * inverse(f(x) ^ Suc (Suc 0))))";
paulson@10751
  1363
by (asm_full_simp_tac (simpset() addsimps [NSDERIV_DERIV_iff,
paulson@10751
  1364
            DERIV_inverse_fun] delsimps [realpow_Suc]) 1);
paulson@10751
  1365
qed "NSDERIV_inverse_fun";
paulson@10751
  1366
paulson@10751
  1367
(*--------------------------------------------------------------
paulson@10751
  1368
        Derivative of quotient 
paulson@10751
  1369
 -------------------------------------------------------------*)
paulson@12018
  1370
Goal "[| DERIV f x :> d; DERIV g x :> e; g(x) \\<noteq> 0 |] \
wenzelm@11701
  1371
\      ==> DERIV (%y. f(y) / (g y)) x :> (d*g(x) + -(e*f(x))) / (g(x) ^ Suc (Suc 0))";
paulson@10751
  1372
by (dres_inst_tac [("f","g")] DERIV_inverse_fun 1);
paulson@10751
  1373
by (dtac DERIV_mult 2);
paulson@10751
  1374
by (REPEAT(assume_tac 1));
paulson@10751
  1375
by (asm_full_simp_tac
paulson@10751
  1376
    (simpset() addsimps [real_divide_def, real_add_mult_distrib2,
paulson@10751
  1377
                         realpow_inverse,real_minus_mult_eq1] @ real_mult_ac 
nipkow@12481
  1378
       delsimps [realpow_Suc, real_mult_minus_eq1, real_mult_minus_eq2]) 1);
paulson@10751
  1379
qed "DERIV_quotient";
paulson@10751
  1380
paulson@12018
  1381
Goal "[| NSDERIV f x :> d; DERIV g x :> e; g(x) \\<noteq> 0 |] \
paulson@10751
  1382
\      ==> NSDERIV (%y. f(y) / (g y)) x :> (d*g(x) \
wenzelm@11701
  1383
\                           + -(e*f(x))) / (g(x) ^ Suc (Suc 0))";
paulson@10751
  1384
by (asm_full_simp_tac (simpset() addsimps [NSDERIV_DERIV_iff,
paulson@10751
  1385
            DERIV_quotient] delsimps [realpow_Suc]) 1);
paulson@10751
  1386
qed "NSDERIV_quotient";
paulson@10751
  1387
 
paulson@10751
  1388
(* ------------------------------------------------------------------------ *)
paulson@10751
  1389
(* Caratheodory formulation of derivative at a point: standard proof        *)
paulson@10751
  1390
(* ------------------------------------------------------------------------ *)
paulson@10751
  1391
paulson@10751
  1392
Goal "(DERIV f x :> l) = \
paulson@11383
  1393
\     (\\<exists>g. (\\<forall>z. f z - f x = g z * (z - x)) & isCont g x & g x = l)";
paulson@11176
  1394
by Safe_tac;
paulson@10751
  1395
by (res_inst_tac 
paulson@10751
  1396
    [("x","%z. if  z = x then l else (f(z) - f(x)) / (z - x)")] exI 1);
paulson@10751
  1397
by (auto_tac (claset(),simpset() addsimps [real_mult_assoc,
paulson@12018
  1398
    ARITH_PROVE "z \\<noteq> x ==> z - x \\<noteq> (0::real)"]));
paulson@10751
  1399
by (auto_tac (claset(),simpset() addsimps [isCont_iff,DERIV_iff]));
paulson@10751
  1400
by (ALLGOALS(rtac (LIM_equal RS iffD1)));
paulson@10751
  1401
by (auto_tac (claset(),simpset() addsimps [real_diff_def,real_mult_assoc]));
paulson@10751
  1402
qed "CARAT_DERIV";
paulson@10751
  1403
paulson@10751
  1404
Goal "NSDERIV f x :> l ==> \
paulson@11383
  1405
\     \\<exists>g. (\\<forall>z. f z - f x = g z * (z - x)) & isNSCont g x & g x = l";
paulson@10751
  1406
by (auto_tac (claset(),simpset() addsimps [NSDERIV_DERIV_iff,
paulson@10751
  1407
    isNSCont_isCont_iff,CARAT_DERIV]));
paulson@10751
  1408
qed "CARAT_NSDERIV";
paulson@10751
  1409
paulson@10751
  1410
(* How about a NS proof? *)
paulson@11383
  1411
Goal "(\\<forall>z. f z - f x = g z * (z - x)) & isNSCont g x & g x = l \
paulson@10751
  1412
\     ==> NSDERIV f x :> l";
paulson@10751
  1413
by (auto_tac (claset(), 
paulson@10751
  1414
              simpset() delsimprocs real_cancel_factor
paulson@10751
  1415
                        addsimps [NSDERIV_iff2]));
paulson@10751
  1416
by (auto_tac (claset(),
paulson@10751
  1417
              simpset() addsimps [hypreal_mult_assoc]));
paulson@10751
  1418
by (asm_full_simp_tac (simpset() addsimps [hypreal_eq_minus_iff3 RS sym,
paulson@10751
  1419
                                           hypreal_diff_def]) 1);
paulson@10751
  1420
by (asm_full_simp_tac (simpset() addsimps [isNSCont_def]) 1);
paulson@10751
  1421
qed "CARAT_DERIVD";
paulson@10751
  1422
 
paulson@10751
  1423
paulson@10751
  1424
paulson@10751
  1425
(*--------------------------------------------------------------------------*)
paulson@10751
  1426
(* Lemmas about nested intervals and proof by bisection (cf.Harrison)       *)
paulson@10751
  1427
(* All considerably tidied by lcp                                           *)
paulson@10751
  1428
(*--------------------------------------------------------------------------*)
paulson@10751
  1429
paulson@11383
  1430
Goal "(\\<forall>n. (f::nat=>real) n \\<le> f (Suc n)) --> f m \\<le> f(m + no)";
paulson@10751
  1431
by (induct_tac "no" 1);
paulson@10751
  1432
by (auto_tac (claset() addIs [order_trans], simpset()));
paulson@10751
  1433
qed_spec_mp "lemma_f_mono_add";
paulson@10751
  1434
paulson@11383
  1435
Goal "[| \\<forall>n. f(n) \\<le> f(Suc n); \
paulson@11383
  1436
\        \\<forall>n. g(Suc n) \\<le> g(n); \
paulson@11383
  1437
\        \\<forall>n. f(n) \\<le> g(n) |] \
paulson@10751
  1438
\     ==> Bseq f";
paulson@10751
  1439
by (res_inst_tac [("k","f 0"),("K","g 0")] BseqI2 1 THEN rtac allI 1);
paulson@10751
  1440
by (induct_tac "n" 1);
paulson@10751
  1441
by (auto_tac (claset() addIs [order_trans], simpset()));
paulson@10751
  1442
by (res_inst_tac [("y","g(Suc na)")] order_trans 1);
paulson@10751
  1443
by (induct_tac "na" 2);
paulson@10751
  1444
by (auto_tac (claset() addIs [order_trans], simpset()));
paulson@10751
  1445
qed "f_inc_g_dec_Beq_f";
paulson@10751
  1446
paulson@11383
  1447
Goal "[| \\<forall>n. f(n) \\<le> f(Suc n); \
paulson@11383
  1448
\        \\<forall>n. g(Suc n) \\<le> g(n); \
paulson@11383
  1449
\        \\<forall>n. f(n) \\<le> g(n) |] \
paulson@10751
  1450
\     ==> Bseq g";
paulson@10751
  1451
by (stac (Bseq_minus_iff RS sym) 1);
paulson@10751
  1452
by (res_inst_tac [("g","%x. -(f x)")] f_inc_g_dec_Beq_f 1); 
paulson@10751
  1453
by Auto_tac;  
paulson@10751
  1454
qed "f_inc_g_dec_Beq_g";
paulson@10751
  1455
paulson@11383
  1456
Goal "[| \\<forall>n. f n \\<le> f (Suc n);  convergent f |] ==> f n \\<le> lim f";
paulson@10751
  1457
by (rtac real_leI 1);
paulson@10751
  1458
by (auto_tac (claset(), 
paulson@10751
  1459
      simpset() addsimps [convergent_LIMSEQ_iff, LIMSEQ_iff, monoseq_Suc]));
paulson@10751
  1460
by (dtac real_less_sum_gt_zero 1);
paulson@10751
  1461
by (dres_inst_tac [("x","f n + - lim f")] spec 1);
paulson@10751
  1462
by Safe_tac;
paulson@12018
  1463
by (dres_inst_tac [("P","%na. no\\<le>na --> ?Q na"),("x","no + n")] spec 1);
paulson@10751
  1464
by Auto_tac;
paulson@11383
  1465
by (subgoal_tac "lim f \\<le> f(no + n)" 1);
paulson@10751
  1466
by (induct_tac "no" 2);
paulson@10751
  1467
by (auto_tac (claset() addIs [order_trans],
paulson@10751
  1468
              simpset() addsimps [real_diff_def, real_abs_def]));
paulson@10751
  1469
by (dres_inst_tac [("x","f(no + n)"),("no1","no")] 
paulson@10751
  1470
    (lemma_f_mono_add RSN (2,order_less_le_trans)) 1);
paulson@10751
  1471
by (auto_tac (claset(), simpset() addsimps [add_commute]));
paulson@10751
  1472
qed "f_inc_imp_le_lim";
paulson@10751
  1473
paulson@10751
  1474
Goal "convergent g ==> lim (%x. - g x) = - (lim g)";
paulson@10751
  1475
by (rtac (LIMSEQ_minus RS limI) 1); 
paulson@10751
  1476
by (asm_full_simp_tac (simpset() addsimps [convergent_LIMSEQ_iff]) 1); 
paulson@10751
  1477
qed "lim_uminus";
paulson@10751
  1478
paulson@11383
  1479
Goal "[| \\<forall>n. g(Suc n) \\<le> g(n);  convergent g |] ==> lim g \\<le> g n";
paulson@11383
  1480
by (subgoal_tac "- (g n) \\<le> - (lim g)" 1);
paulson@10751
  1481
by (cut_inst_tac [("f", "%x. - (g x)")] f_inc_imp_le_lim 2);
paulson@10751
  1482
by (auto_tac (claset(), 
paulson@10751
  1483
              simpset() addsimps [lim_uminus, convergent_minus_iff RS sym]));  
paulson@10751
  1484
qed "g_dec_imp_lim_le";
paulson@10751
  1485
paulson@11383
  1486
Goal "[| \\<forall>n. f(n) \\<le> f(Suc n); \
paulson@11383
  1487
\        \\<forall>n. g(Suc n) \\<le> g(n); \
paulson@11383
  1488
\        \\<forall>n. f(n) \\<le> g(n) |] \
paulson@11383
  1489
\     ==> \\<exists>l m. l \\<le> m &  ((\\<forall>n. f(n) \\<le> l) & f ----> l) & \
paulson@11383
  1490
\                           ((\\<forall>n. m \\<le> g(n)) & g ----> m)";
paulson@10751
  1491
by (subgoal_tac "monoseq f & monoseq g" 1);
paulson@10751
  1492
by (force_tac (claset(), simpset() addsimps [LIMSEQ_iff,monoseq_Suc]) 2);
paulson@10751
  1493
by (subgoal_tac "Bseq f & Bseq g" 1);
paulson@10751
  1494
by (blast_tac (claset() addIs [f_inc_g_dec_Beq_f, f_inc_g_dec_Beq_g]) 2); 
paulson@10751
  1495
by (auto_tac (claset() addSDs [Bseq_monoseq_convergent],
paulson@10751
  1496
              simpset() addsimps [convergent_LIMSEQ_iff]));
paulson@10751
  1497
by (res_inst_tac [("x","lim f")] exI 1);
paulson@10751
  1498
by (res_inst_tac [("x","lim g")] exI 1);
paulson@10751
  1499
by (auto_tac (claset() addIs [LIMSEQ_le], simpset()));
paulson@10751
  1500
by (auto_tac (claset(), 
paulson@10751
  1501
              simpset() addsimps [f_inc_imp_le_lim, g_dec_imp_lim_le, 
paulson@10751
  1502
                                  convergent_LIMSEQ_iff]));  
paulson@10751
  1503
qed "lemma_nest";
paulson@10751
  1504
paulson@11383
  1505
Goal "[| \\<forall>n. f(n) \\<le> f(Suc n); \
paulson@11383
  1506
\        \\<forall>n. g(Suc n) \\<le> g(n); \
paulson@11383
  1507
\        \\<forall>n. f(n) \\<le> g(n); \
paulson@12018
  1508
\        (%n. f(n) - g(n)) ----> 0 |] \
paulson@11383
  1509
\     ==> \\<exists>l. ((\\<forall>n. f(n) \\<le> l) & f ----> l) & \
paulson@11383
  1510
\               ((\\<forall>n. l \\<le> g(n)) & g ----> l)";
paulson@10751
  1511
by (dtac lemma_nest 1 THEN Auto_tac);
paulson@10751
  1512
by (subgoal_tac "l = m" 1);
paulson@10751
  1513
by (dres_inst_tac [("X","f")] LIMSEQ_diff 2);
paulson@10751
  1514
by (auto_tac (claset() addIs [LIMSEQ_unique], simpset()));
paulson@10751
  1515
qed "lemma_nest_unique";
paulson@10751
  1516
paulson@10751
  1517
paulson@11383
  1518
Goal "a \\<le> b ==> \
paulson@11383
  1519
\  \\<forall>n. fst (Bolzano_bisect P a b n) \\<le> snd (Bolzano_bisect P a b n)";
paulson@10751
  1520
by (rtac allI 1);
paulson@10751
  1521
by (induct_tac "n" 1);
paulson@10751
  1522
by (auto_tac (claset(), simpset() addsimps [Let_def, split_def]));  
paulson@10751
  1523
qed "Bolzano_bisect_le";
paulson@10751
  1524
paulson@11383
  1525
Goal "a \\<le> b ==> \
paulson@11383
  1526
\  \\<forall>n. fst(Bolzano_bisect P a b n) \\<le> fst (Bolzano_bisect P a b (Suc n))";
paulson@10751
  1527
by (rtac allI 1);
paulson@10751
  1528
by (induct_tac "n" 1);
paulson@10751
  1529
by (auto_tac (claset(), 
paulson@10751
  1530
              simpset() addsimps [Bolzano_bisect_le, Let_def, split_def]));  
paulson@10751
  1531
qed "Bolzano_bisect_fst_le_Suc";
paulson@10751
  1532
paulson@11383
  1533
Goal "a \\<le> b ==> \
paulson@11383
  1534
\  \\<forall>n. snd(Bolzano_bisect P a b (Suc n)) \\<le> snd (Bolzano_bisect P a b n)";
paulson@10751
  1535
by (rtac allI 1);
paulson@10751
  1536
by (induct_tac "n" 1);
paulson@10751
  1537
by (auto_tac (claset(), 
paulson@10751
  1538
              simpset() addsimps [Bolzano_bisect_le, Let_def, split_def]));  
paulson@10751
  1539
qed "Bolzano_bisect_Suc_le_snd";
paulson@10751
  1540
wenzelm@11704
  1541
Goal "((x::real) = y / (2 * z)) = (2 * x = y/z)";
paulson@10751
  1542
by Auto_tac;  
paulson@12018
  1543
by (dres_inst_tac [("f","%u. (1/2)*u")] arg_cong 1); 
paulson@10751
  1544
by Auto_tac;  
paulson@10751
  1545
qed "eq_divide_2_times_iff";
paulson@10751
  1546
paulson@11383
  1547
Goal "a \\<le> b ==> \
paulson@10751
  1548
\     snd(Bolzano_bisect P a b n) - fst(Bolzano_bisect P a b n) = \
wenzelm@11704
  1549
\     (b-a) / (2 ^ n)";
paulson@10751
  1550
by (induct_tac "n" 1);
paulson@10751
  1551
by (auto_tac (claset(), 
paulson@10751
  1552
      simpset() addsimps [eq_divide_2_times_iff, real_add_divide_distrib, 
paulson@10751
  1553
                          Let_def, split_def]));
paulson@10751
  1554
by (auto_tac (claset(), 
paulson@10751
  1555
              simpset() addsimps (real_add_ac@[Bolzano_bisect_le, real_diff_def])));
paulson@10751
  1556
qed "Bolzano_bisect_diff";
paulson@10751
  1557
paulson@10751
  1558
val Bolzano_nest_unique =
paulson@10751
  1559
    [Bolzano_bisect_fst_le_Suc, Bolzano_bisect_Suc_le_snd, Bolzano_bisect_le] 
paulson@10751
  1560
    MRS lemma_nest_unique;
paulson@10751
  1561
paulson@10751
  1562
(*P_prem is a looping simprule, so it works better if it isn't an assumption*)
paulson@10751
  1563
val P_prem::notP_prem::rest =
paulson@11383
  1564
Goal "[| !!a b c. [| P(a,b); P(b,c); a \\<le> b; b \\<le> c|] ==> P(a,c); \
paulson@11383
  1565
\        ~ P(a,b);  a \\<le> b |] ==> \
paulson@10751
  1566
\     ~ P(fst(Bolzano_bisect P a b n), snd(Bolzano_bisect P a b n))";
paulson@10751
  1567
by (cut_facts_tac rest 1);
paulson@10751
  1568
by (induct_tac "n" 1);
paulson@10751
  1569
by (auto_tac (claset(), 
paulson@10751
  1570
              simpset() delsimps [surjective_pairing RS sym]
paulson@10751
  1571
			addsimps [notP_prem, Let_def, split_def]));  
paulson@10751
  1572
by (swap_res_tac [P_prem] 1);
paulson@10751
  1573
by (assume_tac 1); 
paulson@10751
  1574
by (auto_tac (claset(), simpset() addsimps [Bolzano_bisect_le]));  
paulson@10751
  1575
qed "not_P_Bolzano_bisect";
paulson@10751
  1576
paulson@10751
  1577
(*Now we re-package P_prem as a formula*)
paulson@11383
  1578
Goal "[| \\<forall>a b c. P(a,b) & P(b,c) & a \\<le> b & b \\<le> c --> P(a,c); \
paulson@11383
  1579
\        ~ P(a,b);  a \\<le> b |] ==> \
paulson@11383
  1580
\     \\<forall>n. ~ P(fst(Bolzano_bisect P a b n), snd(Bolzano_bisect P a b n))";
paulson@10751
  1581
by (blast_tac (claset() addSEs [not_P_Bolzano_bisect RSN (2,rev_notE)]) 1); 
paulson@10751
  1582
qed "not_P_Bolzano_bisect'";
paulson@10751
  1583
paulson@10751
  1584
paulson@11383
  1585
Goal "[| \\<forall>a b c. P(a,b) & P(b,c) & a \\<le> b & b \\<le> c --> P(a,c); \
paulson@12018
  1586
\        \\<forall>x. \\<exists>d::real. 0 < d & \
paulson@11383
  1587
\               (\\<forall>a b. a \\<le> x & x \\<le> b & (b - a) < d --> P(a,b)); \
paulson@11383
  1588
\        a \\<le> b |]  \
paulson@10751
  1589
\     ==> P(a,b)";
paulson@10751
  1590
by (rtac (inst "P1" "P" Bolzano_nest_unique RS exE) 1);
paulson@10751
  1591
by (REPEAT (assume_tac 1));
paulson@10751
  1592
by (rtac LIMSEQ_minus_cancel 1);
paulson@10751
  1593
by (asm_simp_tac (simpset() addsimps [Bolzano_bisect_diff,
paulson@10751
  1594
                                      LIMSEQ_divide_realpow_zero]) 1); 
paulson@10751
  1595
by (rtac ccontr 1);
paulson@10751
  1596
by (dtac not_P_Bolzano_bisect' 1); 
paulson@10751
  1597
by (REPEAT (assume_tac 1));
paulson@10751
  1598
by (rename_tac "l" 1);
paulson@10751
  1599
by (dres_inst_tac [("x","l")] spec 1 THEN Clarify_tac 1);
paulson@10751
  1600
by (rewtac LIMSEQ_def);
paulson@12018
  1601
by (dres_inst_tac [("P", "%r. 0<r --> ?Q r"), ("x","d/2")] spec 1);
paulson@12018
  1602
by (dres_inst_tac [("P", "%r. 0<r --> ?Q r"), ("x","d/2")] spec 1);
paulson@10751
  1603
by (dtac real_less_half_sum 1);
paulson@10751
  1604
by Safe_tac;
paulson@10751
  1605
(*linear arithmetic bug if we just use Asm_simp_tac*)
paulson@10751
  1606
by (ALLGOALS Asm_full_simp_tac);
paulson@10751
  1607
by (dres_inst_tac [("x","fst(Bolzano_bisect P a b (no + noa))")] spec 1);
paulson@10751
  1608
by (dres_inst_tac [("x","snd(Bolzano_bisect P a b (no + noa))")] spec 1);
paulson@10751
  1609
by Safe_tac;
paulson@10751
  1610
by (ALLGOALS Asm_simp_tac);
paulson@10751
  1611
by (res_inst_tac [("y","abs(fst(Bolzano_bisect P a b(no + noa)) - l) + \
paulson@10751
  1612
\                       abs(snd(Bolzano_bisect P a b(no + noa)) - l)")] 
paulson@10751
  1613
    order_le_less_trans 1);
paulson@10751
  1614
by (asm_simp_tac (simpset() addsimps [real_abs_def]) 1);  
paulson@10751
  1615
by (rtac (real_sum_of_halves RS subst) 1);
paulson@10751
  1616
by (rtac real_add_less_mono 1);
paulson@10751
  1617
by (ALLGOALS 
paulson@10751
  1618
    (asm_full_simp_tac (simpset() addsimps [symmetric real_diff_def])));
paulson@10751
  1619
qed "lemma_BOLZANO";
paulson@10751
  1620
paulson@10751
  1621
paulson@11383
  1622
Goal "((\\<forall>a b c. (a \\<le> b & b \\<le> c & P(a,b) & P(b,c)) --> P(a,c)) & \
paulson@12018
  1623
\      (\\<forall>x. \\<exists>d::real. 0 < d & \
paulson@11383
  1624
\               (\\<forall>a b. a \\<le> x & x \\<le> b & (b - a) < d --> P(a,b)))) \
paulson@11383
  1625
\     --> (\\<forall>a b. a \\<le> b --> P(a,b))";
paulson@10751
  1626
by (Clarify_tac 1);
paulson@10751
  1627
by (blast_tac (claset() addIs [lemma_BOLZANO]) 1); 
paulson@10751
  1628
qed "lemma_BOLZANO2";
paulson@10751
  1629
paulson@10751
  1630
paulson@10751
  1631
(*----------------------------------------------------------------------------*)
paulson@10751
  1632
(* Intermediate Value Theorem (prove contrapositive by bisection)             *)
paulson@10751
  1633
(*----------------------------------------------------------------------------*)
paulson@10751
  1634
paulson@11383
  1635
Goal "[| f(a) \\<le> y & y \\<le> f(b); \
paulson@11383
  1636
\        a \\<le> b; \
paulson@11383
  1637
\        (\\<forall>x. a \\<le> x & x \\<le> b --> isCont f x) |] \
paulson@11383
  1638
\     ==> \\<exists>x. a \\<le> x & x \\<le> b & f(x) = y";
paulson@10751
  1639
by (rtac contrapos_pp 1);
paulson@10751
  1640
by (assume_tac 1);
paulson@10751
  1641
by (cut_inst_tac
paulson@11383
  1642
    [("P","%(u,v). a \\<le> u & u \\<le> v & v \\<le> b --> ~(f(u) \\<le> y & y \\<le> f(v))")] 
paulson@10751
  1643
    lemma_BOLZANO2 1);
paulson@11176
  1644
by Safe_tac;
paulson@10751
  1645
by (ALLGOALS(Asm_full_simp_tac));
paulson@10751
  1646
by (asm_full_simp_tac (simpset() addsimps [isCont_iff,LIM_def]) 1);
paulson@10751
  1647
by (rtac ccontr 1);
paulson@11383
  1648
by (subgoal_tac "a \\<le> x & x \\<le> b" 1);
paulson@10751
  1649
by (Asm_full_simp_tac 2);
paulson@12018
  1650
by (dres_inst_tac [("P", "%d. 0<d --> ?P d"),("x","1")] spec 2);
paulson@10751
  1651
by (Step_tac 2);
paulson@10751
  1652
by (Asm_full_simp_tac 2);
paulson@10751
  1653
by (Asm_full_simp_tac 2);
paulson@10751
  1654
by (REPEAT(blast_tac (claset() addIs [order_trans]) 2));
paulson@10751
  1655
by (REPEAT(dres_inst_tac [("x","x")] spec 1));
paulson@10751
  1656
by (Asm_full_simp_tac 1);
paulson@12018
  1657
by (dres_inst_tac [("P", "%r. ?P r --> (\\<exists>s. 0<s & ?Q r s)"),
paulson@10751
  1658
                   ("x","abs(y - f x)")] spec 1);
paulson@11176
  1659
by Safe_tac;
paulson@10751
  1660
by (asm_full_simp_tac (simpset() addsimps []) 1);
paulson@10751
  1661
by (dres_inst_tac [("x","s")] spec 1);
paulson@10751
  1662
by (Clarify_tac 1);
paulson@10751
  1663
by (cut_inst_tac [("R1.0","f x"),("R2.0","y")] real_linear 1);
paulson@10751
  1664
by Safe_tac;
paulson@10751
  1665
by (dres_inst_tac [("x","ba - x")] spec 1);
paulson@10751
  1666
by (ALLGOALS (asm_full_simp_tac (simpset() addsimps [abs_iff])));
paulson@10751
  1667
by (dres_inst_tac [("x","aa - x")] spec 1);
paulson@11383
  1668
by (case_tac "x \\<le> aa" 1);
paulson@10751
  1669
by (ALLGOALS Asm_full_simp_tac);
paulson@10751
  1670
by (dres_inst_tac [("z","x"),("w","aa")] real_le_anti_sym 1);
paulson@10751
  1671
by (assume_tac 1 THEN Asm_full_simp_tac 1);
paulson@10751
  1672
qed "IVT";
paulson@10751
  1673
paulson@10751
  1674
paulson@11383
  1675
Goal "[| f(b) \\<le> y & y \\<le> f(a); \
paulson@11383
  1676
\        a \\<le> b; \
paulson@11383
  1677
\        (\\<forall>x. a \\<le> x & x \\<le> b --> isCont f x) \
paulson@11383
  1678
\     |] ==> \\<exists>x. a \\<le> x & x \\<le> b & f(x) = y";
paulson@11383
  1679
by (subgoal_tac "- f a \\<le> -y & -y \\<le> - f b" 1);
paulson@11383
  1680
by (thin_tac "f b \\<le> y & y \\<le> f a" 1);
paulson@10751
  1681
by (dres_inst_tac [("f","%x. - f x")] IVT 1);
paulson@10751
  1682
by (auto_tac (claset() addIs [isCont_minus],simpset()));
paulson@10751
  1683
qed "IVT2";
paulson@10751
  1684
paulson@10751
  1685
paulson@10751
  1686
(*HOL style here: object-level formulations*)
paulson@11383
  1687
Goal "(f(a) \\<le> y & y \\<le> f(b) & a \\<le> b & \
paulson@11383
  1688
\     (\\<forall>x. a \\<le> x & x \\<le> b --> isCont f x)) \
paulson@11383
  1689
\     --> (\\<exists>x. a \\<le> x & x \\<le> b & f(x) = y)";
paulson@10751
  1690
by (blast_tac (claset() addIs [IVT]) 1);
paulson@10751
  1691
qed "IVT_objl";
paulson@10751
  1692
paulson@11383
  1693
Goal "(f(b) \\<le> y & y \\<le> f(a) & a \\<le> b & \
paulson@11383
  1694
\     (\\<forall>x. a \\<le> x & x \\<le> b --> isCont f x)) \
paulson@11383
  1695
\     --> (\\<exists>x. a \\<le> x & x \\<le> b & f(x) = y)";
paulson@10751
  1696
by (blast_tac (claset() addIs [IVT2]) 1);
paulson@10751
  1697
qed "IVT2_objl";
paulson@10751
  1698
paulson@10751
  1699
(*---------------------------------------------------------------------------*)
paulson@10751
  1700
(* By bisection, function continuous on closed interval is bounded above     *)
paulson@10751
  1701
(*---------------------------------------------------------------------------*)
paulson@10751
  1702
paulson@10919
  1703
Goal "abs (real x) = real (x::nat)";
paulson@10919
  1704
by (auto_tac (claset() addIs [abs_eqI1], simpset()));
paulson@10751
  1705
qed "abs_real_of_nat_cancel";
paulson@10751
  1706
Addsimps [abs_real_of_nat_cancel];
paulson@10751
  1707
wenzelm@11713
  1708
Goal "~ abs(x) + (1::real) < x";
paulson@10751
  1709
by (rtac real_leD 1);
paulson@10751
  1710
by (auto_tac (claset() addIs [abs_ge_self RS order_trans],simpset()));
paulson@10751
  1711
qed "abs_add_one_not_less_self";
paulson@10751
  1712
Addsimps [abs_add_one_not_less_self];
paulson@10751
  1713
paulson@10751
  1714
paulson@11383
  1715
Goal "[| a \\<le> b; \\<forall>x. a \\<le> x & x \\<le> b --> isCont f x |]\
paulson@11383
  1716
\     ==> \\<exists>M. \\<forall>x. a \\<le> x & x \\<le> b --> f(x) \\<le> M";
paulson@11383
  1717
by (cut_inst_tac [("P","%(u,v). a \\<le> u & u \\<le> v & v \\<le> b --> \
paulson@11383
  1718
\                         (\\<exists>M. \\<forall>x. u \\<le> x & x \\<le> v --> f x \\<le> M)")] 
paulson@10751
  1719
    lemma_BOLZANO2 1);
paulson@11176
  1720
by Safe_tac;
paulson@11176
  1721
by (ALLGOALS Asm_full_simp_tac);
paulson@11176
  1722
by (rename_tac "x xa ya M Ma" 1);
paulson@11176
  1723
by (cut_inst_tac [("x","M"),("y","Ma")] linorder_linear 1);
paulson@11176
  1724
by Safe_tac;
paulson@10751
  1725
by (res_inst_tac [("x","Ma")] exI 1);
paulson@11176
  1726
by (Clarify_tac 1); 
paulson@11176
  1727
by (cut_inst_tac [("x","xb"),("y","xa")] linorder_linear 1);
paulson@11176
  1728
by (Force_tac 1); 
paulson@10751
  1729
by (res_inst_tac [("x","M")] exI 1);
paulson@11176
  1730
by (Clarify_tac 1); 
paulson@11176
  1731
by (cut_inst_tac [("x","xb"),("y","xa")] linorder_linear 1);
paulson@11176
  1732
by (Force_tac 1); 
paulson@11383
  1733
by (case_tac "a \\<le> x & x \\<le> b" 1);
paulson@12018
  1734
by (res_inst_tac [("x","1")] exI 2);
paulson@11176
  1735
by (Force_tac 2); 
paulson@11176
  1736
by (asm_full_simp_tac (simpset() addsimps [LIM_def,isCont_iff]) 1);
paulson@10751
  1737
by (dres_inst_tac [("x","x")] spec 1 THEN Auto_tac);
paulson@11383
  1738
by (thin_tac "\\<forall>M. \\<exists>x. a \\<le> x & x \\<le> b & ~ f x \\<le> M" 1);
paulson@12018
  1739
by (dres_inst_tac [("x","1")] spec 1);
paulson@10751
  1740
by Auto_tac;  
paulson@11176
  1741
by (res_inst_tac [("x","s")] exI 1 THEN Clarify_tac 1);
paulson@12018
  1742
by (res_inst_tac [("x","abs(f x) + 1")] exI 1 THEN Clarify_tac 1);
paulson@11176
  1743
by (dres_inst_tac [("x","xa - x")] spec 1 THEN Safe_tac);
paulson@11176
  1744
by (arith_tac 1);
paulson@11176
  1745
by (arith_tac 1);
paulson@11176
  1746
by (asm_full_simp_tac (simpset() addsimps [abs_ge_self]) 1); 
paulson@11176
  1747
by (arith_tac 1);
paulson@10751
  1748
qed "isCont_bounded";
paulson@10751
  1749
paulson@10751
  1750
(*----------------------------------------------------------------------------*)
paulson@10751
  1751
(* Refine the above to existence of least upper bound                         *)
paulson@10751
  1752
(*----------------------------------------------------------------------------*)
paulson@10751
  1753
paulson@11383
  1754
Goal "((\\<exists>x. x \\<in> S) & (\\<exists>y. isUb UNIV S (y::real))) --> \
paulson@11383
  1755
\     (\\<exists>t. isLub UNIV S t)";
paulson@10751
  1756
by (blast_tac (claset() addIs [reals_complete]) 1);
paulson@10751
  1757
qed "lemma_reals_complete";
paulson@10751
  1758
paulson@11383
  1759
Goal "[| a \\<le> b; \\<forall>x. a \\<le> x & x \\<le> b --> isCont f x |] \
paulson@11383
  1760
\        ==> \\<exists>M. (\\<forall>x. a \\<le> x & x \\<le> b --> f(x) \\<le> M) & \
paulson@11383
  1761
\                  (\\<forall>N. N < M --> (\\<exists>x. a \\<le> x & x \\<le> b & N < f(x)))";
paulson@11383
  1762
by (cut_inst_tac [("S","Collect (%y. \\<exists>x. a \\<le> x & x \\<le> b & y = f x)")]
paulson@10751
  1763
    lemma_reals_complete 1);
paulson@10751
  1764
by Auto_tac;
paulson@10751
  1765
by (dtac isCont_bounded 1 THEN assume_tac 1);
paulson@10751
  1766
by (auto_tac (claset(),simpset() addsimps [isUb_def,leastP_def,
paulson@10751
  1767
    isLub_def,setge_def,setle_def]));
paulson@10751
  1768
by (rtac exI 1 THEN Auto_tac);
paulson@10751
  1769
by (REPEAT(dtac spec 1) THEN Auto_tac);
paulson@10751
  1770
by (dres_inst_tac [("x","x")] spec 1);
paulson@10751
  1771
by (auto_tac (claset() addSIs [real_leI],simpset()));
paulson@10751
  1772
qed "isCont_has_Ub";
paulson@10751
  1773
paulson@10751
  1774
(*----------------------------------------------------------------------------*)
paulson@10751
  1775
(* Now show that it attains its upper bound                                   *)
paulson@10751
  1776
(*----------------------------------------------------------------------------*)
paulson@10751
  1777
paulson@11383
  1778
Goal "[| a \\<le> b; \\<forall>x. a \\<le> x & x \\<le> b --> isCont f x |] \
paulson@11383
  1779
\        ==> \\<exists>M. (\\<forall>x. a \\<le> x & x \\<le> b --> f(x) \\<le> M) & \
paulson@11383
  1780
\                  (\\<exists>x. a \\<le> x & x \\<le> b & f(x) = M)";
paulson@10751
  1781
by (ftac isCont_has_Ub 1 THEN assume_tac 1);
paulson@10751
  1782
by (Clarify_tac 1);
paulson@10751
  1783
by (res_inst_tac [("x","M")] exI 1);
paulson@10751
  1784
by (Asm_full_simp_tac 1); 
paulson@10751
  1785
by (rtac ccontr 1);
paulson@11383
  1786
by (subgoal_tac "\\<forall>x. a \\<le> x & x \\<le> b --> f x < M" 1 THEN Step_tac 1);
paulson@10751
  1787
by (rtac ccontr 2 THEN dtac real_leI 2);
paulson@10751
  1788
by (dres_inst_tac [("z","M")] real_le_anti_sym 2);
paulson@10751
  1789
by (REPEAT(Blast_tac 2));
paulson@11383
  1790
by (subgoal_tac "\\<forall>x. a \\<le> x & x \\<le> b --> isCont (%x. inverse(M - f x)) x" 1);
paulson@11176
  1791
by Safe_tac;
paulson@10751
  1792
by (EVERY[rtac isCont_inverse 2, rtac isCont_diff 2, rtac notI 4]);
paulson@10751
  1793
by (ALLGOALS(asm_full_simp_tac (simpset() addsimps [real_diff_eq_eq])));
paulson@10751
  1794
by (Blast_tac 2);
paulson@10751
  1795
by (subgoal_tac 
paulson@11383
  1796
    "\\<exists>k. \\<forall>x. a \\<le> x & x \\<le> b --> (%x. inverse(M - (f x))) x \\<le> k" 1);
paulson@10751
  1797
by (rtac isCont_bounded 2);
paulson@11176
  1798
by Safe_tac;
paulson@12018
  1799
by (subgoal_tac "\\<forall>x. a \\<le> x & x \\<le> b --> 0 < inverse(M - f(x))" 1);
paulson@10751
  1800
by (Asm_full_simp_tac 1); 
paulson@11176
  1801
by Safe_tac;
paulson@10751
  1802
by (asm_full_simp_tac (simpset() addsimps [real_less_diff_eq]) 2);
paulson@10751
  1803
by (subgoal_tac 
paulson@12018
  1804
    "\\<forall>x. a \\<le> x & x \\<le> b --> (%x. inverse(M - (f x))) x < (k + 1)" 1);
paulson@11176
  1805
by Safe_tac;
paulson@10751
  1806
by (res_inst_tac [("y","k")] order_le_less_trans 2);
paulson@10751
  1807
by (asm_full_simp_tac (simpset() addsimps [real_zero_less_one]) 3);
paulson@10751
  1808
by (Asm_full_simp_tac 2); 
paulson@11383
  1809
by (subgoal_tac "\\<forall>x. a \\<le> x & x \\<le> b --> \
paulson@12018
  1810
\                inverse(k + 1) < inverse((%x. inverse(M - (f x))) x)" 1);
paulson@11176
  1811
by Safe_tac;
paulson@10751
  1812
by (rtac real_inverse_less_swap 2);
paulson@10751
  1813
by (ALLGOALS Asm_full_simp_tac);
paulson@10751
  1814
by (dres_inst_tac [("P", "%N. N<M --> ?Q N"),
paulson@12018
  1815
                   ("x","M - inverse(k + 1)")] spec 1);
paulson@10751
  1816
by (Step_tac 1 THEN dtac real_leI 1);
paulson@10751
  1817
by (dtac (real_le_diff_eq RS iffD1) 1);
paulson@10751
  1818
by (REPEAT(dres_inst_tac [("x","a")] spec 1));
paulson@10751
  1819
by (Asm_full_simp_tac 1);
paulson@10751
  1820
by (asm_full_simp_tac 
paulson@10751
  1821
    (simpset() addsimps [real_inverse_eq_divide, pos_real_divide_le_eq]) 1); 
paulson@10751
  1822
by (cut_inst_tac [("x","k"),("y","M-f a")] real_0_less_mult_iff 1);
paulson@10751
  1823
by (Asm_full_simp_tac 1); 
paulson@10751
  1824
(*last one*)
paulson@10751
  1825
by (REPEAT(dres_inst_tac [("x","x")] spec 1));
paulson@10751
  1826
by (Asm_full_simp_tac 1); 
paulson@10751
  1827
qed "isCont_eq_Ub";
paulson@10751
  1828
paulson@10751
  1829
paulson@10751
  1830
(*----------------------------------------------------------------------------*)
paulson@10751
  1831
(* Same theorem for lower bound                                               *)
paulson@10751
  1832
(*----------------------------------------------------------------------------*)
paulson@10751
  1833
paulson@11383
  1834
Goal "[| a \\<le> b; \\<forall>x. a \\<le> x & x \\<le> b --> isCont f x |] \
paulson@11383
  1835
\        ==> \\<exists>M. (\\<forall>x. a \\<le> x & x \\<le> b --> M \\<le> f(x)) & \
paulson@11383
  1836
\                  (\\<exists>x. a \\<le> x & x \\<le> b & f(x) = M)";
paulson@11383
  1837
by (subgoal_tac "\\<forall>x. a \\<le> x & x \\<le> b --> isCont (%x. -(f x)) x" 1);
paulson@10751
  1838
by (blast_tac (claset() addIs [isCont_minus]) 2);
paulson@10751
  1839
by (dres_inst_tac [("f","(%x. -(f x))")] isCont_eq_Ub 1);
paulson@11176
  1840
by Safe_tac;
paulson@10751
  1841
by Auto_tac;
paulson@10751
  1842
qed "isCont_eq_Lb";
paulson@10751
  1843
paulson@10751
  1844
paulson@10751
  1845
(* ------------------------------------------------------------------------- *)
paulson@10751
  1846
(* Another version.                                                          *)
paulson@10751
  1847
(* ------------------------------------------------------------------------- *)
paulson@10751
  1848
paulson@11383
  1849
Goal "[|a \\<le> b; \\<forall>x. a \\<le> x & x \\<le> b --> isCont f x |] \
paulson@11383
  1850
\     ==> \\<exists>L M. (\\<forall>x. a \\<le> x & x \\<le> b --> L \\<le> f(x) & f(x) \\<le> M) & \
paulson@11383
  1851
\         (\\<forall>y. L \\<le> y & y \\<le> M --> (\\<exists>x. a \\<le> x & x \\<le> b & (f(x) = y)))";
paulson@10751
  1852
by (ftac isCont_eq_Lb 1);
paulson@10751
  1853
by (ftac isCont_eq_Ub 2);
paulson@10751
  1854
by (REPEAT(assume_tac 1));
paulson@11176
  1855
by Safe_tac;
paulson@10751
  1856
by (res_inst_tac [("x","f x")] exI 1);
paulson@10751
  1857
by (res_inst_tac [("x","f xa")] exI 1);
paulson@10751
  1858
by (Asm_full_simp_tac 1);
paulson@11176
  1859
by Safe_tac;
paulson@11176
  1860
by (cut_inst_tac [("x","x"),("y","xa")] linorder_linear 1);
paulson@11176
  1861
by Safe_tac;
paulson@10751
  1862
by (cut_inst_tac [("f","f"),("a","x"),("b","xa"),("y","y")] IVT_objl 1);
paulson@10751
  1863
by (cut_inst_tac [("f","f"),("a","xa"),("b","x"),("y","y")] IVT2_objl 2);
paulson@11176
  1864
by Safe_tac;
paulson@10751
  1865
by (res_inst_tac [("x","xb")] exI 2);
paulson@10751
  1866
by (res_inst_tac [("x","xb")] exI 4);
paulson@10751
  1867
by (ALLGOALS(Asm_full_simp_tac));
paulson@10751
  1868
qed "isCont_Lb_Ub";
paulson@10751
  1869
paulson@10751
  1870
(*----------------------------------------------------------------------------*)
paulson@10751
  1871
(* If f'(x) > 0 then x is locally strictly increasing at the right            *)
paulson@10751
  1872
(*----------------------------------------------------------------------------*)
paulson@10751
  1873
paulson@10751
  1874
Goalw [deriv_def,LIM_def] 
paulson@12018
  1875
    "[| DERIV f x :> l;  0 < l |] \
paulson@12018
  1876
\    ==> \\<exists>d. 0 < d & (\\<forall>h. 0 < h & h < d --> f(x) < f(x + h))";
paulson@10751
  1877
by (dtac spec 1 THEN Auto_tac);
paulson@10751
  1878
by (res_inst_tac [("x","s")] exI 1 THEN Auto_tac);
paulson@12018
  1879
by (subgoal_tac "0 < l*h" 1);
paulson@10751
  1880
by (asm_full_simp_tac (simpset() addsimps [real_0_less_mult_iff]) 2); 
paulson@10751
  1881
by (dres_inst_tac [("x","h")] spec 1);
paulson@10751
  1882
by (asm_full_simp_tac
paulson@10751
  1883
    (simpset() addsimps [real_abs_def, real_inverse_eq_divide, 
paulson@10751
  1884
                 pos_real_le_divide_eq, pos_real_less_divide_eq]
paulson@10751
  1885
              addsplits [split_if_asm]) 1); 
paulson@10751
  1886
qed "DERIV_left_inc";
paulson@10751
  1887
paulson@10751
  1888
Goalw [deriv_def,LIM_def] 
paulson@12018
  1889
    "[| DERIV f x :> l;  l < 0 |] ==> \
paulson@12018
  1890
\      \\<exists>d. 0 < d & (\\<forall>h. 0 < h & h < d --> f(x) < f(x - h))";
paulson@10751
  1891
by (dres_inst_tac [("x","-l")] spec 1 THEN Auto_tac);
paulson@10751
  1892
by (res_inst_tac [("x","s")] exI 1 THEN Auto_tac);
paulson@12018
  1893
by (subgoal_tac "l*h < 0" 1);
paulson@10751
  1894
by (asm_full_simp_tac (simpset() addsimps [real_mult_less_0_iff]) 2); 
paulson@10751
  1895
by (dres_inst_tac [("x","-h")] spec 1);
paulson@10751
  1896
by (asm_full_simp_tac
paulson@10751
  1897
    (simpset() addsimps [real_abs_def, real_inverse_eq_divide, 
paulson@10751
  1898
                         pos_real_less_divide_eq,
paulson@10751
  1899
                         symmetric real_diff_def]
berghofe@13601
  1900
               addsplits [split_if_asm]
berghofe@13601
  1901
               delsimprocs [fast_real_arith_simproc]) 1);
paulson@12018
  1902
by (subgoal_tac "0 < (f (x - h) - f x)/h" 1);
paulson@10751
  1903
by (arith_tac 2);
paulson@10751
  1904
by (asm_full_simp_tac
paulson@10751
  1905
    (simpset() addsimps [pos_real_less_divide_eq]) 1); 
paulson@10751
  1906
qed "DERIV_left_dec";
paulson@10751
  1907
paulson@10751
  1908
paulson@10751
  1909
Goal "[| DERIV f x :> l; \
paulson@12018
  1910
\        \\<exists>d. 0 < d & (\\<forall>y. abs(x - y) < d --> f(y) \\<le> f(x)) |] \
paulson@12018
  1911
\     ==> l = 0";
paulson@12018
  1912
by (res_inst_tac [("R1.0","l"),("R2.0","0")] real_linear_less2 1);
paulson@11176
  1913
by Safe_tac;
paulson@10751
  1914
by (dtac DERIV_left_dec 1);
paulson@10751
  1915
by (dtac DERIV_left_inc 3);
paulson@11176
  1916
by Safe_tac;
paulson@10751
  1917
by (dres_inst_tac [("d1.0","d"),("d2.0","da")] real_lbound_gt_zero 1);
paulson@10751
  1918
by (dres_inst_tac [("d1.0","d"),("d2.0","da")] real_lbound_gt_zero 3);
paulson@11176
  1919
by Safe_tac;
paulson@10751
  1920
by (dres_inst_tac [("x","x - e")] spec 1);
paulson@10751
  1921
by (dres_inst_tac [("x","x + e")] spec 2);
paulson@10751
  1922
by (auto_tac (claset(), simpset() addsimps [real_abs_def]));
paulson@10751
  1923
qed "DERIV_local_max";
paulson@10751
  1924
paulson@10751
  1925
(*----------------------------------------------------------------------------*)
paulson@10751
  1926
(* Similar theorem for a local minimum                                        *)
paulson@10751
  1927
(*----------------------------------------------------------------------------*)
paulson@10751
  1928
paulson@10751
  1929
Goal "[| DERIV f x :> l; \
paulson@12018
  1930
\        \\<exists>d::real. 0 < d & (\\<forall>y. abs(x - y) < d --> f(x) \\<le> f(y)) |] \
paulson@12018
  1931
\     ==> l = 0";
paulson@10751
  1932
by (dtac (DERIV_minus RS DERIV_local_max) 1); 
paulson@10751
  1933
by Auto_tac;  
paulson@10751
  1934
qed "DERIV_local_min";
paulson@10751
  1935
paulson@10751
  1936
(*----------------------------------------------------------------------------*)
paulson@10751
  1937
(* In particular if a function is locally flat                                *)
paulson@10751
  1938
(*----------------------------------------------------------------------------*)
paulson@10751
  1939
paulson@10751
  1940
Goal "[| DERIV f x :> l; \
paulson@12018
  1941
\        \\<exists>d. 0 < d & (\\<forall>y. abs(x - y) < d --> f(x) = f(y)) |] \
paulson@12018
  1942
\     ==> l = 0";
paulson@10751
  1943
by (auto_tac (claset() addSDs [DERIV_local_max],simpset()));
paulson@10751
  1944
qed "DERIV_local_const";
paulson@10751
  1945
paulson@10751
  1946
(*----------------------------------------------------------------------------*)
paulson@10751
  1947
(* Lemma about introducing open ball in open interval                         *)
paulson@10751
  1948
(*----------------------------------------------------------------------------*)
paulson@10751
  1949
paulson@10751
  1950
Goal "[| a < x;  x < b |] ==> \
paulson@12018
  1951
\       \\<exists>d::real. 0 < d &  (\\<forall>y. abs(x - y) < d --> a < y & y < b)";
paulson@10751
  1952
by (simp_tac (simpset() addsimps [abs_interval_iff]) 1);
paulson@11176
  1953
by (cut_inst_tac [("x","x - a"),("y","b - x")] linorder_linear 1);
paulson@11176
  1954
by Safe_tac;
paulson@10751
  1955
by (res_inst_tac [("x","x - a")] exI 1);
paulson@10751
  1956
by (res_inst_tac [("x","b - x")] exI 2);
paulson@10751
  1957
by Auto_tac;
paulson@10751
  1958
by (auto_tac (claset(),simpset() addsimps [real_less_diff_eq]));
paulson@10751
  1959
qed "lemma_interval_lt";
paulson@10751
  1960
paulson@10751
  1961
Goal "[| a < x;  x < b |] ==> \
paulson@12018
  1962
\       \\<exists>d::real. 0 < d &  (\\<forall>y. abs(x - y) < d --> a \\<le> y & y \\<le> b)";
paulson@10751
  1963
by (dtac lemma_interval_lt 1);
paulson@10751
  1964
by Auto_tac;
paulson@10751
  1965
by (auto_tac (claset() addSIs [exI] ,simpset()));
paulson@10751
  1966
qed "lemma_interval";
paulson@10751
  1967
paulson@10751
  1968
(*-----------------------------------------------------------------------
paulson@10751
  1969
            Rolle's Theorem
paulson@10751
  1970
   If f is defined and continuous on the finite closed interval [a,b]
paulson@10751
  1971
   and differentiable a least on the open interval (a,b), and f(a) = f(b),
paulson@12018
  1972
   then x0 \\<in> (a,b) such that f'(x0) = 0
paulson@10751
  1973
 ----------------------------------------------------------------------*)
paulson@10751
  1974
paulson@10751
  1975
Goal "[| a < b; f(a) = f(b); \
paulson@11383
  1976
\        \\<forall>x. a \\<le> x & x \\<le> b --> isCont f x; \
paulson@11383
  1977
\        \\<forall>x. a < x & x < b --> f differentiable x \
paulson@12018
  1978
\     |] ==> \\<exists>z. a < z & z < b & DERIV f z :> 0";
paulson@10751
  1979
by (ftac (order_less_imp_le RS isCont_eq_Ub) 1);
paulson@10751
  1980
by (EVERY1[assume_tac,Step_tac]);
paulson@10751
  1981
by (ftac (order_less_imp_le RS isCont_eq_Lb) 1);
paulson@10751
  1982
by (EVERY1[assume_tac,Step_tac]);
paulson@10751
  1983
by (case_tac "a < x & x < b" 1 THEN etac conjE 1);
paulson@10751
  1984
by (Asm_full_simp_tac 2);
paulson@10751
  1985
by (forw_inst_tac [("a","a"),("x","x")] lemma_interval 1);
paulson@10751
  1986
by (EVERY1[assume_tac,etac exE]);
paulson@10751
  1987
by (res_inst_tac [("x","x")] exI 1 THEN Asm_full_simp_tac 1);
paulson@11383
  1988
by (subgoal_tac "(\\<exists>l. DERIV f x :> l) & \
paulson@12018
  1989
\        (\\<exists>d. 0 < d & (\\<forall>y. abs(x - y) < d --> f(y) \\<le> f(x)))" 1);
paulson@10751
  1990
by (Clarify_tac 1 THEN rtac conjI 2);
paulson@10751
  1991
by (blast_tac (claset() addIs [differentiableD]) 2);
paulson@10751
  1992
by (Blast_tac 2);
paulson@10751
  1993
by (ftac DERIV_local_max 1);
paulson@10751
  1994
by (EVERY1[Blast_tac,Blast_tac]);
paulson@10751
  1995
by (case_tac "a < xa & xa < b" 1 THEN etac conjE 1);
paulson@10751
  1996
by (Asm_full_simp_tac 2);
paulson@10751
  1997
by (forw_inst_tac [("a","a"),("x","xa")] lemma_interval 1);
paulson@10751
  1998
by (EVERY1[assume_tac,etac exE]);
paulson@10751
  1999
by (res_inst_tac [("x","xa")] exI 1 THEN Asm_full_simp_tac 1);
paulson@11383
  2000
by (subgoal_tac "(\\<exists>l. DERIV f xa :> l) & \
paulson@12018
  2001
\        (\\<exists>d. 0 < d & (\\<forall>y. abs(xa - y) < d --> f(xa) \\<le> f(y)))" 1);
paulson@10751
  2002
by (Clarify_tac 1 THEN rtac conjI 2);
paulson@10751
  2003
by (blast_tac (claset() addIs [differentiableD]) 2);
paulson@10751
  2004
by (Blast_tac 2);
paulson@10751
  2005
by (ftac DERIV_local_min 1);
paulson@10751
  2006
by (EVERY1[Blast_tac,Blast_tac]);
paulson@11383
  2007
by (subgoal_tac "\\<forall>x. a \\<le> x & x \\<le> b --> f(x) = f(b)" 1);
paulson@10751
  2008
by (Clarify_tac 2);
paulson@10751
  2009
by (rtac real_le_anti_sym 2);
paulson@10751
  2010
by (subgoal_tac "f b = f x" 2);
paulson@10751
  2011
by (Asm_full_simp_tac 2);
paulson@10751
  2012
by (res_inst_tac [("x1","a"),("y1","x")] (order_le_imp_less_or_eq RS disjE) 2);
paulson@10751
  2013
by (assume_tac 2);
paulson@10751
  2014
by (dres_inst_tac [("z","x"),("w","b")] real_le_anti_sym 2);
paulson@10751
  2015
by (subgoal_tac "f b = f xa" 5);
paulson@10751
  2016
by (Asm_full_simp_tac 5);
paulson@10751
  2017
by (res_inst_tac [("x1","a"),("y1","xa")] (order_le_imp_less_or_eq RS disjE) 5);
paulson@10751
  2018
by (assume_tac 5);
paulson@10751
  2019
by (dres_inst_tac [("z","xa"),("w","b")] real_le_anti_sym 5);
paulson@10751
  2020
by (REPEAT(Asm_full_simp_tac 2));
paulson@10751
  2021
by (dtac real_dense 1 THEN etac exE 1);
berghofe@13601
  2022
by (res_inst_tac [("x","r")] exI 1 THEN Asm_simp_tac 1);
paulson@10751
  2023
by (etac conjE 1);
paulson@10751
  2024
by (forw_inst_tac [("a","a"),("x","r")] lemma_interval 1);
paulson@10751
  2025
by (EVERY1[assume_tac, etac exE]);
paulson@11383
  2026
by (subgoal_tac "(\\<exists>l. DERIV f r :> l) & \
paulson@12018
  2027
\        (\\<exists>d. 0 < d & (\\<forall>y. abs(r - y) < d --> f(r) = f(y)))" 1);
paulson@10751
  2028
by (Clarify_tac 1 THEN rtac conjI 2);
paulson@10751
  2029
by (blast_tac (claset() addIs [differentiableD]) 2);
paulson@10751
  2030
by (EVERY1[ftac DERIV_local_const, Blast_tac, Blast_tac]);
paulson@10751
  2031
by (res_inst_tac [("x","d")] exI 1);
paulson@10751
  2032
by (EVERY1[rtac conjI, Blast_tac, rtac allI, rtac impI]);
paulson@10751
  2033
by (res_inst_tac [("s","f b")] trans 1);
paulson@10751
  2034
by (blast_tac (claset() addSDs [order_less_imp_le]) 1);
paulson@10751
  2035
by (rtac sym 1 THEN Blast_tac 1);
paulson@10751
  2036
qed "Rolle";
paulson@10751
  2037
paulson@10751
  2038
(*----------------------------------------------------------------------------*)
paulson@10751
  2039
(* Mean value theorem                                                         *)
paulson@10751
  2040
(*----------------------------------------------------------------------------*)
paulson@10751
  2041
paulson@10751
  2042
Goal "f a - (f b - f a)/(b - a) * a = \
paulson@10751
  2043
\     f b - (f b - f a)/(b - a) * (b::real)";
paulson@10751
  2044
by (case_tac "a = b" 1);
paulson@10751
  2045
by (asm_full_simp_tac (simpset() addsimps [REAL_DIVIDE_ZERO]) 1); 
paulson@10751
  2046
by (res_inst_tac [("c1","b - a")] (real_mult_left_cancel RS iffD1) 1);
paulson@10751
  2047
by (arith_tac 1);
paulson@10751
  2048
by (auto_tac (claset(),
paulson@10751
  2049
              simpset() addsimps [real_diff_mult_distrib2]));
paulson@10751
  2050
by (auto_tac (claset(),
paulson@10751
  2051
           simpset() addsimps [real_diff_mult_distrib]));
paulson@10751
  2052
qed "lemma_MVT";
paulson@10751
  2053
paulson@10751
  2054
Goal "[| a < b; \
paulson@11383
  2055
\        \\<forall>x. a \\<le> x & x \\<le> b --> isCont f x; \
paulson@11383
  2056
\        \\<forall>x. a < x & x < b --> f differentiable x |] \
paulson@11383
  2057
\     ==>  \\<exists>l z. a < z & z < b & DERIV f z :> l & \
paulson@10751
  2058
\                  (f(b) - f(a) = (b - a) * l)";
paulson@10751
  2059
by (dres_inst_tac [("f","%x. f(x) - (((f(b) - f(a)) / (b - a)) * x)")]
paulson@10751
  2060
    Rolle 1);
paulson@10751
  2061
by (rtac lemma_MVT 1);
paulson@11176
  2062
by Safe_tac;
paulson@10751
  2063
by (rtac isCont_diff 1 THEN Blast_tac 1);
paulson@10751
  2064
by (rtac (isCont_const RS isCont_mult) 1);
paulson@10751
  2065
by (rtac isCont_Id 1); 
paulson@10751
  2066
by (dres_inst_tac [("P", "%x. ?Pre x --> f differentiable x"), 
paulson@10751
  2067
                   ("x","x")] spec 1);
paulson@10751
  2068
by (asm_full_simp_tac (simpset() addsimps [differentiable_def]) 1);
paulson@11176
  2069
by Safe_tac;
paulson@10751
  2070
by (res_inst_tac [("x","xa - ((f(b) - f(a)) / (b - a))")] exI 1);
paulson@10751
  2071
by (rtac DERIV_diff 1 THEN assume_tac 1);
paulson@10751
  2072
(*derivative of a linear function is the constant...*)
paulson@10751
  2073
by (subgoal_tac "(%x. (f b - f a) * x / (b - a)) = \
paulson@10751
  2074
\                op * ((f b - f a) / (b - a))" 1);
paulson@10751
  2075
by (rtac ext 2 THEN Simp_tac 2);
paulson@10751
  2076
by (Asm_full_simp_tac 1); 
paulson@10751
  2077
(*final case*)
paulson@10751
  2078
by (res_inst_tac [("x","((f(b) - f(a)) / (b - a))")] exI 1);
paulson@10751
  2079
by (res_inst_tac [("x","z")] exI 1);
paulson@11176
  2080
by Safe_tac;
paulson@10751
  2081
by (Asm_full_simp_tac 2); 
paulson@10751
  2082
by (subgoal_tac "DERIV (%x. ((f(b) - f(a)) / (b - a)) * x) z :> \
paulson@10751
  2083
\                           ((f(b) - f(a)) / (b - a))" 1);
paulson@10751
  2084
by (rtac DERIV_cmult_Id 2); 
paulson@10751
  2085
by (dtac DERIV_add 1 THEN assume_tac 1);
paulson@10751
  2086
by (asm_full_simp_tac (simpset() addsimps [real_add_assoc, real_diff_def]) 1);
paulson@10751
  2087
qed "MVT";
paulson@10751
  2088
paulson@10751
  2089
(*----------------------------------------------------------------------------*)
paulson@10751
  2090
(* Theorem that function is constant if its derivative is 0 over an interval. *)
paulson@10751
  2091
(*----------------------------------------------------------------------------*)
paulson@10751
  2092
paulson@10751
  2093
Goal "[| a < b; \
paulson@11383
  2094
\        \\<forall>x. a \\<le> x & x \\<le> b --> isCont f x; \
paulson@12018
  2095
\        \\<forall>x. a < x & x < b --> DERIV f x :> 0 |] \
paulson@10751
  2096
\       ==> (f b = f a)";
paulson@10751
  2097
by (dtac MVT 1 THEN assume_tac 1);
paulson@10751
  2098
by (blast_tac (claset() addIs [differentiableI]) 1);
paulson@10751
  2099
by (auto_tac (claset() addSDs [DERIV_unique],simpset() 
paulson@10751
  2100
    addsimps [real_diff_eq_eq]));
paulson@10751
  2101
qed "DERIV_isconst_end";
paulson@10751
  2102
paulson@10751
  2103
Goal "[| a < b; \
paulson@11383
  2104
\        \\<forall>x. a \\<le> x & x \\<le> b --> isCont f x; \
paulson@12018
  2105
\        \\<forall>x. a < x & x < b --> DERIV f x :> 0 |] \
paulson@11383
  2106
\       ==> \\<forall>x. a \\<le> x & x \\<le> b --> f x = f a";
paulson@11176
  2107
by Safe_tac;
paulson@10751
  2108
by (dres_inst_tac [("x","a")] order_le_imp_less_or_eq 1);
paulson@11176
  2109
by Safe_tac;
paulson@10751
  2110
by (dres_inst_tac [("b","x")] DERIV_isconst_end 1);
paulson@10751
  2111
by Auto_tac;
paulson@10751
  2112
qed "DERIV_isconst1";
paulson@10751
  2113
paulson@10751
  2114
Goal "[| a < b; \
paulson@11383
  2115
\        \\<forall>x. a \\<le> x & x \\<le> b --> isCont f x; \
paulson@12018
  2116
\        \\<forall>x. a < x & x < b --> DERIV f x :> 0; \
paulson@11383
  2117
\        a \\<le> x; x \\<le> b |] \
paulson@10751
  2118
\       ==> f x = f a";
paulson@10751
  2119
by (blast_tac (claset() addDs [DERIV_isconst1]) 1);
paulson@10751
  2120
qed "DERIV_isconst2";
paulson@10751
  2121
paulson@12018
  2122
Goal "\\<forall>x. DERIV f x :> 0 ==> f(x) = f(y)";
paulson@10751
  2123
by (res_inst_tac [("R1.0","x"),("R2.0","y")] real_linear_less2 1);
paulson@10751
  2124
by (rtac sym 1);
paulson@10751
  2125
by (auto_tac (claset() addIs [DERIV_isCont,DERIV_isconst_end],simpset()));
paulson@10751
  2126
qed "DERIV_isconst_all";
paulson@10751
  2127
paulson@11383
  2128
Goal "[|a \\<noteq> b; \\<forall>x. DERIV f x :> k |] ==> (f(b) - f(a)) = (b - a) * k";
paulson@10751
  2129
by (res_inst_tac [("R1.0","a"),("R2.0","b")] real_linear_less2 1);
paulson@10751
  2130
by Auto_tac;
paulson@10751
  2131
by (ALLGOALS(dres_inst_tac [("f","f")] MVT));
paulson@10751
  2132
by (auto_tac (claset() addDs [DERIV_isCont,DERIV_unique],simpset() addsimps 
paulson@10751
  2133
    [differentiable_def]));
paulson@10751
  2134
by (auto_tac (claset() addDs [DERIV_unique],
nipkow@12481
  2135
       simpset() addsimps [real_add_mult_distrib, real_diff_def]));
paulson@10751
  2136
qed "DERIV_const_ratio_const";
paulson@10751
  2137
paulson@11383
  2138
Goal "[|a \\<noteq> b; \\<forall>x. DERIV f x :> k |] ==> (f(b) - f(a))/(b - a) = k";
paulson@10751
  2139
by (res_inst_tac [("c1","b - a")] (real_mult_right_cancel RS iffD1) 1);
paulson@10751
  2140
by (auto_tac (claset() addSDs [DERIV_const_ratio_const], 
paulson@10751
  2141
              simpset() addsimps [real_mult_assoc]));
paulson@10751
  2142
qed "DERIV_const_ratio_const2";
paulson@10751
  2143
wenzelm@11704
  2144
Goal "((a + b) /2 - a) = (b - a)/(2::real)";
paulson@10751
  2145
by Auto_tac;  
paulson@10751
  2146
qed "real_average_minus_first";
paulson@10751
  2147
Addsimps [real_average_minus_first];
paulson@10751
  2148
wenzelm@11704
  2149
Goal "((b + a)/2 - a) = (b - a)/(2::real)";
paulson@10751
  2150
by Auto_tac;  
paulson@10751
  2151
qed "real_average_minus_second";
paulson@10751
  2152
Addsimps [real_average_minus_second];
paulson@10751
  2153
paulson@10751
  2154
paulson@10751
  2155
(* Gallileo's "trick": average velocity = av. of end velocities *)
paulson@11383
  2156
Goal "[|a \\<noteq> (b::real); \\<forall>x. DERIV v x :> k|] \
wenzelm@11704
  2157
\     ==> v((a + b)/2) = (v a + v b)/2";
paulson@10751
  2158
by (res_inst_tac [("R1.0","a"),("R2.0","b")] real_linear_less2 1);
berghofe@13601
  2159
by Safe_tac;
paulson@10751
  2160
by (ftac DERIV_const_ratio_const2 1 THEN assume_tac 1);
paulson@10751
  2161
by (ftac DERIV_const_ratio_const2 2 THEN assume_tac 2);
paulson@10751
  2162
by (dtac real_less_half_sum 1);
paulson@10751
  2163
by (dtac real_gt_half_sum 2); 
paulson@10751
  2164
by (ftac (real_not_refl2 RS DERIV_const_ratio_const2) 1 THEN assume_tac 1);
paulson@10751
  2165
by (dtac ((real_not_refl2 RS not_sym) RS DERIV_const_ratio_const2) 2
paulson@10751
  2166
    THEN assume_tac 2);
paulson@10751
  2167
by (ALLGOALS (dres_inst_tac [("f","%u. (b-a)*u")] arg_cong)); 
paulson@10751
  2168
by (auto_tac (claset(), simpset() addsimps [real_inverse_eq_divide])); 
paulson@10751
  2169
by (asm_full_simp_tac (simpset() addsimps [real_add_commute, eq_commute]) 1);  
paulson@10751
  2170
qed "DERIV_const_average";
paulson@10751
  2171
paulson@10751
  2172
paulson@10751
  2173
(* ------------------------------------------------------------------------ *)
paulson@10751
  2174
(* Dull lemma that an continuous injection on an interval must have a strict*)
paulson@10751
  2175
(* maximum at an end point, not in the middle.                              *)
paulson@10751
  2176
(* ------------------------------------------------------------------------ *)
paulson@10751
  2177
paulson@12018
  2178
Goal "[|0 < d; \\<forall>z. abs(z - x) \\<le> d --> g(f z) = z; \
paulson@11383
  2179
\       \\<forall>z. abs(z - x) \\<le> d --> isCont f z |]  \
paulson@11383
  2180
\     ==> ~(\\<forall>z. abs(z - x) \\<le> d --> f(z) \\<le> f(x))";
paulson@10751
  2181
by (rtac notI 1);
paulson@10751
  2182
by (rotate_tac 3 1);
paulson@10751
  2183
by (forw_inst_tac [("x","x - d")] spec 1);
paulson@10751
  2184
by (forw_inst_tac [("x","x + d")] spec 1);
paulson@11176
  2185
by Safe_tac;
paulson@10751
  2186
by (cut_inst_tac [("x","f(x - d)"),("y","f(x + d)")] 
paulson@11383
  2187
    (ARITH_PROVE "x \\<le> y | y \\<le> (x::real)") 4);
paulson@10751
  2188
by (etac disjE 4);
paulson@10751
  2189
by (REPEAT(arith_tac 1));
paulson@10751
  2190
by (cut_inst_tac [("f","f"),("a","x - d"),("b","x"),("y","f(x + d)")]
paulson@10751
  2191
    IVT_objl 1);
paulson@11176
  2192
by Safe_tac;
paulson@10751
  2193
by (arith_tac 1);
paulson@10751
  2194
by (asm_full_simp_tac (simpset() addsimps [abs_le_interval_iff]) 1);
paulson@10751
  2195
by (dres_inst_tac [("f","g")] arg_cong 1);
paulson@10751
  2196
by (rotate_tac 2 1);
paulson@10751
  2197
by (forw_inst_tac [("x","xa")] spec 1);
paulson@10751
  2198
by (dres_inst_tac [("x","x + d")] spec 1);
paulson@10751
  2199
by (asm_full_simp_tac (simpset() addsimps [abs_le_interval_iff]) 1);
paulson@10751
  2200
(* 2nd case: similar *)
paulson@10751
  2201
by (cut_inst_tac [("f","f"),("a","x"),("b","x + d"),("y","f(x - d)")]
paulson@10751
  2202
    IVT2_objl 1);
paulson@11176
  2203
by Safe_tac;
paulson@10751
  2204
by (arith_tac 1);
paulson@10751
  2205
by (asm_full_simp_tac (simpset() addsimps [abs_le_interval_iff]) 1);
paulson@10751
  2206
by (dres_inst_tac [("f","g")] arg_cong 1);
paulson@10751
  2207
by (rotate_tac 2 1);
paulson@10751
  2208
by (forw_inst_tac [("x","xa")] spec 1);
paulson@10751
  2209
by (dres_inst_tac [("x","x - d")] spec 1);
paulson@10751
  2210
by (asm_full_simp_tac (simpset() addsimps [abs_le_interval_iff]) 1);
paulson@10751
  2211
qed "lemma_isCont_inj";
paulson@10751
  2212
paulson@10751
  2213
(* ------------------------------------------------------------------------ *)
paulson@10751
  2214
(* Similar version for lower bound                                          *)
paulson@10751
  2215
(* ------------------------------------------------------------------------ *)
paulson@10751
  2216
paulson@12018
  2217
Goal "[|0 < d; \\<forall>z. abs(z - x) \\<le> d --> g(f z) = z; \
paulson@11383
  2218
\       \\<forall>z. abs(z - x) \\<le> d --> isCont f z |]  \
paulson@11383
  2219
\     ==> ~(\\<forall>z. abs(z - x) \\<le> d --> f(x) \\<le> f(z))";
paulson@10751
  2220
by (auto_tac (claset() addSDs [(asm_full_simplify (simpset()) 
paulson@10751
  2221
    (read_instantiate [("f","%x. - f x"),("g","%y. g(-y)"),("x","x"),("d","d")]
paulson@10751
  2222
     lemma_isCont_inj))],simpset() addsimps [isCont_minus]));
paulson@10751
  2223
qed "lemma_isCont_inj2";
paulson@10751
  2224
paulson@10751
  2225
(* ------------------------------------------------------------------------ *)
paulson@10751
  2226
(* Show there's an interval surrounding f(x) in f[[x - d, x + d]]           *)
paulson@10751
  2227
(* Also from John's theory                                                  *)
paulson@10751
  2228
(* ------------------------------------------------------------------------ *)
paulson@10751
  2229
paulson@12018
  2230
val lemma_le = ARITH_PROVE "0 \\<le> (d::real) ==> -d \\<le> d";
paulson@10751
  2231
paulson@10751
  2232
(* FIXME: awful proof - needs improvement *)
paulson@12018
  2233
Goal "[| 0 < d; \\<forall>z. abs(z - x) \\<le> d --> g(f z) = z; \
paulson@11383
  2234
\        \\<forall>z. abs(z - x) \\<le> d --> isCont f z |] \
paulson@12018
  2235
\      ==> \\<exists>e. 0 < e & \
paulson@11383
  2236
\                 (\\<forall>y. \
paulson@11383
  2237
\                     abs(y - f(x)) \\<le> e --> \
paulson@11383
  2238
\                     (\\<exists>z. abs(z - x) \\<le> d & (f z = y)))";
paulson@10751
  2239
by (ftac order_less_imp_le 1);
paulson@10751
  2240
by (dtac (lemma_le RS (asm_full_simplify (simpset()) (read_instantiate 
paulson@10751
  2241
    [("f","f"),("a","x - d"),("b","x + d")] isCont_Lb_Ub))) 1);
paulson@11176
  2242
by Safe_tac;
paulson@10751
  2243
by (asm_full_simp_tac (simpset() addsimps [abs_le_interval_iff]) 1);
paulson@11383
  2244
by (subgoal_tac "L \\<le> f x & f x \\<le> M" 1);
paulson@10751
  2245
by (dres_inst_tac [("P", "%v. ?P v --> ?Q v & ?R v"), ("x","x")] spec 2);
paulson@10751
  2246
by (Asm_full_simp_tac 2);
paulson@10751
  2247
by (subgoal_tac "L < f x & f x < M" 1);
paulson@11176
  2248
by Safe_tac;
paulson@12018
  2249
by (dres_inst_tac [("x","L")] (ARITH_PROVE "x < y ==> 0 < y - (x::real)") 1);
paulson@12018
  2250
by (dres_inst_tac [("x","f x")] (ARITH_PROVE "x < y ==> 0 < y - (x::real)") 1);
paulson@10751
  2251
by (dres_inst_tac [("d1.0","f x - L"),("d2.0","M - f x")] 
paulson@12018
  2252
    (real_lbound_gt_zero) 1);
paulson@11176
  2253
by Safe_tac;
paulson@10751
  2254
by (res_inst_tac [("x","e")] exI 1);
paulson@11176
  2255
by Safe_tac;
paulson@10751
  2256
by (asm_full_simp_tac (simpset() addsimps [abs_le_interval_iff]) 1);
paulson@11383
  2257
by (dres_inst_tac [("P","%v. ?PP v --> (\\<exists>xa. ?Q v xa)"),("x","y")] spec 1);
paulson@10751
  2258
by (Step_tac 1 THEN REPEAT(arith_tac 1));
paulson@10751
  2259
by (res_inst_tac [("x","xa")] exI 1);
paulson@10751
  2260
by (arith_tac 1);
paulson@11383
  2261
by (ALLGOALS(etac (ARITH_PROVE "[|x \\<le> y; x \\<noteq> y |] ==> x < (y::real)")));
paulson@10751
  2262
by (ALLGOALS(rotate_tac 3));
paulson@10751
  2263
by (dtac lemma_isCont_inj2 1);
paulson@10751
  2264
by (assume_tac 2);
paulson@10751
  2265
by (dtac lemma_isCont_inj 3);
paulson@10751
  2266
by (assume_tac 4);
paulson@10751
  2267
by (TRYALL(assume_tac));
paulson@11176
  2268
by Safe_tac;
paulson@10751
  2269
by (ALLGOALS(dres_inst_tac [("x","z")] spec));
paulson@10751
  2270
by (ALLGOALS(arith_tac));
paulson@10751
  2271
qed "isCont_inj_range";
paulson@10751
  2272
paulson@10751
  2273
paulson@10751
  2274
(* ------------------------------------------------------------------------ *)
paulson@10751
  2275
(* Continuity of inverse function                                           *)
paulson@10751
  2276
(* ------------------------------------------------------------------------ *)
paulson@10751
  2277
paulson@12018
  2278
Goal "[| 0 < d; \\<forall>z. abs(z - x) \\<le> d --> g(f(z)) = z; \
paulson@11383
  2279
\        \\<forall>z. abs(z - x) \\<le> d --> isCont f z |] \
paulson@10751
  2280
\     ==> isCont g (f x)";
paulson@10751
  2281
by (simp_tac (simpset() addsimps [isCont_iff,LIM_def]) 1);
paulson@11176
  2282
by Safe_tac;
paulson@12018
  2283
by (dres_inst_tac [("d1.0","r")] (real_lbound_gt_zero) 1);
paulson@10751
  2284
by (assume_tac 1 THEN Step_tac 1);
paulson@11383
  2285
by (subgoal_tac "\\<forall>z. abs(z - x) \\<le> e --> (g(f z) = z)" 1);
paulson@10751
  2286
by (Force_tac 2);
paulson@11383
  2287
by (subgoal_tac "\\<forall>z. abs(z - x) \\<le> e --> isCont f z" 1);
paulson@10751
  2288
by (Force_tac 2);
paulson@10751
  2289
by (dres_inst_tac [("d","e")] isCont_inj_range 1);
paulson@10751
  2290
by (assume_tac 2 THEN assume_tac 1);
paulson@11176
  2291
by Safe_tac;
paulson@10751
  2292
by (res_inst_tac [("x","ea")] exI 1);
paulson@10751
  2293
by Auto_tac;
paulson@10751
  2294
by (rotate_tac 4 1);
paulson@10751
  2295
by (dres_inst_tac [("x","f(x) + xa")] spec 1);
paulson@10751
  2296
by Auto_tac;
paulson@10751
  2297
by (dtac sym 1 THEN Auto_tac);
paulson@10751
  2298
by (arith_tac 1);
paulson@11383
  2299
qed "isCont_inverse_function";
paulson@10751
  2300