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:
- Arithmetic operations
- Integration and differentiation
- Lambda calculus (abstraction and application)
- Identifiers and numbers
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:
^(exponentiation) - highest*,/(multiplication, division)+,-(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
- Variable: Second argument is the integration variable
- Notation: Both
∫ f d xandint(f, x)are equivalent - Recommended: Use
int(f, x)for better tool support
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
- Variable: Second argument is the differentiation variable
- Notation: Both
d/d x (f)anddiff(f, x)are equivalent - Recommended: Use
diff(f, x)for clarity
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
- Syntax:
λ var. bodyorabstraction var. body - Variable: Identifier after λ/abstraction
- Body: Expression that can reference the variable
- Recommended: Use
abstractionfor better tool support
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
- Syntax:
f @ xorapply(f, x) - Function: Must be an abstraction
- Argument: Can be identifier, number, or term
- Recommended: Use
apply(f, x)for clarity
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
- Start: Must begin with letter (a-z, A-Z)
- Continue: Can contain letters, numbers, underscores
- Case sensitive:
xandXare different - No keywords: All identifiers are treated equally
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
- Integers: Sequence of digits
- Decimals: Optional decimal point and fractional part
- Negative: Optional leading minus sign
- No scientific notation: Write out full number
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
- Start: Hash symbol
# - Extent: To end of line
- Ignored: Comments are stripped during parsing
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
- Circuit Grammar - Circuit syntax specification
- Operations - Operation reference
- Equations Concepts - Using equations