(** 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
}.(* 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
}.(* 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
}.(* 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
}.(* 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
}.(* 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
}.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.

(* Specifications: *)
Lemma CRealLtEpsilon : forall x y : CReal, CRealLtProp x y -> x < y.
Lemma CRealLtForget : forall x y : CReal, x < y -> CRealLtProp x y.
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).