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.
(* -------------------------------------------------------------------- *)
(* 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]
Require Import mathcomp.bigenough.bigenough. From mathcomp.classical Require Import boolp classical_sets functions. From mathcomp.classical Require Import mathcomp_extra. Require Import xfinmap ereal reals discrete topology. Set Implicit Arguments. Unset Strict Implicit. Unset Printing Implicit Defensive. Unset SsrOldRewriteGoalsOrder. Import Order.TTheory GRing.Theory Num.Theory BigEnough. Local Open Scope ring_scope. (* -------------------------------------------------------------------- *) Notation "f '<=1' g" := (forall x, f x <= g x) (at level 70, no associativity). Notation "f '<=2' g" := (forall x y, f x y <= g x y) (at level 70, no associativity). (* -------------------------------------------------------------------- *) Section FFTheory. Context {R : realDomainType} (T : Type). Implicit Types (f g h : T -> R). Lemma leff f : f <=1 f. Proof. by []. Qed. Lemma lef_trans g f h : f <=1 g -> g <=1 h -> f <=1 h. Proof. by move=> h1 h2 x; apply/(le_trans (h1 x)). Qed. End FFTheory. (* -------------------------------------------------------------------- *) Section Nbh. Context {R : realType}. Inductive nbh : \bar R -> predArgType := | NFin (c e : R) of (0 < e) : nbh c%:E | NPInf (M : R) : nbh +oo | NNInf (M : R) : nbh -oo. Coercion pred_of_nbh l (v : nbh l) := match v with | @NFin l e _ => [pred x : R | `|x - l| < e] | @NPInf M => [pred x : R | x > M] | @NNInf M => [pred x : R | x < M] end. End Nbh. (* -------------------------------------------------------------------- *) Section NbhElim. Context {R : realType}. Lemma nbh_finW c (P : forall x, nbh x -> Prop) : (forall e (h : 0 < e), P _ (@NFin R c e h)) -> forall (v : nbh c%:E), P _ v. Proof. move=> ih; move: {-2}c%:E (erefl c%:E). by move=> e eE v; case: v eE => // c' e' h [->]. Qed. Lemma nbh_pinfW (P : forall x, nbh x -> Prop) : (forall M, P _ (@NPInf R M)) -> forall (v : nbh +oo), P _ v. Proof. move=> ih; move: {-2}+oo%E (erefl (@EPInf R)). by move=> e eE v; case: v eE => // c' e' h [->]. Qed. Lemma nbh_ninfW (P : forall x, nbh x -> Prop) : (forall M, P _ (@NNInf R M)) -> forall (v : nbh -oo), P _ v. Proof. move=> ih ; move: {-2}-oo%E (erefl (@ENInf R)). by move=> e eE v; case: v eE => // c' e' h [->]. Qed. End NbhElim. Arguments nbh_finW : clear implicits. Arguments nbh_pinfW : clear implicits. Arguments nbh_ninfW : clear implicits. (* -------------------------------------------------------------------- *) Definition eclamp {R : realType} (e : R) := if e <= 0 then 1 else e. Lemma gt0_clamp {R : realType} (e : R) : 0 < eclamp e. Proof. by rewrite /eclamp; case: (lerP e 0) => h //; apply/ltr01. Qed. Lemma eclamp_id {R : realType} (e : R) : 0 < e -> eclamp e = e. Proof. by rewrite ltNge /eclamp => /negbTE ->. Qed. Definition B1 {R : realType} (x : R) := @NFin R x 1 ltr01. Definition B {R : realType} (x e : R) := @NFin R x (eclamp e) (gt0_clamp e). (* -------------------------------------------------------------------- *) Lemma separable_le {R : realType} (l1 l2 : \bar R) : (l1 < l2)%E -> exists (v1 : nbh l1) (v2 : nbh l2), forall x y, x \in v1 -> y \in v2 -> x < y. Proof. case: l1 l2 => [l1||] [l2||] //= lt_l12; last first. + exists (NNInf 0), (NPInf 1) => x y; rewrite !inE => lt1 lt2. by apply/(lt_trans lt1)/(lt_trans ltr01). + exists (NNInf (l2-1)), (B1 l2) => x y; rewrite !inE. rewrite ltr_norml [-1 < _]ltr_subr_addl. by move => lt1 /andP[lt2 _]; apply/(lt_trans lt1). + exists (B1 l1), (NPInf (l1+1)) => x y; rewrite !inE. rewrite ltr_norml ltr_subl_addr [1+_]addrC => /andP[_]. by move=> lt1 lt2; apply/(lt_trans lt1). pose e := l2 - l1; exists (B l1 (e/2%:R)), (B l2 (e/2%:R)). have gt0_e: 0 < e by rewrite subr_gt0. move=> x y; rewrite !inE/= /eclamp pmulr_rle0 // invr_le0. rewrite lern0 /= !ltr_distl => /andP[_ lt1] /andP[lt2 _]. apply/(lt_trans lt1)/(le_lt_trans _ lt2). rewrite ler_subr_addl addrCA -mulrDl -mulr2n -mulr_natr. by rewrite mulfK ?pnatr_eq0 //= /e addrCA subrr addr0. Qed. Lemma separable {R : realType} (l1 l2 : \bar R) : l1 != l2 -> exists (v1 : nbh l1) (v2 : nbh l2), forall x, x \notin [predI v1 & v2]. Proof. wlog: l1 l2 / (l1 < l2)%E => [wlog ne_l12|le_l12 _]. case/boolP: (l1 < l2)%E => [/wlog/(_ ne_l12)//|]. rewrite -leNgt le_eqVlt eq_sym (negbTE ne_l12) /=. case/wlog=> [|x [y h]]; first by rewrite eq_sym. by exists y, x=> z; rewrite inE andbC /= (h z). case/separable_le: le_l12 => [v1] [v2] h; exists v1, v2. move=> x; apply/negP; rewrite inE/= => /andP[] xv1 xv2. by have := h _ _ xv1 xv2; rewrite ltxx. Qed. (* -------------------------------------------------------------------- *) Section SequenceLim. Variable (R : realType). Implicit Types (u v : nat -> R). Definition ncvg u l := forall v : nbh l, exists K, forall n, (K <= n)%N -> u n \in v. Definition iscvg (u : nat -> R) := exists l, ncvg u l%:E. Definition nbounded u := exists v : nbh 0%:E, forall n, u n \in v. Lemma nboundedP u : reflect (exists2 M, 0 < M & forall n, `|u n| < M) `[< nbounded u >]. Proof. apply: (iffP idP) => [/asboolP[]|]; first elim/nbh_finW. move=> M /= gt0_M cv; exists M => [|n] //. by have := cv n; rewrite inE subr0. case=> M _ cv; apply/asboolP; exists (B 0 M) => n; rewrite inE subr0. by rewrite eclamp_id // (@le_lt_trans _ _ `|u 0%N|). Qed. End SequenceLim. (* -------------------------------------------------------------------- *) Notation "c %:S" := (fun _ : nat => c) (at level 2, format "c %:S"). Section SeqLimTh. Variable (R : realType). Implicit Types (u v : nat -> R) (c : R) (l : \bar R). Lemma ncvg_uniq u l1 l2 : ncvg u l1 -> ncvg u l2 -> l1 = l2. Proof. move=> cv1 cv2; apply/eqP; case: (l1 =P l2) => // /eqP. case/separable=> [n1] [n2] h; move: (cv1 n1) (cv2 n2). case=> [K1 c1] [K2 c2]; pose K := maxn K1 K2. move/(_ (u K)): h; rewrite !inE/= !(c1, c2) //. by apply/leq_maxl. by apply/leq_maxr. Qed. Lemma ncvg_eq_from K v u l : (forall n, (K <= n)%N -> u n = v n) -> ncvg v l -> ncvg u l. Proof. move=> eq cu nb; case: (cu nb) => Ku {}cu; exists (maxn K Ku) => n. by rewrite geq_max => /andP[leK leKu]; rewrite eq // cu. Qed. Lemma ncvg_eq v u l : u =1 v -> ncvg v l -> ncvg u l. Proof. by move=> eq; apply: (@ncvg_eq_from 0). Qed. Lemma ncvg_le_from K v u (lv lu : \bar R) : (forall n, (K <= n)%N -> u n <= v n) -> ncvg v lv -> ncvg u lu -> (lu <= lv)%E. Proof. move=> le_uv cv cu; rewrite leNgt; apply/negP=> /separable_le. case=> [v1] [v2] h; have [] := (cv v1, cu v2). case=> [K1 vv1] [K2 uv2]; pose_big_enough K'. have []// := And3 (le_uv K' _) (vv1 K' _) (uv2 K' _). 2: by close. by move=> le h1 h2; have := h _ _ h1 h2; rewrite ltNge le. Qed. Lemma ncvg_le v u (lv lu : \bar R) : u <=1 v -> ncvg v lv -> ncvg u lu -> (lu <= lv)%E. Proof. by move=> le_uv; apply/(@ncvg_le_from 0). Qed. Lemma ncvg_nbounded u x : ncvg u x%:E -> nbounded u. Proof. (* FIXME: factor out `sup` of a finite set *) case/(_ (B x 1)) => K cu; pose S := [seq `|u n| | n <- iota 0 K]. pose M : R := sup [set x : R | x \in S]; pose e := Num.max (`|x| + 1) (M + 1). apply/asboolP/nboundedP; exists e => [|n]; first by rewrite lt_maxr ltr_paddl. case: (ltnP n K); last first. move/cu; rewrite inE eclamp_id ?ltr01 // => ltunBx1. rewrite lt_maxr; apply/orP; left; rewrite -[u n](addrK x) addrAC. by apply/(le_lt_trans (ler_norm_add _ _)); rewrite addrC ltr_add2l. move=> lt_nK; have: `|u n| \in S; first by apply/map_f; rewrite mem_iota. move=> un_S; rewrite lt_maxr; apply/orP; right. case E: {+}K lt_nK => [|k] // lt_nSk; apply/ltr_spaddr; first apply/ltr01. suff : has_sup (fun x : R => x \in S) by move/sup_upper_bound/ubP => ->. split; first by exists `|u 0%N|; rewrite /S E inE eqxx. elim: {+}S => [|v s [ux /ubP hux]]; first by exists 0; apply/ubP. exists (Num.max v ux); apply/ubP=> y; rewrite inE => /orP[/eqP->|]. by rewrite le_maxr lexx. by move/hux=> le_yux; rewrite le_maxr le_yux orbT. Qed. Lemma nboundedC c : nbounded c%:S. Proof. apply/asboolP/nboundedP; exists (`|c| + 1). by rewrite ltr_spaddr. by move=> _; rewrite ltr_addl. Qed. Lemma ncvgC c : ncvg c%:S c%:E. Proof. elim/nbh_finW => e /= gt0_e; exists 0%N => n _. by rewrite inE subrr normr0. Qed. Lemma ncvgD u v lu lv : ncvg u lu%:E -> ncvg v lv%:E -> ncvg (u \+ v) (lu + lv)%:E. Proof. move=> cu cv; elim/nbh_finW => e /= gt0_e; pose z := e / 2%:R. case: (cu (B lu z)) (cv (B lv z)) => [ku {}cu] [kv {}cv]. exists (maxn ku kv) => n; rewrite geq_max => /andP[leu lev]. rewrite inE opprD addrACA (le_lt_trans (ler_norm_add _ _)) //. move: (cu _ leu) (cv _ lev); rewrite !inE eclamp_id. by rewrite mulr_gt0 // invr_gt0 ltr0Sn. move=> cu' cv'; suff ->: e = z + z by rewrite ltr_add. by rewrite -mulrDl -mulr2n -mulr_natr mulfK ?pnatr_eq0. Qed. Lemma ncvgN u lu : ncvg u lu -> ncvg (- u) (- lu). Proof. case: lu => [lu||] cu /=; first last. + elim/nbh_pinfW=> M; case: (cu (NNInf (-M))) => K {}cu. by exists K => n /cu; rewrite !inE ltr_oppr. + elim/nbh_ninfW=> M; case: (cu (NPInf (-M))) => K {}cu. by exists K => n /cu; rewrite !inE ltr_oppl. elim/nbh_finW => e /= gt0_e; case: (cu (B lu e)). by move=> K {}cu; exists K=> n /cu; rewrite !inE -opprD normrN eclamp_id. Qed. Lemma ncvgN_fin u lu : ncvg u lu%:E -> ncvg (- u) (- lu)%:E. Proof. by apply/ncvgN. Qed. Lemma ncvgB u v lu lv : ncvg u lu%:E -> ncvg v lv%:E -> ncvg (u \- v) (lu - lv)%:E. Proof. by move=> cu cv; apply/ncvgD/ncvgN_fin. Qed. Lemma ncvg_abs u lu : ncvg u lu%:E -> ncvg (fun n => `|u n|) `|lu|%:E. Proof. move=> cu; elim/nbh_finW => e /= gt0_e; case: (cu (B lu e)). move=> K {}cu; exists K=> n /cu; rewrite !inE eclamp_id //. by move/(le_lt_trans (ler_dist_dist _ _)). Qed. Lemma ncvg_abs0 u : ncvg (fun n => `|u n|) 0%:E -> ncvg u 0%:E. Proof. move=> cu; elim/nbh_finW => e /= gt0_e; case: (cu (B 0 e)). by move=> K {}cu; exists K=> n /cu; rewrite !inE !subr0 eclamp_id // normr_id. Qed. Lemma ncvgMl u v : ncvg u 0%:E -> nbounded v -> ncvg (u \* v) 0%:E. move=> cu /asboolP/nboundedP [M gt0_M ltM]; elim/nbh_finW => e /= gt0_e. case: (cu (B 0 (e / (M + 1)))) => K {}cu; exists K => n le_Kn. rewrite inE subr0 normrM; apply/(@lt_trans _ _ (e / (M + 1) * M)). apply/ltr_pmul => //; have /cu := le_Kn; rewrite inE subr0 eclamp_id //. by rewrite mulr_gt0 // invr_gt0 addr_gt0. rewrite -mulrAC -mulrA gtr_pmulr // ltr_pdivr_mulr ?addr_gt0 //. by rewrite mul1r ltr_addl. Qed. Lemma ncvgMr u v : ncvg v 0%:E -> nbounded u -> ncvg (u \* v) 0%:E. Proof. move=> cv bu; apply/(@ncvg_eq (v \* u)). by move=> x; rewrite /= mulrC. by apply/ncvgMl. Qed. Lemma ncvgM u v lu lv : ncvg u lu%:E -> ncvg v lv%:E -> ncvg (u \* v) (lu * lv)%:E. Proof. move=> cu cv; pose a := u \- lu%:S; pose b := v \- lv%:S. have eq: (u \* v) =1 (lu * lv)%:S \+ ((lu%:S \* b) \+ (a \* v)). move=> n; rewrite {}/a {}/b /= [u n+_]addrC [(_+_)*(v n)]mulrDl. rewrite !addrA -[LHS]add0r; congr (_ + _); rewrite mulrDr. by rewrite !(mulrN, mulNr) (addrCA (lu * lv)) subrr addr0 subrr. apply/(ncvg_eq eq); rewrite -[X in X%:E]addr0; apply/ncvgD. by apply/ncvgC. rewrite -[X in X%:E]addr0; apply/ncvgD. + apply/ncvgMr; first rewrite -[X in X%:E](subrr lv). by apply/ncvgB/ncvgC. by apply/nboundedC. + apply/ncvgMl; first rewrite -[X in X%:E](subrr lu). by apply/ncvgB/ncvgC. by apply/(ncvg_nbounded cv). Qed. Lemma ncvgZ c u lu : ncvg u lu%:E -> ncvg (c \*o u) (c * lu)%:E. Proof. by move=> cu; apply/ncvgM => //; apply/ncvgC. Qed. Lemma ncvg_leC c u (lu : \bar R) : (forall n, u n <= c) -> ncvg u lu -> (lu <= c%:E)%E. Proof. by move=> le cu; apply/(@ncvg_le c%:S u)=> //; apply/ncvgC. Qed. Lemma ncvg_geC c u (lu : \bar R) : (forall n, c <= u n) -> ncvg u lu -> (c%:E <= lu)%E. Proof. by move=> le cu; apply/(@ncvg_le u c%:S)=> //; apply/ncvgC. Qed. Lemma iscvgC c : iscvg c%:S. Proof. by exists c; apply/ncvgC. Qed. Hint Resolve iscvgC : core. Lemma iscvgD (u v : nat -> R) : iscvg u -> iscvg v -> iscvg (u \+ v). Proof. by case=> [lu cu] [lv cv]; exists (lu + lv); apply/ncvgD. Qed. Lemma iscvg_sum {I : eqType} (u : I -> nat -> R) r : (forall i, i \in r -> iscvg (u i)) -> iscvg (fun n => \sum_(i <- r) u i n). Proof. elim: r => [|i r ih] h. by exists 0; apply/(@ncvg_eq 0%:S)/ncvgC => n; rewrite big_nil. case: ih => [j jr|c cv]; first by apply/h; rewrite inE jr orbT. have [l cl]: iscvg (u i) by apply/h; rewrite inE eqxx. exists (c + l); have := ncvgD cv cl; apply/ncvg_eq. by move=> n; rewrite big_cons addrC. Qed. Lemma iscvg_eq (u v : nat -> R) : u =1 v -> iscvg v -> iscvg u. Proof. by move=> equv [l h]; exists l; apply/(ncvg_eq equv). Qed. Lemma ncvg_sub h u lu : {homo h : x y / (x < y)%N} -> ncvg u lu -> ncvg (fun n => u (h n)) lu. Proof. move=> mono_h cvu v; case: (cvu v)=> K {}cvu; exists K. move=> n le_Kn; apply/cvu; apply/(leq_trans le_Kn). elim: {le_Kn} n => [|n ih] //; apply/(leq_ltn_trans ih). by rewrite mono_h. Qed. Lemma iscvg_sub σ u : {homo σ : x y / (x < y)%N} -> iscvg u -> iscvg (u \o σ). Proof. by move=> homoσ [l h]; exists l; apply/ncvg_sub. Qed. Lemma ncvg_shift k (u : nat -> R) l : ncvg u l <-> ncvg (fun n => u (n + k)%N) l. Proof. split => h v; move/(_ v): h => [K h]. + by exists K => n leKn; apply/h/(leq_trans leKn)/leq_addr. + exists (K + k)%N => n leKkn; rewrite -[n](@subnK k). * by apply/(leq_trans _ leKkn)/leq_addl. apply/h/(@leq_trans ((K+k) - k))/leq_sub2r => //. by rewrite addnK. Qed. Lemma iscvg_shift k (u : nat -> R) : iscvg u <-> iscvg (fun n => u (n + k)%N). Proof. by split=> -[l h]; exists l; apply/(ncvg_shift _ u). Qed. Lemma ncvg_gt (u : nat -> R) (l1 l2 : \bar R) : (l1 < l2)%E -> ncvg u l2 -> exists K, forall n, (K <= n)%N -> (l1 < (u n)%:E)%E. Proof. case: l1 l2 => [l1||] [l2||] //=; first last. + by move=> _ _; exists 0%N => ? ?; exact: ltNyr. + by move=> _ _; exists 0%N => ? ?; exact: ltNyr. + by move=> _ /(_ (NPInf l1)) [K cv]; exists K => n /cv. move=> lt_12; pose e := l2 - l1 => /(_ (B l2 e)). case=> K cv; exists K => n /cv; rewrite !inE eclamp_id ?subr_gt0 //. rewrite ltr_distl => /andP[] /(le_lt_trans _) h _; apply: h. by rewrite {cv}/e opprB addrCA subrr addr0. Qed. Lemma ncvg_lt (u : nat -> R) (l1 l2 : \bar R) : (l1 < l2)%E -> ncvg u l1 -> exists K, forall n, (K <= n)%N -> ((u n)%:E < l2)%E. Proof. move=> lt_12 cv_u_l1; case: (@ncvg_gt (- u) (-l2) (-l1)). by rewrite lte_opp2. by apply/ncvgN. by move=> K cv; exists K => n /cv; rewrite (@lte_opp2 _ _ (u n)%:E). Qed. Lemma ncvg_homo_lt (u : nat -> R) (l1 l2 : \bar R) : (forall m n, (m <= n)%N -> u m <= u n) -> (l1 < l2)%E -> ncvg u l1 -> forall n, ((u n)%:E < l2)%E. Proof. move=> homo_u lt_12 cvu n; have [K {cvu}cv] := ncvg_lt lt_12 cvu. case: (leqP n K) => [/homo_u|/ltnW /cv //]. by move/lee_tofin/le_lt_trans; apply; apply/cv. Qed. Lemma ncvg_homo_le (u : nat -> R) (l : \bar R) : (forall m n, (m <= n)%N -> u m <= u n) -> ncvg u l -> forall n, ((u n)%:E <= l)%E. Proof. move=> homo_u cvu n; rewrite leNgt. by apply/negP => /ncvg_homo_lt /(_ cvu) -/(_ homo_u n); rewrite ltxx. Qed. End SeqLimTh. (* -------------------------------------------------------------------- *) Section LimOp. Context {R : realType}. Implicit Types (u v : nat -> R). Definition nlim u : \bar R := if @idP `[< exists l, `[< ncvg u l >] >] is ReflectT Px then xchoose (asboolP _ Px) else -oo. Lemma nlim_ncvg u : (exists l, ncvg u l) -> ncvg u (nlim u). Proof. case=> l cv_u_l; rewrite /nlim; case: {-}_ / idP; last first. by case; apply/asboolP; exists l; apply/asboolP. by move=> p; apply/asboolP/(xchooseP (asboolP _ p)). Qed. Lemma nlim_out u : ~ (exists l, ncvg u l) -> nlim u = -oo%E. Proof. move=> h; rewrite /nlim; case: {-}_ / idP => // p. by case: h; case/asboolP: p => l /asboolP; exists l. Qed. CoInductive nlim_spec (u : nat -> R) : \bar R -> Type := | NLimCvg l : ncvg u l -> nlim_spec u l | NLimOut : ~ (exists l, ncvg u l) -> nlim_spec u -oo. Lemma nlimP u : nlim_spec u (nlim u). Proof. case/boolP: `[< exists l, `[< ncvg u l >] >] => /asboolP/exists_asboolP/asboolP. by move/nlim_ncvg=> h; apply/NLimCvg. by move=> h; rewrite nlim_out //; apply/NLimOut. Qed. Lemma nlimE (u : nat -> R) (l : \bar R) : ncvg u l -> nlim u = l. Proof. move=> cu; have: (ncvg u (nlim u)). by apply/nlim_ncvg; exists l. by move/(ncvg_uniq cu) => ->. Qed. Lemma nlimC c : nlim c%:S = c%:E :> \bar R. Proof. by move/nlimE: (@ncvgC R c). Qed. Lemma nlimD (u v : nat -> R) : iscvg u -> iscvg v -> nlim (u \+ v) = (nlim u + nlim v)%E. Proof. case=> [lu cu] [lv cv]; rewrite (nlimE cu) (nlimE cv) /=. by rewrite (nlimE (ncvgD cu cv)). Qed. Lemma eq_from_nlim K (v u : nat -> R) : (forall n, (K <= n)%N -> u n = v n) -> nlim u = nlim v. Proof. move=> eq; have h := ncvg_eq_from eq; case: (nlimP v). by move=> l cv; have cu := h _ cv; rewrite (nlimE cu). move=> Ncv; rewrite nlim_out //; case=> l cu. apply: Ncv; exists l; apply/(@ncvg_eq_from _ K u) => //. by move=> n /eq /esym. Qed. Lemma eq_nlim (v u : nat -> R) : u =1 v -> nlim u = nlim v. Proof. by move=> eq; apply/(@eq_from_nlim 0) => n _; apply/eq. Qed. Lemma nlim_bump (u : nat -> R) : nlim (fun n => u n.+1) = nlim u. Proof. case: (nlimP u) => [l cu|Ncu]. suff: ncvg (fun n => u n.+1) l by move/nlimE. move=> v; case/(_ v): cu => K cu; exists K => n le_Kn. by apply/cu; apply/(leq_trans le_Kn). rewrite nlim_out //; case=> l cu; apply/Ncu; exists l. move=> v; case/(_ v): cu => K cu; exists K.+1 => n le_Kn. rewrite -[n]prednK; first by apply/(leq_trans _ le_Kn). by apply/cu; rewrite -ltnS prednK ?(leq_trans _ le_Kn). Qed. Lemma nlim_lift (u : nat -> R) p : nlim (fun n => u (n + p)%N) = nlim u. Proof. elim: p => [|p ih]; first by apply/eq_nlim=> k; rewrite addn0. rewrite -ih -[in RHS]nlim_bump; apply/eq_nlim=> k /=. by rewrite addSnnS. Qed. Lemma nlim_sum {I : eqType} (u : I -> nat -> R) (r : seq I) : (forall i, i \in r -> iscvg (u i)) -> nlim (fun n => \sum_(i <- r) (u i) n) = (\sum_(i <- r) nlim (u i))%E. Proof. elim: r => /= [|i r ih] h; first rewrite big_nil. by rewrite (@eq_nlim 0%:S) ?nlimC //= => n; rewrite big_nil. rewrite big_cons -ih -?nlimD. by move=> j jr; apply/h; rewrite inE jr orbT. by apply/h; rewrite inE eqxx. by apply/iscvg_sum=> j jr; apply/h; rewrite inE jr orbT. by apply/eq_nlim=> n /=; rewrite big_cons. Qed. Lemma nlim_sumR {I : eqType} (u : I -> nat -> R) (r : seq I) : (forall i, i \in r -> iscvg (u i)) -> nlim (fun n => \sum_(i <- r) (u i) n) = (\sum_(i <- r) (fine (nlim (u i)) : R))%:E. Proof. move=> h; rewrite nlim_sum //; elim: r h => [|i r ih] h. by rewrite !big_nil. rewrite !big_cons; case: (h i); first by rewrite inE eqxx. move=> c /nlimE ->; rewrite ih // => j jr. by apply/h; rewrite inE jr orbT. Qed. Lemma nlim_sup (u : nat -> R) l : (forall n m, (n <= m)%N -> u n <= u m) -> ncvg u l%:E -> sup [set r | exists n, r = u n] = l. Proof. move=> mn_u cv_ul; set S := (X in sup X); suff: ncvg u (sup S)%:E. by move/nlimE; move/nlimE: cv_ul => -> [->]. elim/nbh_finW=> /= e gt0_e; have sS: has_sup S. split; first exists (u 0%N). by exists 0%N. exists l; apply/ubP => _ [n ->]. by rewrite -lee_fin; apply/ncvg_homo_le. have /sup_adherent := sS => /(_ _ gt0_e) [r] [N ->] lt_uN. exists N => n le_Nn; rewrite !inE distrC ger0_norm ?subr_ge0. by move/ubP : (sup_upper_bound sS) => -> //; exists n. by rewrite ltr_subl_addr -ltr_subl_addl (lt_le_trans lt_uN) ?mn_u. Qed. End LimOp. (* -------------------------------------------------------------------- *)