From 3f59f58480cc3e0bc55ba517663baaec407e0b78 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Legat?= Date: Thu, 29 Aug 2024 19:05:17 +0200 Subject: [PATCH 1/7] Update to JuMP and MOI v1 --- .github/workflows/ci.yml | 9 +- Project.toml | 6 +- src/MOI_wrapper/Bridges/bool.jl | 2 +- src/MOI_wrapper/reified.jl | 2 +- test/Project.toml | 3 +- test/unit/constraints/indicator.jl | 157 +++++++++++++++-------------- 6 files changed, 94 insertions(+), 85 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 844a5282..e783b750 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -37,6 +37,13 @@ jobs: ${{ runner.os }}-test-${{ env.cache-name }}- ${{ runner.os }}-test- ${{ runner.os }}- + - name: CPE + shell: julia --project=@. {0} + run: | + using Pkg + Pkg.add([ + PackageSpec(name="ConstraintProgrammingExtensions", rev="master"), + ]) - uses: julia-actions/julia-buildpkg@v1 - uses: julia-actions/julia-runtest@v1 - uses: julia-actions/julia-processcoverage@v1 @@ -57,4 +64,4 @@ jobs: env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} DOCUMENTER_KEY: ${{ secrets.DOCUMENTER_KEY }} # For authentication with SSH deploy key - run: julia --project=docs/ docs/make.jl \ No newline at end of file + run: julia --project=docs/ docs/make.jl diff --git a/Project.toml b/Project.toml index c7dd9201..aae193b4 100644 --- a/Project.toml +++ b/Project.toml @@ -19,7 +19,7 @@ StatsFuns = "4c63d2b9-4356-54db-8cca-17b64c39e42c" TableLogger = "72b659bb-f61b-4d0d-9dbb-0f81f57d8545" [compat] -ConstraintProgrammingExtensions = "^0.6" +ConstraintProgrammingExtensions = "^0.7" DataStructures = "~0.11, ~0.12, ~0.13, ~0.14, ~0.15, ~0.16, ~0.17, ~0.18" Formatting = "^0.4.1" JSON = "~0.18, ~0.19, ~0.20, ~0.21" @@ -27,7 +27,7 @@ JuMP = "^0.22, 0.23, 1" LightGraphs = "1" MathOptInterface = "^0.10, 1" MatrixNetworks = "^1" -StatsBase = "^0.33" -StatsFuns = "^0.9.5" +StatsBase = "^0.33, 0.34" +StatsFuns = "^0.9.5, 1" TableLogger = "^0.1" julia = "^1.6" diff --git a/src/MOI_wrapper/Bridges/bool.jl b/src/MOI_wrapper/Bridges/bool.jl index 5d4ba577..09cc2e28 100644 --- a/src/MOI_wrapper/Bridges/bool.jl +++ b/src/MOI_wrapper/Bridges/bool.jl @@ -77,7 +77,7 @@ function get_constraint_types( if direct_support return [(F,S)] else - return MOIB.added_constraint_types(inner_bridge, F, S) + return MOIB.added_constraint_types(MOIB.Constraint.concrete_bridge_type(inner_bridge, F, S)) end end diff --git a/src/MOI_wrapper/reified.jl b/src/MOI_wrapper/reified.jl index 5b96858d..f4e021a4 100644 --- a/src/MOI_wrapper/reified.jl +++ b/src/MOI_wrapper/reified.jl @@ -45,7 +45,7 @@ end function JuMP.parse_constraint_head(_error::Function, ::Val{:(:=)}, lhs, rhs) variable, S = _reified_variable_set(_error, lhs) - if !JuMP.isexpr(rhs, :braces) || length(rhs.args) != 1 + if !Meta.isexpr(rhs, :braces) || length(rhs.args) != 1 _error("Invalid right-hand side `$(rhs)` of reified constraint. Expected constraint surrounded by `{` and `}`.") end rhs_con = rhs.args[1] diff --git a/test/Project.toml b/test/Project.toml index 3bfdc17d..1ee14502 100644 --- a/test/Project.toml +++ b/test/Project.toml @@ -2,6 +2,7 @@ Cbc = "9961bab8-2fa3-5c5a-9d89-47fab24efd76" Combinatorics = "861a8166-3701-5b0c-9a16-15d98fcdc6aa" ConstraintProgrammingExtensions = "b65d079e-ed98-51d9-b0db-edee61a5c5f8" +ConstraintSolver = "e0e52ebd-5523-408d-9ca3-7641f1cd1405" DataStructures = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8" Formatting = "59287772-0a20-5a39-b81b-1366585eb4c0" ForwardDiff = "f6369f11-7733-5829-9624-2563aa707210" @@ -18,4 +19,4 @@ Statistics = "10745b16-79ce-11e8-11f9-7d13ad32a3b2" Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" [compat] -ReferenceTests = "=0.9.0" +ReferenceTests = "0.10" diff --git a/test/unit/constraints/indicator.jl b/test/unit/constraints/indicator.jl index d7a0d5ff..bd88a304 100644 --- a/test/unit/constraints/indicator.jl +++ b/test/unit/constraints/indicator.jl @@ -62,7 +62,7 @@ for ind in constr_indices[2:3] @test sort(CS.values(com.search_space[ind])) == [-3, 1, 2, 3] end - @test sort(CS.values(com.search_space[1])) == [0, 1] + @test sort(CS.values(com.search_space[constr_indices[1]])) == [0, 1] # feasible but remove -3 @test CS.fix!(com, com.search_space[constr_indices[1]], 1) @test CS.prune_constraint!(com, constraint, constraint.fct, constraint.set) @@ -72,82 +72,83 @@ CS.values(com.search_space[constr_indices[1]]) == [1] end -@testset "indicator is_constraint_violated test" begin - m = Model(optimizer_with_attributes(CS.Optimizer, "no_prune" => true, "logging" => [])) - @variable(m, b, Bin) - @variable(m, -5 <= x[1:5] <= 5, Int) - @constraint(m, b => {x in CS.GeqSet()}) - optimize!(m) - com = CS.get_inner_model(m) - - constraint = com.constraints[1] - - variables = com.search_space - @test CS.fix!(com, variables[constraint.indices[1]], 1; check_feasibility = false) - @test CS.remove_above!( - com, - variables[constraint.indices[2]], - 3; - check_feasibility = false, - ) - @test CS.remove_below!( - com, - variables[constraint.indices[3]], - 4; - check_feasibility = false, - ) - @test CS.is_constraint_violated(com, constraint, constraint.fct, constraint.set) - - m = Model(optimizer_with_attributes(CS.Optimizer, "no_prune" => true, "logging" => [])) - @variable(m, b, Bin) - @variable(m, -5 <= x[1:5] <= 5, Int) - @constraint(m, b => {x in CS.GeqSet()}) - optimize!(m) - com = CS.get_inner_model(m) - - constraint = com.constraints[1] - - variables = com.search_space - @test CS.fix!(com, variables[constraint.indices[1]], 1; check_feasibility = false) - @test CS.remove_above!( - com, - variables[constraint.indices[2]], - 3; - check_feasibility = false, - ) - @test CS.remove_below!( - com, - variables[constraint.indices[3]], - 3; - check_feasibility = false, - ) - @test !CS.is_constraint_violated(com, constraint, constraint.fct, constraint.set) - - m = Model(optimizer_with_attributes(CS.Optimizer, "no_prune" => true, "logging" => [])) - @variable(m, b, Bin) - @variable(m, -5 <= x[1:5] <= 5, Int) - @constraint(m, b => {x in CS.GeqSet()}) - optimize!(m) - com = CS.get_inner_model(m) - - constraint = com.constraints[1] - - variables = com.search_space - @test CS.fix!(com, variables[constraint.indices[1]], 0; check_feasibility = false) - @test CS.remove_above!( - com, - variables[constraint.indices[2]], - 3; - check_feasibility = false, - ) - @test CS.remove_below!( - com, - variables[constraint.indices[3]], - 4; - check_feasibility = false, - ) - @test !CS.is_constraint_violated(com, constraint, constraint.fct, constraint.set) -end +# FIXME +#@testset "indicator is_constraint_violated test" begin +# m = Model(optimizer_with_attributes(CS.Optimizer, "no_prune" => true, "logging" => [])) +# @variable(m, b, Bin) +# @variable(m, -5 <= x[1:5] <= 5, Int) +# @constraint(m, b => {x in CS.GeqSet()}) +# optimize!(m) +# com = CS.get_inner_model(m) +# +# constraint = com.constraints[1] +# +# variables = com.search_space +# @test CS.fix!(com, variables[constraint.indices[1]], 1; check_feasibility = false) +# @test CS.remove_above!( +# com, +# variables[constraint.indices[2]], +# 3; +# check_feasibility = false, +# ) +# @test CS.remove_below!( +# com, +# variables[constraint.indices[3]], +# 4; +# check_feasibility = false, +# ) +# @test CS.is_constraint_violated(com, constraint, constraint.fct, constraint.set) +# +# m = Model(optimizer_with_attributes(CS.Optimizer, "no_prune" => true, "logging" => [])) +# @variable(m, b, Bin) +# @variable(m, -5 <= x[1:5] <= 5, Int) +# @constraint(m, b => {x in CS.GeqSet()}) +# optimize!(m) +# com = CS.get_inner_model(m) +# +# constraint = com.constraints[1] +# +# variables = com.search_space +# @test CS.fix!(com, variables[constraint.indices[1]], 1; check_feasibility = false) +# @test CS.remove_above!( +# com, +# variables[constraint.indices[2]], +# 3; +# check_feasibility = false, +# ) +# @test CS.remove_below!( +# com, +# variables[constraint.indices[3]], +# 3; +# check_feasibility = false, +# ) +# @test !CS.is_constraint_violated(com, constraint, constraint.fct, constraint.set) +# +# m = Model(optimizer_with_attributes(CS.Optimizer, "no_prune" => true, "logging" => [])) +# @variable(m, b, Bin) +# @variable(m, -5 <= x[1:5] <= 5, Int) +# @constraint(m, b => {x in CS.GeqSet()}) +# optimize!(m) +# com = CS.get_inner_model(m) +# +# constraint = com.constraints[1] +# +# variables = com.search_space +# @test CS.fix!(com, variables[constraint.indices[1]], 0; check_feasibility = false) +# @test CS.remove_above!( +# com, +# variables[constraint.indices[2]], +# 3; +# check_feasibility = false, +# ) +# @test CS.remove_below!( +# com, +# variables[constraint.indices[3]], +# 4; +# check_feasibility = false, +# ) +# @test !CS.is_constraint_violated(com, constraint, constraint.fct, constraint.set) +#end @testset "indicator is_constraint_violated test" begin m = Model(optimizer_with_attributes(CS.Optimizer, "backtrack" => false, "logging" => [])) @@ -161,4 +162,4 @@ end constraint = com.constraints[1] # b is not active so no pruning should happen @test sort(CS.values.(m, x)) == -5:5 -end \ No newline at end of file +end From dacccac83b6c207b1596465271a02644e09e3143 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Legat?= Date: Thu, 29 Aug 2024 19:12:06 +0200 Subject: [PATCH 2/7] Ref to JuMP issue --- test/unit/constraints/indicator.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/unit/constraints/indicator.jl b/test/unit/constraints/indicator.jl index bd88a304..6c42575c 100644 --- a/test/unit/constraints/indicator.jl +++ b/test/unit/constraints/indicator.jl @@ -72,7 +72,7 @@ CS.values(com.search_space[constr_indices[1]]) == [1] end -# FIXME +# FIXME this is hitting https://github.com/jump-dev/JuMP.jl/issues/3812 #@testset "indicator is_constraint_violated test" begin # m = Model(optimizer_with_attributes(CS.Optimizer, "no_prune" => true, "logging" => [])) # @variable(m, b, Bin) From c5a79a480f2df7189ad4fd6a43576d92050b4ed8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Legat?= Date: Thu, 29 Aug 2024 20:46:22 +0200 Subject: [PATCH 3/7] Remove CS from test/Project.toml --- test/Project.toml | 1 - 1 file changed, 1 deletion(-) diff --git a/test/Project.toml b/test/Project.toml index 1ee14502..1cc541f2 100644 --- a/test/Project.toml +++ b/test/Project.toml @@ -2,7 +2,6 @@ Cbc = "9961bab8-2fa3-5c5a-9d89-47fab24efd76" Combinatorics = "861a8166-3701-5b0c-9a16-15d98fcdc6aa" ConstraintProgrammingExtensions = "b65d079e-ed98-51d9-b0db-edee61a5c5f8" -ConstraintSolver = "e0e52ebd-5523-408d-9ca3-7641f1cd1405" DataStructures = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8" Formatting = "59287772-0a20-5a39-b81b-1366585eb4c0" ForwardDiff = "f6369f11-7733-5829-9624-2563aa707210" From 45fa0bacfab1cb40dddc5ab86a1268841b4eeceb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Legat?= Date: Thu, 29 Aug 2024 21:23:50 +0200 Subject: [PATCH 4/7] Fixes --- src/ConstraintSolver.jl | 2 +- src/MOI_wrapper/indicator.jl | 8 ++++---- test/constraints/indicator.jl | 10 +++++----- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/ConstraintSolver.jl b/src/ConstraintSolver.jl index a5a5f528..5a444bd8 100644 --- a/src/ConstraintSolver.jl +++ b/src/ConstraintSolver.jl @@ -93,7 +93,7 @@ include("simplify.jl") Return the ConstraintSolverModel for the Model or Optimizer """ -function get_inner_model(m::Model) +function get_inner_model(m::JuMP.GenericModel) JuMP.backend(m).optimizer.model.model.inner end diff --git a/src/MOI_wrapper/indicator.jl b/src/MOI_wrapper/indicator.jl index 65030278..7db39681 100644 --- a/src/MOI_wrapper/indicator.jl +++ b/src/MOI_wrapper/indicator.jl @@ -10,11 +10,11 @@ function JuMP._build_indicator_constraint( S = typeof(constraint.set) F = typeof(JuMP.moi_function(constraint)) set = CS.Indicator{A,F,S}(constraint.set, 1 + length(constraint.func)) - if constraint.func isa Vector{VariableRef} - vov = JuMP.VariableRef[variable] + if constraint.func isa Vector{typeof(variable)} + vov = [variable] else - vov = JuMP.AffExpr[variable] + vov = typeof(1variable)[variable] end append!(vov, constraint.func) return JuMP.VectorConstraint(vov, set) -end \ No newline at end of file +end diff --git a/test/constraints/indicator.jl b/test/constraints/indicator.jl index 7f517b4b..283a6be6 100644 --- a/test/constraints/indicator.jl +++ b/test/constraints/indicator.jl @@ -1,6 +1,6 @@ @testset "IndicatorConstraint" begin @testset "Basic ==" begin - m = Model(CSJuMPTestOptimizer()) + m = GenericModel{Int}(CSJuMPTestOptimizer()) @variable(m, x, CS.Integers([1, 2, 4])) @variable(m, y, CS.Integers([3, 4])) @variable(m, b, Bin) @@ -18,7 +18,7 @@ end @testset "Basic == Active on zero" begin - m = Model(CSJuMPTestOptimizer()) + m = GenericModel{Int}(CSJuMPTestOptimizer()) @variable(m, x, CS.Integers([1, 2, 4])) @variable(m, y, CS.Integers([3, 4])) @variable(m, b, Bin) @@ -125,7 +125,7 @@ end @testset "Basic AllDifferent" begin - m = Model(CSJuMPTestOptimizer()) + m = GenericModel{Int}(CSJuMPTestOptimizer()) @variable(m, 0 <= x <= 1, Int) @variable(m, 0 <= y <= 1, Int) @variable(m, a, Bin) @@ -150,7 +150,7 @@ end @testset "Basic AllDifferent achievable" begin - m = Model(CSJuMPTestOptimizer()) + m = GenericModel{Int}(CSJuMPTestOptimizer()) @variable(m, 0 <= x <= 1, Int) @variable(m, 0 <= y <= 1, Int) @variable(m, a, Bin) @@ -169,7 +169,7 @@ end @testset "Basic AllDifferent negated" begin - m = Model(CSJuMPTestOptimizer()) + m = GenericModel{Int}(CSJuMPTestOptimizer()) @variable(m, 0 <= x <= 1, Int) @variable(m, 0 <= y <= 1, Int) @variable(m, a, Bin) From 4475c73b144597760003283ea1d1e3bf89ed77fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Legat?= Date: Thu, 29 Aug 2024 23:07:19 +0200 Subject: [PATCH 5/7] Fixes --- src/MOI_wrapper/results.jl | 2 +- test/constraints/indicator.jl | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/MOI_wrapper/results.jl b/src/MOI_wrapper/results.jl index 84ab1e6b..83493c04 100644 --- a/src/MOI_wrapper/results.jl +++ b/src/MOI_wrapper/results.jl @@ -3,7 +3,7 @@ function MOI.get(model::Optimizer, ::MOI.TerminationStatus) end function MOI.get(model::Optimizer, ov::MOI.ObjectiveValue) - return model.inner.solutions[ov.result_index].incumbent + return float(model.inner.solutions[ov.result_index].incumbent) end function MOI.get(model::Optimizer, ::MOI.ObjectiveBound) diff --git a/test/constraints/indicator.jl b/test/constraints/indicator.jl index 283a6be6..7f517b4b 100644 --- a/test/constraints/indicator.jl +++ b/test/constraints/indicator.jl @@ -1,6 +1,6 @@ @testset "IndicatorConstraint" begin @testset "Basic ==" begin - m = GenericModel{Int}(CSJuMPTestOptimizer()) + m = Model(CSJuMPTestOptimizer()) @variable(m, x, CS.Integers([1, 2, 4])) @variable(m, y, CS.Integers([3, 4])) @variable(m, b, Bin) @@ -18,7 +18,7 @@ end @testset "Basic == Active on zero" begin - m = GenericModel{Int}(CSJuMPTestOptimizer()) + m = Model(CSJuMPTestOptimizer()) @variable(m, x, CS.Integers([1, 2, 4])) @variable(m, y, CS.Integers([3, 4])) @variable(m, b, Bin) @@ -125,7 +125,7 @@ end @testset "Basic AllDifferent" begin - m = GenericModel{Int}(CSJuMPTestOptimizer()) + m = Model(CSJuMPTestOptimizer()) @variable(m, 0 <= x <= 1, Int) @variable(m, 0 <= y <= 1, Int) @variable(m, a, Bin) @@ -150,7 +150,7 @@ end @testset "Basic AllDifferent achievable" begin - m = GenericModel{Int}(CSJuMPTestOptimizer()) + m = Model(CSJuMPTestOptimizer()) @variable(m, 0 <= x <= 1, Int) @variable(m, 0 <= y <= 1, Int) @variable(m, a, Bin) @@ -169,7 +169,7 @@ end @testset "Basic AllDifferent negated" begin - m = GenericModel{Int}(CSJuMPTestOptimizer()) + m = Model(CSJuMPTestOptimizer()) @variable(m, 0 <= x <= 1, Int) @variable(m, 0 <= y <= 1, Int) @variable(m, a, Bin) From 57fd5c99f0aacd05eb711c43926abc496d90037b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Legat?= Date: Fri, 30 Aug 2024 09:53:51 +0200 Subject: [PATCH 6/7] Reenable test --- test/unit/constraints/indicator.jl | 153 ++++++++++++++--------------- 1 file changed, 76 insertions(+), 77 deletions(-) diff --git a/test/unit/constraints/indicator.jl b/test/unit/constraints/indicator.jl index 6c42575c..3dcf3483 100644 --- a/test/unit/constraints/indicator.jl +++ b/test/unit/constraints/indicator.jl @@ -72,83 +72,82 @@ CS.values(com.search_space[constr_indices[1]]) == [1] end -# FIXME this is hitting https://github.com/jump-dev/JuMP.jl/issues/3812 -#@testset "indicator is_constraint_violated test" begin -# m = Model(optimizer_with_attributes(CS.Optimizer, "no_prune" => true, "logging" => [])) -# @variable(m, b, Bin) -# @variable(m, -5 <= x[1:5] <= 5, Int) -# @constraint(m, b => {x in CS.GeqSet()}) -# optimize!(m) -# com = CS.get_inner_model(m) -# -# constraint = com.constraints[1] -# -# variables = com.search_space -# @test CS.fix!(com, variables[constraint.indices[1]], 1; check_feasibility = false) -# @test CS.remove_above!( -# com, -# variables[constraint.indices[2]], -# 3; -# check_feasibility = false, -# ) -# @test CS.remove_below!( -# com, -# variables[constraint.indices[3]], -# 4; -# check_feasibility = false, -# ) -# @test CS.is_constraint_violated(com, constraint, constraint.fct, constraint.set) -# -# m = Model(optimizer_with_attributes(CS.Optimizer, "no_prune" => true, "logging" => [])) -# @variable(m, b, Bin) -# @variable(m, -5 <= x[1:5] <= 5, Int) -# @constraint(m, b => {x in CS.GeqSet()}) -# optimize!(m) -# com = CS.get_inner_model(m) -# -# constraint = com.constraints[1] -# -# variables = com.search_space -# @test CS.fix!(com, variables[constraint.indices[1]], 1; check_feasibility = false) -# @test CS.remove_above!( -# com, -# variables[constraint.indices[2]], -# 3; -# check_feasibility = false, -# ) -# @test CS.remove_below!( -# com, -# variables[constraint.indices[3]], -# 3; -# check_feasibility = false, -# ) -# @test !CS.is_constraint_violated(com, constraint, constraint.fct, constraint.set) -# -# m = Model(optimizer_with_attributes(CS.Optimizer, "no_prune" => true, "logging" => [])) -# @variable(m, b, Bin) -# @variable(m, -5 <= x[1:5] <= 5, Int) -# @constraint(m, b => {x in CS.GeqSet()}) -# optimize!(m) -# com = CS.get_inner_model(m) -# -# constraint = com.constraints[1] -# -# variables = com.search_space -# @test CS.fix!(com, variables[constraint.indices[1]], 0; check_feasibility = false) -# @test CS.remove_above!( -# com, -# variables[constraint.indices[2]], -# 3; -# check_feasibility = false, -# ) -# @test CS.remove_below!( -# com, -# variables[constraint.indices[3]], -# 4; -# check_feasibility = false, -# ) -# @test !CS.is_constraint_violated(com, constraint, constraint.fct, constraint.set) -#end +@testset "indicator is_constraint_violated test" begin + m = Model(optimizer_with_attributes(CS.Optimizer, "no_prune" => true, "logging" => [])) + @variable(m, b, Bin) + @variable(m, -5 <= x[1:5] <= 5, Int) + @constraint(m, b => {x in CS.GeqSet()}) + optimize!(m) + com = CS.get_inner_model(m) + + constraint = com.constraints[1] + + variables = com.search_space + @test CS.fix!(com, variables[constraint.indices[1]], 1; check_feasibility = false) + @test CS.remove_above!( + com, + variables[constraint.indices[2]], + 3; + check_feasibility = false, + ) + @test CS.remove_below!( + com, + variables[constraint.indices[3]], + 4; + check_feasibility = false, + ) + @test CS.is_constraint_violated(com, constraint, constraint.fct, constraint.set) + + m = Model(optimizer_with_attributes(CS.Optimizer, "no_prune" => true, "logging" => [])) + @variable(m, b, Bin) + @variable(m, -5 <= x[1:5] <= 5, Int) + @constraint(m, b => {x in CS.GeqSet()}) + optimize!(m) + com = CS.get_inner_model(m) + + constraint = com.constraints[1] + + variables = com.search_space + @test CS.fix!(com, variables[constraint.indices[1]], 1; check_feasibility = false) + @test CS.remove_above!( + com, + variables[constraint.indices[2]], + 3; + check_feasibility = false, + ) + @test CS.remove_below!( + com, + variables[constraint.indices[3]], + 3; + check_feasibility = false, + ) + @test !CS.is_constraint_violated(com, constraint, constraint.fct, constraint.set) + + m = Model(optimizer_with_attributes(CS.Optimizer, "no_prune" => true, "logging" => [])) + @variable(m, b, Bin) + @variable(m, -5 <= x[1:5] <= 5, Int) + @constraint(m, b => {x in CS.GeqSet()}) + optimize!(m) + com = CS.get_inner_model(m) + + constraint = com.constraints[1] + + variables = com.search_space + @test CS.fix!(com, variables[constraint.indices[1]], 0; check_feasibility = false) + @test CS.remove_above!( + com, + variables[constraint.indices[2]], + 3; + check_feasibility = false, + ) + @test CS.remove_below!( + com, + variables[constraint.indices[3]], + 4; + check_feasibility = false, + ) + @test !CS.is_constraint_violated(com, constraint, constraint.fct, constraint.set) +end @testset "indicator is_constraint_violated test" begin m = Model(optimizer_with_attributes(CS.Optimizer, "backtrack" => false, "logging" => [])) From 62510700d02aa158b3491b69a9a4e626ccce4dc4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Legat?= Date: Fri, 30 Aug 2024 19:46:45 +0200 Subject: [PATCH 7/7] Fixes --- src/constraints/element1Dconst.jl | 6 ++++-- test/graph_color.jl | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/constraints/element1Dconst.jl b/src/constraints/element1Dconst.jl index a9b9c459..6d1da733 100644 --- a/src/constraints/element1Dconst.jl +++ b/src/constraints/element1Dconst.jl @@ -149,8 +149,10 @@ function prune_constraint!( end elseif change_type == :remove_above for val in change_val+1:length(T) - T_val_shifted = T[val] - z.lower_bound + 1 - zSupp[T_val_shifted] > 0 && (zSupp[T_val_shifted] -= 1) + if z.lower_bound <= T[val] <= z.upper_bound + T_val_shifted = T[val] - z.lower_bound + 1 + zSupp[T_val_shifted] > 0 && (zSupp[T_val_shifted] -= 1) + end end elseif change_type == :remove_below for val in 1:min(change_val-1, length(T)) diff --git a/test/graph_color.jl b/test/graph_color.jl index aa1491ec..f5f7adcc 100644 --- a/test/graph_color.jl +++ b/test/graph_color.jl @@ -762,7 +762,7 @@ @constraint(m, georgia != florida) # test strictly less than - @constraint(m, max_color .< states+1) + @constraint(m, max_color .< states .+ 1) @objective(m, Max, max_color)