COOLJAPAN
← All posts

SciRS2 0.4.4 Released — A Pure-Rust Computer Algebra System Lands in scirs2-symbolic

SciRS2 0.4.4 turns scirs2-symbolic into a full computer algebra system — EML-IR-native canonical form, real OxiZ SMT verification, Cranelift JIT, symbolic regression, and LaTeX export. A pure-Rust SymPy/Mathematica alternative on top of the NumPy/SciPy replacement.

release scirs2 computer-algebra symbolic-math smt jit pure-rust scientific-computing

A computer algebra system that compiles to a single static binary, verifies its own rewrites with an SMT solver, and JITs your symbolic expressions to native code — written entirely in Rust.

Today we released SciRS2 0.4.4 — the release where scirs2-symbolic stops being an expression library and becomes a real computer algebra system, built on a hash-consed EML intermediate representation with an EML-IR-native canonical form, OxiZ-backed SMT verification, and a Cranelift JIT.

No C. No Fortran. No SymPy. No Mathematica license. The whole CAS — the term graph, the canonicalizer, the SMT-certified rewriter, the symbolic-regression engine, the LaTeX exporter — is pure Rust. It compiles to a single static binary, or to WASM, and runs anywhere your code runs. There is no Python interpreter to ship, no proprietary kernel to license, and nothing to phone home.

This is a patch release by number, but a genuinely large feature drop: 0.4.4 ships 36,446+ tests passing across 29 workspace crates, 4.2 million lines of Rust, 80,800+ public API items, zero warnings (clippy + rustdoc + fmt clean), Apache-2.0. The symbolic side alone gained roughly 564 new tests this release, growing to 800+ symbolic tests through the wave series, plus 8 new tests in the autograd symbolic backend.

Why SciRS2 0.4.4 is a game changer

Symbolic mathematics has long been split between two unhappy choices. SymPy is open and friendly but Python-only and slow, with no path to a compiled artifact and an awkward story for embedding inside a high-performance numerical pipeline. Mathematica and the other commercial systems are fast and complete but proprietary, license-gated, and impossible to vendor into a sovereign Rust application. Neither one JITs your expressions to native code, and neither one drops cleanly into a cargo build.

SciRS2 0.4.4 closes that gap with concrete, tested machinery:

The float-tape-to-EML gradient parity is below 1e-10 over 12 operations, and the whole EML substrate is a clean-room native implementation with oxieml v0.1.0 parity at 1e-9 tolerance (ADR-0001).

Technical Deep Dive: A CAS built on EML-IR

(a) The EML substrate. Everything starts with eml::tree. An expression is an EmlTree of Arc-shared EmlNodes, deduplicated through a thread-local hash-cons table and keyed by a u128 structural hash. There are 27 canonical EML constructors. For evaluation and compilation, a tree is lowered to a flat LoweredOp IR plus a stack-machine tape via lower/raise, and an iterative stack-machine evaluator runs it over real f64 or Complex64 — iterative, not recursive, so it stays stack-safe even on 543-deep trees. Differentiation is symbolic: eml::grad (along with grad_all, jacobian, and hessian, all public) produces gradient expressions in the same IR, and outward-rounded interval arithmetic is available for rigorous bounds.

(b) cas::canonicalize + cas::smt. Canonicalization applies the seven rewrite rules to a fixed point, idempotently, so two expressions that are algebraically equal converge to the same normal form. Verification lives in cas::smt: the EmlSmtSolver first tries a structural-hash fast path, then falls back to OxiZ’s QF_NRA decision procedure with real backtracking, encoding transcendental functions through an Ackermann scheme for 16 operations. Rewrites can be certified, with RAII guarding solver state. One important detail (and a tip below): always canonicalize before calling the solver — OxiZ 0.2.1’s NLSAT is incomplete on surface commutativity, so the canonical form does the commutativity work the solver shouldn’t have to.

(c) compile::to_jit / compile::to_gpu. Hot symbolic expressions don’t have to stay interpreted. compile::to_jit runs LoweredOp through Cranelift to native CPU code, cached by structural hash in a JitCache. compile::to_gpu emits a WGSL compute shader for batched evaluation on the GPU. to_jit_auto picks between them by batch size — CPU below ~100k, GPU above.

(d) Symbolic regression and cross-crate integration. regression::discover is ndarray-first with a Config builder (max_depth, learning_rate, tolerance, cv_folds, loss, strategy, seed, parallel); discover_multi handles vector targets (Lorenz, double-pendulum) and discover_ode does SINDy-style RHS discovery. Results come back as a regression::Pareto of DiscoveredFormula. Constraints (with_constraints) are SMT-pruned — monotone_increasing, range_bounded, odd_function, even_function, BoundedOutput, Monotonic — and units::{Units, Dimension, UnitAware} provide the SI 7-vector dimensional check. Prediction is NUMA-aware and parallel.

The CAS reaches across the workspace, too. scirs2-optimize gains symbolic::newton (exact symbolic Hessian and gradient via Gaussian elimination), lbfgs_symbolic, trust_region_symbolic, and a Lagrangian/KKT layer (build_kkt, solve_lagrangian_symbolic). scirs2-integrate gets solve_ivp_symbolic (BDF1 with a JIT-compiled symbolic Jacobian) and quad_gauss_legendre_symbolic. scirs2-linalg adds det_symbolic, eigenvalues_symbolic_2x2, condition_number_symbolic, and einsum/einsum_grad. scirs2-stats adds mle_symbolic/mle::derive, and scirs2-neural gains SymbolicActivation/SymbolicLoss and a closed-form RoPE attention logit. The whole thing is clean-room compatible with oxieml (parity-tested) and leans on OxiZ for verification.

Getting Started

Add SciRS2 to your project:

cargo add scirs2

A minimal taste of the new CAS — build f = x² + sin(x), take its symbolic derivative, canonicalize, JIT-compile, and evaluate:

use scirs2::symbolic::{eml, cas, compile};

fn main() {
    // Build f(x) = x^2 + sin(x) as an EML expression.
    let x = eml::var("x");
    let f = eml::add(
        eml::pow(x.clone(), eml::constant(2.0)),
        eml::sin(x.clone()),
    );

    // Symbolic gradient: df/dx = 2*x + cos(x).
    let df = eml::grad(&f, "x");

    // Canonicalize to the EML-IR normal form (fixed-point, idempotent).
    let df = cas::canonicalize(&df);

    // Lower to flat IR and JIT-compile for repeated evaluation.
    let lowered = eml::lower(&df);
    let jit = compile::to_jit(&lowered);

    // Evaluate df/dx at x = 1.0.
    let value = jit.eval_real(&[("x", 1.0)]);
    println!("df/dx at x=1: {value}"); // 2*1 + cos(1) ≈ 2.5403

    // Or evaluate the symbolic IR directly without compiling.
    let direct = eml::eval_real(&df, &[("x", 1.0)]);
    println!("direct: {direct}");
}

Everything here — eml::grad, cas::canonicalize, compile::to_jit, eval_real — is real public API in 0.4.4.

What’s New in 0.4.4

The CAS centerpiece

Bindings and integrations

Advanced CAS (later waves landing in 0.4.4)

Non-symbolic algorithm wins

Tips

Part of the COOLJAPAN ecosystem

SciRS2’s new CAS doesn’t stand alone. Verification runs on OxiZ, our pure-Rust SMT solver, through its QF_NRA decision procedure; the JIT is built on Cranelift; the EML substrate is a clean-room, parity-tested twin of oxieml; and the numeric core continues to rest on OxiBLAS and OxiFFT for pure-Rust linear algebra and transforms. Around it sit the rest of the COOLJAPAN peers — torsh, optirs, numrs, pandrs, sklears, and trustformers — so symbolic math, numerics, dataframes, classical ML, and deep learning share one sovereign, C-free, Fortran-free foundation.

Repository: https://github.com/cool-japan/scirs

Star the repo if a pure-Rust computer algebra system — one you can vendor, JIT, verify, and ship as a single binary — is something you’ve been waiting for.

Pure Rust computer algebra is here — fast, safe, verifiable, and sovereign.

KitaSan at COOLJAPAN OÜ May 15, 2026

↑ Back to all posts