- Symbolic expressions — first-class symbolic algebra: declare symbolic variables, compose expressions with
+,-,*,/, and evaluate with concrete values at runtime. - JIT compilation — programs are compiled on-the-fly via MLIR/LLVM and executed natively.
- MLIR-powered — a custom MLIR dialect (
symbolic) represents symbolic expressions, lowered toarith+funcfor native codegen. - Statically typed — type-checked at compile time.
df main() i32 {
sym x: expr<i32>;
let a: expr<i32> = x + 5;
let r1: i32 = eval(a, x, 10);
let b: expr<i32> = 3 * x;
let r2: i32 = eval(b, x, 10);
let c: expr<i32> = 2 * x + 1;
let r3: i32 = eval(c, x, 10);
return r1 + r2 + r3;
}Declares symbolic variables (sym), composes expressions with arithmetic, and evaluates them with concrete values at runtime.
LLVM/MLIR 21 is required. After installing, set:
export LLVM_SYS_211_PREFIX=/path/to/llvm-21
export MLIR_SYS_210_PREFIX=/path/to/llvm-21
export TABLEGEN_210_PREFIX=/path/to/llvm-21Installing LLVM/MLIR (click to expand)
brew install llvm@21
export LLVM_SYS_211_PREFIX=$(brew --prefix llvm@21)
export MLIR_SYS_210_PREFIX=$(brew --prefix llvm@21)
export TABLEGEN_210_PREFIX=$(brew --prefix llvm@21)You may also need:
export LIBRARY_PATH=/opt/homebrew/libRequires ~6 GB RAM and ~20 GB disk space.
git clone https://github.com/llvm/llvm-project.git
cd llvm-project
git checkout llvmorg-21.1.7
cmake -G Ninja ../llvm \
-DLLVM_ENABLE_PROJECTS="mlir" \
-DCMAKE_BUILD_TYPE=RelWithDebInfo \
-DLLVM_ENABLE_ASSERTIONS=On \
-DLLVM_BUILD_LLVM_DYLIB=On \
-DLLVM_LINK_LLVM_DYLIB=On \
-DMLIR_BUILD_MLIR_C_DYLIB=On \
-DLLVM_TARGETS_TO_BUILD=host \
-DCMAKE_INSTALL_PREFIX=/opt/llvm-21 \
-DLLVM_USE_LINKER=mold # optional, faster with mold
ninja installcargo install mathicMake sure
LLVM_SYS_211_PREFIX,MLIR_SYS_210_PREFIXandTABLEGEN_210_PREFIXare set before building.
euler <file>.mthSee docs/ for the full project structure and pipeline. See docs/dialects/Symbolic.md for the symbolic dialect reference.
Early development. Features are added incrementally. The symbolic dialect and its lowering passes are functional but evolving.
Built with ❤️ and 🦀 Rust