diff --git a/CHANGELOG_UNRELEASED.md b/CHANGELOG_UNRELEASED.md index 2d85fdc0a5..f7dbae9655 100644 --- a/CHANGELOG_UNRELEASED.md +++ b/CHANGELOG_UNRELEASED.md @@ -126,6 +126,8 @@ - in `filter.v`: + mixin `isSubNbhs`, structure `SubNbhs`, notation `subNbhsType` + + new lemmas `near_eq_cvgE`, `near_eq_is_cvg`, `near_eq_lim`, + `cvg_to_eq`, `cvg_to_withinP`, and `within_cvg_to_within`. - in `topology_structure.v`: + structure `SubTopological`, notation `subTopologicalType` @@ -234,6 +236,35 @@ - in `measurable_structure.v`: + lemmas `countable_bigcap_measurable`, `countable_bigcup_measurable` + +- in file `function_spaces.v`, + + new lemma `within_continuous_big`. +- in file `nat_topology.v`, + + new lemma `near_infty_after`. +- in file `num_topology.v`, + + new lemmas `at_rightD`, `at_leftD`, `near_at_rightD`, `near_at_leftD`, + `at_left_shift`, `at_right_shift`, `near_right_in_itv`, and `near_left_in_itv`. + +- in file `num_normedtype.v`, + + new lemmas `pinftyV`, `ninftyV`, `cvgryV`, `cvgrNyV`, `lt0_cvgMlNy`, + `lt0_cvgMrNy`, `lt0_cvgMly`, and `lt0_cvgMry`. +- in file `normed_module.v`, + + new lemmas `cvg1MC`, `cvg1M`, `cvgCM1`, `cvgM1`, `cvg0MC`, `cvg0M`, + `cvgCM0`, and `cvgM0`. +- in file `pseudometric_normed_Zmodule.v`, + + new lemmas `cvgDl`, `cvgDr`, `cvgBl`, `cvgBr`, `cvg0D`, `cvg0DC`, + `cvgD0`, `cvgCD0`, `cvg0B`, `cvg0BC`, `cvgB0`, `cvgCB0`, `cvgN0`, `fmap_at_left0P`, and `fmap_at_right0E`. +- in file `tvs.v`, + + new lemmas `near_shiftE`, and `nearZE`. + +- in `derive.v` + + new lemmas `derive1Dn`, `der1_scaleLR`, `deriveZLR`, `derivableZLR`, + `derivable_shiftf`, `derive_shiftf`, `is_derive_shiftf`, `derive1_shiftf`, + `near_eq_derive1n_near`, `near_eq_derive1_near`, `near_eq_derive1n`, and + `near_eq_derive1`, `right_derivative_limit`, `left_derivative_limit`, and + `dnbhs_derivative_limit`. + + new theorem `derivative_limit_theorem`. + ### Changed - in `realsum.v`: @@ -354,6 +385,11 @@ - in `classical_sets.v` + lemma `bigcupDr` -> `setD_bigcupr` (deprecating `bigcupDr`) +- moved from `realfun.v` to `derive.v`: + + lemmas `is_deriveV`, `is_derive1_comp`. +- moved from `metric_structure.v` to `num_topology.v`: + + lemma `cvg_at_right_left_dnbhs`, generalized to `topologicalType` from `metricType`. + ### Renamed - in `tvs.v`: diff --git a/classical/filter.v b/classical/filter.v index b26d00d72f..4233a6d9bc 100644 --- a/classical/filter.v +++ b/classical/filter.v @@ -925,10 +925,23 @@ Lemma near_eq_cvg {T U} {F : set_system T} {FF : Filter F} (f g : T -> U) : {near F, f =1 g} -> g @ F `=>` f @ F. Proof. by move=> eq_fg P /=; apply: filterS2 eq_fg => x /= <-. Qed. +Lemma near_eq_cvgE {T U} {F : set_system T} {FF : Filter F} (f g : T -> U) : + {near F, f =1 g} -> f @ F = g @ F. +Proof. +move=> eq_fg. +apply/seteqP; split; apply: near_eq_cvg => //. +by near do symmetry. +Unshelve. all: by end_near. +Qed. + Lemma eq_cvg (T T' : Type) (F : set_system T) (f g : T -> T') (x : set_system T') : f =1 g -> (f @ F --> x) = (g @ F --> x). Proof. by move=> /funext->. Qed. +Lemma near_eq_is_cvg (T : Type) (T' : pnbhsType) (F : set_system T) (f g : T -> T') : + Filter F -> {near F, g =1 f} -> cvg (f x @[x --> F]) -> cvg(g x @[x --> F]). +Proof. by move=> /@near_eq_cvgE /[apply] ->. Qed. + Lemma eq_is_cvg_in (T T' : Type) (fT : pfilteredType T') (F : set_system T) (f g : T -> T') : f =1 g -> [cvg (f @ F) in fT] = [cvg (g @ F) in fT]. Proof. by move=> /funext->. Qed. @@ -937,6 +950,14 @@ Lemma eq_is_cvg (T : Type) (T' : pnbhsType) (F : set_system T) (f g : T -> T') : f =1 g -> cvg (f @ F) = cvg (g @ F). Proof. by move=> /funext->. Qed. +Lemma near_eq_lim (T : Type) (T' : pnbhsType) {F : set_system T} {FF : Filter F} (f g : T -> T') : + {near F, f =1 g} -> lim (f @ F) = lim (g @ F). +Proof. by move=> /near_eq_cvgE ->. Qed. + +Lemma cvg_to_eq {T : nbhsType} {F : set_system T} (l l' : T) : + F --> l' -> l = l' -> F --> l. +Proof. by move=> + ->. Qed. + Lemma neari_eq_loc {T U} {F : set_system T} {FF : Filter F} (f g : T -> set U) : {near F, f =2 g} -> g `@ F `=>` f `@ F. Proof. @@ -1197,6 +1218,25 @@ Qed. End within. +Lemma cvg_to_withinP (T U : Type) {F : set_system T} {FF : Filter F} {G : set_system U} {FG : Filter G} + (f : T -> U) (A : set U) : + (f @ F --> within A G) <-> (f @ F --> G /\ \forall x \near F, A (f x)). +Proof. +split. + move=> cvg_w; split. + - apply: (cvg_trans cvg_w). + exact: cvg_within. + - apply: cvg_w. + exact: withinT. +move=> [cvgT nearfA] P. +rewrite !nbhs_nearE near_withinE. +move: cvgT => /[apply]. +rewrite near_map appfilter nbhs_nearE => nearF_AP. +near=> x. +suff : A (f x) by near: x. +by near: x. +Unshelve. all: by end_near. Qed. + Global Instance within_filter T D F : Filter F -> Filter (@within T D F). Proof. move=> FF; rewrite /within; constructor => /=. @@ -1210,6 +1250,18 @@ Qed. Canonical within_filter_on T D (F : filter_on T) := FilterType (within D F) (within_filter _ _). +Lemma within_cvg_to_within (T U : Type) {F : set_system T} {FF : Filter F} {G : set_system U} {FG : Filter G} + (f : T -> U) (A : set T) (B : set U) : + (\forall x \near F, A x -> B (f x)) -> f @ F --> G -> f @ within A F --> within B G. +Proof. +move=> near_hom cvgT. +apply/cvg_to_withinP; split. +- apply: cvg_trans cvgT. + apply: cvg_app. + exact: cvg_within. +- by rewrite near_withinE. +Qed. + Lemma filter_bigI_within T (I : choiceType) (D : {fset I}) (f : I -> set T) (F : set_system T) (P : set T) : Filter F -> (forall i, i \in D -> F [set j | P j -> f i j]) -> diff --git a/theories/derive.v b/theories/derive.v index 07a7aa7cab..5d49ccb5e7 100644 --- a/theories/derive.v +++ b/theories/derive.v @@ -408,6 +408,9 @@ Proof. by []. Qed. Lemma derive1Sn V (f : R -> V) n : f^`(n.+1) = f^`()^`(n). Proof. exact: iterSr. Qed. +Lemma derive1Dn V (f : R -> V) (i j : nat) : f^`(i + j) = f^`(j)^`(i). +Proof. by rewrite /derive1n iterD. Qed. + End DifferentialR2. Notation "f ^` ()" := (derive1 f) : classical_set_scope. Notation "f ^` ( n )" := (derive1n n f) : classical_set_scope. @@ -1254,6 +1257,58 @@ move=> dfx; apply: DeriveDef; first exact: derivableZ. by rewrite deriveZ // derive_val. Qed. +Lemma der1_scaleLR (k : R -> R) (f : R -> V) (x : R) : + derivable k x 1 -> derivable f x 1 -> + h^-1 *: (((fun x0 : R => k x0 *: f x0) \o shift x) h%:A - k x *: f x) + @[h --> 0^'] --> 'D_1 k x *: f x + k x *: 'D_1 f x. +Proof. +move=> der_k der_f. +rewrite /comp/=. +apply: cvg_trans. + apply: near_eq_cvg. + near=> h. + rewrite -[X in _ = _ *: X](addrKA (- (k x *: f (h%:A + x)))) opprD opprK. + rewrite -scalerBl -scalerBr scalerDr [in X in _ = X + _]scalerA. + by rewrite scalerA (mulrC h^-1 (k x)) -[in X in _ = _ + X]scalerA. +apply: cvgD. +- apply: cvgZ; first exact: der_k. + apply: (cvg_comp _ _ (G := nbhs x)). + + apply: cvg0DC. + apply: cvg0MC. + by apply: cvg_within_filter. + + change (continuous_at x f). + by apply/differentiable_continuous/derivable1_diffP. +- apply: cvgZl_tmp. + exact: der_f. +Unshelve. all: by end_near. Qed. + +Global Instance is_derive1ZLR (k : R -> R) (f : R -> V) (x dk : R) (df : V) : + is_derive x 1 k dk -> is_derive x 1 f df -> is_derive x 1 (fun x => k x *: f x) (dk *: f x + k x *: df). +Proof. +move=> [der_k vdk] [der_f vdf]. +constructor. +- apply: cvgP. + by apply: der1_scaleLR. +- apply: norm_cvg_lim. + apply: cvg_to_eq; first by apply: der1_scaleLR. + by rewrite vdk vdf. +Qed. + +Lemma deriveZLR (k : R -> R) (f : R -> V) (x : R) : + derivable k x 1 -> derivable f x 1 -> + 'D_1 (fun x => k x *: f x) x = 'D_1 k x *: f x + k x *: 'D_1 f x. +Proof. +move=> dk df. +by apply: derive_val; apply: is_derive1ZLR; apply: derivableP. +Qed. + +Lemma derivableZLR (k : R -> R) (f : R -> V) (x : R) : + derivable k x 1 -> derivable f x 1 -> derivable (fun x => k x *: f x) x 1. +Proof. +move=> dk df. +by apply: ex_derive; apply: is_derive1ZLR; apply: derivableP. +Qed. + Lemma derive_cst (k : W) (x v : V) : 'D_v (cst k) x = 0. Proof. by rewrite derive_val. Qed. @@ -1398,6 +1453,15 @@ move=> df dg; apply/cvg_ex; exists (- (f x) ^- 2 *: 'D_v f x). exact: der_inv. Qed. +Lemma is_deriveV f (x v : V) (df : R) : + f x != 0 -> is_derive x v f df -> + is_derive x v (fun y => (f y)^-1) (- (f x) ^- 2 *: df). +Proof. +move=> fxNZ Df. +constructor; first by apply: derivableV => //; case: Df. +by rewrite deriveV //; case: Df => _ ->. +Qed. + End Derive_lemmasVR. Lemma derive_shift {R : numFieldType} (v k : R) : @@ -1410,6 +1474,38 @@ Lemma is_derive_shift {R : numFieldType} x v (k : R) : is_derive x v (shift k) v. Proof. by apply: DeriveDef => //; rewrite derive_val addr0. Qed. +Section derive_shiftf. +Context (R : numFieldType) (V : normedModType R) (f : R -> V). +Implicit Types (x a v : R). + +Lemma derivable_shiftf x a v : + derivable f (x + a) v -> derivable (f \o shift a) x v. +Proof. +rewrite /derivable/=. +by under eq_is_cvg do rewrite addrA. +Qed. + +Lemma derive_shiftf x a v : + 'D_v (f \o shift a) x = 'D_v f (x + a). +Proof. + rewrite /derive/=. + by under [in RHS]eq_fun do rewrite addrA. +Qed. + +Lemma is_derive_shiftf x a (df : V) : + is_derive (x + a) 1 f df -> is_derive x 1 (f \o shift a) df. +Proof. + move=> [/derivable_shiftf derf +]. + rewrite -derive_shiftf => derf_val. + by constructor. +Qed. + +Lemma derive1_shiftf x a : + (f \o shift a)^`() x = f^`() (x + a). +Proof. by rewrite !derive1E derive_shiftf. Qed. + +End derive_shiftf. + Lemma derive1_cst {R : numFieldType} (V : normedModType R) (k : V) t : (cst k)^`() t = 0. Proof. by rewrite derive1E derive_cst. Qed. @@ -1440,6 +1536,10 @@ have /= := @deriveX R R id n x v (@derivable_id _ _ _ _). by rewrite fctE => ->; rewrite derive_id. Qed. +Global Instance is_derive_exp (R : numFieldType) n x v : + is_derive x v (@GRing.exp R ^~ n) (n%:R *: x ^+ n.-1 *: v). +Proof. by constructor; [ exact: exprn_derivable | exact: exp_derive ]. Qed. + Lemma exp_derive1 {R : numFieldType} n x : (@GRing.exp R ^~ n)^`() x = n%:R *: x ^+ n.-1. Proof. by rewrite derive1E exp_derive [LHS]mulr1. Qed. @@ -2068,6 +2168,15 @@ rewrite diff_comp // !derive1E' //= -[X in 'd _ _ X = _]mulr1. by rewrite [LHS]linearZ mulrC. Qed. +Global Instance is_derive1_comp (R : realFieldType) (f g : R -> R) (x a b : 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; first exact/derivable1_diffP. + by move/derivable1_diffP in fgxv. +by rewrite -derive1E (derive1_comp gv fgxv) 2!derive1E. +Qed. + Lemma near_eq_growth_rate (R : numFieldType) (V W : normedModType R) (f g : V -> W) (a v : V) : {near a, f =1 g} -> \forall h \near 0, @@ -2105,6 +2214,30 @@ move=> fg [fav <-]; rewrite (near_eq_derive _ fg). by apply: DeriveDef => //; exact: near_eq_derivable fav. Qed. +Lemma near_eq_derive1n_near (R : numFieldType) (V : normedModType R) (k : nat) (f g : R -> V) (x : R) : + {near x, f =1 g} -> {near x, f^`(k) =1 g^`(k)}. +Proof. +move=> near_eq. +elim: k => [//|k IH]. +near=> y. +rewrite !derive1nS !derive1E. +apply: near_eq_derive. +near: y. +by rewrite near_nbhs; apply: near_join. +Unshelve. all: by end_near. Qed. + +Lemma near_eq_derive1_near (R : numFieldType) (V : normedModType R) (f g : R -> V) (x : R) : + {near x, f =1 g} -> {near x, f^`() =1 g^`()}. +Proof. rewrite -!derive1n1; exact: near_eq_derive1n_near. Qed. + +Lemma near_eq_derive1n (R : numFieldType) (V : normedModType R) (k : nat) (f g : R -> V) (x : R) : + {near x, f =1 g} -> f^`(k) x = g^`(k) x. +Proof. by move/near_eq_derive1n_near => /(_ k) /nbhs_singleton. Qed. + +Lemma near_eq_derive1 (R : numFieldType) (V : normedModType R) (f g : R -> V) (x : R) : + {near x, f =1 g} -> f^`() x = g^`() x. +Proof. by rewrite -!derive1n1; exact: near_eq_derive1n. Qed. + Section Derive_max. Context {K : realType} {V W : normedModType K}. Implicit Types f g : V -> K^o. @@ -2507,3 +2640,231 @@ by rewrite diff_row_mx// !diff_val. Qed. End is_diff_row_mx. + +Section derivative_limit_theorem. +Context (R : realType). +Implicit Types (f df : R -> R) (a b : R). + +Fact MVT_choice_fun f df a b : + a < b -> + (forall x : R, x \in `]a, b[%R -> is_derive x 1 f (df x)) -> + {within `[a, b], continuous f} -> + { c : R -> R | forall (x : R), x \in `]a, b[%R -> + c x \in `]a, x[%R /\ f x - f a = df (c x) * (x - a) + }. +Proof. +move=> a_lt_b der_f cf. +suff [c hc] : { c : `]a, b[ -> R & forall (x : `]a, b[), + c x \in `]a, (\val x)[%R /\ f (\val x) - f a = df (c x) * (\val x - a) + }. + exists (fun x => + match (boolP (x \in `]a, b[)) with + | AltTrue hin => c (exist _ x hin) + | AltFalse _ => 0 + end + ). + move=> x x_ab. + move: (boolP (x \in `]a, b[)) => B. + destruct B as [hab|hNab]; last first. + move: hNab x_ab. + by rewrite notin_setE/=. + set X := (X in c X). + by have := hc X. +apply: (choice (P := fun x c => + c \in `]a, \val x[%R /\ f (\val x) - f a = df c * (\val x - a) +)). +move=> /= [x /= /set_mem/=]. +rewrite in_itv/= => /andP[a_lt_x x_lt_b]. +have der_f_x : forall (y : R), y \in `]a, x[%R -> is_derive y 1 f (df y). + move=> y y_ax. + apply: der_f. + move: y_ax. + rewrite !in_itv/= => /andP[-> /= /lt_trans]. + by apply. +have cf_x : {within `[a, x], continuous f}. + apply: continuous_subspaceW; last exact: cf. + apply: subset_itvl; rewrite bnd_simp. + by apply: ltW. +have [c c_ax hc_eq] := MVT a_lt_x der_f_x cf_x. +by exists c. +Qed. + +Lemma right_derivative_limit f df a (l : R) : + (\forall x \near a^'+, is_derive x (1 :> R) f (df x)) -> + df x @[x --> a^'+] --> l -> + f x @[x --> a^'+] --> f a -> + h^-1 *: (f (a + h) - f a) @[h --> 0^'+] --> l. +Proof. +move=> is_df df_cvg f_cvgl. +move: (is_df). +rewrite /prop_near1/= {1}/nbhs/= {1}/at_right/= /within/= -nbhs_nearE. +rewrite nbhs_simpl -filter_from_ballE /filter_from/= => -[M M_gt0 M_def]. +have := MVT_choice_fun (f := f) (df := df) (a := a) (b := a + M/2). +have M2_gt0 : M / 2 > 0 by apply: divr_gt0. +have M2_lt_M : M / 2 < M. + by rewrite ltr_pdivrMr// mulr_natr mulr2n ltrDl. +rewrite ltrDl => /(_ M2_gt0). +have itv_in_ball : `]a, a + M/2[ `<=` ball a M. + move=> x /=. + rewrite in_itv/= => /andP[a_lt_x x_lt_aM2]. + rewrite /ball/= ltr_distlC. + apply/andP; split. + - apply: lt_trans; last exact: a_lt_x. + by rewrite gtrBl. + - apply: lt_trans; first exact: x_lt_aM2. + by rewrite ltrD2l. +have /[swap] /[apply] : + forall x : R, x \in `]a, a + M/2[%R -> is_derive x 1 f (df x). + move=> x /[dup] x_itv. + rewrite in_itv => /andP[a_lt_x _]. + apply: M_def => //. + by apply: itv_in_ball. +have /[swap] /[apply] : {within `[a, a + M/2], continuous f}. + apply/continuous_within_itvP; first by rewrite ltrDl. + split=> //. + - move=> x /[dup]. + rewrite {1}in_itv/= => /andP[a_lt_x _]. + move=> /itv_in_ball /M_def /(_ a_lt_x) [+ _]. + by move/derivable1_diffP/differentiable_continuous. + - apply: cvg_at_left_filter. + apply: differentiable_continuous. + apply/derivable1_diffP. + apply: ex_derive. + apply: M_def; last by rewrite ltrDl. + by rewrite /ball/= opprD addNKr normrN gtr0_norm. +case=> [c c_def]. +apply: cvg_trans. + apply: near_eq_cvg. + near=> h. + move: (c_def (a + h)) => [|_ ->]. + rewrite in_itv/= ltrDl ltrD2l. + by apply/andP. + by rewrite ?(addrC _ (-a)) ?addKr /GRing.scale/= mulrC mulrK ?unitf_gt0. +apply: cvg_comp; last exact: df_cvg. +apply/cvg_to_withinP; split. +- apply: (squeeze_cvgr (f := fun=> a) (h := fun h => a + h)); last 2 first. + + exact: cvg_cst. + + apply: cvgCD0. + by apply: cvg_at_right_filter. + + near=> h. + move: c_def => /(_ (a + h)). + have /[swap] /[apply] : a + h \in `]a, a + M/2[%R. + rewrite in_itv/= ltrDl ltrD2l. + by apply/andP. + rewrite in_itv/= => -[/andP[c_gt c_lt] _]. + by apply/andP; split; apply: ltW. +- near=> h. + suff : a + h \in `]a, a + M/2[%R. + move/c_def => [+ _]. + by rewrite in_itv/= => /andP[]. + rewrite in_itv/= ltrDl ltrD2l. + by apply/andP. +Unshelve. all: by end_near. Qed. + +Lemma left_derivative_limit f df a (l : R) : + (\forall x \near a^'-, is_derive x (1 :> R) f (df x)) -> + df x @[x --> a^'-] --> l -> + f x @[x --> a^'-] --> f a -> + h^-1 *: (f (a + h) - f a) @[h --> 0^'-] --> l. +Proof. +move=> is_df_l df_cvg_l f_cvg_l. +pose f' x := f (a *+ 2 - x). +pose df' x := - df (a *+ 2 - x). +have a2Ba : -a + a *+ 2 = a by rewrite mulr2n addKr. +have := right_derivative_limit (f := f') (df := df') (a := a) (l := -l). +have /[swap] /[apply] : \forall x \near a^'+, is_derive x (1 :> R) f' (df' x). + rewrite -a2Ba near_at_rightD at_rightN near_map. + near=> x. + rewrite /f' /df'. + apply: (near_eq_is_derive (f := f \o -%R \o center (a *+ 2))). + apply: (nearW (F := nbhs (-x + a*+2))) => y /=. + by rewrite opprB. + apply: is_derive_shiftf. + rewrite addrK addrC opprD subrK opprK. + apply: is_derive_eq. + apply: (is_derive1_comp (a := (df x))); last exact: is_deriveNid. + rewrite opprK. + by near: x. + by rewrite mulrN1. +have /[swap] /[apply] : df' x @[x --> a^'+] --> -l. + rewrite /df'. + apply: cvgN. + rewrite -{2}a2Ba at_rightD at_rightN -!fmap_comp. + apply: cvg_trans; last exact: df_cvg_l. + apply: near_eq_cvg. + near=> x => /=. + by rewrite addrC opprD opprK subrK. +have /[swap] /[apply] : f' x @[x --> a^'+] --> f' a. + rewrite /f' -{2}a2Ba at_rightD at_rightN -!fmap_comp (addrC _ (-a)) a2Ba. + apply: cvg_trans; last exact: f_cvg_l. + apply: near_eq_cvg. + near=> x => /=. + by rewrite addrC opprD opprK subrK. +rewrite -{1}oppr0 at_rightN -fmap_comp/= => /cvgN. +rewrite opprK. +apply: cvg_trans. +apply: near_eq_cvg. +near=> h. +rewrite fctE/= invrN scaleNr opprK /f' (addrC _ (-a)) a2Ba. +congr (_ *: (f _ - _)). +by rewrite addrC opprB -addrA a2Ba addrC. +Unshelve. all: by end_near. +Qed. + +Lemma dnbhs_derivative_limit f df a (l : R) : + (\forall x \near a^', is_derive x (1 :> R) f (df x)) -> + df x @[x --> a^'] --> l -> + {for a, continuous f} -> + h^-1 *: (f (a + h) - f a) @[h --> 0^'] --> l. +Proof. +move=> is_df df_cvg cf. +have gt_sub_neq : [set u : R | a < u] `<=` [set u : R | u != a]. + move=> u /= a_lt_u. + by rewrite neq_lt a_lt_u orbT. +have lt_sub_neq : [set u : R | u < a] `<=` [set u : R | u != a]. + move=> u /= u_lt_a. + by rewrite neq_lt u_lt_a. +apply: cvg_at_right_left_dnbhs. +- apply: (right_derivative_limit (df := df)). + + move: is_df. + rewrite -!nbhs_nearE/= /nbhs/= /dnbhs /at_right/=. + by apply: within_subset. + + move: df_cvg. + apply: cvg_trans. + apply: cvg_app. + by apply: within_subset. + + move: cf. + apply: cvg_trans. + apply: cvg_app. + exact: cvg_within. +- apply: (left_derivative_limit (df := df)). + + move: is_df. + rewrite -!nbhs_nearE/= /nbhs/= /dnbhs /at_left/=. + by apply: within_subset. + + move: df_cvg. + apply: cvg_trans. + apply: cvg_app. + by apply: within_subset. + + move: cf. + apply: cvg_trans. + apply: cvg_app. + exact: cvg_within. +Qed. + +Theorem derivative_limit_theorem f df a (l : R) : + (\forall x \near a^', is_derive x (1 :> R) f (df x)) -> + df x @[x --> a^'] --> l -> + {for a, continuous f} -> + is_derive a (1 :> R) f l. +Proof. +move=> is_df df_cvg cf. +constructor. +- apply: cvgP. + under eq_cvg do rewrite /comp/= scaler1 (addrC _ a). + by apply: (dnbhs_derivative_limit (df := df) (l := l)). +- apply: norm_cvg_lim. + under eq_cvg do rewrite /comp/= scaler1 (addrC _ a). + by apply: (dnbhs_derivative_limit (df := df) (l := l)). +Qed. + +End derivative_limit_theorem. \ No newline at end of file diff --git a/theories/normedtype_theory/normed_module.v b/theories/normedtype_theory/normed_module.v index 1252178b3f..94a72d0f8e 100644 --- a/theories/normedtype_theory/normed_module.v +++ b/theories/normedtype_theory/normed_module.v @@ -642,6 +642,30 @@ Proof. exact: cvgZr_tmp. Qed. Lemma cvgMl_tmp g a b : g @ F --> b -> a * g x @[x --> F] --> a * b. Proof. exact: cvgZl_tmp. Qed. +Lemma cvg1MC f a : f @ F --> (1 :> K) -> f x * a @[x --> F] --> a. +Proof. by move/(cvgMr_tmp (b := a)); rewrite mul1r. Qed. + +Lemma cvg1M f g a : f @ F --> (1 :> K) -> g @ F --> a -> f \* g @ F --> a. +Proof. by move=> /cvgM /[apply]; rewrite mul1r. Qed. + +Lemma cvgCM1 f a : f @ F --> (1 :> K) -> a * f x @[x --> F] --> a. +Proof. by move/(cvgMl_tmp (a := a)); rewrite mulr1. Qed. + +Lemma cvgM1 f g a : f @ F --> a -> g @ F --> (1 :> K) -> f \* g @ F --> a. +Proof. by move=> /cvgM /[apply]; rewrite mulr1. Qed. + +Lemma cvg0MC f a : f @ F --> 0 -> f x * a @[x --> F] --> 0. +Proof. by move/(cvgMr_tmp (b := a)); rewrite mul0r. Qed. + +Lemma cvg0M f g a : f @ F --> 0 -> g @ F --> a -> f \* g @ F --> 0. +Proof. by move=> /cvgM /[apply]; rewrite mul0r. Qed. + +Lemma cvgCM0 f a : f @ F --> 0 -> a * f x @[x --> F] --> 0. +Proof. by move/(cvgMl_tmp (a := a)); rewrite mulr0. Qed. + +Lemma cvgM0 f g a : f @ F --> a -> g @ F --> 0 -> f \* g @ F --> 0. +Proof. by move=> /cvgM /[apply]; rewrite mulr0. Qed. + Lemma is_cvgM f g : cvg (f @ F) -> cvg (g @ F) -> cvg (f \* g @ F). Proof. exact: is_cvgZ. Qed. diff --git a/theories/normedtype_theory/num_normedtype.v b/theories/normedtype_theory/num_normedtype.v index 9457d67f93..9b8c182fd2 100644 --- a/theories/normedtype_theory/num_normedtype.v +++ b/theories/normedtype_theory/num_normedtype.v @@ -245,6 +245,53 @@ apply/seteqP; split => [A [M [Mreal MA]]|A [M [Mreal MA]]]. by exists (- M); rewrite ?realN; split=> // x; rewrite ltrNl => /MA. Qed. +Lemma pinftyV (R : numFieldType) : x^-1 @[x --> +oo] = (0 : R)^'+. +Proof. +apply/seteqP; split=> [A [M [Mreal MA]]|A [r /= r0 rA]]. +- have mM1_gt0 : 0 < Num.max M 1. + case: (@real_leP _ M 1) => //. + by apply: lt_trans. + exists (Num.max M 1)^-1; first by rewrite /= invr_gt0. + move=> x /= /[swap] x_gt0. + rewrite distrC subr0 gtr0_norm// invf_pgt ?posrE// => mM1_lt_xV. + rewrite -(invrK x); apply: MA. + apply: le_lt_trans mM1_lt_xV. + by case: (@real_leP _ M 1). +- exists r^-1; split; first by rewrite realV gtr0_real. + move=> x /[dup] rV_lt_x. + have x_gt0 : x > 0. + apply: lt_trans rV_lt_x. + by rewrite invr_gt0. + rewrite invf_plt// => xV_lt_r. + apply: rA; last by rewrite invr_gt0. + by rewrite /= distrC subr0 gtr0_norm// invr_gt0. +Qed. + +Lemma ninftyV (R : numFieldType) : x^-1 @[x --> -oo] = (0 : R)^'-. +Proof. +apply/seteqP; split=> [A [M [Mreal MA]]|A [r /= r0 rA]]. +- pose M' := Num.min M (-1). + have M'_lt0 : M' < 0. + rewrite /M'. + case: (@real_leP _ M (-1)) => // /le_lt_trans. + by apply. + exists (-M')^-1; first by rewrite /= invr_gt0 oppr_gt0. + move=> x /= /[swap] x_lt0. + rewrite distrC subr0 ltr0_norm// invrN ltrN2 => x_gt_VM'. + rewrite -(invrK x); apply: MA. + apply: (lt_le_trans (y := M')). + + by rewrite invf_nlt. + + by rewrite /M'; case: (@real_ltP _ M (-1)). +- exists (- r^-1); split; first by rewrite realN realV gtr0_real. + move=> x /[dup] x_lt_NrV. + have x_lt0 : x < 0. + apply: (lt_trans x_lt_NrV). + by rewrite oppr_lt0 invr_gt0. + rewrite ltrNr invf_plt// ?posrE ?oppr_gt0// => NxV_lt_r. + apply: rA; last by rewrite invr_lt0. + by rewrite /= distrC subr0 ltr0_norm ?invr_lt0// -invrN. +Qed. + Section infty_nbhs_instances. Context {R : numFieldType}. Implicit Types r : R. @@ -441,6 +488,20 @@ Unshelve. all: end_near. Qed. Lemma cvgNrNy f : (- f @ F --> -oo) <-> (f @ F --> +oo). Proof. by rewrite -cvgNry opprK. Qed. +Lemma cvgryV f : f @ F --> +oo -> (f x)^-1 @[x --> F] --> (0 : R). +Proof. +move=> cvgy. +apply: cvg_comp; first exact: cvgy. +by rewrite pinftyV; exact: cvg_within. +Qed. + +Lemma cvgrNyV f : f @ F --> -oo -> (f x)^-1 @[x --> F] --> (0 : R). +Proof. +move=> cvgNy. +apply: cvg_comp; first exact: cvgNy. +by rewrite ninftyV; exact: cvg_within. +Qed. + End cvg_infty_numField. Section cvg_infty_realField. @@ -526,6 +587,31 @@ Proof. by move=> fy; under eq_fun do rewrite mulrC; exact: gt0_cvgMly. Qed. End gt0_cvg. +Section lt0_cvg. +Context {R : realFieldType} {F : set_system R} {FF : Filter F}. +Variables (M : R) (f : R -> R). +Hypothesis M0 : M < 0. + +Lemma lt0_cvgMlNy : (f r) @[r --> F] --> +oo -> (f r * M)%R @[r --> F] --> -oo. +Proof. +move=> /cvgryPge fy; apply/cvgrNyPle => A. +by apply: filterS (fy (A / M)) => x; rewrite ler_ndivrMr. +Qed. + +Lemma lt0_cvgMrNy : (f r) @[r --> F] --> +oo -> (M * f r)%R @[r --> F] --> -oo. +Proof. by move=> fy; under eq_fun do rewrite mulrC; exact: lt0_cvgMlNy. Qed. + +Lemma lt0_cvgMly : f r @[r --> F] --> -oo -> (f r * M)%R @[r --> F] --> +oo. +Proof. +move=> /cvgrNyPle fNy; apply/cvgryPge => A. +by apply: filterS (fNy (A / M)) => x; rewrite ler_ndivlMr. +Qed. + +Lemma lt0_cvgMry : f r @[r --> F] --> -oo -> (M * f r)%R @[r --> F] --> +oo. +Proof. by move=> fy; under eq_fun do rewrite mulrC; exact: lt0_cvgMly. Qed. + +End lt0_cvg. + Lemma cvgNy_compNP {T : topologicalType} {R : numFieldType} (f : R -> T) (l : set_system T) : f x @[x --> -oo] --> l <-> (f \o -%R) x @[x --> +oo] --> l. diff --git a/theories/normedtype_theory/pseudometric_normed_Zmodule.v b/theories/normedtype_theory/pseudometric_normed_Zmodule.v index 9f945624de..182887799a 100644 --- a/theories/normedtype_theory/pseudometric_normed_Zmodule.v +++ b/theories/normedtype_theory/pseudometric_normed_Zmodule.v @@ -628,6 +628,22 @@ Proof. by rewrite at_leftN -?fmap_comp; under [_ \o _]eq_fun => ? do rewrite /= opprK. Qed. +Lemma fmap_at_left0P {T : Type} {R : numFieldType} x (f : R -> T) : (f (x - e) @[e --> 0^'+]) = (f @ x^'-). +Proof. +rewrite -(subrr (-x)) at_right_shift at_rightN -fmap_comp. +apply: near_eq_cvgE. +apply: (nearW (F := x^'-)) => y /=. +by rewrite opprB addNKr opprK. +Qed. + +Lemma fmap_at_right0E {T : Type} {R : numFieldType} (x : R) (f : R -> T) : (f (x + e) @[e --> 0^'+]) = (f @ x^'+). +Proof. +rewrite -(subrr x) at_right_shift. +apply: near_eq_cvgE. +apply: (nearW (F := x^'+)) => y. +by rewrite addrC subrK. +Qed. + Section at_left_right_pseudoMetricNormedZmod. Variables (R : numFieldType) (V : pseudoMetricNormedZmodType R). @@ -1098,6 +1114,45 @@ Qed. Lemma is_cvgDrE f g : cvg (f @ F) -> cvg ((f + g) @ F) = cvg (g @ F). Proof. by rewrite addrC; apply: is_cvgDlE. Qed. +Lemma cvgDl f a b : f @ F --> b -> a + f x @[x --> F] --> a + b. +Proof. apply: cvgD; exact: cvg_cst. Qed. + +Lemma cvgDr f a b : f @ F --> a -> f x + b @[x --> F] --> a + b. +Proof. move/cvgD; apply; exact: cvg_cst. Qed. + +Lemma cvgBl f a b : f @ F --> b -> a - f x @[x --> F] --> a - b. +Proof. by move/cvgN; apply: cvgDl. Qed. + +Lemma cvgBr f a b : f @ F --> a -> f x - b @[x --> F] --> a - b. +Proof. exact: cvgDr. Qed. + +Lemma cvg0D f g a : f @ F --> 0 -> g @ F --> a -> f x + g x @[x --> F] --> a. +Proof. by move=> /cvgD /[apply]; rewrite add0r. Qed. + +Lemma cvg0DC f a : f @ F --> 0 -> f x + a @[x --> F] --> a. +Proof. by move=> /(cvgDr (b := a)); rewrite add0r. Qed. + +Lemma cvgD0 f g a : f @ F --> a -> g @ F --> 0 -> f x + g x @[x --> F] --> a. +Proof. by move=> /cvgD /[apply]; rewrite addr0. Qed. + +Lemma cvgCD0 f a : f @ F --> 0 -> a + f x @[x --> F] --> a. +Proof. by move/(@cvgDl _ a); rewrite addr0. Qed. + +Lemma cvg0B f g a : f @ F --> 0 -> g @ F --> a -> f x - g x @[x --> F] --> -a. +Proof. by move=> /cvgB /[apply]; rewrite add0r. Qed. + +Lemma cvg0BC f a : f @ F --> 0 -> f x - a @[x --> F] --> -a. +Proof. by move=> /(cvgBr (b := a)); rewrite add0r. Qed. + +Lemma cvgB0 f g a : f @ F --> a -> g @ F --> 0 -> f x - g x @[x --> F] --> a. +Proof. by move=> /cvgB /[apply]; rewrite subr0. Qed. + +Lemma cvgCB0 f a : f @ F --> 0 -> a - f x @[x --> F] --> a. +Proof. by move/(@cvgBl _ a); rewrite subr0. Qed. + +Lemma cvgN0 f : f @ F --> 0 -> - f @ F --> 0. +Proof. by rewrite -{2}oppr0; exact: cvgN. Qed. + Lemma cvg_sub0 f g a : (f - g) @ F --> (0 : V) -> g @ F --> a -> f @ F --> a. Proof. by move=> Cfg Cg; have := cvgD Cfg Cg; rewrite subrK add0r; apply. diff --git a/theories/normedtype_theory/tvs.v b/theories/normedtype_theory/tvs.v index 41126a781d..85b1a0a54c 100644 --- a/theories/normedtype_theory/tvs.v +++ b/theories/normedtype_theory/tvs.v @@ -647,6 +647,19 @@ Proof. exact/nbhsB_subproof/add_continuous. Qed. End ConvexTvs_numDomain. +Lemma near_shiftE (R : numDomainType) (E : convexTvsType R) (U : set E) (x a : E) : + (\forall y \near x + a, U y) = (\near x, U (x + a)). +Proof. +eqProp; rewrite -!nbhs_nearE. +- move/(nbhsB (-a)). + rewrite addrC addrK. + apply: filterS => _ [y Uy <-]. + by rewrite addrC addNKr. +- move/(nbhsB a); rewrite addrC. + apply: filterS => ? [y Uya <-]. + by rewrite addrC. +Qed. + Section ConvexTvs_numField. Lemma nbhs0Z (R : numFieldType) (E : convexTvsType R) (U : set E) (r : R) : @@ -667,6 +680,20 @@ near=> z; exists (r^-1 *: z); last by rewrite scalerA divff// scale1r. by apply: (BU (r^-1,z)); split; [exact: nbhs_singleton|near: z]. Unshelve. all: by end_near. Qed. +Lemma nearZE (R : numFieldType) (T : convexTvsType R) (c : R) (x : T) (P : set T) : + c != 0 -> (\forall y \near c *: x, P y) = (\near x, P (c *: x)). +Proof. +move=> c_neq0. +have cinv_neq0 : c^-1 != 0 by apply: invr_neq0. +eqProp. +- move/(nbhsZ cinv_neq0). + rewrite scalerK//. + apply: filterS => ? [y Py <-]. + by rewrite scalerKV. +- move/(nbhsZ c_neq0). + by apply: filterS => ? [y Pcy <-]. +Qed. + End ConvexTvs_numField. Section standard_topology. diff --git a/theories/probability_theory/beta_distribution.v b/theories/probability_theory/beta_distribution.v index 9a879b1443..832378557a 100644 --- a/theories/probability_theory/beta_distribution.v +++ b/theories/probability_theory/beta_distribution.v @@ -77,7 +77,6 @@ Lemma derive_onemXn n x : (fun y => y.~ ^+ n)^`()%classic x = - n%:R * x.~ ^+ n.-1. Proof. rewrite (@derive1_comp _ (@onem _) (fun x => x ^+ n))//. - exact: exprn_derivable. rewrite derive1E exp_derive// derive1E deriveB// -derive1E. by rewrite derive1_cst derive_id sub0r mulrN1 [in RHS]mulNr scaler1. Qed. diff --git a/theories/realfun.v b/theories/realfun.v index dd0e368af8..d2a1326c3d 100644 --- a/theories/realfun.v +++ b/theories/realfun.v @@ -1872,25 +1872,6 @@ apply/continuous_subspaceT=> r. exact/differentiable_continuous/derivable1_diffP. Qed. -Global Instance is_derive1_comp (f g : R -> R) (x a b : 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; first exact/derivable1_diffP. - by move/derivable1_diffP in fgxv. -by rewrite -derive1E (derive1_comp gv fgxv) 2!derive1E. -Qed. - -Lemma is_deriveV (f : R -> R) (x t v : R) : - f x != 0 -> is_derive x v f t -> - is_derive x v (fun y => (f y)^-1) (- (f x) ^- 2 *: t). -Proof. -move=> fxNZ Df. -constructor; first by apply: derivableV => //; case: Df. -by rewrite deriveV //; case: Df => _ ->. -Qed. - Lemma is_derive_inverse (f g : R -> R) l x : {near x, cancel f g} -> {near x, continuous f} -> diff --git a/theories/topology_theory/function_spaces.v b/theories/topology_theory/function_spaces.v index 8c82e106d0..432d5a00bc 100644 --- a/theories/topology_theory/function_spaces.v +++ b/theories/topology_theory/function_spaces.v @@ -1600,6 +1600,11 @@ Proof. by move=> F_cont x; apply: cvg_big => // i /F_cont; exact. Qed. +Lemma within_continuous_big (T : topologicalType) (A : set T) (r : seq I) (F : I -> T -> U) : + (forall (i : I), P i -> {within A, continuous (F i)}) -> + {within A, continuous (fun x : T => \big[op/x0]_(i <- r | P i) F i x)}. +Proof. by move=> cont_F x; apply: continuous_big. Qed. + End big_continuous. Definition eval {X Y : topologicalType} : continuousType X Y * X -> Y := diff --git a/theories/topology_theory/metric_structure.v b/theories/topology_theory/metric_structure.v index d9477e84cb..34da60f8d8 100644 --- a/theories/topology_theory/metric_structure.v +++ b/theories/topology_theory/metric_structure.v @@ -315,33 +315,6 @@ Unshelve. all: end_near. Qed. End cvg_nbhsP. -Section cvg_at_right_left_dnbhs. -Variables (R : realFieldType) (T : metricType R). - -Import metricType_numDomainType. - -Lemma cvg_at_right_left_dnbhs (f : R -> T) (p : R) (l : T) : - f x @[x --> p^'+] --> l -> f x @[x --> p^'-] --> l -> - f x @[x --> p^'] --> l. -Proof. -move=> /cvgrPdist_le fppl /cvgrPdist_le fpnl; apply/cvgrPdist_le => e e0. -have {fppl}[a /= a0 fppl] := fppl (at_right_proper_filter p) _ e0. -have {fpnl}[b /= b0 fpnl] := fpnl (at_left_proper_filter p) _ e0. -near=> t. -have : t != p by near: t; exact: nbhs_dnbhs_neq. -rewrite neq_lt => /orP[tp|pt]. -- apply: fpnl => //=; near: t. - exists (b / 2) => //=; first by rewrite divr_gt0. - move=> z/= + _ => /lt_le_trans; apply. - by rewrite ler_pdivrMr// ler_pMr// ler1n. -- apply: fppl =>//=; near: t. - exists (a / 2) => //=; first by rewrite divr_gt0. - move=> z/= + _ => /lt_le_trans; apply. - by rewrite ler_pdivrMr// ler_pMr// ler1n. -Unshelve. all: by end_near. Qed. - -End cvg_at_right_left_dnbhs. - Section at_left_rightR. Variable (R : numFieldType). diff --git a/theories/topology_theory/nat_topology.v b/theories/topology_theory/nat_topology.v index e2d0274f38..49ae67d0ac 100644 --- a/theories/topology_theory/nat_topology.v +++ b/theories/topology_theory/nat_topology.v @@ -93,6 +93,18 @@ Lemma near_inftyS (P : set nat) : (\forall x \near \oo, P (S x)) -> (\forall x \near \oo, P x). Proof. case=> N _ NPS; exists (S N) => // [[]]; rewrite /= ?ltn0 //. Qed. +Lemma near_infty_after (P : set nat) : + (\forall n \near \oo, P n) <-> (\forall N \near \oo, forall n, (n >= N)%N -> P n). +Proof. +split. +- move=> [N _ afterN]. + exists N => // n /= /[swap] n' /leq_trans /[apply]. + exact: afterN. +- move=> [N _ afterN]. + exists N => // n /=. + by apply: afterN => /=. +Qed. + Section infty_nat. Local Open Scope nat_scope. diff --git a/theories/topology_theory/num_topology.v b/theories/topology_theory/num_topology.v index fc7caea215..9e46a719b7 100644 --- a/theories/topology_theory/num_topology.v +++ b/theories/topology_theory/num_topology.v @@ -241,6 +241,50 @@ split=> [pPf e|ex_notPx]. by rewrite /ball/= ltr0_norm ?subr_lt0// opprB ltrBlDl. Unshelve. all: by end_near. Qed. +Lemma at_rightD x a : (x + a)^'+ = (y + a @[y --> x^'+]). +Proof. +apply/seteqP; split=> P /=. +- move=> [/= r r0 br_sub]. + exists r => // y bxy x_lt_y. + apply: br_sub => /=. + + by rewrite (addrC y) addrKA. + + by rewrite ltrD2r. +- move=> [/= r r0 br_sub]. + exists r => // y bxay xDa_lt_y. + rewrite -(subrK a y). + apply: br_sub => /=. + + by rewrite opprB addrA. + + by rewrite ltrBrDr. +Qed. + +Lemma at_leftD x a : (x + a)^'- = (y + a @[y --> x^'-]). +Proof. +apply/seteqP; split=> P /=. +- move=> [/= r r0 br_sub]. + exists r => // y bxy x_gt_y. + apply: br_sub => /=. + + by rewrite (addrC y) addrKA. + + by rewrite ltrD2r. +- move=> [/= r r0 br_sub]. + exists r => // y bxay xDa_gt_y. + rewrite -(subrK a y). + apply: br_sub => /=. + + by rewrite opprB addrA. + + by rewrite ltrBlDr. +Qed. + +Lemma near_at_rightD x a (P : set R) : (\forall y \near (x + a)^'+, P y) = (\forall y \near x^'+, P (y + a)). +Proof. by rewrite at_rightD near_map. Qed. + +Lemma near_at_leftD x a (P : set R) : (\forall y \near (x + a)^'-, P y) = (\forall y \near x^'-, P (y + a)). +Proof. by rewrite at_leftD near_map. Qed. + +Lemma at_left_shift (T : Type) x a (f : R -> T) : (f @ (x + a)^'-) = (f (y + a) @[y --> x^'-]). +Proof. by rewrite at_leftD. Qed. + +Lemma at_right_shift (T : Type) x a (f : R -> T) : (f @ (x + a)^'+) = (f (y + a) @[y --> x^'+]). +Proof. by rewrite at_rightD. Qed. + End at_left_right. #[global] Typeclasses Opaque at_left at_right. Notation "x ^'-" := (at_left x) : classical_set_scope. @@ -252,6 +296,16 @@ Notation "x ^'+" := (at_right x) : classical_set_scope. #[global] Hint Extern 0 (Filter (nbhs _^'-)) => (apply: at_left_proper_filter) : typeclass_instances. +Lemma cvg_at_right_left_dnbhs (R : realFieldType) (T : topologicalType) (f : R -> T) (p : R) (l : T) : + f x @[x --> p^'+] --> l -> f x @[x --> p^'-] --> l -> f x @[x --> p^'] --> l. +Proof. +move=> + + U Uz => /(_ U Uz) + /(_ U Uz); near_simpl. +rewrite !near_withinE !near_nbhs => lf rf. +apply: filter_app lf; apply: filter_app rf. +near=> t => xlt xgt. +by case/lt_total/orP. +Unshelve. all: by end_near. Qed. + Lemma left_right_continuousP {R : realFieldType} {T : topologicalType} (f : R -> T) x : f @ x^'- --> f x /\ f @ x^'+ --> f x <-> f @ x --> f x. @@ -420,6 +474,46 @@ move=> r/=; rewrite ltr_pdivlMr// -ltrBlDr; apply: le_lt_trans. by rewrite -lerBlDr opprK addrC (le_trans (ler_norm _))// ler_peMr// ler1n. Qed. +Lemma near_right_in_itv (R : realFieldType) (a : R) (P : set R) : + (\forall b \near a^'+, {in `]a, b[, forall x, P x}) + <-> {near a^'+, forall x, P x}. +Proof. +split=> [[/= r r0 hr]|[/= r r0 hr]]. +- exists (r / 2) => [|x /= /ltr_distlCDr x_lt_aDr2 a_lt_x]. + by apply: divr_gt0. + apply: (hr (a + r / 2)) => /=. + + rewrite opprD addNKr normrN gtr0_norm// ?divr_gt0//. + by rewrite gtr_pMr// invf_plt ?posrE// invr1 ltrDl. + + by rewrite ltrDl divr_gt0. + + by rewrite in_itv/= a_lt_x/=. +- exists r => // x /= /ltr_distlCDr x_lt_aDr a_lt_x y. + rewrite in_itv/= => /andP[a_lt_y y_lt_x]. + apply: hr => //=. + rewrite distrC gtr0_norm ?subr_gt0// ltrBlDl. + by apply: lt_trans x_lt_aDr. +Qed. + +Lemma near_left_in_itv (R : realFieldType) (b : R) (P : set R) : + (\forall a \near b^'-, {in `]a, b[, forall x, P x}) + <-> {near b^'-, forall x, P x}. +Proof. +split=> [[/= r r0 hr]|[/= r r0 hr]]. +- exists (r / 2) => [|x /= /ltr_distlDr b_lt_xDr2 x_lt_b]. + by apply: divr_gt0. + apply: (hr (b - r / 2)) => /=. + + rewrite subKr gtr0_norm ?divr_gt0//. + by rewrite gtr_pMr// invf_plt ?posrE// invr1 ltrDl. + + by rewrite gtrBl divr_gt0. + + by rewrite in_itv/= x_lt_b andbT ltrBlDr. +- exists r => // x /= /ltr_distlDr b_lt_xDr x_lt_b y. + rewrite in_itv/= => /andP[x_lt_y y_lt_b]. + apply: hr => //=. + rewrite gtr0_norm ?subr_gt0//. + rewrite ltrBlDl. + apply: (lt_trans b_lt_xDr). + by rewrite ltrD2r. +Qed. + Section nbhs_lt_le. Context {R : numFieldType}. Implicit Types x z : R.