Skip to content

Commit 30f7ade

Browse files
authored
Moi v0.10 (#285)
* Porting to MOI v0.10 with bugfixes in SAF parsing constant
1 parent 170dbe4 commit 30f7ade

31 files changed

+263
-249
lines changed

CHANGELOG.md

+4-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
# ConstrainSolver.jl - Changelog
2-
2+
3+
## v0.9.0 (19th of February 2022)
4+
- Works with MathOptInterface v0.10/v1
5+
36
## v0.8.2 (6th of February 2022)
47
- Support for element constraints with a constant array like `T[y] == z`
58
- **This is experimental** Quite some stuff that might go wrong when combining it inside an indicator, reified or boolean constraint.

Project.toml

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
name = "ConstraintSolver"
22
uuid = "e0e52ebd-5523-408d-9ca3-7641f1cd1405"
33
authors = ["Ole Kröger <[email protected]>"]
4-
version = "0.8.2"
4+
version = "0.9.0"
55

66
[deps]
77
ConstraintProgrammingExtensions = "b65d079e-ed98-51d9-b0db-edee61a5c5f8"
@@ -19,13 +19,13 @@ StatsFuns = "4c63d2b9-4356-54db-8cca-17b64c39e42c"
1919
TableLogger = "72b659bb-f61b-4d0d-9dbb-0f81f57d8545"
2020

2121
[compat]
22-
ConstraintProgrammingExtensions = "^0.3"
22+
ConstraintProgrammingExtensions = "^0.6"
2323
DataStructures = "~0.11, ~0.12, ~0.13, ~0.14, ~0.15, ~0.16, ~0.17, ~0.18"
2424
Formatting = "^0.4.1"
2525
JSON = "~0.18, ~0.19, ~0.20, ~0.21"
26-
JuMP = "^0.21.3"
26+
JuMP = "^0.22"
2727
LightGraphs = "1"
28-
MathOptInterface = "^0.9.11"
28+
MathOptInterface = "^0.10, 1"
2929
MatrixNetworks = "^1"
3030
StatsBase = "^0.33"
3131
StatsFuns = "^0.9.5"

benchmark/killer_sudoku/cs.jl

+1-1
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ function solve_all(filenames; benchmark = false, single_times = true)
5555
MOI.optimize!(m)
5656
status = MOI.get(m, MOI.TerminationStatus())
5757
GC.enable(true)
58-
println(i - 1, ", ", MOI.get(m, MOI.SolveTime()))
58+
println(i - 1, ", ", MOI.get(m, MOI.SolveTimeSec()))
5959
else
6060
GC.enable(false)
6161
MOI.optimize!(m)

benchmark/sudoku/cs.jl

+1-1
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ function solve_all(grids; benchmark = false, single_times = true)
5353
MOI.optimize!(m)
5454
status = MOI.get(m, MOI.TerminationStatus())
5555
GC.enable(true)
56-
# println(i - 1, ", ", MOI.get(m, MOI.SolveTime()))
56+
# println(i - 1, ", ", MOI.get(m, MOI.SolveTimeSec()))
5757
else
5858
GC.enable(false)
5959
MOI.optimize!(m)

src/ConstraintSolver.jl

+1-2
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ using JuMP:
1818
set_lower_bound,
1919
set_upper_bound,
2020
termination_status
21-
import JuMP.sense_to_set
21+
import JuMP.operator_to_set
2222
import JuMP
2323
import ConstraintProgrammingExtensions
2424
using LightGraphs
@@ -39,7 +39,6 @@ const MOIB = MathOptInterface.Bridges
3939
const MOIBC = MathOptInterface.Bridges.Constraint
4040
const MOIU = MOI.Utilities
4141

42-
const SVF = MOI.SingleVariable
4342
const SAF = MOI.ScalarAffineFunction
4443
const VAF = MOI.VectorAffineFunction
4544

src/MOI_wrapper/Bridges/bool.jl

+11-11
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ end
4545

4646
function MOIBC.bridge_constraint(bridge::Type{<:BoolBridge{T, B, F1, F2, S1, S2}}, model, fct, set::CS.AbstractBoolSet) where {T, B, F1, F2, S1, S2}
4747
new_fct = map_function(bridge, fct, set)
48-
new_set = MOIBC.map_set(bridge, set)
48+
new_set = MOIB.map_set(bridge, set)
4949
return BoolBridge{T,B,F1,F2,S1,S2}(MOI.add_constraint(model, new_fct, new_set))
5050
end
5151

@@ -90,7 +90,7 @@ function get_mapped_fct(
9090
if direct_support
9191
return fct
9292
else
93-
return MOIBC.map_function(inner_bridge, fct)
93+
return MOIB.map_function(inner_bridge, fct)
9494
end
9595
end
9696

@@ -103,7 +103,7 @@ function get_mapped_set(
103103
if direct_support
104104
return set
105105
else
106-
return MOIBC.map_set(inner_bridge, set)
106+
return MOIB.map_set(inner_bridge, set)
107107
end
108108
end
109109

@@ -213,34 +213,34 @@ end
213213

214214
##########################
215215

216-
function MOIBC.map_set(
216+
function MOIB.map_set(
217217
bridge::Type{<:BoolBridge{T, B}},
218218
set::CS.AbstractBoolSet{F1,F2,F1dim,F2dim,S1,S2}
219219
) where {T,B,F1,F2,F1dim,F2dim,S1<:AbstractBoolSet,S2<:AbstractBoolSet}
220-
lhs_set = MOIBC.map_set(bridge, set.lhs_set)
221-
rhs_set = MOIBC.map_set(bridge, set.rhs_set)
220+
lhs_set = MOIB.map_set(bridge, set.lhs_set)
221+
rhs_set = MOIB.map_set(bridge, set.rhs_set)
222222
return typeof_without_params(set){F1,F2}(lhs_set, rhs_set)
223223
end
224224

225-
function MOIBC.map_set(
225+
function MOIB.map_set(
226226
bridge::Type{<:BoolBridge{T, B}},
227227
set::CS.AbstractBoolSet{F1,F2,F1dim,F2dim,S1,S2}
228228
) where {T,B,F1,F2,F1dim,F2dim,S1<:AbstractBoolSet,S2}
229-
lhs_set = MOIBC.map_set(bridge, set.lhs_set)
229+
lhs_set = MOIB.map_set(bridge, set.lhs_set)
230230
rhs_set = get_mapped_set(B, F2, S2, set.rhs_set)
231231
return typeof_without_params(set){F1,F2}(lhs_set, rhs_set)
232232
end
233233

234-
function MOIBC.map_set(
234+
function MOIB.map_set(
235235
bridge::Type{<:BoolBridge{T, B}},
236236
set::CS.AbstractBoolSet{F1,F2,F1dim,F2dim,S1,S2}
237237
) where {T,B,F1,F2,F1dim,F2dim,S1,S2<:AbstractBoolSet}
238238
lhs_set = get_mapped_set(B, F1, S1, set.lhs_set)
239-
rhs_set = MOIBC.map_set(bridge, set.rhs_set)
239+
rhs_set = MOIB.map_set(bridge, set.rhs_set)
240240
return typeof_without_params(set){F1,F2}(lhs_set, rhs_set)
241241
end
242242

243-
function MOIBC.map_set(
243+
function MOIB.map_set(
244244
bridge::Type{<:BoolBridge{T, B}},
245245
set::CS.AbstractBoolSet{F1,F2,F1dim,F2dim,S1,S2}
246246
) where {T,B,F1,F2,F1dim,F2dim,S1,S2}

src/MOI_wrapper/Bridges/complement.jl

+5-5
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ end
5050

5151
function MOIBC.bridge_constraint(::Type{<:ComplementBridge{T, B, F, S}}, model, fct, set) where {T, B, F, S}
5252
new_fct = map_function(B, fct, set.set)
53-
new_inner_set = MOIBC.map_set(B, set.set)
53+
new_inner_set = MOIB.map_set(B, set.set)
5454
new_set = CS.ComplementSet{F}(new_inner_set)
5555
if (new_fct isa SAF) && F <: SAF
5656
new_fct = get_saf(new_fct)
@@ -66,17 +66,17 @@ function map_function(
6666
return map_function(B, fct, set.set)
6767
end
6868

69-
function MOIBC.map_function(
69+
function MOIB.map_function(
7070
bridge::Type{<:ComplementBridge{T, B}},
7171
fct,
7272
) where {T,B}
73-
return MOIBC.map_function(B, fct)
73+
return MOIB.map_function(B, fct)
7474
end
7575

76-
function MOIBC.map_set(
76+
function MOIB.map_set(
7777
bridge::Type{<:ComplementBridge{T, B}},
7878
set::ComplementSet{F},
7979
) where {T,B,F}
80-
mapped_set = MOIBC.map_set(B, set.set)
80+
mapped_set = MOIB.map_set(B, set.set)
8181
return ComplementSet{F}(mapped_set)
8282
end

src/MOI_wrapper/Bridges/indicator.jl

+16-16
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ end
55
function MOI.supports_constraint(
66
::Type{<:IndicatorBridge{T, B}},
77
::Type{F},
8-
::Type{MOI.IndicatorSet{A,S}}
8+
::Type{MOI.Indicator{A,S}}
99
) where {T, B, F<:MOI.VectorAffineFunction, A, S}
1010
is_supported = MOI.supports_constraint(B, MOIU.scalar_type(F), S)
1111
!is_supported && return false
@@ -18,7 +18,7 @@ end
1818
function MOI.supports_constraint(
1919
::Type{<:IndicatorBridge{T, B}},
2020
::Type{F},
21-
::Type{CS.IndicatorSet{A,IF,S}}
21+
::Type{CS.Indicator{A,IF,S}}
2222
) where {T, B, F<:MOI.VectorAffineFunction, A, IF, S}
2323
is_supported = MOI.supports_constraint(B, IF, S)
2424
!is_supported && return false
@@ -32,18 +32,18 @@ function MOIBC.concrete_bridge_type(
3232
IB::Type{<:IndicatorBridge{T,B}},
3333
G::Type{<:MOI.VectorAffineFunction},
3434
::Type{IS},
35-
) where {T,B,A,S,IS<:MOI.IndicatorSet{A,S}}
35+
) where {T,B,A,S,IS<:MOI.Indicator{A,S}}
3636
concrete_B = get_concrete_B(IB,S)
37-
return IndicatorBridge{T,concrete_B,A,MOI.IndicatorSet,MOI.ScalarAffineFunction,S}
37+
return IndicatorBridge{T,concrete_B,A,MOI.Indicator,MOI.ScalarAffineFunction,S}
3838
end
3939

4040
function MOIBC.concrete_bridge_type(
4141
IB::Type{<:IndicatorBridge{T,B}},
4242
G::Type{<:MOI.VectorAffineFunction},
4343
::Type{IS},
44-
) where {T,B,A,S,IF,IS<:CS.IndicatorSet{A,IF,S}}
44+
) where {T,B,A,S,IF,IS<:CS.Indicator{A,IF,S}}
4545
concrete_B = get_concrete_B(IB,S)
46-
return IndicatorBridge{T,concrete_B,A,CS.IndicatorSet,IF,S}
46+
return IndicatorBridge{T,concrete_B,A,CS.Indicator,IF,S}
4747
end
4848

4949
function get_concrete_B(
@@ -59,36 +59,36 @@ end
5959

6060
function MOIB.added_constraint_types(
6161
::Type{<:IndicatorBridge{T,B,A,IS_MOI_OR_CS,F,S}}
62-
) where {T,B,A,IS_MOI_OR_CS<:MOI.IndicatorSet,F,S}
62+
) where {T,B,A,IS_MOI_OR_CS<:MOI.Indicator,F,S}
6363
added_constraints = added_constraint_types(B, S)
64-
return [(MOI.VectorAffineFunction{T}, MOI.IndicatorSet{A,added_constraints[1][2]})]
64+
return [(MOI.VectorAffineFunction{T}, MOI.Indicator{A,added_constraints[1][2]})]
6565
end
6666

6767
function MOIB.added_constraint_types(
6868
::Type{<:IndicatorBridge{T,B,A,IS_MOI_OR_CS,F,S}}
69-
) where {T,B,A,IS_MOI_OR_CS<:CS.IndicatorSet,F,S}
69+
) where {T,B,A,IS_MOI_OR_CS<:CS.Indicator,F,S}
7070
added_constraints = added_constraint_types(B, S)
71-
return [(MOI.VectorAffineFunction{T}, CS.IndicatorSet{A,F,added_constraints[1][2]})]
71+
return [(MOI.VectorAffineFunction{T}, CS.Indicator{A,F,added_constraints[1][2]})]
7272
end
7373

7474

7575
function MOIB.added_constrained_variable_types(::Type{<:IndicatorBridge{T,B}}) where {T,B}
7676
return MOIB.added_constrained_variable_types(B)
7777
end
7878

79-
function MOIBC.bridge_constraint(::Type{<:IndicatorBridge{T, B, A, IS_MOI_OR_CS, F, S}}, model, func, set) where {T, B, A, IS_MOI_OR_CS<:MOI.IndicatorSet, F, S}
79+
function MOIBC.bridge_constraint(::Type{<:IndicatorBridge{T, B, A, IS_MOI_OR_CS, F, S}}, model, func, set) where {T, B, A, IS_MOI_OR_CS<:MOI.Indicator, F, S}
8080
f = MOIU.eachscalar(func)
8181
new_func = MOIU.operate(vcat, T, f[1], map_function(B, f[2:end], set.set))
82-
new_inner_set = MOIBC.map_set(B, set.set)
83-
new_set = MOI.IndicatorSet{A}(new_inner_set)
82+
new_inner_set = MOIB.map_set(B, set.set)
83+
new_set = MOI.Indicator{A}(new_inner_set)
8484
return IndicatorBridge{T,B,A,IS_MOI_OR_CS,F,S}(MOI.add_constraint(model, new_func, new_set))
8585
end
8686

87-
function MOIBC.bridge_constraint(::Type{<:IndicatorBridge{T, B, A, IS_MOI_OR_CS, F, S}}, model, func, set) where {T, B, A, IS_MOI_OR_CS<:CS.IndicatorSet, F, S}
87+
function MOIBC.bridge_constraint(::Type{<:IndicatorBridge{T, B, A, IS_MOI_OR_CS, F, S}}, model, func, set) where {T, B, A, IS_MOI_OR_CS<:CS.Indicator, F, S}
8888
f = MOIU.eachscalar(func)
8989
new_func = MOIU.operate(vcat, T, f[1], map_function(B, f[2:end], set.set))
90-
new_inner_set = MOIBC.map_set(B, set.set)
91-
new_set = CS.IndicatorSet{A,F}(new_inner_set)
90+
new_inner_set = MOIB.map_set(B, set.set)
91+
new_set = CS.Indicator{A,F}(new_inner_set)
9292
return IndicatorBridge{T,B,A,IS_MOI_OR_CS,F,S}(MOI.add_constraint(model, new_func, new_set))
9393
end
9494

src/MOI_wrapper/Bridges/reified.jl

+5-5
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ end
55
function MOI.supports_constraint(
66
::Type{<:ReifiedBridge{T, B}},
77
::Type{F},
8-
::Type{<:CS.ReifiedSet{A,RF,S}}
8+
::Type{<:CS.Reified{A,RF,S}}
99
) where {T, B, F<:MOI.VectorAffineFunction, A, RF, S}
1010
is_supported = MOI.supports_constraint(B, RF, S)
1111
!is_supported && return false
@@ -20,7 +20,7 @@ function MOIBC.concrete_bridge_type(
2020
::Type{<:ReifiedBridge{T,B}},
2121
G::Type{<:MOI.VectorAffineFunction},
2222
::Type{IS},
23-
) where {T,B,A,F,S,IS<:CS.ReifiedSet{A,F,S}}
23+
) where {T,B,A,F,S,IS<:CS.Reified{A,F,S}}
2424
if S <: AbstractBoolSet
2525
concrete_B = B
2626
else
@@ -37,7 +37,7 @@ function MOIB.added_constraint_types(
3737
else
3838
added_constraints = MOIB.added_constraint_types(B)
3939
end
40-
return [(MOI.VectorAffineFunction{T}, CS.ReifiedSet{A,F,added_constraints[1][2]})]
40+
return [(MOI.VectorAffineFunction{T}, CS.Reified{A,F,added_constraints[1][2]})]
4141
end
4242

4343
function MOIB.added_constrained_variable_types(::Type{<:ReifiedBridge{T,B}}) where {T,B}
@@ -47,7 +47,7 @@ end
4747
function MOIBC.bridge_constraint(::Type{<:ReifiedBridge{T, B, A, F, S}}, model, func, set) where {T, B, A, F, S}
4848
f = MOIU.eachscalar(func)
4949
new_func = MOIU.operate(vcat, T, f[1], map_function(B, f[2:end], set.set))
50-
new_inner_set = MOIBC.map_set(B, set.set)
51-
new_set = CS.ReifiedSet{A,F,typeof(new_inner_set)}(new_inner_set, 1+MOI.dimension(new_inner_set))
50+
new_inner_set = MOIB.map_set(B, set.set)
51+
new_set = CS.Reified{A,F,typeof(new_inner_set)}(new_inner_set, 1+MOI.dimension(new_inner_set))
5252
return ReifiedBridge{T,B,A,F,S}(MOI.add_constraint(model, new_func, new_set))
5353
end

src/MOI_wrapper/Bridges/strictly_greater_than.jl

+2-2
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,10 @@ struct StrictlyGreaterToStrictlyLessBridge{
55
} <: MOIBC.FlipSignBridge{T,CPE.Strictly{MOI.GreaterThan{T},T},CPE.Strictly{MOI.LessThan{T}, T},F,G}
66
constraint::CI{F,CPE.Strictly{MOI.LessThan{T}, T}}
77
end
8-
function MOIBC.map_set(::Type{<:StrictlyGreaterToStrictlyLessBridge}, set::CPE.Strictly{MOI.GreaterThan{T}, T}) where T
8+
function MOIB.map_set(::Type{<:StrictlyGreaterToStrictlyLessBridge}, set::CPE.Strictly{MOI.GreaterThan{T}, T}) where T
99
return CPE.Strictly(MOI.LessThan(-set.set.lower))
1010
end
11-
function MOIBC.inverse_map_set(::Type{<:StrictlyGreaterToStrictlyLessBridge}, set::CPE.Strictly{MOI.LessThan{T}, T}) where T
11+
function MOIB.inverse_map_set(::Type{<:StrictlyGreaterToStrictlyLessBridge}, set::CPE.Strictly{MOI.LessThan{T}, T}) where T
1212
return CPE.Strictly(MOI.GreaterThan(-set.set.upper))
1313
end
1414
function MOIBC.concrete_bridge_type(

src/MOI_wrapper/Bridges/util.jl

+2-2
Original file line numberDiff line numberDiff line change
@@ -25,15 +25,15 @@ end
2525
"""
2626
map_function(bridge, fct, set)
2727
28-
Default for when set is not needed so return `MOIBC.map_function(bridge, fct)`
28+
Default for when set is not needed so return `MOIB.map_function(bridge, fct)`
2929
If the set is needed a specific method should be implemented
3030
"""
3131
function map_function(
3232
bridge::Type{<:MOIBC.AbstractBridge},
3333
fct,
3434
set
3535
)
36-
MOIBC.map_function(bridge, fct)
36+
MOIB.map_function(bridge, fct)
3737
end
3838

3939
"""

src/MOI_wrapper/MOI_wrapper.jl

+7-7
Original file line numberDiff line numberDiff line change
@@ -89,20 +89,20 @@ end
8989
"""
9090
Copy constructor for the optimizer
9191
"""
92-
MOIU.supports_default_copy_to(model::Optimizer, copy_names::Bool) = !copy_names
93-
function MOI.copy_to(model::Optimizer, src::MOI.ModelLike; kws...)
94-
return MOIU.automatic_copy_to(model, src; kws...)
92+
MOI.supports_incremental_interface(model::Optimizer) = true
93+
function MOI.copy_to(model::Optimizer, src::MOI.ModelLike)
94+
return MOIU.default_copy_to(model, src)
9595
end
9696

97-
MOI.supports(::Optimizer, ::MOI.RawParameter) = true
97+
MOI.supports(::Optimizer, ::MOI.RawOptimizerAttribute) = true
9898
MOI.supports(::Optimizer, ::MOI.TimeLimitSec) = true
9999

100100
"""
101-
MOI.set(model::Optimizer, p::MOI.RawParameter, value)
101+
MOI.set(model::Optimizer, p::MOI.RawOptimizerAttribute, value)
102102
103-
Set a RawParameter to `value`
103+
Set a RawOptimizerAttribute to `value`
104104
"""
105-
function MOI.set(model::Optimizer, p::MOI.RawParameter, value)
105+
function MOI.set(model::Optimizer, p::MOI.RawOptimizerAttribute, value)
106106
current_options_type = SolverOptions
107107
current_options_obj = model.options
108108
p_symbol = Symbol(p.name)

src/MOI_wrapper/bool.jl

+5-5
Original file line numberDiff line numberDiff line change
@@ -55,15 +55,15 @@ function parse_bool_constraint(_error, bool_val::BOOL_VALS, lhs, rhs)
5555
lhs = transform_binary_expr(lhs)
5656

5757
lhs_vectorized, lhs_parsecode, lhs_buildcall =
58-
JuMP.parse_constraint_expr(_error, lhs)
58+
JuMP.parse_constraint(_error, lhs)
5959

6060
if lhs_vectorized
6161
_error("`$(lhs)` should be non vectorized. There is currently no vectorized support for `and` constraints. Please open an issue at ConstraintSolver.jl")
6262
end
6363

6464
rhs = transform_binary_expr(rhs)
6565
rhs_vectorized, rhs_parsecode, rhs_buildcall =
66-
JuMP.parse_constraint_expr(_error1, rhs)
66+
JuMP.parse_constraint(_error1, rhs)
6767

6868
if rhs_vectorized
6969
_error("`$(rhs)` should be non vectorized. There is currently no vectorized support for `and` constraints. Please open an issue at ConstraintSolver.jl")
@@ -91,8 +91,8 @@ function JuMP.parse_constraint_head(_error::Function, bool_val::BOOL_VALS, lhs,
9191
return parse_bool_constraint(_error, bool_val, lhs, rhs)
9292
end
9393

94-
function JuMP.parse_one_operator_constraint(_error::Function, vectorized::Bool, bool_val::BOOL_VALS, lhs, rhs)
94+
function JuMP.parse_constraint_call(_error::Function, vectorized::Bool, bool_val::BOOL_VALS, lhs, rhs)
9595
@assert !vectorized
96-
v,c,b = parse_bool_constraint(_error, bool_val, lhs, rhs)
97-
return c,b
96+
_, parse_code, build_code = parse_bool_constraint(_error, bool_val, lhs, rhs)
97+
return parse_code, build_code
9898
end

0 commit comments

Comments
 (0)