Getting started
Install
PyPI (default)
Alkahest is on the Python Package Index. Supported interpreters are Python 3.9 through 3.13 (requires-python on PyPI).
python -m pip install -U pip
pip install alkahest
Use a virtual environment when you also build from source or test multiple Python versions:
python3 -m venv .venv && source .venv/bin/activate # Windows: .venv\Scripts\activate
python -m pip install -U pip
pip install alkahest
Default PyPI wheels include the vendored egglog e-graph backend (egraph) and the Gröbner solver (groebner) — so alkahest.solve, Diophantine, and homotopy APIs are available out of the box. They do not include LLVM JIT, Cranelift, or parallel. Numeric APIs use the tree-walking interpreter fallback.
There is no pip install alkahest[jit] / alkahest[full] that swaps the native extension: pip extras only add Python dependencies, not alternate binaries.
For native LLVM CPU JIT—or JIT plus parallel F4—use an opt-in +jit or +full Linux wheel from GitHub Releases (below), or build from source (add --features cranelift for a pure-Rust fast-compile JIT without system LLVM). See the repository README.md for the same policy in short form.
Optional Linux wheels (+jit / +full)
Tagged releases attach linux_x86_64 wheels on GitHub Releases (CI builds them on ubuntu-22.04; these are not the manylinux wheels published as the default PyPI binaries). Pick the .whl whose tags match your Python (cp311, etc.) and linux_x86_64.
| Local version | Cargo features | When to use |
|---|---|---|
+jit | egraph groebner jit | LLVM CPU JIT (smaller than +full; groebner and egraph are already in the default PyPI wheel). |
+full | egraph groebner jit parallel | JIT plus parallel F4 S-polynomial reduction (largest wheel). |
Example direct installs (replace version, tag, and wheel name using the release asset list):
pip install "https://github.com/alkahest-cas/alkahest/releases/download/v2.0.2/alkahest-2.0.2+full-cp311-cp311-linux_x86_64.whl"
pip install "https://github.com/alkahest-cas/alkahest/releases/download/v2.0.2/alkahest-2.0.2+jit-cp311-cp311-linux_x86_64.whl"
These wheels vendor LLVM and related .so files under site-packages/alkahest.libs/. If import alkahest fails with a missing libLLVM-*.so or libffi-*.so, prepend that directory to LD_LIBRARY_PATH (or install matching system packages).
If your downloader rejects + in the URL, percent-encode it in the filename segment (e.g. 2.0.2%2Bfull).
After +jit or +full, alkahest.jit_is_available() should be True. Gröbner-backed APIs such as alkahest.solve are available in all wheels (including the default PyPI wheel) since groebner became a default Cargo feature in 2.3.1.
macOS and Windows +jit / +full wheels are not produced in CI yet; use building from source there.
Roadmap: a small PEP 503 extras index URL hosting only +jit / +full wheels (PyTorch-style --extra-index-url). Until then, use PyPI for the default wheel or direct URLs / asset downloads from Releases.
Optional: RL environments (alkahest[rl])
Reinforcement-learning environments (symbolic integration, Prime Intellect Hub) are an
optional extra. Requires Python ≥ 3.10 (verifiers does not support 3.9).
pip install "alkahest[rl]"
This adds verifiers and datasets. Environment code ships in the main wheel under
alkahest.rl. See the RL guide for API details, veRL integration, and
Environments Hub publishing.
From source
For optional Cargo features (jit, parallel, cuda, …), GPU/NVPTX, or development, build the PyO3 extension with maturin. The groebner and egraph features are default and included automatically.
Prerequisites (typical): Rust stable (≥ 1.76) and nightly, LLVM 15, FLINT (≥ 2.9, pulls in GMP/MPFR). See the repository README for distro-specific package names.
pip install maturin
git clone https://github.com/alkahest-cas/alkahest.git
cd alkahest
maturin develop --manifest-path alkahest-py/Cargo.toml --release
The default build already includes egraph and groebner. Additional optional features:
# LLVM JIT for native compiled evaluation
maturin develop --manifest-path alkahest-py/Cargo.toml --release --features jit
# Pure-Rust Cranelift JIT (fast compile, no system LLVM required)
maturin develop --manifest-path alkahest-py/Cargo.toml --release --features cranelift
# Parallel simplification and parallel F4 (sharded ExprPool + numpy_eval_par)
maturin develop --manifest-path alkahest-py/Cargo.toml --release --features parallel
# CUDA / NVPTX codegen (requires CUDA toolkit and LLVM with NVPTX target)
maturin develop --manifest-path alkahest-py/Cargo.toml --release --features cuda
# Full native build (JIT + parallel; egraph and groebner are already default)
maturin develop --manifest-path alkahest-py/Cargo.toml --release --features "parallel cranelift jit"
Rust crate
alkahest-cas is also published on crates.io (docs.rs) for use directly from Rust:
[dependencies]
alkahest-cas = "2"
# groebner is included by default; add other optional features as needed:
# alkahest-cas = { version = "2", features = ["parallel", "egraph"] }
System prerequisites (same libraries as the Python build — must be installed before cargo build):
# Debian / Ubuntu
sudo apt-get install -y libflint-dev libgmp-dev libmpfr-dev
# macOS (Homebrew)
brew install flint
The jit feature additionally requires LLVM 15 dev headers (llvm-15-dev / brew install llvm@15).
A self-contained runnable example is in examples/rust_quickstart/.
First steps
Every computation starts with an ExprPool. It owns all expressions; you create symbols and integers from it.
import alkahest
from alkahest import ExprPool, diff, simplify, integrate, sin, exp, cos
pool = ExprPool()
x = pool.symbol("x")
y = pool.symbol("y")
Building expressions
Python operators build expression trees:
expr = x**2 + pool.integer(2) * x + pool.integer(1)
print(expr) # x^2 + 2*x + 1
Math functions accept expressions:
f = sin(x**2) + exp(x * y)
Parsing expressions from strings
Use parse when the expression comes from user input or a config file:
from alkahest import parse
e = parse("x^2 + 2*x + 1", pool, {"x": x})
print(e) # x^2 + 2*x + 1
Identifiers not in the symbols dict are auto-created as symbols in pool.
Both ^ and ** denote exponentiation. See Parsing from strings
for the full syntax reference.
Simplification
r = simplify(x + pool.integer(0))
print(r.value) # x
print(r.steps) # [RewriteStep(rule='add_zero', ...)]
Differentiation
dr = diff(sin(x**2), x)
print(dr.value) # 2*x*cos(x^2)
Integration
r = integrate(exp(x), x)
print(r.value) # exp(x)
r = integrate(sin(x), x)
print(r.value) # -cos(x)
Polynomial arithmetic
from alkahest import UniPoly, RationalFunction
# Convert to FLINT-backed univariate polynomial
p = UniPoly.from_symbolic(x**3 + pool.integer(-1), x)
q = UniPoly.from_symbolic(x + pool.integer(-1), x)
print(p.gcd(q)) # x - 1
print(p // q) # x^2 + x + 1
Compiled evaluation
from alkahest import compile_expr, eval_expr
# Scalar evaluation via a dict binding
result = eval_expr(x**2 + y, {x: 3.0, y: 1.0})
print(result) # 10.0
# JIT-compiled callable
f = compile_expr(x**2 + pool.integer(1), [x])
print(f([3.0])) # 10.0
Vectorized evaluation over NumPy arrays
import numpy as np
from alkahest import compile_expr, numpy_eval
f = compile_expr(sin(x) * exp(pool.integer(-1) * x), [x])
xs = np.linspace(0, 10, 1_000_000)
ys = numpy_eval(f, xs) # vectorised; much faster than a Python loop
Context manager
with alkahest.context(pool=pool, simplify=True):
z = alkahest.symbol("z") # uses the active pool
expr = z**2 + alkahest.sin(z)
Running the examples
The examples/ directory in the Git repository has runnable end-to-end scripts. With alkahest installed (pip install alkahest or maturin develop as above), from the repository root run:
python examples/calculus.py
python examples/polynomials.py
python examples/jit_eval.py
python examples/ball_arithmetic.py
python examples/ode_modeling.py
If you are developing without installing the extension into the active environment, set PYTHONPATH=python so the pure-Python package is importable alongside your build.