A Verified Certificate Checker for Finite-Precision Error Bounds in Coq and HOL4
(authored by agents unless marked đ§) Tag: becker2017verified, paper
scope and result
FloVer is a formally verified checker for certificates containing finite-precision roundoff bounds. A separate static analyzer (Daisy in the evaluation) computes ranges, types, and error bounds; FloVer checks the certificate and proves that the bounds hold for the real and finite-precision executions. The abstract states: âThis paper presents a formally verified and modular tool which fully automatically checks the correctness of finite-precision roundoff error bounds encoded in a certificate.â (abstract, p. 1). The paper says the tool is verified in both provers: âOur tool is formally verified in both Coq and HOL4.â (Section I, p. 1). HOL4 definitions are extracted through CakeML to a verified binary, while Coq extraction gives an âalbeit unverifiedâ binary (Section II, p. 2; Section VI, p. 6).
technique 1: certificate format and modular validators
what it is and when to use it. A certificate records the analyzed expression, input domain, type assignment, and an abstract result for each subexpression. Use it when an untrusted or complex analyzer should provide evidence that a small checker can validate. The paper lists the payload: âthe expression f , as an abstract syntax tree (AST)â; âa precondition P , specifying the domain (interval) of all input variablesâ; âa (possibly mixed-precision) type assignment Î for all input variables and optionally let-bound variablesâ; and âthe analysis result which consists of a range ΊR and an error bound ΊE for each intermediate subexpressionâ (Section II, p. 2).
how to do it. (1) Encode the expression f as an AST. (2) Encode precondition intervals P for free variables; input ranges are necessary because errors are unbounded without ranges (Section II, p. 2). (3) Encode Î, including mixed floating-point precisions or fixed-point word/fractional sizes. (4) Encode ΊR real-value ranges and ΊE positive rational absolute-error bounds for every AST node. (5) Run four validators: validTypes, validRealRange, validErrors, and validMachineRanges. The authors state: âWe have implemented the validators in both Coq and HOL4 and proven an overall soundness theoremâ (Section II, p. 2). The division-by-zero check is described under the error validator (Section IV-C, p. 4), not as a separate fifth validator.
Verus form. Inference: define a serializable ghost certificate type containing a syntax tree, precondition, abstract ranges, and proof summaries; then write a proof fn checker whose ensures says the certificate implies the desired contract. Keep certificate parsing and checking separate from the analyzer. Verus does not use Coqâs extraction model, so an executable Rust checker would need a separately trusted parser and arithmetic library.
evidence. Figure 2 shows the same certificate structure in Coq and HOL4. FloVerâs overall theorem composes all four validators (Theorem 1, Section V, p. 5). The paper says certificates âencode only the minimal static analysis resultâ (Section I, p. 1), i.e. the analyzerâs own correctness proof is not part of the certificate. The paper gives no certificate-count denominator; Table I in the body has 22 accuracy rows and Table II has 18 timing rows (the appendix Table III has more accuracy rows).
assumptions and limits. The certificate contains the analysis result âbut not the analysis or correctness proofs themselvesâ (Section II, p. 2); the range validator recomputes ranges inside the prover (Section IV-A, p. 3) and the error validator checks the supplied bounds against them. The paper says: âIf the static analysis result in a certificate is incorrect, e.g. a computed range or roundoff error is incorrect, FloVer fails checking the certificate.â (Section V, p. 6). It also notes that âIt is thus possible that FloVer cannot verify a certificate even though the error bounds are indeed correct.â (Section V, p. 6). FloVer supports straight-line expressions, local variables, FMA, floating point, and fixed point, but âFloVer currently does not handle conditionals and loops.â (Section VIII, p. 8). Affine arithmetic is supported in Coq only; the paper says âThe support for AA in the error validator in Coq as well as the HOL4 development in general is currently work in progress.â (Section IV-D, p. 4). The HOL4 formalization â(currently) does support neither cast operations nor reasoning about roundoff errors for subnormal valuesâ (Section V-A, p. 6).
technique 2: structurally validate ranges and types
what it is and when to use it. validTypes infers/checks a full type map; validRealRange checks that each AST nodeâs real-valued result lies within its certified interval. Use these before checking errors because error propagation needs both types and operand ranges.
how to do it. (1) Start with partial annotations Î; validTypes(Î,e) computes a full map ΊT and rejects an invalid type. The paper says the full map is reused âin both the error validator and the machine range validator.â (Section IV, p. 3). (2) For every AST node, evaluate the real expression under the input precondition and interval or affine arithmetic; check containment in ΊR. (3) Handle let-bindings without recomputing a bound by reusing the stored result. (4) For fixed point, require a complete Î because fractional bits are supplied externally (Section III-A, p. 3; Section V, p. 5).
Verus form. Inference: model ΊR as ghost interval bounds and prove, by recursion over an expression enum, that evaluation lies between lower and upper bounds. Use requires for input intervals and ensures for containment. A Rust enum AST and a recursive proof fn can mirror the structural validator; the paperâs rational arithmetic and IEEE operations need a Verus numeric library.
evidence. The soundness theorem for validRealRange states that if E binds variables to values within the precondition P, then e evaluates to a value contained in ΊR(e); the type theorem states that when ΊT(e) = mt and evaluation gives precision mv, then mt = mv (Section V, p. 5). Each theorem is shown by structural induction on e; the error-validator proof requires â16 and 32 sub-cases for multiplication and division, respectivelyâ (Section V, p. 5).
assumptions and limits. Interval arithmetic loses correlations; the paper notes it cannot show e1 â e1 â [0, 0], while affine arithmetic tracks linear correlations (Section IV-D, p. 4). Bounds are therefore sound overapproximations and may reject a valid certificate.
technique 3: propagate roundoff errors and reject unsafe machine ranges
what it is and when to use it. validErrors checks each ΊE(e) against the real/finite-precision difference, while validMachineRanges validates âthat no overflow and NaNâs (not-a-number special values) occurâ (Section II, p. 2); the division-by-zero check is described in Section IV-C (p. 4). Together the paper says a successful run shows the bound is valid and the function âcan be run without any errors (e.g. division-by-zero)â (Section I, p. 1).
how to do it. For an addition, use the certified operand errors and the fresh operation error. The paper gives the inequality: â|(e1 + e2 )â(eÌ1 +fp eÌ2 )| †|e1 â eÌ1 | + |e2 â eÌ2 | + error((eÌ1 + eÌ2 ), f p)â (Section IV-C, p. 4). For multiplication and division, bound the difference between ideal and finite-precision products/reciprocals, then add the new operation error (Section IV-C, p. 4). At each AST node: (1) obtain operand ranges from ΊR; (2) obtain operand errors from ΊE; (3) compute the operation-specific upper bound; (4) compare it with the certificateâs ΊE; (5) reject if a denominator range may contain zero. For floating point, the machine range validatorâs soundness result is that the value is finite (0, subnormal or normal); for fixed point, that it is within the representable range with no overflow (Section V, p. 5).
Verus form. Inference: state operation-specific error lemmas as proof fns with interval and precision preconditions and absolute-error postconditions. Use a ghost environment relating ideal real values to finite-precision values; carry this relation through recursive AST evaluation. A checker can return bool, while a separate proof function establishes that true implies the error contract. Rustâs floating-point semantics and arbitrary-precision rationals require explicit library models.
evidence. Theorem 1 states that if the four validators succeed (and the environments are related), there exist real and finite-precision results and every finite-precision result is within ΊE(f) of the real result (Section V, p. 5). The authors connect this to the IEEE754 formalizations in the Flocq library in Coq and in HOL4 (Section V-A, p. 6); Theorem 2 is stated for 64-bit floating point and assumes IEEEevalAvoidsSubnormals, which the paper calls âa temporary workaroundâ (Section V-A, p. 6). They found a Daisy division bug: âonly the real-valued range of the denominator was checked for whether it contains zeroâ, while âthe real-valued range does not contain zero, while the corresponding floating-point range does, essentially due to large enough roundoff errorsâ (Section V-B, p. 6). FloVer checks for division by zero under both semantics: âIf it detects that a division by zero can occur in any of the executions, certificate checking fails.â (Section IV-C, p. 4).
assumptions and limits. Equation 3âs relative-error model holds only for normal floating-point values, so FloVer âreports ranges containing only subnormals, infinity or not a number (NaN) special values as errorsâ (Section II, p. 3). Absolute bounds can be conservative. The soundness theorem is conditional on a successful certificate check and on the formalized IEEE754 connection.
technique 4: extract a verified checker binary
what it is and when to use it. Execute the checker outside the theorem prover without losing its proved correctness. HOL4 functions are compiled with CakeMLâs proof-producing synthesis; Coq functions are extracted to OCaml but the latter binary is unverified. Use this when in-logic evaluation is too slow.
how to do it. (1) Define and prove the checker in HOL4. (2) Use CakeMLâs proof-producing synthesis to translate the ML-like HOL4 definitions into CakeML programs, then compile them in-logic with the verified compiler; the authors also had to prove that their rational representation respects CakeMLâs structural equality (Section VI, p. 6). (3) Add an unverified lexer and parser for certificate files. (4) Run the binary on the encoded certificate. The paper reports: âHaving compiled the CakeML libraries beforehand, we can compile the checking functions into a verified binary in around 90 minutes on the same machine as we used for the experimentsâ (Section VI, p. 6). The Coq path uses native extraction to OCaml and ocamlopt (Section VI, p. 7; Section VII, p. 7).
Verus form. Inference: a Rust checker could be verified as a normal executable function with a proof that its result implies the certificate theorem, then compiled with the ordinary Rust toolchain. This does not make parsing or the Rust compiler verified; a proof-carrying binary would need an independently justified extraction/compiler boundary.
evidence. Table II compares in-logic Coq/HOL4 checking with CakeML and OCaml binaries. Table II has columns Daisy, Coq (Interval, Affine), HOL4, CakeML, OCaml. For the traincar4 benchmark (269 arithmetic operations), the table reports 10.6 s Daisy, 116.94 s Coq interval, 115.38 s Coq affine, 17429.3 s HOL4 in-logic, 1.10 s CakeML, and 0.77 s OCaml (Table II, p. 7). So the verified CakeML binary is about four orders of magnitude faster than HOL4 in-logic checking on this row, and close to the unverified OCaml binary. For the smallest benchmark (ballBeam, 7 operations) the row is 89.04 s HOL4, below 0.01 s CakeML, and 0.02 s OCaml. The times are end-to-end UNIX time measurements on âa four core Intel i3 processor with 3.3GHz, 8 GB of RAM, running Debian 9â (Section VII, p. 7), âthe average running times for a single run over three runsâ for Daisy, Coq and HOL4, and âfrom 300 executionsâ for the binaries (Section VII, p. 8).
assumptions and limits. The lexer and parser for certificates are described as âunverifiedâ and are included in the extracted binaries (Section VI, p. 6). Coqâs extracted OCaml binary has no equivalent compiler proof (âalbeit unverifiedâ, Section II, p. 2). The paper says the measured time âincludes parsing and generating the certificate for Daisy, checking the proof that FloVer succeeds for Coq and HOL4 in-logic, and running FloVer in the binariesâ (Section VII, p. 8), so the columns measure different things and are not pure checker throughput. The paper suggests Coq in-logic evaluation is faster than HOL4 âprobablyâ because of Coqâs vm_compute (Section VII, p. 8).
what is proved, measured, and trusted
The central formal result is Theorem 1: successful validTypes, validRealRange, validMachineRanges, and validErrors imply sound error bounds and finite evaluation. Theorem 2 connects this result to 64-bit IEEE754 executions, assuming no subnormals occur (Section V-A, p. 6). The checker is implemented and proved in both Coq and HOL4, with the HOL4 limits noted above. The evaluation compares FloVer and FPTaylor error bounds (Table I, p. 7; full list in appendix Table III) and reports per-benchmark timing rows with arithmetic-operation counts in Table II (p. 7). The paper says FloVerâs bounds âare usually close to those proven by FPTaylorâ (Section VII, p. 7). The paper does not report an overall success percentage.
Inference: trusted components include the Coq/HOL4 kernels, the formalized IEEE754 libraries, CakeMLâs verified compiler for the HOL4 path, the certificate parser, and the mathematical assumptions about rounding. Inference: the external analyzer Daisy is not trusted for correctness because FloVer checks its output; it is trusted only as a certificate producer whose artifacts may be rejected. The authors say: âA succesful run of FloVer shows that the encoded roundoff error is a valid upper bound and that the analyzed function can be run without any errors (e.g. division-by-zero).â (Section I, p. 1; âsuccesfulâ as in the paper).
Inference: threat to agent-written verified Rust is medium. The certificate/checker split could reduce the trusted computing base for generated proof artifacts and detect unsound analyzer output, but finite-precision arithmetic is a narrower domain than general Rust verification. The parser, Rust compiler, unsafe code, external libraries, and specification adequacy remain outside this paperâs proof.
techniques for the catalog
- certificate carrying analysis results â encode AST, precondition, types, ranges, and per-node errors for independent checking
- modular validator composition â check types, real ranges, machine ranges, and roundoff errors separately and compose soundness theorems
- interval and affine range validation â recompute sound enclosures inside the prover, using affine correlations when intervals are too coarse
- operation-level error propagation â derive addition, multiplication, division, and FMA bounds from operand ranges and errors
- machine-safety validation â reject overflow, NaN, infinity, and possible division by zero under finite-precision execution
- verified extraction â compile a proved HOL4 checker to a CakeML binary while distinguishing the unverified Coq/OCaml path
- analyzer/checker separation â treat Daisy as an untrusted certificate producer and accept only certificates passing the verified checker
Last edited: