Skip to content

Commit e2cd0a9

Browse files
authored
Implement ConstraintFunction/ConstraintSet for VariablesContainer (#1635)
* Implement ConstraintFunction/ConstraintSet for VariablesContainer * Fixes * Fixes * Fix * Fix
1 parent 17608cb commit e2cd0a9

6 files changed

Lines changed: 139 additions & 127 deletions

File tree

src/Bridges/bridge_optimizer.jl

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1127,8 +1127,8 @@ function MOI.set(
11271127
ci::MOI.ConstraintIndex{F},
11281128
func,
11291129
) where {F}
1130-
if typeof(func) != F
1131-
throw(ArgumentError("Invalid type when setting ConstraintFunction."))
1130+
if !(func isa F)
1131+
throw(MOI.FunctionTypeMismatch{F,typeof(func)}())
11321132
end
11331133
if Variable.has_bridges(Variable.bridges(b))
11341134
set = MOI.get(b, MOI.ConstraintSet(), ci)
@@ -1165,8 +1165,8 @@ function MOI.set(
11651165
ci::MOI.ConstraintIndex{MOI.VariableIndex,S},
11661166
value,
11671167
) where {S<:MOI.AbstractScalarSet}
1168-
if typeof(value) != S
1169-
throw(ArgumentError("Invalid type when setting ConstraintSet."))
1168+
if !(value isa S)
1169+
throw(MOI.SetTypeMismatch{S,typeof(value)}())
11701170
end
11711171
_set_substituted(b, attr, ci, value)
11721172
return
@@ -1191,8 +1191,8 @@ function MOI.set(
11911191
ci::MOI.ConstraintIndex{<:MOI.AbstractScalarFunction,S},
11921192
set,
11931193
) where {S<:MOI.AbstractScalarSet}
1194-
if typeof(set) != S
1195-
throw(ArgumentError("Invalid type when setting ConstraintSet."))
1194+
if !(set isa S)
1195+
throw(MOI.SetTypeMismatch{S,typeof(set)}())
11961196
end
11971197
if Variable.has_bridges(Variable.bridges(b))
11981198
func = MOI.get(b, MOI.ConstraintFunction(), ci)

src/Test/test_modification.jl

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -951,10 +951,16 @@ function test_modification_incorrect(model::MOI.ModelLike, ::Config)
951951
MOI.EqualTo(1.0),
952952
)
953953
@test_throws(
954-
ArgumentError,
954+
MOI.SetTypeMismatch{MOI.EqualTo{Float64},MOI.LessThan{Float64}},
955955
MOI.set(model, MOI.ConstraintSet(), c, MOI.LessThan(1.0)),
956956
)
957-
@test_throws(ArgumentError, MOI.set(model, MOI.ConstraintFunction(), c, x))
957+
@test_throws(
958+
MOI.FunctionTypeMismatch{
959+
MOI.ScalarAffineFunction{Float64},
960+
MOI.VariableIndex,
961+
},
962+
MOI.set(model, MOI.ConstraintFunction(), c, x),
963+
)
958964
return
959965
end
960966

@@ -978,11 +984,11 @@ function test_modification_incorrect_VariableIndex(
978984
x = MOI.add_variable(model)
979985
c = MOI.add_constraint(model, x, MOI.GreaterThan(zero(T)))
980986
@test_throws(
981-
ArgumentError,
987+
MOI.SetTypeMismatch{MOI.GreaterThan{T},MOI.LessThan{T}},
982988
MOI.set(model, MOI.ConstraintSet(), c, MOI.LessThan(one(T))),
983989
)
984990
@test_throws(
985-
ArgumentError,
991+
MOI.FunctionTypeMismatch{MOI.VariableIndex,MOI.ScalarAffineFunction{T}},
986992
MOI.set(model, MOI.ConstraintFunction(), c, one(T) * x),
987993
)
988994
y = MOI.add_variable(model)

src/Utilities/model.jl

Lines changed: 18 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -107,15 +107,21 @@ function MOI.delete(model::AbstractModel, vis::Vector{MOI.VariableIndex})
107107
return
108108
end
109109

110-
function MOI.is_valid(
110+
# `AbstractModel` fields `.variables` and `.constraints` act like a
111+
# `StructOfConstraints` where `.variables` contains the `VariableIndex`-in-`S`
112+
# constraints and `.constraints` contains the other constraints.
113+
function constraints(
111114
model::AbstractModel,
112-
ci::CI{MOI.VariableIndex,S},
113-
) where {S}
114-
return MOI.is_valid(model.variables, ci)
115+
ci::MOI.ConstraintIndex{MOI.VariableIndex},
116+
)
117+
return model.variables
118+
end
119+
function constraints(model::AbstractModel, ci::MOI.ConstraintIndex)
120+
return model.constraints
115121
end
116122

117123
function MOI.is_valid(model::AbstractModel, ci::MOI.ConstraintIndex)
118-
return MOI.is_valid(model.constraints, ci)
124+
return MOI.is_valid(constraints(model, ci), ci)
119125
end
120126

121127
function MOI.is_valid(model::AbstractModel, x::MOI.VariableIndex)
@@ -375,21 +381,8 @@ function MOI.get(
375381
return MOI.get(model.constraints, attr, ci)
376382
end
377383

378-
function _delete_constraint(
379-
model::AbstractModel,
380-
ci::MOI.ConstraintIndex{MOI.VariableIndex,S},
381-
) where {S}
382-
MOI.throw_if_not_valid(model, ci)
383-
MOI.delete(model.variables, ci)
384-
return
385-
end
386-
387-
function _delete_constraint(model::AbstractModel, ci::MOI.ConstraintIndex)
388-
return MOI.delete(model.constraints, ci)
389-
end
390-
391384
function MOI.delete(model::AbstractModel, ci::MOI.ConstraintIndex)
392-
_delete_constraint(model, ci)
385+
MOI.delete(constraints(model, ci), ci)
393386
model.name_to_con = nothing
394387
delete!(model.con_to_name, ci)
395388
return
@@ -404,43 +397,13 @@ function MOI.modify(
404397
return
405398
end
406399

407-
function MOI.set(
408-
::AbstractModel,
409-
::MOI.ConstraintFunction,
410-
::MOI.ConstraintIndex{MOI.VariableIndex,<:MOI.AbstractScalarSet},
411-
::MOI.VariableIndex,
412-
)
413-
return throw(MOI.SettingVariableIndexNotAllowed())
414-
end
415-
416-
function MOI.set(
417-
model::AbstractModel{T},
418-
attr::MOI.ConstraintSet,
419-
ci::MOI.ConstraintIndex{MOI.VariableIndex,S},
420-
set::S,
421-
) where {T,S<:SUPPORTED_VARIABLE_SCALAR_SETS{T}}
422-
MOI.throw_if_not_valid(model, ci)
423-
MOI.set(model.variables, attr, ci, set)
424-
return
425-
end
426-
427-
function MOI.set(
428-
model::AbstractModel,
429-
attr::MOI.ConstraintSet,
430-
ci::MOI.ConstraintIndex{<:MOI.AbstractFunction,S},
431-
set::S,
432-
) where {S<:MOI.AbstractSet}
433-
MOI.set(model.constraints, attr, ci, set)
434-
return
435-
end
436-
437400
function MOI.set(
438401
model::AbstractModel,
439-
attr::MOI.ConstraintFunction,
440-
ci::MOI.ConstraintIndex{F,<:MOI.AbstractSet},
441-
func::F,
442-
) where {F<:MOI.AbstractFunction}
443-
MOI.set(model.constraints, attr, ci, func)
402+
attr::Union{MOI.ConstraintFunction,MOI.ConstraintSet},
403+
ci::MOI.ConstraintIndex,
404+
value,
405+
)
406+
MOI.set(constraints(model, ci), attr, ci, value)
444407
return
445408
end
446409

@@ -482,29 +445,12 @@ function MOI.get(
482445
return MOI.get(model.constraints, loc)
483446
end
484447

485-
function MOI.get(
486-
model::AbstractModel,
487-
::MOI.ConstraintFunction,
488-
ci::CI{MOI.VariableIndex},
489-
)
490-
MOI.throw_if_not_valid(model, ci)
491-
return MOI.VariableIndex(ci.value)
492-
end
493448
function MOI.get(
494449
model::AbstractModel,
495450
attr::Union{MOI.ConstraintFunction,MOI.ConstraintSet},
496451
ci::MOI.ConstraintIndex,
497452
)
498-
return MOI.get(model.constraints, attr, ci)
499-
end
500-
501-
function MOI.get(
502-
model::AbstractModel,
503-
::MOI.ConstraintSet,
504-
ci::CI{MOI.VariableIndex,S},
505-
) where {S}
506-
MOI.throw_if_not_valid(model, ci)
507-
return set_from_constants(model.variables, S, ci.value)
453+
return MOI.get(constraints(model, ci), attr, ci)
508454
end
509455

510456
function MOI.is_empty(model::AbstractModel)

src/Utilities/variables_container.jl

Lines changed: 50 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -288,22 +288,68 @@ function MOI.is_valid(
288288
return !iszero(b.set_mask[ci.value] & _single_variable_flag(S))
289289
end
290290

291+
function MOI.get(
292+
model::VariablesContainer,
293+
::MOI.ConstraintFunction,
294+
ci::CI{MOI.VariableIndex},
295+
)
296+
MOI.throw_if_not_valid(model, ci)
297+
return MOI.VariableIndex(ci.value)
298+
end
299+
291300
function MOI.set(
292-
b::VariablesContainer,
301+
::VariablesContainer,
302+
::MOI.ConstraintFunction,
303+
::MOI.ConstraintIndex{MOI.VariableIndex},
304+
::MOI.VariableIndex,
305+
)
306+
return throw(MOI.SettingVariableIndexNotAllowed())
307+
end
308+
309+
function MOI.set(
310+
::VariablesContainer,
311+
::MOI.ConstraintFunction,
312+
ci::MOI.ConstraintIndex,
313+
func,
314+
)
315+
return throw(MOI.FunctionTypeMismatch{MOI.func_type(ci),typeof(func)}())
316+
end
317+
318+
function MOI.get(
319+
model::VariablesContainer,
293320
::MOI.ConstraintSet,
294321
ci::MOI.ConstraintIndex{MOI.VariableIndex,S},
295-
set::S,
296322
) where {S}
323+
MOI.throw_if_not_valid(model, ci)
324+
return set_from_constants(model, S, ci.value)
325+
end
326+
327+
function MOI.set(
328+
model::VariablesContainer{T},
329+
::MOI.ConstraintSet,
330+
ci::MOI.ConstraintIndex{MOI.VariableIndex,S},
331+
set::S,
332+
) where {T,S<:SUPPORTED_VARIABLE_SCALAR_SETS{T}}
333+
MOI.throw_if_not_valid(model, ci)
297334
flag = _single_variable_flag(S)
298335
if !iszero(flag & _LOWER_BOUND_MASK)
299-
b.lower[ci.value] = _lower_bound(set)
336+
model.lower[ci.value] = _lower_bound(set)
300337
end
301338
if !iszero(flag & _UPPER_BOUND_MASK)
302-
b.upper[ci.value] = _upper_bound(set)
339+
model.upper[ci.value] = _upper_bound(set)
303340
end
304341
return
305342
end
306343

344+
function MOI.set(
345+
::VariablesContainer,
346+
::MOI.ConstraintSet,
347+
ci::MOI.ConstraintIndex{MOI.VariableIndex},
348+
set,
349+
)
350+
return throw(MOI.SetTypeMismatch{MOI.set_type(ci),typeof(set)}())
351+
end
352+
307353
function MOI.get(
308354
b::VariablesContainer,
309355
::MOI.NumberOfConstraints{MOI.VariableIndex,S},

0 commit comments

Comments
 (0)