math_spec.validation
Load-time validation of expression and where strings.
Every expression and where string is parsed, expanded and resolved before any backend runs, so typos and malformed math fail at load time with the offending component named — not mid-build, and not differently in each lane.
Resolution is the substance (resolution.py): this module walks the schema
and hands each string to the same pass the backends use, collecting every
problem rather than raising on the first. Name checking is not a separate
implementation of name resolution; that duplication is what let the two lanes
disagree about scoping.
Macro templates are the one thing checked without being resolved, their free names including formals. They are name-checked against the schema plus their own formals, so an unused macro still fails at load time.
load_model(model)
#
Load and validate a model definition — the language's front door.
Everything decidable without data is decided here: schema shape, every expression and where string, every macro template, and every declaration a formulation emits.
| PARAMETER | DESCRIPTION |
|---|---|
model
|
A YAML path, a mapping, or a loaded :class: |
| RETURNS | DESCRIPTION |
|---|---|
Model
|
The schema as the file declares it, |
| RAISES | DESCRIPTION |
|---|---|
LanguageError
|
Anything the language does not accept. |
Source code in src/math_spec/validation.py
validate_expressions(schema)
#
Validate and resolve every expression and where string in schema.
What is checked:
- the expression parses, and constraints hold exactly one comparison where objectives hold none;
- every referenced name resolves, and every operator is a built-in whose dimension arguments name declared dimensions;
- where strings parse and resolve — an unknown name there is an error, not a silently-empty mask;
- macro formals may shadow model names but not a declared dimension, since
over=snapshotunder a formalsnapshotcannot say which it means; - every dim rule (
dimensions.check_schema), once names resolve.
Dim rules run here rather than at either entry point because they are language rules: every lane arrives through this function, and one that could skip them would be a lane with a different language (hard rule 3).
| RAISES | DESCRIPTION |
|---|---|
SchemaError
|
Listing every problem found, one per line. |