Skip to content

Nonlinear: change how constraints are parsed #1817

Closed
@odow

Description

@odow

To minimize differences when refactoring, we kept the same parsing behavior as JuMP. That means, constraints like x^2 <= 1 get parsed into x^2 - 1 <= 0.0:

function _expr_to_constraint(expr::Expr)
if isexpr(expr, :comparison)
@assert expr.args[2] == expr.args[4]
@assert expr.args[2] in (:<=, :>=)
lhs, body, rhs =
_normalize_constraint_expr(expr.args[1], expr.args[3], expr.args[5])
return body, MOI.Interval(lhs, rhs)
end
lhs, rhs = _normalize_constraint_expr(expr.args[2], expr.args[3])
if expr.args[1] == :<=
return :($lhs - $rhs), MOI.LessThan(0.0)
elseif expr.args[1] == :>=
return :($lhs - $rhs), MOI.GreaterThan(0.0)
else
@assert expr.args[1] == :(==)
return :($lhs - $rhs), MOI.EqualTo(0.0)
end
end

Changing this behavior would lead to more informative RHSs being passed to the solvers, and remove an additional operation. However, doing so would break JuMP's tests and printing, which have things like this:

model = Nonlinear.Model()
x = MOI.VariableIndex(1)
input = :($x^2 + 1 <= 1.0)
c = Nonlinear.add_constraint(model, input)
@test model[c].set == MOI.LessThan(0.0)
evaluator = Nonlinear.Evaluator(model)
MOI.initialize(evaluator, [:ExprGraph])
@test MOI.constraint_expr(evaluator, 1) == :((x[$x]^2 + 1) - 1.0 <= 0.0)

As suggested by @blegat #1804 (comment), one option is to remove the ability to specify constraints as a <= b, and instead force add_constraint(model, f, set), and then make JuMP keep the existing behavior.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions