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.
(* mathcomp analysis (c) 2017 Inria and AIST. License: CeCILL-C.              *)
(* -------------------------------------------------------------------- *)
(* Copyright (c) - 2015--2016 - IMDEA Software Institute                *)
(* Copyright (c) - 2015--2018 - Inria                                   *)
(* Copyright (c) - 2016--2018 - Polytechnique                           *)
(* -------------------------------------------------------------------- *)

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.classical Require Import boolp classical_sets functions fsbigop. From mathcomp.classical Require Import cardinality set_interval mathcomp_extra. Require Import reals signed topology. Require Export constructive_ereal. (******************************************************************************) (* Extended real numbers, classical part *) (* *) (* This is an addition to the file ereal.v with classical logic elements. *) (* *) (* (\sum_(i \in A) f i)%E == finitely supported sum, see fsbigop.v *) (* *) (* ereal_sup E == supremum of E *) (* ereal_inf E == infimum of E *) (* ereal_supremums_neq0 S == S has a supremum *) (* *) (* Topology of extended real numbers: *) (* ereal_topologicalType R == topology for extended real numbers over *) (* R, a realFieldType *) (* ereal_pseudoMetricType R == pseudometric space for extended reals *) (* over R where is a realFieldType; the *) (* distance between x and y is defined by *) (* `|contract x - contract y| *) (* *) (* Filters: *) (* ereal_dnbhs x == filter on extended real numbers that *) (* corresponds to the deleted neighborhood *) (* x^' if x is a real number and to *) (* predicates that are eventually true if x *) (* is +oo/-oo. *) (* ereal_nbhs x == same as ereal_dnbhs where dnbhs is *) (* replaced with nbhs. *) (* ereal_loc_seq x == sequence that converges to x in the set *) (* of extended real numbers. *) (* *) (******************************************************************************) Set Implicit Arguments. Unset Strict Implicit. Unset Printing Implicit Defensive. Import Order.TTheory GRing.Theory Num.Theory. Import numFieldTopology.Exports. Local Open Scope ring_scope. Local Open Scope ereal_scope. Local Open Scope classical_set_scope. Lemma EFin_bigcup T (F : nat -> set T) : EFin @` (\bigcup_i F i) = \bigcup_i (EFin @` F i). Proof. rewrite eqEsubset; split => [_ [r [n _ Fnr <-]]|]; first by exists n => //; exists r. by move=> x [n _ [r Fnr <- /=]]; exists r => //; exists n. Qed. Lemma EFin_setC T (A : set T) : EFin @` (~` A) = (~` (EFin @` A)) `\` [set -oo; +oo]. Proof. rewrite eqEsubset; split => [_ [r Ar <-]|[r | |]]. by split => [|[]//]; apply: contra_not Ar => -[? ? [] <-]. - move=> [Ar _]; apply/not_exists2P; apply: contra_not Ar => h. by exists r => //; have [|//] := h r; apply: contrapT. - by move=> -[_] /not_orP[_ /=]. - by move=> -[_] /not_orP[/=]. Qed. Local Close Scope classical_set_scope. Notation "\sum_ ( i '\in' A ) F" := (\big[+%dE/0%E]_(i \in A) F%dE) : ereal_dual_scope. Notation "\sum_ ( i '\in' A ) F" := (\big[+%E/0%E]_(i \in A) F%E) : ereal_scope. Section ERealArith. Context {R : numDomainType}. Implicit Types x y z : \bar R. Local Open Scope classical_set_scope. Lemma preimage_abse_pinfty : @abse R @^-1` [set +oo] = [set -oo; +oo]. Proof. by rewrite predeqE => y; split ; move: y => [y//| |]//=; [right | left | case]. Qed. Lemma preimage_abse_ninfty : (@abse R @^-1` [set -oo])%classic = set0. Proof. rewrite predeqE => t; split => //=; apply/eqP. by rewrite gt_eqF// (lt_le_trans _ (abse_ge0 t)). Qed. Local Close Scope classical_set_scope. End ERealArith. Section ERealArithTh_numDomainType. Context {R : numDomainType}. Implicit Types (x y z : \bar R) (r : R). Lemma oppe_subset (A B : set (\bar R)) : ((A `<=` B) <-> (-%E @` A `<=` -%E @` B))%classic. Proof. split=> [AB _ [] x ? <-|AB x Ax]; first by exists x => //; exact: AB. have /AB[y By] : ((-%E @` A) (- x))%classic by exists x. by rewrite eqe_oppP => <-. Qed. Lemma fsume_ge0 (I : choiceType) (P : set I) (F : I -> \bar R) : (forall i, P i -> 0 <= F i) -> 0 <= \sum_(i \in P) F i. Proof. move=> PF; case: finite_supportP; rewrite ?big_nil// => X XP F0 _. by rewrite big_seq_cond big_mkcondr sume_ge0// => i /XP/PF. Qed. Lemma fsume_le0 (I : choiceType) (P : set I) (F : I -> \bar R) : (forall t, P t -> F t <= 0) -> \sum_(i \in P) F i <= 0. Proof. move=> PF; case: finite_supportP; rewrite ?big_nil// => X XP F0 _. by rewrite big_seq_cond big_mkcondr sume_le0// => i /XP/PF. Qed. Lemma fsumEFin (I : choiceType) A (F : I -> R) : finite_set A -> \sum_(i \in A) (F i)%:E = (\sum_(i \in A) F i)%:E. Proof. by move=> fs; rewrite fsbig_finite//= sumEFin -fsbig_finite. Qed. End ERealArithTh_numDomainType. Section ERealArithTh_realDomainType. Context {R : realDomainType}. Implicit Types (x y z u a b : \bar R) (r : R). Lemma fsume_gt0 (I : choiceType) (P : set I) (F : I -> \bar R) : 0 < \sum_(i \in P) F i -> exists2 i, P i & 0 < F i. Proof. apply: contraPP => /forall2NP xNPF; rewrite le_gtF// fsume_le0// => i Pi. by case: (xNPF i) => // /negP; case: ltP. Qed. Lemma fsume_lt0 (I : choiceType) (P : set I) (F : I -> \bar R) : \sum_(i \in P) F i < 0 -> exists2 i, P i & F i < 0. Proof. apply: contraPP => /forall2NP xNPF; rewrite le_gtF// fsume_ge0// => i Pi. by case: (xNPF i) => // /negP; case: ltP. Qed. Lemma pfsume_eq0 (I : choiceType) (P : set I) (F : I -> \bar R) : finite_set P -> (forall i, P i -> 0 <= F i) -> \sum_(i \in P) F i = 0 -> forall i, P i -> F i = 0. Proof. move=> Pfin F0 /eqP; apply: contraTP => /existsPNP[i Pi /eqP Fi0]. rewrite (fsbigD1 i)//= padde_eq0 ?F0 ?negb_and ?Fi0//. by rewrite fsume_ge0// => j [/F0->]. Qed. Lemma lee_fsum_nneg_subset [T : choiceType] [A B : set T] [f : T -> \bar R] : finite_set A -> finite_set B -> {subset A <= B} -> {in [predD B & A], forall t : T, 0 <= f t}%E -> (\sum_(t \in A) f t <= \sum_(t \in B) f t)%E. Proof. move=> finA finB AB f0; rewrite !fsbig_finite//=; apply: lee_sum_nneg_subfset. by apply/fsubsetP; rewrite -fset_set_sub//; apply/subsetP. by move=> t; rewrite !inE !in_fset_set// => /f0. Qed. Lemma lee_fsum [T : choiceType] (I : set T) (a b : T -> \bar R) : finite_set I -> (forall i, I i -> a i <= b i)%E -> (\sum_(i \in I) a i <= \sum_(i \in I) b i)%E. Proof. move=> finI ab. rewrite !fsbig_finite// big_seq [in leRHS]big_seq lee_sum //. by move=> i; rewrite in_fset_set// inE; exact: ab. Qed. Lemma ge0_mule_fsumr (T : choiceType) x (F : T -> \bar R) (P : set T) : (forall i : T, 0 <= F i) -> x * (\sum_(i \in P) F i) = \sum_(i \in P) x * F i. Proof. move=> F0; have [->{x}|x0] := eqVneq x 0%E. by rewrite mul0e big1// => ? _; rewrite mul0e. rewrite ge0_sume_distrr//; apply: eq_fbigl => y. rewrite !unlock; congr (_ \in fset_set _). apply/seteqP; rewrite /preimage; split=> [|] z/= [Pz Fz0]; split=> //; apply: contra_not Fz0. by move=> /eqP; rewrite mule_eq0 (negbTE x0)/= => /eqP. by move=> ->; rewrite mule0. Qed. Lemma ge0_mule_fsuml (T : choiceType) x (F : T -> \bar R) (P : set T) : (forall i : T, 0 <= F i) -> (\sum_(i \in P) F i) * x = \sum_(i \in P) F i * x. Proof. move=> F0; rewrite muleC ge0_mule_fsumr//. by apply: eq_fsbigr => i; rewrite muleC. Qed. End ERealArithTh_realDomainType. Arguments lee_fsum [R T I a b]. Module DualAddTheoryNumDomain. Import DualAddTheory. Section DualERealArithTh_numDomainType. Local Open Scope ereal_dual_scope. Context {R : numDomainType}. Implicit Types x y z : \bar R. Lemma finite_supportNe (I : choiceType) (P : set I) (F : I -> \bar R) : finite_support 0%E P (\- F)%E = finite_support 0%E P F. Proof. rewrite /finite_support !unlock; congr fset_set; congr setI. by rewrite seteqP; split=> x /= /eqP + /ltac:(apply/eqP); rewrite oppe_eq0. Qed. Lemma dual_fsumeE (I : choiceType) (P : set I) (F : I -> \bar R) : (\sum_(i \in P) F i)%dE = (- (\sum_(i \in P) (- F i)))%E. Proof. rewrite finite_supportNe. apply: (big_ind2 (fun x y => x = - y)%E) => [|_ x _ y -> ->|i _]. - by rewrite oppe0. - by rewrite dual_addeE !oppeK. - by rewrite oppeK. Qed. Lemma dfsume_ge0 (I : choiceType) (P : set I) (F : I -> \bar R) : (forall i, P i -> 0 <= F i) -> 0 <= \sum_(i \in P) F i. Proof. move=> PF; case: finite_supportP; rewrite ?big_nil// => X XP F0 _. by rewrite big_seq_cond big_mkcondr dsume_ge0// => i /XP/PF. Qed. Lemma dfsume_le0 (I : choiceType) (P : set I) (F : I -> \bar R) : (forall t, P t -> F t <= 0) -> \sum_(i \in P) F i <= 0. Proof. move=> PF; case: finite_supportP; rewrite ?big_nil// => X XP F0 _. by rewrite big_seq_cond big_mkcondr dsume_le0// => i /XP/PF. Qed. End DualERealArithTh_numDomainType. Section DualERealArithTh_realDomainType. Import DualAddTheory. Local Open Scope ereal_dual_scope. Context {R : realDomainType}. Implicit Types x y z a b : \bar R. Lemma dfsume_gt0 (I : choiceType) (P : set I) (F : I -> \bar R) : 0 < \sum_(i \in P) F i -> exists2 i, P i & 0 < F i. Proof. rewrite dual_fsumeE oppe_gt0 => /fsume_lt0[i Pi]. by rewrite oppe_lt0 => ?; exists i. Qed. Lemma dfsume_lt0 (I : choiceType) (P : set I) (F : I -> \bar R) : \sum_(i \in P) F i < 0 -> exists2 i, P i & F i < 0. Proof. rewrite dual_fsumeE oppe_lt0 => /fsume_gt0[i Pi]. by rewrite oppe_gt0 => ?; exists i. Qed. Lemma pdfsume_eq0 (I : choiceType) (P : set I) (F : I -> \bar R) : finite_set P -> (forall i, P i -> 0 <= F i) -> \sum_(i \in P) F i = 0 -> forall i, P i -> F i = 0. Proof. move=> Pfin F0 /eqP; apply: contraTP => /existsPNP[i Pi /eqP Fi0]. rewrite (fsbigD1 i)//= pdadde_eq0 ?F0 ?negb_and ?Fi0//. by rewrite dfsume_ge0// => j [/F0->]. Qed. Lemma le0_mule_dfsumr (T : choiceType) x (F : T -> \bar R) (P : set T) : (forall i : T, F i <= 0) -> x * (\sum_(i \in P) F i) = \sum_(i \in P) x * F i. Proof. move=> Fge0. rewrite !dual_fsumeE muleN ge0_mule_fsumr; last by move=> ?; rewrite oppe_ge0. rewrite (eq_bigr _ (fun _ _ => muleN _ _)). by rewrite (eq_finite_support _ (fun i _ => muleN _ _)). Qed. Lemma le0_mule_dfsuml (T : choiceType) x (F : T -> \bar R) (P : set T) : (forall i : T, F i <= 0) -> (\sum_(i \in P) F i) * x = \sum_(i \in P) F i * x. Proof. move=> F0; rewrite muleC le0_mule_dfsumr//. by apply: eq_fsbigr => i; rewrite muleC. Qed. End DualERealArithTh_realDomainType. End DualAddTheoryNumDomain. Module DualAddTheory. Export ConstructiveDualAddTheory. Export DualAddTheoryNumDomain. End DualAddTheory. Section ereal_supremum. Variable R : realFieldType. Local Open Scope classical_set_scope. Implicit Types (S : set (\bar R)) (x y : \bar R). Lemma ereal_ub_pinfty S : ubound S +oo. Proof. by apply/ubP=> x _; rewrite leey. Qed. Lemma ereal_ub_ninfty S : ubound S -oo -> S = set0 \/ S = [set -oo]. Proof. have [->|/set0P[x Sx] Snoo] := eqVneq S set0; first by left. right; rewrite predeqE => y; split => [/Snoo|->{y}]. by rewrite leeNy_eq => /eqP ->. by have := Snoo _ Sx; rewrite leeNy_eq => /eqP <-. Qed. Lemma ereal_supremums_set0_ninfty : supremums (@set0 (\bar R)) -oo. Proof. by split; [exact/ubP | apply/lbP=> y _; rewrite leNye]. Qed. Lemma supremum_pinfty S x0 : S +oo -> supremum x0 S = +oo. Proof. move=> Spoo; rewrite /supremum ifF; last by apply/eqP => S0; rewrite S0 in Spoo. have sSoo : supremums S +oo. split; first exact: ereal_ub_pinfty. by move=> /= y /(_ _ Spoo); rewrite leye_eq => /eqP ->. case: xgetP. by move=> _ -> sSxget; move: (is_subset1_supremums sSoo sSxget). by move/(_ +oo) => gSoo; exfalso; apply gSoo => {gSoo}. Qed. Definition ereal_sup S := supremum -oo S. Definition ereal_inf S := - ereal_sup (-%E @` S). Lemma ereal_sup0 : ereal_sup set0 = -oo. Proof. exact: supremum0. Qed. Lemma ereal_sup1 x : ereal_sup [set x] = x. Proof. exact: supremum1. Qed. Lemma ereal_inf0 : ereal_inf set0 = +oo. Proof. by rewrite /ereal_inf image_set0 ereal_sup0. Qed. Lemma ereal_inf1 x : ereal_inf [set x] = x. Proof. by rewrite /ereal_inf image_set1 ereal_sup1 oppeK. Qed. Lemma ub_ereal_sup S M : ubound S M -> ereal_sup S <= M. Proof. rewrite /ereal_sup /supremum; case: ifPn => [/eqP ->|]; first by rewrite leNye. - by move=> _ SM; case: xgetP => [_ -> [_]| _] /=; [exact |rewrite leNye]. Qed. Lemma lb_ereal_inf S M : lbound S M -> M <= ereal_inf S. Proof. move=> SM; rewrite /ereal_inf lee_oppr; apply ub_ereal_sup => x [y Sy <-{x}]. by rewrite lee_oppl oppeK; apply SM. Qed. Lemma ub_ereal_sup_adherent S (e : R) : (0 < e)%R -> ereal_sup S \is a fin_num -> exists2 x, S x & (ereal_sup S - e%:E < x). Proof. move=> e0 Sr; have : ~ ubound S (ereal_sup S - e%:E). move/ub_ereal_sup; apply/negP. by rewrite -ltNge lte_subl_addr // lte_addl // lte_fin. move/asboolP; rewrite asbool_neg; case/existsp_asboolPn => /= x. by rewrite not_implyE => -[? ?]; exists x => //; rewrite ltNge; apply/negP. Qed. Lemma lb_ereal_inf_adherent S (e : R) : (0 < e)%R -> ereal_inf S \is a fin_num -> exists2 x, S x & (x < ereal_inf S + e%:E). Proof. move=> e0; rewrite fin_numN => /(ub_ereal_sup_adherent e0)[x []]. move=> y Sy <-; rewrite -lte_oppr => /lt_le_trans ex; exists y => //. by apply: ex; rewrite fin_num_oppeD// oppeK. Qed. Lemma ereal_sup_gt S x : x < ereal_sup S -> exists2 y, S y & x < y. Proof. rewrite not_exists2P => + g; apply/negP; rewrite -leNgt. by apply: ub_ereal_sup => y Sy; move: (g y) => [//|/negP]; rewrite leNgt. Qed. Lemma ereal_inf_lt S x : ereal_inf S < x -> exists2 y, S y & y < x. Proof. rewrite lte_oppl => /ereal_sup_gt[_ [y Sy <-]]. by rewrite lte_oppl oppeK => xlty; exists y. Qed. End ereal_supremum. Section ereal_supremum_realType. Variable R : realType. Local Open Scope classical_set_scope. Implicit Types S : set (\bar R). Implicit Types x : \bar R. Let fine_def r0 x : R := if x is r%:E then r else r0. (* NB: see also fine above *) Lemma ereal_supremums_neq0 S : supremums S !=set0. Proof. have [->|Snoo] := eqVneq S [set -oo]. by exists -oo; split; [rewrite ub_set1 |exact: lb_ub_refl]. have [->|S0] := eqVneq S set0. by exists -oo; exact: ereal_supremums_set0_ninfty. have [Spoo|Spoo] := pselect (S +oo). by exists +oo; split; [apply/ereal_ub_pinfty | apply/lbP => /= y /ubP; apply]. have [r Sr] : exists r, S r%:E. move: S0 => /set0P[] [r Sr| // |Snoo1]; first by exists r. apply/not_existsP => nS; move/negP : Snoo; apply. by apply/eqP; rewrite predeqE => -[] // r; split => // /nS. set U := fine_def r @` S. have [|] := eqVneq (ubound U) set0. rewrite -subset0 => U0; exists +oo. split; [exact/ereal_ub_pinfty | apply/lbP => /= -[r0 /ubP Sr0|//|]]. - suff : ubound U r0 by move/U0. by apply/ubP=> _ -[] [r1 Sr1 <-|//| /= _ <-]; rewrite -lee_fin; apply Sr0. - by move/ereal_ub_ninfty => [|]; by [move/eqP : S0|move/eqP : Snoo]. set u : R := sup U. exists u%:E; split; last first. apply/lbP=> -[r0 /ubP Sr0| |]. - rewrite lee_fin; apply/sup_le_ub; first by exists r, r%:E. by apply/ubP => _ -[[r2 ? <-| // | /= _ <-]]; rewrite -lee_fin; exact: Sr0. - by rewrite leey. - by move/ereal_ub_ninfty=> [|/eqP //]; [move/eqP : S0|rewrite (negbTE Snoo)]. apply/ubP => -[r0 Sr0|//|_]; last by rewrite leNye. rewrite lee_fin. suff : has_sup U by move/sup_upper_bound/ubP; apply; exists r0%:E. split; first by exists r0, r0%:E. exists u; apply/ubP => y; move=> [] y' Sy' <-{y}. have : has_sup U by split; [exists r, r%:E | exact/set0P]. move/sup_upper_bound/ubP; apply. by case: y' Sy' => [r1 /= Sr1 | // | /= _]; [exists r1%:E | exists r%:E]. Qed. Lemma ereal_sup_ub S : ubound S (ereal_sup S). Proof. move=> y Sy; rewrite /ereal_sup /supremum ifF; last first. by apply/eqP; rewrite predeqE => /(_ y)[+ _]; exact. case: xgetP => /=; first by move=> _ -> -[] /ubP geS _; apply geS. by case: (ereal_supremums_neq0 S) => /= x0 Sx0; move/(_ x0). Qed. Lemma ereal_sup_ninfty S : ereal_sup S = -oo <-> S `<=` [set -oo]. Proof. split. by move=> supS [r /ereal_sup_ub | /ereal_sup_ub |//]; rewrite supS. move=> /(@subset_set1 _ S) [] ->; [exact: ereal_sup0|exact: ereal_sup1]. Qed. Lemma ereal_inf_lb S : lbound S (ereal_inf S). Proof. by move=> x Sx; rewrite /ereal_inf lee_oppl; apply ereal_sup_ub; exists x. Qed. Lemma ereal_inf_pinfty S : ereal_inf S = +oo <-> S `<=` [set +oo]. Proof. rewrite eqe_oppLRP oppe_subset image_set1; exact: ereal_sup_ninfty. Qed. Lemma le_ereal_sup : {homo @ereal_sup R : A B / A `<=` B >-> A <= B}. Proof. by move=> A B AB; apply ub_ereal_sup => x Ax; apply/ereal_sup_ub/AB. Qed. Lemma le_ereal_inf : {homo @ereal_inf R : A B / A `<=` B >-> B <= A}. Proof. by move=> A B AB; apply lb_ereal_inf => x Bx; exact/ereal_inf_lb/AB. Qed. Lemma hasNub_ereal_sup (A : set (\bar R)) : ~ has_ubound A -> A !=set0 -> ereal_sup A = +oo%E. Proof. move=> hasNubA A0. apply/eqP; rewrite eq_le leey /= leNgt; apply: contra_notN hasNubA => Aoo. by exists (ereal_sup A); exact: ereal_sup_ub. Qed. Lemma ereal_sup_EFin (A : set R) : has_ubound A -> A !=set0 -> ereal_sup (EFin @` A) = (sup A)%:E. Proof. move=> has_ubA A0; apply/eqP; rewrite eq_le; apply/andP; split. by apply: ub_ereal_sup => /= y [r Ar <-{y}]; rewrite lee_fin sup_ub. set esup := ereal_sup _; have := leey esup. rewrite le_eqVlt => /predU1P[->|esupoo]; first by rewrite leey. have := leNye esup; rewrite le_eqVlt => /predU1P[/esym|ooesup]. case: A0 => i Ai. by move=> /ereal_sup_ninfty /(_ i%:E) /(_ (ex_intro2 A _ i Ai erefl)). have esup_fin_num : esup \is a fin_num. by rewrite fin_numE -leeNy_eq -ltNge ooesup /= -leye_eq -ltNge esupoo. rewrite -(@fineK _ esup) // lee_fin leNgt. apply/negP => /(sup_gt A0)[r Ar]; apply/negP; rewrite -leNgt. by rewrite -lee_fin fineK//; apply: ereal_sup_ub; exists r. Qed. Lemma ereal_inf_EFin (A : set R) : has_lbound A -> A !=set0 -> ereal_inf (EFin @` A) = (inf A)%:E. Proof. move=> has_lbA A0; rewrite /ereal_inf /inf EFinN; congr (- _)%E. rewrite -ereal_sup_EFin; [|exact/has_lb_ubN|exact/nonemptyN]. by rewrite !image_comp. Qed. End ereal_supremum_realType. Canonical ereal_pointed (R : numDomainType) := PointedType (extended R) 0%E. Lemma restrict_abse T (R : numDomainType) (f : T -> \bar R) (D : set T) : (abse \o f) \_ D = abse \o (f \_ D). Proof. by apply/funext=> t; rewrite /restrict/=; case: ifPn => // _; rewrite abse0. Qed. Section SignedRealFieldStability. Context {R : realFieldType}. Definition ereal_sup_reality_subdef (xnz : KnownSign.nullity) (xr : KnownSign.reality) := (if KnownSign.wider_reality <=0 xr then KnownSign.Real <=0 else >=<0)%snum_sign. Arguments ereal_sup_reality_subdef /. Lemma ereal_sup_snum_subproof (xnz : KnownSign.nullity) (xr : KnownSign.reality) (S : {compare (0 : \bar R) & xnz & xr} -> Prop) (r := ereal_sup_reality_subdef xnz xr) : Signed.spec 0 ?=0 r (ereal_sup [set x%:num | x in S]%classic). Proof. rewrite {}/r; move: xr S => [[[]|]|] S /=; do ?[by apply: ub_ereal_sup => _ [? _ <-] |by case: ereal_sup => [s||]; rewrite ?leey ?leNye// !lee_fin -realE num_real]. Qed. Canonical ereal_sup_snum (xnz : KnownSign.nullity) (xr : KnownSign.reality) (S : {compare (0 : \bar R) & xnz & xr} -> Prop) := Signed.mk (ereal_sup_snum_subproof S). Definition ereal_inf_reality_subdef (xnz : KnownSign.nullity) (xr : KnownSign.reality) := (if KnownSign.wider_reality >=0 xr then KnownSign.Real >=0 else >=<0)%snum_sign. Arguments ereal_inf_reality_subdef /. Lemma ereal_inf_snum_subproof (xnz : KnownSign.nullity) (xr : KnownSign.reality) (S : {compare (0 : \bar R) & xnz & xr} -> Prop) (r := ereal_inf_reality_subdef xnz xr) : Signed.spec 0 ?=0 r (ereal_inf [set x%:num | x in S]%classic). Proof. rewrite {}/r; move: xr S => [[[]|]|] S /=; do ?[by apply: lb_ereal_inf => _ [? _ <-] |by case: ereal_inf => [s||]; rewrite ?leey ?leNye// !lee_fin -realE num_real]. Qed. Canonical ereal_inf_snum (xnz : KnownSign.nullity) (xr : KnownSign.reality) (S : {compare (0 : \bar R) & xnz & xr} -> Prop) := Signed.mk (ereal_inf_snum_subproof S). End SignedRealFieldStability. Section ereal_nbhs. Context {R : numFieldType}. Local Open Scope ereal_scope. Local Open Scope classical_set_scope. Definition ereal_dnbhs (x : \bar R) (P : \bar R -> Prop) : Prop := match x with | r%:E => r^' (fun r => P r%:E) | +oo => exists M, M \is Num.real /\ forall y, M%:E < y -> P y | -oo => exists M, M \is Num.real /\ forall y, y < M%:E -> P y end. Definition ereal_nbhs (x : \bar R) (P : \bar R -> Prop) : Prop := match x with | x%:E => nbhs x (fun r => P r%:E) | +oo => exists M, M \is Num.real /\ forall y, M%:E < y -> P y | -oo => exists M, M \is Num.real /\ forall y, y < M%:E -> P y end. Canonical ereal_ereal_filter := FilteredType (extended R) (extended R) (ereal_nbhs). End ereal_nbhs. Section ereal_nbhs_instances. Context {R : numFieldType}. Global Instance ereal_dnbhs_filter : forall x : \bar R, ProperFilter (ereal_dnbhs x). Proof. case=> [x||]. - case: (Proper_dnbhs_numFieldType x) => x0 [//= xT xI xS]. apply Build_ProperFilter' => //=; apply Build_Filter => //=. move=> P Q lP lQ; exact: xI. by move=> P Q PQ /xS; apply => y /PQ. - apply Build_ProperFilter. move=> P [x [xr xP]] //; exists (x + 1)%:E; apply xP => /=. by rewrite lte_fin ltr_addl. split=> /= [|P Q [MP [MPr gtMP]] [MQ [MQr gtMQ]] |P Q sPQ [M [Mr gtM]]]. + by exists 0%R. + have [MP0|MP0] := eqVneq MP 0%R. have [MQ0|MQ0] := eqVneq MQ 0%R. by exists 0%R; split => // x x0; split; [apply/gtMP; rewrite MP0 | apply/gtMQ; rewrite MQ0]. exists `|MQ|%R; rewrite realE normr_ge0; split => // x MQx; split. by apply: gtMP; rewrite (le_lt_trans _ MQx) // MP0 lee_fin. by apply gtMQ; rewrite (le_lt_trans _ MQx)// lee_fin real_ler_normr ?lexx. have [MQ0|MQ0] := eqVneq MQ 0%R. exists `|MP|%R; rewrite realE normr_ge0; split => // x MPx; split. by apply gtMP; rewrite (le_lt_trans _ MPx)// lee_fin real_ler_normr ?lexx. by apply gtMQ; rewrite (le_lt_trans _ MPx) // lee_fin MQ0. have {}MP0 : (0 < `|MP|)%R by rewrite normr_gt0. have {}MQ0 : (0 < `|MQ|)%R by rewrite normr_gt0. exists (Num.max (PosNum MP0) (PosNum MQ0))%:num. rewrite realE /= ge0 /=; split => //. case=> [r| |//]. * rewrite lte_fin/= num_max num_lt_maxl /= => /andP[MPx MQx]; split. by apply/gtMP; rewrite lte_fin (le_lt_trans _ MPx)// real_ler_normr ?lexx. by apply/gtMQ; rewrite lte_fin (le_lt_trans _ MQx)// real_ler_normr ?lexx. * by move=> _; split; [apply/gtMP | apply/gtMQ]. + by exists M; split => // ? /gtM /sPQ. - apply Build_ProperFilter. + move=> P [M [Mr ltMP]]; exists (M - 1)%:E. by apply: ltMP; rewrite lte_fin gtr_addl oppr_lt0. + split=> /= [|P Q [MP [MPr ltMP]] [MQ [MQr ltMQ]] |P Q sPQ [M [Mr ltM]]]. * by exists 0%R. * have [MP0|MP0] := eqVneq MP 0%R. have [MQ0|MQ0] := eqVneq MQ 0%R. by exists 0%R; split => // x x0; split; [apply/ltMP; rewrite MP0 | apply/ltMQ; rewrite MQ0]. exists (- `|MQ|)%R; rewrite realN realE normr_ge0; split => // x xMQ. split. by apply ltMP; rewrite (lt_le_trans xMQ)// lee_fin MP0 ler_oppl oppr0. apply ltMQ; rewrite (lt_le_trans xMQ) // lee_fin ler_oppl -normrN. by rewrite real_ler_normr ?realN // lexx. * have [MQ0|MQ0] := eqVneq MQ 0%R. exists (- `|MP|)%R; rewrite realN realE normr_ge0; split => // x MPx. split. apply ltMP; rewrite (lt_le_trans MPx) // lee_fin ler_oppl -normrN. by rewrite real_ler_normr ?realN // lexx. by apply ltMQ; rewrite (lt_le_trans MPx) // lee_fin MQ0 ler_oppl oppr0. have {}MP0 : (0 < `|MP|)%R by rewrite normr_gt0. have {}MQ0 : (0 < `|MQ|)%R by rewrite normr_gt0. exists (- (Num.max (PosNum MP0) (PosNum MQ0))%:num)%R. rewrite realN realE /= ge0 /=; split => //. case=> [r|//|]. - rewrite lte_fin ltr_oppr num_max num_lt_maxl => /andP[]. rewrite ltr_oppr => MPx; rewrite ltr_oppr => MQx; split. apply/ltMP; rewrite lte_fin (lt_le_trans MPx) //= ler_oppl -normrN. by rewrite real_ler_normr ?realN // lexx. apply/ltMQ; rewrite lte_fin (lt_le_trans MQx) //= ler_oppl -normrN. by rewrite real_ler_normr ?realN // lexx. - by move=> _; split; [apply/ltMP | apply/ltMQ]. * by exists M; split => // x /ltM /sPQ. Qed. Typeclasses Opaque ereal_dnbhs. Global Instance ereal_nbhs_filter : forall x, ProperFilter (@ereal_nbhs R x). Proof. case=> [r| |]. - case: (ereal_dnbhs_filter r%:E) => r0 [//= nrT rI rS]. apply: Build_ProperFilter => P /nbhs_ballP[r2 r20 rr2]. by exists r%:E; exact/rr2/ballxx. - exact: (ereal_dnbhs_filter +oo). - exact: (ereal_dnbhs_filter -oo). Qed. Typeclasses Opaque ereal_nbhs. End ereal_nbhs_instances. Section ereal_nbhs_infty. Context (R : numFieldType). Implicit Type (r : R). Lemma ereal_nbhs_pinfty_gt r : r \is Num.real -> \forall x \near +oo, r%:E < x. Proof. by exists r. Qed. Lemma ereal_nbhs_pinfty_ge r : r \is Num.real -> \forall x \near +oo, r%:E <= x. Proof. by exists r; split => //; apply: ltW. Qed. Lemma ereal_nbhs_ninfty_lt r : r \is Num.real -> \forall x \near -oo, r%:E > x. Proof. by exists r. Qed. Lemma ereal_nbhs_ninfty_le r : r \is Num.real -> \forall x \near -oo, r%:E >= x. Proof. by exists r; split => // ?; apply: ltW. Qed. Lemma ereal_nbhs_pinfty_real : \forall x \near +oo, fine x \is @Num.real R. Proof. apply: filterS (ereal_nbhs_pinfty_gt (@real0 _)) => x. by case: x => //= x; apply: gtr0_real. Qed. Lemma ereal_nbhs_ninfty_real : \forall x \near -oo, fine x \is @Num.real R. Proof. apply: filterS (ereal_nbhs_ninfty_lt (@real0 _)) => x. by case: x => //= x; apply: ltr0_real. Qed. End ereal_nbhs_infty. Section ereal_topologicalType. Variable R : realFieldType. Lemma ereal_nbhs_singleton (p : \bar R) (A : set (\bar R)) : ereal_nbhs p A -> A p. Proof. move: p => -[p | [M [Mreal MA]] | [M [Mreal MA]]] /=; [|exact: MA | exact: MA]. move=> /nbhs_ballP[_/posnumP[e]]; apply; exact/ballxx. Qed. Lemma ereal_nbhs_nbhs (p : \bar R) (A : set (\bar R)) : ereal_nbhs p A -> ereal_nbhs p (ereal_nbhs^~ A). Proof. move: p => -[p| [M [Mreal MA]] | [M [Mreal MA]]] //=. - move=> /nbhs_ballP[_/posnumP[e]] ballA. apply/nbhs_ballP; exists (e%:num / 2) => //= r per. apply/nbhs_ballP; exists (e%:num / 2) => //= x rex. apply/ballA/(@ball_splitl _ _ r) => //; exact/ball_sym. - exists (M + 1)%R; split; first by rewrite realD. move=> -[x| _ |_] //=; last by exists M. rewrite lte_fin => M'x /=. apply/nbhs_ballP; exists 1%R => //= y x1y. apply MA; rewrite lte_fin. rewrite addrC -ltr_subr_addl in M'x. rewrite (lt_le_trans M'x) // ler_subl_addl addrC -ler_subl_addl. rewrite (le_trans _ (ltW x1y)) // real_ler_norm // realB //. rewrite ltr_subr_addr in M'x. rewrite -comparabler0 (@comparabler_trans _ (M + 1)%R) //. by rewrite /Order.comparable (ltW M'x) orbT. by rewrite comparabler0 realD. by rewrite num_real. (* where we really use realFieldType *) - exists (M - 1)%R; split; first by rewrite realB. move=> -[x| _ |_] //=; last by exists M. rewrite lte_fin => M'x /=. apply/nbhs_ballP; exists 1%R => //= y x1y. apply MA; rewrite lte_fin. rewrite ltr_subr_addl in M'x. rewrite (le_lt_trans _ M'x) // addrC -ler_subl_addl. rewrite (le_trans _ (ltW x1y)) // distrC real_ler_norm // realB //. by rewrite num_real. (* where we really use realFieldType *) rewrite addrC -ltr_subr_addr in M'x. rewrite -comparabler0 (@comparabler_trans _ (M - 1)%R) //. by rewrite /Order.comparable (ltW M'x). by rewrite comparabler0 realB. Qed. Definition ereal_topologicalMixin : Topological.mixin_of (@ereal_nbhs R) := topologyOfFilterMixin _ ereal_nbhs_singleton ereal_nbhs_nbhs. Canonical ereal_topologicalType := TopologicalType _ ereal_topologicalMixin. End ereal_topologicalType. Local Open Scope classical_set_scope. Lemma nbhsNe (R : realFieldType) (x : \bar R) : nbhs (- x) = [set (-%E @` A) | A in nbhs x]. Proof. case: x => [r /=| |]. - rewrite /nbhs /= /ereal_nbhs -nbhs_ballE. rewrite predeqE => S; split => [[_/posnumP[e] reS]|[S' [_ /posnumP[e] reS' <-]]]. exists (-%E @` S). exists e%:num => //= r1 rer1; exists (- r1%:E); last by rewrite oppeK. by apply reS; rewrite /ball /= opprK -normrN opprD opprK. rewrite predeqE => s; split => [[y [z Sz] <- <-]|Ss]. by rewrite oppeK. by exists (- s); [exists s | rewrite oppeK]. exists e%:num => //= r1 rer1; exists (- r1%:E); last by rewrite oppeK. by apply reS'; rewrite /ball /= opprK -normrN opprD. - rewrite predeqE => S; split=> [[M [Mreal MS]]|[x [M [Mreal Mx]] <-]]. exists (-%E @` S). exists (- M)%R; rewrite realN Mreal; split => // x Mx. by exists (- x); [apply MS; rewrite lte_oppl | rewrite oppeK]. rewrite predeqE => x; split=> [[y [z Sz <- <-]]|Sx]; first by rewrite oppeK. by exists (- x); [exists x | rewrite oppeK]. exists (- M)%R; rewrite realN; split => // y yM. exists (- y); by [apply Mx; rewrite lte_oppr|rewrite oppeK]. - rewrite predeqE => S; split=> [[M [Mreal MS]]|[x [M [Mreal Mx]] <-]]. exists (-%E @` S). exists (- M)%R; rewrite realN Mreal; split => // x Mx. by exists (- x); [apply MS; rewrite lte_oppr | rewrite oppeK]. rewrite predeqE => x; split=> [[y [z Sz <- <-]]|Sx]; first by rewrite oppeK. by exists (- x); [exists x | rewrite oppeK]. exists (- M)%R; rewrite realN; split => // y yM. exists (- y); by [apply Mx; rewrite lte_oppl|rewrite oppeK]. Qed. Lemma nbhsNKe (R : realFieldType) (z : \bar R) (A : set (\bar R)) : nbhs (- z) (-%E @` A) -> nbhs z A. Proof. rewrite nbhsNe => -[S zS] SA; rewrite -(oppeK z) nbhsNe. exists (-%E @` S); first by rewrite nbhsNe; exists S. rewrite predeqE => x; split => [[y [u Su <-{y} <-]]|Ax]. rewrite oppeK. move: SA; rewrite predeqE => /(_ (- u)) [h _]. have : (exists2 y, S y & - y = - u) by exists u. by move/h => -[y Ay] /eqP; rewrite eqe_opp => /eqP <-. exists (- x); last by rewrite oppeK. exists x => //. move: SA; rewrite predeqE => /(_ (- x)) [_ h]. have : (-%E @` A) (- x) by exists x. by move/h => [y Sy] /eqP; rewrite eqe_opp => /eqP <-. Qed. Lemma oppe_continuous (R : realFieldType) : continuous (@oppe R). Proof. move=> x S /= xS; apply nbhsNKe; rewrite image_preimage //. by rewrite predeqE => y; split => // _; exists (- y) => //; rewrite oppeK. Qed. Section contract_expand. Variable R : realFieldType. Implicit Types (x : \bar R) (r : R). Local Open Scope ereal_scope. Lemma contract_imageN (S : set (\bar R)) : (@contract R) @` (-%E @` S) = -%R @` ((@contract R) @` S). Proof. rewrite predeqE => r; split => [[y [z Sz <-{y} <-{r}]]|[s [y Sy <-{s} <-{r}]]]. by exists (contract z); [exists z | rewrite contractN]. by exists (- y); [exists y | rewrite contractN]. Qed. Lemma contractK : cancel (@contract R) (@expand R). Proof. apply: (onS_can [pred r | `|r| <= 1]%R (@contract_le1 R)). exact: inj_can_sym_on (@expandK R) (on2W (@contract_inj R)). Qed. Lemma bijective_contract : {on [pred r | `|r| <= 1]%R, bijective (@contract R)}. Proof. exists (@expand R); [exact: in1W contractK | exact: (@expandK R)]. Qed. Definition le_expandLR := monoLR_in (in_onW_can _ predT contractK) (fun x _ => contract_le1 x) (@le_expand_in R). Definition lt_expandLR := monoLR_in (in_onW_can _ predT contractK) (fun x _ => contract_le1 x) (@lt_expand R). Definition le_expandRL := monoRL_in (in_onW_can _ predT contractK) (fun x _ => contract_le1 x) (@le_expand_in R). Definition lt_expandRL := monoRL_in (in_onW_can _ predT contractK) (fun x _ => contract_le1 x) (@lt_expand R). Lemma contract_eq0 x : (contract x == 0%R) = (x == 0). Proof. by rewrite -(can_eq contractK) contract0. Qed. Lemma contract_eqN1 x : (contract x == -1) = (x == -oo). Proof. by rewrite -(can_eq contractK). Qed. Lemma contract_eq1 x : (contract x == 1%R) = (x == +oo). Proof. by rewrite -(can_eq contractK). Qed. End contract_expand. Section contract_expand_realType. Variable R : realType. Let contract := @contract R. Lemma sup_contract_le1 S : S !=set0 -> (`|sup (contract @` S)| <= 1)%R. Proof. case=> x Sx; rewrite ler_norml; apply/andP; split; last first. apply sup_le_ub; first by exists (contract x), x. by move=> r [y Sy] <-; case/ler_normlP : (contract_le1 y). rewrite (@le_trans _ _ (contract x)) //. by case/ler_normlP : (contract_le1 x); rewrite ler_oppl. apply sup_ub; last by exists x. by exists 1%R => r [y Sy <-]; case/ler_normlP : (contract_le1 y). Qed. Lemma contract_sup S : S !=set0 -> contract (ereal_sup S) = sup (contract @` S). Proof. move=> S0; apply/eqP; rewrite eq_le; apply/andP; split; last first. apply sup_le_ub. by case: S0 => x Sx; exists (contract x), x. move=> x [y Sy] <-{x}; rewrite le_contract; exact/ereal_sup_ub. rewrite leNgt; apply/negP. set supc := sup _; set csup := contract _; move=> ltsup. suff [y [ysupS ?]] : exists y, y < ereal_sup S /\ ubound S y. have : ereal_sup S <= y by apply ub_ereal_sup. by move/(lt_le_trans ysupS); rewrite ltxx. suff [x [? [ubSx x1]]] : exists x, (x < csup)%R /\ ubound (contract @` S) x /\ (`|x| <= 1)%R. exists (expand x); split => [|y Sy]. by rewrite -(contractK (ereal_sup S)) lt_expand // inE // contract_le1. by rewrite -(contractK y) le_expand //; apply ubSx; exists y. exists ((supc + csup) / 2); split; first by rewrite midf_lt. split => [r [y Sy <-{r}]|]. rewrite (@le_trans _ _ supc) ?midf_le //; last by rewrite ltW. apply sup_ub; last by exists y. by exists 1%R => r [z Sz <-]; case/ler_normlP : (contract_le1 z). rewrite ler_norml; apply/andP; split; last first. rewrite ler_pdivr_mulr // mul1r (_ : 2 = 1 + 1)%R // ler_add //. by case/ler_normlP : (sup_contract_le1 S0). by case/ler_normlP : (contract_le1 (ereal_sup S)). rewrite ler_pdivl_mulr // (_ : 2 = 1 + 1)%R // mulN1r opprD ler_add //. by case/ler_normlP : (sup_contract_le1 S0); rewrite ler_oppl. by case/ler_normlP : (contract_le1 (ereal_sup S)); rewrite ler_oppl. Qed. Lemma contract_inf S : S !=set0 -> contract (ereal_inf S) = inf (contract @` S). Proof. move=> -[x Sx]; rewrite /ereal_inf /contract (contractN (ereal_sup (-%E @` S))). by rewrite -/contract contract_sup /inf; [rewrite contract_imageN | exists (- x), x]. Qed. End contract_expand_realType. Section ereal_PseudoMetric. Variable R : realFieldType. Implicit Types (x y : \bar R) (r : R). Lemma le_ereal_ball x : {homo ereal_ball x : e e' / (e <= e')%R >-> e `<=` e'}. Proof. by move=> e e' ee' y; rewrite /ereal_ball => /lt_le_trans; exact. Qed. Lemma expand_ereal_ball_pinfty {e : {posnum R}} r : (e%:num <= 1)%R -> expand (1 - e%:num)%R < r%:E -> ereal_ball +oo e%:num r%:E. Proof. move=> e1 er; rewrite /ereal_ball gtr0_norm ?subr_gt0; last first. by case/ltr_normlP : (contract_lt1 r). rewrite ltr_subl_addl addrC -ltr_subl_addl -[ltLHS]expandK ?lt_contract//. by rewrite inE ger0_norm ?ler_subl_addl ?ler_addr // subr_ge0. Qed. Lemma contract_ereal_ball_fin_le r r' (e : {posnum R}) : (r <= r')%R -> (1 <= contract r%:E + e%:num)%R -> ereal_ball r%:E e%:num r'%:E. Proof. rewrite le_eqVlt => /predU1P[<-{r'} _|rr' re1]; first exact: ereal_ball_center. rewrite /ereal_ball ltr0_norm; last by rewrite subr_lt0 lt_contract lte_fin. rewrite opprB ltr_subl_addl (lt_le_trans _ re1) //. by case/ltr_normlP : (contract_lt1 r'). Qed. Lemma contract_ereal_ball_fin_lt r r' (e : {posnum R}) : (r' < r)%R -> (contract r%:E - e%:num <= -1)%R -> ereal_ball r%:E e%:num r'%:E. Proof. move=> r'r reN1; rewrite /ereal_ball. rewrite gtr0_norm ?subr_gt0 ?lt_contract ?lte_fin//. rewrite ltr_subl_addl addrC -ltr_subl_addl (le_lt_trans reN1) //. by move: (contract_lt1 r'); rewrite ltr_norml => /andP[]. Qed. Lemma expand_ereal_ball_fin_lt r' r (e : {posnum R}) : (r' < r)%R -> expand (contract r%:E - e%:num)%R < r'%:E -> (`|contract r%:E - e%:num| < 1)%R -> ereal_ball r%:E e%:num r'%:E. Proof. move=> r'r ? r'e'r. rewrite /ereal_ball gtr0_norm ?subr_gt0 ?lt_contract ?lte_fin//. by rewrite ltr_subl_addl addrC -ltr_subl_addl -lt_expandLR ?inE ?ltW. Qed. Lemma ball_ereal_ball_fin_lt r r' (e : {posnum R}) : let e' := (r - fine (expand (contract r%:E - e%:num)))%R in ball r e' r' -> (r' < r)%R -> (`|contract r%:E - (e)%:num| < 1)%R -> ereal_ball r%:E (e)%:num r'%:E. Proof. move=> e' re'r' rr' X; rewrite /ereal_ball. rewrite gtr0_norm ?subr_gt0// ?lt_contract ?lte_fin//. move: re'r'. rewrite /ball /= gtr0_norm // ?subr_gt0// /e'. rewrite -ltr_subl_addl addrAC subrr add0r ltr_oppl opprK -lte_fin. rewrite fine_expand // lt_expandLR ?inE ?ltW//. by rewrite ltr_subl_addl addrC -ltr_subl_addl. Qed. Lemma ball_ereal_ball_fin_le r r' (e : {posnum R}) : let e' : R := (fine (expand (contract r%:E + e%:num)) - r)%R in ball r e' r' -> (r <= r')%R -> (`| contract r%:E + e%:num | < 1)%R -> (ereal_ball r%:E e%:num r'%:E). Proof. move=> e' r'e'r rr' re1; rewrite /ereal_ball. move: rr'; rewrite le_eqVlt => /predU1P[->|rr']; first by rewrite subrr normr0. rewrite /ball /= ltr0_norm ?subr_lt0// opprB in r'e'r. rewrite ltr0_norm ?subr_lt0 ?lt_contract ?lte_fin//. rewrite opprB; move: r'e'r. rewrite /e' -ltr_subl_addr opprK subrK -lte_fin fine_expand //. by rewrite lt_expandRL ?inE ?ltW// ltr_subl_addl. Qed. Lemma nbhs_oo_up_e1 (A : set (\bar R)) (e : {posnum R}) : (e%:num <= 1)%R -> ereal_ball +oo e%:num `<=` A -> nbhs +oo A. Proof. move=> e1 ooeA. exists (fine (expand (1 - e%:num)%R)); rewrite num_real; split => //. case => [r | | //]. - rewrite fine_expand; last first. by rewrite ger0_norm ?ltr_subl_addl ?ltr_addr // subr_ge0. by move=> ?; exact/ooeA/expand_ereal_ball_pinfty. - by move=> _; exact/ooeA/ereal_ball_center. Qed. Lemma nbhs_oo_down_e1 (A : set (\bar R)) (e : {posnum R}) : (e%:num <= 1)%R -> ereal_ball -oo e%:num `<=` A -> nbhs -oo A. Proof. move=> e1 reA; suff h : nbhs +oo (-%E @` A). rewrite (_ : -oo = - +oo) // nbhsNe; exists (-%E @` A) => //. rewrite predeqE => x; split=> [[y [z Az <- <-]]|Ax]; rewrite ?oppeK //. by exists (- x); [exists x | rewrite oppeK]. apply (@nbhs_oo_up_e1 _ e) => // x x1e; exists (- x); last by rewrite oppeK. by apply/reA/ereal_ballN; rewrite oppeK. Qed. Lemma nbhs_oo_up_1e (A : set (\bar R)) (e : {posnum R}) : (1 < e%:num)%R -> ereal_ball +oo e%:num `<=` A -> nbhs +oo A. Proof. move=> e1 reA; have [e2{e1}|e2] := ltrP 2 e%:num. suff -> : A = setT by exists 0%R. rewrite predeqE => x; split => // _; apply reA. exact/ereal_ballN/ereal_ball_ninfty_oversize. have /andP[e10 e11] : (0 < e%:num - 1 <= 1)%R. by rewrite subr_gt0 e1 /= ler_subl_addl. apply nbhsNKe. have : ((PosNum e10)%:num <= 1)%R by []. move/(@nbhs_oo_down_e1 (-%E @` A) (PosNum e10)); apply. move=> y ye; exists (- y); last by rewrite oppeK. apply/reA/ereal_ballN; rewrite oppeK /=. by apply: le_ereal_ball ye => /=; rewrite ler_subl_addl ler_addr. Qed. Lemma nbhs_oo_down_1e (A : set (\bar R)) (e : {posnum R}) : (1 < e%:num)%R -> ereal_ball -oo e%:num `<=` A -> nbhs -oo A. Proof. move=> e1 reA; have [e2{e1}|e2] := ltrP 2 e%:num. suff -> : A = setT by exists 0%R. by rewrite predeqE => x; split => // _; exact/reA/ereal_ball_ninfty_oversize. have /andP[e10 e11] : (0 < e%:num - 1 <= 1)%R. by rewrite subr_gt0 e1 /= ler_subl_addl. apply nbhsNKe. have : ((PosNum e10)%:num <= 1)%R by []. move/(@nbhs_oo_up_e1 (-%E @` A) (PosNum e10)); apply. move=> y ye; exists (- y); last by rewrite oppeK. apply/reA/ereal_ballN; rewrite /= oppeK. by apply: le_ereal_ball ye => /=; rewrite ler_subl_addl ler_addr. Qed. Lemma nbhs_fin_out_above r (e : {posnum R}) (A : set (\bar R)) : ereal_ball r%:E e%:num `<=` A -> (- 1 < contract r%:E - e%:num)%R -> (1 <= contract r%:E + e%:num)%R -> nbhs r%:E A. Proof. move=> reA reN1 re1. have er1 : (`|contract r%:E - e%:num| < 1)%R. rewrite ltr_norml reN1 andTb ltr_subl_addl ltr_spaddl //. by move: (contract_le1 r%:E); rewrite ler_norml => /andP[]. pose e' := (r - fine (expand (contract r%:E - e%:num)))%R. have e'0 : (0 < e')%R. rewrite subr_gt0 -lte_fin -[ltRHS](contractK r%:E). rewrite fine_expand // lt_expand ?inE ?contract_le1// ?ltW//. by rewrite ltr_subl_addl ltr_addr. apply/nbhs_ballP; exists e' => // r' re'r'; apply reA. by have [?|?] := lerP r r'; [exact: contract_ereal_ball_fin_le | exact: ball_ereal_ball_fin_lt]. Qed. Lemma nbhs_fin_out_below r (e : {posnum R}) (A : set (\bar R)) : ereal_ball r%:E e%:num `<=` A -> (contract r%:E - e%:num <= - 1)%R -> (contract r%:E + e%:num < 1)%R -> nbhs r%:E A. Proof. move=> reA reN1 re1. have ? : (`|contract r%:E + e%:num| < 1)%R. rewrite ltr_norml re1 andbT (@lt_le_trans _ _ (contract r%:E)) // ?ler_addl //. by move: (contract_lt1 r); rewrite ltr_norml => /andP[]. pose e' : R := (fine (expand (contract r%:E + e%:num)) - r)%R. have e'0 : (0 < e')%R. rewrite /e' subr_gt0 -lte_fin -[in ltLHS](contractK r%:E). by rewrite fine_expand // lt_expand ?inE ?contract_le1 ?ltr_addl ?ltW. apply/nbhs_ballP; exists e' => // r' r'e'r; apply reA. by have [?|?] := lerP r r'; [exact: ball_ereal_ball_fin_le | exact: contract_ereal_ball_fin_lt]. Qed. Lemma nbhs_fin_out_above_below r (e : {posnum R}) (A : set (\bar R)) : ereal_ball r%:E e%:num `<=` A -> (contract r%:E - e%:num < -1)%R -> (1 < contract r%:E + e%:num)%R -> nbhs r%:E A. Proof. move=> reA reN1 re1; suff : A = setT by move->; apply: filterT. rewrite predeqE => x; split => // _; apply reA. case: x => [r'| |] //. - have [?|?] := lerP r r'. + by apply: contract_ereal_ball_fin_le => //; exact/ltW. + by apply contract_ereal_ball_fin_lt => //; exact/ltW. - exact/contract_ereal_ball_pinfty. - apply/ereal_ballN/contract_ereal_ball_pinfty. by rewrite EFinN contractN -(opprK 1%R) ltr_oppl opprD opprK. Qed. Lemma nbhs_fin_inbound r (e : {posnum R}) (A : set (\bar R)) : ereal_ball r%:E e%:num `<=` A -> nbhs r%:E A. Proof. move=> reA. have [|reN1] := boolP (contract r%:E - e%:num == -1)%R. rewrite subr_eq addrC => /eqP reN1. have [re1|] := boolP (contract r%:E + e%:num == 1)%R. move/eqP : reN1; rewrite -(eqP re1) opprD addrCA subrr addr0 -subr_eq0. rewrite opprK -mulr2n mulrn_eq0 orFb contract_eq0 => /eqP[r0]. move: re1; rewrite r0 contract0 add0r => /eqP e1. apply/nbhs_ballP; exists 1%R => //= r'; rewrite /ball /= sub0r normrN => r'1. apply reA. by rewrite /ereal_ball r0 contract0 sub0r normrN e1 contract_lt1. rewrite neq_lt => /orP[re1|re1]. by apply (@nbhs_fin_out_below _ e) => //; rewrite reN1 addrAC subrr sub0r. have e1 : (1 < e%:num)%R. move: re1; rewrite reN1 addrAC ltr_subr_addl -!mulr2n -(mulr_natl e%:num). by rewrite -{1}(mulr1 2) => ?; rewrite -(@ltr_pmul2l _ 2). have Aoo : setT `\ -oo `<=` A. move=> x [_]; rewrite /set1 /= => xnoo; apply reA. case: x xnoo => [r' _ | _ |//]. have [rr'|r'r] := lerP (contract r%:E) (contract r'%:E). apply: contract_ereal_ball_fin_le; last exact/ltW. by rewrite -lee_fin -(contractK r%:E) -(contractK r'%:E) le_expand. apply: contract_ereal_ball_fin_lt; last first. by rewrite reN1 addrAC subrr add0r. rewrite -lte_fin -(contractK r%:E) -(contractK r'%:E). by rewrite lt_expand // inE; exact: contract_le1. exact: contract_ereal_ball_pinfty. have : nbhs r%:E (setT `\ -oo) by apply/nbhs_ballP; exists 1%R => /=. move=> /nbhs_ballP[_/posnumP[e']] /=; rewrite /ball /= => h. by apply/nbhs_ballP; exists e'%:num => //= y /h; apply: Aoo. move: reN1; rewrite eq_sym neq_lt => /orP[reN1|reN1]. have [re1|re1] := eqVneq (contract r%:E + e%:num)%R 1%R. by apply (@nbhs_fin_out_above _ e) => //; rewrite re1. move: re1; rewrite neq_lt => /orP[re1|re1]. have ? : (`|contract r%:E - e%:num| < 1)%R. rewrite ltr_norml reN1 andTb ltr_subl_addl. rewrite (@lt_le_trans _ _ 1%R) // ?ler_addr//. by case/ltr_normlP : (contract_lt1 r). have ? : (`|contract r%:E + e%:num| < 1)%R. rewrite ltr_norml re1 andbT -(addr0 (-1)) ler_lt_add //. by move: (contract_le1 r%:E); rewrite ler_norml => /andP[]. pose e' : R := Num.min (r - fine (expand (contract r%:E - e%:num)))%R (fine (expand (contract r%:E + e%:num)) - r)%R. have e'0 : (0 < e')%R. rewrite /e' lt_minr; apply/andP; split. rewrite subr_gt0 -lte_fin -[in ltRHS](contractK r%:E). rewrite fine_expand // lt_expand// ?inE ?contract_le1 ?ltW//. by rewrite ltr_subl_addl ltr_addr. rewrite subr_gt0 -lte_fin -[in ltLHS](contractK r%:E). by rewrite fine_expand// lt_expand ?inE ?contract_le1 ?ltr_addl ?ltW. apply/nbhs_ballP; exists e' => // r' re'r'; apply reA. have [|r'r] := lerP r r'. move=> rr'; apply: ball_ereal_ball_fin_le => //. by apply: le_ball re'r'; rewrite le_minl lexx orbT. move: re'r'; rewrite /ball /= lt_minr => /andP[]. rewrite gtr0_norm ?subr_gt0 // -ltr_subl_addl addrAC subrr add0r ltr_oppl. rewrite opprK -lte_fin fine_expand // => r'e'r _. exact: expand_ereal_ball_fin_lt. by apply (@nbhs_fin_out_above _ e) => //; rewrite ltW. have [re1|re1] := ltrP 1 (contract r%:E + e%:num). exact: (@nbhs_fin_out_above_below _ e). move: re1; rewrite le_eqVlt => /orP[re1|re1]. have {}re1 : contract r%:E = (1 - e%:num)%R. by move: re1; rewrite eq_sym -subr_eq => /eqP <-. have e1 : (1 < e%:num)%R. move: reN1. rewrite re1 -addrA -opprD ltr_subl_addl ltr_subr_addl -!mulr2n. rewrite -(mulr_natl e%:num) -{1}(mulr1 2) => ?. by rewrite -(@ltr_pmul2l _ 2). have Aoo : (setT `\ +oo `<=` A). move=> x [_]; rewrite /set1 /= => xpoo; apply reA. case: x xpoo => [r' _ | // |_]. rewrite /ereal_ball. have [rr'|r'r] := lerP (contract r%:E) (contract r'%:E). rewrite re1 opprB addrCA -[ltRHS]addr0 ltr_add2 subr_lt0. by case/ltr_normlP : (contract_lt1 r'). rewrite /ereal_ball. rewrite re1 addrAC ltr_subl_addl ltr_add // (lt_trans _ e1) // ltr_oppl. by move: (contract_lt1 r'); rewrite ltr_norml => /andP[]. rewrite /ereal_ball. rewrite [contract -oo]/= opprK gtr0_norm ?subr_gt0; last first. rewrite -ltr_subl_addl add0r ltr_oppl. by move: (contract_lt1 r); rewrite ltr_norml => /andP[]. by rewrite re1 addrAC ltr_subl_addl ltr_add. have : nbhs r%:E (setT `\ +oo) by exists 1%R => /=. case => _/posnumP[x] /=; rewrite /ball_ => h. by exists x%:num => //= y /h; exact: Aoo. by apply (@nbhs_fin_out_below _ e) => //; rewrite ltW. Qed. Lemma ereal_nbhsE : nbhs = nbhs_ (entourage_ (@ereal_ball R)). Proof. set diag := fun r => [set xy | ereal_ball xy.1 r xy.2]. rewrite predeq2E => x A; split. - rewrite {1}/nbhs /= /ereal_nbhs. case: x => [/= r [_/posnumP[e] reA]| [M [/= Mreal MA]]| [M [/= Mreal MA]]]. + pose e' : R := Num.min (contract r%:E - contract (r%:E - e%:num%:E))%R (contract (r%:E + e%:num%:E) - contract r%:E)%R. exists (diag e'); rewrite /diag. exists e' => //. rewrite /= /e' lt_minr; apply/andP; split. by rewrite subr_gt0 lt_contract lte_fin ltr_subl_addr ltr_addl. by rewrite subr_gt0 lt_contract lte_fin ltr_addl. case=> [r' /= re'r'| |]/=. * rewrite /ereal_ball in re'r'. have [r'r|rr'] := lerP (contract r'%:E) (contract r%:E). apply: reA; rewrite /ball /= real_ltr_norml // ?num_real //. rewrite ger0_norm ?subr_ge0// in re'r'. have : (contract (r%:E - e%:num%:E) < contract r'%:E)%R. move: re'r'; rewrite /e' lt_minr => /andP[+ _]. rewrite /e' ltr_subr_addl addrC -ltr_subr_addl => /lt_le_trans. by apply; rewrite opprB addrCA subrr addr0. rewrite -lt_expandRL ?inE ?contract_le1 // !contractK lte_fin. rewrite ltr_subl_addr addrC -ltr_subl_addr => ->; rewrite andbT. rewrite (@lt_le_trans _ _ 0%R)// 1?ltr_oppl 1?oppr0// subr_ge0. by rewrite -lee_fin -le_contract. apply: reA; rewrite /ball /= real_ltr_norml // ?num_real //. rewrite ltr0_norm ?subr_lt0// opprB in re'r'. apply/andP; split; last first. by rewrite (@lt_trans _ _ 0%R) // subr_lt0 -lte_fin -lt_contract. rewrite ltr_oppl opprB. rewrite /e' in re'r'. have r're : (contract r'%:E < contract (r%:E + e%:num%:E))%R. move: re'r'; rewrite lt_minr => /andP[_]. by rewrite ltr_subl_addr subrK. rewrite ltr_subl_addr -lte_fin -(contractK (_ + r)%:E)%R. by rewrite addrC -(contractK r'%:E) // lt_expand ?inE ?contract_le1. * rewrite /ereal_ball [contract +oo]/=. rewrite lt_minr => /andP[re'1 re'2]. have [cr0|cr0] := lerP 0 (contract r%:E). move: re'2; rewrite ler0_norm; last first. by rewrite subr_le0; case/ler_normlP : (contract_le1 r%:E). rewrite opprB ltr_subr_addl addrCA subrr addr0 => h. exfalso. move: h; apply/negP; rewrite -leNgt. by case/ler_normlP : (contract_le1 (r%:E + e%:num%:E)). move: re'2; rewrite ler0_norm; last first. by rewrite subr_le0; case/ler_normlP : (contract_le1 r%:E). rewrite opprB ltr_subr_addl addrCA subrr addr0 => h. exfalso. move: h; apply/negP; rewrite -leNgt. by case/ler_normlP : (contract_le1 (r%:E + e%:num%:E)). * rewrite /ereal_ball [contract -oo]/=; rewrite opprK. rewrite lt_minr => /andP[re'1 _]. move: re'1. rewrite ger0_norm; last first. rewrite addrC -ler_subl_addl add0r. by move: (contract_le1 r%:E); rewrite ler_norml => /andP[]. rewrite ltr_add2l => h. exfalso. move: h; apply/negP; rewrite -leNgt -ler_oppl. by move: (contract_le1 (r%:E - e%:num%:E)); rewrite ler_norml => /andP[]. + exists (diag (1 - contract M%:E))%R; rewrite /diag. exists (1 - contract M%:E)%R => //=. by rewrite subr_gt0 (le_lt_trans _ (contract_lt1 M)) // ler_norm. case=> [r| |]/=. * rewrite /ereal_ball [_ +oo]/= => rM1. apply: MA; rewrite lte_fin. rewrite ger0_norm in rM1; last first. by rewrite subr_ge0 // (le_trans _ (contract_le1 r%:E)) // ler_norm. rewrite ltr_subl_addr addrC addrCA addrC -ltr_subl_addr subrr in rM1. rewrite subr_gt0 in rM1. by rewrite -lte_fin -lt_contract. * by rewrite /ereal_ball /= subrr normr0 => h; exact: MA. * rewrite /ereal_ball /= opprK => h {MA}. exfalso. move: h; apply/negP. rewrite -leNgt [in leRHS]ger0_norm // ler_subl_addr. rewrite -/(contract M%:E) addrC -ler_subl_addr opprD addrA subrr sub0r. by move: (contract_le1 M%:E); rewrite ler_norml => /andP[]. + exists (diag (1 + contract M%:E)%R); rewrite /diag. exists (1 + contract M%:E)%R => //=. rewrite -ltr_subl_addl sub0r. by move: (contract_lt1 M); rewrite ltr_norml => /andP[]. case=> [r| |]. * rewrite /ereal_ball => /= rM1. apply MA. rewrite lte_fin. rewrite ler0_norm in rM1; last first. rewrite ler_subl_addl addr0 ltW //. by move: (contract_lt1 r); rewrite ltr_norml => /andP[]. rewrite opprB opprK -ltr_subl_addl addrK in rM1. by rewrite -lte_fin -lt_contract. * rewrite /ereal_ball /= -opprD normrN => h {MA}. exfalso. move: h; apply/negP. rewrite -leNgt [in leRHS]ger0_norm// -ler_subl_addr addrAC. rewrite subrr add0r -/(contract M%:E). by rewrite (le_trans _ (ltW (contract_lt1 M))) // ler_norm. * rewrite /ereal_ball /= => _; exact: MA. - case: x => [r [E [_/posnumP[e] reA] sEA] | [E [_/posnumP[e] reA] sEA] | [E [_/posnumP[e] reA] sEA]] //=. + by apply nbhs_fin_inbound with e => ? ?; exact/sEA/reA. + have [|] := boolP (e%:num <= 1)%R. by move/nbhs_oo_up_e1; apply => ? ?; exact/sEA/reA. by rewrite -ltNge => /nbhs_oo_up_1e; apply => ? ?; exact/sEA/reA. + have [|] := boolP (e%:num <= 1)%R. by move/nbhs_oo_down_e1; apply => ? ?; exact/sEA/reA. by rewrite -ltNge => /nbhs_oo_down_1e; apply => ? ?; exact/sEA/reA. Qed. Definition ereal_pseudoMetricType_mixin := PseudoMetric.Mixin (@ereal_ball_center R) (@ereal_ball_sym R) (@ereal_ball_triangle R) erefl. Definition ereal_uniformType_mixin : @Uniform.mixin_of (\bar R) nbhs := uniformityOfBallMixin ereal_nbhsE ereal_pseudoMetricType_mixin. Canonical ereal_uniformType := UniformType (extended R) ereal_uniformType_mixin. Canonical ereal_pseudoMetricType := PseudoMetricType (extended R) ereal_pseudoMetricType_mixin. End ereal_PseudoMetric. (* TODO: generalize to numFieldType? *) Lemma nbhs_interval (R : realFieldType) (P : R -> Prop) (r : R) (a b : \bar R) : a < r%:E -> r%:E < b -> (forall y, a < y%:E -> y%:E < b -> P y) -> nbhs r P. Proof. move => ar rb abP; case: (lt_ereal_nbhs ar rb) => d rd. exists d%:num => //= y; rewrite /= distrC. by move=> /rd /andP[? ?]; apply: abP. Qed. Lemma ereal_dnbhs_le (R : numFieldType) (x : \bar R) : ereal_dnbhs x --> ereal_nbhs x. Proof. move: x => [r P [_/posnumP[e] reP] |r P|r P] //=. by exists e%:num => //= ? ? ?; apply: reP. Qed. Lemma ereal_dnbhs_le_finite (R : numFieldType) (r : R) : ereal_dnbhs r%:E --> nbhs r%:E. Proof. by move=> P [_/posnumP[e] reP] //=; exists e%:num => //= ? ? ?; exact: reP. Qed. Definition ereal_loc_seq (R : numDomainType) (x : \bar R) (n : nat) := match x with | x%:E => (x + (n%:R + 1)^-1)%:E | +oo => n%:R%:E | -oo => - n%:R%:E end. Lemma cvg_ereal_loc_seq (R : realType) (x : \bar R) : ereal_loc_seq x --> ereal_dnbhs x. Proof. move=> P; rewrite /ereal_loc_seq. case: x => /= [x [_/posnumP[d] dP] |[d [dreal dP]] |[d [dreal dP]]]; last 2 first. have /ZnatP [N Nfloor] : floor (Num.max d 0%R) \is a Znat. by rewrite Znat_def floor_ge0 le_maxr lexx orbC. exists N.+1 => // n ltNn; apply: dP. have /le_lt_trans : (d <= Num.max d 0)%R by rewrite le_maxr lexx. by apply; rewrite (lt_le_trans (lt_succ_floor _))// Nfloor natr1 ler_nat. have /ZnatP [N Nfloor] : floor (Num.max (- d)%R 0%R) \is a Znat. by rewrite Znat_def floor_ge0 le_maxr lexx orbC. exists N.+1 => // n ltNn; apply: dP; rewrite lte_fin ltr_oppl. have /le_lt_trans : (- d <= Num.max (- d) 0)%R by rewrite le_maxr lexx. by apply; rewrite (lt_le_trans (lt_succ_floor _))// Nfloor natr1 ler_nat. have /ZnatP [N Nfloor] : floor (d%:num^-1) \is a Znat. by rewrite Znat_def floor_ge0. exists N => // n leNn; apply: dP; last first. by rewrite eq_sym addrC -subr_eq subrr eq_sym; exact/invr_neq0/lt0r_neq0. rewrite /= opprD addrA subrr distrC subr0 gtr0_norm; last by rewrite invr_gt0. rewrite -[ltLHS]mulr1 ltr_pdivr_mull // -ltr_pdivr_mulr // div1r. by rewrite (lt_le_trans (lt_succ_floor _))// Nfloor ler_add// ler_nat. Qed.