E-MD0003 — Nested comparison in a constraint

Error Type

Modeling Error

Phase

building the model (adding a constraint)

Python exception

jijmodeling.ModelingError

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()])