Linear Memory DAE Arena & Lowering
The Differential Algebraic Equations (DAE) representation in ModelScript is implemented via DAEBuilder in @modelscript/runtime (packages/runtime/src/dae/wasm_dae.ts).
Unlike traditional compilers that construct linked expression trees using heap-allocated objects, DAEBuilder operates strictly on flat, contiguous typed arrays (Struct-of-Arrays) in WebAssembly linear memory.
Arena Struct-of-Arrays (SoA) Layout
The arena maintains three primary contiguous arrays:
┌───────────────────────────────────────────────────────────────────┐
│ DAEBuilder Linear Memory │
├─────────────────┬──────────────────┬──────────────────────────────┤
│ Buffer │ Element Size │ Contents │
├─────────────────┼──────────────────┼──────────────────────────────┤
│ varData │ 32 bytes │ Name, type, variability, │
│ │ │ causality, start value, flags│
├─────────────────┼──────────────────┼──────────────────────────────┤
│ exprData │ 16 bytes │ OpKind, data1, leftExprId, │
│ │ │ rightExprId │
├─────────────────┼──────────────────┼──────────────────────────────┤
│ eqData │ 24 bytes │ EqKind, lhsExprId, │
│ │ │ rhsExprId, flags │
└─────────────────┴──────────────────┴──────────────────────────────┘Every variable, expression, and equation is assigned a persistent 32-bit integer handle:
VarId: Handle to a variable invarDataExprId: Handle to an expression node inexprDataEqId: Handle to an equation ineqData
Lowering Pipeline
Flattening a high-level Modelica model into linear DAE form proceeds in two coordinated layers:
Layer 1: Components & Hierarchy
Reads Salsa queries (instantiate, classInstance, variability) to allocate variables and parameters in DAEBuilder:
- Scalar variables (
Real,Integer,Boolean,String) - Array dimensions and indices
- Start values, nominals, and min/max boundaries
Layer 2: Equations & Statements
Walks the linear CST of the class body (db.cstNode(classId)):
- Lowers binary, unary, and call expressions directly into
ExprIdnodes in linear memory. - Emits equality equations (
lhs = rhs), initial equations, and algorithm statements.
Expression Lowering Rules
To match OpenModelica's canonical output, the flattener applies specific normalization rules:
- Real Coercion in Binary Operations: If one operand of an arithmetic operator is
Realand the other isInteger, the integer operand is automatically cast to Real usingcastToRealExpr(). - Negation Distribution: Expressions of the form
-(a * b)are rewritten canonically to(-a) * b. - Binding Literal Kind Matching: When a binding expression is lowered,
addIntLiteral()is used forVarType.IntegerandaddRealLiteral()forVarType.Real(e.g.parameter Real R = 100becomes100.0).
Optimization & Transformation Passes
Once lowered to the arena, equations pass through four high-performance transformations:
- Constant Folding (
foldArenaConstants): Recursively simplifies compile-time constant arithmetic expressions directly in the arena. - Alias Elimination (
eliminateArenaAliases): Detects trivial equality equations () generated by connectors and replaces all references with a single canonical variable handle. - Pantelides Index Reduction: Differentiates high-index algebraic constraints to reduce the DAE index to 1 or 0 for stable numerical integration.
- Tarjan BLT Partitioning: Constructs the bipartite incidence graph between variables and equations, computes maximum matching, and finds Strongly Connected Components (SCC) using Tarjan's algorithm.

