hdavid16 / DisjunctiveProgramming.jl

A JuMP extension for Generalized Disjunctive Programming
MIT License
27 stars 3 forks source link

Update code to access a Nonlinear constraint name when supported by JuMP #51

Closed hdavid16 closed 1 year ago

hdavid16 commented 1 year ago

The following trick is done to get the names of nonlinear constraints (which requires accessing the object dictionary to find the constraint). This is done because name is not supported for Nonlinear constraints (https://github.com/jump-dev/JuMP.jl/issues/3069)

https://github.com/hdavid16/DisjunctiveProgramming.jl/blob/dcab5d6ed6dcca1a3b0911430c8b0eb3cdfa1084/src/utils.jl#L73-L80

The object dictionary is currently stored so that any deletions of Nonlinear constraints do not break the object dictionary: https://github.com/hdavid16/DisjunctiveProgramming.jl/blob/dcab5d6ed6dcca1a3b0911430c8b0eb3cdfa1084/src/reformulate.jl#L16

odow commented 1 year ago

I'm a bit confused by all of this. I think I need to take a look. You certainly shouldn't have something like @expression(m, original_object_dict, object_dictionary(m)).

It's the equivalent of

d = object_dictionary(m)
d[:original_object_dict] = d

Why does deleting the nonlinear constraint break the dictionary?

odow commented 1 year ago

At a guess, without looking too deeply, you're probably storing things in the object dictionary, instead of using anonymous syntax and storing references in the extension dictionary: https://jump.dev/JuMP.jl/stable/developers/extensions/#The-extension-dictionary

For example, if it make sense, you could do

m.ext[:original_object_dict] = copy(object_dictionary(m))
hdavid16 commented 1 year ago

Yes! Thanks for pointing me to the extension dictionary. I'll use that instead.

When I delete constraints and don't unregister them, then I cannot call object_dictionary(model), which is why I'm storing the original dictionary.

odow commented 1 year ago

When I delete constraints

Are you deleting constraints that you yourself added? If so, don't add them with named identifiers; use the anonymous syntax.

then I cannot call object_dictionary(model)

Sure you can? You just can't add new constraints with an existing name? And you probably can't print the dictionary.

hdavid16 commented 1 year ago

I name them because I may want to refer to them later when nesting disjunctions.

If the object is not unregistered, object_dictionary(m) returns a KeyError:

julia> object_dictionary(m)
Dict{Symbol, Any} with 2 entries:Error showing value of type Dict{Symbol, Any}:
ERROR: KeyError: key MathOptInterface.Nonlinear.ConstraintIndex(1) not found
odow commented 1 year ago

I name them because I may want to refer to them later when nesting disjunctions.

Use the anonymous syntax, and store them in the .ext dictionary.

returns a KeyError:

This is just for the printing, because it cannot print the dictionary if the function is missing.