-
Notifications
You must be signed in to change notification settings - Fork 48
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
proof of L'Hopital rule #1371
base: master
Are you sure you want to change the base?
proof of L'Hopital rule #1371
Changes from all commits
c8df1b0
17ae5ef
5e0b0db
d6d5deb
6835511
e6ca697
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -41,6 +41,9 @@ From HB Require Import structures. | |
(* lime_sup f a/lime_inf f a == limit sup/inferior of the extended real- *) | ||
(* valued function f at point a *) | ||
(* ``` *) | ||
(* cauchy_MVT == Cauchy's mean value theorem *) | ||
(* lhopital_right == L'Hopital rule (limit taken on the right) *) | ||
(* lhopital_left == L'Hopital rule (limit taken on the left) *) | ||
(* *) | ||
(******************************************************************************) | ||
|
||
|
@@ -2544,3 +2547,239 @@ apply/continuous_within_itvP => //; split. | |
Qed. | ||
|
||
End variation_continuity. | ||
|
||
Section Cauchy_MVT. | ||
Context {R : realType}. | ||
Variables (f df g dg : R -> R) (a b c : R). | ||
Hypothesis ab : a < b. | ||
Hypotheses (cf : {within `[a, b], continuous f}) | ||
(cg : {within `[a, b], continuous g}). | ||
Hypotheses (fdf : forall x, x \in `]a, b[%R -> is_derive x 1 f (df x)) | ||
(gdg : forall x, x \in `]a, b[%R -> is_derive x 1 g (dg x)). | ||
Hypotheses (dg0 : forall x, x \in `]a, b[%R -> dg x != 0). | ||
|
||
Lemma differentiable_subr_neq0 : | ||
g b - g a != 0. | ||
Proof. | ||
have [r] := MVT ab gdg cg; rewrite in_itv/= => /andP[ar rb] dgg. | ||
by rewrite dgg mulf_neq0 ?dg0 ?in_itv/= ?ar//; rewrite subr_eq0 gt_eqF. | ||
Qed. | ||
|
||
Lemma cauchy_MVT : | ||
exists2 c, c \in `]a, b[%R & df c / dg c = (f b - f a) / (g b - g a). | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Seems like callers will need to know that There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done, as a separate lemma instead of inside the proof, but unsure if you perhaps meant outside of the MVT Cauchy section (so without all of its assumptions?) Also I'm a bit unsure of what the naming convention would be for that one, so happy to rename it to something proper. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This makes sense to me. I don't have any idea for naming here, so I'd say it's fine for now. |
||
Proof. | ||
have [r] := MVT ab gdg cg; rewrite in_itv/= => /andP[ar rb] dgg. | ||
pose h (x : R) := f x - ((f b - f a) / (g b - g a)) * g x. | ||
have hder x : x \in `]a, b[%R -> derivable h x 1. | ||
move=> xab; apply: derivableB => /=. | ||
exact: (@ex_derive _ _ _ _ _ _ _ (fdf xab)). | ||
by apply: derivableM => //; exact: (@ex_derive _ _ _ _ _ _ _ (gdg xab)). | ||
have ch : {within `[a, b], continuous h}. | ||
rewrite continuous_subspace_in => x xab. | ||
by apply: cvgB; [exact: cf|apply: cvgM; [exact: cvg_cst|exact: cg]]. | ||
have /(Rolle ab hder ch)[x xab derh] : h a = h b. | ||
rewrite /h; apply/eqP; rewrite subr_eq eq_sym -addrA eq_sym addrC -subr_eq. | ||
rewrite -mulrN -mulrDr -(addrC (g a)) -[X in _ * X]opprB mulrN -mulrA. | ||
rewrite mulVf//. | ||
by rewrite mulr1 opprB. | ||
by rewrite differentiable_subr_neq0. | ||
pose dh (x : R) := df x - (f b - f a) / (g b - g a) * dg x. | ||
have his_der y : y \in `]a, b[%R -> is_derive x 1 h (dh x). | ||
by move=> yab; apply: is_deriveB; [exact: fdf|apply: is_deriveZ; exact: gdg]. | ||
exists x => //. | ||
have := @derive_val _ R _ _ _ _ _ (his_der _ xab). | ||
have -> := @derive_val _ R _ _ _ _ _ derh. | ||
move=> /eqP; rewrite eq_sym subr_eq add0r => /eqP ->. | ||
by rewrite -mulrA divff ?mulr1//; exact: dg0. | ||
Qed. | ||
|
||
End Cauchy_MVT. | ||
|
||
Section lhopital. | ||
Context {R : realType}. | ||
Variables (f df g dg : R -> R) (a : R) (U : set R) (Ua : nbhs a U). | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. As usual, a question about boundary conditions. I'm a bit surprised to see we require There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good catch - I think this should go through, but changes are a bit more time-consuming than I expected so still in progress, should be done sometime next week. |
||
Hypotheses (fdf : forall x, x \in U -> is_derive x 1 f (df x)) | ||
(gdg : forall x, x \in U -> is_derive x 1 g (dg x)). | ||
Hypotheses (fa0 : f a = 0) (ga0 : g a = 0) | ||
(cdg : \forall x \near a^', dg x != 0). | ||
|
||
Lemma lhopital_right (l : R) : | ||
df x / dg x @[x --> a^'+] --> l -> f x / g x @[x --> a^'+] --> l. | ||
Proof. | ||
case: cdg => r/= r0 cdg'. | ||
move: Ua; rewrite filter_of_nearI => -[D /= D0 aDU]. | ||
near a^'+ => b. | ||
have abf x : x \in `]a, b[%R -> {within `[a, x], continuous f}. | ||
rewrite in_itv/= => /andP[ax xb]. | ||
apply: derivable_within_continuous => y; rewrite in_itv/= => /andP[ay yx]. | ||
apply: ex_derive. | ||
apply: fdf. | ||
rewrite inE; apply: aDU => /=. | ||
rewrite ler0_norm? subr_le0//. | ||
rewrite opprD opprK addrC ltrBlDr (le_lt_trans yx)// (lt_trans xb)//. | ||
near: b; apply: nbhs_right_lt. | ||
by rewrite ltrDr. | ||
have abg x : x \in `]a, b[%R -> {within `[a, x], continuous g}. | ||
rewrite in_itv/= => /andP[ax xb]. | ||
apply: derivable_within_continuous => y; rewrite in_itv/= => /andP[ay yx]. | ||
apply: ex_derive. | ||
apply: gdg. | ||
rewrite inE; apply: aDU => /=. | ||
rewrite ler0_norm? subr_le0//. | ||
rewrite opprD opprK addrC ltrBlDr (le_lt_trans yx)// (lt_trans xb)//. | ||
near: b; apply: nbhs_right_lt. | ||
by rewrite ltrDr. | ||
have fdf' y : y \in `]a, b[%R -> is_derive y 1 f (df y). | ||
rewrite in_itv/= => /andP[ay yb]; apply: fdf. | ||
rewrite inE; apply: aDU => /=. | ||
rewrite ltr0_norm ?subr_lt0//. | ||
rewrite opprD opprK addrC ltrBlDr (lt_le_trans yb)//. | ||
near: b; apply: nbhs_right_le. | ||
by rewrite ltrDr. | ||
have gdg' y : y \in `]a, b[%R -> is_derive y 1 g (dg y). | ||
rewrite in_itv/= => /andP[ay yb]; apply: gdg. | ||
rewrite inE; apply: aDU => /=. | ||
rewrite ltr0_norm ?subr_lt0//. | ||
rewrite opprD opprK addrC ltrBlDr (lt_le_trans yb)//. | ||
near: b; apply: nbhs_right_le. | ||
by rewrite ltrDr. | ||
have {}dg0 y : y \in `]a, b[%R -> dg y != 0. | ||
rewrite in_itv/= => /andP[ay yb]. | ||
apply: (cdg' y) => /=; last by rewrite gt_eqF. | ||
rewrite ltr0_norm; last by rewrite subr_lt0. | ||
rewrite opprB ltrBlDl (lt_trans yb)//. | ||
near: b; apply: nbhs_right_lt. | ||
by rewrite ltrDl. | ||
move=> fgal. | ||
have L : \forall x \near a^'+, | ||
exists2 c, c \in `]a, x[%R & df c / dg c = f x / g x. | ||
near=> x. | ||
have /andP[ax xb] : a < x < b by exact/andP. | ||
have {}fdf' y : y \in `]a, x[%R -> is_derive y 1 f (df y). | ||
rewrite !in_itv/= => /andP[ay yx]. | ||
by apply: fdf'; rewrite in_itv/= ay/= (lt_trans yx). | ||
have {}gdg' y : y \in `]a, x[%R -> is_derive y 1 g (dg y). | ||
rewrite !in_itv/= => /andP[ay yx]. | ||
by apply: gdg'; rewrite in_itv/= ay/= (lt_trans yx). | ||
have {}dg0 y : y \in `]a, x[%R -> dg y != 0. | ||
rewrite in_itv/= => /andP[ya yx]. | ||
by apply: dg0; rewrite in_itv/= ya/= (lt_trans yx). | ||
have {}axf : {within `[a, x], continuous f}. | ||
rewrite continuous_subspace_in => y; rewrite inE/= in_itv/= => /andP[ay yx]. | ||
by apply: abf; rewrite in_itv/= xb andbT. | ||
have {}axg : {within `[a, x], continuous g}. | ||
rewrite continuous_subspace_in => y; rewrite inE/= in_itv/= => /andP[ay yx]. | ||
by apply: abg; rewrite in_itv/= xb andbT. | ||
have := @cauchy_MVT _ f df g dg _ _ ax axf axg fdf' gdg' dg0. | ||
by rewrite fa0 ga0 2!subr0. | ||
apply/cvgrPdist_le => /= e e0. | ||
move/cvgrPdist_le : fgal. | ||
move=> /(_ _ e0)[r'/= r'0 fagl]. | ||
case: L => d /= d0 L. | ||
near=> t. | ||
have /= := L t. | ||
have atd : `|a - t| < d. | ||
rewrite ltr0_norm; last by rewrite subr_lt0. | ||
rewrite opprB ltrBlDl. | ||
near: t; apply: nbhs_right_lt. | ||
by rewrite ltrDl. | ||
have at_ : a < t by []. | ||
move=> /(_ atd)/(_ at_)[c]; rewrite in_itv/= => /andP[ac ct <-]. | ||
apply: fagl => //=. | ||
rewrite ltr0_norm; last by rewrite subr_lt0. | ||
rewrite opprB ltrBlDl (lt_trans ct)//. | ||
near: t; apply: nbhs_right_lt. | ||
by rewrite ltrDl. | ||
Unshelve. all: by end_near. Qed. | ||
|
||
Lemma lhopital_left (l : R) : | ||
df x / dg x @[x --> a^'-] --> l -> f x / g x @[x --> a^'-] --> l. | ||
Proof. | ||
case: cdg => r/= r0 cdg'. | ||
move: Ua; rewrite filter_of_nearI => -[D /= D0 aDU]. | ||
near a^'- => b. | ||
have baf x : x \in `]b, a[%R -> {within `[x, a], continuous f}. | ||
rewrite in_itv/= => /andP[bx xa]. | ||
apply: derivable_within_continuous => y; rewrite in_itv/= => /andP[xy ya]. | ||
apply: ex_derive. | ||
apply: fdf. | ||
rewrite inE; apply: aDU => /=. | ||
rewrite ger0_norm ?subr_ge0//. | ||
rewrite ltrBlDr -ltrBlDl (lt_le_trans _ xy)// (le_lt_trans _ bx)//. | ||
near: b; apply: nbhs_left_ge. | ||
by rewrite ltrBlDl ltrDr. | ||
have bag x : x \in `]b, a[%R -> {within `[x, a], continuous g}. | ||
rewrite in_itv/= => /andP[bx xa]. | ||
apply: derivable_within_continuous => y; rewrite in_itv/= => /andP[xy ya]. | ||
apply: ex_derive. | ||
apply: gdg. | ||
rewrite inE; apply: aDU => /=. | ||
rewrite ger0_norm ?subr_ge0//. | ||
rewrite ltrBlDr -ltrBlDl (lt_le_trans _ xy)// (lt_trans _ bx)//. | ||
near: b; apply: nbhs_left_gt. | ||
by rewrite ltrBlDl ltrDr. | ||
have fdf' y : y \in `]b, a[%R -> is_derive y 1 f (df y). | ||
rewrite in_itv/= => /andP[by_ ya]; apply: fdf. | ||
rewrite inE. | ||
apply: aDU => /=. | ||
rewrite gtr0_norm ?subr_gt0//. | ||
rewrite ltrBlDl -ltrBlDr (le_lt_trans _ by_)//. | ||
near: b; apply: nbhs_left_ge. | ||
by rewrite ltrBlDr ltrDl. | ||
have gdg' y : y \in `]b, a[%R -> is_derive y 1 g (dg y). | ||
rewrite in_itv/= => /andP[by_ ya]; apply: gdg. | ||
rewrite inE; apply: aDU => /=. | ||
rewrite gtr0_norm ?subr_gt0//. | ||
rewrite ltrBlDl -ltrBlDr (le_lt_trans _ by_)//. | ||
near: b; apply: nbhs_left_ge. | ||
by rewrite ltrBlDr ltrDl. | ||
have {}dg0 y : y \in `]b, a[%R -> dg y != 0. | ||
rewrite in_itv/= => /andP[by_ ya]. | ||
apply: (cdg' y) => /=; last by rewrite lt_eqF. | ||
rewrite gtr0_norm; last by rewrite subr_gt0. | ||
rewrite ltrBlDr -ltrBlDl (lt_trans _ by_)//. | ||
near: b; apply: nbhs_left_gt. | ||
by rewrite ltrBlDl ltrDr. | ||
move=> fgal. | ||
have L : \forall x \near a^'-, | ||
exists2 c, c \in `]x, a[%R & df c / dg c = f x / g x. | ||
near=> x. | ||
have /andP[bx xa] : b < x < a by exact/andP. | ||
have {}fdf' y : y \in `]x, a[%R -> is_derive y 1 f (df y). | ||
rewrite in_itv/= => /andP[xy ya]. | ||
by apply: fdf'; rewrite in_itv/= ya andbT (lt_trans bx). | ||
have {}gdg' y : y \in `]x, a[%R -> is_derive y 1 g (dg y). | ||
rewrite in_itv/= => /andP[xy ya]. | ||
by apply: gdg'; rewrite in_itv/= ya andbT (lt_trans _ xy). | ||
have {}dg0 y : y \in `]x, a[%R -> dg y != 0. | ||
rewrite in_itv/= => /andP[xy ya]. | ||
by apply: dg0; rewrite in_itv/= ya andbT (lt_trans bx). | ||
have {}xaf : {within `[x, a], continuous f}. | ||
rewrite continuous_subspace_in => y; rewrite inE/= in_itv/= => /andP[xy ya]. | ||
by apply: baf; rewrite in_itv/= bx. | ||
have {}xag : {within `[x, a], continuous g}. | ||
rewrite continuous_subspace_in => y; rewrite inE/= in_itv/= => /andP[xy ya]. | ||
by apply: bag; rewrite in_itv/= bx. | ||
have := @cauchy_MVT _ f df g dg _ _ xa xaf xag fdf' gdg' dg0. | ||
by rewrite fa0 ga0 !sub0r divrN mulNr opprK. | ||
apply/cvgrPdist_le => /= e e0. | ||
move/cvgrPdist_le : fgal. | ||
move=> /(_ _ e0)[r'/= r'0 fagl]. | ||
case: L => d /= d0 L. | ||
near=> t. | ||
have /= := L t. | ||
have atd : `|a - t| < d. | ||
rewrite gtr0_norm; last by rewrite subr_gt0. | ||
rewrite ltrBlDr -ltrBlDl. | ||
near: t; apply: nbhs_left_gt. | ||
by rewrite ltrBlDl ltrDr. | ||
have ta : t < a by []. | ||
move=> /(_ atd)/(_ ta)[c]; rewrite in_itv/= => /andP[tc ca <-]. | ||
apply: fagl => //=. | ||
rewrite gtr0_norm; last by rewrite subr_gt0. | ||
rewrite ltrBlDr -ltrBlDl (lt_trans _ tc)//. | ||
near: t; apply: nbhs_left_gt. | ||
by rewrite ltrBlDl ltrDr. | ||
Unshelve. all: by end_near. Qed. | ||
|
||
End lhopital. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we extend the predicate
derivable_oo_continuous_bnd
to include an option for an explicit derivative as an argument (E.G.derivable_oo_continuous_bnd_with f df x y
)?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Gave it a try, but couldn't extend quickly, so perhaps something to extend separately for a different PR?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, I have no problem with that. Happy to deal with it later.