From 832690103e5d1aab14e61022363e93f27c39fcf5 Mon Sep 17 00:00:00 2001 From: odow Date: Tue, 4 Mar 2025 09:20:52 +1300 Subject: [PATCH 1/2] [Bridges] fix deleting bridges before final touch --- .../Constraint/bridges/IndicatorToMILPBridge.jl | 3 +++ .../Constraint/bridges/SOS1ToMILPBridge.jl | 4 ++++ .../Constraint/bridges/SOS2ToMILPBridge.jl | 3 +++ test/Bridges/Constraint/IndicatorToMILPBridge.jl | 16 ++++++++++++++++ test/Bridges/Constraint/SOS1ToMILPBridge.jl | 15 +++++++++++++++ test/Bridges/Constraint/SOS2ToMILPBridge.jl | 15 +++++++++++++++ 6 files changed, 56 insertions(+) diff --git a/src/Bridges/Constraint/bridges/IndicatorToMILPBridge.jl b/src/Bridges/Constraint/bridges/IndicatorToMILPBridge.jl index e3e5351881..7aeb012c16 100644 --- a/src/Bridges/Constraint/bridges/IndicatorToMILPBridge.jl +++ b/src/Bridges/Constraint/bridges/IndicatorToMILPBridge.jl @@ -126,6 +126,9 @@ function MOI.delete( model::MOI.ModelLike, bridge::IndicatorToMILPBridge{T}, ) where {T} + if bridge.slack === nothing + return # We're deleting the bridge before final_touch + end MOI.delete.(model, bridge.slack_bounds) MOI.delete(model, bridge.constraint) MOI.delete(model, bridge.slack::MOI.VariableIndex) diff --git a/src/Bridges/Constraint/bridges/SOS1ToMILPBridge.jl b/src/Bridges/Constraint/bridges/SOS1ToMILPBridge.jl index fb941a73fb..9b0119e372 100644 --- a/src/Bridges/Constraint/bridges/SOS1ToMILPBridge.jl +++ b/src/Bridges/Constraint/bridges/SOS1ToMILPBridge.jl @@ -116,6 +116,10 @@ function MOI.get(::MOI.ModelLike, ::MOI.ConstraintSet, bridge::SOS1ToMILPBridge) end function MOI.delete(model::MOI.ModelLike, bridge::SOS1ToMILPBridge) + if isempty(bridge.variables) + println("HHello") + return # We're deleting the bridge before final_touch + end MOI.delete(model, bridge.equal_to) for ci in bridge.less_than MOI.delete(model, ci) diff --git a/src/Bridges/Constraint/bridges/SOS2ToMILPBridge.jl b/src/Bridges/Constraint/bridges/SOS2ToMILPBridge.jl index e7931d7012..3d0e07611f 100644 --- a/src/Bridges/Constraint/bridges/SOS2ToMILPBridge.jl +++ b/src/Bridges/Constraint/bridges/SOS2ToMILPBridge.jl @@ -116,6 +116,9 @@ function MOI.get(::MOI.ModelLike, ::MOI.ConstraintSet, bridge::SOS2ToMILPBridge) end function MOI.delete(model::MOI.ModelLike, bridge::SOS2ToMILPBridge) + if isempty(bridge.variables) + return # We're deleting the bridge before final_touch + end MOI.delete(model, bridge.equal_to) for ci in bridge.less_than MOI.delete(model, ci) diff --git a/test/Bridges/Constraint/IndicatorToMILPBridge.jl b/test/Bridges/Constraint/IndicatorToMILPBridge.jl index 3b2093e42d..d7f3a87db6 100644 --- a/test/Bridges/Constraint/IndicatorToMILPBridge.jl +++ b/test/Bridges/Constraint/IndicatorToMILPBridge.jl @@ -288,6 +288,22 @@ function test_runtests_error_affine() return end +function test_delete_before_final_touch() + model = MOI.Bridges.Constraint.IndicatorToMILP{Float64}( + MOI.Utilities.Model{Float64}(), + ) + x = MOI.add_variables(model, 2) + MOI.add_constraint(model, x[1], MOI.ZeroOne()) + c = MOI.add_constraint( + model, + MOI.VectorOfVariables(x), + MOI.Indicator{MOI.ACTIVATE_ON_ZERO}(MOI.GreaterThan(2.0)), + ) + MOI.delete(model, c) + @test !MOI.is_valid(model, c) + return +end + end # module TestConstraintIndicatorToMILP.runtests() diff --git a/test/Bridges/Constraint/SOS1ToMILPBridge.jl b/test/Bridges/Constraint/SOS1ToMILPBridge.jl index a3b4c95a70..b9a774e12a 100644 --- a/test/Bridges/Constraint/SOS1ToMILPBridge.jl +++ b/test/Bridges/Constraint/SOS1ToMILPBridge.jl @@ -119,6 +119,21 @@ function test_runtests_error_affine() return end +function test_delete_before_final_touch() + model = MOI.Bridges.Constraint.SOS1ToMILP{Float64}( + MOI.Utilities.Model{Float64}(), + ) + x = MOI.add_variables(model, 2) + c = MOI.add_constraint( + model, + MOI.VectorOfVariables(x), + MOI.SOS1([1.0, 2.0]), + ) + MOI.delete(model, c) + @test !MOI.is_valid(model, c) + return +end + end # module TestConstraintSOS1ToMILP.runtests() diff --git a/test/Bridges/Constraint/SOS2ToMILPBridge.jl b/test/Bridges/Constraint/SOS2ToMILPBridge.jl index 4327912165..5a62cacbbf 100644 --- a/test/Bridges/Constraint/SOS2ToMILPBridge.jl +++ b/test/Bridges/Constraint/SOS2ToMILPBridge.jl @@ -129,6 +129,21 @@ function test_runtests_error_affine() return end +function test_delete_before_final_touch() + model = MOI.Bridges.Constraint.SOS2ToMILP{Float64}( + MOI.Utilities.Model{Float64}(), + ) + x = MOI.add_variables(model, 2) + c = MOI.add_constraint( + model, + MOI.VectorOfVariables(x), + MOI.SOS2([1.0, 2.0]), + ) + MOI.delete(model, c) + @test !MOI.is_valid(model, c) + return +end + end # module TestConstraintSOS2ToMILP.runtests() From 109cae264f547906c5acc6760765b9372c607dc6 Mon Sep 17 00:00:00 2001 From: odow Date: Tue, 4 Mar 2025 09:23:51 +1300 Subject: [PATCH 2/2] Update --- src/Bridges/Constraint/bridges/SOS1ToMILPBridge.jl | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Bridges/Constraint/bridges/SOS1ToMILPBridge.jl b/src/Bridges/Constraint/bridges/SOS1ToMILPBridge.jl index 9b0119e372..d4df1922ef 100644 --- a/src/Bridges/Constraint/bridges/SOS1ToMILPBridge.jl +++ b/src/Bridges/Constraint/bridges/SOS1ToMILPBridge.jl @@ -117,7 +117,6 @@ end function MOI.delete(model::MOI.ModelLike, bridge::SOS1ToMILPBridge) if isempty(bridge.variables) - println("HHello") return # We're deleting the bridge before final_touch end MOI.delete(model, bridge.equal_to)