@@ -44,6 +44,8 @@ mutable struct Map <: AbstractDict{MOI.VariableIndex,AbstractBridge}
4444 # `(ci::ConstraintIndex{MOI.VectorOfVariables}).value` ->
4545 # the dimension of the set
4646 vector_of_variables_length:: Vector{Int64}
47+ # Same as in `MOI.Utilities.VariablesContainer`
48+ set_mask:: Vector{UInt16}
4749end
4850
4951function Map ()
@@ -58,6 +60,7 @@ function Map()
5860 Dict {MOI.ConstraintIndex,Int64} (),
5961 Int64[],
6062 Int64[],
63+ UInt16[],
6164 )
6265end
6366
@@ -88,6 +91,7 @@ function Base.empty!(map::Map)
8891 empty! (map. constraint_context)
8992 empty! (map. vector_of_variables_map)
9093 empty! (map. vector_of_variables_length)
94+ empty! (map. set_mask)
9195 return map
9296end
9397
113117function Base. delete! (map:: Map , vi:: MOI.VariableIndex )
114118 if iszero (map. info[- vi. value])
115119 # Delete scalar variable
116- map. bridges[bridge_index (map, vi)] = nothing
117- map. sets[bridge_index (map, vi)] = nothing
120+ index = bridge_index (map, vi)
121+ map. bridges[index] = nothing
122+ map. sets[index] = nothing
118123 elseif has_keys (map, [vi])
119124 # Delete whole vector
120125 delete! (map, [vi])
@@ -131,6 +136,7 @@ function Base.delete!(map::Map, vi::MOI.VariableIndex)
131136 map. index_in_vector[i] -= 1
132137 end
133138 end
139+ map. set_mask[- vi. value] = MOI. Utilities. _DELETED_VARIABLE
134140 map. index_in_vector[- vi. value] = - 1
135141 return map
136142end
@@ -144,6 +150,7 @@ function Base.delete!(map::Map, vis::Vector{MOI.VariableIndex})
144150 )
145151 end
146152 for vi in vis
153+ map. set_mask[- vi. value] = MOI. Utilities. _DELETED_VARIABLE
147154 map. index_in_vector[- vi. value] = - 1
148155 end
149156 map. bridges[bridge_index (map, first (vis))] = nothing
@@ -274,6 +281,64 @@ function MOI.is_valid(
274281 map. sets[index] === S
275282end
276283
284+ """
285+ MOI.add_constraint(map::Map, vi::MOI.VariableIndex, set::MOI.AbstractScalarSet)
286+
287+ Record that a constraint `vi`-in-`set` is added and throws if a lower or upper bound
288+ is set by this constraint and such bound has already been set for `vi`.
289+ """
290+ function MOI. add_constraint (:: Map , :: MOI.VariableIndex , :: MOI.AbstractScalarSet )
291+ # Nothing to do as this is is not recognized as setting a lower or upper bound
292+ end
293+
294+ # We cannot use `SUPPORTED_VARIABLE_SCALAR_SETS` because
295+ # `Integer` and `ZeroOne` do not define `T` and we need `T`
296+ # for `_throw_if_lower_bound_set`.
297+ const _BOUNDED_VARIABLE_SCALAR_SETS{T} = Union{
298+ MOI. EqualTo{T},
299+ MOI. GreaterThan{T},
300+ MOI. LessThan{T},
301+ MOI. Interval{T},
302+ MOI. Semicontinuous{T},
303+ MOI. Semiinteger{T},
304+ MOI. Parameter{T},
305+ }
306+
307+ function MOI. add_constraint (
308+ map:: Map ,
309+ vi:: MOI.VariableIndex ,
310+ :: S ,
311+ ) where {T,S<: _BOUNDED_VARIABLE_SCALAR_SETS{T} }
312+ flag = MOI. Utilities. _single_variable_flag (S)
313+ index = - vi. value
314+ mask = map. set_mask[index]
315+ MOI. Utilities. _throw_if_lower_bound_set (vi, S, mask, T)
316+ MOI. Utilities. _throw_if_upper_bound_set (vi, S, mask, T)
317+ map. set_mask[index] = mask | flag
318+ return
319+ end
320+
321+ """
322+ delete(map::Map, ci::MOI.ConstraintIndex{MOI.VariableIndex,<:MOI.AbstractScalarSet})
323+
324+ Record that the constraint `vi`-in-`S` is deleted.
325+ """
326+ function MOI. delete (
327+ :: Map ,
328+ ci:: MOI.ConstraintIndex{MOI.VariableIndex,<:MOI.AbstractScalarSet} ,
329+ )
330+ # Nothing to do as this is is not recognized as setting a lower or upper bound
331+ end
332+
333+ function MOI. delete (
334+ map:: Map ,
335+ ci:: MOI.ConstraintIndex{MOI.VariableIndex,S} ,
336+ ) where {T,S<: _BOUNDED_VARIABLE_SCALAR_SETS{T} }
337+ flag = MOI. Utilities. _single_variable_flag (S)
338+ map. set_mask[- ci. value] &= ~ flag
339+ return
340+ end
341+
277342"""
278343 constraints_with_set(map::Map, S::Type{<:MOI.AbstractSet})
279344
@@ -384,6 +449,7 @@ function add_key_for_bridge(
384449 push! (map. index_in_vector, 0 )
385450 push! (map. bridges, nothing )
386451 push! (map. sets, typeof (set))
452+ push! (map. set_mask, 0x0000 )
387453 map. bridges[bridge_index] = call_in_context (map, bridge_index, bridge_fun)
388454 index = - bridge_index
389455 variable = MOI. VariableIndex (index)
@@ -400,6 +466,7 @@ function add_key_for_bridge(
400466 end
401467 end
402468 end
469+ MOI. add_constraint (map, variable, set)
403470 return variable, MOI. ConstraintIndex {MOI.VariableIndex,typeof(set)} (index)
404471end
405472
@@ -443,12 +510,14 @@ function add_keys_for_bridge(
443510 push! (map. index_in_vector, 1 )
444511 push! (map. bridges, nothing )
445512 push! (map. sets, typeof (set))
513+ push! (map. set_mask, 0x0000 )
446514 for i in 2 : MOI. dimension (set)
447515 push! (map. parent_index, 0 )
448516 push! (map. info, i)
449517 push! (map. index_in_vector, i)
450518 push! (map. bridges, nothing )
451519 push! (map. sets, nothing )
520+ push! (map. set_mask, 0x0000 )
452521 end
453522 map. bridges[bridge_index] = call_in_context (map, bridge_index, bridge_fun)
454523 variables = MOI. VariableIndex[
0 commit comments