Overview
Constants and Lookup Tables are how you separate a model’s parameters from its logic. Instead of hardcoding values inside expressions, you name them, store them in one place, and reference them from anywhere. Change the named value once, and every expression that references it updates automatically. This matters for three reasons:- Tuning — adjust model parameters without hunting through expressions. Change
BASE_PROCESSING_TIMEfrom 60 to 75 and every relevant component follows. - Readability —
shift_efficiency_factoris easier to understand than0.87sprinkled across expressions. - Non-technical access — operators and analysts who shouldn’t modify expressions can still tune the model by changing constant values.
Constants
A Constant is a named value with a specific type:number, string, or boolean. Each constant has:
- Name — how expressions reference it (e.g.,
BASE_CYCLE_TIME) - Description — what it represents and what units
- Type —
number,string, orboolean - Value — the actual data
When to Use a Constant
- Any value that appears in multiple places. If you find yourself typing
0.87in several expressions, extract it to a constant. - Any value you might want to change between runs or sweep in an experiment. Constants are first-class parameters that experiments can vary systematically.
- Any value a non-technical stakeholder might need to adjust. Analysts can tune a constant without knowing the expression language.
Managing Constants
Constants are defined in the Library of the Data section, alongside Entities and Lookup Tables. Add, edit, or delete constants there — changes propagate to every model that references them.Lookup Tables
A Lookup Table is a named key-value table. Query it withLOOKUP(table_name, key) in any expression:
LOOKUP returns a type-specific zero (0 for numeric, "" for text, FALSE for boolean) — see Multi-Dimensional Lookups below for details and the default:= override.
When to Use a Lookup Table
- Values that vary by a categorical attribute. Processing time by product type, yield rate by material, priority weight by customer tier — all natural lookups.
- Routing and proportional splits. Different entities route differently; store the routing rules in a table rather than deeply nested
IFexpressions. - Data-driven configuration. When the “configuration” of a model is really a set of numbers tied to categories, a lookup table is clearer than encoding the same information across many fields.
Multi-Dimensional Lookups
Lookup tables are multi-dimensional by default — a table can have multiple key columns, and a lookup specifies a value for each. This is how you represent data that varies across two or more axes at once, like “processing time by (product type, station)” or “yield rate by (shift, material class).”0 for a numeric-valued table, "" for a text-valued table, FALSE for a boolean-valued table. (LOOKUP doesn’t return null.)
Fallback with default:=. Use the default:= keyword argument to specify what to return on no match, instead of the type-specific zero:
default:= keyword argument handles fallbacks directly — no need to wrap the lookup in an IF(). This is the cleanest way to express “the typical value for this attribute, with a sensible fallback when the combination isn’t in the table.”
Partial matches. Always provide one argument per key column — no wildcards, no partial matches. A three-column table queried with two keys is an invalid call and the lookup falls through to the default (or the type-specific zero if no default is provided).
Constants vs. Lookup Tables — Which to Use?
- Single value used in many places → Constant
- Value that depends on a categorical attribute (type, class, tier) → Lookup Table
- Needs to be swept in an experiment → Constant (experiments treat constants as parameter axes)
- Large reference dataset → Lookup Table

