Bounds — Rational Interval Arithmetic for the rsa_predict Backend #
Closed intervals [lo, hi] over ℚ, with proofs that arithmetic and transcendental
operations preserve ℝ containment. This is the numeric foundation for the
rsa_predict tactic:
- Reify an ℝ expression into a tree of
QIntervaloperations - Evaluate the tree to get a concrete
[lo, hi](computable ℚ) - Check separation
b.hi < a.lo(decidable on ℚ) - Conclude
a > bon ℝ viagt_of_separated
Layered structure #
The file is organized in dependency order:
- QInterval — the core type and exact arithmetic (
add,sub,mul,divPos,invPos,powNat,rpowNat), separation predicate, and rational coarsening (truncDown/truncUp/coarsen) that bounds bit growth across long products. - PadeExp —
[4/4]Padé approximant forReal.expon[-1, 1]with argument reduction by repeated squaring, givingexpPoint/expIntervalwith relative error< 1/4000000. - LogInterval —
Real.logfor positive rationals via 50-step bisection againstexpPoint, with bracket bits proportional tolog q. Includes alog 0fall-through. - SqrtInterval —
√x = exp(log x / 2)for positive intervals, used by Hellinger-distance RSA models (@cite{herbstritt-franke-2019}). - rpow specials —
rpowNat_containsReal(real-exponent bridge forQInterval.rpowNat),rpowZero,rpowOne_containsRealfor the dominant RSA case (α : ℕ).
All transcendental routines deliberately stop at containsReal rather than
proving exact bounds: the rsa_predict tactic only needs lo ≤ ⟦e⟧ ≤ hi.
Equations
- Interval.instReprQInterval = { reprPrec := Interval.instReprQInterval.repr }
Equations
- One or more equations did not get rendered due to their size.
Instances For
The interval contains a real number x: lo ≤ x ≤ hi (via ℚ → ℝ cast).
Equations
- I.containsReal x = (↑I.lo ≤ x ∧ x ≤ ↑I.hi)
Instances For
Zero-width interval [q, q].
Equations
- Interval.QInterval.exact q = { lo := q, hi := q, valid := ⋯ }
Instances For
Containment for (0 : ℝ). Uses the literal 0 so the proof type mentions
@OfNat.ofNat ℝ 0 _ (= @Zero.zero ℝ _), matching expressions directly.
Containment for (1 : ℝ). Uses the literal 1 so the proof type mentions
@OfNat.ofNat ℝ 1 _ (= @One.one ℝ _), avoiding the Nat.cast 1 = 0 + 1
mismatch that breaks nested proof terms.
Containment for natural number literals ≥ 2 cast via Nat.cast.
For n ≥ 2, @OfNat.ofNat ℝ n _ is definitionally equal to @Nat.cast ℝ _ n
(via Mathlib's instOfNat). For n = 0, 1, use exact_zero_containsReal /
exact_one_containsReal instead (since Nat.cast 1 ≢ OfNat.ofNat 1).
General interval multiplication via 4-corner method.
For intervals [a, b] and [c, d], the product interval is
[min(ac, ad, bc, bd), max(ac, ad, bc, bd)].
Handles arbitrary signs (unlike mulNonneg which requires both nonneg).
Equations
Instances For
Containment for general interval multiplication.
For a.lo ≤ x ≤ a.hi and b.lo ≤ y ≤ b.hi, x·y lies between
min(corners) and max(corners) since extrema of a bilinear function
on a rectangle occur at corners.
Scale interval by a nonneg rational: [qa.lo, qa.hi].
Equations
- Interval.QInterval.scaleNonneg q a hq = { lo := q * a.lo, hi := q * a.hi, valid := ⋯ }
Instances For
Key theorem: interval separation implies ℝ strict ordering.
If a.hi ≤ b.lo, then x ≤ y. Dual of gt_of_separated.
Interval separation implies ≥.
Two exact intervals at the same point imply equality.
If the condition is known false, take the else branch.
If the condition is known true, take the then branch.
Decidable.rec with condition known true → take the isTrue branch.
Handles the case where ite has been unfolded to Decidable.rec by whnf.
Decidable.rec with condition known false → take the isFalse branch.
If an interval has positive lower bound, the contained value is positive.
If an interval has positive lower bound, the contained value is nonzero.
If an interval has nonneg lower bound and nonpos upper bound, the value is zero.
Used by the tactic to prove x = 0 when the interval is [0, 0].
If x is in a zero interval, x * y is in the zero interval.
If y is in a zero interval, x * y is in the zero interval.
If x is in a zero interval, x / y is in the zero interval.
Transport containment along a real-valued equality.
If y = x and the interval contains x, it contains y.
Containment for x ^ n (nat power) with nonneg base.
Maximum bit length for rational numerator/denominator. 64 bits ≈ 19 decimal digits, enough precision for RSA comparisons.
Equations
Instances For
Widen an interval to bounded-precision rationals. Sound: only makes the interval wider, so containment is preserved.
Equations
- I.coarsen bits = { lo := Interval.QInterval.truncDown✝ I.lo bits, hi := Interval.QInterval.truncUp✝ I.hi bits, valid := ⋯ }
Instances For
Padé [4/4] numerator: 1 + x/2 + 3x²/28 + x³/84 + x⁴/1680 (Horner form).
Equations
- Interval.padeNum x = 1 + x * (1 / 2 + x * (3 / 28 + x * (1 / 84 + x * (1 / 1680))))
Instances For
Padé [4/4] denominator: padeNum(-x).
Equations
- Interval.padeDen x = Interval.padeNum (-x)
Instances For
Padé [4/4] approximant: padeNum(x) / padeDen(x).
Equations
- Interval.padeExp x = Interval.padeNum x / Interval.padeDen x
Instances For
Conservative error bound for Padé [4/4] on [-1, 1]. True error is ~4.3×10⁻⁸; this bound gives 2.3× safety margin.
Equations
- Interval.padeErrorBound = 1 / 4000000
Instances For
The Padé [4/4] approximant is within padeErrorBound of exp on [-1, 1].
Proof via triangle inequality: |exp(q) - P(q)/Q(q)| ≤ |exp(q) - T₁₀(q)| + |T₁₀(q) - P(q)/Q(q)|
where T₁₀ is the degree-10 Taylor polynomial. The first term is bounded by Real.exp_bound
with n = 11 (≤ 1/36590400 ≈ 2.73×10⁻⁸). The second term equals |T₁₀·Q - P|/Q; the numerator
is a polynomial with terms only at degrees 9-14 (Padé matching property), bounded by
187/2032128000 ≈ 9.2×10⁻⁸ via coefficient sum, and Q ≥ 143/240.
Number of halvings needed so q / 2^k ∈ [-1, 1].
Equations
- Interval.reductionSteps q = if q.num.natAbs ≤ q.den then 0 else Nat.log 2 q.num.natAbs - Nat.log 2 q.den + 1
Instances For
Repeated squaring of a nonneg interval. Squares I a total of n times: repeatedSq I 0 = I, repeatedSq I (n+1) = (repeatedSq I n)².
Equations
- Interval.repeatedSq I n h = ↑(Interval.repeatedSqCore✝ I n h)
Instances For
Point interval containing exp(q) for arbitrary rational q.
Strategy: reduce q → q' = q/2^k with |q'| ≤ 1 via reductionSteps,
compute exp(q') via Padé [4/4], then square k times since exp(q) = exp(q')^(2^k).
The nonneg guard on small.lo is always true by construction:
padeExp(q') ≈ exp(q') ≥ exp(-1) ≈ 0.368 >> padeErrorBound = 2.5×10⁻⁷.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Containment theorem for expPoint.
Interval containing exp(x) for x in rational interval I.
Uses monotonicity of exp: for x ∈ [lo, hi], exp(lo) ≤ exp(x) ≤ exp(hi) so exp(x) ∈ [expPoint(lo).lo, expPoint(hi).hi].
Equations
- Interval.expInterval I = { lo := (Interval.expPoint I.lo).lo, hi := (Interval.expPoint I.hi).hi, valid := ⋯ }
Instances For
Containment theorem for expInterval: monotonicity of exp + expPoint containment.
Number of bisection iterations.
Equations
Instances For
Point interval containing log(q) for rational q > 0.
Initial bracket: [-(Nat.log 2 q.den + 1), Nat.log 2 q.num.natAbs + 1].
This uses bit lengths instead of raw values, giving a bracket width
proportional to log₂(q) rather than q itself — critical for
large-denominator rationals from interval arithmetic chains.
Lower: exp(-(log₂ d + 1)) < 1/d ≤ q since d < 2^(log₂ d + 1) ≤ exp(log₂ d + 1).
Upper: q ≤ p ≤ exp(log₂ p + 1) by the same argument.
50 bisection iterations narrow this to precision bracket_width / 2^50.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Containment theorem for logPoint: the bisection invariant exp(lo) ≤ q ≤ exp(hi) implies lo ≤ log(q) ≤ hi by monotonicity of log.
Interval containing log(x) for x in a positive rational interval I.
Uses monotonicity of log: for x ∈ [lo, hi] with lo > 0,
log(lo) ≤ log(x) ≤ log(hi)
so log(x) ∈ [logPoint(lo).lo, logPoint(hi).hi].
Equations
- Interval.logInterval I hI = { lo := (Interval.logPoint I.lo hI).lo, hi := (Interval.logPoint I.hi ⋯).hi, valid := ⋯ }
Instances For
Containment theorem for logInterval: monotonicity of log + logPoint containment.
When the argument is known to be zero (from interval [0,0]),
Real.log x = Real.log 0 = 0, contained in exact 0.
Interval square root for positive intervals.
Uses the identity √x = exp(log(x) / 2) for x > 0.
Chains logInterval, rational halving, and expInterval.
Equations
- Interval.sqrtInterval a ha = Interval.expInterval { lo := (Interval.logInterval a ha).lo / 2, hi := (Interval.logInterval a ha).hi / 2, valid := ⋯ }
Instances For
Soundness: if x ∈ [a.lo, a.hi] and a.lo > 0, then √x ∈ sqrtInterval a.
Real-exponent bridge for QInterval.rpowNat: same proof as
QInterval.powNat_containsReal, but with the goal stated using
Real.rpow (real-valued exponent) rather than HPow.hPow (nat).
Interval for rpow(x, 0) = [1, 1].
Equations
Instances For
For rpow(x, 1) with x ∈ interval a, the result is just a.