Simplification you can audit
Every rewrite records the rule applied — not just the final expression.
from alkahest import ExprPool, simplify
pool = ExprPool()
x = pool.symbol("x")
r = simplify(x + pool.integer(0))
print(r.value) # x
print(r.steps) # e.g. [RewriteStep(rule='add_zero', ...)]
Dense univariate polynomials (FLINT)
GCD and exact division stay in a FLINT-backed representation for heavy
polynomial work.
from alkahest import ExprPool, UniPoly
pool = ExprPool()
x = pool.symbol("x")
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
Plotting — no bundled dependency
alkahest detects what you have installed (Matplotlib or Plotly) and
calls into it. A dependency-free SVG renderer is built into the
Rust kernel for zero-install use.
import alkahest as ak
pool = ak.ExprPool()
x = pool.symbol("x")
# Curve — uses matplotlib by default, or plotly if specified
ak.plot(ak.sin(x), x, (-6.28, 6.28))
ak.plot(ak.sin(x), x, (-6.28, 6.28), backend="plotly")
# 2-D surface
y = pool.symbol("y")
ak.plot3d(ak.sin(x) * ak.cos(y), x, y, (-5, 5), (-5, 5))
# Standalone SVG — no plotting library needed
svg = ak.plot_svg(ak.sin(x), x, (-6, 6))
Use the Rust kernel directly
alkahest-cas is a native Rust crate — embed the CAS in
your own library or CLI without a Python runtime.
// Cargo.toml: alkahest-cas = "2"
use alkahest_cas::{ExprPool, diff, simplify, render_latex, parse};
use alkahest_cas::kernel::Domain;
use std::collections::HashMap;
fn main() {
let pool = ExprPool::new();
let x = pool.symbol("x", Domain::Real);
let mut syms = HashMap::from([("x".to_owned(), x)]);
// parse from a string
let expr = parse("sin(x)^2 + cos(x)^2", &pool, &mut syms).unwrap();
// differentiate
let d = diff(expr, x, &pool).unwrap();
println!("{}", render_latex(d.value, &pool));
}