Jerbie.jl is a Julia/Rust tool for automatically improving the floating-point accuracy of numerical expressions, using equality saturation (via egg) to search for mathematically equivalent rewrites and real point-sampling (via rival) to score each candidate's accuracy. It follows the same search+score methodology as Herbie.
Jerbie.jl is not yet a registered Julia package. Until then, install it directly from source:
using Pkg
Pkg.develop(url = "https://github.com/JuliaSymbolics/Jerbie.jl.git", subdir = "Jerbie.jl")Jerbie's e-graph search runs through a Rust backend (egg-jerbie/) that must
be built locally before use — a prebuilt binary distribution (via
BinaryBuilder/Jerbie_jll) is planned but not yet available:
cd egg-jerbie
cargo build --releaseSee the dev documentation
for the full API reference and internals guide. It is rebuilt automatically
on every push to main.
egg-jerbie— this repo's own Rust crate, a thin FFI layer around theeggequality-saturation library. Jerbie.jl calls into it viaccallto build, saturate, and extract from e-graphs; the rewrite rule set (egg-jerbie/src/herbie_rules.rs) is adapted from Herbie's own rules.rival3— a Rust dependency ofegg-jerbie, used to evaluate each rewrite candidate against real-valued sample points to score its floating-point accuracy.- Herbie — the Racket tool this project's
search+score approach is directly modeled on. Herbie solves the same
problem (find a more accurate equivalent of a floating-point expression);
Jerbie.jl re-implements that methodology for the Julia/Symbolics.jl
ecosystem, on top of
eggrather than Herbie's own e-graph implementation.
Expressions are written as ordinary Julia code over Symbolics.jl variables:
using Symbolics, Jerbie
@variables x
result = optimize_expr(sqrt(x + 1) - sqrt(x))This runs the full search (guided by equality saturation) and scores every candidate against 8000 held-out sample points, printing a summary:
*********************************************************************
input: sqrt(1 + x) - sqrt(x)
alternatives:
[1] 1 / (sqrt(1 + x) + sqrt(x))
[2] 1 / (1 + sqrt(x))
[3] sqrt(1 + x) - sqrt(x)
start_score (bits-of-error, original): 29.658448391155197
end_score (bits-of-error, winner): 0.1634530078147536
The scores are bits-of-error (lower is better) — the winning alternative here
recovers about 29.5 bits of accuracy lost to catastrophic cancellation in the
original expression, near x = 0.
result itself is a NamedTuple with everything needed to inspect or reuse
the run:
julia> propertynames(result)
(:alternatives, :start_score, :end_score, :test_context)See the documentation for
the full walkthrough, including run_improve_with_report and the lower-level
e-graph/scoring primitives Jerbie.jl is built from.
Jerbie.jl builds directly on the following prior work:
@article{2021-egg,
author = {Willsey, Max and Nandi, Chandrakana and Wang, Yisu Remy and Flatt, Oliver and Tatlock, Zachary and Panchekha, Pavel},
title = {egg: Fast and Extensible Equality Saturation},
year = {2021},
journal = {Proc. ACM Program. Lang.},
volume = {5},
number = {POPL},
articleno = {23},
doi = {10.1145/3434304},
url = {https://doi.org/10.1145/3434304}
}
@misc{flatt2021interval,
author = {Flatt, Oliver and Panchekha, Pavel},
title = {An Interval Arithmetic for Robust Error Estimation},
year = {2021},
eprint = {2107.05784},
archivePrefix = {arXiv},
primaryClass = {math.NA},
url = {https://arxiv.org/abs/2107.05784}
}
@inproceedings{panchekha2015herbie,
author = {Panchekha, Pavel and Sanchez-Stern, Alex and Wilcox, James R. and Tatlock, Zachary},
title = {Automatically Improving Accuracy for Floating Point Expressions},
booktitle = {Proceedings of the 36th ACM SIGPLAN Conference on Programming Language Design and Implementation},
series = {PLDI '15},
year = {2015},
pages = {1--11},
doi = {10.1145/2737924.2737959},
url = {https://dl.acm.org/doi/10.1145/2737924.2737959}
}@ParthsarthiSingh-glang
Developed with assistance from Claude (Anthropic). Especially for test generation, parsing, and documentation.