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:

  1. ^ (exponentiation) - highest
  2. *, / (multiplication, division)
  3. +, - (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:

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")

Next Steps