Constraints handling in JuMP/MOI


Hello all

I’ve been looking at the code of the new JuMP with MOI, and I would like to understand how to update the things that are going to break in my code. In particular, I have been doing the following things

  • Inspect a linear constraint breaking it down using constr.terms and constr.terms
  • Interrogating variables in constraints to identify where they come from constr.terms.vars[1].m
  • loading and saving a solution from a JLD file by simply setting or storing the value of m.colVal

I see that the new JuMP model object has less elements than the previous one. This gives less access to info to develop advanced algorithms that are solver-independent. Could you help me understand how things like the ones I listed are going to be done in the future?.




Great! This is a good time to start doing so unless you need NLP (that’s in progress). Please don’t hesitate to file issues. Documentation on the JuMP side is missing, but should be okay at the MOI level. It’s not unlikely that the JuMP API will go through a big renaming once it’s more stabilized.

The lack of context might suggest this, but it’s actually the opposite case. The JuMP/MOI model is designed to be more transparent in how it stores data. There are no more ad-hoc, undocumented arrays for storing different types of constraints. Everything except nonlinear objects is stored directly in the moibackend field which has a well-defined (and mostly documented) interface for accessing any property you might want. There are currently some JuMP-level wrappers for accessing these, but you can also query them directly.

See and

Variables still have the same m field. However, the current JuMP/MOI model by default doesn’t support constraints containing variables that belong to different models.

The good news is that we now have the infrastructure in place to handle solutions objects (i.e., a solver returning more than one solution, creating a solution and checking its feasibility, separating the result solution from the starting point etc.), but that’s not really hooked up yet. colVal (I’m cringing at the name) was never a public interface. The new way to do this is to create an array of all the variables in the model and ask for its resultvalue. You can do this with the ListOfVariableIndices attribute which returns MOI variable indices. You construct a JuMP variable from a model and a MOI variable index. It would be a reasonable feature request to ask for a JuMP-level API for this.



Thank you for the clarifications. I read the MOI documentation and now I am less scared of it. About the constraints with variables with different models. I am currently developing on top of Plasmo (J.Jalving, U Wisc), which defines a graph of models with linking constraints, those have variables from different models.

From what I read in MOI, to do advanced things the user would have to play a lot with m.moibackend.instance, is this the intention or are you planning to bring more power to the JuMP layer?.

Also, at some point you mentioned things like indicator constraints (which I’m interested in) will be easier with MOI. Do you have an idea on how would that be?. Indicator constraints take 3 arguments: a binary variable, a value (0 or 1), and a linear constraint. As in y = 1 => 2x <= 5, which MOI function would be used to generate something like that?.

Finally, where is the right place to ask these kind of questions or to request no features. I have a long shopping list of things I would like to see in JuMP. For example, I was thinking about writing a solution object with Excel export.

best regards



You should never need to touch m.moibackend.instance, that’s an implementation detail that could change if InstanceManager changes. At the moment you may need to deal with m.moibackend, but the intention is for everything to have a nice JuMP-level wrapper. Open an issue on JuMP whenever you find a need to interact with m.moibackend directly. Definitely open an issue at MathOptInterfaceUtilities if you find a need to touch m.moibackend.instance.

Define IndicatorSet(param::Bool) to be the 2-dimensional set \mathcal{I}_{param} = \{ (x,y) : x = param, y \le 0 \} \cup \{ (x,y) : x = 1 - param, y \in \mathbb{R} \}. Then (x, 2y - 5) \in \mathcal{I}_1 means that x = 1 implies 2y \le 5. The expression (x, 2y-5) is representable as a VectorAffineFunction where the solver can throw an error if the first output component isn’t a single variable.

Discourse or the gitter channel are appropriate for these kinds of questions. You can open issues on JuMP to discuss new potential features.