src/HOL/Deriv.thy
changeset 60758 d8d85a8172b5
parent 60177 2bfcb83531c6
child 61204 3e491e34a62e
equal deleted inserted replaced
60757:c09598a97436 60758:d8d85a8172b5
     4     Author      : Brian Huffman
     4     Author      : Brian Huffman
     5     Conversion to Isar and new proofs by Lawrence C Paulson, 2004
     5     Conversion to Isar and new proofs by Lawrence C Paulson, 2004
     6     GMVT by Benjamin Porter, 2005
     6     GMVT by Benjamin Porter, 2005
     7 *)
     7 *)
     8 
     8 
     9 section{* Differentiation *}
     9 section\<open>Differentiation\<close>
    10 
    10 
    11 theory Deriv
    11 theory Deriv
    12 imports Limits
    12 imports Limits
    13 begin
    13 begin
    14 
    14 
    15 subsection {* Frechet derivative *}
    15 subsection \<open>Frechet derivative\<close>
    16 
    16 
    17 definition
    17 definition
    18   has_derivative :: "('a::real_normed_vector \<Rightarrow> 'b::real_normed_vector) \<Rightarrow> ('a \<Rightarrow> 'b) \<Rightarrow> 'a filter \<Rightarrow>  bool"
    18   has_derivative :: "('a::real_normed_vector \<Rightarrow> 'b::real_normed_vector) \<Rightarrow> ('a \<Rightarrow> 'b) \<Rightarrow> 'a filter \<Rightarrow>  bool"
    19   (infix "(has'_derivative)" 50)
    19   (infix "(has'_derivative)" 50)
    20 where
    20 where
    21   "(f has_derivative f') F \<longleftrightarrow>
    21   "(f has_derivative f') F \<longleftrightarrow>
    22     (bounded_linear f' \<and>
    22     (bounded_linear f' \<and>
    23      ((\<lambda>y. ((f y - f (Lim F (\<lambda>x. x))) - f' (y - Lim F (\<lambda>x. x))) /\<^sub>R norm (y - Lim F (\<lambda>x. x))) ---> 0) F)"
    23      ((\<lambda>y. ((f y - f (Lim F (\<lambda>x. x))) - f' (y - Lim F (\<lambda>x. x))) /\<^sub>R norm (y - Lim F (\<lambda>x. x))) ---> 0) F)"
    24 
    24 
    25 text {*
    25 text \<open>
    26   Usually the filter @{term F} is @{term "at x within s"}.  @{term "(f has_derivative D)
    26   Usually the filter @{term F} is @{term "at x within s"}.  @{term "(f has_derivative D)
    27   (at x within s)"} means: @{term D} is the derivative of function @{term f} at point @{term x}
    27   (at x within s)"} means: @{term D} is the derivative of function @{term f} at point @{term x}
    28   within the set @{term s}. Where @{term s} is used to express left or right sided derivatives. In
    28   within the set @{term s}. Where @{term s} is used to express left or right sided derivatives. In
    29   most cases @{term s} is either a variable or @{term UNIV}.
    29   most cases @{term s} is either a variable or @{term UNIV}.
    30 *}
    30 \<close>
    31 
    31 
    32 lemma has_derivative_eq_rhs: "(f has_derivative f') F \<Longrightarrow> f' = g' \<Longrightarrow> (f has_derivative g') F"
    32 lemma has_derivative_eq_rhs: "(f has_derivative f') F \<Longrightarrow> f' = g' \<Longrightarrow> (f has_derivative g') F"
    33   by simp
    33   by simp
    34 
    34 
    35 definition 
    35 definition 
    49 
    49 
    50 lemma has_vector_derivative_eq_rhs: "(f has_vector_derivative X) F \<Longrightarrow> X = Y \<Longrightarrow> (f has_vector_derivative Y) F"
    50 lemma has_vector_derivative_eq_rhs: "(f has_vector_derivative X) F \<Longrightarrow> X = Y \<Longrightarrow> (f has_vector_derivative Y) F"
    51   by simp
    51   by simp
    52 
    52 
    53 named_theorems derivative_intros "structural introduction rules for derivatives"
    53 named_theorems derivative_intros "structural introduction rules for derivatives"
    54 setup {*
    54 setup \<open>
    55   let
    55   let
    56     val eq_thms = @{thms has_derivative_eq_rhs DERIV_cong has_vector_derivative_eq_rhs}
    56     val eq_thms = @{thms has_derivative_eq_rhs DERIV_cong has_vector_derivative_eq_rhs}
    57     fun eq_rule thm = get_first (try (fn eq_thm => eq_thm OF [thm])) eq_thms
    57     fun eq_rule thm = get_first (try (fn eq_thm => eq_thm OF [thm])) eq_thms
    58   in
    58   in
    59     Global_Theory.add_thms_dynamic
    59     Global_Theory.add_thms_dynamic
    60       (@{binding derivative_eq_intros},
    60       (@{binding derivative_eq_intros},
    61         fn context =>
    61         fn context =>
    62           Named_Theorems.get (Context.proof_of context) @{named_theorems derivative_intros}
    62           Named_Theorems.get (Context.proof_of context) @{named_theorems derivative_intros}
    63           |> map_filter eq_rule)
    63           |> map_filter eq_rule)
    64   end;
    64   end;
    65 *}
    65 \<close>
    66 
    66 
    67 text {*
    67 text \<open>
    68   The following syntax is only used as a legacy syntax.
    68   The following syntax is only used as a legacy syntax.
    69 *}
    69 \<close>
    70 abbreviation (input)
    70 abbreviation (input)
    71   FDERIV :: "('a::real_normed_vector \<Rightarrow> 'b::real_normed_vector) \<Rightarrow> 'a \<Rightarrow>  ('a \<Rightarrow> 'b) \<Rightarrow> bool"
    71   FDERIV :: "('a::real_normed_vector \<Rightarrow> 'b::real_normed_vector) \<Rightarrow> 'a \<Rightarrow>  ('a \<Rightarrow> 'b) \<Rightarrow> bool"
    72   ("(FDERIV (_)/ (_)/ :> (_))" [1000, 1000, 60] 60)
    72   ("(FDERIV (_)/ (_)/ :> (_))" [1000, 1000, 60] 60)
    73 where
    73 where
    74   "FDERIV f x :> f' \<equiv> (f has_derivative f') (at x)"
    74   "FDERIV f x :> f' \<equiv> (f has_derivative f') (at x)"
   187   by (auto simp add: has_derivative_iff_norm intro: tendsto_within_subset)
   187   by (auto simp add: has_derivative_iff_norm intro: tendsto_within_subset)
   188 
   188 
   189 lemmas has_derivative_within_subset = has_derivative_subset 
   189 lemmas has_derivative_within_subset = has_derivative_subset 
   190 
   190 
   191 
   191 
   192 subsection {* Continuity *}
   192 subsection \<open>Continuity\<close>
   193 
   193 
   194 lemma has_derivative_continuous:
   194 lemma has_derivative_continuous:
   195   assumes f: "(f has_derivative f') (at x within s)"
   195   assumes f: "(f has_derivative f') (at x within s)"
   196   shows "continuous (at x within s) f"
   196   shows "continuous (at x within s) f"
   197 proof -
   197 proof -
   212     by simp
   212     by simp
   213   from tendsto_add[OF this tendsto_const, of "f x"] show ?thesis
   213   from tendsto_add[OF this tendsto_const, of "f x"] show ?thesis
   214     by (simp add: continuous_within)
   214     by (simp add: continuous_within)
   215 qed
   215 qed
   216 
   216 
   217 subsection {* Composition *}
   217 subsection \<open>Composition\<close>
   218 
   218 
   219 lemma tendsto_at_iff_tendsto_nhds_within: "f x = y \<Longrightarrow> (f ---> y) (at x within s) \<longleftrightarrow> (f ---> y) (inf (nhds x) (principal s))"
   219 lemma tendsto_at_iff_tendsto_nhds_within: "f x = y \<Longrightarrow> (f ---> y) (at x within s) \<longleftrightarrow> (f ---> y) (inf (nhds x) (principal s))"
   220   unfolding tendsto_def eventually_inf_principal eventually_at_filter
   220   unfolding tendsto_def eventually_inf_principal eventually_at_filter
   221   by (intro ext all_cong imp_cong) (auto elim!: eventually_elim1)
   221   by (intro ext all_cong imp_cong) (auto elim!: eventually_elim1)
   222 
   222 
   388 next
   388 next
   389   fix y::'a assume h: "y \<noteq> x" "dist y x < norm x"
   389   fix y::'a assume h: "y \<noteq> x" "dist y x < norm x"
   390   then have "y \<noteq> 0"
   390   then have "y \<noteq> 0"
   391     by (auto simp: norm_conv_dist dist_commute)
   391     by (auto simp: norm_conv_dist dist_commute)
   392   have "norm (?inv y - ?inv x - ?f (y -x)) / norm (y - x) = norm ((?inv y - ?inv x) * (y - x) * ?inv x) / norm (y - x)"
   392   have "norm (?inv y - ?inv x - ?f (y -x)) / norm (y - x) = norm ((?inv y - ?inv x) * (y - x) * ?inv x) / norm (y - x)"
   393     apply (subst inverse_diff_inverse [OF `y \<noteq> 0` x])
   393     apply (subst inverse_diff_inverse [OF \<open>y \<noteq> 0\<close> x])
   394     apply (subst minus_diff_minus)
   394     apply (subst minus_diff_minus)
   395     apply (subst norm_minus_cancel)
   395     apply (subst norm_minus_cancel)
   396     apply (simp add: left_diff_distrib)
   396     apply (simp add: left_diff_distrib)
   397     done
   397     done
   398   also have "\<dots> \<le> norm (?inv y - ?inv x) * norm (y - x) * norm (?inv x) / norm (y - x)"
   398   also have "\<dots> \<le> norm (?inv y - ?inv x) * norm (y - x) * norm (?inv x) / norm (y - x)"
   420   shows "((\<lambda>x. f x / g x) has_derivative
   420   shows "((\<lambda>x. f x / g x) has_derivative
   421                 (\<lambda>h. - f x * (inverse (g x) * g' h * inverse (g x)) + f' h / g x)) (at x within s)"
   421                 (\<lambda>h. - f x * (inverse (g x) * g' h * inverse (g x)) + f' h / g x)) (at x within s)"
   422   using has_derivative_mult[OF f has_derivative_inverse[OF x g]]
   422   using has_derivative_mult[OF f has_derivative_inverse[OF x g]]
   423   by (simp add: field_simps)
   423   by (simp add: field_simps)
   424 
   424 
   425 text{*Conventional form requires mult-AC laws. Types real and complex only.*}
   425 text\<open>Conventional form requires mult-AC laws. Types real and complex only.\<close>
   426 
   426 
   427 lemma has_derivative_divide'[derivative_intros]: 
   427 lemma has_derivative_divide'[derivative_intros]: 
   428   fixes f :: "_ \<Rightarrow> 'a::real_normed_field"
   428   fixes f :: "_ \<Rightarrow> 'a::real_normed_field"
   429   assumes f: "(f has_derivative f') (at x within s)" and g: "(g has_derivative g') (at x within s)" and x: "g x \<noteq> 0"
   429   assumes f: "(f has_derivative f') (at x within s)" and g: "(g has_derivative g') (at x within s)" and x: "g x \<noteq> 0"
   430   shows "((\<lambda>x. f x / g x) has_derivative (\<lambda>h. (f' h * g x - f x * g' h) / (g x * g x))) (at x within s)"
   430   shows "((\<lambda>x. f x / g x) has_derivative (\<lambda>h. (f' h * g x - f x * g' h) / (g x * g x))) (at x within s)"
   437   then show ?thesis
   437   then show ?thesis
   438     using has_derivative_divide [OF f g] x
   438     using has_derivative_divide [OF f g] x
   439     by simp
   439     by simp
   440 qed
   440 qed
   441 
   441 
   442 subsection {* Uniqueness *}
   442 subsection \<open>Uniqueness\<close>
   443 
   443 
   444 text {*
   444 text \<open>
   445 
   445 
   446 This can not generally shown for @{const has_derivative}, as we need to approach the point from
   446 This can not generally shown for @{const has_derivative}, as we need to approach the point from
   447 all directions. There is a proof in @{text Multivariate_Analysis} for @{text euclidean_space}.
   447 all directions. There is a proof in @{text Multivariate_Analysis} for @{text euclidean_space}.
   448 
   448 
   449 *}
   449 \<close>
   450 
   450 
   451 lemma has_derivative_zero_unique:
   451 lemma has_derivative_zero_unique:
   452   assumes "((\<lambda>x. 0) has_derivative F) (at x)" shows "F = (\<lambda>h. 0)"
   452   assumes "((\<lambda>x. 0) has_derivative F) (at x)" shows "F = (\<lambda>h. 0)"
   453 proof -
   453 proof -
   454   interpret F: bounded_linear F
   454   interpret F: bounded_linear F
   483     by (rule has_derivative_zero_unique)
   483     by (rule has_derivative_zero_unique)
   484   thus "F = F'"
   484   thus "F = F'"
   485     unfolding fun_eq_iff right_minus_eq .
   485     unfolding fun_eq_iff right_minus_eq .
   486 qed
   486 qed
   487 
   487 
   488 subsection {* Differentiability predicate *}
   488 subsection \<open>Differentiability predicate\<close>
   489 
   489 
   490 definition
   490 definition
   491   differentiable :: "('a::real_normed_vector \<Rightarrow> 'b::real_normed_vector) \<Rightarrow> 'a filter \<Rightarrow> bool"
   491   differentiable :: "('a::real_normed_vector \<Rightarrow> 'b::real_normed_vector) \<Rightarrow> 'a filter \<Rightarrow> bool"
   492   (infix "differentiable" 50)
   492   (infix "differentiable" 50)
   493 where
   493 where
   607   done
   607   done
   608 
   608 
   609 lemma mult_commute_abs: "(\<lambda>x. x * c) = op * (c::'a::ab_semigroup_mult)"
   609 lemma mult_commute_abs: "(\<lambda>x. x * c) = op * (c::'a::ab_semigroup_mult)"
   610   by (simp add: fun_eq_iff mult.commute)
   610   by (simp add: fun_eq_iff mult.commute)
   611 
   611 
   612 subsection {* Vector derivative *}
   612 subsection \<open>Vector derivative\<close>
   613 
   613 
   614 lemma has_field_derivative_iff_has_vector_derivative:
   614 lemma has_field_derivative_iff_has_vector_derivative:
   615   "(f has_field_derivative y) F \<longleftrightarrow> (f has_vector_derivative y) F"
   615   "(f has_field_derivative y) F \<longleftrightarrow> (f has_vector_derivative y) F"
   616   unfolding has_vector_derivative_def has_field_derivative_def real_scaleR_def mult_commute_abs ..
   616   unfolding has_vector_derivative_def has_field_derivative_def real_scaleR_def mult_commute_abs ..
   617 
   617 
   685   fixes a :: "'a :: real_normed_algebra"
   685   fixes a :: "'a :: real_normed_algebra"
   686   shows "(f has_vector_derivative x) F \<Longrightarrow> ((\<lambda>x. f x * a) has_vector_derivative (x * a)) F"
   686   shows "(f has_vector_derivative x) F \<Longrightarrow> ((\<lambda>x. f x * a) has_vector_derivative (x * a)) F"
   687   by (rule bounded_linear.has_vector_derivative[OF bounded_linear_mult_left])
   687   by (rule bounded_linear.has_vector_derivative[OF bounded_linear_mult_left])
   688 
   688 
   689 
   689 
   690 subsection {* Derivatives *}
   690 subsection \<open>Derivatives\<close>
   691 
   691 
   692 lemma DERIV_D: "DERIV f x :> D \<Longrightarrow> (\<lambda>h. (f (x + h) - f x) / h) -- 0 --> D"
   692 lemma DERIV_D: "DERIV f x :> D \<Longrightarrow> (\<lambda>h. (f (x + h) - f x) / h) -- 0 --> D"
   693   by (simp add: DERIV_def)
   693   by (simp add: DERIV_def)
   694 
   694 
   695 lemma DERIV_const [simp, derivative_intros]: "((\<lambda>x. k) has_field_derivative 0) F"
   695 lemma DERIV_const [simp, derivative_intros]: "((\<lambda>x. k) has_field_derivative 0) F"
   746   "(f has_field_derivative Da) (at x within s) \<Longrightarrow> (g has_field_derivative Db) (at x within s) \<Longrightarrow>
   746   "(f has_field_derivative Da) (at x within s) \<Longrightarrow> (g has_field_derivative Db) (at x within s) \<Longrightarrow>
   747   ((\<lambda>x. f x * g x) has_field_derivative Da * g x + Db * f x) (at x within s)"
   747   ((\<lambda>x. f x * g x) has_field_derivative Da * g x + Db * f x) (at x within s)"
   748   by (rule has_derivative_imp_has_field_derivative[OF has_derivative_mult])
   748   by (rule has_derivative_imp_has_field_derivative[OF has_derivative_mult])
   749      (auto simp: field_simps dest: has_field_derivative_imp_has_derivative)
   749      (auto simp: field_simps dest: has_field_derivative_imp_has_derivative)
   750 
   750 
   751 text {* Derivative of linear multiplication *}
   751 text \<open>Derivative of linear multiplication\<close>
   752 
   752 
   753 lemma DERIV_cmult:
   753 lemma DERIV_cmult:
   754   "(f has_field_derivative D) (at x within s) ==> ((\<lambda>x. c * f x) has_field_derivative c * D) (at x within s)"
   754   "(f has_field_derivative D) (at x within s) ==> ((\<lambda>x. c * f x) has_field_derivative c * D) (at x within s)"
   755   by (drule DERIV_mult' [OF DERIV_const], simp)
   755   by (drule DERIV_mult' [OF DERIV_const], simp)
   756 
   756 
   782 proof -
   782 proof -
   783   have "(f has_derivative (\<lambda>x. x * D)) = (f has_derivative op * D)"
   783   have "(f has_derivative (\<lambda>x. x * D)) = (f has_derivative op * D)"
   784     by (rule arg_cong [of "\<lambda>x. x * D"]) (simp add: fun_eq_iff)
   784     by (rule arg_cong [of "\<lambda>x. x * D"]) (simp add: fun_eq_iff)
   785   with assms have "(f has_derivative (\<lambda>x. x * D)) (at x within s)"
   785   with assms have "(f has_derivative (\<lambda>x. x * D)) (at x within s)"
   786     by (auto dest!: has_field_derivative_imp_has_derivative)
   786     by (auto dest!: has_field_derivative_imp_has_derivative)
   787   then show ?thesis using `f x \<noteq> 0`
   787   then show ?thesis using \<open>f x \<noteq> 0\<close>
   788     by (auto intro: has_derivative_imp_has_field_derivative has_derivative_inverse)
   788     by (auto intro: has_derivative_imp_has_field_derivative has_derivative_inverse)
   789 qed
   789 qed
   790 
   790 
   791 text {* Power of @{text "-1"} *}
   791 text \<open>Power of @{text "-1"}\<close>
   792 
   792 
   793 lemma DERIV_inverse:
   793 lemma DERIV_inverse:
   794   "x \<noteq> 0 \<Longrightarrow> ((\<lambda>x. inverse(x)) has_field_derivative - (inverse x ^ Suc (Suc 0))) (at x within s)"
   794   "x \<noteq> 0 \<Longrightarrow> ((\<lambda>x. inverse(x)) has_field_derivative - (inverse x ^ Suc (Suc 0))) (at x within s)"
   795   by (drule DERIV_inverse' [OF DERIV_ident]) simp
   795   by (drule DERIV_inverse' [OF DERIV_ident]) simp
   796 
   796 
   797 text {* Derivative of inverse *}
   797 text \<open>Derivative of inverse\<close>
   798 
   798 
   799 lemma DERIV_inverse_fun:
   799 lemma DERIV_inverse_fun:
   800   "(f has_field_derivative d) (at x within s) \<Longrightarrow> f x \<noteq> 0 \<Longrightarrow>
   800   "(f has_field_derivative d) (at x within s) \<Longrightarrow> f x \<noteq> 0 \<Longrightarrow>
   801   ((\<lambda>x. inverse (f x)) has_field_derivative (- (d * inverse(f x ^ Suc (Suc 0))))) (at x within s)"
   801   ((\<lambda>x. inverse (f x)) has_field_derivative (- (d * inverse(f x ^ Suc (Suc 0))))) (at x within s)"
   802   by (drule (1) DERIV_inverse') (simp add: ac_simps nonzero_inverse_mult_distrib)
   802   by (drule (1) DERIV_inverse') (simp add: ac_simps nonzero_inverse_mult_distrib)
   803 
   803 
   804 text {* Derivative of quotient *}
   804 text \<open>Derivative of quotient\<close>
   805 
   805 
   806 lemma DERIV_divide[derivative_intros]:
   806 lemma DERIV_divide[derivative_intros]:
   807   "(f has_field_derivative D) (at x within s) \<Longrightarrow>
   807   "(f has_field_derivative D) (at x within s) \<Longrightarrow>
   808   (g has_field_derivative E) (at x within s) \<Longrightarrow> g x \<noteq> 0 \<Longrightarrow>
   808   (g has_field_derivative E) (at x within s) \<Longrightarrow> g x \<noteq> 0 \<Longrightarrow>
   809   ((\<lambda>x. f x / g x) has_field_derivative (D * g x - f x * E) / (g x * g x)) (at x within s)"
   809   ((\<lambda>x. f x / g x) has_field_derivative (D * g x - f x * E) / (g x * g x)) (at x within s)"
   840 
   840 
   841 corollary DERIV_chain2: "DERIV f (g x) :> Da \<Longrightarrow> (g has_field_derivative Db) (at x within s) \<Longrightarrow>
   841 corollary DERIV_chain2: "DERIV f (g x) :> Da \<Longrightarrow> (g has_field_derivative Db) (at x within s) \<Longrightarrow>
   842   ((\<lambda>x. f (g x)) has_field_derivative Da * Db) (at x within s)"
   842   ((\<lambda>x. f (g x)) has_field_derivative Da * Db) (at x within s)"
   843   by (rule DERIV_chain')
   843   by (rule DERIV_chain')
   844 
   844 
   845 text {* Standard version *}
   845 text \<open>Standard version\<close>
   846 
   846 
   847 lemma DERIV_chain:
   847 lemma DERIV_chain:
   848   "DERIV f (g x) :> Da \<Longrightarrow> (g has_field_derivative Db) (at x within s) \<Longrightarrow> 
   848   "DERIV f (g x) :> Da \<Longrightarrow> (g has_field_derivative Db) (at x within s) \<Longrightarrow> 
   849   (f o g has_field_derivative Da * Db) (at x within s)"
   849   (f o g has_field_derivative Da * Db) (at x within s)"
   850   by (drule (1) DERIV_chain', simp add: o_def mult.commute)
   850   by (drule (1) DERIV_chain', simp add: o_def mult.commute)
   870   by (metis UNIV_I DERIV_chain_s [of UNIV] assms)
   870   by (metis UNIV_I DERIV_chain_s [of UNIV] assms)
   871 
   871 
   872 declare
   872 declare
   873   DERIV_power[where 'a=real, unfolded real_of_nat_def[symmetric], derivative_intros]
   873   DERIV_power[where 'a=real, unfolded real_of_nat_def[symmetric], derivative_intros]
   874 
   874 
   875 text{*Alternative definition for differentiability*}
   875 text\<open>Alternative definition for differentiability\<close>
   876 
   876 
   877 lemma DERIV_LIM_iff:
   877 lemma DERIV_LIM_iff:
   878   fixes f :: "'a::{real_normed_vector,inverse} \<Rightarrow> 'a" shows
   878   fixes f :: "'a::{real_normed_vector,inverse} \<Rightarrow> 'a" shows
   879      "((%h. (f(a + h) - f(a)) / h) -- 0 --> D) =
   879      "((%h. (f(a + h) - f(a)) / h) -- 0 --> D) =
   880       ((%x. (f(x)-f(a)) / (x-a)) -- a --> D)"
   880       ((%x. (f(x)-f(a)) / (x-a)) -- a --> D)"
   906 lemma DERIV_mirror:
   906 lemma DERIV_mirror:
   907   "(DERIV f (- x) :> y) \<longleftrightarrow> (DERIV (\<lambda>x. f (- x::real) :: real) x :> - y)"
   907   "(DERIV f (- x) :> y) \<longleftrightarrow> (DERIV (\<lambda>x. f (- x::real) :: real) x :> - y)"
   908   by (simp add: DERIV_def filterlim_at_split filterlim_at_left_to_right
   908   by (simp add: DERIV_def filterlim_at_split filterlim_at_left_to_right
   909                 tendsto_minus_cancel_left field_simps conj_commute)
   909                 tendsto_minus_cancel_left field_simps conj_commute)
   910 
   910 
   911 text {* Caratheodory formulation of derivative at a point *}
   911 text \<open>Caratheodory formulation of derivative at a point\<close>
   912 
   912 
   913 lemma CARAT_DERIV: (*FIXME: SUPERSEDED BY THE ONE IN Deriv.thy. But still used by NSA/HDeriv.thy*)
   913 lemma CARAT_DERIV: (*FIXME: SUPERSEDED BY THE ONE IN Deriv.thy. But still used by NSA/HDeriv.thy*)
   914   "(DERIV f x :> l) \<longleftrightarrow> (\<exists>g. (\<forall>z. f z - f x = g z * (z - x)) \<and> isCont g x \<and> g x = l)"
   914   "(DERIV f x :> l) \<longleftrightarrow> (\<exists>g. (\<forall>z. f z - f x = g z * (z - x)) \<and> isCont g x \<and> g x = l)"
   915       (is "?lhs = ?rhs")
   915       (is "?lhs = ?rhs")
   916 proof
   916 proof
   930   thus "(DERIV f x :> l)"
   930   thus "(DERIV f x :> l)"
   931      by (auto simp add: isCont_iff DERIV_def cong: LIM_cong)
   931      by (auto simp add: isCont_iff DERIV_def cong: LIM_cong)
   932 qed
   932 qed
   933 
   933 
   934 
   934 
   935 subsection {* Local extrema *}
   935 subsection \<open>Local extrema\<close>
   936 
   936 
   937 text{*If @{term "0 < f'(x)"} then @{term x} is Locally Strictly Increasing At The Right*}
   937 text\<open>If @{term "0 < f'(x)"} then @{term x} is Locally Strictly Increasing At The Right\<close>
   938 
   938 
   939 lemma DERIV_pos_inc_right:
   939 lemma DERIV_pos_inc_right:
   940   fixes f :: "real => real"
   940   fixes f :: "real => real"
   941   assumes der: "DERIV f x :> l"
   941   assumes der: "DERIV f x :> l"
   942       and l:   "0 < l"
   942       and l:   "0 < l"
  1035   with lt le [THEN spec [where x="x+e"]]
  1035   with lt le [THEN spec [where x="x+e"]]
  1036   show ?thesis by (auto simp add: abs_if)
  1036   show ?thesis by (auto simp add: abs_if)
  1037 qed
  1037 qed
  1038 
  1038 
  1039 
  1039 
  1040 text{*Similar theorem for a local minimum*}
  1040 text\<open>Similar theorem for a local minimum\<close>
  1041 lemma DERIV_local_min:
  1041 lemma DERIV_local_min:
  1042   fixes f :: "real => real"
  1042   fixes f :: "real => real"
  1043   shows "[| DERIV f x :> l; 0 < d; \<forall>y. \<bar>x-y\<bar> < d --> f(x) \<le> f(y) |] ==> l = 0"
  1043   shows "[| DERIV f x :> l; 0 < d; \<forall>y. \<bar>x-y\<bar> < d --> f(x) \<le> f(y) |] ==> l = 0"
  1044 by (drule DERIV_minus [THEN DERIV_local_max], auto)
  1044 by (drule DERIV_minus [THEN DERIV_local_max], auto)
  1045 
  1045 
  1046 
  1046 
  1047 text{*In particular, if a function is locally flat*}
  1047 text\<open>In particular, if a function is locally flat\<close>
  1048 lemma DERIV_local_const:
  1048 lemma DERIV_local_const:
  1049   fixes f :: "real => real"
  1049   fixes f :: "real => real"
  1050   shows "[| DERIV f x :> l; 0 < d; \<forall>y. \<bar>x-y\<bar> < d --> f(x) = f(y) |] ==> l = 0"
  1050   shows "[| DERIV f x :> l; 0 < d; \<forall>y. \<bar>x-y\<bar> < d --> f(x) = f(y) |] ==> l = 0"
  1051 by (auto dest!: DERIV_local_max)
  1051 by (auto dest!: DERIV_local_max)
  1052 
  1052 
  1053 
  1053 
  1054 subsection {* Rolle's Theorem *}
  1054 subsection \<open>Rolle's Theorem\<close>
  1055 
  1055 
  1056 text{*Lemma about introducing open ball in open interval*}
  1056 text\<open>Lemma about introducing open ball in open interval\<close>
  1057 lemma lemma_interval_lt:
  1057 lemma lemma_interval_lt:
  1058      "[| a < x;  x < b |]
  1058      "[| a < x;  x < b |]
  1059       ==> \<exists>d::real. 0 < d & (\<forall>y. \<bar>x-y\<bar> < d --> a < y & y < b)"
  1059       ==> \<exists>d::real. 0 < d & (\<forall>y. \<bar>x-y\<bar> < d --> a < y & y < b)"
  1060 
  1060 
  1061 apply (simp add: abs_less_iff)
  1061 apply (simp add: abs_less_iff)
  1068         \<exists>d::real. 0 < d &  (\<forall>y. \<bar>x-y\<bar> < d --> a \<le> y & y \<le> b)"
  1068         \<exists>d::real. 0 < d &  (\<forall>y. \<bar>x-y\<bar> < d --> a \<le> y & y \<le> b)"
  1069 apply (drule lemma_interval_lt, auto)
  1069 apply (drule lemma_interval_lt, auto)
  1070 apply force
  1070 apply force
  1071 done
  1071 done
  1072 
  1072 
  1073 text{*Rolle's Theorem.
  1073 text\<open>Rolle's Theorem.
  1074    If @{term f} is defined and continuous on the closed interval
  1074    If @{term f} is defined and continuous on the closed interval
  1075    @{text "[a,b]"} and differentiable on the open interval @{text "(a,b)"},
  1075    @{text "[a,b]"} and differentiable on the open interval @{text "(a,b)"},
  1076    and @{term "f(a) = f(b)"},
  1076    and @{term "f(a) = f(b)"},
  1077    then there exists @{text "x0 \<in> (a,b)"} such that @{term "f'(x0) = 0"}*}
  1077    then there exists @{text "x0 \<in> (a,b)"} such that @{term "f'(x0) = 0"}\<close>
  1078 theorem Rolle:
  1078 theorem Rolle:
  1079   assumes lt: "a < b"
  1079   assumes lt: "a < b"
  1080       and eq: "f(a) = f(b)"
  1080       and eq: "f(a) = f(b)"
  1081       and con: "\<forall>x. a \<le> x & x \<le> b --> isCont f x"
  1081       and con: "\<forall>x. a \<le> x & x \<le> b --> isCont f x"
  1082       and dif [rule_format]: "\<forall>x. a < x & x < b --> f differentiable (at x)"
  1082       and dif [rule_format]: "\<forall>x. a < x & x < b --> f differentiable (at x)"
  1092               and alex': "a \<le> x'" and x'leb: "x' \<le> b"
  1092               and alex': "a \<le> x'" and x'leb: "x' \<le> b"
  1093     by blast
  1093     by blast
  1094   show ?thesis
  1094   show ?thesis
  1095   proof cases
  1095   proof cases
  1096     assume axb: "a < x & x < b"
  1096     assume axb: "a < x & x < b"
  1097         --{*@{term f} attains its maximum within the interval*}
  1097         --\<open>@{term f} attains its maximum within the interval\<close>
  1098     hence ax: "a<x" and xb: "x<b" by arith + 
  1098     hence ax: "a<x" and xb: "x<b" by arith + 
  1099     from lemma_interval [OF ax xb]
  1099     from lemma_interval [OF ax xb]
  1100     obtain d where d: "0<d" and bound: "\<forall>y. \<bar>x-y\<bar> < d \<longrightarrow> a \<le> y \<and> y \<le> b"
  1100     obtain d where d: "0<d" and bound: "\<forall>y. \<bar>x-y\<bar> < d \<longrightarrow> a \<le> y \<and> y \<le> b"
  1101       by blast
  1101       by blast
  1102     hence bound': "\<forall>y. \<bar>x-y\<bar> < d \<longrightarrow> f y \<le> f x" using x_max
  1102     hence bound': "\<forall>y. \<bar>x-y\<bar> < d \<longrightarrow> f y \<le> f x" using x_max
  1103       by blast
  1103       by blast
  1104     from differentiableD [OF dif [OF axb]]
  1104     from differentiableD [OF dif [OF axb]]
  1105     obtain l where der: "DERIV f x :> l" ..
  1105     obtain l where der: "DERIV f x :> l" ..
  1106     have "l=0" by (rule DERIV_local_max [OF der d bound'])
  1106     have "l=0" by (rule DERIV_local_max [OF der d bound'])
  1107         --{*the derivative at a local maximum is zero*}
  1107         --\<open>the derivative at a local maximum is zero\<close>
  1108     thus ?thesis using ax xb der by auto
  1108     thus ?thesis using ax xb der by auto
  1109   next
  1109   next
  1110     assume notaxb: "~ (a < x & x < b)"
  1110     assume notaxb: "~ (a < x & x < b)"
  1111     hence xeqab: "x=a | x=b" using alex xleb by arith
  1111     hence xeqab: "x=a | x=b" using alex xleb by arith
  1112     hence fb_eq_fx: "f b = f x" by (auto simp add: eq)
  1112     hence fb_eq_fx: "f b = f x" by (auto simp add: eq)
  1113     show ?thesis
  1113     show ?thesis
  1114     proof cases
  1114     proof cases
  1115       assume ax'b: "a < x' & x' < b"
  1115       assume ax'b: "a < x' & x' < b"
  1116         --{*@{term f} attains its minimum within the interval*}
  1116         --\<open>@{term f} attains its minimum within the interval\<close>
  1117       hence ax': "a<x'" and x'b: "x'<b" by arith+ 
  1117       hence ax': "a<x'" and x'b: "x'<b" by arith+ 
  1118       from lemma_interval [OF ax' x'b]
  1118       from lemma_interval [OF ax' x'b]
  1119       obtain d where d: "0<d" and bound: "\<forall>y. \<bar>x'-y\<bar> < d \<longrightarrow> a \<le> y \<and> y \<le> b"
  1119       obtain d where d: "0<d" and bound: "\<forall>y. \<bar>x'-y\<bar> < d \<longrightarrow> a \<le> y \<and> y \<le> b"
  1120   by blast
  1120   by blast
  1121       hence bound': "\<forall>y. \<bar>x'-y\<bar> < d \<longrightarrow> f x' \<le> f y" using x'_min
  1121       hence bound': "\<forall>y. \<bar>x'-y\<bar> < d \<longrightarrow> f x' \<le> f y" using x'_min
  1122   by blast
  1122   by blast
  1123       from differentiableD [OF dif [OF ax'b]]
  1123       from differentiableD [OF dif [OF ax'b]]
  1124       obtain l where der: "DERIV f x' :> l" ..
  1124       obtain l where der: "DERIV f x' :> l" ..
  1125       have "l=0" by (rule DERIV_local_min [OF der d bound'])
  1125       have "l=0" by (rule DERIV_local_min [OF der d bound'])
  1126         --{*the derivative at a local minimum is zero*}
  1126         --\<open>the derivative at a local minimum is zero\<close>
  1127       thus ?thesis using ax' x'b der by auto
  1127       thus ?thesis using ax' x'b der by auto
  1128     next
  1128     next
  1129       assume notax'b: "~ (a < x' & x' < b)"
  1129       assume notax'b: "~ (a < x' & x' < b)"
  1130         --{*@{term f} is constant througout the interval*}
  1130         --\<open>@{term f} is constant througout the interval\<close>
  1131       hence x'eqab: "x'=a | x'=b" using alex' x'leb by arith
  1131       hence x'eqab: "x'=a | x'=b" using alex' x'leb by arith
  1132       hence fb_eq_fx': "f b = f x'" by (auto simp add: eq)
  1132       hence fb_eq_fx': "f b = f x'" by (auto simp add: eq)
  1133       from dense [OF lt]
  1133       from dense [OF lt]
  1134       obtain r where ar: "a < r" and rb: "r < b" by blast
  1134       obtain r where ar: "a < r" and rb: "r < b" by blast
  1135       from lemma_interval [OF ar rb]
  1135       from lemma_interval [OF ar rb]
  1153         thus "f r = f y" by (simp add: eq_fb ar rb order_less_imp_le)
  1153         thus "f r = f y" by (simp add: eq_fb ar rb order_less_imp_le)
  1154       qed
  1154       qed
  1155       from differentiableD [OF dif [OF conjI [OF ar rb]]]
  1155       from differentiableD [OF dif [OF conjI [OF ar rb]]]
  1156       obtain l where der: "DERIV f r :> l" ..
  1156       obtain l where der: "DERIV f r :> l" ..
  1157       have "l=0" by (rule DERIV_local_const [OF der d bound'])
  1157       have "l=0" by (rule DERIV_local_const [OF der d bound'])
  1158         --{*the derivative of a constant function is zero*}
  1158         --\<open>the derivative of a constant function is zero\<close>
  1159       thus ?thesis using ar rb der by auto
  1159       thus ?thesis using ar rb der by auto
  1160     qed
  1160     qed
  1161   qed
  1161   qed
  1162 qed
  1162 qed
  1163 
  1163 
  1164 
  1164 
  1165 subsection{*Mean Value Theorem*}
  1165 subsection\<open>Mean Value Theorem\<close>
  1166 
  1166 
  1167 lemma lemma_MVT:
  1167 lemma lemma_MVT:
  1168      "f a - (f b - f a)/(b-a) * a = f b - (f b - f a)/(b-a) * (b::real)"
  1168      "f a - (f b - f a)/(b-a) * a = f b - (f b - f a)/(b-a) * (b::real)"
  1169   by (cases "a = b") (simp_all add: field_simps)
  1169   by (cases "a = b") (simp_all add: field_simps)
  1170 
  1170 
  1213 apply (force dest: order_less_imp_le simp add: real_differentiable_def)
  1213 apply (force dest: order_less_imp_le simp add: real_differentiable_def)
  1214 apply (blast dest: DERIV_unique order_less_imp_le)
  1214 apply (blast dest: DERIV_unique order_less_imp_le)
  1215 done
  1215 done
  1216 
  1216 
  1217 
  1217 
  1218 text{*A function is constant if its derivative is 0 over an interval.*}
  1218 text\<open>A function is constant if its derivative is 0 over an interval.\<close>
  1219 
  1219 
  1220 lemma DERIV_isconst_end:
  1220 lemma DERIV_isconst_end:
  1221   fixes f :: "real => real"
  1221   fixes f :: "real => real"
  1222   shows "[| a < b;
  1222   shows "[| a < b;
  1223          \<forall>x. a \<le> x & x \<le> b --> isCont f x;
  1223          \<forall>x. a \<le> x & x \<le> b --> isCont f x;
  1259   let ?b = "max x y"
  1259   let ?b = "max x y"
  1260   
  1260   
  1261   have "\<forall>z. ?a \<le> z \<and> z \<le> ?b \<longrightarrow> DERIV f z :> 0"
  1261   have "\<forall>z. ?a \<le> z \<and> z \<le> ?b \<longrightarrow> DERIV f z :> 0"
  1262   proof (rule allI, rule impI)
  1262   proof (rule allI, rule impI)
  1263     fix z :: real assume "?a \<le> z \<and> z \<le> ?b"
  1263     fix z :: real assume "?a \<le> z \<and> z \<le> ?b"
  1264     hence "a < z" and "z < b" using `x \<in> {a <..< b}` and `y \<in> {a <..< b}` by auto
  1264     hence "a < z" and "z < b" using \<open>x \<in> {a <..< b}\<close> and \<open>y \<in> {a <..< b}\<close> by auto
  1265     hence "z \<in> {a<..<b}" by auto
  1265     hence "z \<in> {a<..<b}" by auto
  1266     thus "DERIV f z :> 0" by (rule derivable)
  1266     thus "DERIV f z :> 0" by (rule derivable)
  1267   qed
  1267   qed
  1268   hence isCont: "\<forall>z. ?a \<le> z \<and> z \<le> ?b \<longrightarrow> isCont f z"
  1268   hence isCont: "\<forall>z. ?a \<le> z \<and> z \<le> ?b \<longrightarrow> isCont f z"
  1269     and DERIV: "\<forall>z. ?a < z \<and> z < ?b \<longrightarrow> DERIV f z :> 0" using DERIV_isCont by auto
  1269     and DERIV: "\<forall>z. ?a < z \<and> z < ?b \<longrightarrow> DERIV f z :> 0" using DERIV_isCont by auto
  1270 
  1270 
  1271   have "?a < ?b" using `x \<noteq> y` by auto
  1271   have "?a < ?b" using \<open>x \<noteq> y\<close> by auto
  1272   from DERIV_isconst2[OF this isCont DERIV, of x] and DERIV_isconst2[OF this isCont DERIV, of y]
  1272   from DERIV_isconst2[OF this isCont DERIV, of x] and DERIV_isconst2[OF this isCont DERIV, of y]
  1273   show ?thesis by auto
  1273   show ?thesis by auto
  1274 qed auto
  1274 qed auto
  1275 
  1275 
  1276 lemma DERIV_isconst_all:
  1276 lemma DERIV_isconst_all:
  1300 by (simp)
  1300 by (simp)
  1301 
  1301 
  1302 lemma real_average_minus_second [simp]: "((b + a)/2 - a) = (b-a)/(2::real)"
  1302 lemma real_average_minus_second [simp]: "((b + a)/2 - a) = (b-a)/(2::real)"
  1303 by (simp)
  1303 by (simp)
  1304 
  1304 
  1305 text{*Gallileo's "trick": average velocity = av. of end velocities*}
  1305 text\<open>Gallileo's "trick": average velocity = av. of end velocities\<close>
  1306 
  1306 
  1307 lemma DERIV_const_average:
  1307 lemma DERIV_const_average:
  1308   fixes v :: "real => real"
  1308   fixes v :: "real => real"
  1309   assumes neq: "a \<noteq> (b::real)"
  1309   assumes neq: "a \<noteq> (b::real)"
  1310       and der: "\<forall>x. DERIV v x :> k"
  1310       and der: "\<forall>x. DERIV v x :> k"
  1453   apply (rule DERIV_pos_imp_increasing_at_bot [where f = "\<lambda>i. f (-i)" and b = "-b", simplified])
  1453   apply (rule DERIV_pos_imp_increasing_at_bot [where f = "\<lambda>i. f (-i)" and b = "-b", simplified])
  1454   apply (metis DERIV_mirror der le_minus_iff neg_0_less_iff_less)
  1454   apply (metis DERIV_mirror der le_minus_iff neg_0_less_iff_less)
  1455   apply (metis filterlim_at_top_mirror lim)
  1455   apply (metis filterlim_at_top_mirror lim)
  1456   done
  1456   done
  1457 
  1457 
  1458 text {* Derivative of inverse function *}
  1458 text \<open>Derivative of inverse function\<close>
  1459 
  1459 
  1460 lemma DERIV_inverse_function:
  1460 lemma DERIV_inverse_function:
  1461   fixes f g :: "real \<Rightarrow> real"
  1461   fixes f g :: "real \<Rightarrow> real"
  1462   assumes der: "DERIV f (g x) :> D"
  1462   assumes der: "DERIV f (g x) :> D"
  1463   assumes neq: "D \<noteq> 0"
  1463   assumes neq: "D \<noteq> 0"
  1502   thus "(\<lambda>y. inverse ((f (g y) - x) / (g y - g x)))
  1502   thus "(\<lambda>y. inverse ((f (g y) - x) / (g y - g x)))
  1503         -- x --> inverse D"
  1503         -- x --> inverse D"
  1504     using neq by (rule tendsto_inverse)
  1504     using neq by (rule tendsto_inverse)
  1505 qed
  1505 qed
  1506 
  1506 
  1507 subsection {* Generalized Mean Value Theorem *}
  1507 subsection \<open>Generalized Mean Value Theorem\<close>
  1508 
  1508 
  1509 theorem GMVT:
  1509 theorem GMVT:
  1510   fixes a b :: real
  1510   fixes a b :: real
  1511   assumes alb: "a < b"
  1511   assumes alb: "a < b"
  1512     and fc: "\<forall>x. a \<le> x \<and> x \<le> b \<longrightarrow> isCont f x"
  1512     and fc: "\<forall>x. a \<le> x \<and> x \<le> b \<longrightarrow> isCont f x"
  1579   then show ?thesis
  1579   then show ?thesis
  1580     by auto
  1580     by auto
  1581 qed
  1581 qed
  1582 
  1582 
  1583 
  1583 
  1584 subsection {* L'Hopitals rule *}
  1584 subsection \<open>L'Hopitals rule\<close>
  1585 
  1585 
  1586 lemma isCont_If_ge:
  1586 lemma isCont_If_ge:
  1587   fixes a :: "'a :: linorder_topology"
  1587   fixes a :: "'a :: linorder_topology"
  1588   shows "continuous (at_left a) g \<Longrightarrow> (f ---> g a) (at_right a) \<Longrightarrow> isCont (\<lambda>x. if x \<le> a then g x else f x) a"
  1588   shows "continuous (at_left a) g \<Longrightarrow> (f ---> g a) (at_right a) \<Longrightarrow> isCont (\<lambda>x. if x \<le> a then g x else f x) a"
  1589   unfolding isCont_def continuous_within
  1589   unfolding isCont_def continuous_within
  1643 
  1643 
  1644   have "\<exists>\<zeta>. \<forall>x\<in>{0 <..< a}. 0 < \<zeta> x \<and> \<zeta> x < x \<and> f x / g x = f' (\<zeta> x) / g' (\<zeta> x)"
  1644   have "\<exists>\<zeta>. \<forall>x\<in>{0 <..< a}. 0 < \<zeta> x \<and> \<zeta> x < x \<and> f x / g x = f' (\<zeta> x) / g' (\<zeta> x)"
  1645   proof (rule bchoice, rule)
  1645   proof (rule bchoice, rule)
  1646     fix x assume "x \<in> {0 <..< a}"
  1646     fix x assume "x \<in> {0 <..< a}"
  1647     then have x[arith]: "0 < x" "x < a" by auto
  1647     then have x[arith]: "0 < x" "x < a" by auto
  1648     with g'_neq_0 g_neq_0 `g 0 = 0` have g': "\<And>x. 0 < x \<Longrightarrow> x < a  \<Longrightarrow> 0 \<noteq> g' x" "g 0 \<noteq> g x"
  1648     with g'_neq_0 g_neq_0 \<open>g 0 = 0\<close> have g': "\<And>x. 0 < x \<Longrightarrow> x < a  \<Longrightarrow> 0 \<noteq> g' x" "g 0 \<noteq> g x"
  1649       by auto
  1649       by auto
  1650     have "\<And>x. 0 \<le> x \<Longrightarrow> x < a \<Longrightarrow> isCont f x"
  1650     have "\<And>x. 0 \<le> x \<Longrightarrow> x < a \<Longrightarrow> isCont f x"
  1651       using `isCont f 0` f by (auto intro: DERIV_isCont simp: le_less)
  1651       using \<open>isCont f 0\<close> f by (auto intro: DERIV_isCont simp: le_less)
  1652     moreover have "\<And>x. 0 \<le> x \<Longrightarrow> x < a \<Longrightarrow> isCont g x"
  1652     moreover have "\<And>x. 0 \<le> x \<Longrightarrow> x < a \<Longrightarrow> isCont g x"
  1653       using `isCont g 0` g by (auto intro: DERIV_isCont simp: le_less)
  1653       using \<open>isCont g 0\<close> g by (auto intro: DERIV_isCont simp: le_less)
  1654     ultimately have "\<exists>c. 0 < c \<and> c < x \<and> (f x - f 0) * g' c = (g x - g 0) * f' c"
  1654     ultimately have "\<exists>c. 0 < c \<and> c < x \<and> (f x - f 0) * g' c = (g x - g 0) * f' c"
  1655       using f g `x < a` by (intro GMVT') auto
  1655       using f g \<open>x < a\<close> by (intro GMVT') auto
  1656     then obtain c where *: "0 < c" "c < x" "(f x - f 0) * g' c = (g x - g 0) * f' c"
  1656     then obtain c where *: "0 < c" "c < x" "(f x - f 0) * g' c = (g x - g 0) * f' c"
  1657       by blast
  1657       by blast
  1658     moreover
  1658     moreover
  1659     from * g'(1)[of c] g'(2) have "(f x - f 0)  / (g x - g 0) = f' c / g' c"
  1659     from * g'(1)[of c] g'(2) have "(f x - f 0)  / (g x - g 0) = f' c / g' c"
  1660       by (simp add: field_simps)
  1660       by (simp add: field_simps)
  1661     ultimately show "\<exists>y. 0 < y \<and> y < x \<and> f x / g x = f' y / g' y"
  1661     ultimately show "\<exists>y. 0 < y \<and> y < x \<and> f x / g x = f' y / g' y"
  1662       using `f 0 = 0` `g 0 = 0` by (auto intro!: exI[of _ c])
  1662       using \<open>f 0 = 0\<close> \<open>g 0 = 0\<close> by (auto intro!: exI[of _ c])
  1663   qed
  1663   qed
  1664   then obtain \<zeta> where "\<forall>x\<in>{0 <..< a}. 0 < \<zeta> x \<and> \<zeta> x < x \<and> f x / g x = f' (\<zeta> x) / g' (\<zeta> x)" ..
  1664   then obtain \<zeta> where "\<forall>x\<in>{0 <..< a}. 0 < \<zeta> x \<and> \<zeta> x < x \<and> f x / g x = f' (\<zeta> x) / g' (\<zeta> x)" ..
  1665   then have \<zeta>: "eventually (\<lambda>x. 0 < \<zeta> x \<and> \<zeta> x < x \<and> f x / g x = f' (\<zeta> x) / g' (\<zeta> x)) (at_right 0)"
  1665   then have \<zeta>: "eventually (\<lambda>x. 0 < \<zeta> x \<and> \<zeta> x < x \<and> f x / g x = f' (\<zeta> x) / g' (\<zeta> x)) (at_right 0)"
  1666     unfolding eventually_at by (intro exI[of _ a]) (auto simp: dist_real_def)
  1666     unfolding eventually_at by (intro exI[of _ a]) (auto simp: dist_real_def)
  1667   moreover
  1667   moreover
  1763   moreover
  1763   moreover
  1764   from inv_g have "((\<lambda>t. norm ((f a - x * g a) * inverse (g t))) ---> norm ((f a - x * g a) * 0)) (at_right 0)"
  1764   from inv_g have "((\<lambda>t. norm ((f a - x * g a) * inverse (g t))) ---> norm ((f a - x * g a) * 0)) (at_right 0)"
  1765     by (intro tendsto_intros)
  1765     by (intro tendsto_intros)
  1766   then have "((\<lambda>t. norm (f a - x * g a) / norm (g t)) ---> 0) (at_right 0)"
  1766   then have "((\<lambda>t. norm (f a - x * g a) / norm (g t)) ---> 0) (at_right 0)"
  1767     by (simp add: inverse_eq_divide)
  1767     by (simp add: inverse_eq_divide)
  1768   from this[unfolded tendsto_iff, rule_format, of "e / 2"] `0 < e`
  1768   from this[unfolded tendsto_iff, rule_format, of "e / 2"] \<open>0 < e\<close>
  1769   have "eventually (\<lambda>t. norm (f a - x * g a) / norm (g t) < e / 2) (at_right 0)"
  1769   have "eventually (\<lambda>t. norm (f a - x * g a) / norm (g t) < e / 2) (at_right 0)"
  1770     by (auto simp: dist_real_def)
  1770     by (auto simp: dist_real_def)
  1771 
  1771 
  1772   ultimately show "eventually (\<lambda>t. dist (f t / g t) x < e) (at_right 0)"
  1772   ultimately show "eventually (\<lambda>t. dist (f t / g t) x < e) (at_right 0)"
  1773   proof eventually_elim
  1773   proof eventually_elim
  1778       using f0 g0 t(1,2) by (intro GMVT') (force intro!: DERIV_isCont)+
  1778       using f0 g0 t(1,2) by (intro GMVT') (force intro!: DERIV_isCont)+
  1779     then obtain y where [arith]: "t < y" "y < a"
  1779     then obtain y where [arith]: "t < y" "y < a"
  1780       and D_eq0: "(g a - g t) * f' y = (f a - f t) * g' y"
  1780       and D_eq0: "(g a - g t) * f' y = (f a - f t) * g' y"
  1781       by blast
  1781       by blast
  1782     from D_eq0 have D_eq: "(f t - f a) / (g t - g a) = f' y / g' y"
  1782     from D_eq0 have D_eq: "(f t - f a) / (g t - g a) = f' y / g' y"
  1783       using `g a < g t` g'_neq_0[of y] by (auto simp add: field_simps)
  1783       using \<open>g a < g t\<close> g'_neq_0[of y] by (auto simp add: field_simps)
  1784 
  1784 
  1785     have *: "f t / g t - x = ((f t - f a) / (g t - g a) - x) * (1 - g a / g t) + (f a - x * g a) / g t"
  1785     have *: "f t / g t - x = ((f t - f a) / (g t - g a) - x) * (1 - g a / g t) + (f a - x * g a) / g t"
  1786       by (simp add: field_simps)
  1786       by (simp add: field_simps)
  1787     have "norm (f t / g t - x) \<le>
  1787     have "norm (f t / g t - x) \<le>
  1788         norm (((f t - f a) / (g t - g a) - x) * (1 - g a / g t)) + norm ((f a - x * g a) / g t)"
  1788         norm (((f t - f a) / (g t - g a) - x) * (1 - g a / g t)) + norm ((f a - x * g a) / g t)"
  1789       unfolding * by (rule norm_triangle_ineq)
  1789       unfolding * by (rule norm_triangle_ineq)
  1790     also have "\<dots> = dist (f' y / g' y) x * norm (1 - g a / g t) + norm (f a - x * g a) / norm (g t)"
  1790     also have "\<dots> = dist (f' y / g' y) x * norm (1 - g a / g t) + norm (f a - x * g a) / norm (g t)"
  1791       by (simp add: abs_mult D_eq dist_real_def)
  1791       by (simp add: abs_mult D_eq dist_real_def)
  1792     also have "\<dots> < (e / 4) * 2 + e / 2"
  1792     also have "\<dots> < (e / 4) * 2 + e / 2"
  1793       using ineq Df[of y] `0 < e` by (intro add_le_less_mono mult_mono) auto
  1793       using ineq Df[of y] \<open>0 < e\<close> by (intro add_le_less_mono mult_mono) auto
  1794     finally show "dist (f t / g t) x < e"
  1794     finally show "dist (f t / g t) x < e"
  1795       by (simp add: dist_real_def)
  1795       by (simp add: dist_real_def)
  1796   qed
  1796   qed
  1797 qed
  1797 qed
  1798 
  1798