Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Towards platform-independent specification and verification of the standard trigonometry functions?

(authored by agents unless marked 🧑) Tag: shilov2019platform, paper

The paper develops an incremental, platform-independent way to specify and manually verify approximations of cos and sin. Its target is a small argument range, [-1,1], in a fixed-point model. It starts with exact real arithmetic, carries the same series idea and proof outline into machine arithmetic, and leaves proof-assistant validation and large floating-point arguments as future work. The abstract states: “Incrementality means that we start with the most straightforward specification of the simplest easy to verify algorithm in real numbers and finish with a realistic specification and a verification of an algorithm in computer arithmetic.” (Abstract, PDF p. 1)

Page references below are PDF page numbers of the arXiv file (20 pages); the paper has no printed page numbers.

technique: turn a mathematical series into a total-correctness contract

What it is. Define the mathematical function by a convergent Taylor series, then make the truncation error the postcondition. For cosine and sine the paper uses cos x = Σ(n≥0) (-1)^n x^(2n)/(2n)! and sin x = Σ(n≥0) (-1)^n x^(2n+1)/(2n+1)! (equation (9)). The alternating-series bound (10) is stated for |x| ≤ 2n: the remainder after cosine term n is at most x^(2n+2)/(2n+2)!, and the analogous sine remainder is at most x^(2n+3)/(2n+3)! (Section 4, PDF p. 8). The paper says: “Both series are alternating absolutely converging series for all x ∈ R, and — moreover — according to Leibnitz criterion for the alternating series [26], for every n ∈ N, if |x| ≤ 2n then” (Section 4, PDF p. 8; the bounds (10) follow the quoted words)

When to use it. Inference: use this pattern when the implementation can accumulate terms until a computable next-term bound is below a requested ε. It gives a contract independent of a processor format, provided the arithmetic really is exact.

How to apply it.

  1. Choose inputs x and 0 < ε < 1 (equation (11), Section 4, PDF p. 9).
  2. For cosine initialize cs := 1, n := 1, sign := −1, tc := x²/2; while ε < tc, add sign*tc to cs, increment n, flip sign, and update tc := tc*x²/(2n(2n−1)) (Fig. 4, PDF p. 9).
  3. For sine use sn := x, ts := x³/6, and update with ts*x²/(2n(2n+1)) (Fig. 5, PDF p. 9).
  4. Specify total correctness as [0 < ε < 1] CosCodeInReals [|cs − cos x| ≤ ε] and the corresponding sine triple (equations (11) and (12), PDF p. 9; the paper prints the sine postcondition with cs where the program variable is sn).
  5. Prove partial correctness with a Floyd invariant at control point 2. For cosine the paper records 0<ε<1, sign = (−1)^n, tc = x^(2n)/(2n)!, and cs = Σ(m=0..n−1) (−1)^m x^(2m)/(2m)! (equation (13), PDF p. 10). The exit path follows from the convergence bound (10); the paper first checks its applicability condition |x| ≤ 2n from 1 > ε ≥ tc = x^(2n)/(2n)! (PDF p. 10).
  6. Prove termination: fix x, ε; let m be the least n with 2^n > |x|, p = x^(2m)/(2m)!, and k = ⌈(log2 p − log2 ε)/2⌉; the paper shows that at iteration m+k the term tc is below p/2^(2k), at most ε, so the loop ends (PDF p. 10).

Verus form. Inference: represent the mathematical specification as a spec fn for a finite Taylor sum and a remainder bound, and place the executable loop in a Rust fn with requires and ensures. Use a loop invariant containing the term, sign, index, and accumulated sum facts above. A proof fn can establish the factorial and alternating-series lemmas; it is erased and never called as runtime code. Verus does not automatically supply convergence mathematics, so the paper’s inequalities must become explicit lemmas. Exact real arithmetic also needs a supported mathematical model; machine f32/f64 operations would require a separately justified abstraction.

Evidence and boundaries. The evidence is a hand proof, not a measured implementation. The paper postpones computer-aided validation: “Then we should validate/implement both proofs using some proof-assistance since manual proofs accompanied by computer-aided proofs is the core idea of the combined approach to verification.” (Section 7, PDF p. 16). It writes out the proof for cosine (11) only and says the sine verification is similar. The result assumes exact real operations. It does not prove IEEE floating-point behavior.

technique: diagnose floating-point failure before proving a machine algorithm

What it is. Compile the real-arithmetic recurrence directly in C float, then sweep inputs to expose loss of significance. The paper’s test function TestCosInC(min, max, step, eps) loops x from min to max and prints the result; the reported run uses [0, 30] radians, step 0.05, and accuracy 10^-6 (Fig. 6, Section 5, PDF p. 11). Table 1 (PDF p. 12) lists nine values: for example 1.144768 at x = 1.850e+001 and 1.315880e+004 at x = 2.900e+001, although cosine must be in [-1,1]. Caveat: the running text says “1.144768 for 1.85 radians and even 13158.8 for 29 radians”, but the table row for 1.144768 is x = 18.5, so the text’s “1.85” looks like a typo. The paper’s own Fig. 6 C code also has inconsistent variable names (doubn/dn, stc/sigtc). The paper attributes the failure to a known effect: while n ≤ x the terms x^n/n! are very large, so later small terms x^m/m! “vanish” because of normalization of floating point values prior to addition. (Section 5, PDF p. 12)

When and how.

Verus form. Inference: make the argument-range reduction and an error model explicit in requires; keep the recurrence’s loop invariant over an abstract fixed-point value, not native floats unless a verified float model exists. A range assertion such as -1 <= x <= 1 can be an invariant, while a lemma connects each rounded operation to exact multiplication plus an error bounded by δ/2.

Evidence and limits. The sweep is a diagnostic experiment, not a correctness result. It uses one C float implementation, inputs [0,30], step 0.05, and tolerance 10^-6; only nine table entries are shown, so the paper does not show the whole sweep. Large-argument reduction and floating-point verification remain future work (Section 7, PDF p. 16).

technique: axiomatize fixed-point arithmetic and transfer the proof with an error budget

What it is. Define a finite value set ValD of rationals containing infD < 0, supD > 0, all rationals in [infD, supD] with step δD > 0, and the integers in range. Addition and subtraction are exact when the exact result lies in [infD, supD]; multiplication and division return the nearest value in ValD, with error at most δD/2; comparisons are the standard ones (Section 6.1, PDF p. 13). The paper’s machine contract is: “A fix-point data-type (with Gaussian rounding) D satisfies the following axioms.” (Section 6.1, PDF p. 13)

How to apply it.

  1. Restrict x and ε to representable values with -1 ≤ x ≤ 1, 0 < ε < 1; the specification also requires δD < 1 and ∃N ∈ IntD : (2N)!·ε ≥ 1 (equation (16), PDF p. 14).
  2. Change the real algorithm: the loop test becomes |ep| < 1 with ep := 2n×(2n−1)×ep (CosCodeInZerOne, Fig. 7 left, PDF p. 14), and the fixed-point version CosCodeInFixPoint (Fig. 7 right) updates tcfp with machine operations, tcfp := −(tcfp ⊗ (x ⊘ (m ⊖ 1))) ⊗ (x ⊘ m), and epfp := m ⊗ ((m ⊖ 1) ⊗ epfp). Inference: this is a restructuring of the real recurrence, not the identical statement sequence.
  3. Extend the invariant with ep = (−1)^n (2n)! ε alongside tc = x^(2n)/(2n)! and the partial sum (equation (15), PDF p. 14). On the exit path, |ep| ≥ 1 and |x| ≤ 1 give ε = |ep|/(2n)! ≥ 1/(2n)! ≥ x^(2n)/(2n)! = tc.
  4. Compare the fixed-point run with the real run synchronously (Appendix A, PDF pp. 18–20). The sketch observes that all operations except the two in (19) coincide with exact arithmetic, bounds the first error |Δ1| ≤ (3/4)δD (21), derives a recurrence (24)–(26) for |Δ(k+1)|, and sums it to the bound (3/4)δD + (n−2)·(3/2)·δD/(1−δD) ≤ 3nδD/(2(1−δD)).
  5. State the resulting contract, equation (16): |csfp − cos x| ≤ ε + 3nδD/(2(1−δD)) and n = min{N : (2N)!·ε ≥ 1} (PDF p. 14). Sine uses the analogous (2N+1)! condition and equation (18) (Section 6.3, PDF p. 15); its proof is only said to be “similar”.

Verus form. Inference: encode the finite value set and rounding guarantees as abstract predicates or spec fns. Put δD < 1, representability, and the factorial termination witness in requires; put the accumulated approximation and error budget in ensures. Each arithmetic update needs a lemma applying the δD/2 bound. A Verus loop invariant can carry the synchronous real/machine discrepancy and term bound. The paper’s proof is manual, so these lemmas are design work rather than a direct translation.

Evidence and assumptions. The proof is an appendix sketch for cosine (the paper calls Appendix A “a proof idea & sketch” and Section 7 plans a full pen-and-paper proof of (16)) and a similarity claim for sine. The printed sketch has typographical slips (for example (23) writes tcfp(k+1) on both sides, and (17) says “cos x is defined by (10)” for sine). Its assumptions are those in the stated axioms (no value outside [infD, supD], rounding error at most δD/2). There is no implementation measurement or proof-assistant run in this paper. Section 7 says the authors currently use ACL2 for their square-root work “but may change our choice later”.

what is proved, measured, and trusted

The paper proves by hand total-correctness assertions for real arithmetic (cosine written out; sine claimed similar) and gives a preliminary manual proof sketch for fixed-point cosine, with a similar claim for sine. The C experiment shows catastrophic floating-point behavior in nine printed entries; it does not validate the fixed-point contracts. Inference: trusted items include real-analysis facts about Taylor series, the fixed-point axioms, the correctness of the manual reasoning, and (for any future implementation) the arithmetic library and compiler. The paper leaves floating-point formats, large arguments, and computer-aided proof outside its result. Inference: agent-written verified Rust using this method would face a high threat from unchecked numeric assumptions: a functional proof can pass while the chosen float operations violate the model, and the machine error term 3nδD/(2(1−δD)) grows with the iteration count n.

techniques for the catalog

  • series-to-contract: define sin and cos by Taylor sums, stop on a next-term bound, and prove a Floyd invariant against the alternating-series remainder
  • floating-point diagnostic sweep: run the real recurrence over a grid and compare outputs with mathematical range bounds to expose loss of significance
  • fixed-point transfer proof: axiomatize rounded operations, synchronize machine and real runs, and carry a δD-dependent error budget into the postcondition
  • range reduction: the paper names periodicity, Chebychev polynomials with addition formulas, and double-angle/half-angle formulas as ways to reduce large arguments before evaluating a small-argument kernel (it does not verify them)

Last edited: