diff --git a/src/Bridges/Constraint/bridges/IndicatorToMILPBridge.jl b/src/Bridges/Constraint/bridges/IndicatorToMILPBridge.jl index c109256e37..bd05ebfe1b 100644 --- a/src/Bridges/Constraint/bridges/IndicatorToMILPBridge.jl +++ b/src/Bridges/Constraint/bridges/IndicatorToMILPBridge.jl @@ -188,6 +188,18 @@ end MOI.Bridges.needs_final_touch(::IndicatorToMILPBridge) = true +function _is_binary(model::MOI.ModelLike, f::MOI.AbstractScalarFunction) + x = convert(MOI.VariableIndex, f) + return _is_binary(model, x) +end + +function _is_binary(model::MOI.ModelLike, x::MOI.VariableIndex) + return MOI.is_valid( + model, + MOI.ConstraintIndex{MOI.VariableIndex,MOI.ZeroOne}(x.value), + ) +end + function MOI.Bridges.final_touch( bridge::IndicatorToMILPBridge{T,F}, model::MOI.ModelLike, @@ -198,6 +210,10 @@ function MOI.Bridges.final_touch( ret = MOI.Utilities.get_bounds(model, bounds, fi) if ret === nothing throw(MOI.Bridges.BridgeRequiresFiniteDomainError(bridge, fi)) + elseif !_is_binary(model, scalars[1]) + error( + "Unable to reformulate indicator constraint to a MILP. The indicator variable must be binary.", + ) end if bridge.slack === nothing # This is the first time calling final_touch diff --git a/test/Bridges/Constraint/IndicatorToMILPBridge.jl b/test/Bridges/Constraint/IndicatorToMILPBridge.jl index 95e7a6bfa5..d29ab62d30 100644 --- a/test/Bridges/Constraint/IndicatorToMILPBridge.jl +++ b/test/Bridges/Constraint/IndicatorToMILPBridge.jl @@ -301,6 +301,25 @@ function test_delete_before_final_touch() return end +function test_runtests_error_not_binary() + inner = MOI.Utilities.Model{Int}() + model = MOI.Bridges.Constraint.IndicatorToMILP{Int}(inner) + x = MOI.add_variables(model, 2) + MOI.add_constraint(model, x[2], MOI.Interval(0, 4)) + c = MOI.add_constraint( + model, + MOI.VectorOfVariables(x), + MOI.Indicator{MOI.ACTIVATE_ON_ZERO}(MOI.GreaterThan(2)), + ) + @test_throws( + ErrorException( + "Unable to reformulate indicator constraint to a MILP. The indicator variable must be binary.", + ), + MOI.Bridges.final_touch(model), + ) + return +end + end # module TestConstraintIndicatorToMILP.runtests()