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 *)(* -------------------------------------------------------------------- *)(******************************************************************************)(* An axiomatization of real numbers *)(* *)(* This file provides a classical axiomatization of real numbers as a *)(* discrete real archimedean field with in particular a theory of floor and *)(* ceil. *)(* *)(* realType == type of real numbers *)(* sup A == where A : set R with R : realType, the supremum of A when *)(* it exists, 0 otherwise *)(* inf A := - sup (- A) *)(* *)(* The mixin corresponding to realType extends an archiFieldType with two *)(* properties: *)(* - when sup A exists, it is an upper bound of A (lemma sup_upper_bound) *)(* - when sup A exists, there exists an element x in A such that *)(* sup A - eps < x for any 0 < eps (lemma sup_adherent) *)(* *)(* Rint == the set of real numbers that can be written as z%:~R, *)(* i.e., as an integer *)(* Rtoint r == r when r is an integer, 0 otherwise *)(* floor_set x := [set y | Rtoint y /\ y <= x] *)(* Rfloor x == the floor of x as a real number *)(* floor x == the floor of x as an integer (type int) *)(* range1 x := [set y |x <= y < x + 1] *)(* Rceil x == the ceil of x as a real number, i.e., - Rfloor (- x) *)(* ceil x := - floor (- x) *)(* *)(******************************************************************************)
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 set_interval.
From mathcomp.classical Require Import mathcomp_extra.
Require Import Setoid.
Declare Scope real_scope.
(* -------------------------------------------------------------------- *)Set Implicit Arguments.
Unset Strict Implicit.
Unset Printing Implicit Defensive.
Unset SsrOldRewriteGoalsOrder.
Import Order.TTheory Order.Syntax GRing.Theory Num.Def Num.Theory.
(* -------------------------------------------------------------------- *)Delimit Scope real_scope with real.
LocalOpen Scope classical_set_scope.
LocalOpen Scope ring_scope.
Sectionsubr_image.
VariableR : numDomainType.
Implicit Types (E : set R) (x : R).
Lemmahas_ub_lbNE : has_ubound E <-> has_lbound (-%R @` E).
Proof.
rewrite has_lb_ubN image_comp /comp /=.
byunder eq_fun dorewrite opprK; rewrite image_id.
Qed.
Lemmahas_lbound0 : has_lbound (@set0 R). Proof. byexists0. Qed.
Lemmahas_ubound0 : has_ubound (@set0 R). Proof. byexists0. Qed.
Lemmaubound0 : ubound (@set0 R) = setT.
Proof. byrewrite predeqE => r; split => // _. Qed.
LemmalboundT : lbound [set: R] = set0.
Proof.
rewrite predeqE => r; split => // /(_ (r - 1) Logic.I).
rewrite ler_subr_addl addrC -ler_subr_addl subrr.
byrewrite real_leNgt ?realE?ler01// ?lexx// ltr01.
Qed.
Endsubr_image.
Sectionhas_bound_lemmas.
VariableR : realDomainType.
Implicit TypesE : set R.
Implicit Typesx : R.
Lemmahas_ub_image_normE : has_ubound (normr @` E) -> has_ubound E.
Proof.
case => M /ubP uM; exists `|M|; apply/ubP => r rS.
rewrite (le_trans (real_ler_norm _)) ?num_real //.
rewrite (le_trans (uM _ _)) ?real_ler_norm?num_real //.
byexistsr.
Qed.
Lemmahas_inf_supNE : has_sup (-%R @` E) <-> has_inf E.
Proof.
split=> [ [NEn0 [x /ub_lbN xubE]] | [En0 [x /lb_ubN xlbe]] ].
bysplit; [apply/nonemptyN|rewrite -[E]setNK; exists (- x)].
bysplit; [apply/nonemptyN|exists (- x)].
Qed.
Lemmahas_supPn {E} : E !=set0 ->
~ has_sup E <-> (forallx, exists2 y, E y & x < y).
Proof.
move=> nzE; split=> [/asboolPn|/has_ubPn h [_]] //.
byrewrite asbool_and (asboolT nzE) /= => /asboolP/has_ubPn.
Qed.
Endhas_bound_lemmas.
(* -------------------------------------------------------------------- *)ModuleReal.
SectionMixin.
Variable (R : archiFieldType).
Recordmixin_of : Type := Mixin {
_ :
forallE : set (Num.ArchimedeanField.sort R),
has_sup E -> ubound E (supremum 0 E) ;
_ :
forall (E : set (Num.ArchimedeanField.sort R)) (eps : R), 0 < eps ->
has_sup E -> exists2 e : R, E e & (supremum 0 E - eps) < e ;
}.
EndMixin.
DefinitionEtaMixinRsup_upper_boundsup_adherent :=
let_ := @Mixin R sup_upper_bound sup_adherent in
@Mixin (Num.ArchimedeanField.Pack (Num.ArchimedeanField.class R))
sup_upper_bound sup_adherent.
SectionClassDef.
Recordclass_of (R : Type) : Type := Class {
base : Num.ArchimedeanField.class_of R;
mixin_rcf : Num.real_closed_axiom (Num.NumDomain.Pack base);
(* TODO: ajouter une structure de pseudoMetricNormedDomain *)
mixin : mixin_of (Num.ArchimedeanField.Pack base)
}.
Local Coercionbase : class_of >-> Num.ArchimedeanField.class_of.
Local Coercionbase_rcf R (c : class_of R) : Num.RealClosedField.class_of R :=
@Num.RealClosedField.Class_c (@mixin_rcf _ c).
Structuretype := Pack {sort; _ : class_of sort; _ : Type}.
Local Coercionsort : type >-> Sortclass.
Variables (T : Type) (cT : type).
Definitionclass := let: Pack _ c _ as cT' := cT return class_of cT' in c.
Definitionclonecofphant_idclassc := @Pack T c T.
LetxT := let: Pack T _ _ := cT in T.
Notationxclass := (class : class_of xT).
Definitionrcf_axiom {R} (cR : Num.RealClosedField.class_of R) :
Num.real_closed_axiom (Num.NumDomain.Pack cR) :=
match cR with Num.RealClosedField.Class_ax => ax end.
Coercionrcf_axiom : Num.RealClosedField.class_of >-> Num.real_closed_axiom.
Definitionpackb0 (m0 : mixin_of (@Num.ArchimedeanField.Pack T b0)) :=
funbTb & phant_id (Num.ArchimedeanField.class bT) b =>
fun (bTr : rcfType) (br : Num.RealClosedField.class_of bTr) &
phant_id (Num.RealClosedField.class bTr) br =>
funcra & phant_id (@rcf_axiom bTr br) cra =>
funm & phant_id m0 m => Pack (@ClassTbcram) T.
DefinitioneqType := @Equality.Pack cT xclass.
DefinitionchoiceType := @Choice.Pack cT xclass.
DefinitionporderType := @Order.POrder.Pack ring_display cT xclass.
DefinitionlatticeType := @Order.Lattice.Pack ring_display cT xclass.
DefinitiondistrLatticeType := @Order.DistrLattice.Pack ring_display cT xclass.
DefinitionorderType := @Order.Total.Pack ring_display cT xclass.
DefinitionzmodType := @GRing.Zmodule.Pack cT xclass.
DefinitionringType := @GRing.Ring.Pack cT xclass.
DefinitioncomRingType := @GRing.ComRing.Pack cT xclass.
DefinitionunitRingType := @GRing.UnitRing.Pack cT xclass.
DefinitioncomUnitRingType := @GRing.ComUnitRing.Pack cT xclass.
DefinitionidomainType := @GRing.IntegralDomain.Pack cT xclass.
DefinitionnumDomainType := @Num.NumDomain.Pack cT xclass.
DefinitionnormedZmodType := NormedZmodType numDomainType cT xclass.
DefinitionfieldType := @GRing.Field.Pack cT xclass.
DefinitionrealDomainType := @Num.RealDomain.Pack cT xclass.
DefinitionnumFieldType := @Num.NumField.Pack cT xclass.
DefinitionrealFieldType := @Num.RealField.Pack cT xclass.
DefinitionarchimedeanFieldType := @Num.ArchimedeanField.Pack cT xclass.
DefinitionrcfType := @Num.RealClosedField.Pack cT xclass.
Definitionjoin_rcfType := @Num.RealClosedField.Pack archimedeanFieldType xclass.
EndClassDef.
ModuleExports.
Coercionbase : class_of >-> Num.ArchimedeanField.class_of.
Coercionbase_rcf : class_of >-> Num.RealClosedField.class_of.
Coercionmixin : class_of >-> mixin_of.
Coercionsort : type >-> Sortclass.
Bind Scope ring_scope with sort.
CoercioneqType : type >-> Equality.type.
CanonicaleqType.
CoercionchoiceType : type >-> Choice.type.
CanonicalchoiceType.
CoercionporderType : type >-> Order.POrder.type.
CanonicalporderType.
CoercionlatticeType : type >-> Order.Lattice.type.
CanonicallatticeType.
CoerciondistrLatticeType : type >-> Order.DistrLattice.type.
CanonicaldistrLatticeType.
CoercionorderType : type >-> Order.Total.type.
CanonicalorderType.
CoercionzmodType : type >-> GRing.Zmodule.type.
CanonicalzmodType.
CoercionringType : type >-> GRing.Ring.type.
CanonicalringType.
CoercioncomRingType : type >-> GRing.ComRing.type.
CanonicalcomRingType.
CoercionunitRingType : type >-> GRing.UnitRing.type.
CanonicalunitRingType.
CoercioncomUnitRingType : type >-> GRing.ComUnitRing.type.
CanonicalcomUnitRingType.
CoercionidomainType : type >-> GRing.IntegralDomain.type.
CanonicalidomainType.
CoercionnumDomainType : type >-> Num.NumDomain.type.
CanonicalnumDomainType.
CoercionnormedZmodType : type >-> Num.NormedZmodule.type.
CanonicalnormedZmodType.
CoercionrealDomainType : type >-> Num.RealDomain.type.
CanonicalrealDomainType.
CoercionfieldType : type >-> GRing.Field.type.
CanonicalfieldType.
CoercionnumFieldType : type >-> Num.NumField.type.
CanonicalnumFieldType.
CoercionrealFieldType : type >-> Num.RealField.type.
CanonicalrealFieldType.
CoercionarchimedeanFieldType : type >-> Num.ArchimedeanField.type.
CanonicalarchimedeanFieldType.
CoercionrcfType : type >-> Num.RealClosedField.type.
CanonicalrcfType.
Canonicaljoin_rcfType.
NotationrealType := type.
NotationRealType T m := (@pack T _ m _ _ id _ _ id _ id _ id).
NotationRealMixin := EtaMixin.
Notation"[ 'realType' 'of' T 'for' cT ]" := (@clone T cT _ idfun)
(at level0, format"[ 'realType' 'of' T 'for' cT ]") : form_scope.
Notation"[ 'realType' 'of' T ]" := (@clone T _ _ id)
(at level0, format"[ 'realType' 'of' T ]") : form_scope.
EndExports.
EndReal.
Export Real.Exports.
(* -------------------------------------------------------------------- *)Definitionsup {R : realType} := @supremum _ R 0.
(*Local Notation "-` E" := [pred x | - x \in E] (at level 35, right associativity) : fun_scope.*)Definitioninf {R : realType} (E : set R) := - sup (-%R @` E).
(* -------------------------------------------------------------------- *)Lemmasup_upper_bound {R : realType} (E : set R):
has_sup E -> ubound E (sup E).
Proof. bymove=> supE; case: R E supE=> ? [? ? []]. Qed.
Lemmasup_adherent {R : realType} (E : set R) (eps : R) : 0 < eps ->
has_sup E -> exists2 e : R, E e & (sup E - eps) < e.
Proof. bycase: R E eps=> ? [? ? []]. Qed.
(* -------------------------------------------------------------------- *)SectionIsInt.
Context {R : realFieldType}.
DefinitionRint := [qualify a x : R | `[< existsz, x == z%:~R >]].
FactRint_key : pred_key Rint. Proof. by []. Qed.
CanonicalRint_keyed := KeyedQualifier Rint_key.
LemmaRint_defx : (x \is a Rint) = (`[< existsz, x == z%:~R >]).
Proof. by []. Qed.
LemmaRintPx : reflect (existsz, x = z%:~R) (x \in Rint).
Proof.
byapply/(iffP idP) => [/asboolP[z /eqP]|[z]] ->; [|apply/asboolP]; existsz.
Qed.
LemmaRintCz : z%:~R \is a Rint.
Proof. byapply/RintP; existsz. Qed.
LemmaRint0 : 0 \is a Rint.
Proof. byrewrite -[0](mulr0z 1) RintC. Qed.
LemmaRint1 : 1 \is a Rint.
Proof. byrewrite -[1]mulr1z RintC. Qed.
Hint Resolve Rint0 Rint1 RintC : core.
LemmaRint_subring_closed : subring_closed Rint.
Proof.
split=> // _ _ /RintP[x ->] /RintP[y ->]; apply/RintP.
byexists (x - y); rewrite rmorphB. byexists (x * y); rewrite rmorphM.
Qed.
CanonicalRint_opprPred := OpprPred Rint_subring_closed.
CanonicalRint_addrPred := AddrPred Rint_subring_closed.
CanonicalRint_mulrPred := MulrPred Rint_subring_closed.
CanonicalRint_zmodPred := ZmodPred Rint_subring_closed.
CanonicalRint_semiringPred := SemiringPred Rint_subring_closed.
CanonicalRint_smulrPred := SmulrPred Rint_subring_closed.
CanonicalRint_subringPred := SubringPred Rint_subring_closed.
LemmaRint_ler_addr1 (xy : R) : x \is a Rint -> y \is a Rint ->
(x + 1 <= y) = (x < y).
Proof.
move=> /RintP[xi ->] /RintP[yi ->]; rewrite -{2}[1]mulr1z.
byrewrite -intrD !(ltr_int, ler_int) lez_addr1.
Qed.
LemmaRint_ltr_addr1 (xy : R) : x \is a Rint -> y \is a Rint ->
(x < y + 1) = (x <= y).
move=> /RintP[xi ->] /RintP[yi ->]; rewrite -{3}[1]mulr1z.
byrewrite -intrD !(ltr_int, ler_int) ltz_addr1.
Qed.
EndIsInt.
(* -------------------------------------------------------------------- *)SectionToInt.
Context {R : realType}.
Implicit Typesxy : R.
DefinitionRtoint (x : R) : int :=
if insub x : {? x | x \is a Rint} is Some Px then
xchoose (asboolP _ (tagged Px))
else0.
LemmaRtointK (x : R): x \is a Rint -> (Rtoint x)%:~R = x.
Proof.
move=> Ix; rewrite /Rtoint insubT /= [RHS](eqP (xchooseP (asboolP _ Ix))).
bycongr _%:~R; apply/eq_xchoose.
Qed.
LemmaRtointz (z : int): Rtoint z%:~R = z.
Proof. byapply/eqP; rewrite -(@eqr_int R) RtointK ?rpred_int. Qed.
LemmaRtointn (n : nat): Rtoint n%:R = n%:~R.
Proof. byrewrite -{1}mulrz_nat Rtointz. Qed.
Lemmainj_Rtoint : {in Rint &, injective Rtoint}.
Proof. bymove=> x y Ix Iy /= /(congr1 (@intmul R 1)); rewrite !RtointK. Qed.
LemmaRtointNx : x \is a Rint -> Rtoint (- x) = - Rtoint x.
Proof.
move=> Ir; apply/eqP.
byrewrite -(@eqr_int R) RtointK // ?rpredN // mulrNz RtointK.
Qed.
EndToInt.
(* -------------------------------------------------------------------- *)SectionRealDerivedOps.
VariableR : realType.
Implicit Typesxy : R.
Definitionfloor_setx := [set y : R | (y \is a Rint) && (y <= x)].
DefinitionRfloorx : R := sup (floor_set x).
Definitionfloorx : int := Rtoint (Rfloor x).
Definitionrange1 (x : R) := [set y | x <= y < x + 1].
DefinitionRceilx := - Rfloor (- x).
Definitionceilx := - floor (- x).
EndRealDerivedOps.
(*-------------------------------------------------------------------- *)SectionRealLemmas.
Variables (R : realType).
Implicit TypesE : set R.
Implicit Typesx : R.
Lemmasup_outE : ~ has_sup E -> sup E = 0. Proof. exact: supremum_out. Qed.
Lemmasup0 : sup (@set0 R) = 0. Proof. exact: supremum0. Qed.
Lemmasup1x : sup [set x] = x. Proof. exact: supremum1. Qed.
Lemmasup_ub {E} : has_ubound E -> ubound E (sup E).
Proof.
move=> ubE; apply/ubP=> x x_in_E; move: (x) (x_in_E).
byapply/ubP/sup_upper_bound=> //; split; firstbyexistsx.
Qed.
Lemmasup_ub_strictE : has_ubound E ->
~ E (sup E) -> E `<=` [set r | r < sup E].
Proof.
move=> ubE EsupE r Er; rewrite /mkset lt_neqAle sup_ub // andbT.
byapply/negP => /eqP supEr; move: EsupE; rewrite -supEr.
Qed.
Lemmasup_total {E} x : has_sup E -> down E x \/ sup E <= x.
Proof.
move=> has_supE; rewrite orC.
case: (lerP (sup E) x)=> hx /=; [byleft|right].
have /sup_adherent/(_ has_supE) : 0 < sup E - x byrewrite subr_gt0.
case=> e Ee hlte; apply/downP; existse => //; move: hlte.
byrewrite opprB addrCA subrr addr0 => /ltW.
Qed.
Lemmasup_le_ub {E} x : E !=set0 -> (ubound E) x -> sup E <= x.
Proof.
move=> hasE leEx; set y := sup E; pose z := (x + y) / 2%:R.
have Dz: 2%:R * z = x + y.
byrewrite mulrCA divff ?mulr1 // pnatr_eq0.
have ubE : has_sup E bysplit => //; existsx.
have [/downP [t Et lezt] | leyz] := sup_total z ubE.
rewrite -(ler_add2l x) -Dz -mulr2n -[leRHS]mulr_natl.
rewrite ler_pmul2l ?ltr0Sn //; apply/(le_trans lezt).
bymove/ubP : leEx; exact.
rewrite -(ler_add2r y) -Dz -mulr2n -[leLHS]mulr_natl.
byrewrite ler_pmul2l ?ltr0Sn.
Qed.
Lemmasup_setU (AB : set R) : has_sup B ->
(forallab, A a -> B b -> a <= b) -> sup (A `|` B) = sup B.
Proof.
move=> [B0 [l Bl]] AB; apply/eqP; rewrite eq_le; apply/andP; split.
- apply sup_le_ub => [|x [Ax|]]; firstbyapply: subset_nonempty B0 => ?; right.
bycase: B0 => b Bb; rewrite (le_trans (AB _ _ Ax Bb)) // sup_ub //; existsl.
- bymove=> Bx; rewrite sup_ub //; existsl.
- apply sup_le_ub => // b Bb; apply sup_ub; lastbyright.
byexistsl => x [Ax|Bx]; [rewrite (le_trans (AB _ _ Ax Bb)) // Bl|exact: Bl].
Qed.
Lemmasup_gt (S : set R) (x : R) : S !=set0 ->
(x < sup S -> exists2 y, S y & x < y)%R.
Proof.
move=> S0; rewrite not_exists2P => + g; apply/negP; rewrite -leNgt.
byapply sup_le_ub => // y Sy; move: (g y) => -[// | /negP]; rewrite leNgt.
Qed.
EndRealLemmas.
(* -------------------------------------------------------------------- *)SectionInfTheory.
Variables (R : realType).
Implicit TypesE : set R.
Implicit Typesx : R.
Lemmainf_lower_boundE : has_inf E -> lbound E (inf E).
Proof.
move=> /has_inf_supN /sup_upper_bound /ubP inflb; apply/lbP => x.
byrewrite memNE => /inflb; rewrite ler_oppl.
Qed.
Lemmainf_adherentE (eps : R) : 0 < eps ->
has_inf E -> exists2 e, E e & e < inf E + eps.
Proof.
move=> + /has_inf_supN supNE => /sup_adherent /(_ supNE)[e NEx egtsup].
exists (- e); firstbycase: NEx => x Ex <-{}; rewrite opprK.
byrewrite ltr_oppl -mulN1r mulrDr !mulN1r opprK.
Qed.
Lemmainf_outE : ~ has_inf E -> inf E = 0.
Proof.
move=> ninfE; rewrite -oppr0 -(@sup_out _ (-%R @` E)) => // supNE; apply: ninfE.
exact/has_inf_supN.
Qed.
Lemmainf0 : inf (@set0 R) = 0.
Proof. byrewrite /inf image_set0 sup0 oppr0. Qed.
Lemmainf1x : inf [set x] = x.
Proof. byrewrite /inf image_set1 sup1 opprK. Qed.
Lemmainf_lbE : has_lbound E -> lbound E (inf E).
Proof. bymove/has_lb_ubN/sup_ub/ub_lbN; rewrite setNK. Qed.
Lemmainf_lb_strictE : has_lbound E ->
~ E (inf E) -> E `<=` [set r | inf E < r].
Proof.
move=> lE EinfE r Er; rewrite /mkset lt_neqAle inf_lb // andbT.
byapply/negP => /eqP infEr; move: EinfE; rewrite infEr.
Qed.
Lemmalb_le_infEx : nonempty E -> (lbound E) x -> x <= inf E.
Proof.
bymove=> /(nonemptyN E) En0 /lb_ubN /(sup_le_ub En0); rewrite ler_oppr.
Qed.
Lemmahas_infPnE : nonempty E ->
~ has_inf E <-> (forallx, exists2 y, E y & y < x).
Proof.
move=> nzE; split=> [/asboolPn|/has_lbPn h [_] //].
byrewrite asbool_and (asboolT nzE) /= => /asboolP/has_lbPn.
Qed.
Lemmainf_setU (AB : set R) : has_inf A ->
(forallab, A a -> B b -> a <= b) -> inf (A `|` B) = inf A.
Proof.
move=> hiA AB; congr (- _).
rewrite image_setU setUC sup_setU //; firstexact/has_inf_supN.
bymove=> _ _ [] b Bb <-{} [] a Aa <-{}; rewrite ler_oppl opprK; apply AB.
Qed.
Lemmainf_lt (S : set R) (x : R) : S !=set0 ->
(inf S < x -> exists2 y, S y & y < x)%R.
Proof.
move=> /nonemptyN S0; rewrite /inf ltr_oppl => /sup_gt => /(_ S0)[r [r' Sr']].
bymove=> <-; rewrite ltr_oppr opprK => r'x; existsr'.
Qed.
EndInfTheory.
(* -------------------------------------------------------------------- *)SectionFloorTheory.
VariableR : realType.
Implicit Typesxy : R.
Lemmahas_sup_floor_setx : has_sup (floor_set x).
Proof.
split; [exists (- (Num.bound (-x))%:~R) | exists (Num.bound x)%:~R].
rewrite /floor_set/mkset rpredN rpred_int /= ler_oppl.
case: (ger0P (-x)) => [/archi_boundP/ltW//|].
bymove/ltW/le_trans; apply; rewrite ler0z.
apply/ubP=> y /andP[_] /le_trans; apply.
case: (ger0P x)=> [/archi_boundP/ltW|] //.
bymove/ltW/le_trans; apply; rewrite ler0z.
Qed.
Lemmasup_in_floor_setx : (floor_set x) (sup (floor_set x)).
Proof.
have /(sup_adherent ltr01) [y Fy] := has_sup_floor_set x.
have /sup_upper_bound /ubP /(_ _ Fy) := has_sup_floor_set x.
rewrite le_eqVlt=> /orP[/eqP<-//| lt_yFx].
rewrite ltr_subl_addr -ltr_subl_addl => lt1_FxBy.
pose e := sup (floor_set x) - y; have := has_sup_floor_set x.
move/sup_adherent=> -/(_ e) []; firstbyrewrite subr_gt0.
move=> z Fz; rewrite /e opprB addrCA subrr addr0 => lt_yz.
have /sup_upper_bound /ubP /(_ _ Fz) := has_sup_floor_set x.
rewrite -(ler_add2r (-y)) => /le_lt_trans /(_ lt1_FxBy).
case/andP: Fy Fz lt_yz=> /RintP[yi -> _].
case/andP=> /RintP[zi -> _]; rewrite -rmorphB /= ltrz1 ltr_int.
rewrite lt_neqAle => /andP[ne_yz le_yz].
rewrite -[_-_]gez0_abs ?subr_ge0 // ltz_nat ltnS leqn0.
byrewrite absz_eq0 subr_eq0 eq_sym (negbTE ne_yz).
Qed.
Lemmaisint_Rfloorx : Rfloor x \is a Rint.
Proof. bycase/andP: (sup_in_floor_set x). Qed.
LemmaRfloorEx : Rfloor x = (floor x)%:~R.
Proof. byrewrite /floor RtointK ?isint_Rfloor. Qed.
Lemmamem_rg1_Rfloorx : (range1 (Rfloor x)) x.
Proof.
rewrite /range1/mkset.
have /andP[_ ->] /= := sup_in_floor_set x.
have [|] := pselect ((floor_set x) (Rfloor x + 1)); last first.
rewrite /floor_set => /negP.
byrewrite negb_and -ltNge rpredD // ?(Rint1, isint_Rfloor).
move/ubP : (sup_upper_bound (has_sup_floor_set x)) => h/h.
byrewrite ger_addl ler10.
Qed.
LemmaRfloor_lex : Rfloor x <= x.
Proof. bycase/andP: (mem_rg1_Rfloor x). Qed.
Lemmafloor_lex : (floor x)%:~R <= x.
Proof. byrewrite -RfloorE; exact: Rfloor_le. Qed.
Lemmalt_succ_Rfloorx : x < Rfloor x + 1.
Proof. bycase/andP: (mem_rg1_Rfloor x). Qed.
Lemmarange1z_injx (m1m2 : int) :
(range1 m1%:~R) x -> (range1 m2%:~R) x -> m1 = m2.
Proof.
move=> /andP[m1x x_m1] /andP[m2x x_m2].
wlogsuffices: m1 m2 m1x {x_m1 m2x} x_m2 / (m1 <= m2).
bymove=> ih; apply/eqP; rewrite eq_le !ih.
rewrite -(ler_add2r 1) lez_addr1 -(@ltr_int R) intrD.
exact/(le_lt_trans m1x).
Qed.
Lemmarange1rrx : (range1 x) x.
Proof. byrewrite /range1/mkset lexx /= ltr_addl ltr01. Qed.
Lemmarange1zP (m : int) x : Rfloor x = m%:~R <-> (range1 m%:~R) x.
Proof.
split=> [<-|h]; firstexact/mem_rg1_Rfloor.
apply/eqP; rewrite RfloorE eqr_int; apply/eqP/(@range1z_inj x) => //.
byrewrite /range1/mkset -RfloorE mem_rg1_Rfloor.
Qed.
LemmaRfloor_natz (z : int) : Rfloor z%:~R = z%:~R :> R.
Proof. byapply/range1zP/range1rr. Qed.
LemmaRfloor0 : Rfloor 0 = 0 :> R.
Proof. byrewrite -{1}(mulr0z 1) Rfloor_natz. Qed.
LemmaRfloor1 : Rfloor 1 = 1 :> R.
Proof. byrewrite -{1}(mulr1z 1) Rfloor_natz. Qed.
Lemmale_Rfloor : {homo (@Rfloor R) : x y / x <= y}.
Proof.
move=> x y le_xy; case: lerP=> //=; rewrite -Rint_ler_addr1 ?isint_Rfloor //.
move/(lt_le_trans (lt_succ_Rfloor y))/lt_le_trans/(_ (Rfloor_le x)).
byrewrite ltNge le_xy.
Qed.
LemmaRfloor_ge_intx (n : int) : (n%:~R <= x)= (n%:~R <= Rfloor x).
Proof.
apply/idP/idP; lastbymove/le_trans => /(_ _ (Rfloor_le x)).
bymove/le_Rfloor; apply le_trans; rewrite Rfloor_natz.
Qed.
LemmaRfloor_lt_intx (z : int) : (x < z%:~R) = (Rfloor x < z%:~R).
Proof. byrewrite ltNge Rfloor_ge_int -ltNge. Qed.
LemmaRfloor_le0x : x <= 0 -> Rfloor x <= 0.
Proof. bymove=> ?; rewrite -Rfloor0 le_Rfloor. Qed.
LemmaRfloor_lt0x : x < 0 -> Rfloor x < 0.
Proof. bymove=> x0; rewrite (le_lt_trans _ x0) // Rfloor_le. Qed.
Lemmafloor_natzn : floor (n%:R : R) = n%:~R :> int.
Proof. byrewrite /floor (Rfloor_natz n) Rtointz intz. Qed.
Lemmafloor0 : floor (0 : R) = 0.
Proof. byrewrite /floor Rfloor0 (_ : 0 = 0%:R) // Rtointn. Qed.
Lemmafloor1 : floor (1 : R) = 1.
Proof. byrewrite /floor Rfloor1 (_ : 1 = 1%:R) // Rtointn. Qed.
Lemmafloor_ge0x : (0 <= floor x) = (0 <= x).
Proof. byrewrite -(@ler_int R) -RfloorE -Rfloor_ge_int. Qed.
Lemmafloor_le0x : x <= 0 -> floor x <= 0.
Proof. bymove=> ?; rewrite -(@ler_int R) -RfloorE Rfloor_le0. Qed.
Lemmafloor_lt0x : x < 0 -> floor x < 0.
Proof. bymove=> ?; rewrite -(@ltrz0 R) RtointK ?isint_Rfloor// Rfloor_lt0. Qed.
Lemmale_floor : {homo @floor R : x y / x <= y}.
Proof. bymove=>*; rewrite -(@ler_int R) !RtointK ?isint_Rfloor?le_Rfloor. Qed.
Lemmafloor_neq0x : (floor x != 0) = (x < 0) || (x >= 1).
Proof.
apply/idP/orP => [|[x0|/le_floor r1]]; firstrewrite neq_lt => /orP[x0|x0].
- byleft; apply: contra_lt x0; rewrite floor_ge0.
- byright; rewrite (le_trans _ (floor_le _))// ler1z -gtz0_ge1.
- byrewrite lt_eqF//; apply: contra_lt x0; rewrite floor_ge0.
- byrewrite gt_eqF// (lt_le_trans _ r1)// floor1.
Qed.
Lemmalt_succ_floorx : x < (floor x)%:~R + 1.
Proof. byrewrite -RfloorE lt_succ_Rfloor. Qed.
Lemmafloor_lt_intx (z : int) : (x < z%:~R) = (floor x < z).
Proof. byrewrite Rfloor_lt_int RfloorE ltr_int. Qed.
Lemmafloor_ge_intx (z : int) : (z%:~R <= x) = (z <= floor x).
Proof. byrewrite Rfloor_ge_int RfloorE ler_int. Qed.
Lemmaltr_add_invr (yx : R) : y < x -> existsk, y + k.+1%:R^-1 < x.
Proof.
move=> yx; exists `|floor (x - y)^-1|%N.
rewrite -ltr_subr_addl -{2}(invrK (x - y)%R) ltf_pinv ?qualifE?ltr0n//.
byrewrite invr_gt0 subr_gt0.
rewrite -natr1 natr_absz ger0_norm.
byrewrite floor_ge0 invr_ge0 subr_ge0 ltW.
byrewrite -RfloorE lt_succ_Rfloor.
Qed.
EndFloorTheory.
SectionCeilTheory.
VariableR : realType.
Implicit Typesxy : R.
Lemmaisint_Rceilx : Rceil x \is a Rint.
Proof. byrewrite /Rceil rpredN isint_Rfloor. Qed.
LemmaRceil0 : Rceil 0 = 0 :> R.
Proof. byrewrite /Rceil oppr0 Rfloor0 oppr0. Qed.
LemmaRceil_gex : x <= Rceil x.
Proof. byrewrite /Rceil ler_oppr Rfloor_le. Qed.
Lemmale_Rceil : {homo (@Rceil R) : x y / x <= y}.
Proof. bymove=> x y ?; rewrite ler_oppl opprK le_Rfloor // ler_oppl opprK. Qed.
LemmaRceil_ge0x : 0 <= x -> 0 <= Rceil x.
Proof. bymove=> ?; rewrite -Rceil0 le_Rceil. Qed.
LemmaRceilEx : Rceil x = (ceil x)%:~R.
Proof. byrewrite /Rceil /ceil RfloorE mulrNz. Qed.
Lemmaceil_gex : x <= (ceil x)%:~R.
Proof. byrewrite -RceilE; exact: Rceil_ge. Qed.
Lemmaceil_ge0x : 0 <= x -> 0 <= ceil x.
Proof. bymove/(ge_trans (ceil_ge x)); rewrite -(ler_int R). Qed.
Lemmaceil_gt0x : 0 < x -> 0 < ceil x.
Proof. bymove=> ?; rewrite /ceil oppr_gt0 floor_lt0 // ltr_oppl oppr0. Qed.
Lemmaceil_le0x : x <= 0 -> ceil x <= 0.
Proof. bymove=> x0; rewrite -ler_oppl oppr0 floor_ge0 -ler_oppr oppr0. Qed.
Lemmale_ceil : {homo @ceil R : x y / x <= y}.
Proof. bymove=> x y xy; rewrite ler_oppl opprK le_floor // ler_oppl opprK. Qed.
Lemmaceil_ge_intx (z : int) : (x <= z%:~R) = (ceil x <= z).
Proof. byrewrite /ceil ler_oppl -floor_ge_int// -ler_oppr mulrNz opprK. Qed.
Lemmaceil_lt_intx (z : int) : (z%:~R < x) = (z < ceil x).
Proof. byrewrite ltNge ceil_ge_int -ltNge. Qed.
EndCeilTheory.
(* -------------------------------------------------------------------- *)SectionSup.
Context {R : realType}.
Lemmale_down (S : set R) : S `<=` down S.
Proof. bymove=> x xS; apply/downP; existsx. Qed.
LemmadownK (S : set R) : down (down S) = down S.
Proof.
rewrite predeqE => x; split.
- case/downP => y /downP[z Sz yz xy].
byapply/downP; existsz => //; rewrite (le_trans xy).
- bymove=> Sx; apply/downP; existsx.
Qed.
Lemmahas_sup_down (S : set R) : has_sup (down S) <-> has_sup S.
Proof.
split=> -[nzS nzubS].
case: nzS=> x /downP[y yS le_xy]; split; firstbyexistsy.
case: nzubS=> u /ubP ubS; existsu; apply/ubP=> z zS.
byapply/ubS; apply/downP; existsz.
case: nzS=> x xS; split; firstbyexistsx; apply/le_down.
case: nzubS=> u /ubP ubS; existsu; apply/ubP=> y /downP [].
bymove=> z zS /le_trans; apply; apply/ubS.
Qed.
Lemmale_sup (S1S2 : set R) :
S1 `<=` down S2 -> nonempty S1 -> has_sup S2
-> sup S1 <= sup S2.
Proof.
move=> le_S12 nz_S1 hs_S2; have hs_S1: has_sup S1.
split=> //; case: hs_S2=> _ [x ubx].
existsx; apply/ubP=> y /le_S12 /downP[z zS2 le_yz].
byapply/(le_trans le_yz); move/ubP: ubx; apply.
rewrite leNgt -subr_gt0; apply/negP => lt_sup.
case: (sup_adherent lt_sup hs_S1 )=> x /le_S12 xdS2.
rewrite subKr => lt_S2x; case/downP: xdS2=> z zS2.
move/(lt_le_trans lt_S2x); rewrite ltNge.
bymove/ubP: (sup_upper_bound hs_S2) => ->.
Qed.
Lemmasup_down (S : set R) : sup (down S) = sup S.
Proof.
have [supS|supNS] := pselect (has_sup S); last first.
byrewrite !sup_out // => /has_sup_down.
have supDS : has_sup (down S) byapply/has_sup_down.
apply/eqP; rewrite eq_le !le_sup //.
bycase: supS => -[x xS] _; existsx; apply/le_down.
rewrite downK; exact: le_down.
bycase: supS.
Qed.
Lemmalt_sup_imfset {T : Type} (F : T -> R) l :
has_sup [set y | existsx, y = F x] ->
l < sup [set y | existsx, y = F x] ->
exists2 x, l < F x & F x <= sup [set y | existsx, y = F x].
Proof.
set P := [set y | _] => hs; rewrite -subr_gt0.
move=> /sup_adherent/(_ hs)[_ [x ->]]; rewrite subKr=> lt_lFx.
byexistsx => //; move/ubP : (sup_upper_bound hs) => -> //; existsx.
Qed.
Lemmalt_inf_imfset {T : Type} (F : T -> R) l :
has_inf [set y | existsx, y = F x] ->
inf [set y | existsx, y = F x] < l ->
exists2 x, F x < l & inf [set y | existsx, y = F x] <= F x.
Proof.
set P := [set y | _]; move=> hs; rewrite -subr_gt0.
move=> /inf_adherent/(_ hs)[_ [x ->]]; rewrite addrA [_ + l]addrC addrK.
bymove=> ltFxl; existsx=> //; move/lbP : (inf_lower_bound hs) => -> //; existsx.
Qed.
EndSup.
Lemmaint_lbound_has_minimum (B : set int) i : B !=set0 -> lbound B i ->
existsj, B j /\ forallk, B k -> j <= k.
Proof.
move=> [i0 Bi0] lbBi; have [n i0in] : existsn, i0 - i = n%:Z.
byexists `|i0 - i|%N; rewrite gez0_abs // subr_ge0; exact: lbBi.
elim: n i lbBi i0in => [i lbBi /eqP|n ih i lbBi i0in1].
byrewrite subr_eq0 => /eqP i0i; existsi0; split =>// k Bk; rewrite i0i lbBi.
have i0i1n : i0 - (i + 1) = n byrewrite opprD addrA i0in1 -addn1 PoszD addrK.
have [?|/not_forallP] := pselect (lbound B (i + 1)); firstexact: (ih (i + 1)).
move=> /contrapT[x /not_implyP[Bx i1x]]; existsx; split => // k Bk.
rewrite (le_trans _ (lbBi _ Bk)) //.
bymove/negP : i1x; rewrite -ltNge ltz_addr1.
Qed.
Sectionrat_in_itvoo.
Letbound_div (R : archiFieldType) (xy : R) : nat :=
if y < 0then0%N else Num.bound (y / x).
Letarchi_bound_divP (R : archiFieldType) (xy : R) :
0 < x -> y < x *+ bound_div x y.
Proof.
move=> x0; have [y0|y0] := leP 0 y; lastbyrewrite /bound_div y0 mulr0n.
rewrite /bound_div (ltNge y 0) y0/= -mulr_natl -ltr_pdivr_mulr//.
byrewrite archi_boundP// (divr_ge0 _(ltW _)).
Qed.
Lemmarat_in_itvoo (R : realType) (xy : R) :
x < y -> existsq, ratr q \in `]x, y[.
Proof.
move=> xy; move: (xy); rewrite -subr_gt0.
move=> /(archi_bound_divP 1); set n := bound_div _ _ => nyx.
have [m1 m1nx] : existsm1, m1.+1%:~R > x *+ n.
have := archi_bound_divP (x *+ n) ltr01; set p := bound_div _ _ => nxp.
have [x0|x0] := ltP 0 x.
existsp.-1; rewrite prednK // lt0n; apply: contraPN nxp => /eqP ->.
byapply/negP; rewrite -leNgt mulrn_wge0 // ltW.
byexists0%N; rewrite (le_lt_trans _ ltr01) // mulrn_wle0.
have [m2 m2nx] : existsm2, m2.+1%:~R > - x *+ n.
have := archi_bound_divP (- x *+ n) ltr01; set p := bound_div _ _ => nxp.
have [x0|x0] := ltP 0 x.
byexistsO; rewrite (le_lt_trans _ ltr01) // nmulrn_rle0// oppr_lt0.
existsp.-1; rewrite prednK // -(ltr_nat R) (le_lt_trans _ nxp) //.
byrewrite mulrn_wge0 // oppr_ge0.
have : existsm, -(m2.+1 : int) <= m <= m1.+1 /\ m%:~R - 1 <= x *+ n < m%:~R.
have m2m1 : - (m2.+1 : int) < m1.+1.
byrewrite -(ltr_int R) (lt_trans _ m1nx)// rmorphN /= ltr_oppl // -mulNrn.
pose B := [set m : int | m%:~R > x *+ n].
have m1B : B m1.+1by [].
have m2B : lbound B (- m2.+1%:~R).
move=> i; rewrite /B /= -(opprK (x *+ n)) -ltr_oppl -mulNrn => nxi.
rewrite -(mulN1r m2.+1%:~R) mulN1r -ler_oppl.
byhave := lt_trans nxi m2nx; rewrite intz -mulrNz ltr_int => /ltW.
have [m [Bm infB]] := int_lbound_has_minimum (ex_intro _ _ m1B) m2B.
have mN1B : ~ B (m - 1).
bymove=> /infB; apply/negP; rewrite -ltNge ltr_subl_addr ltz_addr1.
existsm; split; [apply/andP; split|apply/andP; split] => //.
- bymove: m2B; rewrite /lbound /= => /(_ _ Bm); rewrite intz.
- exact: infB.
- byrewrite leNgt; apply/negP; rewrite /B /= intrD in mN1B.
move=> [m [/andP[m2m mm1] /andP[mnx nxm]]].
have [/andP[a b] c] : x *+ n < m%:~R <= 1 + x *+ n /\ 1 + x *+ n < y *+ n.
split; [apply/andP; split|] => //; firstbyrewrite -ler_subl_addl.
bymove: nyx; rewrite mulrnDl -ltr_subr_addr mulNrn.
have n_gt0 : n != 0%N byapply: contraTN nyx => /eqP ->; rewrite mulr0n ltr10.
exists (m%:Q / n%:Q); rewrite in_itv /=; apply/andP; split.
rewrite rmorphM (@rmorphV _ _ _ n%:~R); firstbyrewrite unitfE // intr_eq0.
rewrite ltr_pdivl_mulr /=; firstbyrewrite ltr0q ltr0z ltz_nat lt0n.
byrewrite mulrC // !ratr_int mulr_natl.
rewrite rmorphM /= (@rmorphV _ _ _ n%:~R); firstbyrewrite unitfE // intr_eq0.
rewrite ltr_pdivr_mulr /=; firstbyrewrite ltr0q ltr0z ltz_nat lt0n.
byrewrite2!ratr_int mulr_natr (le_lt_trans _ c).
Qed.
Endrat_in_itvoo.