# Constraints

DRAFT: Describe how constraints are represented (link to MOI docs). Constraints are very similar to variables in (1) how names work (2) how attributes work, and (3) the macro syntax for constructing them. They're a bit different because they're parameterized by function-set type. Describe constraints vs. `ConstraintRefs`

. Describe `JuMP.constraint_object`

. How to delete constraints. How to modify constraints by setting attributes and `MOI.modifyconstraint!`

. Describe semidefinite constraints and symmetry handling. Refer to NLP docs for nonlinear constraints.

`JuMP.@constraint`

— Macro.`@constraint(m::Model, expr)`

Add a constraint described by the expression `expr`

.

`@constraint(m::Model, ref[i=..., j=..., ...], expr)`

Add a group of constraints described by the expression `expr`

parametrized by `i`

, `j`

, ...

The expression `expr`

can either be

- of the form
`func in set`

constraining the function`func`

to belong to the set`set`

, e.g.`@constraint(m, [1, x-1, y-2] in MOI.SecondOrderCone(3))`

constrains the norm of`[x-1, y-2]`

be less than 1; - of the form
`a sign b`

, where`sign`

is one of`==`

,`≥`

,`>=`

,`≤`

and`<=`

building the single constraint enforcing the comparison to hold for the expression`a`

and`b`

, e.g.`@constraint(m, x^2 + y^2 == 1)`

constrains`x`

and`y`

to lie on the unit circle; - of the form
`a ≤ b ≤ c`

or`a ≥ b ≥ c`

(where`≤`

and`<=`

(resp.`≥`

and`>=`

) can be used interchangeably) constraining the paired the expression`b`

to lie between`a`

and`c`

; - of the forms
`@constraint(m, a .sign b)`

or`@constraint(m, a .sign b .sign c)`

which broadcast the constraint creation to each element of the vectors.

**Note for extending the constraint macro**

Each constraint will be created using `add_constraint(m, build_constraint(_error, func, set))`

where

`_error`

is an error function showing the constraint call in addition to the error message given as argument,`func`

is the expression that is constrained- and
`set`

is the set in which it is constrained to belong.

For `expr`

of the first type (i.e. `@constraint(m, func in set)`

), `func`

and `set`

are passed unchanged to `build_constraint`

but for the other types, they are determined from the expressions and signs. For instance, `@constraint(m, x^2 + y^2 == 1)`

is transformed into `add_constraint(m, build_constraint(_error, x^2 + y^2, MOI.EqualTo(1.0)))`

.

To extend JuMP to accept new constraints of this form, it is necessary to add the corresponding methods to `build_constraint`

. Note that this will likely mean that either `func`

or `set`

will be some custom type, rather than e.g. a `Symbol`

, since we will likely want to dispatch on the type of the function or set appearing in the constraint.

`JuMP.@SDconstraint`

— Macro.`@SDconstraint(m::Model, expr)`

Add a semidefinite constraint described by the expression `expr`

.

`@SDconstraint(m::Model, ref[i=..., j=..., ...], expr)`

Add a group of semidefinite constraints described by the expression `expr`

parametrized by `i`

, `j`

, ...

The expression `expr`

needs to be of the form `a sign b`

where `sign`

is `⪰`

, `≥`

, `>=`

, `⪯`

, `≤`

or `<=`

and `a`

and `b`

are `square`

matrices. It constrains that `a - b`

(or `b - a`

if the sign is `⪯`

, `≤`

or `<=`

) is positive semidefinite.