math_spec.resolution
Name resolution — the pass that makes the core AST fully typed.
Parsers emit unresolved names; this module rewrites each into the typed node its kind asks for, so the AST reaching a consumer holds none. The rules live in the language reference.
DeclarationKind = Literal['variable', 'parameter', 'dimension', 'relation']
module-attribute
#
Namespace(schema)
#
The declared names of one schema, by kind — the whole of what a file may name, read once.
A name has one kind: model.py refuses one declared under two sections.
Source code in src/math_spec/resolution.py
constraints = frozenset(schema.constraints)
instance-attribute
#
dimensions = frozenset(schema.dimensions)
instance-attribute
#
dtypes = {**{p: pd.dtype for p, pd in schema.parameters.items()}, **{d: dd.dtype for d, dd in schema.dimensions.items()}}
instance-attribute
#
leaf_dims = {**{p: tuple(pd.dims) for p, pd in schema.parameters.items()}, **{v: tuple(vd.dims) for v, vd in schema.variables.items()}}
instance-attribute
#
parameters = frozenset(schema.parameters)
instance-attribute
#
relations = {n: RelationDeclaration(lk.pairs, lk.key_roles) for n, lk in schema.relations.items()}
instance-attribute
#
schema = schema
instance-attribute
#
variables = frozenset(schema.variables)
instance-attribute
#
kind(name)
#
What name was declared as, or None where the file declares it nowhere.
Source code in src/math_spec/resolution.py
unknown(name, context, *, allow_dims, formals=())
#
The refusal for a name declared nowhere, listing what it could have been.
| PARAMETER | DESCRIPTION |
|---|---|
name
|
The name the file wrote.
TYPE:
|
context
|
The declaration it was found in.
TYPE:
|
allow_dims
|
Whether a dimension would have been accepted there. It marks a where string, which reads a relation as readily as a parameter, so the listing carries the relations too; an expression, where a relation is not a value, lists the variables instead.
TYPE:
|
formals
|
A macro's formals, listed first when there are any. |
Source code in src/math_spec/resolution.py
unknown_constraint(name, context, *, formals=())
#
The refusal for a dual(name) naming no constraint — nor, inside a template, a formal.
Source code in src/math_spec/resolution.py
Resolved(expressions, variables, constraints, objective, relations, assumptions, piecewise)
dataclass
#
Every expression and where string of one schema, typed once at load.
:func:~math_spec.validation.validate_expressions builds it, and every
reader after — the dim rules, lowering, the typesetter — walks these trees
rather than parsing, expanding and resolving the text again. Each mapping
is keyed as the schema's own section is. A where the file did not
write, or one every row passes, is None.
| ATTRIBUTE | DESCRIPTION |
|---|---|
expressions |
Each |
variables |
Each variable's |
constraints |
Each constraint's comparison and
TYPE:
|
objective |
The objective's expression,
TYPE:
|
relations |
Each relation's columns and key, as declared — the one
copy, which every :class:
TYPE:
|
assumptions |
Each
TYPE:
|
piecewise |
Each |
assumptions
instance-attribute
#
constraints
instance-attribute
#
expressions
instance-attribute
#
objective
instance-attribute
#
piecewise
instance-attribute
#
read_by_the_math
cached
property
#
The named expressions the math reads: every entry the objective, a constraint or a curve reaches, transitively.
Read off those three positions alone: a bound and a where name no
entry. The rest of the expressions: section is read back after a
solve and never fed to one
(:attr:~math_spec.program.ExpressionDeclaration.in_math). A curve
counts because it states rows, so the answer does not move when the
curve is written out (:meth:~math_spec.model.Spec.expand).
relations
instance-attribute
#
variables
instance-attribute
#
ResolvedAssumption
#
Bases: NamedTuple
One assumption's typed halves: the predicate it states, and the mask it is checked under.
description is the sentence a refusal quotes where one was written or
a method implied one, and None where the name is the whole of what a
reader is told.
ResolvedConstraint
#
Bases: NamedTuple
One constraint's typed halves: the comparison it states, and the mask it holds under.
mask_of(node)
#
The mask a declaration carries for a resolved where: None where there is none, or where every row passes.
Source code in src/math_spec/resolution.py
names_in(value)
#
The names a relation kwarg carries: one bare, several bracketed, none otherwise.
Source code in src/math_spec/resolution.py
resolve_expression(node, ns, context, errors, *, formals=frozenset())
#
Rewrite every NameNode under node to a typed node, checking operator call shapes on the way.
A name in formals stays bare, so a macro template is checked by the rules a call site is, before anything calls it.
| RETURNS | DESCRIPTION |
|---|---|
ParsedNode | None
|
The typed tree, or |
ParsedNode | None
|
errors rather than raising, so a caller collecting problems across a |
ParsedNode | None
|
whole schema reports them together. |
Source code in src/math_spec/resolution.py
resolve_where(node, ns, context, errors, self_variable=None)
#
Rewrite a parsed where AST into typed predicates, folded as :class:~math_spec.program.Mask folds.
| RETURNS | DESCRIPTION |
|---|---|
Predicate | None
|
The typed tree — a mask admitting every row or none comes back as the |
Predicate | None
|
one |
Predicate | None
|
problems appended to errors. |
Source code in src/math_spec/resolution.py
resolve_where_text(text, ns, context, errors, self_variable=None)
#
Parse and resolve one where string as :func:resolve_where does, a parse failure appended to errors.
| RETURNS | DESCRIPTION |
|---|---|
Predicate | None
|
|