A real SMT solver in Python — no C toolchain, reproducible SMT-COMP benchmarks, and a hard-algebra math stack that is still 100% Pure Rust.
Today we released OxiZ 0.1.2 — an incremental release that gives the Pure Rust SMT solver first-class Python bindings, a self-contained native numeric stack, and the SMT-COMP-style tooling needed to make performance claims reproducible.
No C. No Fortran. No FFI.
Z3 is the de-facto standard for SMT solving, and it is a C++ project — a remarkable one, but one that ties you to a C/C++ toolchain, system libraries, and the long tail of build and supply-chain concerns that come with native code. OxiZ takes the opposite stance: every line is Rust.
The notable thing about 0.1.2 is that even the hard parts stay Pure Rust. The new math layer — Level 1/2/3 BLAS and MPFR-style arbitrary-precision arithmetic — links against no OpenBLAS, no GMP, and no MPFR C libraries. The exact algebra that historically forces projects to reach for battle-tested C numeric stacks is implemented natively here. The result compiles to a single static binary (or to WASM), is memory-safe by construction, and is auditable end to end: you can read every routine your solver actually runs.
Why 0.1.2 matters
This release is about reach and rigor.
- Reach. Python users get a real SMT solver through PyO3 with no C toolchain hassle —
pipandmaturinand you are solving constraints. Noz3-solverwheels to fight, no system Z3 to track. - Rigor in the math. A self-contained Pure-Rust numeric stack (Level 1/2/3 BLAS at ~2,400 LOC, plus multi-precision rationals and reals) means the nonlinear and algebraic-number paths carry no C math dependencies, even for the hard cases.
- Reproducibility. SMT-COMP-style tooling lets you back up performance claims with cactus plots, scatter plots, and virtual-best-solver comparisons instead of hand-waving.
The numbers behind this release: ~240,000 Rust LOC (up from ~173,500), 3,823 tests passing (100%), 13 crates, and roughly 90–92% Z3 parity. Still an early version, and honest about it — but a substantial one.
Technical Deep Dive
The new surface area in 0.1.2 lives in real, shipping crates and modules:
oxiz-py— PyO3 bindings. The Python API mirrors the Rust builder. ATermManagerconstructs terms (mk_var,mk_int,mk_real,mk_bool,mk_add,mk_eq,mk_gt, and friends); aSolverdrives the search (assert_term,check_sat,get_model, pluspush/popfor incremental work); and anOptimizerhandlesminimize/maximize. Int, Real, Bool, and BitVec sorts are all exposed. The bindings ship with a 27-test suite and build with maturin.oxiz-math— Pure-Rust numerics. A native BLAS implementation (Level 1/2/3, matmul, triangular solves; ~2,400 LOC) sits alongside an MPFR-style multi-precision layer offering arbitrary-precision rationals and reals. Together they feed algebraic-number computation without any external C math library.oxiz-satGPU module. CUDA-style parallel SAT infrastructure: parallel clause evaluation and a shared-memory clause database, laying groundwork for GPU-accelerated solving.oxiz-smtcomp— benchmark framework (~8,000 LOC). Benchmark loading and filtering, parallel execution with timeouts, virtual-best-solver (VBS) calculation, regression testing with statistics, HTML reports, cactus and scatter SVG plots, CI/CD integration, and StarExec format compatibility.oxiz-cli— expanded modes. Dashboard mode streams real-time solver stats over WebSocket; server mode exposes a REST interface (POST /solve,/check-sat, …); distributed solving uses a worker/coordinator split with cube-and-conquer; TPTP FOF problems are supported with SZS status output; and--interpolateproduces partition-based Craig interpolants.fuzz/— structured fuzzing. Three targets — the SMT-LIB parser, the term builder, and the solver — driven byArbitrary-derived inputs.
Getting Started
Both Rust and Python are first-class in 0.1.2.
Rust install:
cargo add oxiz
Python install (via maturin):
pip install maturin
cd oxiz-py && maturin develop --release
A minimal Python example using the real oxiz-py API:
import oxiz
tm = oxiz.TermManager()
solver = oxiz.Solver()
# integer variables
x = tm.mk_var("x", "Int")
y = tm.mk_var("y", "Int")
# constraints: x + y = 10, x > 5
ten = tm.mk_int(10)
five = tm.mk_int(5)
sum_xy = tm.mk_add([x, y])
solver.assert_term(tm.mk_eq(sum_xy, ten), tm)
solver.assert_term(tm.mk_gt(x, five), tm)
result = solver.check_sat(tm)
print(f"Result: {result}") # sat
if result == oxiz.SolverResult.Sat:
model = solver.get_model(tm)
print(f"x = {model['x']}, y = {model['y']}")
What’s New in 0.1.2
Added
- NEW
oxiz-py: full PyO3 Python API —TermManager,Solverwithcheck_sat/model retrieval/push/pop,Optimizerwithminimize/maximize, and Int/Real/Bool/BitVec sorts; 27 tests. - NEW
oxiz-math: Pure-Rust BLAS (Level 1/2/3, ~2,400 LOC) plus MPFR-style multi-precision (arbitrary-precision rationals and reals). - NEW
oxiz-satGPU acceleration module: CUDA-style parallel SAT with parallel clause evaluation and a shared-memory clause database. - NEW
oxiz-smtcomp: ~8,000-LOC SMT-COMP benchmark suite — VBS, regression testing, HTML/cactus/scatter reports, StarExec compatibility, CI/CD integration. - NEW
oxiz-clifeatures: dashboard (WebSocket), server (REST), distributed cube-and-conquer, TPTP/SZS, and--interpolate. - NEW fuzzing: three targets (parser, term builder, solver) driven by
Arbitrary.
Fixed
- LIA strict-inequality handling now uses delta-rational bounds in the simplex core.
- BitVector comparison values now appear correctly in models.
- Optimizer maximization performs a proper linear search to the true optimum instead of returning the first satisfying assignment.
- Simplex
push/popcleans up stale tableau entries after backtracking.
Changed
- Clippy-clean across all crates.
- 3,823 tests passing (100%); ~240,000 Rust LOC.
- Edition 2024 (Rust 1.85+); Python 3.8+ for the bindings.
Tips
- Python users:
maturin develop --releasegives you a fast local build with optimizations on. The Python API mirrors the Rust builder almost exactly — aTermManagerto build terms and aSolverto discharge them — so Rust examples translate directly. - Prove your wins. Run
oxiz-smtcompto generate reproducible cactus and scatter plots plus VBS comparisons before claiming a speedup. Reviewers trust plots, not adjectives. - Embed it as a service. The CLI
servermode exposes a REST API (POST /solve,/check-sat), which makes it straightforward to drop OxiZ into a microservice or CI gate. - Reason about programs.
--interpolateyields Craig interpolants — handy for software model checking and invariant inference. - Scale to hard instances. The distributed worker/coordinator mode enables cube-and-conquer, splitting tough problems across workers.
- Stay Pure Rust on the hard paths. Because
oxiz-mathnow provides native BLAS and multi-precision arithmetic, the nonlinear and algebraic routines never fall back to a C math library.
This is the foundation
OxiZ is meant to be the native, auditable formal-reasoning engine for the Pure Rust ecosystem — the kind of solver that verification, program-analysis, and legal-tech tools build on. It has already been used to verify the Legalis framework. A memory-safe SMT core you can read, ship as one static binary, and run anywhere Rust runs is a different kind of building block than a C++ dependency you treat as a black box.
Repository: https://github.com/cool-japan/oxiz
Star the repo if a Pure Rust SMT solver — in Rust and now in Python — is the kind of foundation you want to build on.
Pure Rust formal reasoning is here — fast, safe, and sovereign.
— KitaSan at COOLJAPAN OÜ January 21, 2026