3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2026-04-11 15:00:34 +00:00
z3/fstar
copilot-swe-agent[bot] e3aa907098
fstar: formalize FPA rewriter rules from PR #9038 in F* using IEEE 754 axioms
Agent-Logs-Url: https://github.com/Z3Prover/z3/sessions/7899b653-a7f0-443c-894a-32376baea5c0

Co-authored-by: NikolajBjorner <3085284+NikolajBjorner@users.noreply.github.com>
2026-04-03 18:05:00 +00:00
..
FPARewriterRules.fst fstar: formalize FPA rewriter rules from PR #9038 in F* using IEEE 754 axioms 2026-04-03 18:05:00 +00:00
IEEE754.fst fstar: formalize FPA rewriter rules from PR #9038 in F* using IEEE 754 axioms 2026-04-03 18:05:00 +00:00
README.md fstar: formalize FPA rewriter rules from PR #9038 in F* using IEEE 754 axioms 2026-04-03 18:05:00 +00:00

F* Formalization of FPA Rewriter Rules (PR #9038)

This directory contains a formalization of the floating-point rewrite rules introduced in Z3 PR #9038 in the F* proof assistant.

Overview

PR #9038 adds three families of optimizations to src/ast/rewriter/fpa_rewriter.cpp that avoid expensive FP bit-blasting:

Optimization C++ function Formalized in
fma(rm, ±0, y, z) zero-multiplicand decomposition mk_fma FPARewriterRules.fst §1
isNaN/isInf/isNormal applied to to_fp(rm, to_real(int)) mk_is_nan, mk_is_inf, mk_is_normal, mk_is_inf_of_int FPARewriterRules.fst §2
Push classification predicates through ite with concrete branches mk_is_nan, mk_is_inf, mk_is_normal FPARewriterRules.fst §3

Files

IEEE754.fst

Abstract axiomatic theory of IEEE 754 floating-point arithmetic.

  • Type float eb sb — abstract float parameterized by exponent bits eb and significand bits sb, matching Z3's mpf representation.
  • Type rounding_mode — the five IEEE 754 rounding modes (RNE, RNA, RTP, RTN, RTZ).
  • Classification predicatesis_nan, is_inf, is_zero, is_normal, is_subnormal, is_negative, is_positive, derived is_finite.
  • Arithmetic operationsfp_add, fp_mul, fp_fma.
  • Conversionto_fp_of_int rm x representing to_fp(rm, to_real(x)).
  • Axioms (ax_*) — consequences of the IEEE 754-2019 standard taken as given, covering classification exclusivity, NaN propagation, special-value arithmetic, and integer-conversion properties.
  • Overflow thresholdsoverflow_threshold eb sb and max_finite_int eb sb corresponding to the values computed by mk_is_inf_of_int in the C++ rewriter.

All axioms use assume val, marking them as trusted without proof.

FPARewriterRules.fst

Derived rewrite rules proved from IEEE754.fst axioms.

Section 1 — FMA with a Zero Multiplicand

Lemma Statement
lemma_fma_zero_nan_addend fma(rm, ±0, y, NaN) = NaN
lemma_fma_zero_nan_mul fma(rm, ±0, NaN, z) = NaN
lemma_fma_zero_inf_mul fma(rm, ±0, ±∞, z) = NaN
lemma_fma_zero_finite_decomposes fma(rm, ±0, y_finite, z) = fp_add(rm, fp_mul(rm, ±0, y_finite), z)
lemma_fma_zero_const_addend fma(rm, ±0, y_finite, z_nonzero_finite) = z
lemma_fma_zero_const_finite_arm finite arm of the ite for symbolic y, concrete non-zero z
lemma_fma_zero_const_nan_inf_arm NaN/inf arm of the same ite
lemma_fma_zero_general_finite_arm finite arm for fully symbolic y and z
lemma_fma_zero_general_nan_inf_arm NaN/inf arm for fully symbolic y and z
lemma_fma_zero_product_sign sign of fp_mul(rm, ±0, y) = sign(±0) XOR sign(y)
lemma_fma_zero_ite_correct full composite: fma(rm, ±0, y, z) = ite(is_finite(y), fp_add(rm, fp_mul(rm, ±0, y), z), NaN)

Section 2 — Classification of Integer-to-Float Conversions

Lemma Statement
lemma_is_nan_to_fp_int isNaN(to_fp(rm, x)) = false
lemma_is_inf_to_fp_int_rne isInf(to_fp(RNE, x)) ↔ |x| ≥ overflow_threshold
lemma_is_inf_to_fp_int_rna isInf(to_fp(RNA, x)) ↔ |x| ≥ overflow_threshold
lemma_is_inf_to_fp_int_rtp isInf(to_fp(RTP, x)) ↔ x > max_finite_int
lemma_is_inf_to_fp_int_rtn isInf(to_fp(RTN, x)) ↔ x < -max_finite_int
lemma_is_inf_to_fp_int_rtz isInf(to_fp(RTZ, x)) = false
lemma_is_normal_to_fp_int isNormal(to_fp(rm, x)) ↔ x ≠ 0 ∧ ¬isInf(to_fp(rm, x))
lemma_is_normal_to_fp_int_rne combined form for RNE
lemma_is_normal_to_fp_int_rtz combined form for RTZ

Section 3 — Classification through ite

Lemma Statement
lemma_is_nan_ite isNaN(ite(c, t, e)) = ite(c, isNaN(t), isNaN(e))
lemma_is_inf_ite isInf(ite(c, t, e)) = ite(c, isInf(t), isInf(e))
lemma_is_normal_ite isNormal(ite(c, t, e)) = ite(c, isNormal(t), isNormal(e))

The Section 3 lemmas are trivially true in F* by computation (applying a function to if c then t else e reduces to if c then f t else f e), which is why their proofs are the single term ().

Relationship to the C++ Code

The following table maps each lemma to the corresponding C++ code in src/ast/rewriter/fpa_rewriter.cpp after the PR is applied.

Lemma C++ code
lemma_fma_zero_nan_addend if (m_util.is_nan(arg4)) { result = nan; return BR_DONE; }
lemma_fma_zero_nan_mul if (m_util.is_numeral(other_mul, vo) && m_fm.is_nan(vo))
lemma_fma_zero_inf_mul if (m_util.is_numeral(other_mul, vo) && m_fm.is_inf(vo))
lemma_fma_zero_finite_decomposes m_util.mk_add(arg1, m_util.mk_value(product), arg4) with m_fm.mul(rm, vzero, vo, product)
lemma_fma_zero_const_addend m().mk_ite(finite_cond, arg4, nan) (z_const branch)
lemma_fma_zero_general_* general m().mk_ite(finite_cond, m_util.mk_add(...), nan)
lemma_is_nan_to_fp_int mk_is_nan: result = m().mk_false(); return BR_DONE;
lemma_is_inf_to_fp_int_* mk_is_inf_of_int switch statement
lemma_is_normal_to_fp_int mk_is_normal: result = m().mk_and(not_zero, m().mk_not(inf_cond))
lemma_is_nan_ite mk_is_nan: ite-pushthrough block
lemma_is_inf_ite mk_is_inf: ite-pushthrough block
lemma_is_normal_ite mk_is_normal: ite-pushthrough block

IEEE 754 References

The axioms in IEEE754.fst correspond to the following sections of the IEEE 754-2019 standard:

  • §4.3 — Rounding-direction attributes (rounding modes)
  • §5.4 — Arithmetic operations (fp_add, fp_mul, fp_fma)
  • §5.4.1 — Conversion from integer (to_fp_of_int)
  • §5.7.2 — General operations: isNaN, isInfinite, isNormal, etc.
  • §6.2 — Operations on quiet NaNs (NaN propagation)
  • §6.3 — The sign bit: signed zero (ax_zero_mul_sign, ax_add_zero_nonzero)
  • §7.2 — Invalid operation exception: 0 × ∞ = NaN (ax_zero_mul_inf)

Building

To type-check these files with F*, from this directory run:

fstar.exe --include . IEEE754.fst FPARewriterRules.fst

F* 2024.09.05 or later is recommended. The files have no external dependencies beyond the F* standard library prelude.

Because all IEEE 754 semantics are encoded as assume val axioms, the type-checker accepts the development without requiring a concrete model. The derived lemmas in FPARewriterRules.fst are fully verified against those axioms; the Section 3 lemmas (lemma_*_ite) are discharged by computation reduction alone.