E-MD0003 — Nested comparison in a constraint
Error Type |
|
|---|---|
Phase |
building the model (adding a constraint) |
Python exception |
|
Message
Nested comparisons are not supported in constraints yet.
A constraint must be a single `<=`, `>=`, or `==` comparison.
Cause
The constraint expression is an element-wise comparison which is itself another non-scalar comparison — that is, a comparison over a container whose elements are themselves containers. For example, comparing the rows of a jagged array against a scalar:
a = problem.Float("x", shape=(N, M))
b = problem.Float("y", shape=M)
problem.Constraint("c", a.rows() <= b) # E-MD0003!
Note that two superficially similar forms do not produce this error: a Python chained comparison such as a <= x <= b is rejected before the constraint is built, because Python evaluates it via bool() on the intermediate comparison and JijModeling expressions raise a plain TypeError from __bool__; and an explicitly nested comparison such as (x <= 1) == (y <= 1) is rejected earlier by the type checker with E-TE0015.
Fix
Constrain each row or element individually via an indexed constraint family instead of comparing the nested container directly. With the decorated API (@problem.update), iterate over the rows and their elements with a generator comprehension:
@problem.update
def _(problem: jm.DecoratedProblem):
a = problem.Float("x", shape=(N, M))
b = problem.Float("y", shape=M)
problem.Constraint("c", [a_row <= b for a_row in a.rows()])