From 8a856bb677fdc1ec1e9a40a8a41e64089f7b6437 Mon Sep 17 00:00:00 2001 From: Oscar Dowson Date: Wed, 16 Aug 2023 12:17:06 +1200 Subject: [PATCH] Add support for constant LHS in complements constraint (#3452) --- src/complement.jl | 10 ++++----- test/test_complement.jl | 48 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+), 5 deletions(-) diff --git a/src/complement.jl b/src/complement.jl index 0f8c782c8c3..e3de1ce2175 100644 --- a/src/complement.jl +++ b/src/complement.jl @@ -11,7 +11,7 @@ function _build_complements_constraint( errorf::Function, - F::AbstractArray{<:AbstractJuMPScalar}, + F::AbstractArray{<:Union{Real,AbstractJuMPScalar}}, x::AbstractArray{<:AbstractVariableRef}, ) if size(F) != size(x) @@ -25,7 +25,7 @@ end function _build_complements_constraint( errorf::Function, - F::Containers.SparseAxisArray{<:AbstractJuMPScalar}, + F::Containers.SparseAxisArray{<:Union{Real,AbstractJuMPScalar}}, x::Containers.SparseAxisArray{<:AbstractVariableRef}, ) elements = [F[i] for i in eachindex(F)] @@ -41,7 +41,7 @@ end function _build_complements_constraint( errorf::Function, - ::AbstractArray{<:AbstractJuMPScalar}, + ::AbstractArray{<:Union{Real,AbstractJuMPScalar}}, ::AbstractArray{<:AbstractJuMPScalar}, ) return errorf("second term must be an array of variables.") @@ -49,7 +49,7 @@ end function _build_complements_constraint( ::Function, - F::AbstractJuMPScalar, + F::Union{Real,AbstractJuMPScalar}, x::AbstractVariableRef, ) return VectorConstraint([F, x], MOI.Complements(2)) @@ -57,7 +57,7 @@ end function _build_complements_constraint( errorf::Function, - ::AbstractJuMPScalar, + ::Union{Real,AbstractJuMPScalar}, ::AbstractJuMPScalar, ) return errorf("second term must be a variable.") diff --git a/test/test_complement.jl b/test/test_complement.jl index 7c16e4b6fed..725122fb325 100644 --- a/test/test_complement.jl +++ b/test/test_complement.jl @@ -57,6 +57,19 @@ function test_scalar_error_F_F() return end +function test_scalar_error_0_F() + model = Model() + @variable(model, x >= 0) + @test_throws_strip( + ErrorException( + "In `@constraint(model, 0 ⟂ 2x - 1)`: second term must be a " * + "variable.", + ), + @constraint(model, 0 ⟂ 2x - 1) + ) + return +end + function test_vector_complements() model = Model() @variable(model, x[1:2] >= 0) @@ -116,6 +129,20 @@ function test_vector_error_F_F() return end +function test_vector_error_0_F() + model = Model() + @variable(model, x[1:2] >= 0) + y = [1.2, -1.3] + @test_throws_strip( + ErrorException( + "In `@constraint(model, y ⟂ 2x .- 1)`: second term must " * + "be an array of variables.", + ), + @constraint(model, y ⟂ 2x .- 1) + ) + return +end + function test_sparse_complements() model = Model() @variable(model, x[i = 1:3; isodd(i)] >= 0) @@ -146,4 +173,25 @@ function test_sparse_key_mismatch() return end +function test_F_constant_scalar() + model = Model() + @variable(model, 0 <= x <= 1) + @constraint(model, c, 0 ⟂ x) + obj = constraint_object(c) + @test obj.func == AffExpr[0, x] + @test obj.set == MOI.Complements(2) + return +end + +function test_F_constant_vector() + model = Model() + @variable(model, 0 <= x[1:2] <= 1) + F = [1.2, -1.3] + @constraint(model, c, F ⟂ x) + obj = constraint_object(c) + @test obj.func == [F; x] + @test obj.set == MOI.Complements(4) + return +end + end # module