From a6596d2780afe55e28b2b83105014b261d15d618 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Legat?= Date: Fri, 15 Dec 2023 00:03:00 +0100 Subject: [PATCH 01/22] [Bridges] Fix ConstraintIndex conflicts between variable and constraint bridges --- src/Bridges/Constraint/map.jl | 16 ++++++++++++++++ src/Bridges/Variable/map.jl | 22 +++++++++++++++++----- src/Bridges/bridge_optimizer.jl | 2 ++ 3 files changed, 35 insertions(+), 5 deletions(-) diff --git a/src/Bridges/Constraint/map.jl b/src/Bridges/Constraint/map.jl index 38cfbb11d7..c78376df7f 100644 --- a/src/Bridges/Constraint/map.jl +++ b/src/Bridges/Constraint/map.jl @@ -280,13 +280,29 @@ Return a new constraint index `ci` and store the mapping `ci => bridge`. """ function add_key_for_bridge end +_ensure_available(::Map, ::Type, ::Type, ::Function) = nothing +function _ensure_available( + map::Map, + F::Type{MOI.VectorOfVariables}, + ::Type{S}, + is_available::Function, +) where {S} + while !is_available(MOI.ConstraintIndex{F,S}(length(map.bridges) + 1)) + push!(map.bridges, nothing) + push!(map.constraint_types, (F, S)) + end + return +end + function add_key_for_bridge( map::Map, bridge::AbstractBridge, ::F, ::S, + is_available::Function, ) where {F<:MOI.AbstractFunction,S<:MOI.AbstractSet} _register_for_final_touch(map, bridge) + _ensure_available(map, F, S, is_available) push!(map.bridges, bridge) push!(map.constraint_types, (F, S)) return _index(length(map.bridges), F, S) diff --git a/src/Bridges/Variable/map.jl b/src/Bridges/Variable/map.jl index 7b9e98adb0..26782c88c4 100644 --- a/src/Bridges/Variable/map.jl +++ b/src/Bridges/Variable/map.jl @@ -36,6 +36,10 @@ mutable struct Map <: AbstractDict{MOI.VariableIndex,AbstractBridge} current_context::Int64 # Context of constraint bridged by constraint bridges constraint_context::Dict{MOI.ConstraintIndex,Int64} + # `(ci::ConstraintIndex{MOI.VectorOfVariables}).value` -> + # the first variable index + # and `0` if it is the index of a constraint bridge + vector_of_variables_map::Vector{Int64} end function Map() @@ -48,6 +52,7 @@ function Map() Int64[], 0, Dict{MOI.ConstraintIndex,Int64}(), + Int64[], ) end @@ -76,6 +81,7 @@ function Base.empty!(map::Map) empty!(map.parent_index) map.current_context = 0 empty!(map.constraint_context) + empty!(map.vector_of_variables_map) return map end @@ -350,6 +356,7 @@ function add_keys_for_bridge( map::Map, bridge_fun::Function, set::MOI.AbstractVectorSet, + is_available::Function, ) if iszero(MOI.dimension(set)) return MOI.VariableIndex[], @@ -386,9 +393,13 @@ function add_keys_for_bridge( end end end - index = first(variables).value - return variables, - MOI.ConstraintIndex{MOI.VectorOfVariables,typeof(set)}(index) + F = MOI.VectorOfVariables + S = typeof(set) + while !is_available(MOI.ConstraintIndex{F,S}(-length(map.vector_of_variables_map) - 1)) + push!(map.vector_of_variables_map, 0) + end + push!(map.vector_of_variables_map, first(variables).value) + return variables, MOI.ConstraintIndex{F,S}(-length(map.vector_of_variables_map)) end """ @@ -408,12 +419,13 @@ Return `MOI.VectorOfVariables(vis)` where `vis` is the vector of bridged variables corresponding to `ci`. """ function function_for(map::Map, ci::MOI.ConstraintIndex{MOI.VectorOfVariables}) + index = map.vector_of_variables_map[ci] variables = MOI.VariableIndex[] - for i in ci.value:-1:-length(map.bridges) + for i in index:-1:-length(map.bridges) vi = MOI.VariableIndex(i) if map.index_in_vector[-vi.value] == -1 continue - elseif bridge_index(map, vi) == -ci.value + elseif bridge_index(map, vi) == -index push!(variables, vi) else break diff --git a/src/Bridges/bridge_optimizer.jl b/src/Bridges/bridge_optimizer.jl index e0100e6344..34b7ddd666 100644 --- a/src/Bridges/bridge_optimizer.jl +++ b/src/Bridges/bridge_optimizer.jl @@ -1721,6 +1721,7 @@ function add_bridged_constraint(b, BridgeType, f, s) bridge, f, s, + Base.Fix1(haskey, Variable.bridges(b)), ) Variable.register_context(Variable.bridges(b), ci) return ci @@ -2000,6 +2001,7 @@ function MOI.add_constrained_variables( Variable.bridges(b)::Variable.Map, () -> Variable.bridge_constrained_variable(BridgeType, b, set), set, + Base.Fix1(haskey, Constraint.bridges(b)), ) else variables = MOI.add_variables(b, MOI.dimension(set)) From 378f811437238a330e748d3b689705fd5d30da76 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Legat?= Date: Sat, 16 Dec 2023 12:12:18 +0100 Subject: [PATCH 02/22] Fixes --- src/Bridges/Variable/map.jl | 7 +++++-- src/Bridges/bridge_optimizer.jl | 4 ++-- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/Bridges/Variable/map.jl b/src/Bridges/Variable/map.jl index 26782c88c4..4023807cf8 100644 --- a/src/Bridges/Variable/map.jl +++ b/src/Bridges/Variable/map.jl @@ -395,11 +395,14 @@ function add_keys_for_bridge( end F = MOI.VectorOfVariables S = typeof(set) - while !is_available(MOI.ConstraintIndex{F,S}(-length(map.vector_of_variables_map) - 1)) + while !is_available( + MOI.ConstraintIndex{F,S}(-length(map.vector_of_variables_map) - 1), + ) push!(map.vector_of_variables_map, 0) end push!(map.vector_of_variables_map, first(variables).value) - return variables, MOI.ConstraintIndex{F,S}(-length(map.vector_of_variables_map)) + return variables, + MOI.ConstraintIndex{F,S}(-length(map.vector_of_variables_map)) end """ diff --git a/src/Bridges/bridge_optimizer.jl b/src/Bridges/bridge_optimizer.jl index 34b7ddd666..e7b9448da8 100644 --- a/src/Bridges/bridge_optimizer.jl +++ b/src/Bridges/bridge_optimizer.jl @@ -1721,7 +1721,7 @@ function add_bridged_constraint(b, BridgeType, f, s) bridge, f, s, - Base.Fix1(haskey, Variable.bridges(b)), + !Base.Fix1(haskey, Variable.bridges(b)), ) Variable.register_context(Variable.bridges(b), ci) return ci @@ -2001,7 +2001,7 @@ function MOI.add_constrained_variables( Variable.bridges(b)::Variable.Map, () -> Variable.bridge_constrained_variable(BridgeType, b, set), set, - Base.Fix1(haskey, Constraint.bridges(b)), + !Base.Fix1(haskey, Constraint.bridges(b)), ) else variables = MOI.add_variables(b, MOI.dimension(set)) From 011b80bd40a7b5250c9c7d7dcd047062b0d8f41d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Legat?= Date: Sat, 16 Dec 2023 18:42:21 +0100 Subject: [PATCH 03/22] Fix --- src/Bridges/Constraint/map.jl | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Bridges/Constraint/map.jl b/src/Bridges/Constraint/map.jl index c78376df7f..8ba3152d44 100644 --- a/src/Bridges/Constraint/map.jl +++ b/src/Bridges/Constraint/map.jl @@ -274,6 +274,7 @@ end bridge::AbstractBridge, func::MOI.AbstractFunction, set::MOI.AbstractSet, + is_available::Function, ) Return a new constraint index `ci` and store the mapping `ci => bridge`. @@ -313,6 +314,7 @@ function add_key_for_bridge( bridge::AbstractBridge, func::MOI.VariableIndex, ::S, + ::Function, ) where {S<:MOI.AbstractScalarSet} _register_for_final_touch(map, bridge) map.single_variable_constraints[(func.value, S)] = bridge From 7466479926495996c72cdcbe882fd0b37488c493 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Legat?= Date: Sat, 16 Dec 2023 21:22:44 +0100 Subject: [PATCH 04/22] Fixes --- src/Bridges/Variable/map.jl | 44 ++++++++++++++++++++++------------ test/Bridges/Constraint/map.jl | 10 +++++++- test/Bridges/Variable/map.jl | 17 ++++++++++--- 3 files changed, 52 insertions(+), 19 deletions(-) diff --git a/src/Bridges/Variable/map.jl b/src/Bridges/Variable/map.jl index 4023807cf8..330a269fed 100644 --- a/src/Bridges/Variable/map.jl +++ b/src/Bridges/Variable/map.jl @@ -40,6 +40,9 @@ mutable struct Map <: AbstractDict{MOI.VariableIndex,AbstractBridge} # the first variable index # and `0` if it is the index of a constraint bridge vector_of_variables_map::Vector{Int64} + # `(ci::ConstraintIndex{MOI.VectorOfVariables}).value` -> + # the dimension of the set + vector_of_variables_length::Vector{Int64} end function Map() @@ -53,6 +56,7 @@ function Map() 0, Dict{MOI.ConstraintIndex,Int64}(), Int64[], + Int64[], ) end @@ -82,6 +86,7 @@ function Base.empty!(map::Map) map.current_context = 0 empty!(map.constraint_context) empty!(map.vector_of_variables_map) + empty!(map.vector_of_variables_length) return map end @@ -114,7 +119,7 @@ function Base.delete!(map::Map, vi::MOI.VariableIndex) delete!(map, [vi]) else # Delete variable in vector and resize vector - map.info[bridge_index(map, vi)] += 1 + map.vector_of_variables_length[-map.info[bridge_index(map, vi)]] -= 1 for i in (-vi.value):length(map.index_in_vector) if map.index_in_vector[i] == -1 continue @@ -213,10 +218,17 @@ function number_with_set(map::Map, S::Type{<:MOI.AbstractSet}) return count(isequal(S), map.sets) end +_constraint + function constraint(map::Map, vi::MOI.VariableIndex) S = constrained_set(map, vi)::Type{<:MOI.AbstractSet} F = MOI.Utilities.variable_function_type(S) - return MOI.ConstraintIndex{F,S}(-bridge_index(map, vi)) + index = bridge_index(map, vi) + constraint_index = map.info[index] + if iszero(constraint_index) + constraint_index = -index + end + return MOI.ConstraintIndex{F,S}(constraint_index) end """ @@ -226,8 +238,8 @@ Return the list of constraints corresponding to bridged variables in `S`. """ function constraints_with_set(map::Map, S::Type{<:MOI.AbstractSet}) F = MOI.Utilities.variable_function_type(S) - return [ - MOI.ConstraintIndex{F,S}(-i) for + return MOI.ConstraintIndex{F,S}[ + constraint(map, MOI.VariableIndex(-i)) for i in eachindex(map.sets) if map.sets[i] == S ] end @@ -278,7 +290,7 @@ If `vi` was bridged in a scalar set, it returns 0. Otherwise, it returns the dimension of the set. """ function length_of_vector_of_variables(map::Map, vi::MOI.VariableIndex) - return -map.info[bridge_index(map, vi)] + return map.vector_of_variables_length[-map.info[bridge_index(map, vi)]] end """ @@ -364,7 +376,17 @@ function add_keys_for_bridge( end push!(map.parent_index, map.current_context) bridge_index = Int64(length(map.parent_index)) - push!(map.info, -MOI.dimension(set)) + F = MOI.VectorOfVariables + S = typeof(set) + while !is_available( + MOI.ConstraintIndex{F,S}(-length(map.vector_of_variables_map) - 1), + ) + push!(map.vector_of_variables_map, 0) + push!(map.vector_of_variables_length, 0) + end + push!(map.vector_of_variables_map, -bridge_index) + push!(map.vector_of_variables_length, MOI.dimension(set)) + push!(map.info, -length(map.vector_of_variables_length)) push!(map.index_in_vector, 1) push!(map.bridges, nothing) push!(map.sets, typeof(set)) @@ -393,14 +415,6 @@ function add_keys_for_bridge( end end end - F = MOI.VectorOfVariables - S = typeof(set) - while !is_available( - MOI.ConstraintIndex{F,S}(-length(map.vector_of_variables_map) - 1), - ) - push!(map.vector_of_variables_map, 0) - end - push!(map.vector_of_variables_map, first(variables).value) return variables, MOI.ConstraintIndex{F,S}(-length(map.vector_of_variables_map)) end @@ -422,7 +436,7 @@ Return `MOI.VectorOfVariables(vis)` where `vis` is the vector of bridged variables corresponding to `ci`. """ function function_for(map::Map, ci::MOI.ConstraintIndex{MOI.VectorOfVariables}) - index = map.vector_of_variables_map[ci] + index = map.vector_of_variables_map[-ci.value] variables = MOI.VariableIndex[] for i in index:-1:-length(map.bridges) vi = MOI.VariableIndex(i) diff --git a/test/Bridges/Constraint/map.jl b/test/Bridges/Constraint/map.jl index 3671259c47..26df06122b 100644 --- a/test/Bridges/Constraint/map.jl +++ b/test/Bridges/Constraint/map.jl @@ -34,7 +34,13 @@ function test_map() x = MOI.VariableIndex(1) y = MOI.VariableIndex(2) b1 = ConstraintDummyBridge(1) - c1 = MOI.Bridges.Constraint.add_key_for_bridge(map, b1, x, MOI.EqualTo(0.0)) + c1 = MOI.Bridges.Constraint.add_key_for_bridge( + map, + b1, + x, + MOI.EqualTo(0.0), + ci -> true, + ) @test c1.value == x.value @test haskey(map, c1) @@ -53,6 +59,7 @@ function test_map() b2, vov, MOI.SecondOrderCone(2), + ci -> true, ) @test c2.value == -1 @test haskey(map, c2) @@ -70,6 +77,7 @@ function test_map() b3, 1.0x + 2.0, MOI.EqualTo(0.0), + ci -> true, ) @test haskey(map, c3) @test map[c3] == b3 diff --git a/test/Bridges/Variable/map.jl b/test/Bridges/Variable/map.jl index be2d67f848..a2c664f602 100644 --- a/test/Bridges/Variable/map.jl +++ b/test/Bridges/Variable/map.jl @@ -82,8 +82,14 @@ function test_map() set2 = MOI.Zeros(4) F2 = MOI.VectorOfVariables S2 = typeof(set2) - v2, c2 = MOI.Bridges.Variable.add_keys_for_bridge(map, () -> b2, set2) - @test v2[1].value == c2.value == -2 + v2, c2 = MOI.Bridges.Variable.add_keys_for_bridge( + map, + () -> b2, + set2, + ci -> true, + ) + @test v2[1].value == -2 + @test c2.value == -1 @test MOI.Bridges.Variable.has_keys(map, v2) @test !MOI.Bridges.Variable.has_keys(map, v2[4:-1:1]) for i in 1:4 @@ -117,7 +123,12 @@ function test_map() b3 = VariableDummyBridge(3) set3 = MOI.Zeros(0) - v3, c3 = MOI.Bridges.Variable.add_keys_for_bridge(map, () -> b3, set3) + v3, c3 = MOI.Bridges.Variable.add_keys_for_bridge( + map, + () -> b3, + set3, + ci -> true, + ) @test isempty(v3) @test c3.value == 0 From 84a0d9ba6a36c15a7bbc360a153c22a71195dfae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Legat?= Date: Sun, 17 Dec 2023 19:08:02 +0100 Subject: [PATCH 05/22] Fix --- src/Bridges/Variable/map.jl | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/Bridges/Variable/map.jl b/src/Bridges/Variable/map.jl index 330a269fed..09e1138c83 100644 --- a/src/Bridges/Variable/map.jl +++ b/src/Bridges/Variable/map.jl @@ -218,8 +218,6 @@ function number_with_set(map::Map, S::Type{<:MOI.AbstractSet}) return count(isequal(S), map.sets) end -_constraint - function constraint(map::Map, vi::MOI.VariableIndex) S = constrained_set(map, vi)::Type{<:MOI.AbstractSet} F = MOI.Utilities.variable_function_type(S) From 9a9c0df3501bfafee6f4ad48d2fff2193d492457 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Legat?= Date: Sun, 17 Dec 2023 22:22:35 +0100 Subject: [PATCH 06/22] Fixes --- src/Bridges/Variable/map.jl | 7 ++++++- test/Bridges/Variable/map.jl | 1 + 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/Bridges/Variable/map.jl b/src/Bridges/Variable/map.jl index 09e1138c83..4ac41f2b26 100644 --- a/src/Bridges/Variable/map.jl +++ b/src/Bridges/Variable/map.jl @@ -288,7 +288,12 @@ If `vi` was bridged in a scalar set, it returns 0. Otherwise, it returns the dimension of the set. """ function length_of_vector_of_variables(map::Map, vi::MOI.VariableIndex) - return map.vector_of_variables_length[-map.info[bridge_index(map, vi)]] + info = map.info[bridge_index(map, vi)] + if iszero(info) + return 0 + else + return map.vector_of_variables_length[-info] + end end """ diff --git a/test/Bridges/Variable/map.jl b/test/Bridges/Variable/map.jl index a2c664f602..d02c689ebd 100644 --- a/test/Bridges/Variable/map.jl +++ b/test/Bridges/Variable/map.jl @@ -59,6 +59,7 @@ function test_map() ) @test v1.value == c1.value == -1 @test MOI.Bridges.Variable.constraint(map, v1) == c1 + @test MOI.Bridges.Variable.length_of_vector_of_variables(map, v1) == 0 @test haskey(map, v1) @test map[v1] == b1 @test MOI.Bridges.Variable.constrained_set(map, v1) == S1 From 1c84c46a7f821f009463cc4721bd2118ec1de871 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Legat?= Date: Sun, 17 Dec 2023 23:13:56 +0100 Subject: [PATCH 07/22] Fixes --- src/Bridges/Variable/map.jl | 14 ++++++++++++++ src/Bridges/bridge_optimizer.jl | 2 +- test/Bridges/Variable/map.jl | 2 ++ test/Bridges/lazy_bridge_optimizer.jl | 16 ++++++++++++++++ 4 files changed, 33 insertions(+), 1 deletion(-) diff --git a/src/Bridges/Variable/map.jl b/src/Bridges/Variable/map.jl index 4ac41f2b26..db95915554 100644 --- a/src/Bridges/Variable/map.jl +++ b/src/Bridges/Variable/map.jl @@ -229,6 +229,20 @@ function constraint(map::Map, vi::MOI.VariableIndex) return MOI.ConstraintIndex{F,S}(constraint_index) end +function MOI.is_valid(map::Map, ci::MOI.ConstraintIndex{MOI.VectorOfVariables,S}) where {S} + if !(-ci.value in eachindex(map.vector_of_variables_map)) + return false + end + index = -map.vector_of_variables_map[-ci.value] + return index in eachindex(map.bridges) && !isnothing(map.bridges[index]) && map.sets[index] === S +end + +function MOI.is_valid(map::Map, ci::MOI.ConstraintIndex{MOI.VariableIndex,S}) where {S} + index = -ci.value + return index in eachindex(map.bridges) && !isnothing(map.bridges[index]) && map.sets[index] === S +end + + """ constraints_with_set(map::Map, S::Type{<:MOI.AbstractSet}) diff --git a/src/Bridges/bridge_optimizer.jl b/src/Bridges/bridge_optimizer.jl index e7b9448da8..1ef369b881 100644 --- a/src/Bridges/bridge_optimizer.jl +++ b/src/Bridges/bridge_optimizer.jl @@ -1721,7 +1721,7 @@ function add_bridged_constraint(b, BridgeType, f, s) bridge, f, s, - !Base.Fix1(haskey, Variable.bridges(b)), + !Base.Fix1(MOI.is_valid, Variable.bridges(b)), ) Variable.register_context(Variable.bridges(b), ci) return ci diff --git a/test/Bridges/Variable/map.jl b/test/Bridges/Variable/map.jl index d02c689ebd..a2a7064cde 100644 --- a/test/Bridges/Variable/map.jl +++ b/test/Bridges/Variable/map.jl @@ -53,6 +53,7 @@ function test_map() F1 = MOI.VariableIndex S1 = typeof(set1) v1, c1 = MOI.Bridges.Variable.add_key_for_bridge(map, () -> b1, set1) + MOI.is_valid(map, c1) cannot_unbridge_err = ErrorException( "Cannot unbridge function because some variables are bridged by variable" * " bridges that do not support reverse mapping, e.g., `ZerosBridge`.", @@ -89,6 +90,7 @@ function test_map() set2, ci -> true, ) + MOI.is_valid(map, c2) @test v2[1].value == -2 @test c2.value == -1 @test MOI.Bridges.Variable.has_keys(map, v2) diff --git a/test/Bridges/lazy_bridge_optimizer.jl b/test/Bridges/lazy_bridge_optimizer.jl index 8c27bd80f9..57ce1f38c3 100644 --- a/test/Bridges/lazy_bridge_optimizer.jl +++ b/test/Bridges/lazy_bridge_optimizer.jl @@ -332,6 +332,22 @@ function test_MOI_runtests_GeometricSDPAModel() return end +function test_index_conflict() + optimizer = StandardSDPAModel{Float64}() + model = MOI.Bridges.full_bridge_optimizer(optimizer, Float64) + x, cx = MOI.add_constrained_variables(model, MOI.Nonpositives(1)) + @test MOI.is_valid(model, x[1]) + @test MOI.is_valid(model, cx) + y, cy = MOI.add_constrained_variables(model, MOI.Nonpositives(1)) + @test MOI.is_valid(model, y[1]) + @test MOI.is_valid(model, cy) + c = MOI.add_constraint(model, MOI.VectorOfVariables(y), MOI.Nonpositives(1)) + MOI.is_valid(model, c) + b1 = MOI.Bridges.bridge(model, c) + b2 = MOI.Bridges.bridge(model, b1.constraint) + @test c != b2.slack_in_set +end + function test_show_SPDA() model = StandardSDPAModel{Float64}() model_str = sprint(MOI.Utilities.print_with_acronym, string(typeof(model))) From be707aa2989990296f1c1055864e352ed9787ae7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Legat?= Date: Mon, 18 Dec 2023 15:22:02 +0100 Subject: [PATCH 08/22] Fixes --- src/Bridges/Constraint/map.jl | 2 +- src/Bridges/Variable/map.jl | 19 ++++++++++++++----- 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/src/Bridges/Constraint/map.jl b/src/Bridges/Constraint/map.jl index 8ba3152d44..c2bd084868 100644 --- a/src/Bridges/Constraint/map.jl +++ b/src/Bridges/Constraint/map.jl @@ -288,7 +288,7 @@ function _ensure_available( ::Type{S}, is_available::Function, ) where {S} - while !is_available(MOI.ConstraintIndex{F,S}(length(map.bridges) + 1)) + while !is_available(MOI.ConstraintIndex{F,S}(-length(map.bridges) - 1)) push!(map.bridges, nothing) push!(map.constraint_types, (F, S)) end diff --git a/src/Bridges/Variable/map.jl b/src/Bridges/Variable/map.jl index db95915554..7c4dd2344e 100644 --- a/src/Bridges/Variable/map.jl +++ b/src/Bridges/Variable/map.jl @@ -229,20 +229,29 @@ function constraint(map::Map, vi::MOI.VariableIndex) return MOI.ConstraintIndex{F,S}(constraint_index) end -function MOI.is_valid(map::Map, ci::MOI.ConstraintIndex{MOI.VectorOfVariables,S}) where {S} +function MOI.is_valid( + map::Map, + ci::MOI.ConstraintIndex{MOI.VectorOfVariables,S}, +) where {S} if !(-ci.value in eachindex(map.vector_of_variables_map)) return false end index = -map.vector_of_variables_map[-ci.value] - return index in eachindex(map.bridges) && !isnothing(map.bridges[index]) && map.sets[index] === S + return index in eachindex(map.bridges) && + !isnothing(map.bridges[index]) && + map.sets[index] === S end -function MOI.is_valid(map::Map, ci::MOI.ConstraintIndex{MOI.VariableIndex,S}) where {S} +function MOI.is_valid( + map::Map, + ci::MOI.ConstraintIndex{MOI.VariableIndex,S}, +) where {S} index = -ci.value - return index in eachindex(map.bridges) && !isnothing(map.bridges[index]) && map.sets[index] === S + return index in eachindex(map.bridges) && + !isnothing(map.bridges[index]) && + map.sets[index] === S end - """ constraints_with_set(map::Map, S::Type{<:MOI.AbstractSet}) From 49071cdcfa27f4ef4461480765242e45d04991a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Legat?= Date: Tue, 19 Dec 2023 11:44:41 +0100 Subject: [PATCH 09/22] Fixes --- src/Bridges/Variable/map.jl | 2 ++ test/Bridges/Variable/map.jl | 4 ++++ 2 files changed, 6 insertions(+) diff --git a/src/Bridges/Variable/map.jl b/src/Bridges/Variable/map.jl index 7c4dd2344e..080718a117 100644 --- a/src/Bridges/Variable/map.jl +++ b/src/Bridges/Variable/map.jl @@ -610,3 +610,5 @@ end register_context(::EmptyMap, ::MOI.ConstraintIndex) = nothing call_in_context(::EmptyMap, ::MOI.ConstraintIndex, f::Function) = f() + +MOI.is_valid(::EmptyMap, ::MOI.ConstraintIndex) = false diff --git a/test/Bridges/Variable/map.jl b/test/Bridges/Variable/map.jl index a2a7064cde..249fa6099c 100644 --- a/test/Bridges/Variable/map.jl +++ b/test/Bridges/Variable/map.jl @@ -271,6 +271,10 @@ function test_EmptyMap() @test iszero(MOI.Bridges.Variable.number_with_set(map, S2)) @test isempty(MOI.Bridges.Variable.constraints_with_set(map, S1)) @test isempty(MOI.Bridges.Variable.constraints_with_set(map, S2)) + c1 = MOI.ConstraintIndex{MOI.VariableIndex,S1}(1) + @test !MOI.is_valid(map, c1) + c2 = MOI.ConstraintIndex{MOI.VectorOfVariables,S2}(1) + @test !MOI.is_valid(map, c2) @test sprint(show, map) == "" return end From fbb81fc688a7e0bdc9d703402776c6401398956d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Legat?= Date: Tue, 19 Dec 2023 11:54:08 +0100 Subject: [PATCH 10/22] Add doc --- src/Bridges/Constraint/map.jl | 3 +++ src/Bridges/Variable/map.jl | 13 +++++++++---- src/Bridges/bridge_optimizer.jl | 10 ++++++++++ 3 files changed, 22 insertions(+), 4 deletions(-) diff --git a/src/Bridges/Constraint/map.jl b/src/Bridges/Constraint/map.jl index c2bd084868..9f6a179db2 100644 --- a/src/Bridges/Constraint/map.jl +++ b/src/Bridges/Constraint/map.jl @@ -278,6 +278,9 @@ end ) Return a new constraint index `ci` and store the mapping `ci => bridge`. +If `func isa MOI.VectorOfVariables` then `ci` is such that `is_available(ci)`, +otherwise, `is_available` is ignored because there can only be a clash of +indices between variable and constraint bridge mapping for `MOI.VectorOfVariables`. """ function add_key_for_bridge end diff --git a/src/Bridges/Variable/map.jl b/src/Bridges/Variable/map.jl index 080718a117..9a9c1418c7 100644 --- a/src/Bridges/Variable/map.jl +++ b/src/Bridges/Variable/map.jl @@ -382,13 +382,18 @@ function add_key_for_bridge( end """ - add_keys_for_bridge(map::Map, bridge_fun::Function, - set::MOI.AbstractVectorSet) + function add_keys_for_bridge( + map::Map, + bridge_fun::Function, + set::MOI.AbstractVectorSet, + is_available::Function, + ) Create vector of variable indices `variables`, stores the mapping `vi => bridge` for each `vi ∈ variables` and associate `variables` to -`typeof(set)`. It returns a tuple with `variables` and the constraint index -`MOI.ConstraintIndex{MOI.VectorOfVariables, typeof(set)}(first(variables).value)`. +`typeof(set)`. It returns a tuple with `variables` and a constraint index +`ci::MOI.ConstraintIndex{MOI.VectorOfVariables, typeof(set)}` such that +`is_available(ci)`. """ function add_keys_for_bridge( map::Map, diff --git a/src/Bridges/bridge_optimizer.jl b/src/Bridges/bridge_optimizer.jl index 1ef369b881..bfb4a6e064 100644 --- a/src/Bridges/bridge_optimizer.jl +++ b/src/Bridges/bridge_optimizer.jl @@ -1716,6 +1716,11 @@ end function add_bridged_constraint(b, BridgeType, f, s) bridge = Constraint.bridge_constraint(BridgeType, recursive_model(b), f, s) + # `MOI.VectorOfVariables` constraint indices have negative indices + # to distinguish between the indices of the inner model. + # However, they can clash between the indices created by the variable + # so we use the last argument to inform the constraint bridge mapping about + # indices already taken by variable bridges. ci = Constraint.add_key_for_bridge( Constraint.bridges(b)::Constraint.Map, bridge, @@ -1997,6 +2002,11 @@ function MOI.add_constrained_variables( end if set isa MOI.Reals || is_variable_bridged(b, typeof(set)) BridgeType = Variable.concrete_bridge_type(b, typeof(set)) + # `MOI.VectorOfVariables` constraint indices have negative indices + # to distinguish between the indices of the inner model. + # However, they can clash between the indices created by the variable + # so we use the last argument to inform the variable bridge mapping about + # indices already taken by constraint bridges. return Variable.add_keys_for_bridge( Variable.bridges(b)::Variable.Map, () -> Variable.bridge_constrained_variable(BridgeType, b, set), From 215ca47ca0b11d1d1372b183dff0dad050eff095 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Legat?= Date: Wed, 20 Dec 2023 09:39:29 +0100 Subject: [PATCH 11/22] Update src/Bridges/Variable/map.jl Co-authored-by: Oscar Dowson --- src/Bridges/Variable/map.jl | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Bridges/Variable/map.jl b/src/Bridges/Variable/map.jl index 9a9c1418c7..0760f8cd41 100644 --- a/src/Bridges/Variable/map.jl +++ b/src/Bridges/Variable/map.jl @@ -408,7 +408,6 @@ function add_keys_for_bridge( push!(map.parent_index, map.current_context) bridge_index = Int64(length(map.parent_index)) F = MOI.VectorOfVariables - S = typeof(set) while !is_available( MOI.ConstraintIndex{F,S}(-length(map.vector_of_variables_map) - 1), ) From fbe5a73efe5ba6f6ee10cf61df2bd49184ca4458 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Legat?= Date: Wed, 20 Dec 2023 09:39:37 +0100 Subject: [PATCH 12/22] Update src/Bridges/Variable/map.jl Co-authored-by: Oscar Dowson --- src/Bridges/Variable/map.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Bridges/Variable/map.jl b/src/Bridges/Variable/map.jl index 0760f8cd41..f8a69cb6cc 100644 --- a/src/Bridges/Variable/map.jl +++ b/src/Bridges/Variable/map.jl @@ -400,7 +400,7 @@ function add_keys_for_bridge( bridge_fun::Function, set::MOI.AbstractVectorSet, is_available::Function, -) +) where {S<:MOI.AbstractVectorSet} if iszero(MOI.dimension(set)) return MOI.VariableIndex[], MOI.ConstraintIndex{MOI.VectorOfVariables,typeof(set)}(0) From c83c215a2dd20b0a0ff479f8b441676e0f90df53 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Legat?= Date: Wed, 20 Dec 2023 09:39:45 +0100 Subject: [PATCH 13/22] Update src/Bridges/Variable/map.jl Co-authored-by: Oscar Dowson --- src/Bridges/Variable/map.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Bridges/Variable/map.jl b/src/Bridges/Variable/map.jl index f8a69cb6cc..4925f4f1ce 100644 --- a/src/Bridges/Variable/map.jl +++ b/src/Bridges/Variable/map.jl @@ -398,7 +398,7 @@ Create vector of variable indices `variables`, stores the mapping function add_keys_for_bridge( map::Map, bridge_fun::Function, - set::MOI.AbstractVectorSet, + set::S, is_available::Function, ) where {S<:MOI.AbstractVectorSet} if iszero(MOI.dimension(set)) From 0c5091858d0fe46fff3800ca77155ddd78ac4a78 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Legat?= Date: Wed, 20 Dec 2023 09:42:44 +0100 Subject: [PATCH 14/22] Add doc --- src/Bridges/Variable/map.jl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Bridges/Variable/map.jl b/src/Bridges/Variable/map.jl index 4925f4f1ce..5ab978fd58 100644 --- a/src/Bridges/Variable/map.jl +++ b/src/Bridges/Variable/map.jl @@ -13,7 +13,8 @@ mutable struct Map <: AbstractDict{MOI.VariableIndex,AbstractBridge} # Bridged constrained variables # `i` -> `0`: `VariableIndex(-i)` was added with `add_constrained_variable`. # `i` -> `-j`: `VariableIndex(-i)` was the first variable of - # `add_constrained_variables` with a set of dimension `j`. + # `add_constrained_variables` with a + # `ConstraintIndex{MOI.VectorOfVariables}(-j)`. # `i` -> `j`: `VariableIndex(-i)` was the `j`th variable of # ` add_constrained_variables`. info::Vector{Int64} From 46be39a9ef61a34d0531c9982b1971ea301c0978 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Legat?= Date: Wed, 20 Dec 2023 10:07:07 +0100 Subject: [PATCH 15/22] Add test and fix bug --- src/Bridges/Variable/map.jl | 6 +++--- test/Bridges/lazy_bridge_optimizer.jl | 18 +++++++++++++++++- 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/src/Bridges/Variable/map.jl b/src/Bridges/Variable/map.jl index 5ab978fd58..a93cb69987 100644 --- a/src/Bridges/Variable/map.jl +++ b/src/Bridges/Variable/map.jl @@ -417,7 +417,8 @@ function add_keys_for_bridge( end push!(map.vector_of_variables_map, -bridge_index) push!(map.vector_of_variables_length, MOI.dimension(set)) - push!(map.info, -length(map.vector_of_variables_length)) + constraint_index = -length(map.vector_of_variables_map) + push!(map.info, constraint_index) push!(map.index_in_vector, 1) push!(map.bridges, nothing) push!(map.sets, typeof(set)) @@ -446,8 +447,7 @@ function add_keys_for_bridge( end end end - return variables, - MOI.ConstraintIndex{F,S}(-length(map.vector_of_variables_map)) + return variables, MOI.ConstraintIndex{F,S}(constraint_index) end """ diff --git a/test/Bridges/lazy_bridge_optimizer.jl b/test/Bridges/lazy_bridge_optimizer.jl index 57ce1f38c3..69c094a29d 100644 --- a/test/Bridges/lazy_bridge_optimizer.jl +++ b/test/Bridges/lazy_bridge_optimizer.jl @@ -332,7 +332,7 @@ function test_MOI_runtests_GeometricSDPAModel() return end -function test_index_conflict() +function test_index_constraint_conflict() optimizer = StandardSDPAModel{Float64}() model = MOI.Bridges.full_bridge_optimizer(optimizer, Float64) x, cx = MOI.add_constrained_variables(model, MOI.Nonpositives(1)) @@ -348,6 +348,22 @@ function test_index_conflict() @test c != b2.slack_in_set end +function test_index_variable_conflict() + optimizer = StandardSDPAModel{Float64}() + model = MOI.Bridges.full_bridge_optimizer(optimizer, Float64) + set = MOI.SecondOrderCone(3) + x = MOI.add_variables(model, 3) + c = MOI.add_constraint(model, MOI.VectorOfVariables(x), set) + @test MOI.is_valid(model, c) + y, cy = MOI.add_constrained_variables(model, set) + @test MOI.is_valid(model, cy) + @test cy != c + z, cz = MOI.add_constrained_variables(model, set) + @test MOI.is_valid(model, cz) + @test cz != c +end + + function test_show_SPDA() model = StandardSDPAModel{Float64}() model_str = sprint(MOI.Utilities.print_with_acronym, string(typeof(model))) From d1d6b1e703017576f7a6907a52e8ad2649965f22 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Legat?= Date: Wed, 20 Dec 2023 10:14:48 +0100 Subject: [PATCH 16/22] Fix format --- test/Bridges/lazy_bridge_optimizer.jl | 1 - 1 file changed, 1 deletion(-) diff --git a/test/Bridges/lazy_bridge_optimizer.jl b/test/Bridges/lazy_bridge_optimizer.jl index 69c094a29d..db5d0005bb 100644 --- a/test/Bridges/lazy_bridge_optimizer.jl +++ b/test/Bridges/lazy_bridge_optimizer.jl @@ -363,7 +363,6 @@ function test_index_variable_conflict() @test cz != c end - function test_show_SPDA() model = StandardSDPAModel{Float64}() model_str = sprint(MOI.Utilities.print_with_acronym, string(typeof(model))) From 162e3631dcfbcb39155f6a07466f9115eaf0ebd7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Legat?= Date: Wed, 20 Dec 2023 14:25:09 +0100 Subject: [PATCH 17/22] Add first_variable to fix bugs --- src/Bridges/Variable/map.jl | 8 ++++++++ src/Bridges/bridge_optimizer.jl | 10 +++++----- test/Bridges/bridge_optimizer.jl | 29 +++++++++++++++++++++++++++++ 3 files changed, 42 insertions(+), 5 deletions(-) diff --git a/src/Bridges/Variable/map.jl b/src/Bridges/Variable/map.jl index a93cb69987..e7a5b44fdb 100644 --- a/src/Bridges/Variable/map.jl +++ b/src/Bridges/Variable/map.jl @@ -219,6 +219,14 @@ function number_with_set(map::Map, S::Type{<:MOI.AbstractSet}) return count(isequal(S), map.sets) end +function first_variable(::Map, ci::MOI.ConstraintIndex{MOI.VariableIndex}) + return MOI.VariableIndex(ci.value) +end + +function first_variable(map::Map, ci::MOI.ConstraintIndex{MOI.VectorOfVariables}) + return MOI.VariableIndex(map.vector_of_variables_map[-ci.value]) +end + function constraint(map::Map, vi::MOI.VariableIndex) S = constrained_set(map, vi)::Type{<:MOI.AbstractSet} F = MOI.Utilities.variable_function_type(S) diff --git a/src/Bridges/bridge_optimizer.jl b/src/Bridges/bridge_optimizer.jl index bfb4a6e064..67b5661732 100644 --- a/src/Bridges/bridge_optimizer.jl +++ b/src/Bridges/bridge_optimizer.jl @@ -261,7 +261,8 @@ Return the `AbstractBridge` used to bridge the constraint with index `ci`. """ function bridge(b::AbstractBridgeOptimizer, ci::MOI.ConstraintIndex) if is_variable_bridged(b, ci) - return bridge(b, MOI.VariableIndex(ci.value)) + map = Variable.bridges(b)::Variable.Map + return bridge(b, Variable.first_variable(map, ci)) else return Constraint.bridges(b)[ci] end @@ -312,7 +313,8 @@ function call_in_context( f::Function, ) if is_variable_bridged(b, ci) - return call_in_context(b, MOI.VariableIndex(ci.value), f) + map = Variable.bridges(b)::Variable.Map + return call_in_context(b, Variable.first_variable(map, ci), f) else return Variable.call_in_context( Variable.bridges(b), @@ -483,10 +485,8 @@ function MOI.is_valid( ) where {F,S} if is_bridged(b, ci) if is_variable_bridged(b, ci) - vi = MOI.VariableIndex(ci.value) v_map = Variable.bridges(b)::Variable.Map - return MOI.is_valid(b, vi) && - Variable.constrained_set(v_map, vi) == S + return MOI.is_valid(v_map, ci) else return haskey(Constraint.bridges(b), ci) end diff --git a/test/Bridges/bridge_optimizer.jl b/test/Bridges/bridge_optimizer.jl index 2e8df8af12..daf11fffe3 100644 --- a/test/Bridges/bridge_optimizer.jl +++ b/test/Bridges/bridge_optimizer.jl @@ -1129,6 +1129,35 @@ function test_first_bridge() return end +function test_variable_bridge_constraint_attribute() + mock = MOI.Utilities.MockOptimizer( + MOI.Utilities.UniversalFallback(MOI.Utilities.Model{Float64}()), + ) + model = MOI.Bridges.Variable.NonposToNonneg{Float64}(mock) + x, cx = MOI.add_constrained_variables(model, MOI.Nonpositives(2)) + y, cy = MOI.add_constrained_variables(model, MOI.Nonpositives(2)) + @test MOI.Bridges.bridge(model, x[1]) === MOI.Bridges.bridge(model, cx) + @test MOI.Bridges.bridge(model, x[2]) === MOI.Bridges.bridge(model, cx) + @test MOI.Bridges.bridge(model, y[1]) === MOI.Bridges.bridge(model, cy) + @test MOI.Bridges.bridge(model, y[2]) === MOI.Bridges.bridge(model, cy) + var = [x; y] + val = float.(collect(1:4)) + mock_var = MOI.get(mock, MOI.ListOfVariableIndices()) + MOI.set(mock, MOI.VariablePrimal(), mock_var, -val) + @test MOI.get(model, MOI.VariablePrimal(), var) == val + @test MOI.get(model, MOI.ConstraintPrimal(), cx) == val[1:2] + @test MOI.get(model, MOI.ConstraintPrimal(), cy) == val[3:4] + for v in var + @test MOI.is_valid(model, v) + end + @test MOI.is_valid(model, cx) + @test MOI.is_valid(model, cy) + MOI.delete(model, x) + @test !MOI.is_valid(model, cx) + @test MOI.is_valid(model, cy) + return +end + end # module TestBridgeOptimizer.runtests() From 92c0240ccf28e0293bb0bb20d24fa86e6d316a5a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Legat?= Date: Wed, 20 Dec 2023 14:41:45 +0100 Subject: [PATCH 18/22] Fix format --- src/Bridges/Variable/map.jl | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/Bridges/Variable/map.jl b/src/Bridges/Variable/map.jl index e7a5b44fdb..9384e8265d 100644 --- a/src/Bridges/Variable/map.jl +++ b/src/Bridges/Variable/map.jl @@ -223,7 +223,10 @@ function first_variable(::Map, ci::MOI.ConstraintIndex{MOI.VariableIndex}) return MOI.VariableIndex(ci.value) end -function first_variable(map::Map, ci::MOI.ConstraintIndex{MOI.VectorOfVariables}) +function first_variable( + map::Map, + ci::MOI.ConstraintIndex{MOI.VectorOfVariables}, +) return MOI.VariableIndex(map.vector_of_variables_map[-ci.value]) end From b22d380f94dceff8ad775787881587227661dd7a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Legat?= Date: Wed, 20 Dec 2023 14:45:38 +0100 Subject: [PATCH 19/22] Add docstrings --- src/Bridges/Variable/map.jl | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/Bridges/Variable/map.jl b/src/Bridges/Variable/map.jl index 9384e8265d..8f18f3edb6 100644 --- a/src/Bridges/Variable/map.jl +++ b/src/Bridges/Variable/map.jl @@ -219,10 +219,20 @@ function number_with_set(map::Map, S::Type{<:MOI.AbstractSet}) return count(isequal(S), map.sets) end +""" + first_variable(::Map, ci::MOI.ConstraintIndex{MOI.VariableIndex}) + +Return the `MOI.VariableIndex` of the `MOI.ConstraintFunction` of `ci`. +""" function first_variable(::Map, ci::MOI.ConstraintIndex{MOI.VariableIndex}) return MOI.VariableIndex(ci.value) end +""" + first_variable(::Map, ci::MOI.ConstraintIndex{MOI.VariableIndex}) + +Return the first `MOI.VariableIndex` of the `MOI.ConstraintFunction` of `ci`. +""" function first_variable( map::Map, ci::MOI.ConstraintIndex{MOI.VectorOfVariables}, From 38ab2acdc44031478cfab9de6dab17f08b1c71db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Legat?= Date: Thu, 21 Dec 2023 10:17:05 +0100 Subject: [PATCH 20/22] Add tests --- test/Bridges/lazy_bridge_optimizer.jl | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/test/Bridges/lazy_bridge_optimizer.jl b/test/Bridges/lazy_bridge_optimizer.jl index db5d0005bb..7fd27065fd 100644 --- a/test/Bridges/lazy_bridge_optimizer.jl +++ b/test/Bridges/lazy_bridge_optimizer.jl @@ -348,13 +348,15 @@ function test_index_constraint_conflict() @test c != b2.slack_in_set end -function test_index_variable_conflict() +function _test_index_variable_conflict(set) optimizer = StandardSDPAModel{Float64}() model = MOI.Bridges.full_bridge_optimizer(optimizer, Float64) - set = MOI.SecondOrderCone(3) - x = MOI.add_variables(model, 3) + x = MOI.add_variables(model, MOI.dimension(set)) c = MOI.add_constraint(model, MOI.VectorOfVariables(x), set) @test MOI.is_valid(model, c) + w, cw = MOI.add_constrained_variables(model, set) + @test MOI.is_valid(model, cw) + @test cw != c y, cy = MOI.add_constrained_variables(model, set) @test MOI.is_valid(model, cy) @test cy != c @@ -363,6 +365,16 @@ function test_index_variable_conflict() @test cz != c end +function test_index_variable_conflict() + _test_index_variable_conflict(MOI.Nonpositives(3)) + _test_index_variable_conflict(MOI.SecondOrderCone(3)) + _test_index_variable_conflict(MOI.RotatedSecondOrderCone(3)) + _test_index_variable_conflict(MOI.RotatedSecondOrderCone(2)) + return _test_index_variable_conflict( + MOI.ScaledPositiveSemidefiniteConeTriangle(2), + ) +end + function test_show_SPDA() model = StandardSDPAModel{Float64}() model_str = sprint(MOI.Utilities.print_with_acronym, string(typeof(model))) From d49f5b930bea94d1c1851b678420dec8dcb268fa Mon Sep 17 00:00:00 2001 From: Oscar Dowson Date: Fri, 22 Dec 2023 08:57:04 +1300 Subject: [PATCH 21/22] Update lazy_bridge_optimizer.jl --- test/Bridges/lazy_bridge_optimizer.jl | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/test/Bridges/lazy_bridge_optimizer.jl b/test/Bridges/lazy_bridge_optimizer.jl index 7fd27065fd..50a765f27f 100644 --- a/test/Bridges/lazy_bridge_optimizer.jl +++ b/test/Bridges/lazy_bridge_optimizer.jl @@ -346,6 +346,7 @@ function test_index_constraint_conflict() b1 = MOI.Bridges.bridge(model, c) b2 = MOI.Bridges.bridge(model, b1.constraint) @test c != b2.slack_in_set + return end function _test_index_variable_conflict(set) @@ -363,6 +364,7 @@ function _test_index_variable_conflict(set) z, cz = MOI.add_constrained_variables(model, set) @test MOI.is_valid(model, cz) @test cz != c + return end function test_index_variable_conflict() @@ -370,9 +372,10 @@ function test_index_variable_conflict() _test_index_variable_conflict(MOI.SecondOrderCone(3)) _test_index_variable_conflict(MOI.RotatedSecondOrderCone(3)) _test_index_variable_conflict(MOI.RotatedSecondOrderCone(2)) - return _test_index_variable_conflict( + _test_index_variable_conflict( MOI.ScaledPositiveSemidefiniteConeTriangle(2), ) + return end function test_show_SPDA() From a9bbfbbe959501745d5bf14c553c57a36f439fcd Mon Sep 17 00:00:00 2001 From: Oscar Dowson Date: Fri, 22 Dec 2023 09:21:27 +1300 Subject: [PATCH 22/22] Update lazy_bridge_optimizer.jl --- test/Bridges/lazy_bridge_optimizer.jl | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/test/Bridges/lazy_bridge_optimizer.jl b/test/Bridges/lazy_bridge_optimizer.jl index 50a765f27f..327f1b2289 100644 --- a/test/Bridges/lazy_bridge_optimizer.jl +++ b/test/Bridges/lazy_bridge_optimizer.jl @@ -372,9 +372,7 @@ function test_index_variable_conflict() _test_index_variable_conflict(MOI.SecondOrderCone(3)) _test_index_variable_conflict(MOI.RotatedSecondOrderCone(3)) _test_index_variable_conflict(MOI.RotatedSecondOrderCone(2)) - _test_index_variable_conflict( - MOI.ScaledPositiveSemidefiniteConeTriangle(2), - ) + _test_index_variable_conflict(MOI.ScaledPositiveSemidefiniteConeTriangle(2)) return end