Equations
Asgard uses LEAN-style mathematical syntax for defining equations. This clean, functional notation supports arithmetic, calculus, elementary functions, stochastic differential equations, and lambda calculus.
Syntax Overview
| Operation | Syntax | Example |
|---|---|---|
| Integration | int(term, var) |
int(f, x) |
| Differentiation | diff(term, var) |
diff(f, x) |
| Exponential | exp(term) |
exp(x) |
| Square root | sqrt(term) |
sqrt(x) |
| Logarithm | log(term) |
log(x) |
| Absolute value | abs(term) |
abs(x) |
| SDE | sde(drift, diffusion, var) |
sde(r * X, sigma * X, t) |
| Parameter | $name |
$alpha |
| Lambda | abstraction var. body |
abstraction x. x * x |
| Application | apply(fn, arg) |
apply(f, 5) |
| Arithmetic | +, -, *, /, ^ |
x + y * 2 |
Creating Equations
from gimle.asgard.equation.equation import Equation
# Simple equation
eq = Equation.from_string("x + y = z")
# Fundamental theorem of calculus
eq = Equation.from_string("diff(int(f, x), x) = f")
# Differential equation with parameter
eq = Equation.from_string("diff(y, t) = $alpha * y")
Integration
Define integrals using the int(term, variable) syntax:
# Integrate f with respect to x
eq = Equation.from_string("int(f, x) = g")
# Nested integrals
eq = Equation.from_string("int(int(f, x), y) = g")
# Integration with arithmetic
eq = Equation.from_string("int(a + b, x) = int(a, x) + int(b, x)")
Differentiation
Define derivatives using the diff(term, variable) syntax:
# Differentiate f with respect to x
eq = Equation.from_string("diff(f, x) = g")
# Partial derivatives
eq = Equation.from_string("diff(diff(u, x), y) = 0")
# Chain with integration (fundamental theorem)
eq = Equation.from_string("diff(int(f, x), x) = f")
Elementary Functions
Four elementary functions are supported as first-class syntax:
# Exponential
eq = Equation.from_string("diff(exp(x), x) = exp(x)")
# Square root
eq = Equation.from_string("sqrt(x * x) = abs(x)")
# Natural logarithm
eq = Equation.from_string("log(exp(x)) = x")
# Absolute value
eq = Equation.from_string("abs(x) = y")
These compile to corresponding circuit atomics (exp, power(0.5), log, abs) and can appear anywhere a term is expected.
Parameters
Parameters are named values supplied at runtime, prefixed with $:
# Growth rate as a parameter
eq = Equation.from_string("diff(y, t) = $rate * y")
# Multiple parameters
eq = Equation.from_string("sde($mu * X, $sigma * X, t) = Y")
Parameters are resolved from a dictionary when the compiled circuit executes. This separates the equation structure from its numeric values, enabling parameter sweeps and optimization.
Stochastic Differential Equations
Define SDEs using the sde(drift, diffusion, variable) syntax:
# Geometric Brownian motion: dX = r*X*dt + sigma*X*dW
eq = Equation.from_string("sde($r * X, $sigma * X, t) = Y")
# Ornstein-Uhlenbeck process: dX = -theta*(X - mu)*dt + sigma*dW
eq = Equation.from_string("sde($theta * ($mu - X), $sigma, t) = Y")
# Constant drift and diffusion
eq = Equation.from_string("sde($drift, $sigma, t) = Y")
The sde operation compiles to circuits with stochastic_register for the diffusion term, enabling Monte Carlo simulation at runtime.
Compiling to Circuits
Equations can be compiled to executable circuits:
from gimle.asgard.equation.equation import Equation
from gimle.asgard.compile.compiler import compile_equation_to_circuit
# Define the equation
eq = Equation.from_string("diff(int(f, x), x) = f")
# Compile to circuit (variable isolation is automatic)
circuit, metadata = compile_equation_to_circuit(eq)
print(circuit)
# Output: composition(register(x), deregister(x)) [1->1]
The compiler handles variable isolation (solving for the unknown), trace wiring (connecting feedback loops), and structural validation automatically.
Differential Equations
Express ODEs and PDEs naturally:
# Simple ODE: dy/dt = -y (exponential decay)
eq = Equation.from_string("diff(y, t) = -1.0 * y")
# Exponential growth: dy/dt = ky
eq = Equation.from_string("diff(y, t) = $k * y")
# Heat equation: du/dt = d^2u/dx^2
eq = Equation.from_string("diff(u, t) = diff(diff(u, x), x)")
# Wave equation
eq = Equation.from_string("diff(diff(u, t), t) = diff(diff(u, x), x)")
Arithmetic Operations
Standard mathematical operators with familiar precedence:
# Basic operations
eq = Equation.from_string("x + y = z")
eq = Equation.from_string("a - b = c")
eq = Equation.from_string("2 * x = y")
eq = Equation.from_string("a / b = c")
eq = Equation.from_string("x ^ 2 = y")
# Compound expressions (use parentheses for grouping)
eq = Equation.from_string("(x + 2) * y = z")
Operator Precedence:
^(exponentiation) - highest*,/(multiplication, division)+,-(addition, subtraction) - lowest
Lambda Calculus
Define anonymous functions using abstraction and application:
# Square function
eq = Equation.from_string("apply(abstraction x. x * x, 5) = 25")
# Nested abstractions (curried function)
eq = Equation.from_string("abstraction x. abstraction y. x + y")
# Function application
eq = Equation.from_string("apply(abstraction x. x + 1, y) = z")
Identifiers and Numbers
Identifiers
# Single letter
eq = Equation.from_string("x = y")
# Multi-letter with underscores
eq = Equation.from_string("initial_value = final_value")
# With numbers (must start with letter)
eq = Equation.from_string("x1 + x2 = y")
Rules:
- Must begin with a letter (a-z, A-Z)
- Can contain letters, numbers, underscores
- Case sensitive (
xandXare different)
Numbers
# Integers
eq = Equation.from_string("x = 42")
# Decimals
eq = Equation.from_string("pi = 3.14159")
# Negative numbers
eq = Equation.from_string("rate = -0.05")