Skip to content

Commit

Permalink
[Utilities] fix adding unsupported constraints to AbstractModel (#2572)
Browse files Browse the repository at this point in the history
  • Loading branch information
odow authored Oct 30, 2024
1 parent 0843e5c commit 95e16c4
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 7 deletions.
28 changes: 21 additions & 7 deletions src/Utilities/model.jl
Original file line number Diff line number Diff line change
Expand Up @@ -312,9 +312,16 @@ end

function MOI.add_constraint(
model::AbstractModel,
func::MOI.AbstractFunction,
set::MOI.AbstractSet,
)
func::F,
set::S,
) where {F<:MOI.AbstractFunction,S<:MOI.AbstractSet}
# We check supports_constraint here because it is a common practice for
# AbstractModels to declare that they do not support particular constraints,
# even though the underlying `.constraints` object does. See, for example,
# the various models in MOI.FileFormats.
if !MOI.supports_constraint(model, F, S)
throw(MOI.UnsupportedConstraint{F,S}())
end
return MOI.add_constraint(model.constraints, func, set)
end

Expand All @@ -328,10 +335,17 @@ end

function MOI.add_constraint(
model::AbstractModel,
f::MOI.VariableIndex,
s::MOI.AbstractScalarSet,
)
return MOI.add_constraint(model.variables, f, s)
func::MOI.VariableIndex,
set::S,
) where {S<:MOI.AbstractScalarSet}
# We check supports_constraint here because it is a common practice for
# AbstractModels to declare that they do not support particular constraints,
# even though the underlying `.constraints` object does. See, for example,
# the various models in MOI.FileFormats.
if !MOI.supports_constraint(model, MOI.VariableIndex, S)
throw(MOI.UnsupportedConstraint{MOI.VariableIndex,S}())
end
return MOI.add_constraint(model.variables, func, set)
end

# MOI.NumberOfConstraints
Expand Down
29 changes: 29 additions & 0 deletions test/Utilities/model.jl
Original file line number Diff line number Diff line change
Expand Up @@ -515,6 +515,35 @@ function test_vector_of_constraints_list_of_constraint_attributes_set()
return
end

function test_copy_to_unsupported_scalar_variable()
F, S = MOI.VariableIndex, MOI.GreaterThan{Float64}
model = MOI.Utilities.Model{Float64}()
x, _ = MOI.add_constrained_variable(model, MOI.GreaterThan(1.0))
dest = MOI.FileFormats.CBF.Model()
@test_throws(MOI.UnsupportedConstraint{F,S}, MOI.copy_to(dest, model))
return
end

function test_copy_to_unsupported_vector_variables()
F, S = MOI.VectorOfVariables, MOI.AllDifferent
model = MOI.Utilities.Model{Float64}()
x, _ = MOI.add_constrained_variables(model, MOI.AllDifferent(3))
dest = MOI.FileFormats.CBF.Model()
@test_throws(MOI.UnsupportedConstraint{F,S}, MOI.copy_to(dest, model))
return
end

function test_copy_to_unsupported_scalar_function()
F, S = MOI.ScalarNonlinearFunction, MOI.EqualTo{Float64}
model = MOI.Utilities.Model{Float64}()
x = MOI.add_variable(model)
f = MOI.ScalarNonlinearFunction(:log, Any[x])
MOI.add_constraint(model, f, MOI.EqualTo(0.0))
dest = MOI.FileFormats.CBF.Model()
@test_throws(MOI.UnsupportedConstraint{F,S}, MOI.copy_to(dest, model))
return
end

end # module

TestModel.runtests()

0 comments on commit 95e16c4

Please sign in to comment.