diff --git a/Project.toml b/Project.toml index 123f5c3..1e5bfde 100644 --- a/Project.toml +++ b/Project.toml @@ -10,7 +10,7 @@ SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" [compat] HiGHS_jll = "=1.5.1, =1.5.3, =1.6.0, =1.7.0, =1.7.1, =1.7.2, =1.8.0" -MathOptInterface = "1.21" +MathOptInterface = "1.34" PrecompileTools = "1" SparseArrays = "1.6" Test = "1.6" diff --git a/src/HiGHS.jl b/src/HiGHS.jl index 1770ede..110cfbb 100644 --- a/src/HiGHS.jl +++ b/src/HiGHS.jl @@ -52,6 +52,9 @@ PrecompileTools.@setup_workload begin MOI.add_constrained_variable(model, MOI.EqualTo(0.0)) MOI.add_constrained_variable(model, MOI.Integer()) MOI.add_constrained_variable(model, MOI.ZeroOne()) + set = (MOI.GreaterThan(0.0), MOI.LessThan(0.0)) + MOI.supports_add_constrained_variable(model, typeof(set)) + MOI.add_constrained_variable(model, set) f = 1.0 * x[1] + x[2] + x[3] c1 = MOI.add_constraint(model, f, MOI.GreaterThan(0.0)) MOI.set(model, MOI.ConstraintName(), c1, "c1") diff --git a/src/MOI_wrapper.jl b/src/MOI_wrapper.jl index 929ef75..37310f1 100644 --- a/src/MOI_wrapper.jl +++ b/src/MOI_wrapper.jl @@ -803,6 +803,37 @@ function MOI.add_constrained_variable( return index, MOI.ConstraintIndex{MOI.VariableIndex,S}(index.value) end +function MOI.supports_add_constrained_variable( + ::Optimizer, + ::Type{Tuple{MOI.GreaterThan{Float64},MOI.LessThan{Float64}}}, +) + return true +end + +function MOI.add_constrained_variable( + model::Optimizer, + set::Tuple{MOI.GreaterThan{Float64},MOI.LessThan{Float64}}, +) + # Initialize `_VariableInfo` with a dummy `VariableIndex` and a column, + # because we need `add_item` to tell us what the `VariableIndex` is. + index = CleverDicts.add_item( + model.variable_info, + _VariableInfo(MOI.VariableIndex(0), HighsInt(0)), + ) + info = _info(model, index) + # Now, set `.index` and `.column`. + info.index = index + info.column = HighsInt(length(model.variable_info) - 1) + l, u = set[1].lower, set[2].upper + ret = Highs_addCol(model, 0.0, l, u, 0, C_NULL, C_NULL) + _check_ret(ret) + _update_info(info, set[1]) + _update_info(info, set[2]) + c_gt = MOI.ConstraintIndex{MOI.VariableIndex,(typeof(set[1]))}(index.value) + c_lt = MOI.ConstraintIndex{MOI.VariableIndex,(typeof(set[2]))}(index.value) + return index, (c_gt, c_lt) +end + function MOI.is_valid(model::Optimizer, v::MOI.VariableIndex) return haskey(model.variable_info, v) end diff --git a/test/MOI_wrapper.jl b/test/MOI_wrapper.jl index b336159..966672a 100644 --- a/test/MOI_wrapper.jl +++ b/test/MOI_wrapper.jl @@ -956,6 +956,21 @@ function test_active_bound() return end +function test_add_constrained_variable_tuple() + F = MOI.VariableIndex + model = HiGHS.Optimizer() + set = (MOI.GreaterThan(0.0), MOI.LessThan(1.0)) + @test MOI.supports_add_constrained_variable(model, typeof(set)) + x, (c_l, c_u) = MOI.add_constrained_variable(model, set) + @test c_l == MOI.ConstraintIndex{F,MOI.GreaterThan{Float64}}(x.value) + @test c_u == MOI.ConstraintIndex{F,MOI.LessThan{Float64}}(x.value) + @test MOI.get(model, MOI.ConstraintFunction(), c_l) == x + @test MOI.get(model, MOI.ConstraintSet(), c_l) == set[1] + @test MOI.get(model, MOI.ConstraintFunction(), c_u) == x + @test MOI.get(model, MOI.ConstraintSet(), c_u) == set[2] + return +end + end # module TestMOIHighs.runtests()