(************************************************************************)
(*         *      The Rocq Prover / The Rocq Development Team           *)
(*  v      *         Copyright INRIA, CNRS and contributors             *)
(* <O___,, * (see version control and CREDITS file for authors & dates) *)
(*   \VV/  **************************************************************)
(*    //   *    This file is distributed under the terms of the         *)
(*         *     GNU Lesser General Public License Version 2.1          *)
(*         *     (see LICENSE file for the text of the license)         *)
(************************************************************************)
(************************************************************************)
Require CMorphisms.
(** The constructive Cauchy real numbers, ie the Cauchy sequences of rational numbers.  Cauchy reals are Cauchy sequences of rational numbers, equipped with explicit moduli of convergence and an equivalence relation (the difference converges to zero).  Without convergence moduli, we would fail to prove that a Cauchy sequence of constructive reals converges.  Because of the Specker sequences (increasing, computable and bounded sequences of rationals that do not converge to a computable real number), constructive reals do not follow the least upper bound principle.  The double quantification on p q is needed to avoid forall un, QSeqEquiv un (fun _ => un O) (fun q => O) which says nothing about the limit of un.  We define sequences as Z -> Q instead of nat -> Q, so that we can compute arguments like 2^n fast.  Todo: doc for Z->Q  WARNING: this module is not meant to be imported directly, please import `Reals.Abstract.ConstructiveReals` instead.  WARNING: this file is experimental and likely to change in future releases. *)
Definition QCauchySeq (xn : Z -> Q)
: Prop
:= forall (k : Z) (p q : Z),
Z.le p k
-> Z.le q k
-> Qabs (xn p - xn q) < 2 ^ k.
Definition QBound (xn : Z -> Q) (scale : Z)
: Prop
:= forall (k : Z),
Qabs (xn k) < 2 ^ scale.
(* A Cauchy real is a sequence with a proof that the sequence is Cauchy *)
Record CReal := mkCReal {
seq : Z -> Q;
scale : Z;
cauchy : QCauchySeq seq;
bound : QBound seq scale
}.
Declare Scope CReal_scope.
(* Declare Scope R_scope with Key R *)
Delimit Scope CReal_scope with CReal.
(* Automatically open scope R_scope for arguments of type R *)
Bind Scope CReal_scope with CReal.
Local Open Scope CReal_scope.
Definition CRealLt (x y : CReal) : Set
:= { n : Z |  Qlt (2 * 2 ^ n) (seq y n - seq x n) }.
Definition CRealLtProp (x y : CReal) : Prop
:= exists n : Z, Qlt (2 * 2 ^ n)(seq y n - seq x n).
Definition CRealGt (x y : CReal) := CRealLt y x.
Definition CReal_appart (x y : CReal) := sum (CRealLt x y) (CRealLt y x).
Infix "<" := CRealLt : CReal_scope.
Infix ">" := CRealGt : CReal_scope.
Infix "#" := CReal_appart : CReal_scope.

(* CRealLt is decided by the LPO in Type, which is a non-constructive oracle. *)
Lemma CRealLt_lpo_dec : forall x y : CReal,
(forall (P : nat -> Prop), (forall n:nat, {P n} + {~P n})
-> {n | ~P n} + {forall n, P n})
-> CRealLt x y + (CRealLt x y -> False).