From fea4681a6429142a2b15452cf668a000a182f866 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Legat?= Date: Wed, 13 Oct 2021 16:57:28 -0400 Subject: [PATCH 1/5] Implement ConstraintFunction/ConstraintSet for VariablesContainer --- src/Test/test_modification.jl | 11 ++-- src/Utilities/model.jl | 93 +++++++--------------------- src/Utilities/variables_container.jl | 54 ++++++++++++++-- src/attributes.jl | 87 ++++++++++++++------------ test/errors.jl | 6 +- 5 files changed, 130 insertions(+), 121 deletions(-) diff --git a/src/Test/test_modification.jl b/src/Test/test_modification.jl index 21bb1150c2..e63d07b487 100644 --- a/src/Test/test_modification.jl +++ b/src/Test/test_modification.jl @@ -951,10 +951,13 @@ function test_modification_incorrect(model::MOI.ModelLike, ::Config) MOI.EqualTo(1.0), ) @test_throws( - ArgumentError, + MOI.SetTypeMismatch{MOI.EqualTo{Float64},MOI.LessThan{Float64}}, MOI.set(model, MOI.ConstraintSet(), c, MOI.LessThan(1.0)), ) - @test_throws(ArgumentError, MOI.set(model, MOI.ConstraintFunction(), c, x)) + @test_throws( + MOI.FunctionTypeMismatch{MOI.ScalarAffineFunction{Float64},MOI.VariableIndex}, + MOI.set(model, MOI.ConstraintFunction(), c, x), + ) return end @@ -978,11 +981,11 @@ function test_modification_incorrect_VariableIndex( x = MOI.add_variable(model) c = MOI.add_constraint(model, x, MOI.GreaterThan(zero(T))) @test_throws( - ArgumentError, + MOI.SetTypeMismatch{MOI.GreaterThan{T},MOI.LessThan{T}}, MOI.set(model, MOI.ConstraintSet(), c, MOI.LessThan(one(T))), ) @test_throws( - ArgumentError, + MOI.FunctionTypeMismatch{MOI.VariableIndex,MOI.ScalarAffineFunction{T}}, MOI.set(model, MOI.ConstraintFunction(), c, one(T) * x), ) y = MOI.add_variable(model) diff --git a/src/Utilities/model.jl b/src/Utilities/model.jl index eaef32c1b3..197a093c75 100644 --- a/src/Utilities/model.jl +++ b/src/Utilities/model.jl @@ -107,15 +107,24 @@ function MOI.delete(model::AbstractModel, vis::Vector{MOI.VariableIndex}) return end -function MOI.is_valid( +# `AbstractModel` fields `.variables` and `.constraints` act like a +# `StructOfConstraints` where `.variables` contains the `VariableIndex`-in-`S` +# constraints and `.constraints` contains the other constraints. +function constraints( model::AbstractModel, - ci::CI{MOI.VariableIndex,S}, -) where {S} - return MOI.is_valid(model.variables, ci) + ci::MOI.ConstraintIndex{MOI.VariableIndex}, +) + return model.variables +end +function constraints( + model::AbstractModel, + ci::MOI.ConstraintIndex, +) + return model.constraints end function MOI.is_valid(model::AbstractModel, ci::MOI.ConstraintIndex) - return MOI.is_valid(model.constraints, ci) + return MOI.is_valid(constraints(model, ci), ci) end function MOI.is_valid(model::AbstractModel, x::MOI.VariableIndex) @@ -375,21 +384,8 @@ function MOI.get( return MOI.get(model.constraints, attr, ci) end -function _delete_constraint( - model::AbstractModel, - ci::MOI.ConstraintIndex{MOI.VariableIndex,S}, -) where {S} - MOI.throw_if_not_valid(model, ci) - MOI.delete(model.variables, ci) - return -end - -function _delete_constraint(model::AbstractModel, ci::MOI.ConstraintIndex) - return MOI.delete(model.constraints, ci) -end - function MOI.delete(model::AbstractModel, ci::MOI.ConstraintIndex) - _delete_constraint(model, ci) + MOI.delete(constraints(model, ci), ci) model.name_to_con = nothing delete!(model.con_to_name, ci) return @@ -404,43 +400,13 @@ function MOI.modify( return end -function MOI.set( - ::AbstractModel, - ::MOI.ConstraintFunction, - ::MOI.ConstraintIndex{MOI.VariableIndex,<:MOI.AbstractScalarSet}, - ::MOI.VariableIndex, -) - return throw(MOI.SettingVariableIndexNotAllowed()) -end - -function MOI.set( - model::AbstractModel{T}, - attr::MOI.ConstraintSet, - ci::MOI.ConstraintIndex{MOI.VariableIndex,S}, - set::S, -) where {T,S<:SUPPORTED_VARIABLE_SCALAR_SETS{T}} - MOI.throw_if_not_valid(model, ci) - MOI.set(model.variables, attr, ci, set) - return -end - function MOI.set( model::AbstractModel, - attr::MOI.ConstraintSet, - ci::MOI.ConstraintIndex{<:MOI.AbstractFunction,S}, - set::S, -) where {S<:MOI.AbstractSet} - MOI.set(model.constraints, attr, ci, set) - return -end - -function MOI.set( - model::AbstractModel, - attr::MOI.ConstraintFunction, - ci::MOI.ConstraintIndex{F,<:MOI.AbstractSet}, - func::F, -) where {F<:MOI.AbstractFunction} - MOI.set(model.constraints, attr, ci, func) + attr::Union{MOI.ConstraintFunction,MOI.ConstraintSet}, + ci::MOI.ConstraintIndex{MOI.VariableIndex}, + value, +) + MOI.set(constraints(model, ci), attr, ci, value) return end @@ -482,29 +448,12 @@ function MOI.get( return MOI.get(model.constraints, loc) end -function MOI.get( - model::AbstractModel, - ::MOI.ConstraintFunction, - ci::CI{MOI.VariableIndex}, -) - MOI.throw_if_not_valid(model, ci) - return MOI.VariableIndex(ci.value) -end function MOI.get( model::AbstractModel, attr::Union{MOI.ConstraintFunction,MOI.ConstraintSet}, ci::MOI.ConstraintIndex, ) - return MOI.get(model.constraints, attr, ci) -end - -function MOI.get( - model::AbstractModel, - ::MOI.ConstraintSet, - ci::CI{MOI.VariableIndex,S}, -) where {S} - MOI.throw_if_not_valid(model, ci) - return set_from_constants(model.variables, S, ci.value) + return MOI.get(constraints(model, ci), attr, ci) end function MOI.is_empty(model::AbstractModel) diff --git a/src/Utilities/variables_container.jl b/src/Utilities/variables_container.jl index 07dca0f147..c84ba053c7 100644 --- a/src/Utilities/variables_container.jl +++ b/src/Utilities/variables_container.jl @@ -288,22 +288,68 @@ function MOI.is_valid( return !iszero(b.set_mask[ci.value] & _single_variable_flag(S)) end +function MOI.get( + model::VariablesContainer, + ::MOI.ConstraintFunction, + ci::CI{MOI.VariableIndex}, +) + MOI.throw_if_not_valid(model, ci) + return MOI.VariableIndex(ci.value) +end + function MOI.set( - b::VariablesContainer, + ::VariablesContainer, + ::MOI.ConstraintFunction, + ::MOI.ConstraintIndex{MOI.VariableIndex}, + ::MOI.VariableIndex, +) + return throw(MOI.SettingVariableIndexNotAllowed()) +end + +function MOI.set( + ::VariablesContainer, + ::MOI.ConstraintFunction, + ci::MOI.ConstraintIndex, + func, +) + return throw(MOI.FunctionTypeMismatch{MOI.func_type(ci),typeof(func)}()) +end + +function MOI.get( + model::VariablesContainer, ::MOI.ConstraintSet, ci::MOI.ConstraintIndex{MOI.VariableIndex,S}, - set::S, ) where {S} + MOI.throw_if_not_valid(model, ci) + return set_from_constants(model, S, ci.value) +end + +function MOI.set( + model::VariablesContainer{T}, + ::MOI.ConstraintSet, + ci::MOI.ConstraintIndex{MOI.VariableIndex,S}, + set::S, +) where {T,S<:SUPPORTED_VARIABLE_SCALAR_SETS{T}} + MOI.throw_if_not_valid(model, ci) flag = _single_variable_flag(S) if !iszero(flag & _LOWER_BOUND_MASK) - b.lower[ci.value] = _lower_bound(set) + model.lower[ci.value] = _lower_bound(set) end if !iszero(flag & _UPPER_BOUND_MASK) - b.upper[ci.value] = _upper_bound(set) + model.upper[ci.value] = _upper_bound(set) end return end +function MOI.set( + ::VariablesContainer, + ::MOI.ConstraintSet, + ci::MOI.ConstraintIndex{MOI.VariableIndex}, + set, +) + return throw(MOI.SetTypeMismatch{MOI.set_type(ci),typeof(set)}()) +end + function MOI.get( b::VariablesContainer, ::MOI.NumberOfConstraints{MOI.VariableIndex,S}, diff --git a/src/attributes.jl b/src/attributes.jl index 9ddfdf470d..c84fabed82 100644 --- a/src/attributes.jl +++ b/src/attributes.jl @@ -145,9 +145,9 @@ message(err::SubmitNotAllowed) = err.message end An error indicating that the requested attribute `attr` could not be retrieved, -because the solver returned too few results compared to what was requested. -For instance, the user tries to retrieve `VariablePrimal(2)` when only one -solution is available, or when the model is infeasible and has no solution. +because the solver returned too few results compared to what was requested. +For instance, the user tries to retrieve `VariablePrimal(2)` when only one +solution is available, or when the model is infeasible and has no solution. See also: [`check_result_index_bounds`](@ref). """ @@ -159,9 +159,9 @@ end """ check_result_index_bounds(model::ModelLike, attr) -This function checks whether enough results are available in the `model` for -the requested `attr`, using its `result_index` field. If the model -does not have sufficient results to answer the query, it throws a +This function checks whether enough results are available in the `model` for +the requested `attr`, using its `result_index` field. If the model +does not have sufficient results to answer the query, it throws a [`ResultIndexBoundsError`](@ref). """ function check_result_index_bounds(model::ModelLike, attr) @@ -1025,10 +1025,10 @@ attribute_value_type(::ObjectiveFunctionType) = Type{<:AbstractFunction} A model attribute for the objective value of the primal solution `result_index`. -If the solver does not have a primal value for the objective because the +If the solver does not have a primal value for the objective because the `result_index` is beyond the available solutions (whose number is indicated by -the [`ResultCount`](@ref) attribute), getting this attribute must throw a -[`ResultIndexBoundsError`](@ref). Otherwise, if the result is unavailable for +the [`ResultCount`](@ref) attribute), getting this attribute must throw a +[`ResultIndexBoundsError`](@ref). Otherwise, if the result is unavailable for another reason (for instance, only a dual solution is available), the result is undefined. Users should first check [`PrimalStatus`](@ref) before accessing the `ObjectiveValue` attribute. @@ -1046,10 +1046,10 @@ end A model attribute for the value of the objective function of the dual problem for the `result_index`th dual result. -If the solver does not have a dual value for the objective because the +If the solver does not have a dual value for the objective because the `result_index` is beyond the available solutions (whose number is indicated by -the [`ResultCount`](@ref) attribute), getting this attribute must throw a -[`ResultIndexBoundsError`](@ref). Otherwise, if the result is unavailable for +the [`ResultCount`](@ref) attribute), getting this attribute must throw a +[`ResultIndexBoundsError`](@ref). Otherwise, if the result is unavailable for another reason (for instance, only a primal solution is available), the result is undefined. Users should first check [`DualStatus`](@ref) before accessing the `DualObjectiveValue` attribute. @@ -1228,10 +1228,10 @@ struct VariablePrimalStart <: AbstractVariableAttribute end A variable attribute for the assignment to some primal variable's value in result `result_index`. If `result_index` is omitted, it is 1 by default. -If the solver does not have a primal value for the variable because the +If the solver does not have a primal value for the variable because the `result_index` is beyond the available solutions (whose number is indicated by -the [`ResultCount`](@ref) attribute), getting this attribute must throw a -[`ResultIndexBoundsError`](@ref). Otherwise, if the result is unavailable for +the [`ResultCount`](@ref) attribute), getting this attribute must throw a +[`ResultIndexBoundsError`](@ref). Otherwise, if the result is unavailable for another reason (for instance, only a dual solution is available), the result is undefined. Users should first check [`PrimalStatus`](@ref) before accessing the `VariablePrimal` attribute. @@ -1298,10 +1298,10 @@ Possible values are: A variable attribute for the `BasisStatusCode` of a variable in result `result_index`, with respect to an available optimal solution basis. -If the solver does not have a basis statue for the variable because the +If the solver does not have a basis statue for the variable because the `result_index` is beyond the available solutions (whose number is indicated by -the [`ResultCount`](@ref) attribute), getting this attribute must throw a -[`ResultIndexBoundsError`](@ref). Otherwise, if the result is unavailable for +the [`ResultCount`](@ref) attribute), getting this attribute must throw a +[`ResultIndexBoundsError`](@ref). Otherwise, if the result is unavailable for another reason (for instance, only a dual solution is available), the result is undefined. Users should first check [`PrimalStatus`](@ref) before accessing the `VariableBasisStatus` attribute. @@ -1408,10 +1408,10 @@ These solvers may return the value of `s` for `ConstraintPrimal`, rather than `b - Ax`. (Although these are constrained by an equality constraint, due to numerical tolerances they may not be identical.) -If the solver does not have a primal value for the constraint because the +If the solver does not have a primal value for the constraint because the `result_index` is beyond the available solutions (whose number is indicated by -the [`ResultCount`](@ref) attribute), getting this attribute must throw a -[`ResultIndexBoundsError`](@ref). Otherwise, if the result is unavailable for +the [`ResultCount`](@ref) attribute), getting this attribute must throw a +[`ResultIndexBoundsError`](@ref). Otherwise, if the result is unavailable for another reason (for instance, only a dual solution is available), the result is undefined. Users should first check [`PrimalStatus`](@ref) before accessing the `ConstraintPrimal` attribute. @@ -1430,10 +1430,10 @@ end A constraint attribute for the assignment to some constraint's dual value(s) in result `result_index`. If `result_index` is omitted, it is 1 by default. -If the solver does not have a dual value for the variable because the +If the solver does not have a dual value for the variable because the `result_index` is beyond the available solutions (whose number is indicated by -the [`ResultCount`](@ref) attribute), getting this attribute must throw a -[`ResultIndexBoundsError`](@ref). Otherwise, if the result is unavailable for +the [`ResultCount`](@ref) attribute), getting this attribute must throw a +[`ResultIndexBoundsError`](@ref). Otherwise, if the result is unavailable for another reason (for instance, only a primal solution is available), the result is undefined. Users should first check [`DualStatus`](@ref) before accessing the `ConstraintDual` attribute. @@ -1452,10 +1452,10 @@ A constraint attribute for the `BasisStatusCode` of some constraint in result `result_index`, with respect to an available optimal solution basis. If `result_index` is omitted, it is 1 by default. -If the solver does not have a basis statue for the constraint because the +If the solver does not have a basis statue for the constraint because the `result_index` is beyond the available solutions (whose number is indicated by -the [`ResultCount`](@ref) attribute), getting this attribute must throw a -[`ResultIndexBoundsError`](@ref). Otherwise, if the result is unavailable for +the [`ResultCount`](@ref) attribute), getting this attribute must throw a +[`ResultIndexBoundsError`](@ref). Otherwise, if the result is unavailable for another reason (for instance, only a dual solution is available), the result is undefined. Users should first check [`PrimalStatus`](@ref) before accessing the `ConstraintBasisStatus` attribute. @@ -1540,6 +1540,15 @@ struct ConstraintFunction <: AbstractConstraintAttribute end attribute_value_type(::ConstraintFunction) = AbstractFunction +struct FunctionTypeMismatch{F1,F2} <: Exception end +function Base.showerror(io::IO, err::FunctionTypeMismatch{F1,F2}) where {F1,F2} + print( + io, + """$(typeof(err)): Cannot modify functions of different types. + Constraint type is $F1 while the replacement function is of type $F2.""", + ) +end + function throw_set_error_fallback( ::ModelLike, attr::ConstraintFunction, @@ -1553,15 +1562,11 @@ func_type(c::ConstraintIndex{F,S}) where {F,S} = F function throw_set_error_fallback( ::ModelLike, ::ConstraintFunction, - constraint_index::ConstraintIndex, + ci::ConstraintIndex, func::AbstractFunction; kwargs..., ) - return throw( - ArgumentError("""Cannot modify functions of different types. - Constraint type is $(func_type(constraint_index)) while the replacement - function is of type $(typeof(func))."""), - ) + return throw(FunctionTypeMismatch{func_type(ci),typeof(func)}()) end """ @@ -1573,6 +1578,16 @@ struct ConstraintSet <: AbstractConstraintAttribute end attribute_value_type(::ConstraintSet) = AbstractSet +struct SetTypeMismatch{S1,S2} <: Exception end +function Base.showerror(io::IO, err::SetTypeMismatch{S1,S2}) where {S1,S2} + print( + io, + """$(typeof(err)): Cannot modify sets of different types. Constraint + type is $S1 while the replacement set is of type $S2. Use `transform` + instead.""", + ) +end + function throw_set_error_fallback( ::ModelLike, attr::ConstraintSet, @@ -1590,11 +1605,7 @@ function throw_set_error_fallback( set::AbstractSet; kwargs..., ) - return throw( - ArgumentError("""Cannot modify sets of different types. Constraint - type is $(set_type(constraint_index)) while the replacement set is of - type $(typeof(set)). Use `transform` instead."""), - ) + return throw(SetTypeMismatch{set_type(constraint_index),typeof(set)}()) end """ diff --git a/test/errors.jl b/test/errors.jl index 5fa7c704e3..d00f420aba 100644 --- a/test/errors.jl +++ b/test/errors.jl @@ -188,7 +188,7 @@ function test_errors_ConstraintFunction_NotAllowed() MOI.set(model, MOI.ConstraintFunction(), ci, vi) ) @test_throws( - ArgumentError, + MOI.SetTypeMismatch{MOI.VariableIndex,MOI.ScalarAffineFunction{Float64}}, MOI.set( model, MOI.ConstraintFunction(), @@ -208,11 +208,11 @@ function test_errors_ConstraintSet_NotAllowed() MOI.set(model, MOI.ConstraintSet(), ci, MOI.EqualTo(1.0)) ) @test_throws( - ArgumentError, + MOI.SetTypeMismatch{MOI.EqualTo{Float64},MOI.EqualTo{Int}}, MOI.set(model, MOI.ConstraintSet(), ci, MOI.EqualTo(1)) ) @test_throws( - ArgumentError, + MOI.SetTypeMismatch{MOI.EqualTo{Float64},MOI.GreaterThan{Float64}}, MOI.set(model, MOI.ConstraintSet(), ci, MOI.GreaterThan(1.0)) ) end From ae0cd40e803fd05ac5ef33c1a26f1696d7f1aa33 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Legat?= Date: Wed, 13 Oct 2021 17:25:48 -0400 Subject: [PATCH 2/5] Fixes --- src/Test/test_modification.jl | 5 ++++- src/Utilities/model.jl | 7 ++----- src/attributes.jl | 4 ++-- test/errors.jl | 5 ++++- 4 files changed, 12 insertions(+), 9 deletions(-) diff --git a/src/Test/test_modification.jl b/src/Test/test_modification.jl index e63d07b487..56bfe919f7 100644 --- a/src/Test/test_modification.jl +++ b/src/Test/test_modification.jl @@ -955,7 +955,10 @@ function test_modification_incorrect(model::MOI.ModelLike, ::Config) MOI.set(model, MOI.ConstraintSet(), c, MOI.LessThan(1.0)), ) @test_throws( - MOI.FunctionTypeMismatch{MOI.ScalarAffineFunction{Float64},MOI.VariableIndex}, + MOI.FunctionTypeMismatch{ + MOI.ScalarAffineFunction{Float64}, + MOI.VariableIndex, + }, MOI.set(model, MOI.ConstraintFunction(), c, x), ) return diff --git a/src/Utilities/model.jl b/src/Utilities/model.jl index 197a093c75..afe1479c13 100644 --- a/src/Utilities/model.jl +++ b/src/Utilities/model.jl @@ -116,10 +116,7 @@ function constraints( ) return model.variables end -function constraints( - model::AbstractModel, - ci::MOI.ConstraintIndex, -) +function constraints(model::AbstractModel, ci::MOI.ConstraintIndex) return model.constraints end @@ -403,7 +400,7 @@ end function MOI.set( model::AbstractModel, attr::Union{MOI.ConstraintFunction,MOI.ConstraintSet}, - ci::MOI.ConstraintIndex{MOI.VariableIndex}, + ci::MOI.ConstraintIndex, value, ) MOI.set(constraints(model, ci), attr, ci, value) diff --git a/src/attributes.jl b/src/attributes.jl index c84fabed82..f9e6dba43f 100644 --- a/src/attributes.jl +++ b/src/attributes.jl @@ -1542,7 +1542,7 @@ attribute_value_type(::ConstraintFunction) = AbstractFunction struct FunctionTypeMismatch{F1,F2} <: Exception end function Base.showerror(io::IO, err::FunctionTypeMismatch{F1,F2}) where {F1,F2} - print( + return print( io, """$(typeof(err)): Cannot modify functions of different types. Constraint type is $F1 while the replacement function is of type $F2.""", @@ -1580,7 +1580,7 @@ attribute_value_type(::ConstraintSet) = AbstractSet struct SetTypeMismatch{S1,S2} <: Exception end function Base.showerror(io::IO, err::SetTypeMismatch{S1,S2}) where {S1,S2} - print( + return print( io, """$(typeof(err)): Cannot modify sets of different types. Constraint type is $S1 while the replacement set is of type $S2. Use `transform` diff --git a/test/errors.jl b/test/errors.jl index d00f420aba..36f60ae3cb 100644 --- a/test/errors.jl +++ b/test/errors.jl @@ -188,7 +188,10 @@ function test_errors_ConstraintFunction_NotAllowed() MOI.set(model, MOI.ConstraintFunction(), ci, vi) ) @test_throws( - MOI.SetTypeMismatch{MOI.VariableIndex,MOI.ScalarAffineFunction{Float64}}, + MOI.FunctionTypeMismatch{ + MOI.VariableIndex, + MOI.ScalarAffineFunction{Float64}, + }, MOI.set( model, MOI.ConstraintFunction(), From 75aba6617e1ba988d810936b7609bdcc0362ac80 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Legat?= Date: Wed, 13 Oct 2021 22:35:45 -0400 Subject: [PATCH 3/5] Fixes --- src/Bridges/bridge_optimizer.jl | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Bridges/bridge_optimizer.jl b/src/Bridges/bridge_optimizer.jl index 114f690988..e8af55e7d6 100644 --- a/src/Bridges/bridge_optimizer.jl +++ b/src/Bridges/bridge_optimizer.jl @@ -1127,8 +1127,8 @@ function MOI.set( ci::MOI.ConstraintIndex{F}, func, ) where {F} - if typeof(func) != F - throw(ArgumentError("Invalid type when setting ConstraintFunction.")) + if !(func isa F) + throw(MOI.FunctionTypeMismatch{F,typeof(func)}()) end if Variable.has_bridges(Variable.bridges(b)) set = MOI.get(b, MOI.ConstraintSet(), ci) @@ -1165,8 +1165,8 @@ function MOI.set( ci::MOI.ConstraintIndex{MOI.VariableIndex,S}, value, ) where {S<:MOI.AbstractScalarSet} - if typeof(value) != S - throw(ArgumentError("Invalid type when setting ConstraintSet.")) + if !(value isa S) + throw(MOI.SetTypeMismatch{S,typeof(value)}()) end _set_substituted(b, attr, ci, value) return From fd6db062b4e33c19468f9a4de5d713aa7c37d252 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Legat?= Date: Thu, 14 Oct 2021 10:05:54 -0400 Subject: [PATCH 4/5] Fix --- src/Bridges/bridge_optimizer.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Bridges/bridge_optimizer.jl b/src/Bridges/bridge_optimizer.jl index e8af55e7d6..5f3f935c7b 100644 --- a/src/Bridges/bridge_optimizer.jl +++ b/src/Bridges/bridge_optimizer.jl @@ -1191,8 +1191,8 @@ function MOI.set( ci::MOI.ConstraintIndex{<:MOI.AbstractScalarFunction,S}, set, ) where {S<:MOI.AbstractScalarSet} - if typeof(set) != S - throw(ArgumentError("Invalid type when setting ConstraintSet.")) + if !(set isa S) + throw(MOI.SetTypeMismatch{S,typeof(value)}()) end if Variable.has_bridges(Variable.bridges(b)) func = MOI.get(b, MOI.ConstraintFunction(), ci) From 90ea90e1ed11f15661643446f6a351111d4e60ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Legat?= Date: Tue, 19 Oct 2021 11:09:45 -0400 Subject: [PATCH 5/5] Fix --- src/Bridges/bridge_optimizer.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Bridges/bridge_optimizer.jl b/src/Bridges/bridge_optimizer.jl index 5f3f935c7b..a627f4cc0d 100644 --- a/src/Bridges/bridge_optimizer.jl +++ b/src/Bridges/bridge_optimizer.jl @@ -1192,7 +1192,7 @@ function MOI.set( set, ) where {S<:MOI.AbstractScalarSet} if !(set isa S) - throw(MOI.SetTypeMismatch{S,typeof(value)}()) + throw(MOI.SetTypeMismatch{S,typeof(set)}()) end if Variable.has_bridges(Variable.bridges(b)) func = MOI.get(b, MOI.ConstraintFunction(), ci)