Skip to content

Commit

Permalink
New release (#33)
Browse files Browse the repository at this point in the history
* Add usual constraints from XCSP3 (#29)

* Fix AllDifferent with param too

* AllDiff and AllEq

* Cardinality

* Channel

* Circuit

* Count

* Cumulative

* Element

* Extension

* Instantiation

* Intention (DistDifferent)

* Maximum

* Minimum

* MDD

* NValues

* No Overlap

* Ordered

* Regular

* Sum

* Test items and fixes

* Fix test items

* Update Project.toml

* Update Project.toml

* Update compat

* Fix test and printing bug for objectives (#32)

* Basic tests for MOI/JuMP

* Solve the printing issue for objectives
  • Loading branch information
Azzaare authored Jun 27, 2024
1 parent 4396243 commit 364df25
Show file tree
Hide file tree
Showing 10 changed files with 338 additions and 145 deletions.
3 changes: 2 additions & 1 deletion Project.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name = "CBLS"
uuid = "a3809bfe-37bb-4d48-a667-bac4c6be8d90"
authors = ["Jean-Francois Baffier"]
version = "0.2.0"
version = "0.2.1"

[deps]
ConstraintCommons = "e37357d9-0691-492f-a822-e5ea6a920954"
Expand All @@ -12,6 +12,7 @@ JuMP = "4076af6c-e467-56ae-b986-b466b2749572"
Lazy = "50d2b5c4-7a5e-59d5-8109-a42b560f39c0"
LocalSearchSolvers = "2b10edaa-728d-4283-ac71-07e312d6ccf3"
MathOptInterface = "b8f27783-ece8-5eb3-8dc8-9495eed66fee"
Pkg = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f"
TestItems = "1c621080-faea-4a02-84b6-bbd5e436b8fe"

[compat]
Expand Down
4 changes: 3 additions & 1 deletion src/CBLS.jl
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ using JuMP
using Lazy
using LocalSearchSolvers
using MathOptInterface
using Pkg
using TestItems

# Const
Expand All @@ -30,7 +31,8 @@ const VAR_TYPES = Union{MOI.ZeroOne, MOI.Integer}
export DiscreteSet

# Export: Constraints
export Error, Predicate
export Error
export Intention, Predicate

export AllDifferent
export AllEqual
Expand Down
177 changes: 149 additions & 28 deletions src/MOI_wrapper.jl
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
"""
JuMP.build_variable(::Function, info::JuMP.VariableInfo, set::T) where T <: MOI.AbstractScalarSet
DOCSTRING
Create a variable constrained by a scalar set.
# Arguments:
- ``: DESCRIPTION
- `info`: DESCRIPTION
- `set`: DESCRIPTION
# Arguments
- `info::JuMP.VariableInfo`: Information about the variable to be created.
- `set::T where T <: MOI.AbstractScalarSet`: The set defining the constraints on the variable.
# Returns
- `JuMP.VariableConstrainedOnCreation`: A variable constrained by the specified set.
"""
function JuMP.build_variable(
::Function,
Expand All @@ -19,12 +21,12 @@ end
"""
Optimizer <: MOI.AbstractOptimizer
DOCSTRING
Defines an optimizer for CBLS.
# Arguments:
- `solver::Solver`: DESCRIPTION
- `status::MOI.TerminationStatusCode`: DESCRIPTION
- `options::Options`: DESCRIPTION
# Fields
- `solver::LS.MainSolver`: The main solver used for local search.
- `int_vars::Set{Int}`: Set of integer variables.
- `compare_vars::Set{Int}`: Set of variables to compare.
"""
mutable struct Optimizer <: MOI.AbstractOptimizer
solver::LS.MainSolver
Expand All @@ -35,7 +37,14 @@ end
"""
Optimizer(model = Model(); options = Options())
DOCSTRING
Create an instance of the Optimizer.
# Arguments
- `model`: The model to be optimized.
- `options::Options`: Options for configuring the solver.
# Returns
- `Optimizer`: An instance of the optimizer.
"""
function Optimizer(model = model(); options = Options())
return Optimizer(
Expand All @@ -51,52 +60,104 @@ end
@forward Optimizer.solver LS._best_bound, LS.best_value, LS.is_sat, LS.get_value
@forward Optimizer.solver LS.domain_size, LS.best_values, LS._max_cons, LS.update_domain!
@forward Optimizer.solver LS.get_variable, LS.has_solution, LS.sense, LS.sense!
@forward Optimizer.solver LS.time_info, LS.status
@forward Optimizer.solver LS.time_info, LS.status, LS.length_vars

# forward functions from Solver (from Options)
@forward Optimizer.solver LS._verbose, LS.set_option!, LS.get_option

"""
MOI.get(::Optimizer, ::MOI.SolverName) = begin
MOI.get(::Optimizer, ::MOI.SolverName)
Get the name of the solver.
DOCSTRING
# Arguments
- `::Optimizer`: The optimizer instance.
# Returns
- `String`: The name of the solver.
"""
MOI.get(::Optimizer, ::MOI.SolverName) = "LocalSearchSolvers"
MOI.get(::Optimizer, ::MOI.SolverName) = "CBLS"

"""
MOI.set(::Optimizer, ::MOI.Silent, bool = true) = begin
MOI.set(::Optimizer, ::MOI.Silent, bool = true)
Set the verbosity of the solver.
DOCSTRING
# Arguments
- `::Optimizer`: The optimizer instance.
- `::MOI.Silent`: The silent option for the solver.
- `bool::Bool`: Whether to set the solver to silent mode.
# Arguments:
- ``: DESCRIPTION
- ``: DESCRIPTION
- `bool`: DESCRIPTION
# Returns
- `Nothing`
"""
MOI.set(::Optimizer, ::MOI.Silent, bool = true) = @debug "TODO: Silent"

"""
MOI.is_empty(model::Optimizer) = begin
MOI.is_empty(model::Optimizer)
Check if the model is empty.
DOCSTRING
# Arguments
- `model::Optimizer`: The optimizer instance.
# Returns
- `Bool`: True if the model is empty, false otherwise.
"""
MOI.is_empty(model::Optimizer) = LS._is_empty(model.solver)

"""
Copy constructor for the optimizer
MOI.supports_incremental_interface(::Optimizer)
Check if the optimizer supports incremental interface.
# Arguments
- `::Optimizer`: The optimizer instance.
# Returns
- `Bool`: True if the optimizer supports incremental interface, false otherwise.
"""
MOI.supports_incremental_interface(::Optimizer) = true

"""
MOI.copy_to(model::Optimizer, src::MOI.ModelLike)
Copy the source model to the optimizer.
# Arguments
- `model::Optimizer`: The optimizer instance.
- `src::MOI.ModelLike`: The source model to be copied.
# Returns
- `Nothing`
"""
function MOI.copy_to(model::Optimizer, src::MOI.ModelLike)
return MOIU.default_copy_to(model, src)
end

"""
MOI.optimize!(model::Optimizer)
Optimize the model using the optimizer.
# Arguments
- `model::Optimizer`: The optimizer instance.
# Returns
- `Nothing`
"""
MOI.optimize!(optimizer::Optimizer) = solve!(optimizer.solver)

"""
DiscreteSet(values)
Create a discrete set of values.
# Arguments
- `values::Vector{T}`: A vector of values to include in the set.
# Returns
- `DiscreteSet{T}`: A discrete set containing the specified values.
"""
struct DiscreteSet{T <: Number} <: MOI.AbstractScalarSet
values::Vector{T}
Expand All @@ -105,22 +166,82 @@ DiscreteSet(values) = DiscreteSet(collect(values))
DiscreteSet(values::T...) where {T <: Number} = DiscreteSet(collect(values))

"""
Base.copy(set::DiscreteSet) = begin
Base.copy(set::DiscreteSet)
Copy a discrete set.
# Arguments
- `set::DiscreteSet`: The discrete set to be copied.
DOCSTRING
# Returns
- `DiscreteSet`: A copy of the discrete set.
"""
Base.copy(set::DiscreteSet) = DiscreteSet(copy(set.values))

"""
MOI.empty!(opt) = begin
MOI.empty!(opt)
DOCSTRING
Empty the optimizer.
# Arguments
- `opt::Optimizer`: The optimizer instance.
# Returns
- `Nothing`
"""
MOI.empty!(opt) = empty!(opt)

"""
MOI.is_valid(optimizer::Optimizer, index::CI{VI, MOI.Integer})
Check if an index is valid for the optimizer.
# Arguments
- `optimizer::Optimizer`: The optimizer instance.
- `index::CI{VI, MOI.Integer}`: The index to be checked.
# Returns
- `Bool`: True if the index is valid, false otherwise.
"""
function MOI.is_valid(optimizer::Optimizer, index::CI{VI, MOI.Integer})
return index.value optimizer.int_vars
end

"""
Base.copy(op::F) where {F <: Function}
Copy a function.
# Arguments
- `op::F`: The function to be copied.
# Returns
- `F`: The copied function.
"""
Base.copy(op::F) where {F <: Function} = op

"""
Base.copy(::Nothing)
Copy a `Nothing` value.
# Arguments
- `::Nothing`: The `Nothing` value to be copied.
# Returns
- `Nothing`: The copied `Nothing` value.
"""
Base.copy(::Nothing) = nothing

"""
Moi.get(::Optimizer, ::MOI.SolverVersion)
Get the version of the solver, here `LocalSearchSolvers.jl`.
"""
function MOI.get(::Optimizer, ::MOI.SolverVersion)
deps = Pkg.dependencies()
local_search_solver_uuid = Base.UUID("2b10edaa-728d-4283-ac71-07e312d6ccf3")
return "v" * string(deps[local_search_solver_uuid].version)
end

MOI.get(opt::Optimizer, ::MOI.NumberOfVariables) = LS.length_vars(opt)
Loading

0 comments on commit 364df25

Please sign in to comment.