math_spec.resolution
Name resolution — the pass that reads the syntax tree into the program vocabulary.
The grammars emit bare names and calls; this module builds the
:mod:math_spec.program node each stands for, so every pass after — the dim
rules, the degree rules, the typesetter, lowering — reads one vocabulary. 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
named(name, context)
#
The expressions: entry name as the node that stands where its name is written.
Resolved under the entry's own context the first time it is asked for, and read from then on, so a fault in it is reported once.
| RAISES | DESCRIPTION |
|---|---|
SchemaError
|
The entry reads itself, or does not load. |
Source code in src/math_spec/resolution.py
named_entry(name)
#
The expressions: entry name resolved, or None, with every refusal it earned.
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, in the program's own vocabulary.
: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. What a program does not carry
is here alone: every use of an expressions: entry stands as the
:class:~math_spec.program.Named node resolution built for it, which
lowering inlines.
| ATTRIBUTE | DESCRIPTION |
|---|---|
expressions |
Each |
variables |
Each variable's |
constraints |
Each constraint, as a program declares it.
TYPE:
|
objective |
The objective,
TYPE:
|
relations |
Each relation's columns and key, as declared — the one
copy, which every :class:
TYPE:
|
assumptions |
Each
TYPE:
|
piecewise |
Each
TYPE:
|
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
#
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
remainder(masks)
#
The region left over: where not one of masks holds.
The otherwise arm's own mask, built rather than written. cases:
carries at least one case, so there is no vacuous truth to spell.
Source code in src/math_spec/resolution.py
resolve_constraint_text(text, ns, context, errors)
#
Parse, expand, resolve and degree-check one constraint string: exactly one comparison, a variable on a side (#1171).
| RETURNS | DESCRIPTION |
|---|---|
tuple[Expression, ComparisonOperator, Expression] | None
|
The two sides and the sense between them, or |
tuple[Expression, ComparisonOperator, Expression] | None
|
failed, the problem appended to errors. |
Source code in src/math_spec/resolution.py
resolve_expression(node, ns, context, errors, *, formals=frozenset())
#
Build the program tree node stands for, checking every name and operator call shape on the way.
| RETURNS | DESCRIPTION |
|---|---|
Expression | None
|
The tree, or |
Expression | None
|
rather than raising, so a caller collecting problems across a whole |
Expression | None
|
schema reports them together. Also |
Expression | None
|
where a name in formals stands under node: a macro template is |
Expression | None
|
checked by the rules a call site is before anything calls it, and |
Expression | None
|
only the call site that binds its formals has a tree to build. |
Source code in src/math_spec/resolution.py
resolve_expression_text(text, ns, context, errors, *, ceiling)
#
Parse, expand, resolve and degree-check one expression string that stands for a value.
ceiling is the degree the position honours, and None for an
expressions: entry's body: what the math admits
(:func:~math_spec.degree.check_expression) is a rule about the position
that reads it, so it fires on the expanded tree of every objective and
piecewise link, and not where an entry is declared. A constraint is
:func:resolve_constraint_text's.
| RETURNS | DESCRIPTION |
|---|---|
Expression | None
|
The typed tree, or |
Expression | None
|
to errors. |
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
|
|