Skip to content

Commit

Permalink
Moi v0.10 (#285)
Browse files Browse the repository at this point in the history
* Porting to MOI v0.10 with bugfixes in SAF parsing constant
  • Loading branch information
Wikunia committed Feb 19, 2022
1 parent 170dbe4 commit 30f7ade
Show file tree
Hide file tree
Showing 31 changed files with 263 additions and 249 deletions.
5 changes: 4 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
# ConstrainSolver.jl - Changelog


## v0.9.0 (19th of February 2022)
- Works with MathOptInterface v0.10/v1

## v0.8.2 (6th of February 2022)
- Support for element constraints with a constant array like `T[y] == z`
- **This is experimental** Quite some stuff that might go wrong when combining it inside an indicator, reified or boolean constraint.
Expand Down
8 changes: 4 additions & 4 deletions Project.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name = "ConstraintSolver"
uuid = "e0e52ebd-5523-408d-9ca3-7641f1cd1405"
authors = ["Ole Kröger <o.kroeger@opensourc.es>"]
version = "0.8.2"
version = "0.9.0"

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

[compat]
ConstraintProgrammingExtensions = "^0.3"
ConstraintProgrammingExtensions = "^0.6"
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"
JuMP = "^0.21.3"
JuMP = "^0.22"
LightGraphs = "1"
MathOptInterface = "^0.9.11"
MathOptInterface = "^0.10, 1"
MatrixNetworks = "^1"
StatsBase = "^0.33"
StatsFuns = "^0.9.5"
Expand Down
2 changes: 1 addition & 1 deletion benchmark/killer_sudoku/cs.jl
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ function solve_all(filenames; benchmark = false, single_times = true)
MOI.optimize!(m)
status = MOI.get(m, MOI.TerminationStatus())
GC.enable(true)
println(i - 1, ", ", MOI.get(m, MOI.SolveTime()))
println(i - 1, ", ", MOI.get(m, MOI.SolveTimeSec()))
else
GC.enable(false)
MOI.optimize!(m)
Expand Down
2 changes: 1 addition & 1 deletion benchmark/sudoku/cs.jl
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ function solve_all(grids; benchmark = false, single_times = true)
MOI.optimize!(m)
status = MOI.get(m, MOI.TerminationStatus())
GC.enable(true)
# println(i - 1, ", ", MOI.get(m, MOI.SolveTime()))
# println(i - 1, ", ", MOI.get(m, MOI.SolveTimeSec()))
else
GC.enable(false)
MOI.optimize!(m)
Expand Down
3 changes: 1 addition & 2 deletions src/ConstraintSolver.jl
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ using JuMP:
set_lower_bound,
set_upper_bound,
termination_status
import JuMP.sense_to_set
import JuMP.operator_to_set
import JuMP
import ConstraintProgrammingExtensions
using LightGraphs
Expand All @@ -39,7 +39,6 @@ const MOIB = MathOptInterface.Bridges
const MOIBC = MathOptInterface.Bridges.Constraint
const MOIU = MOI.Utilities

const SVF = MOI.SingleVariable
const SAF = MOI.ScalarAffineFunction
const VAF = MOI.VectorAffineFunction

Expand Down
22 changes: 11 additions & 11 deletions src/MOI_wrapper/Bridges/bool.jl
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ end

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}
new_fct = map_function(bridge, fct, set)
new_set = MOIBC.map_set(bridge, set)
new_set = MOIB.map_set(bridge, set)
return BoolBridge{T,B,F1,F2,S1,S2}(MOI.add_constraint(model, new_fct, new_set))
end

Expand Down Expand Up @@ -90,7 +90,7 @@ function get_mapped_fct(
if direct_support
return fct
else
return MOIBC.map_function(inner_bridge, fct)
return MOIB.map_function(inner_bridge, fct)
end
end

Expand All @@ -103,7 +103,7 @@ function get_mapped_set(
if direct_support
return set
else
return MOIBC.map_set(inner_bridge, set)
return MOIB.map_set(inner_bridge, set)
end
end

Expand Down Expand Up @@ -213,34 +213,34 @@ end

##########################

function MOIBC.map_set(
function MOIB.map_set(
bridge::Type{<:BoolBridge{T, B}},
set::CS.AbstractBoolSet{F1,F2,F1dim,F2dim,S1,S2}
) where {T,B,F1,F2,F1dim,F2dim,S1<:AbstractBoolSet,S2<:AbstractBoolSet}
lhs_set = MOIBC.map_set(bridge, set.lhs_set)
rhs_set = MOIBC.map_set(bridge, set.rhs_set)
lhs_set = MOIB.map_set(bridge, set.lhs_set)
rhs_set = MOIB.map_set(bridge, set.rhs_set)
return typeof_without_params(set){F1,F2}(lhs_set, rhs_set)
end

function MOIBC.map_set(
function MOIB.map_set(
bridge::Type{<:BoolBridge{T, B}},
set::CS.AbstractBoolSet{F1,F2,F1dim,F2dim,S1,S2}
) where {T,B,F1,F2,F1dim,F2dim,S1<:AbstractBoolSet,S2}
lhs_set = MOIBC.map_set(bridge, set.lhs_set)
lhs_set = MOIB.map_set(bridge, set.lhs_set)
rhs_set = get_mapped_set(B, F2, S2, set.rhs_set)
return typeof_without_params(set){F1,F2}(lhs_set, rhs_set)
end

function MOIBC.map_set(
function MOIB.map_set(
bridge::Type{<:BoolBridge{T, B}},
set::CS.AbstractBoolSet{F1,F2,F1dim,F2dim,S1,S2}
) where {T,B,F1,F2,F1dim,F2dim,S1,S2<:AbstractBoolSet}
lhs_set = get_mapped_set(B, F1, S1, set.lhs_set)
rhs_set = MOIBC.map_set(bridge, set.rhs_set)
rhs_set = MOIB.map_set(bridge, set.rhs_set)
return typeof_without_params(set){F1,F2}(lhs_set, rhs_set)
end

function MOIBC.map_set(
function MOIB.map_set(
bridge::Type{<:BoolBridge{T, B}},
set::CS.AbstractBoolSet{F1,F2,F1dim,F2dim,S1,S2}
) where {T,B,F1,F2,F1dim,F2dim,S1,S2}
Expand Down
10 changes: 5 additions & 5 deletions src/MOI_wrapper/Bridges/complement.jl
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ end

function MOIBC.bridge_constraint(::Type{<:ComplementBridge{T, B, F, S}}, model, fct, set) where {T, B, F, S}
new_fct = map_function(B, fct, set.set)
new_inner_set = MOIBC.map_set(B, set.set)
new_inner_set = MOIB.map_set(B, set.set)
new_set = CS.ComplementSet{F}(new_inner_set)
if (new_fct isa SAF) && F <: SAF
new_fct = get_saf(new_fct)
Expand All @@ -66,17 +66,17 @@ function map_function(
return map_function(B, fct, set.set)
end

function MOIBC.map_function(
function MOIB.map_function(
bridge::Type{<:ComplementBridge{T, B}},
fct,
) where {T,B}
return MOIBC.map_function(B, fct)
return MOIB.map_function(B, fct)
end

function MOIBC.map_set(
function MOIB.map_set(
bridge::Type{<:ComplementBridge{T, B}},
set::ComplementSet{F},
) where {T,B,F}
mapped_set = MOIBC.map_set(B, set.set)
mapped_set = MOIB.map_set(B, set.set)
return ComplementSet{F}(mapped_set)
end
32 changes: 16 additions & 16 deletions src/MOI_wrapper/Bridges/indicator.jl
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ end
function MOI.supports_constraint(
::Type{<:IndicatorBridge{T, B}},
::Type{F},
::Type{MOI.IndicatorSet{A,S}}
::Type{MOI.Indicator{A,S}}
) where {T, B, F<:MOI.VectorAffineFunction, A, S}
is_supported = MOI.supports_constraint(B, MOIU.scalar_type(F), S)
!is_supported && return false
Expand All @@ -18,7 +18,7 @@ end
function MOI.supports_constraint(
::Type{<:IndicatorBridge{T, B}},
::Type{F},
::Type{CS.IndicatorSet{A,IF,S}}
::Type{CS.Indicator{A,IF,S}}
) where {T, B, F<:MOI.VectorAffineFunction, A, IF, S}
is_supported = MOI.supports_constraint(B, IF, S)
!is_supported && return false
Expand All @@ -32,18 +32,18 @@ function MOIBC.concrete_bridge_type(
IB::Type{<:IndicatorBridge{T,B}},
G::Type{<:MOI.VectorAffineFunction},
::Type{IS},
) where {T,B,A,S,IS<:MOI.IndicatorSet{A,S}}
) where {T,B,A,S,IS<:MOI.Indicator{A,S}}
concrete_B = get_concrete_B(IB,S)
return IndicatorBridge{T,concrete_B,A,MOI.IndicatorSet,MOI.ScalarAffineFunction,S}
return IndicatorBridge{T,concrete_B,A,MOI.Indicator,MOI.ScalarAffineFunction,S}
end

function MOIBC.concrete_bridge_type(
IB::Type{<:IndicatorBridge{T,B}},
G::Type{<:MOI.VectorAffineFunction},
::Type{IS},
) where {T,B,A,S,IF,IS<:CS.IndicatorSet{A,IF,S}}
) where {T,B,A,S,IF,IS<:CS.Indicator{A,IF,S}}
concrete_B = get_concrete_B(IB,S)
return IndicatorBridge{T,concrete_B,A,CS.IndicatorSet,IF,S}
return IndicatorBridge{T,concrete_B,A,CS.Indicator,IF,S}
end

function get_concrete_B(
Expand All @@ -59,36 +59,36 @@ end

function MOIB.added_constraint_types(
::Type{<:IndicatorBridge{T,B,A,IS_MOI_OR_CS,F,S}}
) where {T,B,A,IS_MOI_OR_CS<:MOI.IndicatorSet,F,S}
) where {T,B,A,IS_MOI_OR_CS<:MOI.Indicator,F,S}
added_constraints = added_constraint_types(B, S)
return [(MOI.VectorAffineFunction{T}, MOI.IndicatorSet{A,added_constraints[1][2]})]
return [(MOI.VectorAffineFunction{T}, MOI.Indicator{A,added_constraints[1][2]})]
end

function MOIB.added_constraint_types(
::Type{<:IndicatorBridge{T,B,A,IS_MOI_OR_CS,F,S}}
) where {T,B,A,IS_MOI_OR_CS<:CS.IndicatorSet,F,S}
) where {T,B,A,IS_MOI_OR_CS<:CS.Indicator,F,S}
added_constraints = added_constraint_types(B, S)
return [(MOI.VectorAffineFunction{T}, CS.IndicatorSet{A,F,added_constraints[1][2]})]
return [(MOI.VectorAffineFunction{T}, CS.Indicator{A,F,added_constraints[1][2]})]
end


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

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}
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}
f = MOIU.eachscalar(func)
new_func = MOIU.operate(vcat, T, f[1], map_function(B, f[2:end], set.set))
new_inner_set = MOIBC.map_set(B, set.set)
new_set = MOI.IndicatorSet{A}(new_inner_set)
new_inner_set = MOIB.map_set(B, set.set)
new_set = MOI.Indicator{A}(new_inner_set)
return IndicatorBridge{T,B,A,IS_MOI_OR_CS,F,S}(MOI.add_constraint(model, new_func, new_set))
end

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}
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}
f = MOIU.eachscalar(func)
new_func = MOIU.operate(vcat, T, f[1], map_function(B, f[2:end], set.set))
new_inner_set = MOIBC.map_set(B, set.set)
new_set = CS.IndicatorSet{A,F}(new_inner_set)
new_inner_set = MOIB.map_set(B, set.set)
new_set = CS.Indicator{A,F}(new_inner_set)
return IndicatorBridge{T,B,A,IS_MOI_OR_CS,F,S}(MOI.add_constraint(model, new_func, new_set))
end

10 changes: 5 additions & 5 deletions src/MOI_wrapper/Bridges/reified.jl
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ end
function MOI.supports_constraint(
::Type{<:ReifiedBridge{T, B}},
::Type{F},
::Type{<:CS.ReifiedSet{A,RF,S}}
::Type{<:CS.Reified{A,RF,S}}
) where {T, B, F<:MOI.VectorAffineFunction, A, RF, S}
is_supported = MOI.supports_constraint(B, RF, S)
!is_supported && return false
Expand All @@ -20,7 +20,7 @@ function MOIBC.concrete_bridge_type(
::Type{<:ReifiedBridge{T,B}},
G::Type{<:MOI.VectorAffineFunction},
::Type{IS},
) where {T,B,A,F,S,IS<:CS.ReifiedSet{A,F,S}}
) where {T,B,A,F,S,IS<:CS.Reified{A,F,S}}
if S <: AbstractBoolSet
concrete_B = B
else
Expand All @@ -37,7 +37,7 @@ function MOIB.added_constraint_types(
else
added_constraints = MOIB.added_constraint_types(B)
end
return [(MOI.VectorAffineFunction{T}, CS.ReifiedSet{A,F,added_constraints[1][2]})]
return [(MOI.VectorAffineFunction{T}, CS.Reified{A,F,added_constraints[1][2]})]
end

function MOIB.added_constrained_variable_types(::Type{<:ReifiedBridge{T,B}}) where {T,B}
Expand All @@ -47,7 +47,7 @@ end
function MOIBC.bridge_constraint(::Type{<:ReifiedBridge{T, B, A, F, S}}, model, func, set) where {T, B, A, F, S}
f = MOIU.eachscalar(func)
new_func = MOIU.operate(vcat, T, f[1], map_function(B, f[2:end], set.set))
new_inner_set = MOIBC.map_set(B, set.set)
new_set = CS.ReifiedSet{A,F,typeof(new_inner_set)}(new_inner_set, 1+MOI.dimension(new_inner_set))
new_inner_set = MOIB.map_set(B, set.set)
new_set = CS.Reified{A,F,typeof(new_inner_set)}(new_inner_set, 1+MOI.dimension(new_inner_set))
return ReifiedBridge{T,B,A,F,S}(MOI.add_constraint(model, new_func, new_set))
end
4 changes: 2 additions & 2 deletions src/MOI_wrapper/Bridges/strictly_greater_than.jl
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@ struct StrictlyGreaterToStrictlyLessBridge{
} <: MOIBC.FlipSignBridge{T,CPE.Strictly{MOI.GreaterThan{T},T},CPE.Strictly{MOI.LessThan{T}, T},F,G}
constraint::CI{F,CPE.Strictly{MOI.LessThan{T}, T}}
end
function MOIBC.map_set(::Type{<:StrictlyGreaterToStrictlyLessBridge}, set::CPE.Strictly{MOI.GreaterThan{T}, T}) where T
function MOIB.map_set(::Type{<:StrictlyGreaterToStrictlyLessBridge}, set::CPE.Strictly{MOI.GreaterThan{T}, T}) where T
return CPE.Strictly(MOI.LessThan(-set.set.lower))
end
function MOIBC.inverse_map_set(::Type{<:StrictlyGreaterToStrictlyLessBridge}, set::CPE.Strictly{MOI.LessThan{T}, T}) where T
function MOIB.inverse_map_set(::Type{<:StrictlyGreaterToStrictlyLessBridge}, set::CPE.Strictly{MOI.LessThan{T}, T}) where T
return CPE.Strictly(MOI.GreaterThan(-set.set.upper))
end
function MOIBC.concrete_bridge_type(
Expand Down
4 changes: 2 additions & 2 deletions src/MOI_wrapper/Bridges/util.jl
Original file line number Diff line number Diff line change
Expand Up @@ -25,15 +25,15 @@ end
"""
map_function(bridge, fct, set)
Default for when set is not needed so return `MOIBC.map_function(bridge, fct)`
Default for when set is not needed so return `MOIB.map_function(bridge, fct)`
If the set is needed a specific method should be implemented
"""
function map_function(
bridge::Type{<:MOIBC.AbstractBridge},
fct,
set
)
MOIBC.map_function(bridge, fct)
MOIB.map_function(bridge, fct)
end

"""
Expand Down
14 changes: 7 additions & 7 deletions src/MOI_wrapper/MOI_wrapper.jl
Original file line number Diff line number Diff line change
Expand Up @@ -89,20 +89,20 @@ end
"""
Copy constructor for the optimizer
"""
MOIU.supports_default_copy_to(model::Optimizer, copy_names::Bool) = !copy_names
function MOI.copy_to(model::Optimizer, src::MOI.ModelLike; kws...)
return MOIU.automatic_copy_to(model, src; kws...)
MOI.supports_incremental_interface(model::Optimizer) = true
function MOI.copy_to(model::Optimizer, src::MOI.ModelLike)
return MOIU.default_copy_to(model, src)
end

MOI.supports(::Optimizer, ::MOI.RawParameter) = true
MOI.supports(::Optimizer, ::MOI.RawOptimizerAttribute) = true
MOI.supports(::Optimizer, ::MOI.TimeLimitSec) = true

"""
MOI.set(model::Optimizer, p::MOI.RawParameter, value)
MOI.set(model::Optimizer, p::MOI.RawOptimizerAttribute, value)
Set a RawParameter to `value`
Set a RawOptimizerAttribute to `value`
"""
function MOI.set(model::Optimizer, p::MOI.RawParameter, value)
function MOI.set(model::Optimizer, p::MOI.RawOptimizerAttribute, value)
current_options_type = SolverOptions
current_options_obj = model.options
p_symbol = Symbol(p.name)
Expand Down
10 changes: 5 additions & 5 deletions src/MOI_wrapper/bool.jl
Original file line number Diff line number Diff line change
Expand Up @@ -55,15 +55,15 @@ function parse_bool_constraint(_error, bool_val::BOOL_VALS, lhs, rhs)
lhs = transform_binary_expr(lhs)

lhs_vectorized, lhs_parsecode, lhs_buildcall =
JuMP.parse_constraint_expr(_error, lhs)
JuMP.parse_constraint(_error, lhs)

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

rhs = transform_binary_expr(rhs)
rhs_vectorized, rhs_parsecode, rhs_buildcall =
JuMP.parse_constraint_expr(_error1, rhs)
JuMP.parse_constraint(_error1, rhs)

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

function JuMP.parse_one_operator_constraint(_error::Function, vectorized::Bool, bool_val::BOOL_VALS, lhs, rhs)
function JuMP.parse_constraint_call(_error::Function, vectorized::Bool, bool_val::BOOL_VALS, lhs, rhs)
@assert !vectorized
v,c,b = parse_bool_constraint(_error, bool_val, lhs, rhs)
return c,b
_, parse_code, build_code = parse_bool_constraint(_error, bool_val, lhs, rhs)
return parse_code, build_code
end
Loading

0 comments on commit 30f7ade

Please sign in to comment.