Documentation

LeanPool.ComputableReal.ComputableRSeq

Interval-Cauchy real sequences #

A ComputableℝSeq carries a sequence of rational intervals (ℚInterval) that converge to a single real number, with proofs that the lower and upper rational bounds are valid and Cauchy-equivalent. This file develops the basic interval arithmetic on ℚInterval and the algebraic operations (addition, negation, multiplication, inversion) on ComputableℝSeq, culminating in a commutative semiring structure.

The interval sequence is an arbitrary function ℕ → ℚInterval, with no recursiveness requirement, so membership in this type is not computability in the computable-analysis sense. Addition, negation, and multiplication are executable interval arithmetic, while sign (and hence inversion and division, which need a nonzero witness) is defined classically and is noncomputable.

Notation ℚInterval for a nonempty rational interval.

Equations
Instances For
    @[implicit_reducible]

    A real lies in a ℚInterval when it is between the lower and upper bounds.

    Equations
    Instances For

      Multiplication on intervals of ℚ. TODO: Should generalize to any LinearOrderedField...

      Equations
      • One or more equations did not get rendered due to their size.
      Instances For

        Multiplication of intervals by a ℚ. TODO: Should generalize to any LinearOrderedField

        Equations
        Instances For
          @[implicit_reducible]

          Interval multiplication on ℚInterval.

          Equations
          Instances For
            @[implicit_reducible]

            Multiplication of a ℚInterval by a rational scalar.

            Equations
            Instances For
              @[implicit_reducible]

              Division of a ℚInterval by a rational scalar.

              Equations
              Instances For
                theorem QInterval.mulPair_lb_is_lb {x y : NonemptyInterval } (xv : ) :
                xv xyvy, (mulPair x y).toProd.1 xv * yv
                theorem QInterval.mulPair_ub_is_ub {x y : NonemptyInterval } (xv : ) :
                xv xyvy, (mulPair x y).toProd.2 xv * yv
                theorem QInterval.mem_mulPair {x y : NonemptyInterval } (xv : ) :
                xv xyvy, xv * yv mulPair x y
                @[implicit_reducible]

                The constant interval at a rational number.

                Equations
                Instances For
                  @[implicit_reducible]

                  The constant interval at a numeric literal.

                  Equations
                  Instances For

                    Structure for sequences that converge to some real number from above and below. lub is a function that gives upper and lower bounds, bundled so it can reuse computation; it is an arbitrary function ℕ → ℚInterval, with no recursiveness requirement. hcl and hcu assert that the two bounds are Cauchy sequences, hlub asserts that they're valid lower and upper bounds, and heq' asserts that they converge to a common value. Use ComputableℝSeq.mk to construct with regards to a reference real value.

                    The defs lb, ub are the actual CauSeq's , val is the associated real number, and hlb, hub, and heq relate lb ub and val to each other.

                    Instances For

                      The lower-bound Cauchy sequence of a ComputableℝSeq.

                      Equations
                      Instances For

                        The upper-bound Cauchy sequence of a ComputableℝSeq.

                        Equations
                        Instances For
                          @[irreducible]

                          Get the real value determined by the sequence. (Irreducibly) given here as the limit of the lower bound sequence.

                          Equations
                          Instances For
                            theorem ComputableℝSeq.hlb (x : ComputableℝSeq) (n : ) :
                            (x.lb n) x.val
                            theorem ComputableℝSeq.hub (x : ComputableℝSeq) (n : ) :
                            (x.ub n) x.val
                            theorem ComputableℝSeq.val_uniq {x : } {s : ComputableℝSeq} (hlb : ∀ (n : ), (s.lb n) x) (hub : ∀ (n : ), (s.ub n) x) :
                            s.val = x

                            If a real number x is bounded below and above by a sequence, it must be the value of that sequence.

                            def ComputableℝSeq.mk (x : ) (lub : NonemptyInterval ) (hcl : IsCauSeq abs fun (n : ) => (lub n).toProd.1) (hcu : IsCauSeq abs fun (n : ) => (lub n).toProd.2) (hlb : ∀ (n : ), (lub n).toProd.1 x) (hub : ∀ (n : ), (lub n).toProd.2 x) (heq : have lb := fun (n : ) => (lub n).toProd.1, hcl; have ub := fun (n : ) => (lub n).toProd.2, hcu; lb ub) :

                            Make a computable sequence for x from a separate lower and upper bound CauSeq.

                            Equations
                            • ComputableℝSeq.mk x lub hcl hcu hlb hub heq = { lub := lub, hcl := hcl, hcu := hcu, hlub := , heq' := heq }
                            Instances For
                              theorem ComputableℝSeq.mk_val_eq_val {x : } {v : NonemptyInterval } {h₁ : IsCauSeq abs fun (n : ) => (v n).toProd.1} {h₂ : IsCauSeq abs fun (n : ) => (v n).toProd.2} {h₃ : ∀ (n : ), (v n).toProd.1 x} {h₄ : ∀ (n : ), (v n).toProd.2 x} {h₅ : have lb := fun (n : ) => (v n).toProd.1, h₁; have ub := fun (n : ) => (v n).toProd.2, h₂; lb ub} :
                              (mk x v h₁ h₂ h₃ h₄ h₅).val = x
                              theorem ComputableℝSeq.lb_le_ub (x : ComputableℝSeq) (n : ) :
                              x.lb n x.ub n
                              theorem ComputableℝSeq.ext {x y : ComputableℝSeq} (h₁ : ∀ (n : ), x.lb n = y.lb n) (h₂ : ∀ (n : ), x.ub n = y.ub n) :
                              x = y
                              theorem ComputableℝSeq.ext_iff {x y : ComputableℝSeq} :
                              x = y (∀ (n : ), x.lb n = y.lb n) ∀ (n : ), x.ub n = y.ub n

                              All rational numbers q have a computable sequence: the constant sequence q.

                              Equations
                              Instances For
                                @[implicit_reducible]
                                Equations
                                @[implicit_reducible]
                                Equations
                                @[implicit_reducible]
                                Equations

                                Addition of computable real sequences.

                                Equations
                                Instances For

                                  Negation of a computable real sequence.

                                  Equations
                                  Instances For

                                    Subtraction of computable real sequences.

                                    Equations
                                    Instances For

                                      "Bundled" multiplication to give lower and upper bounds. This bundling avoids the need to call lb and ub separately for each half (which, in a large product, leads to an exponential slowdown). This could be further optimized to use only two ℚ multiplications instead of four, when the sign is apparent.

                                      Equations
                                      Instances For

                                        More friendly expression for the lower bound for multiplication, as a CauSeq.

                                        Equations
                                        Instances For

                                          More friendly expression for the lower bound for multiplication, as a CauSeq.

                                          Equations
                                          Instances For

                                            The lower bounds from mul' are precisely the same sequence as mulLb.

                                            The upper bounds from mul' are precisely the same sequence as mulUb.

                                            The lower bounds from mul' form a Cauchy sequence.

                                            The upper bounds from mul' form a Cauchy sequence.

                                            theorem ComputableℝSeq.mulLb_is_lb (x y : ComputableℝSeq) (n : ) :
                                            ((x.mulLb y) n) x.val * y.val
                                            theorem ComputableℝSeq.mulUb_is_ub (x y : ComputableℝSeq) (n : ) :
                                            ((x.mulUb y) n) x.val * y.val

                                            Multiplication of computable real sequences.

                                            Equations
                                            • x.mul y = { lub := x.mul' y, hcl := , hcu := , hlub := , heq' := }
                                            Instances For
                                              @[implicit_reducible]
                                              Equations
                                              @[simp]
                                              theorem ComputableℝSeq.natCast_lb {n : } :
                                              (↑n).lb = n
                                              @[simp]
                                              theorem ComputableℝSeq.natCast_ub {n : } :
                                              (↑n).ub = n
                                              @[simp]
                                              theorem ComputableℝSeq.val_natCast {n : } :
                                              (↑n).val = n
                                              @[simp]
                                              theorem ComputableℝSeq.intCast_lb {z : } :
                                              (↑z).lb = z
                                              @[simp]
                                              theorem ComputableℝSeq.intCast_ub {z : } :
                                              (↑z).ub = z
                                              @[simp]
                                              theorem ComputableℝSeq.val_intCast {z : } :
                                              (↑z).val = z
                                              @[simp]
                                              theorem ComputableℝSeq.val_ratCast {q : } :
                                              (↑q).val = q
                                              @[simp]
                                              @[simp]
                                              @[simp]
                                              @[simp]
                                              @[simp]
                                              @[simp]
                                              theorem ComputableℝSeq.lb_add (x y : ComputableℝSeq) :
                                              (x + y).lb = x.lb + y.lb
                                              @[simp]
                                              theorem ComputableℝSeq.ub_add (x y : ComputableℝSeq) :
                                              (x + y).ub = x.ub + y.ub
                                              @[simp]
                                              @[simp]
                                              theorem ComputableℝSeq.lb_sub (x y : ComputableℝSeq) :
                                              (x - y).lb = x.lb - y.ub
                                              @[simp]
                                              theorem ComputableℝSeq.ub_sub (x y : ComputableℝSeq) :
                                              (x - y).ub = x.ub - y.lb
                                              @[simp]
                                              theorem ComputableℝSeq.lb_mul (x y : ComputableℝSeq) :
                                              (x * y).lb = x.lb * y.lbx.ub * y.lb(x.lb * y.ubx.ub * y.ub)
                                              theorem ComputableℝSeq.ub_mul (x y : ComputableℝSeq) :
                                              (x * y).ub = x.lb * y.lbx.ub * y.lb(x.lb * y.ubx.ub * y.ub)
                                              @[simp]

                                              The sign of x, defined classically as the sign of its real value, so this definition is noncomputable and carries no algorithmic content. (Searching the interval sequence for a sign witness terminates exactly when x ≠ 0 or some interval is the point 0, so a fuel-free executable version cannot be total.) This ends up providing the DecidableEq and DecidableLT instances on Computableℝ, which are likewise classical.

                                              Equations
                                              Instances For
                                                noncomputable def ComputableℝSeq.signWitnessTerm (x : ComputableℝSeq) (hnz : x.val 0) :
                                                { xq : × // 0 < xq.2 xq.2 < |x.val| jxq.1, |↑(x.lb - x.ub) j| < xq.2 }

                                                If x is nonzero, there is eventually a point in the Cauchy sequences where either the lower or upper bound prove this. This theorem states that this point exists.

                                                Equations
                                                • One or more equations did not get rendered due to their size.
                                                Instances For
                                                  theorem ComputableℝSeq.signWitnessTerm_prop (x : ComputableℝSeq) (n : ) (hnz : x.val 0) (hub : ¬x.ub n < 0) (hlb : ¬x.lb n > 0) :
                                                  n + Nat.succ 0 (↑(x.signWitnessTerm hnz)).1
                                                  @[irreducible]
                                                  def ComputableℝSeq.signWitness (x : ComputableℝSeq) (hnz : x.val 0) :
                                                  { n : // 0 < x.val 0 < x.lb n x.val < 0 x.ub n < 0 }

                                                  With the proof that x≠0, we can also eventually get a sign witness: a number n such that either 0 < x and 0 < lb n; or that x < 0 and ub n < 0. Marking it as irreducible because in theory all of the info needed is in the return Subtype.

                                                  Equations
                                                  Instances For

                                                    With the proof that x≠0, we get a total comparison function.

                                                    Equations
                                                    Instances For
                                                      theorem ComputableℝSeq.isPos_iff (x : ComputableℝSeq) (hnz : x.val 0) :
                                                      isPos hnz = true 0 < x.val

                                                      Proof that isPos correctly determines whether a nonzero computable number is positive.

                                                      Given computable sequences for a nonzero x, drop the leading terms of both sequences (lb and ub) until both are nonzero. This gives a new sequence that we can "safely" invert.

                                                      Equations
                                                      Instances For
                                                        theorem ComputableℝSeq.sign_dropTilSigned {x : ComputableℝSeq} (hnz : x.val 0) :
                                                        0 < x.val 0 < (x.dropTilSigned hnz).lb 0 x.val < 0 (x.dropTilSigned hnz).ub 0 < 0

                                                        The sequence of lower bounds of 1/x. Only functions "correctly" to give lower bounds if we assume that hx is already hx.dropTilSigned (as proven in lbInv_correct) -- but those assumptions aren't need for proving that it's Cauchy.

                                                        Equations
                                                        Instances For

                                                          Analgoous to lbInv for providing upper bounds on 1/x.

                                                          Equations
                                                          Instances For
                                                            theorem ComputableℝSeq.lbInv_correct {x : ComputableℝSeq} (hnz : x.val 0) (n : ) :
                                                            (((x.dropTilSigned hnz).lbInv ) n) x.val⁻¹

                                                            When applied to a dropTilSigned, lbInv is a correct lower bound on x⁻¹.

                                                            theorem ComputableℝSeq.ubInv_correct {x : ComputableℝSeq} (hnz : x.val 0) (n : ) :
                                                            (((x.dropTilSigned hnz).ubInv ) n) x.val⁻¹

                                                            When applied to a dropTilSigned, ubInv is a correct upper bound on x⁻¹.

                                                            x.lbInv converges to (x.val)⁻¹.

                                                            When applied to a dropTilSigned, lbInv is converges to x⁻¹.

                                                            x.ubInv converges to (x.val)⁻¹.

                                                            When applied to a dropTilSigned, ubInv is converges to x⁻¹. TODO: version without hnz hypothesis.

                                                            An inverse is defined only on reals that we can prove are nonzero. If we can prove they are nonzero, then we can prove that at some point we learn the sign, and so can start giving actual upper and lower bounds. There is a separate inv that uses sign to construct the proof of nonzeroness by searching along the sequence (but isn't guaranteed to terminate).

                                                            Equations
                                                            Instances For
                                                              @[simp]

                                                              Subtype of sequences with nonzero values. These admit a (terminating) inverse function.

                                                              Equations
                                                              Instances For
                                                                noncomputable def ComputableℝSeq.invNz :

                                                                The inverse on the subtype of sequences with nonzero value.

                                                                Equations
                                                                Instances For
                                                                  @[simp]
                                                                  theorem ComputableℝSeq.val_invNz (x : nzSeq) :
                                                                  (↑(invNz x)).val = (↑x).val⁻¹
                                                                  @[implicit_reducible]
                                                                  noncomputable instance ComputableℝSeq.instNzInv :
                                                                  Equations

                                                                  Inverse of a computable real. Will terminate if the argument is nonzero, or if it is zero and the upper and lower bounds become exactly zero at some point. See ComputableℝSeq.sign. If you want to only call this in a way guaranteed to terminate, use ComputableℝSeq.safeInv.

                                                                  Equations
                                                                  Instances For
                                                                    @[implicit_reducible]
                                                                    Equations
                                                                    @[implicit_reducible]
                                                                    Equations

                                                                    The inverse is equal to the safeInv. This is an actual equality of sequences, not just equivalence.

                                                                    @[simp]

                                                                    Computable sequences have most of the properties of a field, including negation, subtraction, multiplication, division, IntCast all working as one would expect, with commutativity/associativity, involutive negation, and distributive properties ... except for a few crucial facts that a - a ≠ 0, a * a⁻¹ ≠ 1, and (a⁻¹)⁻¹ ≠ a. This typeclass collects all these facts together.

                                                                    TODO could include mul_inv_rev, inv_eq_of_mul, intCast_ofNat, intCast_negSucc.

                                                                    Instances
                                                                      @[implicit_reducible]
                                                                      Equations
                                                                      • One or more equations did not get rendered due to their size.
                                                                      @[implicit_reducible]

                                                                      The equivalence relation on ComputableℝSeq's given by converging to the same real value.

                                                                      Equations