From e40f871c7d24ab8ab80a85ada2e4caac0bf94d95 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Legat?= Date: Sun, 23 Jun 2019 16:35:04 +0200 Subject: [PATCH 1/6] Add MOI.add to add attribute --- src/attributes.jl | 78 ++++++++++++++++++++++++++++++++++++++++++++++- src/indextypes.jl | 13 +++++++- 2 files changed, 89 insertions(+), 2 deletions(-) diff --git a/src/attributes.jl b/src/attributes.jl index 038a25903e..258d4d2d91 100644 --- a/src/attributes.jl +++ b/src/attributes.jl @@ -74,6 +74,24 @@ SetAttributeNotAllowed(attr::AnyAttribute) = SetAttributeNotAllowed(attr, "") operation_name(err::SetAttributeNotAllowed) = "Setting attribute $(err.attr)" message(err::SetAttributeNotAllowed) = err.message +""" + struct AddAttributeNotAllowed{AttrType} <: NotAllowedError + attr::AttrType + message::String # Human-friendly explanation why the attribute cannot be set + end + +An error indicating that the attribute `attr` is supported (see +[`supports`](@ref)) but cannot be added for some reason (see the error string). +""" +struct AddAttributeNotAllowed{AttrType<:AnyAttribute} <: NotAllowedError + attr::AttrType + message::String # Human-friendly explanation why the attribute cannot be set +end +AddAttributeNotAllowed(attr::AnyAttribute) = AddAttributeNotAllowed(attr, "") + +operation_name(err::AddAttributeNotAllowed) = "Adding attribute $(err.attr)" +message(err::AddAttributeNotAllowed) = err.message + """ supports(model::ModelLike, attr::AbstractOptimizerAttribute)::Bool @@ -328,7 +346,65 @@ function throw_set_error_fallback(model::ModelLike, end """ - ListOfOptimizerAttributesSet() + add(optimizer::AbstractOptimizer, attr::AbstractOptimizerAttribute, + value)::AttributeIndex{typeof(attr)} + +Add `value` to the attribute `attr` of the optimizer `optimizer`. + + add(model::ModelLike, attr::AbstractModelAttribute, + value)::AttributeIndex{typeof(attr)} + +Add `value` to the attribute `attr` of the model `model`. + + add(model::ModelLike, attr::AbstractVariableAttribute, v::VariableIndex, + value)::AttributeIndex{typeof(attr)} + +Add `value` to the attribute `attr` of variable `v` in model `model`. + + add(model::ModelLike, attr::AbstractVariableAttribute, + v::Vector{VariableIndex}, + vector_of_values)::Vector{AttributeIndex{typeof(attr)}} + +Add a value respectively to the attribute `attr` of each variable in the +collection `v` in model `model`. + + set(model::ModelLike, attr::AbstractConstraintAttribute, c::ConstraintIndex, + value) + +Add a value to the attribute `attr` of constraint `c` in model `model`. + + set(model::ModelLike, attr::AbstractConstraintAttribute, + c::Vector{ConstraintIndex{F,S}}, vector_of_values) + +Add a value respectively to the attribute `attr` of each constraint in the +collection `c` in model `model`. + +An [`UnsupportedAttribute`](@ref) error is thrown if `model` does not support +the attribute `attr` (see [`supports`](@ref)) and a +[`SetAttributeNotAllowed`](@ref) error is thrown if it supports the attribute +`attr` but it cannot be set. +""" # TODO add an example once we have an attribute which can be added, e.g. Lazy constraint +function add end +# See note with get +function add(model::ModelLike, + attr::Union{AbstractVariableAttribute, + AbstractConstraintAttribute}, + idxs::Vector, vector_of_values::Vector) + if length(idxs) != length(vector_of_values) + throw(DimensionMismatch("Number of indices ($(length(idxs))) does " * + "not match the number of values " * + "($(length(vector_of_values))) added to `$attr`.")) + end + return add.(model, attr, idxs, vector_of_values) +end + +function add(model::ModelLike, attr::AnyAttribute, args...) + throw_set_error_fallback(model, attr, args...; + error_if_supported = AddAttributeNotAllowed(attr)) +end + +""" + SettingSingleVariableFunctionNotAllowed() Error type that should be thrown when the user [`set`](@ref) the [`ConstraintFunction`](@ref) of a [`SingleVariable`](@ref) constraint. diff --git a/src/indextypes.jl b/src/indextypes.jl index 8954a64506..ecace550c5 100644 --- a/src/indextypes.jl +++ b/src/indextypes.jl @@ -35,10 +35,21 @@ end # https://github.com/JuliaLang/julia/issues/10208 Base.hash(v::VariableIndex, h::UInt) = hash(v.value, h) +""" + AttributeIndex{AttrType} + +A type-safe wrapper for `Int64` for use in referencing elements added for +attribute of type `AttrType`. +""" +struct AttributeIndex{AttrType} + attr:AttrType + value::Int64 +end + # No need to define isequal because the default matches our implementation of # hash. -const Index = Union{ConstraintIndex,VariableIndex} +const Index = Union{ConstraintIndex, VariableIndex, AttributeIndex} """ struct InvalidIndex{IndexType<:Index} <: Exception From f6ba0ffb646353b31bd7e0524c54546695cd53eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Legat?= Date: Sun, 23 Jun 2019 16:47:10 +0200 Subject: [PATCH 2/6] Fix typo --- src/indextypes.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/indextypes.jl b/src/indextypes.jl index ecace550c5..74cb494274 100644 --- a/src/indextypes.jl +++ b/src/indextypes.jl @@ -42,7 +42,7 @@ A type-safe wrapper for `Int64` for use in referencing elements added for attribute of type `AttrType`. """ struct AttributeIndex{AttrType} - attr:AttrType + attr::AttrType value::Int64 end From 23705b58f52901831e28fe7b3c0df8ab418643e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Legat?= Date: Wed, 3 Jul 2019 14:03:31 +0200 Subject: [PATCH 3/6] add -> submit --- src/attributes.jl | 115 +++++++++++++++++++++------------------------- src/indextypes.jl | 12 ++--- 2 files changed, 59 insertions(+), 68 deletions(-) diff --git a/src/attributes.jl b/src/attributes.jl index 258d4d2d91..1a0447f1b5 100644 --- a/src/attributes.jl +++ b/src/attributes.jl @@ -75,24 +75,53 @@ operation_name(err::SetAttributeNotAllowed) = "Setting attribute $(err.attr)" message(err::SetAttributeNotAllowed) = err.message """ - struct AddAttributeNotAllowed{AttrType} <: NotAllowedError - attr::AttrType + AbstractSubmittable + +Abstract supertype for objects that can be submitted to the model. +""" +abstract type AbstractSubmittable end + +# This allows to use submittable in broadcast calls without the need to embed +# it in a `Ref`. +Base.broadcastable(sub::AbstractSubmittable) = Ref(sub) + +""" + struct UnsupportedSubmittable{SubmitType} <: UnsupportedError + sub::SubmitType + message::String + end + +An error indicating that the submittable `sub` is not supported by the model, +i.e. that [`supports`](@ref) returns `false`. +""" +struct UnsupportedSubmittable{SubmitType<:AbstractSubmittable} <: UnsupportedError + sub::SubmitType + message::String +end + +""" + struct SubmitNotAllowed{SubmitTyp<:AbstractSubmittable} <: NotAllowedError + sub::SubmitType message::String # Human-friendly explanation why the attribute cannot be set end -An error indicating that the attribute `attr` is supported (see +An error indicating that the submittable `sub` is supported (see [`supports`](@ref)) but cannot be added for some reason (see the error string). """ -struct AddAttributeNotAllowed{AttrType<:AnyAttribute} <: NotAllowedError - attr::AttrType - message::String # Human-friendly explanation why the attribute cannot be set +struct SubmitNotAllowed{SubmitType<:AbstractSubmittable} <: NotAllowedError + sub::SubmitType + message::String # Human-friendly explanation why the attribute cannot be set end -AddAttributeNotAllowed(attr::AnyAttribute) = AddAttributeNotAllowed(attr, "") +SubmitNotAllowed(sub::AbstractSubmittable) = SubmitNotAllowed(sub, "") -operation_name(err::AddAttributeNotAllowed) = "Adding attribute $(err.attr)" -message(err::AddAttributeNotAllowed) = err.message +operation_name(err::SubmitNotAllowed) = "Submitting $(err.sub)" +message(err::SubmitNotAllowed) = err.message """ + supports(model::ModelLike, sub::AbstractSubmittable)::Bool + +Return a `Bool` indicating whether `model` supports the submittable `sub`. + supports(model::ModelLike, attr::AbstractOptimizerAttribute)::Bool Return a `Bool` indicating whether `model` supports the optimizer attribute @@ -120,7 +149,7 @@ Return a `Bool` indicating whether `model` supports the constraint attribute `copy_to(model, src)` cannot be performed in case `attr` is in the [`ListOfConstraintAttributesSet`](@ref) of `src`. -For all four methods, if the attribute is only not supported in specific +For all five methods, if the attribute is only not supported in specific circumstances, it should still return `true`. Note that `supports` is only defined for attributes for which @@ -128,6 +157,7 @@ Note that `supports` is only defined for attributes for which list of attributes set obtained by `ListOf...AttributesSet`. """ function supports end +supports(::ModelLike, ::AbstractSubmittable) = false function supports(::ModelLike, attr::Union{AbstractModelAttribute, AbstractOptimizerAttribute}) if !is_copyable(attr) @@ -346,61 +376,22 @@ function throw_set_error_fallback(model::ModelLike, end """ - add(optimizer::AbstractOptimizer, attr::AbstractOptimizerAttribute, - value)::AttributeIndex{typeof(attr)} - -Add `value` to the attribute `attr` of the optimizer `optimizer`. + submit(optimizer::AbstractOptimizer, sub::AbstractSubmittable, + value)::Union{Nothing, SubmittedIndex{typeof(sub)}} - add(model::ModelLike, attr::AbstractModelAttribute, - value)::AttributeIndex{typeof(attr)} +Submit `value` to the submittable `sub` of the optimizer `optimizer`. -Add `value` to the attribute `attr` of the model `model`. - - add(model::ModelLike, attr::AbstractVariableAttribute, v::VariableIndex, - value)::AttributeIndex{typeof(attr)} - -Add `value` to the attribute `attr` of variable `v` in model `model`. - - add(model::ModelLike, attr::AbstractVariableAttribute, - v::Vector{VariableIndex}, - vector_of_values)::Vector{AttributeIndex{typeof(attr)}} - -Add a value respectively to the attribute `attr` of each variable in the -collection `v` in model `model`. - - set(model::ModelLike, attr::AbstractConstraintAttribute, c::ConstraintIndex, - value) - -Add a value to the attribute `attr` of constraint `c` in model `model`. - - set(model::ModelLike, attr::AbstractConstraintAttribute, - c::Vector{ConstraintIndex{F,S}}, vector_of_values) - -Add a value respectively to the attribute `attr` of each constraint in the -collection `c` in model `model`. - -An [`UnsupportedAttribute`](@ref) error is thrown if `model` does not support -the attribute `attr` (see [`supports`](@ref)) and a -[`SetAttributeNotAllowed`](@ref) error is thrown if it supports the attribute -`attr` but it cannot be set. -""" # TODO add an example once we have an attribute which can be added, e.g. Lazy constraint -function add end -# See note with get -function add(model::ModelLike, - attr::Union{AbstractVariableAttribute, - AbstractConstraintAttribute}, - idxs::Vector, vector_of_values::Vector) - if length(idxs) != length(vector_of_values) - throw(DimensionMismatch("Number of indices ($(length(idxs))) does " * - "not match the number of values " * - "($(length(vector_of_values))) added to `$attr`.")) +An [`UnsupportedSubmittable`](@ref) error is thrown if `model` does not support +the attribute `attr` (see [`supports`](@ref)) and a [`SubmitNotAllowed`](@ref) +error is thrown if it supports the submittable `sub` but it cannot be submitted. +""" # TODO add an example once we have an attribute which can be submitted, e.g. Lazy constraint +function submit end +function submit(model::ModelLike, sub::AbstractSubmittable, args...) + if supports(model, sub) + throw(SubmitNotAllowed(sub)) + else + throw(UnsupportedSubmittable(sub)) end - return add.(model, attr, idxs, vector_of_values) -end - -function add(model::ModelLike, attr::AnyAttribute, args...) - throw_set_error_fallback(model, attr, args...; - error_if_supported = AddAttributeNotAllowed(attr)) end """ diff --git a/src/indextypes.jl b/src/indextypes.jl index 74cb494274..1797b25bb5 100644 --- a/src/indextypes.jl +++ b/src/indextypes.jl @@ -36,20 +36,20 @@ end Base.hash(v::VariableIndex, h::UInt) = hash(v.value, h) """ - AttributeIndex{AttrType} + SubmittedIndex{SubmitType} -A type-safe wrapper for `Int64` for use in referencing elements added for -attribute of type `AttrType`. +A type-safe wrapper for `Int64` for use in referencing elements submitted for +submittable of type `SubmitType`. """ -struct AttributeIndex{AttrType} - attr::AttrType +struct SubmittedIndex{SubmitType} + attr::SubmitType value::Int64 end # No need to define isequal because the default matches our implementation of # hash. -const Index = Union{ConstraintIndex, VariableIndex, AttributeIndex} +const Index = Union{ConstraintIndex, VariableIndex, SubmittedIndex} """ struct InvalidIndex{IndexType<:Index} <: Exception From 92ca5cc44b50b0c71b17523e8180864128d46d6c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Legat?= Date: Tue, 9 Jul 2019 11:04:26 +0200 Subject: [PATCH 4/6] Remove SubmittedIndex --- src/attributes.jl | 2 +- src/indextypes.jl | 13 +------------ 2 files changed, 2 insertions(+), 13 deletions(-) diff --git a/src/attributes.jl b/src/attributes.jl index 1a0447f1b5..b75b615a65 100644 --- a/src/attributes.jl +++ b/src/attributes.jl @@ -377,7 +377,7 @@ end """ submit(optimizer::AbstractOptimizer, sub::AbstractSubmittable, - value)::Union{Nothing, SubmittedIndex{typeof(sub)}} + value)::Nothing Submit `value` to the submittable `sub` of the optimizer `optimizer`. diff --git a/src/indextypes.jl b/src/indextypes.jl index 1797b25bb5..8954a64506 100644 --- a/src/indextypes.jl +++ b/src/indextypes.jl @@ -35,21 +35,10 @@ end # https://github.com/JuliaLang/julia/issues/10208 Base.hash(v::VariableIndex, h::UInt) = hash(v.value, h) -""" - SubmittedIndex{SubmitType} - -A type-safe wrapper for `Int64` for use in referencing elements submitted for -submittable of type `SubmitType`. -""" -struct SubmittedIndex{SubmitType} - attr::SubmitType - value::Int64 -end - # No need to define isequal because the default matches our implementation of # hash. -const Index = Union{ConstraintIndex, VariableIndex, SubmittedIndex} +const Index = Union{ConstraintIndex,VariableIndex} """ struct InvalidIndex{IndexType<:Index} <: Exception From 9e9c8d45e190a0dd9a4a67f5e786dec11f31491e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Legat?= Date: Tue, 9 Jul 2019 16:55:31 +0200 Subject: [PATCH 5/6] Add to doc --- docs/src/apireference.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/docs/src/apireference.md b/docs/src/apireference.md index ddd4eeee31..38929369a8 100644 --- a/docs/src/apireference.md +++ b/docs/src/apireference.md @@ -44,6 +44,11 @@ set supports ``` +## Submit + +Objects may be submitted using [`submit`](@ref). +Note that this is currently no supported by [`Utilities.Cac + ## Model Interface ```@docs From ad650f93ec4e035d334784628c175880edf4a8a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Legat?= Date: Tue, 9 Jul 2019 17:00:45 +0200 Subject: [PATCH 6/6] Add submit to doc --- docs/src/apireference.md | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/docs/src/apireference.md b/docs/src/apireference.md index 38929369a8..72940c9592 100644 --- a/docs/src/apireference.md +++ b/docs/src/apireference.md @@ -44,10 +44,14 @@ set supports ``` -## Submit +### Submit + +Objects may be submitted to an optimizer using [`submit`](@ref). +```@docs +AbstractSubmittable +submit +``` -Objects may be submitted using [`submit`](@ref). -Note that this is currently no supported by [`Utilities.Cac ## Model Interface @@ -407,6 +411,8 @@ AddConstraintNotAllowed ModifyConstraintNotAllowed ModifyObjectiveNotAllowed DeleteNotAllowed +UnsupportedSubmittable +SubmitNotAllowed ``` ## Models