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(variables, parameters, dimensions, relations, dtypes, leaf_dims, constraints)
#
The declared names of one schema, by kind.
A name has one kind: model.py refuses one declared under two sections.
Source code in src/math_spec/resolution.py
constraints = frozenset(constraints)
instance-attribute
#
dimensions = frozenset(dimensions)
instance-attribute
#
dtypes = dict(dtypes)
instance-attribute
#
leaf_dims = dict(leaf_dims)
instance-attribute
#
parameters = frozenset(parameters)
instance-attribute
#
relations = dict(relations)
instance-attribute
#
variables = frozenset(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
of(schema)
classmethod
#
Build the namespace of schema, the whole of what a file may name.
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)
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:
|
constraints
instance-attribute
#
expressions
instance-attribute
#
objective
instance-attribute
#
read_by_the_math
cached
property
#
The named expressions the math reads: every entry the objective or a constraint reaches, transitively.
Read off those two positions alone: a bound and a where name no
entry, and a piecewise link's expression reaches here through the
constraints its expansion emitted. The rest of the expressions:
section is read back after a solve and never fed to one
(:attr:~math_spec.program.ExpressionDeclaration.in_math).
relations
instance-attribute
#
variables
instance-attribute
#
ResolvedConstraint
#
Bases: NamedTuple
One constraint's typed halves: the comparison it states, and the mask it holds under.
expression_of(text, schema, ns, context)
#
Parse, expand and resolve text in one call, raising rather than collecting.
A declaration's tree is on :class:Resolved; this is for a text that is
not one.
| RAISES | DESCRIPTION |
|---|---|
LanguageError
|
Listing every problem the text has. |
Source code in src/math_spec/resolution.py
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)
#
Rewrite every NameNode under node to a typed node, checking operator call shapes on the way.
| 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
|
|
Source code in src/math_spec/resolution.py
where_of(text, ns, context, self_variable=None)
#
Parse and resolve a where string into the :class:~math_spec.program.Mask a declaration carries.
None for no mask, however the file spelled it: a mask that admits every
row is dropped, and one that admits none arrives as a mask over
BooleanLiteral(False).
| RAISES | DESCRIPTION |
|---|---|
LanguageError
|
Listing every problem the predicate has. |