Built with Alectryon, running Coq+SerAPI v8.15.0+0.15.0. Bubbles () indicate interactive fragments: hover for details, tap to reveal contents. Use Ctrl+↑Ctrl+↓ to navigate, Ctrl+🖱️ to focus. On Mac, use ⌘ instead of Ctrl.
Notation"[ predI _ & _ ]" was already used in scope
fun_scope. [notation-overridden,parsing]
Notation"[ predU _ & _ ]" was already used in scope
fun_scope. [notation-overridden,parsing]
Notation"[ predD _ & _ ]" was already used in scope
fun_scope. [notation-overridden,parsing]
Notation"[ predC _ ]" was already used in scope
fun_scope. [notation-overridden,parsing]
Notation"[ preim _ of _ ]" was already used in scope
fun_scope. [notation-overridden,parsing]
Notation"_ + _" was already used in scope nat_scope.
[notation-overridden,parsing]
Notation"_ - _" was already used in scope nat_scope.
[notation-overridden,parsing]
Notation"_ <= _" was already used in scope nat_scope.
[notation-overridden,parsing]
Notation"_ < _" was already used in scope nat_scope.
[notation-overridden,parsing]
Notation"_ >= _" was already used in scope nat_scope.
[notation-overridden,parsing]
Notation"_ > _" was already used in scope nat_scope.
[notation-overridden,parsing]
Notation"_ <= _ <= _" was already used in scope
nat_scope. [notation-overridden,parsing]
Notation"_ < _ <= _" was already used in scope
nat_scope. [notation-overridden,parsing]
Notation"_ <= _ < _" was already used in scope
nat_scope. [notation-overridden,parsing]
Notation"_ < _ < _" was already used in scope
nat_scope. [notation-overridden,parsing]
Notation"_ * _" was already used in scope nat_scope.
[notation-overridden,parsing]
New coercion path [GRing.subring_closedM;
GRing.smulr_closedN] : GRing.subring_closed >-> GRing.oppr_closed is ambiguous with existing
[GRing.subring_closedB; GRing.zmod_closedN] : GRing.subring_closed >-> GRing.oppr_closed.
[ambiguous-paths,typechecker]
New coercion path [GRing.subring_closed_semi;
GRing.semiring_closedM] : GRing.subring_closed >-> GRing.mulr_closed is ambiguous with existing
[GRing.subring_closedM; GRing.smulr_closedM] : GRing.subring_closed >-> GRing.mulr_closed.
New coercion path [GRing.subring_closed_semi;
GRing.semiring_closedD] : GRing.subring_closed >-> GRing.addr_closed is ambiguous with existing
[GRing.subring_closedB; GRing.zmod_closedD] : GRing.subring_closed >-> GRing.addr_closed.
[ambiguous-paths,typechecker]
New coercion path [GRing.sdivr_closed_div;
GRing.divr_closedM] : GRing.sdivr_closed >-> GRing.mulr_closed is ambiguous with existing
[GRing.sdivr_closedM; GRing.smulr_closedM] : GRing.sdivr_closed >-> GRing.mulr_closed.
[ambiguous-paths,typechecker]
New coercion path [GRing.subalg_closedBM;
GRing.subring_closedB] : GRing.subalg_closed >-> GRing.zmod_closed is ambiguous with existing
[GRing.subalg_closedZ; GRing.submod_closedB] : GRing.subalg_closed >-> GRing.zmod_closed.
[ambiguous-paths,typechecker]
New coercion path [GRing.divring_closed_div;
GRing.sdivr_closedM] : GRing.divring_closed >-> GRing.smulr_closed is ambiguous with existing
[GRing.divring_closedBM; GRing.subring_closedM] : GRing.divring_closed >-> GRing.smulr_closed.
[ambiguous-paths,typechecker]
New coercion path [GRing.divalg_closedBdiv;
GRing.divring_closedBM] : GRing.divalg_closed >-> GRing.subring_closed is ambiguous with existing
[GRing.divalg_closedZ; GRing.subalg_closedBM] : GRing.divalg_closed >-> GRing.subring_closed.
[ambiguous-paths,typechecker]
New coercion path [GRing.Pred.subring_smul;
GRing.Pred.smul_mul] : GRing.Pred.subring >-> GRing.Pred.mul is ambiguous with existing
[GRing.Pred.subring_semi; GRing.Pred.semiring_mul] : GRing.Pred.subring >-> GRing.Pred.mul.
[ambiguous-paths,typechecker]
From mathcomp Require Import matrix interval zmodp vector fieldext falgebra.
New coercion path [Empty.mixin; Empty.eqMixin] : Empty.class_of >-> Equality.mixin_of is ambiguous with existing
[Empty.base; Finite.base; Choice.base] : Empty.class_of >-> Equality.mixin_of.
[ambiguous-paths,typechecker]
New coercion path [Empty.mixin; Empty.choiceMixin] : Empty.class_of >-> Choice.mixin_of is ambiguous with existing
[Empty.base; Finite.base; Choice.mixin] : Empty.class_of >-> Choice.mixin_of.
[ambiguous-paths,typechecker]
New coercion path [Empty.mixin; Empty.countMixin] : Empty.class_of >-> Countable.mixin_of is ambiguous with existing
[Empty.base; Finite.mixin; Finite.mixin_base] : Empty.class_of >-> Countable.mixin_of.
[ambiguous-paths,typechecker]
From mathcomp.classical Require Import functions cardinality mathcomp_extra.
Require Import ereal reals signed topology prodnormedzmodule.
Require Import normedtype derive real_interval.
From HB Require Import structures.
(******************************************************************************)(* This file provides properties of standard real-valued functions over real *)(* numbers (e.g., the continuity of the inverse of a continuous function). *)(******************************************************************************)Set Implicit Arguments.
Unset Strict Implicit.
Unset Printing Implicit Defensive.
Import Order.TTheory GRing.Theory Num.Def Num.Theory.
Import numFieldTopology.Exports.
LocalOpen Scope classical_set_scope.
LocalOpen Scope ring_scope.
Import numFieldNormedType.Exports.
Sectionreal_inverse_functions.
VariableR : realType.
Implicit Types (ab : R) (fg : R -> R).
(* This lemma should be used with caution. Generally `{within I, continuous f}` is what one would intend. So having `{in I, continuous f}` as a condition may indicate potential issues at the endpoints of the interval.*)Lemmacontinuous_subspace_itv (I : interval R) (f : R -> R) :
{in I, continuous f} -> {within [set` I], continuous f}.
Proof.
move=> ctsf; apply: continuous_in_subspaceT => x Ix; apply: ctsf.
bymove: Ix; rewrite inE.
Qed.
Lemmaitv_continuous_inj_lef (I : interval R) :
(existsxy, [/\ x \in I, y \in I, x < y & f x <= f y]) ->
{within [set` I], continuous f} -> {in I &, injective f} ->
{in I &, {mono f : x y / x <= y}}.
Proof.
gen have fxy : f / {in I &, injective f} ->
{in I &, forallxy, x < y -> f x != f y}.
move=> fI x y xI yI xLy; apply/negP => /eqP /fI => /(_ xI yI) xy.
bymove: xLy; rewrite xy ltxx.
gen have main : f / forallc, {within [set` I], continuous f} ->
{in I &, injective f} ->
{in I &, forallab, f a < f b -> a < c -> c < b -> f a < f c /\ f c < f b}.
move=> c fC fI a b aI bI faLfb aLc cLb.
have intP := interval_is_interval aI bI.
have cI : c \in I byrewrite intP// (ltW aLc) ltW.
have ctsACf : {within `[a, c], continuous f}.
apply: (continuous_subspaceW _ fC) => x; rewrite /= inE => /itvP axc.
byrewrite intP// axc/= (le_trans _ (ltW cLb))// axc.
have ctsCBf : {within `[c, b], continuous f}.
apply: (continuous_subspaceW _ fC) => x /=; rewrite inE => /itvP axc.
byrewrite intP// axc andbT (le_trans (ltW aLc)) ?axc.
have [aLb alb'] : a < b /\ a <= b byrewrite ltW (lt_trans aLc).
have [faLfc|fcLfa|/eqP faEfc] /= := ltrgtP (f a) (f c).
- split; rewrite // lt_neqAle fxy // leNgt; apply/negP => fbLfc.
have := fbLfc; suff /eqP -> : c == b byrewrite ltxx.
rewrite eq_le (ltW cLb) /=.
have [d /andP[ad dc] fdEfb] : exists2 d, a <= d <= c & f d = f b.
have aLc' : a <= c byrewrite ltW.
apply: IVT => //; last first.
bycase: ltrgtP faLfc; rewrite // (ltW faLfb) // ltW.
rewrite -(fI _ _ _ _ fdEfb) //.
move: ad dc; rewrite le_eqVlt =>/predU1P[<-//| /ltW L] dc.
byrewrite intP// L (le_trans _ (ltW cLb)).
- have [fbLfc | fcLfb | fbEfc] /= := ltrgtP (f b) (f c).
+ byhave := lt_trans fbLfc fcLfa; rewrite ltNge (ltW faLfb).
+ have [d /andP[cLd dLb] /eqP] : exists2 d, c <= d <= b & f d = f a.
have cLb' : c <= b byrewrite ltW.
apply: IVT => //; lastbycase: ltrgtP fcLfb; rewrite // !ltW.
have /(fxy f fI) : a < d byrewrite (lt_le_trans aLc).
suff dI' : d \in I byrewrite eq_sym=> /(_ aI dI') => /negbTE ->.
move: dLb; rewrite le_eqVlt => /predU1P[->//|/ltW db].
byrewrite intP// db (le_trans (ltW aLc)).
+ bymove: fcLfa; rewrite -fbEfc ltNge (ltW faLfb).
bymove/(fxy _ fI) : aLc=> /(_ aI cI); rewrite faEfc.
move=> [u [v [uI vI ulv +]]] fC fI; rewrite le_eqVlt => /predU1P[fufv|fuLfv].
bymove/fI: fufv => /(_ uI vI) uv; move: ulv; rewrite uv ltxx.
have aux a c b : a \in I -> b \in I -> a < c -> c < b ->
(f a < f c -> f a < f b /\ f c < f b) /\
(f c < f b -> f a < f b /\ f a < f c).
move=> aI bI aLc cLb; have aLb := lt_trans aLc cLb.
have cI : c \in I byrewrite (interval_is_interval aI bI)// (ltW aLc)/= ltW.
have fanfb : f a != f b byapply: (fxy f fI).
have decr : f b < f a -> f b < f c /\ f c < f a.
have ofC : {within [set` I], continuous (-f)}.
move=> ?; apply: continuous_comp; [exact: fC | exact: continuousN].
have ofI : {in I &, injective (-f)} bymove=>> ? ? /oppr_inj/fI ->.
rewrite -[X in X < _ -> _](opprK (f b)) ltr_oppl => ofaLofb.
have := main _ c ofC ofI a b aI bI ofaLofb aLc cLb.
by (do2rewrite ltr_oppl opprK); rewrite and_comm.
split=> [faLfc|fcLfb].
suff L : f a < f b byhave [] := main f c fC fI a b aI bI L aLc cLb.
bycase: ltgtP decr fanfb => // fbfa []//; case: ltgtP faLfc.
suff L : f a < f b byhave [] := main f c fC fI a b aI bI L aLc cLb.
bycase: ltgtP decr fanfb => // fbfa []//; case: ltgtP fcLfb.
have{main fC} whole a c b := main f c fC fI a b.
have low a c b : f a < f c -> a \in I -> b \in I ->
a < c -> c < b -> f a < f b /\ f c < f b.
bymove=> L aI bI ac cb; case: (aux a c b aI bI ac cb)=> [/(_ L)].
have high a c b : f c < f b -> a \in I -> b \in I ->
a < c -> c < b -> f a < f b /\ f a < f c.
bymove=> L aI bI ac cb; case: (aux a c b aI bI ac cb)=> [_ /(_ L)].
apply: le_mono_in => x y xI yI xLy.
have [uLx | xLu | xu] := ltrgtP u x.
- suff fuLfx : f u < f x byhave [] := low u x y fuLfx uI yI uLx xLy.
have [xLv | vLx | -> //] := ltrgtP x v; firstbycase: (whole u x v).
bycase: (low u v x).
- have fxLfu : f x < f u byhave [] := high x u v fuLfv xI vI xLu ulv.
have [yLu | uLy | -> //] := ltrgtP y u; firstbycase: (whole x y u).
bycase: (low x u y).
move: xLy; rewrite -xu => uLy.
have [yLv | vLy | -> //] := ltrgtP y v; firstbycase: (whole u y v).
bycase: (low u v y).
Qed.
Lemmaitv_continuous_inj_gef (I : interval R) :
(existsxy, [/\ x \in I, y \in I, x < y & f y <= f x]) ->
{within [set` I], continuous f} -> {in I &, injective f} ->
{in I &, {mono f : x y /~ x <= y}}.
Proof.
move=> [a [b [aI bI ab fbfa]]] fC fI x y xI yI.
suff : (- f) y <= (- f) x = (y <= x) byrewrite ler_oppl opprK.
apply: itv_continuous_inj_le xI => // [|x1 x1I | x1 x2 x1I x2I].
- byexistsa, b; split => //; rewrite ler_oppl opprK.
- byapply/continuousN/fC.
bymove/oppr_inj; apply/fI.
Qed.
Lemmaitv_continuous_inj_monof (I : interval R) :
{within [set` I], continuous f} -> {in I &, injective f} -> monotonous I f.
Proof.
move=> fC fI.
case: (pselect (existsab, [/\ a \in I , b \in I & a < b])); last first.
move=> N2I; left => x y xI yI; suff -> : x = y byrewrite?lexx.
byapply: contra_notP N2I => /eqP; case: ltgtP; [existsx, y|existsy, x|].
move=> [a [b [aI bI lt_ab]]].
have /orP[faLfb|fbLfa] := le_total (f a) (f b).
byleft; apply: itv_continuous_inj_le => //; existsa, b; rewrite?faLfb.
byright; apply: itv_continuous_inj_ge => //; existsa, b; rewrite?fbLfa.
Qed.
Lemmasegment_continuous_inj_lefab :
f a <= f b -> {within `[a, b], continuous f} -> {in `[a, b] &, injective f} ->
{in `[a, b] &, {mono f : x y / x <= y}}.
Proof.
move=> fafb fct finj; have [//|] := itv_continuous_inj_mono fct finj.
have [aLb|bLa|<-] := ltrgtP a b; first1last.
- bymove=> _ x ?; rewrite itv_ge// -ltNge.
- bymove=> _ x y /itvxxP-> /itvxxP->; rewrite !lexx.
move=> /(_ a b); rewrite !bound_itvE fafb.
bymove=> /(_ (ltW aLb) (ltW aLb)); rewrite lt_geF.
Qed.
Lemmasegment_continuous_inj_gefab :
f a >= f b -> {within `[a, b], continuous f} -> {in `[a, b] &, injective f} ->
{in `[a, b] &, {mono f : x y /~ x <= y}}.
Proof.
move=> fafb fct finj; have [|//] := itv_continuous_inj_mono fct finj.
have [aLb|bLa|<-] := ltrgtP a b; first1last.
- bymove=> _ x ?; rewrite itv_ge// -ltNge.
- bymove=> _ x y /itvxxP-> /itvxxP->; rewrite !lexx.
move=> /(_ b a); rewrite !bound_itvE fafb.
bymove=> /(_ (ltW aLb) (ltW aLb)); rewrite lt_geF.
Qed.
(* The condition "f a <= f b" is unnecessary because the last *)(* interval condition is vacuously true otherwise. *)Lemmasegment_can_leabfg : a <= b ->
{within `[a, b], continuous f} ->
{in `[a, b], cancel f g} ->
{in `[f a, f b] &, {mono g : x y / x <= y}}.
Proof.
move=> aLb ctf fK; have [fbLfa | faLfb] := ltrP (f b) (f a).
bymove=> x y; rewrite itv_ge// -ltNge.
have [aab bab] : a \in `[a, b] /\ b \in `[a, b] byrewrite !bound_itvE.
case: ltgtP faLfb => // [faLfb _|-> _ _ _ /itvxxP-> /itvxxP->]; rewrite?lexx//.
have lt_ab : a < b bycase: (ltgtP a b) aLb faLfb => // ->; rewrite ltxx.
have w : existsxy, [/\ x \in `[a, b], y \in `[a, b], x < y & f x <= f y].
byexistsa, b; rewrite !bound_itvE (ltW faLfb).
have fle := itv_continuous_inj_le w ctf (can_in_inj fK).
move=> x y xin yin; have := IVT aLb ctf.
case: (ltrgtP (f a) (f b)) faLfb => // _ _ ivt.
byhave [[u uin <-] [v vin <-]] := (ivt _ xin, ivt _ yin); rewrite !fK// !fle.
Qed.
Sectionnegation_itv.
Local DefinitionitvN_opprab := @GRing.opp R.
Local Lemmaitv_oppr_is_funab :
IsFun _ _ `[- b, - a]%classic `[a, b]%classic (itvN_oppr a b).
Proof. bysplit=> x /=; rewrite oppr_itvcc. Qed.
HB.instance Definition_ab := itv_oppr_is_fun a b.
Endnegation_itv.
(* The condition "f b <= f a" is unnecessary---see seg...increasing above *)Lemmasegment_can_geabfg : a <= b ->
{within `[a, b], continuous f} ->
{in `[a, b], cancel f g} ->
{in `[f b, f a] &, {mono g : x y /~ x <= y}}.
Proof.
move=> aLb fC fK x y xfbfa yfbfa; rewrite -ler_opp2.
apply: (@segment_can_le (- b) (- a) (f \o -%R) (- g));
rewrite /= ?ler_opp2?opprK //.
pose fun_neg : subspace `[-b,-a] -> subspace `[a,b] := itvN_oppr a b.
move=> z; apply: (@continuous_comp _ _ _ [funoffun_neg]); lastexact: fC.
exact/subspaceT_continuous/continuous_subspaceT/opp_continuous.
bymove=> z zab; rewrite -[- g]/(@GRing.opp _ \o g)/= fK ?opprK// oppr_itvcc.
Qed.
Lemmasegment_can_monoabfg : a <= b ->
{within `[a, b], continuous f} -> {in `[a, b], cancel f g} ->
monotonous (f @`[a, b]) g.
Proof.
move=> le_ab fct fK; rewrite /monotonous/=; case: ltrgtP => fab; [left|right..];
do?by [apply: segment_can_le|apply: segment_can_ge].
bymove=> x y /itvxxP<- /itvxxP<-; rewrite !lexx.
Qed.
Lemmasegment_continuous_surjectiveabf : a <= b ->
{within `[a, b], continuous f} -> set_surj `[a, b] (f @`[a, b]) f.
Proof. bymove=> ? fct y/= /IVT[]// x; existsx. Qed.
Lemmasegment_continuous_le_surjectiveabf : a <= b -> f a <= f b ->
{within `[a, b], continuous f} -> set_surj `[a, b] `[f a, f b] f.
Proof.
move=> le_ab f_ab /(segment_continuous_surjective le_ab).
byrewrite (min_idPl _)// (max_idPr _).
Qed.
Lemmasegment_continuous_ge_surjectiveabf : a <= b -> f b <= f a ->
{within `[a, b], continuous f} -> set_surj `[a, b] `[f b, f a] f.
Proof.
move=> le_ab f_ab /(segment_continuous_surjective le_ab).
byrewrite (min_idPr _)// (max_idPl _).
Qed.
Lemmacontinuous_inj_image_segmentabf : a <= b ->
{within `[a, b], continuous f} -> {in `[a, b] &, injective f} ->
f @` `[a, b] = f @`[a, b]%classic.
Proof.
move=> leab fct finj; apply: mono_surj_image_segment => //.
exact: itv_continuous_inj_mono.
exact: segment_continuous_surjective.
Qed.
Lemmacontinuous_inj_image_segmentPabf : a <= b ->
{within `[a, b], continuous f} -> {in `[a, b] &, injective f} ->
forally, reflect (exists2 x, x \in `[a, b] & f x = y) (y \in f @`[a, b]).
Proof.
move=> /continuous_inj_image_segment/[apply]/[apply]/predeqP + y => /(_ y) faby.
byapply/(equivP idP); symmetry.
Qed.
Lemmasegment_continuous_can_symabfg : a <= b ->
{within `[a, b], continuous f} -> {in `[a, b], cancel f g} ->
{in f @`[a, b], cancel g f}.
Proof.
move=> aLb ctf fK; have g_mono := segment_can_mono aLb ctf fK.
have f_mono := itv_continuous_inj_mono ctf (can_in_inj fK).
have f_surj := segment_continuous_surjective aLb ctf.
have fIP := mono_surj_image_segmentP aLb f_mono f_surj.
suff: {in f @`[a, b], {on `[a, b], cancel g & f}}.
bymove=> gK _ /fIP[x xab <-]; rewrite fK.
have: {in f @`[a, b] &, {on `[a, b] &, injective g}}.
bymove=> _ _ /fIP [x xab <-] /fIP[y yab <-]; rewrite !fK// => _ _ ->.
byapply/ssrbool.inj_can_sym_in_on => x xab; rewrite?fK?mono_mem_image_segment.
Qed.
Lemmasegment_continuous_le_can_symabfg : a <= b ->
{within `[a, b], continuous f} -> {in `[a, b], cancel f g} ->
{in `[f a, f b], cancel g f}.
Proof.
move=> aLb fct fK x xfafb; apply: (segment_continuous_can_sym aLb fct fK).
have : f a <= f b byrewrite (itvP xfafb).
bycase: ltrgtP xfafb => // ->.
Qed.
Lemmasegment_continuous_ge_can_symabfg : a <= b ->
{within `[a, b], continuous f} -> {in `[a, b], cancel f g} ->
{in `[f b, f a], cancel g f}.
Proof.
move=> aLb fct fK x xfafb; apply: (segment_continuous_can_sym aLb fct fK).
have : f a >= f b byrewrite (itvP xfafb).
bycase: ltrgtP xfafb => // ->.
Qed.
Lemmasegment_inc_surj_continuousabf :
{in `[a, b] &, {mono f : x y / x <= y}} -> set_surj `[a, b] `[f a, f b] f ->
{within `[a, b], continuous f}.
Proof.
move=> fle f_surj; have [f_inj flt] := (inc_inj_in fle, leW_mono_in fle).
have [aLb|bLa|] := ltgtP a b; firstlast.
- bymove=> ->; rewrite set_itv1; exact: continuous_subspace1.
- rewrite continuous_subspace_in => z /set_mem /=; rewrite in_itv /=.
bymove=> /andP[/le_trans] /[apply]; rewrite leNgt bLa.
have le_ab : a <= b byrewrite ltW.
have [aab bab] : a \in `[a, b] /\ b \in `[a, b] byrewrite !bound_itvE ltW.
have fab : f @` `[a, b] = `[f a, f b]%classic byexact:inc_surj_image_segment.
pose g := pinv `[a, b] f; have fK : {in `[a, b], cancel f g}.
byrewrite -[mem _]mem_setE; apply: pinvKV; rewrite !mem_setE.
have gK : {in `[f a, f b], cancel g f} bymove=> z zab; rewrite pinvK// fab inE.
have gle : {in `[f a, f b] &, {mono g : x y / x <= y}}.
apply: can_mono_in (fle); firstbymove=> *; rewrite gK.
move=> z zfab; have {zfab} : `[f a, f b]%classic z by [].
byrewrite -fab => -[x xab <-]; rewrite fK.
have glt := leW_mono_in gle.
rewrite continuous_subspace_in => x xab.
have xabcc : x \in `[a, b] bymove: xab; rewrite mem_setE.
have fxab : f x \in `[f a, f b] byrewrite in_itv/= !fle.
have := xabcc; rewrite in_itv //= => /andP [ax xb].
apply/cvgrPdist_lt => _ /posnumP[e]; rewrite !near_simpl; near=> y.
rewrite (@le_lt_trans _ _ (e%:num / 2%:R))//; last first.
byrewrite ltr_pdivr_mulr// ltr_pmulr// ltr1n.
rewrite ler_distlC; near: y.
pose u := minr (f x + e%:num / 2) (f b).
pose l := maxr (f x - e%:num / 2) (f a).
have ufab : u \in `[f a, f b].
rewrite !in_itv /= le_minl ?le_minr lexx ?fle // le_ab orbT ?andbT.
byrewrite ler_paddr // fle.
have lfab : l \in `[f a, f b].
rewrite !in_itv/= le_maxl ?le_maxr lexx ?fle// le_ab orbT ?andbT.
byrewrite ler_subl_addr ler_paddr// fle // lexx.
have guab : g u \in `[a, b].
rewrite !in_itv; apply/andP; split; have := ufab; rewrite in_itv => /andP.
bycase; rewrite /= -gle // ?fK // bound_itvE fle.
bycase => _; rewrite /= -gle // ?fK // bound_itvE fle.
have glab : g l \in `[a, b].
rewrite !in_itv; apply/andP; split; have := lfab; rewrite in_itv /= => /andP.
bycase; rewrite -gle // ?fK // bound_itvE fle.
bycase => _; rewrite -gle // ?fK // bound_itvE fle.
have faltu : f a < u.
rewrite /u comparable_lt_minr ?real_comparable?num_real// flt// aLb andbT.
byrewrite (@le_lt_trans _ _ (f x)) ?fle// ltr_addl.
have lltfb : l < f b.
rewrite /u comparable_lt_maxl ?real_comparable?num_real// flt// aLb andbT.
byrewrite (@lt_le_trans _ _ (f x)) ?fle// ltr_subl_addr ltr_addl.
case: pselect => // _; rewrite near_withinE; near_simpl.
have Fnbhs : Filter (nbhs x) byapply: nbhs_filter.
have := ax; rewrite le_eqVlt => /orP[/eqP|] {}ax.
near=> y => /[dup] yab; rewrite /= in_itv => /andP[ay yb]; apply/andP; split.
byrewrite (@le_trans _ _ (f a)) ?fle// ler_subl_addr ax ler_paddr.
apply: ltW; suff : f y < u byrewrite lt_minr => /andP[->].
rewrite -?[f y < _]glt// ?fK//; lastbyrewrite in_itv /= !fle.
by near: y; near_simpl; apply: open_lt; rewrite /= -flt ?gK// -ax.
have := xb; rewrite le_eqVlt => /orP[/eqP {}xb {ax}|{}xb].
near=> y => /[dup] yab; rewrite /= in_itv /= => /andP[ay yb].
apply/andP; split; lastbyrewrite (@le_trans _ _ (f b)) ?fle// xb ler_paddr.
apply: ltW; suff : l < f y byrewrite lt_maxl => /andP[->].
rewrite -?[_ < f y]glt// ?fK//; lastbyrewrite in_itv /= !fle.
by near: y; near_simpl; apply: open_gt; rewrite /= -flt// gK// xb.
have xoab : x \in `]a, b[ byrewrite in_itv /=; apply/andP; split.
near=> y; suff: l <= f y <= u.
byrewrite le_maxl le_minr -!andbA => /and4P[-> _ ->].
have ? : y \in `[a, b] byapply: subset_itv_oo_cc; near: y; apply: near_in_itv.
have fyab : f y \in `[f a, f b] byrewrite in_itv/= !fle// ?ltW.
rewrite -[l <= _]gle -?[_ <= u]gle// ?fK //.
apply: subset_itv_oo_cc; near: y; apply: near_in_itv; rewrite in_itv /=.
rewrite -[x]fK // !glt//= lt_minr lt_maxl ?andbT ltr_subl_addr ltr_spaddr //.
byapply/and3P; split; rewrite // flt.
Unshelve. all: by end_near. Qed.
Lemmasegment_dec_surj_continuousabf :
{in `[a, b] &, {mono f : x y /~ x <= y}} ->
set_surj `[a, b] `[f b, f a] f ->
{within `[a, b], continuous f}.
Proof.
move=> fge f_surj; suff: {within `[a, b], continuous (- f)}.
move=> contNf x xab; rewrite -[f]opprK.
exact/continuous_comp/opp_continuous/contNf.
apply: segment_inc_surj_continuous.
bymove=> x y xab yab; rewrite ler_opp2 fge.
bymove=> y /=; rewrite -oppr_itvcc => /f_surj[x ? /(canLR opprK)<-]; existsx.
Qed.
Lemmasegment_mono_surj_continuousabf :
monotonous `[a, b] f -> set_surj `[a, b] (f @`[a, b]) f ->
{within `[a, b], continuous f}.
Proof.
rewrite continuous_subspace_in => -[fle|fge] f_surj x /set_mem /= xab.
have leab : a <= b byrewrite (itvP xab).
have fafb : f a <= f b byrewrite fle // ?bound_itvE.
byapply: segment_inc_surj_continuous => //; case: ltrP f_surj fafb.
have leab : a <= b byrewrite (itvP xab).
have fafb : f b <= f a byrewrite fge // ?bound_itvE.
byapply: segment_dec_surj_continuous => //; case: ltrP f_surj fafb.
Qed.
Lemmasegment_can_le_continuousabfg : a <= b ->
{within `[a, b], continuous f} ->
{in `[a, b], cancel f g} ->
{within `[(f a), (f b)], continuous g}.
Proof.
move=> aLb ctf; rewrite continuous_subspace_in => fK x /set_mem /= xab.
have faLfb : f a <= f b byrewrite (itvP xab).
apply: segment_inc_surj_continuous; firstexact: segment_can_le.
rewrite !fK ?bound_itvE//=; apply: (@can_surj _ _ f); firstbyrewrite mem_setE.
exact/image_subP/mem_inc_segment/segment_continuous_inj_le/(can_in_inj fK).
Qed.
Lemmasegment_can_ge_continuousabfg : a <= b ->
{within `[a, b], continuous f} ->
{in `[a, b], cancel f g} ->
{within `[(f b), (f a)], continuous g}.
Proof.
move=> aLb ctf; rewrite continuous_subspace_in => fK x /set_mem /= xab.
have fbLfa : f b <= f a byrewrite (itvP xab).
apply: segment_dec_surj_continuous; firstexact: segment_can_ge.
rewrite !fK ?bound_itvE//=; apply: (@can_surj _ _ f); firstbyrewrite mem_setE.
exact/image_subP/mem_dec_segment/segment_continuous_inj_ge/(can_in_inj fK).
Qed.
Lemmasegment_can_continuousabfg : a <= b ->
{within `[a, b], continuous f} ->
{in `[a, b], cancel f g} ->
{within f @`[a, b], continuous g}.
Proof.
move=> aLb crf fK x; case: lerP => // _;
by [apply: segment_can_ge_continuous|apply: segment_can_le_continuous].
Qed.
Lemmanear_can_continuousAcan_symfg (x : R) :
{near x, cancel f g} -> {near x, continuous f} ->
{near f x, continuous g} /\ {near f x, cancel g f}.
Proof.
move=> fK fct; near (0 : R)^'+ => e; have e_gt0 : 0 < e by [].
have xBeLxDe : x - e <= x + e byrewrite ler_add2l gt0_cp.
have fcte : {in `[x - e, x + e], continuous f}.
by near: e; apply/at_right_in_segment.
have fwcte : {within `[x - e, x + e], continuous f}.
apply: continuous_in_subspaceT => y yI.
byapply: fcte; move/set_mem: yI.
have fKe : {in `[x - e, x + e], cancel f g}
by near: e; apply/at_right_in_segment.
have nearfx : \forally \near f x, y \in f @`](x - e), (x + e)[.
apply: near_in_itv; apply: mono_mem_image_itvoo; last first.
byrewrite in_itv/= -ltr_distlC subrr normr0.
apply: itv_continuous_inj_mono => //.
byapply: (@can_in_inj _ _ _ _ g); near: e; apply/at_right_in_segment.
have fxI : f x \in f @`]x - e, x + e[ byexact: (nbhs_singleton nearfx).
split; near=> y; firstlast.
rewrite (@segment_continuous_can_sym (x - e) (x + e))//.
byapply: subset_itv_oo_cc; near: y.
near: y; apply: (filter_app _ _ nearfx); near_simpl; near=> y => yfe.
have : {within f @`]x - e, (x + e)[, continuous g}.
apply: continuous_subspaceW; lastexact: (segment_can_continuous _ fwcte _).
exact: subset_itv_oo_cc.
rewrite continuous_open_subspace; firstbyapply; exact: mem_set.
exact: interval_open.
Unshelve. all: by end_near. Qed.
Lemmanear_can_continuousfg (x : R) :
{near x, cancel f g} -> {near x, continuous f} -> {near f x, continuous g}.
Proof. bymove=> fK fct; have [] := near_can_continuousAcan_sym fK fct. Qed.
Lemmanear_continuous_can_symfg (x : R) :
{near x, continuous f} -> {near x, cancel f g} -> {near f x, cancel g f}.
Proof. bymove=> fct fK; have [] := near_can_continuousAcan_sym fK fct. Qed.
Endreal_inverse_functions.
Sectionreal_inverse_function_instances.
VariableR : realType.
Lemmaexprn_continuousn : continuous (@GRing.exp R ^~ n).
Proof.
move=> x; elim: n=> [|n /(continuousM cvg_id) ih]; firstexact: cst_continuous.
byrewrite exprS; under eq_fun dorewrite exprS; exact: ih.
Qed.
Lemmasqr_continuous : continuous (@exprz R ^~ 2).
Proof. exact: (@exprn_continuous 2%N). Qed.
Lemmasqrt_continuous : continuous (@Num.sqrt R).
Proof.
move=> x; case: (ltrgtP x 0) => [xlt0 | xgt0 | ->].
- apply: (near_cst_continuous 0).
by near dorewrite ltr0_sqrtr//; apply: (cvgr_lt x).
pose I b : set R := [set` `]0 ^+ 2, b ^+ 2[].
suff main b : 0 <= b -> {in I b, continuous (@Num.sqrt R)}.
near +oo_R => M; apply: (main M); rewrite // /I !inE/= in_itv/= expr0n xgt0.
byrewrite -ltr_sqrt ?exprn_gt0// sqrtr_sqr gtr0_norm/=.
move=> b0; rewrite -continuous_open_subspace; lastexact: interval_open.
apply: continuous_subspaceW; firstexact: subset_itv_oo_cc.
apply: (@segment_can_le_continuous _ _ _ (@GRing.exp _^~ _)) => //.
byapply: continuous_subspaceT; exact: exprn_continuous.
bymove=> y y0b; rewrite sqrtr_sqr ger0_norm// (itvP y0b).
- rewrite sqrtr0; apply/cvgr0Pnorm_lt => _ /posnumP[e]; near=> y.
have [ylt0|yge0] := ltrP y 0; firstbyrewrite ltr0_sqrtr ?normr0.
rewrite ger0_norm ?sqrtr_ge0//; have: `|y| < e%:num ^+ 2by [].
byrewrite -ltr_sqrt// ger0_norm// sqrtr_sqr ger0_norm.
Unshelve. all: by end_near. Qed.
Endreal_inverse_function_instances.
Sectionis_derive_inverse.
VariableR : realType.
(* Attempt to prove the diff of inverse *)Lemmais_derive1_caratheodory (f : R -> R) (xa : R) :
is_derive x 1 f a <->
existsg, [/\ forallz, f z - f x = g z * (z - x),
{for x, continuous g} & g x = a].
Proof.
split => [Hd|[g [fxE Cg gxE]]].
exists (funz => if z == x then a else (f(z) - f(x)) / (z - x)); split.
- move=> z; case: eqP => [->|/eqP]; firstbyrewrite !subrr mulr0.
byrewrite -subr_eq0 => /divfK->.
- apply/continuous_withinNshiftx; rewrite eqxx /=.
pose g1 h := (h^-1 *: ((f \o shift x) h%:A - f x)).
have F1 : g1 @ 0^' --> a bycase: Hd => H1 <-.
apply: cvg_trans F1; apply: near_eq_cvg; rewrite /g1 !fctE.
near=> i.
rewrite ifN; firstbyrewrite addrK mulrC /= [_%:A]mulr1.
rewrite -subr_eq0 addrK.
by near: i; rewrite near_withinE /= near_simpl; near=> x1.
byrewrite eqxx.
suff Hf : h^-1 *: ((f \o shift x) h%:A - f x) @[h --> 0^'] --> a.
have F1 : 'D_1 f x = a byapply: cvg_lim.
rewrite -F1 in Hf.
byconstructor.
have F1 : (g \o shift x) y @[y --> 0^'] --> a.
byrewrite -gxE; apply/continuous_withinNshiftx.
apply: cvg_trans F1; apply: near_eq_cvg.
near=> y.
rewrite /= fxE /= addrK [_%:A]mulr1.
suff yNZ : y != 0byrewrite [RHS]mulrC mulfK.
by near: y; rewrite near_withinE /= near_simpl; near=> x1.
Unshelve. all: by end_near. Qed.
Lemmais_derive_0_is_cst (f : R -> R) xy :
(forallx, is_derive x 1 f 0) -> f x = f y.
Proof.
move=> Hd.
wlog xLy : x y / x <= y bymove=> H; case: (leP x y) => [/H |/ltW /H].
rewrite -(subKr (f y) (f x)).
have [| _ _] := MVT_segment xLy; lastbyrewrite mul0r => ->; rewrite subr0.
apply/continuous_subspaceT=> r.
exact/differentiable_continuous/derivable1_diffP.
Qed.
Global Instanceis_derive1_comp (fg : R -> R) (xab : R) :
is_derive (g x) 1 f a -> is_derive x 1 g b ->
is_derive x 1 (f \o g) (a * b).
Proof.
move=> [fgxv <-{a}] [gv <-{b}]; apply: (@DeriveDef _ _ _ _ _ (f \o g)).
apply/derivable1_diffP/differentiable_comp; firstexact/derivable1_diffP.
bymove/derivable1_diffP in fgxv.
byrewrite -derive1E (derive1_comp gv fgxv) 2!derive1E.
Qed.
Lemmais_deriveV (f : R -> R) (xtv : R) :
f x != 0 -> is_derive x v f t ->
is_derive x v (funy => (f y)^-1) (- (f x) ^- 2 *: t).
Proof.
move=> fxNZ Df.
constructor; firstbyapply: derivableV => //; case: Df.
byrewrite deriveV //; case: Df => _ ->.
Qed.
Lemmais_derive_inverse (fg : R -> R) lx :
{near x, cancel f g} ->
{near x, continuous f} ->
is_derive x 1 f l -> l != 0 -> is_derive (f x) 1 g l^-1.
Proof.
move=> fgK fC fD lNZ.
have /is_derive1_caratheodory [h [fE hC hxE]] := fD.
(* There should be something simpler *)have gfxE : g (f x) = x byhave [d Hd]:= nbhs_ex fgK; apply: Hd.
pose g1 y := if y == f x then (h (g y))^-1else (g y - g (f x)) / (y - f x).
apply/is_derive1_caratheodory.
existsg1; split; first2last.
- byrewrite /g1 eqxx gfxE hxE.
- move=> z; rewrite /g1; case: eqP => [->|/eqP]; firstbyrewrite !subrr mulr0.
byrewrite -subr_eq0 => /divfK.
have F1 : (h (g x))^-1 @[x --> f x] --> g1 (f x).
rewrite /g1 eqxx; apply: continuousV; firstbyrewrite /= gfxE hxE.
apply: continuous_comp; lastbyrewrite gfxE.
byapply: nbhs_singleton (near_can_continuous _ _).
apply: cvg_sub0 F1.
apply/cvgrPdist_lt => eps eps_gt0 /=; rewrite !near_simpl /=.
near=> y; rewrite sub0r normrN !fctE.
have fgyE : f (g y) = y by near: y; apply: near_continuous_can_sym.
rewrite /g1; case: eqP => [_|/eqP x1Dfx]; firstbyrewrite subrr normr0.
have -> : y - f x = h (g y) * (g y - x) byrewrite -fE fgyE.
rewrite gfxE invfM mulrC divfK ?subrr?normr0 // subr_eq0.
byapply: contra x1Dfx => /eqP<-; apply/eqP.
Unshelve. all: by end_near. Qed.
Endis_derive_inverse.
#[global] Hint Extern0 (is_derive _ _ (fun_ => (_ _)^-1) _) =>
(eapply is_deriveV; firstby []) : typeclass_instances.