math_spec.degree
Degree — the one admissibility rule that is a scope choice (docs/about/limits.md).
Degree 2 in the math, degree 1 in what stands beside it. An objective and a
constraint both take variable * variable; a bound and a piecewise:
link do not — each of those is read affinely. An expressions: entry is not
degree-checked at declaration at all: the math reading it is checked where it
reads, at that position's own ceiling, and an entry the math never reads
(ExpressionDeclaration.in_math) is held to no degree.
A degree-2 product has a second rule: at most one factor may be a sum of
terms. sum(x, over=i) * sum(y, over=j) is a cross join whose size the
file states nowhere. Factors carrying different dims are not that: x[i] *
y[j] broadcasts.
A divisor's shape is decided here too: a quotient is multiplication by one reciprocal factor, so a divisor that adds is refused at load, where the message can name the rewrite.
calls_dual(node)
#
check_binary(node, context, *, ceiling)
#
Check that node stays inside the degree its position allows.
| PARAMETER | DESCRIPTION |
|---|---|
node
|
The product, quotient or power to judge. |
context
|
What to name in the message — the declaration being read.
TYPE:
|
ceiling
|
The highest degree this position can honour — 2 in an objective or a constraint, 1 everywhere else.
TYPE:
|
| RAISES | DESCRIPTION |
|---|---|
LanguageError
|
A product of two variable-carrying factors where the position allows only degree 1 or where both factors are sums of terms, a power over anything carrying a variable, a divisor carrying a variable or adding. |
Source code in src/math_spec/degree.py
check_expression(node, context, *, ceiling=1)
#
What the math admits at one position: no dual anywhere under node, then :func:check_binary everywhere in it.
Asked of the resolved tree, so a dual or a product reached through a macro or a named expression is caught alongside one written in place. What a plan node can represent is the consumer's question, not this one's.
| RAISES | DESCRIPTION |
|---|---|
LanguageError
|
A dual, which exists only after a solve; or what
:func: |