Skip to content

Commit b0c410f

Browse files
committed
[Bridges] throw MOI error subtypes instead of Base.error()
1 parent 2543d03 commit b0c410f

14 files changed

+60
-76
lines changed

src/Bridges/Constraint/bridges/ComplexNormInfinityToSecondOrderConeBridge.jl

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -42,10 +42,8 @@ function bridge_constraint(
4242
) where {T}
4343
fi_s = MOI.Utilities.scalarize(f)
4444
if !iszero(imag(fi_s[1]))
45-
error(
46-
"The epigraph variable `t` in `[t; x] in NormInfinityCone()` " *
47-
"must be real. It is: $(fi_s[1])",
48-
)
45+
msg = "The epigraph variable `t` in `[t; x] in NormInfinityCone()` must be real. It is: $(fi_s[1])"
46+
throw(MOI.AddConstraintNotAllowed{typeof(f),typeof(s)}(msg))
4947
end
5048
t = real(fi_s[1])
5149
cis = MOI.ConstraintIndex{MOI.VectorAffineFunction{T},MOI.SecondOrderCone}[]

src/Bridges/Constraint/bridges/IndicatorToMILPBridge.jl

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -201,19 +201,18 @@ function _is_binary(model::MOI.ModelLike, x::MOI.VariableIndex)
201201
end
202202

203203
function MOI.Bridges.final_touch(
204-
bridge::IndicatorToMILPBridge{T,F},
204+
bridge::IndicatorToMILPBridge{T,F,A,S},
205205
model::MOI.ModelLike,
206-
) where {T,F}
206+
) where {T,F,A,S}
207207
bounds = Dict{MOI.VariableIndex,NTuple{2,T}}()
208208
scalars = collect(MOI.Utilities.eachscalar(bridge.f))
209209
fi = scalars[2]
210210
ret = MOI.Utilities.get_bounds(model, bounds, fi)
211211
if ret === nothing
212212
throw(MOI.Bridges.BridgeRequiresFiniteDomainError(bridge, fi))
213213
elseif !_is_binary(model, scalars[1])
214-
error(
215-
"Unable to reformulate indicator constraint to a MILP. The indicator variable must be binary.",
216-
)
214+
msg = "Unable to reformulate indicator constraint to a MILP. The indicator variable must be binary."
215+
throw(MOI.AddConstraintNotAllowed{F,MOI.Indicator{A,S}}(msg))
217216
end
218217
if bridge.slack === nothing
219218
# This is the first time calling final_touch

src/Bridges/Constraint/bridges/IntegerToZeroOneBridge.jl

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -156,10 +156,7 @@ function MOI.Bridges.final_touch(
156156
if ret === bridge.last_bounds
157157
return nothing # final_touch already called
158158
elseif ret[1] == typemin(T) || ret[2] == typemax(T)
159-
error(
160-
"Unable to use IntegerToZeroOneBridge because the variable " *
161-
"$(bridge.x) has a non-finite domain",
162-
)
159+
throw(MOI.Bridges.BridgeRequiresFiniteDomainError(bridge, bridge.x))
163160
end
164161
f = MOI.ScalarAffineFunction([MOI.ScalarAffineTerm(T(1), bridge.x)], T(0))
165162
lb, ub = ceil(Int, ret[1]), floor(Int, ret[2])

src/Bridges/Constraint/bridges/SplitIntervalBridge.jl

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -230,9 +230,8 @@ function MOI.get(
230230
if bridge.upper !== nothing
231231
return MOI.get(model, attr, bridge.upper)
232232
end
233-
return error(
234-
"Cannot get `$attr` for a constraint in the interval `[-Inf, Inf]`.",
235-
)
233+
msg = "Cannot get `$attr` for a constraint in the interval `[-Inf, Inf]`."
234+
return throw(MOI.GetAttributeNotAllowed(attr, msg))
236235
end
237236

238237
function MOI.set(
@@ -333,10 +332,8 @@ function MOI.get(
333332
# The only case where the interval `[-∞, ∞]` is allowed is for
334333
# `VariableIndex` constraints but `ConstraintBasisStatus` is not
335334
# defined for `VariableIndex` constraints.
336-
error(
337-
"Cannot get `$attr` for a constraint in the interval " *
338-
"`[-Inf, Inf]`.",
339-
)
335+
msg = "Cannot get `$attr` for a constraint in the interval `[-Inf, Inf]`."
336+
throw(MOI.GetAttributeNotAllowed(attr, msg))
340337
end
341338
return upper_stat
342339
end

src/Bridges/Objective/bridges/SlackBridge.jl

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -58,15 +58,16 @@ function bridge_objective(
5858
) where {T,F,G<:MOI.AbstractScalarFunction}
5959
slack = MOI.add_variable(model)
6060
f = MOI.Utilities.operate(-, T, func, slack)
61-
if MOI.get(model, MOI.ObjectiveSense()) == MOI.MIN_SENSE
62-
set = MOI.LessThan(zero(T))
63-
elseif MOI.get(model, MOI.ObjectiveSense()) == MOI.MAX_SENSE
64-
set = MOI.GreaterThan(zero(T))
61+
sense = MOI.get(model, MOI.ObjectiveSense())
62+
if sense == MOI.FEASIBILITY_SENSE
63+
msg = "Set `MOI.ObjectiveSense` before `MOI.ObjectiveFunction` when using `MOI.Bridges.Objective.SlackBridge`."
64+
throw(MOI.SetAttributeNotAllowed(MOI.ObjectiveFunction{G}(), msg))
65+
end
66+
set = if sense == MOI.MIN_SENSE
67+
MOI.LessThan(zero(T))
6568
else
66-
error(
67-
"Set `MOI.ObjectiveSense` before `MOI.ObjectiveFunction` when",
68-
" using `MOI.Bridges.Objective.SlackBridge`.",
69-
)
69+
@assert sense == MOI.MAX_SENSE
70+
MOI.GreaterThan(zero(T))
7071
end
7172
constraint = MOI.Utilities.normalize_and_add_constraint(model, f, set)
7273
MOI.set(model, MOI.ObjectiveFunction{MOI.VariableIndex}(), slack)

src/Bridges/Objective/bridges/VectorSlackBridge.jl

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -69,15 +69,14 @@ function bridge_objective(
6969
)
7070
sense = MOI.get(model, MOI.ObjectiveSense())
7171
if sense == MOI.FEASIBILITY_SENSE
72-
error(
73-
"Set `MOI.ObjectiveSense` before `MOI.ObjectiveFunction` when",
74-
" using `MOI.Bridges.Objective.VectorSlackBridge`.",
75-
)
72+
msg = "Set `MOI.ObjectiveSense` before `MOI.ObjectiveFunction` when using `MOI.Bridges.Objective.VectorSlackBridge`."
73+
throw(MOI.SetAttributeNotAllowed(MOI.ObjectiveFunction{G}(), msg))
7674
end
7775
slacks = MOI.VectorOfVariables(variables[slacked_objectives])
7876
f = if sense == MOI.MIN_SENSE
7977
MOI.Utilities.operate(-, T, slacks, funcs[slacked_objectives])
80-
elseif sense == MOI.MAX_SENSE
78+
else
79+
@assert sense == MOI.MAX_SENSE
8180
MOI.Utilities.operate(-, T, funcs[slacked_objectives], slacks)
8281
end
8382
set = MOI.Nonnegatives(length(slacked_objectives))

src/Bridges/bridge_optimizer.jl

Lines changed: 15 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -2032,49 +2032,45 @@ _check_double_single_variable(::AbstractBridgeOptimizer, ::Any, ::Any) = nothing
20322032

20332033
function MOI.add_constraint(
20342034
b::AbstractBridgeOptimizer,
2035-
f::MOI.AbstractFunction,
2036-
s::MOI.AbstractSet,
2037-
)
2035+
f::F,
2036+
s::S,
2037+
) where {F<:MOI.AbstractFunction,S<:MOI.AbstractSet}
20382038
if Variable.has_bridges(Variable.bridges(b))
2039-
if f isa MOI.VariableIndex
2039+
if F <: MOI.VariableIndex
20402040
if is_bridged(b, f)
2041-
if MOI.is_valid(
2042-
b,
2043-
MOI.ConstraintIndex{MOI.VariableIndex,typeof(s)}(f.value),
2044-
)
2041+
ci = MOI.ConstraintIndex{MOI.VariableIndex,S}(f.value)
2042+
if MOI.is_valid(b, ci)
20452043
# The other constraint could have been through a variable bridge.
2046-
error(
2047-
"Cannot add two `VariableIndex`-in-`$(typeof(s))`",
2048-
" on the same variable $(f).",
2049-
)
2044+
msg = "Cannot add two `VariableIndex`-in-`$S` on the same variable $f."
2045+
throw(MOI.AddConstraintNotAllowed{F,S}(msg))
20502046
end
20512047
BridgeType = Constraint.concrete_bridge_type(
20522048
constraint_scalar_functionize_bridge(b),
2053-
typeof(f),
2054-
typeof(s),
2049+
F,
2050+
S,
20552051
)
20562052
MOI.add_constraint(Variable.bridges(b), f, s)
20572053
return add_bridged_constraint(b, BridgeType, f, s)
20582054
end
2059-
elseif f isa MOI.VectorOfVariables
2055+
elseif F <: MOI.VectorOfVariables
20602056
if any(vi -> is_bridged(b, vi), f.variables)
20612057
BridgeType = Constraint.concrete_bridge_type(
20622058
constraint_vector_functionize_bridge(b),
2063-
typeof(f),
2064-
typeof(s),
2059+
F,
2060+
S,
20652061
)
20662062
return add_bridged_constraint(b, BridgeType, f, s)
20672063
end
20682064
else
20692065
f, s = bridged_constraint_function(b, f, s)
20702066
end
20712067
end
2072-
if is_bridged(b, typeof(f), typeof(s))
2068+
if is_bridged(b, F, S)
20732069
_check_double_single_variable(b, f, s)
20742070
# We compute `BridgeType` first as `concrete_bridge_type` calls
20752071
# `bridge_type` which might throw an `UnsupportedConstraint` error in
20762072
# which case, we do not want any modification to have been done
2077-
BridgeType = Constraint.concrete_bridge_type(b, typeof(f), typeof(s))
2073+
BridgeType = Constraint.concrete_bridge_type(b, F, S)
20782074
# `add_constraint` might throw an `UnsupportedConstraint` but no
20792075
# modification has been done in the previous line
20802076
return add_bridged_constraint(b, BridgeType, f, s)

test/Bridges/Constraint/ComplexNormInfinityToSecondOrderConeBridge.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ function test_imag_t()
5858
f_x = (1.0 + 2.0im) * x[2] + (3.0 + 4.0im)
5959
f = MOI.Utilities.operate(vcat, Complex{Float64}, f_t, f_x)
6060
@test_throws(
61-
ErrorException(
61+
MOI.AddConstraintNotAllowed{typeof(f),MOI.NormInfinityCone}(
6262
"The epigraph variable `t` in `[t; x] in NormInfinityCone()` " *
6363
"must be real. It is: $f_t",
6464
),

test/Bridges/Constraint/IndicatorToMILPBridge.jl

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -306,13 +306,10 @@ function test_runtests_error_not_binary()
306306
model = MOI.Bridges.Constraint.IndicatorToMILP{Int}(inner)
307307
x = MOI.add_variables(model, 2)
308308
MOI.add_constraint(model, x[2], MOI.Interval(0, 4))
309-
c = MOI.add_constraint(
310-
model,
311-
MOI.VectorOfVariables(x),
312-
MOI.Indicator{MOI.ACTIVATE_ON_ZERO}(MOI.GreaterThan(2)),
313-
)
309+
set = MOI.Indicator{MOI.ACTIVATE_ON_ZERO}(MOI.GreaterThan(2))
310+
c = MOI.add_constraint(model, MOI.VectorOfVariables(x), set)
314311
@test_throws(
315-
ErrorException(
312+
MOI.AddConstraintNotAllowed{MOI.VectorOfVariables,typeof(set)}(
316313
"Unable to reformulate indicator constraint to a MILP. The indicator variable must be binary.",
317314
),
318315
MOI.Bridges.final_touch(model),

test/Bridges/Constraint/IntegerToZeroOneBridge.jl

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -78,10 +78,7 @@ function test_finite_domain_error()
7878
model = MOI.Bridges.Constraint.IntegerToZeroOne{Int}(inner)
7979
x, _ = MOI.add_constrained_variable(model, MOI.Integer())
8080
@test_throws(
81-
ErrorException(
82-
"Unable to use IntegerToZeroOneBridge because the variable " *
83-
"$(x) has a non-finite domain",
84-
),
81+
MOI.Bridges.BridgeRequiresFiniteDomainError,
8582
MOI.Bridges.final_touch(model),
8683
)
8784
return

0 commit comments

Comments
 (0)