Equation Grammar Specification

Complete grammar specification for Asgard's LEAN-style equation syntax.

Overview

Equations in Asgard use LEAN-style syntax - a clean, functional notation for mathematical expressions. The grammar supports:

Grammar Definition

start: equation

equation: term "=" term

term: IDENTIFIER
    | NUMBER
    | application
    | arithmetic_operation
    | integral
    | derivative
    | abstraction
    | "(" term ")"

IDENTIFIER: /[a-zA-Z][a-zA-Z0-9_]*/

NUMBER: /-?[0-9]+(\.[0-9]+)?/

Arithmetic Operations

Syntax

arithmetic_operation: term operator term

operator: "+" | "-" | "*" | "/" | "^"

Examples

# Addition
"x + y = z"

# Subtraction
"a - b = c"

# Multiplication
"2 * x = y"

# Division
"a / b = c"

# Exponentiation
"x ^ 2 = y"

# Compound expressions
"(x + 2) * y = z"

# Nested operations
"a + b * c = d"  # Parsed as: a + (b * c)

Operator Precedence

Standard mathematical precedence:

  1. ^ (exponentiation) - highest
  2. *, / (multiplication, division)
  3. +, - (addition, subtraction) - lowest

Use parentheses for explicit grouping: (a + b) * c

Integration

Syntax

integral: "∫" term "d" IDENTIFIER
        | "int" "(" term "," IDENTIFIER ")"

Examples

# Unicode syntax (∫)
"∫ f d x = g"

# ASCII syntax (int) - recommended
"int(f, x) = g"

# Integration with respect to multiple variables
"int(int(f, x), y) = g"

# Fundamental theorem
"diff(int(f, x), x) = f"

Usage

Differentiation

Syntax

derivative: "d/d" IDENTIFIER "(" term ")"
          | "diff" "(" term "," IDENTIFIER ")"

Examples

# Unicode syntax (d/d)
"d/d x (f) = g"

# ASCII syntax (diff) - recommended
"diff(f, x) = g"

# Partial derivatives
"diff(diff(f, x), y) = g"

# Chain with integration
"diff(int(f, x), x) = f"

# Differential equation
"diff(y, t) = scalar(-0.1, y)"

Usage

Abstraction (Lambda)

Syntax

abstraction: "λ" IDENTIFIER "." term
           | "abstraction" IDENTIFIER "." term

Examples

# Lambda notation
"λ x. x * x"  # Square function

# ASCII notation
"abstraction x. x * x"

# Used in equations
"apply(abstraction x. x + 1, 5) = 6"

# Nested abstractions
"abstraction x. abstraction y. x + y"

# Abstraction with complex body
"abstraction f. diff(int(f, x), x)"

Usage

Application

Syntax

application: abstraction "@" (IDENTIFIER | NUMBER | "(" term ")")
           | "apply" "(" abstraction "," (IDENTIFIER | NUMBER | term) ")"

Examples

# Infix notation (@)
"(λ x. x * x) @ 5 = 25"

# Prefix notation (apply)
"apply(abstraction x. x * x, 5) = 25"

# Application with identifier
"apply(abstraction x. x + 1, y) = z"

# Complex application
"apply(abstraction x. x * x + x + 2, 3) = 0"

# Nested application
"apply(apply(abstraction x. abstraction y. x + y, 2), 3) = 5"

Usage

Identifiers

Syntax

IDENTIFIER: /[a-zA-Z][a-zA-Z0-9_]*/

Examples

# Single letter
"x = y"

# Multi-letter
"velocity = distance / time"

# With numbers
"x1 + x2 = y"

# With underscores
"initial_value = final_value"

# CamelCase
"maxValue = minValue + offset"

Rules

Numbers

Syntax

NUMBER: /-?[0-9]+(\.[0-9]+)?/

Examples

# Integers
"x = 42"
"y = -10"

# Decimals
"pi = 3.14159"
"rate = -0.05"

# Scientific notation not supported
# Use: "1000000" instead of "1e6"

Rules

Comments

Syntax

COMMENT: "#" /[^\n]*/

Examples

# Simple comment
"x + y = z  # This is a comment"

# Full line comment
"# Define the differential equation
diff(y, t) = y"

Rules

Complete Examples

Example 1: Simple Arithmetic

from gimle.asgard.equation.equation import Equation

eq = Equation.from_string("x + y = z")
eq = Equation.from_string("2 * x + 3 = y")
eq = Equation.from_string("(a + b) * (c + d) = result")

Example 2: Calculus

# Fundamental theorem of calculus
eq = Equation.from_string("diff(int(f, x), x) = f")

# Integration
eq = Equation.from_string("int(velocity, t) = position")

# Differentiation
eq = Equation.from_string("diff(position, t) = velocity")

# Partial derivatives
eq = Equation.from_string("diff(diff(u, x), y) = 0")

Example 3: Differential Equations

# Simple ODE: dy/dt = -y
eq = Equation.from_string("diff(y, t) = scalar(-1.0, y)")

# Exponential growth: dy/dt = ky
eq = Equation.from_string("diff(y, t) = k * y")

# Harmonic oscillator
eq = Equation.from_string("diff(diff(x, t), t) = scalar(-omega_squared, x)")

# Driven oscillator
eq = Equation.from_string(
    "diff(diff(x, t), t) + 2 * zeta * omega * diff(x, t) + omega_squared * x = F"
)

Example 4: Lambda Calculus

# Identity function
eq = Equation.from_string("apply(abstraction x. x, y) = y")

# Square function
eq = Equation.from_string("apply(abstraction x. x * x, 5) = 25")

# Function composition
eq = Equation.from_string(
    "apply(abstraction f. abstraction g. abstraction x. apply(f, apply(g, x)), f1) = composed"
)

BNF Notation Summary

equation      ::= term "=" term
term          ::= identifier | number | operation | "(" term ")"
operation     ::= arithmetic | integral | derivative | application | abstraction

arithmetic    ::= term operator term
operator      ::= "+" | "-" | "*" | "/" | "^"

integral      ::= "int" "(" term "," identifier ")"
derivative    ::= "diff" "(" term "," identifier ")"

abstraction   ::= "abstraction" identifier "." term
application   ::= "apply" "(" abstraction "," term ")"

identifier    ::= letter (letter | digit | "_")*
number        ::= ("-")? digit+ ("." digit+)?

Error Handling

Common syntax errors:

# Missing equals
"x + y"  # ERROR: No equation

# Invalid identifier
"2x = y"  # ERROR: Identifier can't start with digit

# Mismatched parentheses
"diff(f, x = g"  # ERROR: Missing )

# Invalid operator
"x & y = z"  # ERROR: & not supported

# Empty derivative
"diff(, x) = g"  # ERROR: Missing term

Next Steps