Expression Schema
The canonical JSON Schema for the Modellus expression language — the LaTeX-based mathematical notation used inside Expression shapes. Covers statement types, operator precedence, built-in functions, and AST node definitions.
Overview
The expression field of each ExpressionShape stores a \displaylines{} LaTeX block. Lines are separated by \\. Each line is parsed as one statement by the LatexMath grammar.
Statement Types
| Kind | Pattern | Term Type Produced |
|---|---|---|
differential | \frac{dx}{dt} = expr | DIFFERENTIAL — requires initial value |
function | name = expr | PARAMETER (constant RHS) or FUNCTION (depends on other terms) |
functionSubscript | x_{n} = f(x_{n-1}) | RECURRENCE — discrete-time iteration |
functionSubscriptDigit | x_0 = value | PARAMETER — initial/reference value |
functionIndependent | f(t) = expr | FUNCTION — explicit argument form |
conditional | name = \begin{cases}...\end{cases} | FUNCTION — piecewise definition (≥ 2 rows) |
domain | x \in {1,2,3} | PARAMETER — a scalar restricted to the listed values |
namedDomain | \text{domain} Color = {\text{red},\text{green}} | None — a declaration, never a term |
display | expr (no assignment) | None — visual display only |
Expression Nodes (AST)
The right-hand side of any statement is a MathExpr — a tree of these node types:
| Node | Description | Example LaTeX |
|---|---|---|
| BinaryOp | Two operands with operator (+, -, ·, /) | a + b |
| UnaryMinus | Negation prefix | -x |
| Power | Exponentiation | x^{2} |
| Fraction | Division as \frac{}{} | \frac{a}{b} |
| Sqrt | Square root | \sqrt{x} |
| FunctionCall | Built-in function application | \sin\left(x\right) |
| Comparison | Relational operator | x > 0 |
| Logical | \lor or \land | a \lor b |
| TermReference | Reference to a named term | v, \omega |
| NumberLiteral | Numeric constant | 9.8 |
| Constant | \pi or e | \pi |
| Delta | Finite difference operator | \Delta x |
| SubscriptRef | Subscript term access | x_{n-1} |
| Absolute | Absolute value bars | |x| |
| EnumLiteral | Categorical value of a declared domain; compares only | \text{red} |
Built-in Functions
| Category | Functions |
|---|---|
| Trigonometric | \sin, \cos, \tan, \cot, \sec, \csc |
| Inverse Trig | \arcsin, \arccos, \arctan |
| Hyperbolic | \sinh, \cosh, \tanh |
| Logarithmic | \ln, \log |
| Two-argument | \max(a,b), \min(a,b), \mod(a,b) |
| Utility | sign(x), rnd(x), irnd(x), int(x), round(x) — written with no backslash, and drawn upright: the editor writes them back as \mathrm{round}\left(x\right), which reads the same as the plain spelling |
| Other | \det(x), \sqrt{x} |
Operators & Precedence
| Precedence | Operators | Associativity |
|---|---|---|
| 1 (lowest) | \lor, \land | Left |
| 2 | =, >, <, \ge, \le, \neq | Left |
| 3 | +, - | Left |
| 4 | \cdot, /, implicit multiplication | Left |
| 5 (highest) | ^{}, ! (factorial), \sqrt{} | Right |
Factorial: Use postfix notation (n!). Factorial is intended for non-negative integer values.
Integral notation: LaTeX integral forms such as \int_{a}^{b} f\left(x\right)\,\mathrm{d}x are valid expression syntax. For integer-part behavior, use int(x).
Domains
A domain says which values a scalar term may take. x \in {1,2,3} leaves x a single selectable number: it does not make x a set, and it is not a true/false membership test. Constrain a term with \in; the = form means the same thing but is only read as a domain when the right-hand side is something no ordinary expression could be, so x={1} and x=Color stay assignments.
| Written | Means |
|---|---|
{1, 2, 3} | Finite domain — exactly the values 1, 2 and 3 |
[1, 5] | Continuous interval — every real value from 1 to 5 |
[1..5] | Discrete inclusive range — {1, 2, 3, 4, 5} |
[0..10..2] | Discrete range with a step — {0, 2, 4, 6, 8, 10} |
A \cup B | Union — a value belonging to A or to B |
x \in D | Constrains the scalar term x to the domain D |
A comma between two bounds is a continuous interval and two dots are a discrete range, so [1,5] and [1..5] are different domains. A range is inclusive at both ends when the step reaches the endpoint: [0..10..3] is {0, 3, 6, 9}.
Every delimiter is read in four spellings — plain, sized, named and sized named — because the editor keeps whichever one was typed: \{ \}, \left\{ \right\}, \lbrace \rbrace, \left\lbrace \right\rbrace for braces, and likewise \lbrack \rbrack and \lparen \rparen for brackets and parentheses. Write the plain form; the others are accepted so a row keeps working whichever way it was written.
The principal example. x \in {1,2,3} \cup [6,7] — x may equal 1, 2 or 3, or any real value in the closed interval from 6 to 7. Nothing between 3 and 6 is allowed.
At the top level of a domain a comma is a union operator too, so x = {1},{2},{3},[6..7] normalizes to x \in {1,2,3,6,7}. Commas inside a set, inside an interval and inside a function call keep their own meaning, so \max\left(a,b\right) is unaffected.
Categorical domains
Write categorical values as \text{red}, both where the domain is declared and where it is compared:
color \in {\text{red},\text{green},\text{blue}}
is\_red = \begin{cases}1 & color=\text{red}\\0 & \text{otherwise}\end{cases}
These values are enum literals, not references to terms called red or green, and they never appear in the term list. They compare with = and \neq and combine with \land, \lor and \lnot. Arithmetic on one is refused with a type diagnostic rather than treated as a number, and a value belonging to no declared domain is refused rather than read as a term.
Built-in domains
| Written | Means |
|---|---|
\mathbb{R} | Every finite real value the engine can represent |
\mathbb{Z} | Integers, of either sign |
\mathbb{N} | Non-negative integers, zero included |
\mathbb{B} | {false, true}, stored as 0 and 1 |
\mathbb{Q} | Accepted, but behaves exactly like \mathbb{R}: values are floating-point numbers, so exact rational membership cannot be decided |
Named domains
\text{domain} Color = {\text{red},\text{green},\text{blue}}
foreground \in Color
background \in Color
The keyword is the word domain, written \text{domain} so the editor draws it upright. A named domain is a declaration, never a calculation term: it never appears in the term list, in the value rows or on a plot. It resolves globally, works inside a union, and may not be defined in terms of itself.
Choosing a value at random
Assigned to a constrained term, rnd reads its argument as a count of domain values rather than as an upper bound:
z \in {\text{green},\text{blue},\text{red}}
z = rnd\left(3\right)
z becomes one of the three labels, each equally likely; rnd\left(2\right) would only ever choose green or blue, because the argument counts from the start of the domain in declared order. This is the only way to pick a categorical value at random — the numbers the labels are stored as are internal and must never be written into a model. It works the same for a numeric domain: n \in [0..10..2] with n = rnd\left(6\right) picks one of 0, 2, 4, 6, 8, 10.
Everywhere else rnd keeps its usual meaning, a number between 0 and its argument: when the term has no domain, when the domain is infinite, and when rnd is only part of the assigned expression as in m = n + rnd\left(3\right). irnd is unchanged.
Initial values and enforcement
A constrained term starts on an explicitly supplied initial value when the domain accepts it, otherwise on the first value of a finite domain, the start of a range, the lower bound of an interval, 0 for the numeric built-ins and false for \mathbb{B}. Values are never clamped or rounded: an update outside the domain is refused and a computed term that leaves its domain becomes undefined for that step, each with a DOMAIN_VIOLATION diagnostic naming the term, the rejected value and the domain.
A term constrained to a set of labels is edited by its labels everywhere the user meets it: the scenarios table and the table of values show green rather than the number behind it, and a cell is changed by choosing from the list of the domain's values instead of by typing.
LaTeX Templates
The schema includes a latexTemplates section providing ready-to-use LaTeX strings for common patterns that agents can emit directly into expression fields.
Name Tokens
Term names follow two patterns:
- ID — alphanumeric identifiers:
x,v0,mass,kB - SPECIAL — Greek letters and symbols:
\omega,\alpha,\beta,\theta,\lambda