diff --git a/src/Bridges/Constraint/single_bridge_optimizer.jl b/src/Bridges/Constraint/single_bridge_optimizer.jl index 290144961b..48b1987e1e 100644 --- a/src/Bridges/Constraint/single_bridge_optimizer.jl +++ b/src/Bridges/Constraint/single_bridge_optimizer.jl @@ -44,6 +44,22 @@ function MOIB.is_bridged(b::SingleBridgeOptimizer, S::Type{<:MOI.AbstractSet}) return MOIB.supports_bridging_constrained_variable(b, S) end +MOIB.is_bridged(::SingleBridgeOptimizer, ::MOI.VariableIndex) = false +function MOIB.is_bridged( + b::SingleBridgeOptimizer, + ci::MOI.ConstraintIndex{MOI.SingleVariable,S}, +) where {S} + return MOIB.is_bridged(b, MOI.SingleVariable, S) && + haskey(Constraint.bridges(b), ci) +end +function MOIB.is_bridged( + b::SingleBridgeOptimizer, + ci::MOI.ConstraintIndex{MOI.VectorOfVariables,S}, +) where {S} + return MOIB.is_bridged(b, MOI.VectorOfVariables, S) && + haskey(Constraint.bridges(b), ci) +end + function MOIB.supports_bridging_constrained_variable( b::SingleBridgeOptimizer, S::Type{<:MOI.AbstractSet}, diff --git a/src/Bridges/Objective/single_bridge_optimizer.jl b/src/Bridges/Objective/single_bridge_optimizer.jl index 8762843de7..048c220192 100644 --- a/src/Bridges/Objective/single_bridge_optimizer.jl +++ b/src/Bridges/Objective/single_bridge_optimizer.jl @@ -36,6 +36,20 @@ function MOIB.is_bridged( return false end +MOIB.is_bridged(::SingleBridgeOptimizer, ::MOI.VariableIndex) = false +function MOIB.is_bridged( + ::SingleBridgeOptimizer, + ::MOI.ConstraintIndex{MOI.SingleVariable}, +) + return false +end +function MOIB.is_bridged( + ::SingleBridgeOptimizer, + ::MOI.ConstraintIndex{MOI.VectorOfVariables}, +) + return false +end + function MOIB.supports_bridging_objective_function( ::SingleBridgeOptimizer{BT}, F::Type{<:MOI.AbstractScalarFunction}, diff --git a/test/Bridges/bridge_optimizer.jl b/test/Bridges/bridge_optimizer.jl index 3535bde62e..06d265039c 100644 --- a/test/Bridges/bridge_optimizer.jl +++ b/test/Bridges/bridge_optimizer.jl @@ -539,3 +539,52 @@ end @test all(vi -> !MOI.is_valid(model, vi), x) end end + +function test_nesting_SingleBridgeOptimizer(::Type{T}) where {T} + model = MOIU.Model{T}() + b0 = MOIB.Variable.Free{T}(model) + b1 = MOIB.Constraint.ScalarFunctionize{T}(b0) + b2 = MOIB.Constraint.VectorFunctionize{T}(b1) + b = MOIB.Objective.Functionize{T}(b2) + x = MOI.add_variable(b) + @test MOI.is_valid(b, x) + @test !MOIB.is_bridged(b, x) + @test MOI.is_valid(b2, x) + @test !MOIB.is_bridged(b2, x) + @test MOI.is_valid(b1, x) + @test !MOIB.is_bridged(b1, x) + @test MOI.is_valid(b0, x) + @test MOIB.is_bridged(b0, x) + @test !MOI.is_valid(model, x) + fx = MOI.SingleVariable(x) + clt = MOI.add_constraint(b, fx, MOI.LessThan(one(T))) + @test MOI.is_valid(b, clt) + @test !MOIB.is_bridged(b, clt) + @test MOI.is_valid(b2, clt) + @test !MOIB.is_bridged(b2, clt) + @test MOI.is_valid(b1, clt) + @test MOIB.is_bridged(b1, clt) + @test !MOI.is_valid(b0, clt) + @test !MOI.is_valid(model, clt) + cnn = MOI.add_constraint(b, MOIU.vectorize([fx]), MOI.Nonnegatives(1)) + @test MOI.is_valid(b, cnn) + @test !MOIB.is_bridged(b, cnn) + @test MOI.is_valid(b2, cnn) + @test MOIB.is_bridged(b2, cnn) + @test !MOI.is_valid(b1, cnn) + @test !MOI.is_valid(b0, cnn) + @test !MOI.is_valid(model, cnn) + obj = fx + attr = MOI.ObjectiveFunction{typeof(obj)}() + MOI.set(b, attr, obj) + @test MOIB.is_bridged(b, attr) + obj = one(T) * fx + attr = MOI.ObjectiveFunction{typeof(obj)}() + MOI.set(b, attr, obj) + @test !MOIB.is_bridged(b, attr) + @test !MOIB.is_bridged(b2, attr) + @test !MOIB.is_bridged(b1, attr) + @test !MOIB.is_bridged(b0, attr) +end + +test_nesting_SingleBridgeOptimizer(Float64)