Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Moi v0.10 #285

Merged
merged 9 commits into from
Feb 19, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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