From 5641663cb1571913af7da93eedb29d831c72061e Mon Sep 17 00:00:00 2001 From: Oscar Dowson Date: Tue, 8 Sep 2026 13:22:30 +1200 Subject: [PATCH 1/2] Enforce dimension > 0 for SOS1 and SOS2 --- src/sets.jl | 22 ++++++++++++++++++++++ test/General/test_sets.jl | 18 ++++++++++++++++++ 2 files changed, 40 insertions(+) diff --git a/src/sets.jl b/src/sets.jl index a5361684c7..0de8902b8d 100644 --- a/src/sets.jl +++ b/src/sets.jl @@ -1852,8 +1852,19 @@ MathOptInterface.ConstraintIndex{MathOptInterface.VectorOfVariables, MathOptInte """ struct SOS1{T<:Real} <: AbstractVectorSet weights::Vector{T} + + function SOS1{T}(weights::Vector{T}) where {T<:Real} + if isempty(weights) + throw(DimensionMismatch("Dimension of SOS1 must be > 0.")) + end + return new{T}(weights) + end end +SOS1(w::AbstractVector{T}) where {T<:Real} = SOS1{T}(w) + +SOS1{T}(w::AbstractVector) where {T<:Real} = SOS1{T}(convert(Vector{T}, w)) + dimension(set::SOS1) = length(set.weights) Base.copy(set::SOS1{T}) where {T} = SOS1{T}(copy(set.weights)) @@ -1889,8 +1900,19 @@ MathOptInterface.ConstraintIndex{MathOptInterface.VectorOfVariables, MathOptInte """ struct SOS2{T<:Real} <: AbstractVectorSet weights::Vector{T} + + function SOS2{T}(weights::Vector{T}) where {T<:Real} + if isempty(weights) + throw(DimensionMismatch("Dimension of SOS2 must be > 0.")) + end + return new{T}(weights) + end end +SOS2(w::AbstractVector{T}) where {T<:Real} = SOS2{T}(w) + +SOS2{T}(w::AbstractVector) where {T<:Real} = SOS2{T}(convert(Vector{T}, w)) + dimension(set::SOS2) = length(set.weights) Base.copy(set::SOS2{T}) where {T} = SOS2{T}(copy(set.weights)) diff --git a/test/General/test_sets.jl b/test/General/test_sets.jl index 853dc97eda..9947beb384 100644 --- a/test/General/test_sets.jl +++ b/test/General/test_sets.jl @@ -503,6 +503,24 @@ function test_VectorNonlinearOracle() return end +function test_SOS1_constructor() + @test_throws DimensionMismatch MOI.SOS1{Float64}(Float64[]) + @test_throws DimensionMismatch MOI.SOS1(Float64[]) + @test_throws DimensionMismatch MOI.SOS1(1:0) + @test MOI.SOS1(1:3) == MOI.SOS1{Int}(Int[1, 2, 3]) + @test MOI.SOS1{Float64}(1:3) == MOI.SOS1{Float64}([1.0, 2.0, 3.0]) + return +end + +function test_SOS2_constructor() + @test_throws DimensionMismatch MOI.SOS2{Float64}(Float64[]) + @test_throws DimensionMismatch MOI.SOS2(Float64[]) + @test_throws DimensionMismatch MOI.SOS2(1:0) + @test MOI.SOS2(1:3) == MOI.SOS2{Int}(Int[1, 2, 3]) + @test MOI.SOS2{Float64}(1:3) == MOI.SOS2{Float64}([1.0, 2.0, 3.0]) + return +end + end # module TestSets.runtests() From 64500a6ab40fcf6003618032399c29244e13973c Mon Sep 17 00:00:00 2001 From: Oscar Dowson Date: Tue, 8 Sep 2026 13:59:42 +1200 Subject: [PATCH 2/2] Apply suggestion from @odow --- src/sets.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sets.jl b/src/sets.jl index 0de8902b8d..8acb9d6bdb 100644 --- a/src/sets.jl +++ b/src/sets.jl @@ -1853,7 +1853,7 @@ MathOptInterface.ConstraintIndex{MathOptInterface.VectorOfVariables, MathOptInte struct SOS1{T<:Real} <: AbstractVectorSet weights::Vector{T} - function SOS1{T}(weights::Vector{T}) where {T<:Real} + function SOS1{T}(weights::Vector{T}) where {T<:Real} if isempty(weights) throw(DimensionMismatch("Dimension of SOS1 must be > 0.")) end