math_spec.boundedness
Provably unbounded models, named by check instead of by the solver.
A variable that is unbounded on the side its objective term improves toward
and appears in no constraint runs to infinity for any data at all — nothing
in the model can stop it. A solver answers that with a bare unbounded,
naming nothing; check says it with the variable, the side and the reason
(#229).
Advice rather than a refusal, because the same shape is what a half-written
model looks like — a variable declared before the constraint that will hold it
— and no door should close on one. Which means these notes reach a caller who
runs check, and nobody else: straight to solve and the solver's answer
is still the first word.
The rule is a conjunction and needs both halves. A variable unbounded on the
improving side but constrained somewhere is ordinary — the constraint is what
bounds it, and "every variable must be defined by a constraint" would reject
most working models. A variable in no constraint but bounded on the improving
side is ordinary too; its own bounds: are what bound it.
Which side improves is read off the sign the variable enters the objective
with, not off the sense alone: under minimize a +v term runs down
toward lower and a -v term runs up toward upper. Where that sign is
not decidable without data — a parameter coefficient, which may be zero, or
occurrences of both signs, which may cancel — nothing is claimed. A false
note here would read as a defect in a model that solves, which is worse than
saying nothing.
Only the whole-variable case is decidable here. A variable whose slice gets no constraint row, because the mask that would have defined it is false in this data, is the same finding one step later, and the row tables at the end of a build are what would answer it.
Sign = Literal['+', '-'] | None
module-attribute
#
unbounded_notes(schema)
#
Name every variable the objective can drive to infinity unopposed.
Takes an expanded schema: a piecewise: block holds the variables it
names, and does so through the constraints it expands into.
| RETURNS | DESCRIPTION |
|---|---|
list[str]
|
One note per variable that is unbounded on the side its objective term |
list[str]
|
improves toward and named by no constraint — what |
list[str]
|
empty for a model this cannot prove anything about. |