From d9a701f97804a9769717fb2a8964f50c5d4ec32e Mon Sep 17 00:00:00 2001 From: Miles Lubin Date: Sat, 10 Feb 2018 21:27:29 -0500 Subject: [PATCH 1/4] Last big renaming (#203) --- docs/src/apimanual.md | 101 +++++++------ docs/src/apireference.md | 26 ++-- src/MathOptInterface.jl | 60 ++++---- src/attributes.jl | 313 +++++++++++++++++++-------------------- src/constraints.jl | 78 +++++----- src/indextypes.jl | 28 ++-- src/nlp.jl | 6 +- src/objectives.jl | 14 +- src/variables.jl | 12 +- 9 files changed, 317 insertions(+), 321 deletions(-) diff --git a/docs/src/apimanual.md b/docs/src/apimanual.md index aa8135855d..1774b97e47 100644 --- a/docs/src/apimanual.md +++ b/docs/src/apimanual.md @@ -3,7 +3,7 @@ ## Purpose -Each mathematical optimization solver API has its own concepts and data structures for representing optimization instances and obtaining results. +Each mathematical optimization solver API has its own concepts and data structures for representing optimization models and obtaining results. However, it is often desirable to represent an instance of an optimization problem at a higher level so that it is easy to try using different solvers. MathOptInterface (MOI) is an abstraction layer designed to provide a unified interface to mathematical optimization solvers so that users do not need to understand multiple solver-specific APIs. MOI can be used directly, or through a higher-level modeling interface like [JuMP](https://github.com/JuliaOpt/JuMP.jl). @@ -19,7 +19,7 @@ MOI is designed to: - Enable a solver to more precisely specify which problem classes it supports - Enable both primal and dual warm starts - Enable adding and removing both variables and constraints by indices that are not required to be consecutive -- Enable any modification that the solver supports to an existing instance +- Enable any modification that the solver supports to an existing model - Avoid requiring the solver wrapper to store an additional copy of the problem data This manual introduces the concepts needed to understand MOI and give a high-level picture of how all of the pieces fit together. The primary focus is on MOI from the perspective of a user of the interface. At the end of the manual we have a section on [Implementing a solver interface](@ref). @@ -56,39 +56,44 @@ The current function types are: * **scalar-valued quadratic**: ``\frac{1}{2} x^T Q x + a^T x + b``, where ``Q`` is a symmetric matrix, ``a`` is a vector, and ``b`` is a constant * **vector-valued quadratic**: a vector of scalar-valued quadratic expressions -In a future version, MOI could be extended to cover functions defined by evaluation oracles (e.g., for nonlinear derivative-based optimization). +Extensions for nonlinear programming are present but not yet well documented. MOI defines some commonly used sets, but the interface is extensible to other sets recognized by the solver. [Describe currently supported sets.] -## Instances +## The `ModelLike` and `AbstractOptimizer` APIs -An **Instance** ([`AbstractInstance`](@ref MathOptInterface.AbstractInstance)) is a representation of a concrete instance of an optimization problem, i.e., with all data specified. Instances are either **standalone instances** or **solver instances**: +The most significant part of MOI is the definition of the **model API** that is +used to specify an instance of an optimization problem (e.g., by adding +variables and constraints). Objects that implement the model API should inherit +from the [`ModelLike`](@ref MathOptInterface.ModelLike) abstract type. -- A **Standalone Instance** ([`AbstractStandaloneInstance`](@ref MathOptInterface.AbstractSolverInstance)) is unattached to any particular solver. It is simply a type that stores the data for an instance, which may be used for reading or writing optimization problems to files or manipulating a problem before providing it to a solver. The [MathOptInterfaceUtilities](https://github.com/JuliaOpt/MathOptInterfaceUtilities.jl) package provides an implementation of a standalone instance. +Notably missing from the model API is the method to solve an optimization problem. +`ModelLike` objects may store an instance (e.g., in memory or backed by a file format) +without being linked to a particular solver. In addition to the model API, MOI +defines [`AbstractOptimizer`](@ref MathOptInterface.AbstractOptimizer). *Optimizers* +(or solvers) implement the model API (inheriting from `ModelLike`) and additionally +provide methods to solve the model. -- A **Solver Instance** ([`AbstractSolverInstance`](@ref MathOptInterface.AbstractSolverInstance)) should be understood as the representation of an instance of an optimization problem *loaded in the solver's API*. That is, the instance data is often (i.e., whenever possible) stored exclusively in the external API, not duplicated in the MOI translation layer (called the *MOI wrapper*). Hence, the ability to modify data in a solver instance depends on whether the solver's own API supports such modifications. Solver instances were designed to allow efficient incremental instance construction and modification, e.g., when solving in a loop. +Through the rest of the manual, `model` is used as a generic `ModelLike`, and +`optimizer` is used as a generic `AbstractOptimizer`. -Instances share a common API for constructing the problem and querying its data. Solver instances, additionally, provide methods to solve the attached instance and query the results. - -Through the rest of the manual, `instance` is used as a generic solver instance. - -[Discuss how instances are constructed, solver parameters.] +[Discuss how models are constructed, optimizer parameters.] ## Variables All variables in MOI are scalar variables. -New scalar variables are created with [`addvariable!`](@ref MathOptInterface.addvariable!) or [`addvariables!`](@ref MathOptInterface.addvariables!), which return a [`VariableIndex`](@ref MathOptInterface.VariableIndex) or `Vector{VariableIndex}` respectively. `VariableIndex` objects are type-safe wrappers around integers that refer to a variable in a particular instance. +New scalar variables are created with [`addvariable!`](@ref MathOptInterface.addvariable!) or [`addvariables!`](@ref MathOptInterface.addvariables!), which return a [`VariableIndex`](@ref MathOptInterface.VariableIndex) or `Vector{VariableIndex}` respectively. `VariableIndex` objects are type-safe wrappers around integers that refer to a variable in a particular model. One uses `VariableIndex` objects to set and get variable attributes. For example, the [`VariablePrimalStart`](@ref MathOptInterface.VariablePrimalStart) attribute is used to provide an initial starting point for a variable or collection of variables: ```julia -v = addvariable!(instance) -set!(instance, VariablePrimalStart(), v, 10.5) -v2 = addvariables!(instance, 3) -set!(instance, VariablePrimalStart(), v2, [1.3,6.8,-4.6]) +v = addvariable!(model) +set!(model, VariablePrimalStart(), v, 10.5) +v2 = addvariables!(model, 3) +set!(model, VariablePrimalStart(), v2, [1.3,6.8,-4.6]) ``` -A variable can be deleted from an instance with [`delete!(::AbstractInstance, ::VariableIndex)`](@ref MathOptInterface.delete!(::MathOptInterface.AbstractInstance, ::MathOptInterface.Index)), if this functionality is supported. +A variable can be deleted from a model with [`delete!(::ModelLike, ::VariableIndex)`](@ref MathOptInterface.delete!(::MathOptInterface.ModelLike, ::MathOptInterface.Index)), if this functionality is supported. ## Functions @@ -99,7 +104,7 @@ struct SingleVariable <: AbstractFunction end ``` -If `v` is a `VariableIndex` object, then `SingleVariable(v)` is simply the scalar-valued function from the complete set of variables in an instance that returns the value of variable `v`. One may also call this function a coordinate projection, which is more useful for defining constraints than as an objective function. +If `v` is a `VariableIndex` object, then `SingleVariable(v)` is simply the scalar-valued function from the complete set of variables in a model that returns the value of variable `v`. One may also call this function a coordinate projection, which is more useful for defining constraints than as an objective function. A more interesting function is [`ScalarAffineFunction`](@ref MathOptInterface.ScalarAffineFunction), defined as @@ -113,13 +118,13 @@ end If `x` is a vector of `VariableIndex` objects, then `ScalarAffineFunction([x[1],x[2]],[5.0,-2.3],1.0)` represents the function ``5x_1 - 2.3x_2 + 1``. -Objective functions are assigned to an instance by setting the [`ObjectiveFunction`](@ref MathOptInterface.ObjectiveFunction) attribute. +Objective functions are assigned to a model by setting the [`ObjectiveFunction`](@ref MathOptInterface.ObjectiveFunction) attribute. The [`ObjectiveSense`](@ref MathOptInterface.ObjectiveSense) attribute is used for setting the optimization sense. For example, ```julia -x = addvariables!(instance, 2) -set!(instance, ObjectiveFunction{ScalarAffineFunction{Float64}}(), ScalarAffineFunction([x[1],x[2]],[5.0,-2.3],1.0)) -set!(instance, ObjectiveSense(), MinSense) +x = addvariables!(model, 2) +set!(model, ObjectiveFunction{ScalarAffineFunction{Float64}}(), ScalarAffineFunction([x[1],x[2]],[5.0,-2.3],1.0)) +set!(model, ObjectiveSense(), MinSense) ``` sets the objective to the function just discussed in the minimization sense. @@ -151,12 +156,12 @@ The code example below encodes the linear optimization problem: ``` ```julia -x = addvariables!(instance, 2) -set!(instance, ObjectiveFunction{ScalarAffineFunction{Float64}}(), ScalarAffineFunction(x, [3.0,2.0], 0.0)) -set!(instance, ObjectiveSense(), MaxSense) -addconstraint!(instance, ScalarAffineFunction(x, [1.0,1.0], 0.0), LessThan(5.0)) -addconstraint!(instance, SingleVariable(x[1]), GreaterThan(0.0)) -addconstraint!(instance, SingleVariable(x[2]), GreaterThan(-1.0)) +x = addvariables!(model, 2) +set!(model, ObjectiveFunction{ScalarAffineFunction{Float64}}(), ScalarAffineFunction(x, [3.0,2.0], 0.0)) +set!(model, ObjectiveSense(), MaxSense) +addconstraint!(model, ScalarAffineFunction(x, [1.0,1.0], 0.0), LessThan(5.0)) +addconstraint!(model, SingleVariable(x[1]), GreaterThan(0.0)) +addconstraint!(model, SingleVariable(x[2]), GreaterThan(-1.0)) ``` [Example with vector-valued set.] @@ -235,14 +240,14 @@ Constraints with `SingleVariable` in `LessThan`, `GreaterThan`, `EqualTo`, or `I ## Solving and retrieving the results -Once a solver instance is loaded with the objective function and all of the constraints, we can ask the solver to solve the instance by calling [`optimize!`](@ref MathOptInterface.optimize!). +Once an optimizer is loaded with the objective function and all of the constraints, we can ask the solver to solve the model by calling [`optimize!`](@ref MathOptInterface.optimize!). ```julia -optimize!(instance) +optimize!(optimizer) ``` -The optimization procedure may terminate for a number of reasons. The [`TerminationStatus`](@ref MathOptInterface.TerminationStatus) attribute of the solver instance returns a [`TerminationStatusCode`](@ref MathOptInterface.TerminationStatusCode) object which explains why the solver stopped. Some statuses indicate generally successful termination, some termination because of limit, and some termination because of something unexpected like invalid problem data or failure to converge. A typical usage of the `TerminationStatus` attribute is as follows: +The optimization procedure may terminate for a number of reasons. The [`TerminationStatus`](@ref MathOptInterface.TerminationStatus) attribute of the optimizer returns a [`TerminationStatusCode`](@ref MathOptInterface.TerminationStatusCode) object which explains why the solver stopped. Some statuses indicate generally successful termination, some termination because of limit, and some termination because of something unexpected like invalid problem data or failure to converge. A typical usage of the `TerminationStatus` attribute is as follows: ```julia -status = MOI.get(instance, TerminationStatus()) +status = MOI.get(optimizer, TerminationStatus()) if status == Success # Ok, the solver has a result to return else @@ -257,7 +262,7 @@ In addition to the primal status, the [`DualStatus`](@ref MathOptInterface.DualS If a result is available, it may be retrieved with the [`VariablePrimal`](@ref MathOptInterface.VariablePrimal) attribute: ```julia -MOI.get(instance, VariablePrimal(), x) +MOI.get(optimizer, VariablePrimal(), x) ``` If `x` is a `VariableIndex` then the function call returns a scalar, and if `x` is a `Vector{VariableIndex}` then the call returns a vector of scalars. `VariablePrimal()` is equivalent to `VariablePrimal(1)`, i.e., the variable primal vector of the first result. Use `VariablePrimal(N)` to access the `N`th result. @@ -300,39 +305,39 @@ w = [0.3, 0.5, 1.0] numvariables = length(c) -instance = GLPKInstance() # TODO: match with actual name in GLPK wrapper +optimizer = GLPKOptimizer() # TODO: match with actual name in GLPK wrapper # create the variables in the problem -x = MOI.addvariables!(instance, numvariables) +x = MOI.addvariables!(optimizer, numvariables) # set the objective function -MOI.set!(instance, MOI.ObjectiveFunction{MOI.ScalarAffineFunction{Float64}}(), MOI.ScalarAffineFunction(x, c, 0.0)) -MOI.set!(instance, MOI.ObjectiveSense(), MOI.MaxSense) +MOI.set!(optimizer, MOI.ObjectiveFunction{MOI.ScalarAffineFunction{Float64}}(), MOI.ScalarAffineFunction(x, c, 0.0)) +MOI.set!(optimizer, MOI.ObjectiveSense(), MOI.MaxSense) # add the knapsack constraint -MOI.addconstraint!(instance, MOI.ScalarAffineFunction(x, w, 0.0), MOI.LessThan(C)) +MOI.addconstraint!(optimizer, MOI.ScalarAffineFunction(x, w, 0.0), MOI.LessThan(C)) # add integrality constraints for i in 1:numvariables - MOI.addconstraint!(instance, MOI.SingleVariable(x[i]), MOI.ZeroOne()) + MOI.addconstraint!(optimizer, MOI.SingleVariable(x[i]), MOI.ZeroOne()) end # all set -MOI.optimize!(instance) +MOI.optimize!(optimizer) -termination_status = MOI.get(instance, TerminationStatus()) -objvalue = MOI.canget(instance, MOI.ObjectiveValue()) ? MOI.get(instance, MOI.ObjectiveValue()) : NaN +termination_status = MOI.get(optimizer, TerminationStatus()) +objvalue = MOI.canget(optimizer, MOI.ObjectiveValue()) ? MOI.get(optimizer, MOI.ObjectiveValue()) : NaN if termination_status != MOI.Success error("Solver terminated with status $termination_status") end -@assert MOI.get(instance, MOI.ResultCount()) > 0 +@assert MOI.get(optimizer, MOI.ResultCount()) > 0 -result_status = MOI.get(instance, MOI.PrimalStatus()) +result_status = MOI.get(optimizer, MOI.PrimalStatus()) if result_status != MOI.FeasiblePoint error("Solver ran successfully did not return a feasible point. The problem may be infeasible.") end -primal_variable_result = MOI.get(instance, MOI.VariablePrimal(), x) +primal_variable_result = MOI.get(optimizer, MOI.VariablePrimal(), x) @show objvalue @show primal_variable_result @@ -343,7 +348,7 @@ primal_variable_result = MOI.get(instance, MOI.VariablePrimal(), x) ### Duals -Conic duality is the starting point for MOI's duality conventions. When all functions are affine (or coordinate projections), and all constraint sets are closed convex cone, the instance may be called a conic optimization problem. +Conic duality is the starting point for MOI's duality conventions. When all functions are affine (or coordinate projections), and all constraint sets are closed convex cone, the model may be called a conic optimization problem. For conic-form minimization problems, the primal is: ```math @@ -455,7 +460,7 @@ If the set ``C_i`` of the section [Duals](@ref) is one of these three cones, then the rows of the matrix ``A_i`` corresponding to off-diagonal entries are twice the value of the `coefficients` field in the `VectorAffineFunction` for the corresponding rows. See [`PositiveSemidefiniteConeTriangle`](@ref MathOptInterface.PositiveSemidefiniteConeTriangle) for details. -### Modifying an instance +### Modifying a model [Explain `modifyconstraint!` and `modifyobjective!`.] diff --git a/docs/src/apireference.md b/docs/src/apireference.md index 9bbf210005..d85be1ce3e 100644 --- a/docs/src/apireference.md +++ b/docs/src/apireference.md @@ -10,13 +10,13 @@ CurrentModule = MathOptInterface Parameter abstract type. ```@docs -AbstractSolverParameter +AbstractOptimizerParameter ``` List of attribute categories. ```@docs -AbstractInstanceAttribute +AbstractModelAttribute AbstractVariableAttribute AbstractConstraintAttribute ``` @@ -32,12 +32,10 @@ set! supports ``` -## Instance +## Model Interface ```@docs -AbstractInstance -AbstractStandaloneInstance -AbstractSolverInstance +ModelLike isempty empty! write @@ -52,7 +50,7 @@ CopyResult CopyStatusCode ``` -List of instance attributes +List of model attributes ```@docs Name @@ -62,21 +60,21 @@ ListOfVariableIndices ListOfConstraints NumberOfConstraints ListOfConstraintIndices -ListOfInstanceAttributesSet +ListOfModelAttributesSet ListOfVariableAttributesSet ListOfConstraintAttributesSet ``` -There are no attributes specific to a standalone instance. -## Solver instance +## Optimizers ```@docs +AbstractOptimizer optimize! free! ``` -List of solver instance attributes +List of attributes useful for optimizers ```@docs @@ -97,7 +95,7 @@ DualStatus ### Termination Status -The `TerminationStatus` attribute indicates why the solver stopped executing. +The `TerminationStatus` attribute indicates why the optimizer stopped executing. The value of the attribute is of type `TerminationStatusCode`. ```@docs @@ -131,7 +129,7 @@ VariableIndex ConstraintIndex candelete isvalid -delete!(::AbstractSolverInstance,::Index) +delete!(::ModelLike,::Index) ``` ### Variables @@ -159,7 +157,7 @@ VariableBasisStatus Functions for adding and modifying constraints. ```@docs -isvalid(::AbstractSolverInstance,::ConstraintIndex) +isvalid(::ModelLike,::ConstraintIndex) canaddconstraint addconstraint! addconstraints! diff --git a/src/MathOptInterface.jl b/src/MathOptInterface.jl index bd642dfde6..e26a9df13b 100644 --- a/src/MathOptInterface.jl +++ b/src/MathOptInterface.jl @@ -2,58 +2,50 @@ __precompile__() module MathOptInterface """ - AbstractInstance + ModelLike -Abstract supertype for objects representing an instance of an optimization problem. +Abstract supertype for objects that implement the "Model" interface for defining +an optimization problem. """ -abstract type AbstractInstance end +abstract type ModelLike end """ - AbstractStandaloneInstance - -Abstract supertype for objects representing an instance of an optimization problem -unattached to any particular solver. Does not have methods for solving -or querying results. -""" -abstract type AbstractStandaloneInstance <: AbstractInstance end - -""" - AbstractSolverInstance + AbstractOptimizer Abstract supertype for objects representing an instance of an optimization problem tied to a particular solver. This is typically a solver's in-memory representation. -In addition to `AbstractInstance`, `AbstractSolverInstance` objects let you -solve the instance and query the solution. +In addition to `ModelLike`, `AbstractOptimizer` objects let you solve the +instance and query the solution. """ -abstract type AbstractSolverInstance <: AbstractInstance end +abstract type AbstractOptimizer <: ModelLike end """ - optimize!(instance::AbstractSolverInstance) + optimize!(optimizer::AbstractOptimizer) Start the solution procedure. """ function optimize! end """ - free!(instance::AbstractSolverInstance) + free!(optimizer::AbstractOptimizer) -Release any resources and memory used by the solver instance. +Release any resources and memory used by the optimizer. Note that the Julia garbage collector takes care of this automatically, but automatic collection cannot always be forced. This method is useful for more precise control of resources, especially in the case of commercial solvers with licensing restrictions on the number of concurrent runs. -Users must discard the solver instance object after this method is invoked. +Users must discard the optimizer object after this method is invoked. """ function free! end """ - write(instance::AbstractInstance, filename::String) + write(model::ModelLike, filename::String) -Writes the current instance data to the given file. +Writes the current model data to the given file. Supported file types depend on the solver or standalone instance type. """ function write end """ - read!(instance::AbstractInstance, filename::String) + read!(model::ModelLike, filename::String) Read the file `filename` into the instance `instance`. If `m` is non-empty, this may throw an error. @@ -63,17 +55,17 @@ Supported file types depend on the instance type. function read! end """ - isempty(instance::AbstractInstance) + isempty(model::ModelLike) -Returns `false` if the `instance` has any instance attribute set or has any variables or constraints. -Note that an empty instance can have solver parameters set. +Returns `false` if the `model` has any instance attribute set or has any variables or constraints. +Note that an empty model can have optimizer parameters set. """ function isempty end """ - empty!(instance::AbstractInstance) + empty!(model::ModelLike) -Empty the instance, that is, remove from the instance `instance` all variables, constraints and instance attributes but not solver parameters. +Empty the model, that is, remove all variables, constraints and model attributes but not optimizer parameters. """ function empty! end @@ -110,11 +102,15 @@ struct CopyResult{T} end """ - copy!(dest::AbstractInstance, src::AbstractInstance, warnattributes=true)::CopyResult + copy!(dest::ModelLike, src::ModelLike, warnattributes=true)::CopyResult -Copy the model from the instance `src` into the instance `dest`. The target instance `dest` is emptied, and all previous indices to variables or constraints in `dest` are invalidated. Returns a `CopyResult` object. If the copy is successfully, the `CopyResult` contains a dictionary-like object that translates variable and constraint indices from the `src` instance to the corresponding indices in the `dest` instance. +Copy the model from `src` into `dest`. The target `dest` is emptied, and all +previous indices to variables or constraints in `dest` are invalidated. Returns +a `CopyResult` object. If the copy is successful, the `CopyResult` contains a +dictionary-like object that translates variable and constraint indices from the +`src` model to the corresponding indices in the `dest` model. -If an attribute `attr` cannot be copied from `src` to `dest` then an error is thrown. If a solver parameter cannot be copied then: +If an attribute `attr` cannot be copied from `src` to `dest` then an error is thrown. If an optimizer parameter cannot be copied then: * If `warnattributes` is `true`, a warning is displayed, otherwise, * The attribute is silently ignored. @@ -122,7 +118,7 @@ If an attribute `attr` cannot be copied from `src` to `dest` then an error is th ### Example ```julia -# Given empty `AbstractInstance`s `src` and `dest`. +# Given empty `ModelLike` objects `src` and `dest`. x = addvariable!(src) diff --git a/src/attributes.jl b/src/attributes.jl index 4b02643084..c98c000bda 100644 --- a/src/attributes.jl +++ b/src/attributes.jl @@ -1,308 +1,305 @@ # Attributes """ - AbstractSolverParameter + AbstractOptimizerParameter -Abstract supertype for parameter objects that can be used to set or get parameters of the solver. +Abstract supertype for parameter objects that can be used to set or get parameters of the optimizer. ### Note -The difference between `AbstractSolverParameter` and `AbstractInstanceAttribute` lies in the behavior of `isempty`, `empty!` and `copy!`. -Typically solver parameters only affect how the instance is solved. +The difference between `AbstractOptimizerParameter` and `AbstractModelAttribute` lies in the behavior of `isempty`, `empty!` and `copy!`. +Typically optimizer parameters only affect how the model is solved. """ -abstract type AbstractSolverParameter end +abstract type AbstractOptimizerParameter end """ - AbstractInstanceAttribute + AbstractModelAttribute -Abstract supertype for attribute objects that can be used to set or get attributes (properties) of the instance. +Abstract supertype for attribute objects that can be used to set or get attributes (properties) of the model. """ -abstract type AbstractInstanceAttribute end +abstract type AbstractModelAttribute end """ AbstractVariableAttribute -Abstract supertype for attribute objects that can be used to set or get attributes (properties) of variables in the instance. +Abstract supertype for attribute objects that can be used to set or get attributes (properties) of variables in the model. """ abstract type AbstractVariableAttribute end """ AbstractConstraintAttribute -Abstract supertype for attribute objects that can be used to set or get attributes (properties) of constraints in the instance. +Abstract supertype for attribute objects that can be used to set or get attributes (properties) of constraints in the model. """ abstract type AbstractConstraintAttribute end -const AnyAttribute = Union{AbstractSolverParameter, AbstractInstanceAttribute, AbstractVariableAttribute, AbstractConstraintAttribute} -const AnyProperty = Union{AbstractSolverParameter, AnyAttribute} +const AnyAttribute = Union{AbstractOptimizerParameter, AbstractModelAttribute, AbstractVariableAttribute, AbstractConstraintAttribute} +const AnyProperty = Union{AbstractOptimizerParameter, AnyAttribute} """ - supports(instance::AbstractInstance, param::AbstractSolverParameter)::Bool + supports(model::ModelLike, param::AbstractOptimizerParameter)::Bool -Return a `Bool` indicating whether `instance` supports the solver parameter `param`. +Return a `Bool` indicating whether `model` supports the optimizer parameter `param`. - supports(instance::AbstractInstance, attr::AbstractInstanceAttribute)::Bool + supports(model::ModelLike, attr::AbstractModelAttribute)::Bool -Return a `Bool` indicating whether `instance` supports the instance attribute `attr`. +Return a `Bool` indicating whether `model` supports the model attribute `attr`. - supports(instance::AbstractInstance, attr::AbstractVariableAttribute, ::Type{VariableIndex})::Bool + supports(model::ModelLike, attr::AbstractVariableAttribute, ::Type{VariableIndex})::Bool -Return a `Bool` indicating whether `instance` supports the variable attribute `attr`. +Return a `Bool` indicating whether `model` supports the variable attribute `attr`. - supports(instance::AbstractInstance, attr::AbstractConstraintAttribute, ::Type{ConstraintIndex{F,S}})::Bool where {F,S} + supports(model::ModelLike, attr::AbstractConstraintAttribute, ::Type{ConstraintIndex{F,S}})::Bool where {F,S} -Return a `Bool` indicating whether `instance` supports the constraint attribute `attr` applied to an `F`-in-`S` constraint. +Return a `Bool` indicating whether `model` supports the constraint attribute `attr` applied to an `F`-in-`S` constraint. -In other words, it should return `true` if `copy!(instance, src)` does not return `CopyUnsupportedAttribute` when the attribute `attr` is set to `src`. +In other words, it should return `true` if `copy!(model, src)` does not return `CopyUnsupportedAttribute` when the attribute `attr` is set to `src`. If the attribute is only not supported in specific circumstances, it should still return `true`. """ function supports end -supports(::AbstractInstance, ::AnyProperty) = false -supports(::AbstractInstance, ::AnyAttribute, ::Type{<:Index}) = false +supports(::ModelLike, ::AnyProperty) = false +supports(::ModelLike, ::AnyAttribute, ::Type{<:Index}) = false """ - get(instance::AbstractInstance, param::AbstractSolverParameter) + get(model::ModelLike, param::AbstractOptimizerParameter) -Return a parameter `param` of the instance `instance`. +Return a parameter `param` of the model `model`. - get(instance::AbstractInstance, attr::AbstractInstanceAttribute) + get(model::ModelLike, attr::AbstractModelAttribute) -Return an attribute `attr` of the instance `instance`. +Return an attribute `attr` of the model `model`. - get(instance::AbstractInstance, attr::AbstractVariableAttribute, v::VariableIndex) + get(model::ModelLike, attr::AbstractVariableAttribute, v::VariableIndex) -Return an attribute `attr` of the variable `v` in instance `instance`. +Return an attribute `attr` of the variable `v` in model `model`. - get(instance::AbstractInstance, attr::AbstractVariableAttribute, v::Vector{VariableIndex}) + get(model::ModelLike, attr::AbstractVariableAttribute, v::Vector{VariableIndex}) -Return a vector of attributes corresponding to each variable in the collection `v` in the instance `instance`. +Return a vector of attributes corresponding to each variable in the collection `v` in the model `model`. - get(instance::AbstractInstance, attr::AbstractConstraintAttribute, c::ConstraintIndex) + get(model::ModelLike, attr::AbstractConstraintAttribute, c::ConstraintIndex) -Return an attribute `attr` of the constraint `c` in instance `instance`. +Return an attribute `attr` of the constraint `c` in model `model`. - get(instance::AbstractInstance, attr::AbstractConstraintAttribute, c::Vector{ConstraintIndex{F,S}}) + get(model::ModelLike, attr::AbstractConstraintAttribute, c::Vector{ConstraintIndex{F,S}}) -Return a vector of attributes corresponding to each constraint in the collection `c` in the instance `instance`. +Return a vector of attributes corresponding to each constraint in the collection `c` in the model `model`. - get(instance::AbstractInstance, ::Type{VariableIndex}, name::String) + get(model::ModelLike, ::Type{VariableIndex}, name::String) -If a variable with name `name` exists in the instance `instance`, return the corresponding index, otherwise throw a `KeyError`. +If a variable with name `name` exists in the model `model`, return the corresponding index, otherwise throw a `KeyError`. - get(instance::AbstractInstance, ::Type{ConstraintIndex{F,S}}, name::String) where {F<:AbstractFunction,S<:AbstractSet} + get(model::ModelLike, ::Type{ConstraintIndex{F,S}}, name::String) where {F<:AbstractFunction,S<:AbstractSet} -If an `F`-in-`S` constraint with name `name` exists in the instance `instance`, return the corresponding index, otherwise throw a `KeyError`. +If an `F`-in-`S` constraint with name `name` exists in the model `model`, return the corresponding index, otherwise throw a `KeyError`. - get(instance::AbstractInstance, ::Type{ConstraintIndex}, name::String) + get(model::ModelLike, ::Type{ConstraintIndex}, name::String) -If *any* constraint with name `name` exists in the instance `instance`, return the corresponding index, otherwise throw a `KeyError`. This version is available for convenience but may incur a performance penalty because it is not type stable. +If *any* constraint with name `name` exists in the model `model`, return the corresponding index, otherwise throw a `KeyError`. This version is available for convenience but may incur a performance penalty because it is not type stable. ### Examples ```julia -get(instance, ObjectiveValue()) -get(instance, VariablePrimal(), ref) -get(instance, VariablePrimal(5), [ref1, ref2]) -get(instance, OtherAttribute("something specific to cplex")) -get(instance, VariableIndex, "var1") -get(instance, ConstraintIndex{ScalarAffineFunction{Float64},LessThan{Float64}}, "con1") -get(instance, ConstraintIndex, "con1") +get(model, ObjectiveValue()) +get(model, VariablePrimal(), ref) +get(model, VariablePrimal(5), [ref1, ref2]) +get(model, OtherAttribute("something specific to cplex")) +get(model, VariableIndex, "var1") +get(model, ConstraintIndex{ScalarAffineFunction{Float64},LessThan{Float64}}, "con1") +get(model, ConstraintIndex, "con1") ``` """ function get end # We want to avoid being too specific in the type arguments to avoid method ambiguity. -# For instance, get(::AbstractInstance, ::AbstractVariableAttribute, ::Vector{VariableIndex}) would not allow -# to define get(::SomeInstance, ::AnyProperty, ::Vector) -get(instance::AbstractInstance, attr::AnyProperty, idxs::Vector) = get.(instance, attr, idxs) +# For model, get(::ModelLike, ::AbstractVariableAttribute, ::Vector{VariableIndex}) would not allow +# to define get(::SomeModel, ::AnyProperty, ::Vector) +get(model::ModelLike, attr::AnyProperty, idxs::Vector) = get.(model, attr, idxs) _name(attr::AnyAttribute) = "attribute $attr" -_name(attr::AbstractSolverParameter) = "parameter $attr" -function get(instance::AbstractInstance, attr::AnyProperty, args...) - throw(ArgumentError("AbstractInstance of type $(typeof(instance)) does not support accessing the $(_name(attr))")) +_name(attr::AbstractOptimizerParameter) = "parameter $attr" +function get(model::ModelLike, attr::AnyProperty, args...) + throw(ArgumentError("ModelLike of type $(typeof(model)) does not support accessing the $(_name(attr))")) end """ - get!(output, instance::AbstractInstance, args...) + get!(output, model::ModelLike, args...) An in-place version of `get`. The signature matches that of `get` except that the the result is placed in the vector `output`. """ function get! end -function get!(output, instance::AbstractInstance, attr::AnyProperty, args...) - throw(ArgumentError("AbstractInstance of type $(typeof(instance)) does not support accessing the $(_name(attr))")) +function get!(output, model::ModelLike, attr::AnyProperty, args...) + throw(ArgumentError("ModelLike of type $(typeof(model)) does not support accessing the $(_name(attr))")) end """ - canget(instance::AbstractInstance, param::AbstractSolverParameter)::Bool + canget(model::ModelLike, param::AbstractOptimizerParameter)::Bool -Return a `Bool` indicating whether `instance` currently has a value for the parameter specified by parameter type `param`. +Return a `Bool` indicating whether `model` currently has a value for the parameter specified by parameter type `param`. - canget(instance::AbstractInstance, attr::AbstractInstanceAttribute)::Bool + canget(model::ModelLike, attr::AbstractModelAttribute)::Bool -Return a `Bool` indicating whether `instance` currently has a value for the attribute specified by attribute type `attr`. +Return a `Bool` indicating whether `model` currently has a value for the attribute specified by attribute type `attr`. - canget(instance::AbstractInstance, attr::AbstractVariableAttribute, ::Type{VariableIndex})::Bool + canget(model::ModelLike, attr::AbstractVariableAttribute, ::Type{VariableIndex})::Bool -Return a `Bool` indicating whether `instance` currently has a value for the attribute specified by attribute type `attr` applied to *every* variable of the instance. +Return a `Bool` indicating whether `model` currently has a value for the attribute specified by attribute type `attr` applied to *every* variable of the model. - canget(instance::AbstractInstance, attr::AbstractConstraintAttribute, ::Type{ConstraintIndex{F,S}})::Bool where {F<:AbstractFunction,S<:AbstractSet} + canget(model::ModelLike, attr::AbstractConstraintAttribute, ::Type{ConstraintIndex{F,S}})::Bool where {F<:AbstractFunction,S<:AbstractSet} -Return a `Bool` indicating whether `instance` currently has a value for the attribute specified by attribute type `attr` applied to *every* `F`-in-`S` constraint. +Return a `Bool` indicating whether `model` currently has a value for the attribute specified by attribute type `attr` applied to *every* `F`-in-`S` constraint. - canget(instance::AbstractInstance, ::Type{VariableIndex}, name::String)::Bool + canget(model::ModelLike, ::Type{VariableIndex}, name::String)::Bool -Return a `Bool` indicating if a variable with the name `name` exists in `instance`. +Return a `Bool` indicating if a variable with the name `name` exists in `model`. - canget(instance::AbstractInstance, ::Type{ConstraintIndex{F,S}}, name::String)::Bool where {F<:AbstractFunction,S<:AbstractSet} + canget(model::ModelLike, ::Type{ConstraintIndex{F,S}}, name::String)::Bool where {F<:AbstractFunction,S<:AbstractSet} -Return a `Bool` indicating if an `F`-in-`S` constraint with the name `name` exists in `instance`. +Return a `Bool` indicating if an `F`-in-`S` constraint with the name `name` exists in `model`. - canget(instance::AbstractInstance, ::Type{ConstraintIndex}, name::String)::Bool + canget(model::ModelLike, ::Type{ConstraintIndex}, name::String)::Bool -Return a `Bool` indicating if a constraint of any kind with the name `name` exists in `instance`. +Return a `Bool` indicating if a constraint of any kind with the name `name` exists in `model`. ### Examples ```julia -canget(instance, ObjectiveValue()) -canget(instance, VariablePrimalStart(), VariableIndex) -canget(instance, VariablePrimal(), VariableIndex) -canget(instance, ConstraintPrimal(), ConstraintIndex{SingleVariable,EqualTo{Float64}}) -canget(instance, VariableIndex, "var1") -canget(instance, ConstraintIndex{ScalarAffineFunction{Float64},LessThan{Float64}}, "con1") -canget(instance, ConstraintIndex, "con1") +canget(model, ObjectiveValue()) +canget(model, VariablePrimalStart(), VariableIndex) +canget(model, VariablePrimal(), VariableIndex) +canget(model, ConstraintPrimal(), ConstraintIndex{SingleVariable,EqualTo{Float64}}) +canget(model, VariableIndex, "var1") +canget(model, ConstraintIndex{ScalarAffineFunction{Float64},LessThan{Float64}}, "con1") +canget(model, ConstraintIndex, "con1") ``` """ function canget end -canget(instance::AbstractInstance, attr::AnyProperty) = false -canget(instance::AbstractInstance, attr::AnyAttribute, ::Type{<:Index}) = false +canget(model::ModelLike, attr::AnyProperty) = false +canget(model::ModelLike, attr::AnyAttribute, ::Type{<:Index}) = false -# TODO: Consider moving from `canset(instance, VariablePrimalStart(), VariableIndex)` to `canset(instance, VariablePrimalStart())` -# and from `canset(instance, ConstraintPrimal(), ConstraintIndex{VectorAffineFunction{Float64},Nonnegatives})` to -# `canset(instance, ConstraintPrimal(), VectorAffineFunction{Float64},Nonnegatives)`. """ - canset(instance::AbstractInstance, param::AbstractSolverParameter)::Bool + canset(model::ModelLike, param::AbstractOptimizerParameter)::Bool -Return a `Bool` indicating whether it is possible to set the parameter `param` to the instance `instance`. +Return a `Bool` indicating whether it is possible to set the parameter `param` to the model `model`. - canset(instance::AbstractInstance, attr::AbstractInstanceAttribute)::Bool + canset(model::ModelLike, attr::AbstractModelAttribute)::Bool -Return a `Bool` indicating whether it is possible to set the attribute `attr` to the instance `instance`. +Return a `Bool` indicating whether it is possible to set the attribute `attr` to the model `model`. - canset(instance::AbstractInstance, attr::AbstractVariableAttribute, R::Type{VariableIndex})::Bool - canset(instance::AbstractInstance, attr::AbstractConstraintAttribute, R::Type{ConstraintIndex{F,S})::Bool + canset(model::ModelLike, attr::AbstractVariableAttribute, R::Type{VariableIndex})::Bool + canset(model::ModelLike, attr::AbstractConstraintAttribute, R::Type{ConstraintIndex{F,S})::Bool -Return a `Bool` indicating whether it is possible to set attribute `attr` applied to the index type `R` in the instance `instance`. +Return a `Bool` indicating whether it is possible to set attribute `attr` applied to the index type `R` in the model `model`. ### Examples ```julia -canset(instance, ObjectiveValue()) -canset(instance, VariablePrimalStart(), VariableIndex) -canset(instance, ConstraintPrimal(), ConstraintIndex{VectorAffineFunction{Float64},Nonnegatives}) +canset(model, ObjectiveValue()) +canset(model, VariablePrimalStart(), VariableIndex) +canset(model, ConstraintPrimal(), ConstraintIndex{VectorAffineFunction{Float64},Nonnegatives}) ``` """ function canset end -canset(instance::AbstractInstance, attr::AnyProperty) = false -canset(instance::AbstractInstance, attr::AnyAttribute, ref::Type{<:Index}) = false +canset(model::ModelLike, attr::AnyProperty) = false +canset(model::ModelLike, attr::AnyAttribute, ref::Type{<:Index}) = false """ - set!(instance::AbstractInstance, param::AbstractSolverParameter, value) + set!(model::ModelLike, param::AbstractOptimizerParameter, value) -Assign `value` to the parameter `param` of the instance `instance`. +Assign `value` to the parameter `param` of the model `model`. - set!(instance::AbstractInstance, attr::AbstractInstanceAttribute, value) + set!(model::ModelLike, attr::AbstractModelAttribute, value) -Assign `value` to the attribute `attr` of the instance `instance`. +Assign `value` to the attribute `attr` of the model `model`. - set!(instance::AbstractInstance, attr::AbstractVariableAttribute, v::VariableIndex, value) + set!(model::ModelLike, attr::AbstractVariableAttribute, v::VariableIndex, value) -Assign `value` to the attribute `attr` of variable `v` in instance `instance`. +Assign `value` to the attribute `attr` of variable `v` in model `model`. - set!(instance::AbstractInstance, attr::AbstractVariableAttribute, v::Vector{VariableIndex}, vector_of_values) + set!(model::ModelLike, attr::AbstractVariableAttribute, v::Vector{VariableIndex}, vector_of_values) -Assign a value respectively to the attribute `attr` of each variable in the collection `v` in instance `instance`. +Assign a value respectively to the attribute `attr` of each variable in the collection `v` in model `model`. - set!(instance::AbstractInstance, attr::AbstractConstraintAttribute, c::ConstraintIndex, value) + set!(model::ModelLike, attr::AbstractConstraintAttribute, c::ConstraintIndex, value) -Assign a value to the attribute `attr` of constraint `c` in instance `instance`. +Assign a value to the attribute `attr` of constraint `c` in model `model`. - set!(instance::AbstractInstance, attr::AbstractConstraintAttribute, c::Vector{ConstraintIndex{F,S}}, vector_of_values) + set!(model::ModelLike, attr::AbstractConstraintAttribute, c::Vector{ConstraintIndex{F,S}}, vector_of_values) -Assign a value respectively to the attribute `attr` of each constraint in the collection `c` in instance `instance`. +Assign a value respectively to the attribute `attr` of each constraint in the collection `c` in model `model`. """ function set! end # See note with get -set!(instance::AbstractInstance, attr::AnyProperty, idxs::Vector, vector_of_values::Vector) = set!.(instance, attr, idxs, vector_of_values) +set!(model::ModelLike, attr::AnyProperty, idxs::Vector, vector_of_values::Vector) = set!.(model, attr, idxs, vector_of_values) -function set!(instance::AbstractInstance, attr::AnyProperty, args...) - throw(ArgumentError("AbstractInstance of type $(typeof(instance)) does not support setting the $(_name(attr))")) +function set!(model::ModelLike, attr::AnyProperty, args...) + throw(ArgumentError("ModelLike of type $(typeof(model)) does not support setting the $(_name(attr))")) end -## Solver parameters +## Optimizer parameters """ - ListOfSolverParametersSet() + ListOfOptimizerParametersSet() -A `Vector{AbstractSolverParameter}` of all solver parameters that were set to the instance. +A `Vector{AbstractOptimizerParameter}` of all optimizer parameters that were set to the model. """ -struct ListOfSolverParametersSet <: AbstractSolverParameter end +struct ListOfOptimizerParametersSet <: AbstractOptimizerParameter end -## Instance attributes +## Model attributes """ - ListOfInstanceAttributesSet() + ListOfModelAttributesSet() -A `Vector{AbstractInstanceAttribute}` of all instance attributes that were set to the instance. +A `Vector{AbstractModelAttribute}` of all model attributes that were set to the model. """ -struct ListOfInstanceAttributesSet <: AbstractInstanceAttribute end +struct ListOfModelAttributesSet <: AbstractModelAttribute end """ Name() -A string identifying the instance. +A string identifying the model. """ -struct Name <: AbstractInstanceAttribute end +struct Name <: AbstractModelAttribute end """ ObjectiveSense() The sense of the objective function, an `OptimizationSense` with value `MinSense`, `MaxSense`, or `FeasiblitySense`. """ -struct ObjectiveSense <: AbstractInstanceAttribute end +struct ObjectiveSense <: AbstractModelAttribute end @enum OptimizationSense MinSense MaxSense FeasibilitySense """ NumberOfVariables() -The number of variables in the instance. +The number of variables in the model. """ -struct NumberOfVariables <: AbstractInstanceAttribute end +struct NumberOfVariables <: AbstractModelAttribute end """ ListOfVariableIndices() A `Vector{VariableIndex}` indexing all variables present -in the instance (i.e., of length equal to the value of `NumberOfVariables()`). +in the model (i.e., of length equal to the value of `NumberOfVariables()`). """ -struct ListOfVariableIndices <: AbstractInstanceAttribute end +struct ListOfVariableIndices <: AbstractModelAttribute end """ ListOfConstraintIndices{F,S}() A `Vector{ConstraintIndex{F,S}}` indexing all constraints of -type `F`-in`S` in the instance (i.e., of length equal to the value of `NumberOfConstraints{F,S}()`). +type `F`-in`S` in the model (i.e., of length equal to the value of `NumberOfConstraints{F,S}()`). """ -struct ListOfConstraintIndices{F,S} <: AbstractInstanceAttribute end +struct ListOfConstraintIndices{F,S} <: AbstractModelAttribute end """ NumberOfConstraints{F,S}() -The number of constraints of the type `F`-in-`S` present in the instance. +The number of constraints of the type `F`-in-`S` present in the model. """ -struct NumberOfConstraints{F,S} <: AbstractInstanceAttribute end +struct NumberOfConstraints{F,S} <: AbstractModelAttribute end """ ListOfConstraints() @@ -311,27 +308,27 @@ A list of tuples of the form `(F,S)`, where `F` is a function type and `S` is a set type indicating that the attribute `NumberOfConstraints{F,S}()` has value greater than zero. """ -struct ListOfConstraints <: AbstractInstanceAttribute end +struct ListOfConstraints <: AbstractModelAttribute end """ ObjectiveFunction{F<:AbstractScalarFunction}() -An `F` instance which represents the objective function. +An `F` model which represents the objective function. It is guaranteed to be equivalent but not necessarily identical to the function provided by the user. Throws an `InexactError` if the objective function cannot be converted to `F`, e.g. the objective function is quadratic and `F` is `ScalarAffineFunction{Float64}` or it has non-integer coefficient and `F` is `ScalarAffineFunction{Int}`. """ -struct ObjectiveFunction{F<:AbstractScalarFunction} <: AbstractInstanceAttribute end +struct ObjectiveFunction{F<:AbstractScalarFunction} <: AbstractModelAttribute end -## Solver instance attributes +## Optimizer attributes """ ObjectiveValue(resultidx::Int=1) The objective value of the `resultindex`th primal result. """ -struct ObjectiveValue <: AbstractInstanceAttribute +struct ObjectiveValue <: AbstractModelAttribute resultindex::Int (::Type{ObjectiveValue})(resultindex=1) = new(resultindex) end @@ -341,21 +338,21 @@ end The best known bound on the optimal objective value. """ -struct ObjectiveBound <: AbstractInstanceAttribute end +struct ObjectiveBound <: AbstractModelAttribute end """ RelativeGap() The final relative optimality gap, defined as ``\\frac{|b-f|}{|f|}``, where ``b`` is the best bound and ``f`` is the best feasible objective value. """ -struct RelativeGap <: AbstractInstanceAttribute end +struct RelativeGap <: AbstractModelAttribute end """ SolveTime() -The total elapsed solution time (in seconds) as reported by the solver. +The total elapsed solution time (in seconds) as reported by the optimizer. """ -struct SolveTime <: AbstractInstanceAttribute end +struct SolveTime <: AbstractModelAttribute end """ SimplexIterations() @@ -363,44 +360,44 @@ struct SolveTime <: AbstractInstanceAttribute end The cumulative number of simplex iterations during the optimization process. In particular, for a mixed-integer program (MIP), the total simplex iterations for all nodes. """ -struct SimplexIterations <: AbstractInstanceAttribute end +struct SimplexIterations <: AbstractModelAttribute end """ BarrierIterations() The cumulative number of barrier iterations while solving a problem. """ -struct BarrierIterations <: AbstractInstanceAttribute end +struct BarrierIterations <: AbstractModelAttribute end """ NodeCount() The total number of branch-and-bound nodes explored while solving a mixed-integer program (MIP). """ -struct NodeCount <: AbstractInstanceAttribute end +struct NodeCount <: AbstractModelAttribute end """ RawSolver() -An object that may be used to access a solver-specific API for this solver instance. +An object that may be used to access a solver-specific API for this optimizer. """ -struct RawSolver <: AbstractInstanceAttribute end +struct RawSolver <: AbstractModelAttribute end """ ResultCount() The number of results available. """ -struct ResultCount <: AbstractInstanceAttribute end +struct ResultCount <: AbstractModelAttribute end ## Variable attributes """ ListOfVariableAttributesSet() -A `Vector{AbstractVariableAttribute}` of all variable attributes that were set to the instance. +A `Vector{AbstractVariableAttribute}` of all variable attributes that were set to the model. """ -struct ListOfVariableAttributesSet <: AbstractInstanceAttribute end +struct ListOfVariableAttributesSet <: AbstractModelAttribute end """ VariableName() @@ -412,7 +409,7 @@ struct VariableName <: AbstractVariableAttribute end """ VariablePrimalStart() -An initial assignment of the variables that the solver may use to warm-start the solve. +An initial assignment of the variables that the optimizer may use to warm-start the solve. """ struct VariablePrimalStart <: AbstractVariableAttribute end @@ -456,7 +453,7 @@ Possible values are: A `Vector{AbstractConstraintAttribute}` of all constraint attributes that were set to `F`-in-`S` constraints. """ -struct ListOfConstraintAttributesSet{F,S} <: AbstractInstanceAttribute end +struct ListOfConstraintAttributesSet{F,S} <: AbstractModelAttribute end """ ConstraintName() @@ -468,14 +465,14 @@ struct ConstraintName <: AbstractConstraintAttribute end """ ConstraintPrimalStart() -An initial assignment of the constraint primal values that the solver may use to warm-start the solve. +An initial assignment of the constraint primal values that the optimizer may use to warm-start the solve. """ struct ConstraintPrimalStart <: AbstractConstraintAttribute end """ ConstraintDualStart() -An initial assignment of the constraint duals that the solver may use to warm-start the solve. +An initial assignment of the constraint duals that the optimizer may use to warm-start the solve. """ struct ConstraintDualStart <: AbstractConstraintAttribute end @@ -529,15 +526,15 @@ struct ConstraintSet <: AbstractConstraintAttribute end """ TerminationStatus() -A `TerminationStatusCode` explaining why the solver stopped. +A `TerminationStatusCode` explaining why the optimizer stopped. """ -struct TerminationStatus <: AbstractInstanceAttribute end +struct TerminationStatus <: AbstractModelAttribute end """ TerminationStatusCode An Enum of possible values for the `TerminationStatus` attribute. -This attribute is meant to explain the reason why the solver stopped executing. +This attribute is meant to explain the reason why the optimizer stopped executing. ## OK @@ -550,7 +547,7 @@ These are generally OK statuses. ## Limits -The solver stopped because of some user-defined limit. +The optimizer stopped because of some user-defined limit. To be documented: `IterationLimit`, `TimeLimit`, `NodeLimit`, `SolutionLimit`, `MemoryLimit`, `ObjectiveLimit`, `NormLimit`, `OtherLimit`. ## Problematic @@ -560,10 +557,10 @@ This group of statuses means that something unexpected or problematic happened. * `SlowProgress`: the algorithm stopped because it was unable to continue making progress towards the solution * `AlmostSuccess` should be used if there is additional information that relaxed convergence tolerances are satisfied -To be documented: `NumericalError`, `InvalidInstance`, `InvalidOption`, `Interrupted`, `OtherError`. +To be documented: `NumericalError`, `InvalidModel`, `InvalidOption`, `Interrupted`, `OtherError`. """ -@enum TerminationStatusCode Success AlmostSuccess InfeasibleNoResult UnboundedNoResult InfeasibleOrUnbounded IterationLimit TimeLimit NodeLimit SolutionLimit MemoryLimit ObjectiveLimit NormLimit OtherLimit SlowProgress NumericalError InvalidSolverInstance InvalidOption Interrupted OtherError +@enum TerminationStatusCode Success AlmostSuccess InfeasibleNoResult UnboundedNoResult InfeasibleOrUnbounded IterationLimit TimeLimit NodeLimit SolutionLimit MemoryLimit ObjectiveLimit NormLimit OtherLimit SlowProgress NumericalError InvalidModel InvalidOption Interrupted OtherError ## Result status @@ -592,7 +589,7 @@ The values indicate how to interpret the result vector. The `ResultStatusCode` of the primal result `N`. If `N` is omitted, it defaults to 1. """ -struct PrimalStatus <: AbstractInstanceAttribute +struct PrimalStatus <: AbstractModelAttribute N::Int end PrimalStatus() = PrimalStatus(1) @@ -604,7 +601,7 @@ PrimalStatus() = PrimalStatus(1) The `ResultStatusCode` of the dual result `N`. If `N` is omitted, it defaults to 1. """ -struct DualStatus <: AbstractInstanceAttribute +struct DualStatus <: AbstractModelAttribute N::Int end DualStatus() = DualStatus(1) diff --git a/src/constraints.jl b/src/constraints.jl index 7bbe6fa222..96d36f96e5 100644 --- a/src/constraints.jl +++ b/src/constraints.jl @@ -1,80 +1,80 @@ # Constraints """ - supportsconstraint(instance::AbstractInstance, ::Type{F}, ::Type{S})::Bool where {F<:AbstractFunction,S<:AbstractSet} + supportsconstraint(model::ModelLike, ::Type{F}, ::Type{S})::Bool where {F<:AbstractFunction,S<:AbstractSet} -Return a `Bool` indicating whether `instance` supports `F`-in-`S` constraints, that is, -`copy!(instance, src)` does not return `CopyUnsupportedConstraint` when `src` contains `F`-in-`S` constraints. +Return a `Bool` indicating whether `model` supports `F`-in-`S` constraints, that is, +`copy!(model, src)` does not return `CopyUnsupportedConstraint` when `src` contains `F`-in-`S` constraints. If `F`-in-`S` constraints are only not supported in specific circumstances, e.g. `F`-in-`S` constraints cannot be combined with another type of constraint, it should still return `true`. """ -supportsconstraint(instance::AbstractInstance, ::Type{<:AbstractFunction}, ::Type{<:AbstractSet}) = false +supportsconstraint(model::ModelLike, ::Type{<:AbstractFunction}, ::Type{<:AbstractSet}) = false """ - canaddconstraint(instance::AbstractInstance, ::Type{F}, ::Type{S})::Bool where {F<:AbstractFunction,S<:AbstractSet} + canaddconstraint(model::ModelLike, ::Type{F}, ::Type{S})::Bool where {F<:AbstractFunction,S<:AbstractSet} Return a `Bool` indicating whether it is possible to add a constraint ``f(x) \\in \\mathcal{S}`` where ``f`` is of type `F`, and ``\\mathcal{S}`` is of type `S`. """ -canaddconstraint(instance::AbstractInstance, ::Type{<:AbstractFunction}, ::Type{<:AbstractSet}) = false +canaddconstraint(model::ModelLike, ::Type{<:AbstractFunction}, ::Type{<:AbstractSet}) = false """ - addconstraint!(instance::AbstractInstance, func::F, set::S)::ConstraintIndex{F,S} where {F,S} + addconstraint!(model::ModelLike, func::F, set::S)::ConstraintIndex{F,S} where {F,S} Add the constraint ``f(x) \\in \\mathcal{S}`` where ``f`` is defined by `func`, and ``\\mathcal{S}`` is defined by `set`. - addconstraint!(instance::AbstractInstance, v::VariableIndex, set::S)::ConstraintIndex{SingleVariable,S} where {S} - addconstraint!(instance::AbstractInstance, vec::Vector{VariableIndex}, set::S)::ConstraintIndex{VectorOfVariables,S} where {S} + addconstraint!(model::ModelLike, v::VariableIndex, set::S)::ConstraintIndex{SingleVariable,S} where {S} + addconstraint!(model::ModelLike, vec::Vector{VariableIndex}, set::S)::ConstraintIndex{VectorOfVariables,S} where {S} Add the constraint ``v \\in \\mathcal{S}`` where ``v`` is the variable (or vector of variables) referenced by `v` and ``\\mathcal{S}`` is defined by `set`. """ function addconstraint! end # convenient shorthands TODO: document -addconstraint!(instance::AbstractInstance, v::VariableIndex, set::AbstractScalarSet) = addconstraint!(instance, SingleVariable(v), set) -addconstraint!(instance::AbstractInstance, v::Vector{VariableIndex}, set::AbstractVectorSet) = addconstraint!(instance, VectorOfVariables(v), set) +addconstraint!(model::ModelLike, v::VariableIndex, set::AbstractScalarSet) = addconstraint!(model, SingleVariable(v), set) +addconstraint!(model::ModelLike, v::Vector{VariableIndex}, set::AbstractVectorSet) = addconstraint!(model, VectorOfVariables(v), set) """ - addconstraints!(instance::AbstractInstance, funcs::Vector{F}, sets::Vector{S})::Vector{ConstraintIndex{F,S}} where {F,S} + addconstraints!(model::ModelLike, funcs::Vector{F}, sets::Vector{S})::Vector{ConstraintIndex{F,S}} where {F,S} Add the set of constraints specified by each function-set pair in `funcs` and `sets`. `F` and `S` should be concrete types. -This call is equivalent to `addconstraint!.(instance, funcs, sets)` but may be more efficient. +This call is equivalent to `addconstraint!.(model, funcs, sets)` but may be more efficient. """ function addconstraints! end # default fallback -addconstraints!(instance::AbstractInstance, funcs, sets) = addconstraint!.(instance, funcs, sets) +addconstraints!(model::ModelLike, funcs, sets) = addconstraint!.(model, funcs, sets) """ ## Modify Function - canmodifyconstraint(instance::AbstractInstance, c::ConstraintIndex{F,S}, ::Type{F})::Bool + canmodifyconstraint(model::ModelLike, c::ConstraintIndex{F,S}, ::Type{F})::Bool Return a `Bool` indicating whether the function in constraint `c` can be replaced by another function of the same type `F` as the original function. ## Modify Set - canmodifyconstraint(instance::AbstractInstance, c::ConstraintIndex{F,S}, ::Type{S})::Bool + canmodifyconstraint(model::ModelLike, c::ConstraintIndex{F,S}, ::Type{S})::Bool Return a `Bool` indicating whether the set in constraint `c` can be replaced by another set of the same type `S` as the original set. ## Partial Modifications - canmodifyconstraint(instance::AbstractInstance, c::ConstraintIndex, ::Type{M})::Bool where M<:AbstractFunctionModification + canmodifyconstraint(model::ModelLike, c::ConstraintIndex, ::Type{M})::Bool where M<:AbstractFunctionModification Return a `Bool` indicating whether it is possible to apply a modification of type `M` to the function of constraint `c`. ### Examples ```julia -canmodifyconstraint(instance, c, ScalarConstantChange{Float64}) +canmodifyconstraint(model, c, ScalarConstantChange{Float64}) ``` """ function canmodifyconstraint end -canmodifyconstraint(instance::AbstractInstance, c::ConstraintIndex, change) = false +canmodifyconstraint(model::ModelLike, c::ConstraintIndex, change) = false """ ## Modify Function - modifyconstraint!(instance::AbstractInstance, c::ConstraintIndex{F,S}, func::F) + modifyconstraint!(model::ModelLike, c::ConstraintIndex{F,S}, func::F) Replace the function in constraint `c` with `func`. `F` must match the original function type used to define the constraint. @@ -83,13 +83,13 @@ Replace the function in constraint `c` with `func`. `F` must match the original If `c` is a `ConstraintIndex{ScalarAffineFunction,S}` and `v1` and `v2` are `VariableIndex` objects, ```julia -modifyconstraint!(instance, c, ScalarAffineFunction([v1,v2],[1.0,2.0],5.0)) -modifyconstraint!(instance, c, SingleVariable(v1)) # Error +modifyconstraint!(model, c, ScalarAffineFunction([v1,v2],[1.0,2.0],5.0)) +modifyconstraint!(model, c, SingleVariable(v1)) # Error ``` ## Modify Set - modifyconstraint!(instance::AbstractInstance, c::ConstraintIndex{F,S}, set::S) + modifyconstraint!(model::ModelLike, c::ConstraintIndex{F,S}, set::S) Change the set of constraint `c` to the new set `set` which should be of the same type as the original set. @@ -98,20 +98,20 @@ Change the set of constraint `c` to the new set `set` which should be of the sam If `c` is a `ConstraintIndex{F,Interval}` ```julia -modifyconstraint!(instance, c, Interval(0, 5)) -modifyconstraint!(instance, c, NonPositives) # Error +modifyconstraint!(model, c, Interval(0, 5)) +modifyconstraint!(model, c, NonPositives) # Error ``` ## Partial Modifications - modifyconstraint!(instance::AbstractInstance, c::ConstraintIndex, change::AbstractFunctionModification) + modifyconstraint!(model::ModelLike, c::ConstraintIndex, change::AbstractFunctionModification) Apply the modification specified by `change` to the function of constraint `c`. ### Examples ```julia -modifyconstraint!(instance, c, ScalarConstantChange(10.0)) +modifyconstraint!(model, c, ScalarConstantChange(10.0)) ``` """ function modifyconstraint! end @@ -120,7 +120,7 @@ function modifyconstraint! end """ ## Transform Constraint Set - transformconstraint!(instance::AbstractInstance, c::ConstraintIndex{F,S1}, newset::S2)::ConstraintIndex{F,S2} + transformconstraint!(model::ModelLike, c::ConstraintIndex{F,S1}, newset::S2)::ConstraintIndex{F,S2} Replace the set in constraint `c` with `newset`. The constraint index `c` will no longer be valid, and the function returns a new constraint index with @@ -139,23 +139,23 @@ Typically, the user should delete the constraint and add a new one. If `c` is a `ConstraintIndex{ScalarAffineFunction{Float64},LessThan{Float64}}`, ```julia -c2 = transformconstraint!(instance, c, GreaterThan(0.0)) -transformconstraint!(instance, c, LessThan(0.0)) # errors +c2 = transformconstraint!(model, c, GreaterThan(0.0)) +transformconstraint!(model, c, LessThan(0.0)) # errors ``` """ function transformconstraint! end # default fallback -function transformconstraint!(instance::AbstractInstance, c::ConstraintIndex, newset) - f = get(instance, ConstraintFunction(), c) - delete!(instance, c) - addconstraint!(instance, f, newset) +function transformconstraint!(model::ModelLike, c::ConstraintIndex, newset) + f = get(model, ConstraintFunction(), c) + delete!(model, c) + addconstraint!(model, f, newset) end """ ## Transform Constraint Set - cantransformconstraint(instance::AbstractInstance, c::ConstraintIndex{F,S1}, ::Type{S2})::Bool where S2<:AbstractSet + cantransformconstraint(model::ModelLike, c::ConstraintIndex{F,S1}, ::Type{S2})::Bool where S2<:AbstractSet Return a `Bool` indicating whether the set of type `S1` in constraint `c` can be replaced by a set of type `S2`. @@ -164,13 +164,13 @@ Return a `Bool` indicating whether the set of type `S1` in constraint `c` can be If `c` is a `ConstraintIndex{ScalarAffineFunction{Float64},LessThan{Float64}}`, ```julia -cantransformconstraint(instance, c, GreaterThan(0.0)) # true -cantransformconstraint(instance, c, ZeroOne()) # false +cantransformconstraint(model, c, GreaterThan(0.0)) # true +cantransformconstraint(model, c, ZeroOne()) # false ``` """ function cantransformconstraint end # default fallback -function cantransformconstraint(instance::AbstractInstance, c::ConstraintIndex{F}, ::Type{S}) where {F<:AbstractFunction, S<:AbstractSet} - canget(instance, ConstraintFunction(), typeof(c)) && candelete(instance, c) && canaddconstraint(instance, F, S) +function cantransformconstraint(model::ModelLike, c::ConstraintIndex{F}, ::Type{S}) where {F<:AbstractFunction, S<:AbstractSet} + canget(model, ConstraintFunction(), typeof(c)) && candelete(model, c) && canaddconstraint(model, F, S) end diff --git a/src/indextypes.jl b/src/indextypes.jl index d54cd6c588..a255eb7fe4 100644 --- a/src/indextypes.jl +++ b/src/indextypes.jl @@ -3,7 +3,7 @@ """ ConstraintIndex{F,S} -A type-safe wrapper for `Int64` for use in referencing `F`-in-`S` constraints in an instance. +A type-safe wrapper for `Int64` for use in referencing `F`-in-`S` constraints in a model. The parameter `F` is the type of the function in the constraint, and the parameter `S` is the type of set in the constraint. To allow for deletion, indices need not be consecutive. """ @@ -14,7 +14,7 @@ end """ VariableIndex -A type-safe wrapper for `Int64` for use in referencing variables in an instance. +A type-safe wrapper for `Int64` for use in referencing variables in a model. To allow for deletion, indices need not be consecutive. """ struct VariableIndex @@ -24,28 +24,28 @@ end const Index = Union{ConstraintIndex,VariableIndex} """ - candelete(instance::AbstractInstance, index::Index)::Bool + candelete(model::ModelLike, index::Index)::Bool -Return a `Bool` indicating whether the object referred to by `index` can be removed from the instance `instance`. +Return a `Bool` indicating whether the object referred to by `index` can be removed from the model `model`. """ -candelete(instance::AbstractInstance, ref::Index) = false +candelete(model::ModelLike, ref::Index) = false """ - isvalid(instance::AbstractInstance, index::Index)::Bool + isvalid(model::ModelLike, index::Index)::Bool -Return a `Bool` indicating whether this index refers to a valid object in the instance `instance`. +Return a `Bool` indicating whether this index refers to a valid object in the model `model`. """ -isvalid(instance::AbstractInstance, ref::Index) = false +isvalid(model::ModelLike, ref::Index) = false """ - delete!(instance::AbstractInstance, index::Index) + delete!(model::ModelLike, index::Index) -Delete the referenced object from the instance. +Delete the referenced object from the model. - delete!{R}(instance::AbstractInstance, indices::Vector{R<:Index}) + delete!{R}(model::ModelLike, indices::Vector{R<:Index}) -Delete the referenced objects in the vector `indices` from the instance. +Delete the referenced objects in the vector `indices` from the model. It may be assumed that `R` is a concrete type. """ -Base.delete!(instance::AbstractInstance, index::Index) = throw(MethodError(Base.delete!, (instance, index))) -Base.delete!(instance::AbstractInstance, indices::Vector{<:Index}) = throw(MethodError(Base.delete!, (instance, indices))) +Base.delete!(model::ModelLike, index::Index) = throw(MethodError(Base.delete!, (model, index))) +Base.delete!(model::ModelLike, indices::Vector{<:Index}) = throw(MethodError(Base.delete!, (model, indices))) diff --git a/src/nlp.jl b/src/nlp.jl index 6760292ca7..043c5d9f9c 100644 --- a/src/nlp.jl +++ b/src/nlp.jl @@ -19,7 +19,7 @@ abstract type AbstractNLPEvaluator end Holds the `NLPBlockData` that represents a set of nonlinear constraints, and optionally a nonlinear objective. """ -struct NLPBlock <: MathOptInterface.AbstractInstanceAttribute end +struct NLPBlock <: AbstractModelAttribute end """ NLPBlockDual(N) @@ -28,7 +28,7 @@ struct NLPBlock <: MathOptInterface.AbstractInstanceAttribute end The Lagrange multipliers on the constraints from the `NLPBlock` in result `N`. If `N` is omitted, it is 1 by default. """ -struct NLPBlockDual <: MathOptInterface.AbstractInstanceAttribute +struct NLPBlockDual <: AbstractModelAttribute N::Int end NLPBlockDual() = NLPBlockDual(1) @@ -39,7 +39,7 @@ NLPBlockDual() = NLPBlockDual(1) An initial assignment of the Lagrange multipliers on the constraints from the `NLPBlock` that the solver may use to warm-start the solve. """ -struct NLPBlockDualStart <: MathOptInterface.AbstractInstanceAttribute end +struct NLPBlockDualStart <: AbstractModelAttribute end """ struct NLPBlockData diff --git a/src/objectives.jl b/src/objectives.jl index 5c271a161a..a9672cb646 100644 --- a/src/objectives.jl +++ b/src/objectives.jl @@ -1,29 +1,29 @@ # Objectives """ - modifyobjective!(instance::AbstractInstance, change::AbstractFunctionModification) + modifyobjective!(model::ModekLike, change::AbstractFunctionModification) -Apply the modification specified by `change` to the objective function of `instance`. +Apply the modification specified by `change` to the objective function of `model`. To change the function completely, call `setobjective!` instead. ### Examples ```julia -modifyobjective!(instance, ScalarConstantChange(10.0)) +modifyobjective!(model, ScalarConstantChange(10.0)) ``` """ function modifyobjective! end """ - canmodifyobjective(instance::AbstractInstance, ::Type{M})::Bool where M<:AbstractFunctionModification + canmodifyobjective(model::ModelLike, ::Type{M})::Bool where M<:AbstractFunctionModification -Return a `Bool` indicating whether it is possible to apply a modification of type `M` to the objective function of instance `instance`. +Return a `Bool` indicating whether it is possible to apply a modification of type `M` to the objective function of model `model`. ### Examples ```julia -canmodifyobjective(instance, ScalarConstantChange{Float64}) +canmodifyobjective(model, ScalarConstantChange{Float64}) ``` """ function canmodifyobjective end -canmodifyobjective(instance::AbstractInstance, change) = false +canmodifyobjective(model::ModelLike, change) = false diff --git a/src/variables.jl b/src/variables.jl index fccf18b9b9..540681351d 100644 --- a/src/variables.jl +++ b/src/variables.jl @@ -1,22 +1,22 @@ # Variables """ - canaddvariable(instance::AbstractInstance)::Bool + canaddvariable(model::ModelLike)::Bool -Return a `Bool` indicating whether it is possible to add a variable to the instance `instance`. +Return a `Bool` indicating whether it is possible to add a variable to the model `model`. """ function canaddvariable end """ - addvariables!(instance::AbstractInstance, n::Int)::Vector{VariableIndex} + addvariables!(model::ModelLike, n::Int)::Vector{VariableIndex} -Add `n` scalar variables to the instance, returning a vector of variable indices. +Add `n` scalar variables to the model, returning a vector of variable indices. """ function addvariables! end """ - addvariable!(instance::AbstractInstance)::VariableIndex + addvariable!(model::ModelLike)::VariableIndex -Add a scalar variable to the instance, returning a variable index. +Add a scalar variable to the model, returning a variable index. """ function addvariable! end From 2d641552a50db1ccd5b53457c5f8a62d98e83c93 Mon Sep 17 00:00:00 2001 From: Miles Lubin Date: Sat, 10 Feb 2018 23:09:42 -0500 Subject: [PATCH 2/4] mention candelete and cone -> cones --- docs/src/apimanual.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/src/apimanual.md b/docs/src/apimanual.md index 1774b97e47..f1f04e3a60 100644 --- a/docs/src/apimanual.md +++ b/docs/src/apimanual.md @@ -93,7 +93,7 @@ v2 = addvariables!(model, 3) set!(model, VariablePrimalStart(), v2, [1.3,6.8,-4.6]) ``` -A variable can be deleted from a model with [`delete!(::ModelLike, ::VariableIndex)`](@ref MathOptInterface.delete!(::MathOptInterface.ModelLike, ::MathOptInterface.Index)), if this functionality is supported. +A variable can be deleted from a model with [`delete!(::ModelLike, ::VariableIndex)`](@ref MathOptInterface.delete!(::MathOptInterface.ModelLike, ::MathOptInterface.Index)). Not all models support deleting variables; the [`candelete`](@ref MathOptInterface.candelete) method is used to check if this is supported. ## Functions @@ -348,7 +348,7 @@ primal_variable_result = MOI.get(optimizer, MOI.VariablePrimal(), x) ### Duals -Conic duality is the starting point for MOI's duality conventions. When all functions are affine (or coordinate projections), and all constraint sets are closed convex cone, the model may be called a conic optimization problem. +Conic duality is the starting point for MOI's duality conventions. When all functions are affine (or coordinate projections), and all constraint sets are closed convex cones, the model may be called a conic optimization problem. For conic-form minimization problems, the primal is: ```math From 5ecd39a190cb42cb75cc4b47354b804cdfad8bf4 Mon Sep 17 00:00:00 2001 From: Miles Lubin Date: Sun, 11 Feb 2018 09:23:28 -0500 Subject: [PATCH 3/4] optimizer parameter -> optimizer attribute --- docs/src/apimanual.md | 2 +- docs/src/apireference.md | 10 ++---- src/MathOptInterface.jl | 8 ++--- src/attributes.jl | 73 +++++++++++++++++++--------------------- 4 files changed, 43 insertions(+), 50 deletions(-) diff --git a/docs/src/apimanual.md b/docs/src/apimanual.md index f1f04e3a60..3da68602dc 100644 --- a/docs/src/apimanual.md +++ b/docs/src/apimanual.md @@ -78,7 +78,7 @@ provide methods to solve the model. Through the rest of the manual, `model` is used as a generic `ModelLike`, and `optimizer` is used as a generic `AbstractOptimizer`. -[Discuss how models are constructed, optimizer parameters.] +[Discuss how models are constructed, optimizer attributes.] ## Variables diff --git a/docs/src/apireference.md b/docs/src/apireference.md index d85be1ce3e..9182647833 100644 --- a/docs/src/apireference.md +++ b/docs/src/apireference.md @@ -6,22 +6,18 @@ CurrentModule = MathOptInterface [Some introduction to API. List basic standalone methods.] -## Parameters and Attributes - -Parameter abstract type. -```@docs -AbstractOptimizerParameter -``` +## Attributes List of attribute categories. ```@docs +AbstractOptimizerAttribute AbstractModelAttribute AbstractVariableAttribute AbstractConstraintAttribute ``` -Functions for getting and setting parameters and attributes. +Functions for getting and setting attributes. ```@docs canget diff --git a/src/MathOptInterface.jl b/src/MathOptInterface.jl index e26a9df13b..d48de986c0 100644 --- a/src/MathOptInterface.jl +++ b/src/MathOptInterface.jl @@ -57,15 +57,15 @@ function read! end """ isempty(model::ModelLike) -Returns `false` if the `model` has any instance attribute set or has any variables or constraints. -Note that an empty model can have optimizer parameters set. +Returns `false` if the `model` has any model attribute set or has any variables or constraints. +Note that an empty model can have optimizer attributes set. """ function isempty end """ empty!(model::ModelLike) -Empty the model, that is, remove all variables, constraints and model attributes but not optimizer parameters. +Empty the model, that is, remove all variables, constraints and model attributes but not optimizer attributes. """ function empty! end @@ -110,7 +110,7 @@ a `CopyResult` object. If the copy is successful, the `CopyResult` contains a dictionary-like object that translates variable and constraint indices from the `src` model to the corresponding indices in the `dest` model. -If an attribute `attr` cannot be copied from `src` to `dest` then an error is thrown. If an optimizer parameter cannot be copied then: +If an attribute `attr` cannot be copied from `src` to `dest` then an error is thrown. If an optimizer attribute cannot be copied then: * If `warnattributes` is `true`, a warning is displayed, otherwise, * The attribute is silently ignored. diff --git a/src/attributes.jl b/src/attributes.jl index c98c000bda..d0cc670bb7 100644 --- a/src/attributes.jl +++ b/src/attributes.jl @@ -1,16 +1,16 @@ # Attributes """ - AbstractOptimizerParameter + AbstractOptimizerAttribute -Abstract supertype for parameter objects that can be used to set or get parameters of the optimizer. +Abstract supertype for attribute objects that can be used to set or get attributes (properties) of the optimizer. ### Note -The difference between `AbstractOptimizerParameter` and `AbstractModelAttribute` lies in the behavior of `isempty`, `empty!` and `copy!`. -Typically optimizer parameters only affect how the model is solved. +The difference between `AbstractOptimizerAttribute` and `AbstractModelAttribute` lies in the behavior of `isempty`, `empty!` and `copy!`. +Typically optimizer attributes only affect how the model is solved. """ -abstract type AbstractOptimizerParameter end +abstract type AbstractOptimizerAttribute end """ AbstractModelAttribute @@ -33,13 +33,12 @@ Abstract supertype for attribute objects that can be used to set or get attribut """ abstract type AbstractConstraintAttribute end -const AnyAttribute = Union{AbstractOptimizerParameter, AbstractModelAttribute, AbstractVariableAttribute, AbstractConstraintAttribute} -const AnyProperty = Union{AbstractOptimizerParameter, AnyAttribute} +const AnyAttribute = Union{AbstractOptimizerAttribute, AbstractModelAttribute, AbstractVariableAttribute, AbstractConstraintAttribute} """ - supports(model::ModelLike, param::AbstractOptimizerParameter)::Bool + supports(model::ModelLike, attr::AbstractOptimizerAttribute)::Bool -Return a `Bool` indicating whether `model` supports the optimizer parameter `param`. +Return a `Bool` indicating whether `model` supports the optimizer attribute `attr`. supports(model::ModelLike, attr::AbstractModelAttribute)::Bool @@ -57,13 +56,13 @@ In other words, it should return `true` if `copy!(model, src)` does not return ` If the attribute is only not supported in specific circumstances, it should still return `true`. """ function supports end -supports(::ModelLike, ::AnyProperty) = false -supports(::ModelLike, ::AnyAttribute, ::Type{<:Index}) = false +supports(::ModelLike, ::Union{AbstractModelAttribute, AbstractOptimizerAttribute}) = false +supports(::ModelLike, ::Union{AbstractVariableAttribute, AbstractConstraintAttribute}, ::Type{<:Index}) = false """ - get(model::ModelLike, param::AbstractOptimizerParameter) + get(optimizer::AbstractOptimizer, attr::AbstractOptimizerAttribute) -Return a parameter `param` of the model `model`. +Return an attribute `attr` of the optimizer `optimizer`. get(model::ModelLike, attr::AbstractModelAttribute) @@ -112,13 +111,11 @@ get(model, ConstraintIndex, "con1") function get end # We want to avoid being too specific in the type arguments to avoid method ambiguity. # For model, get(::ModelLike, ::AbstractVariableAttribute, ::Vector{VariableIndex}) would not allow -# to define get(::SomeModel, ::AnyProperty, ::Vector) -get(model::ModelLike, attr::AnyProperty, idxs::Vector) = get.(model, attr, idxs) +# to define get(::SomeModel, ::AnyAttribute, ::Vector) +get(model::ModelLike, attr::AnyAttribute, idxs::Vector) = get.(model, attr, idxs) -_name(attr::AnyAttribute) = "attribute $attr" -_name(attr::AbstractOptimizerParameter) = "parameter $attr" -function get(model::ModelLike, attr::AnyProperty, args...) - throw(ArgumentError("ModelLike of type $(typeof(model)) does not support accessing the $(_name(attr))")) +function get(model::ModelLike, attr::AnyAttribute, args...) + throw(ArgumentError("ModelLike of type $(typeof(model)) does not support accessing the attribute $attr")) end """ @@ -128,14 +125,14 @@ An in-place version of `get`. The signature matches that of `get` except that the the result is placed in the vector `output`. """ function get! end -function get!(output, model::ModelLike, attr::AnyProperty, args...) - throw(ArgumentError("ModelLike of type $(typeof(model)) does not support accessing the $(_name(attr))")) +function get!(output, model::ModelLike, attr::AnyAttribute, args...) + throw(ArgumentError("ModelLike of type $(typeof(model)) does not support accessing the attribute $attr")) end """ - canget(model::ModelLike, param::AbstractOptimizerParameter)::Bool + canget(optimizer::AbstractOptimizer, attr::AbstractOptimizerAttribute)::Bool -Return a `Bool` indicating whether `model` currently has a value for the parameter specified by parameter type `param`. +Return a `Bool` indicating whether `optimizer` currently has a value for the attribute specified by attr type `attr`. canget(model::ModelLike, attr::AbstractModelAttribute)::Bool @@ -175,13 +172,13 @@ canget(model, ConstraintIndex, "con1") ``` """ function canget end -canget(model::ModelLike, attr::AnyProperty) = false -canget(model::ModelLike, attr::AnyAttribute, ::Type{<:Index}) = false +canget(model::ModelLike, attr::Union{AbstractModelAttribute, AbstractOptimizerAttribute}) = false +canget(model::ModelLike, attr::Union{AbstractVariableAttribute, AbstractConstraintAttribute}, ::Type{<:Index}) = false """ - canset(model::ModelLike, param::AbstractOptimizerParameter)::Bool + canset(optimizer::AbstractOptimizer, attr::AbstractOptimizerAttribute)::Bool -Return a `Bool` indicating whether it is possible to set the parameter `param` to the model `model`. +Return a `Bool` indicating whether it is possible to set the attribute `attr` to the optimizer `optimizer`. canset(model::ModelLike, attr::AbstractModelAttribute)::Bool @@ -201,13 +198,13 @@ canset(model, ConstraintPrimal(), ConstraintIndex{VectorAffineFunction{Float64}, ``` """ function canset end -canset(model::ModelLike, attr::AnyProperty) = false -canset(model::ModelLike, attr::AnyAttribute, ref::Type{<:Index}) = false +canset(model::ModelLike, attr::Union{AbstractModelAttribute, AbstractOptimizerAttribute}) = false +canset(model::ModelLike, attr::Union{AbstractVariableAttribute, AbstractConstraintAttribute}, ref::Type{<:Index}) = false """ - set!(model::ModelLike, param::AbstractOptimizerParameter, value) + set!(optimizer::AbstractOptimizer, attr::AbstractOptimizerAttribute, value) -Assign `value` to the parameter `param` of the model `model`. +Assign `value` to the attribute `attr` of the optimizer `optimizer`. set!(model::ModelLike, attr::AbstractModelAttribute, value) @@ -231,20 +228,20 @@ Assign a value respectively to the attribute `attr` of each constraint in the co """ function set! end # See note with get -set!(model::ModelLike, attr::AnyProperty, idxs::Vector, vector_of_values::Vector) = set!.(model, attr, idxs, vector_of_values) +set!(model::ModelLike, attr::AnyAttribute, idxs::Vector, vector_of_values::Vector) = set!.(model, attr, idxs, vector_of_values) -function set!(model::ModelLike, attr::AnyProperty, args...) - throw(ArgumentError("ModelLike of type $(typeof(model)) does not support setting the $(_name(attr))")) +function set!(model::ModelLike, attr::AnyAttribute, args...) + throw(ArgumentError("ModelLike of type $(typeof(model)) does not support setting the attribute $attr")) end -## Optimizer parameters +## Optimizer attributes """ - ListOfOptimizerParametersSet() + ListOfOptimizerAttributesSet() -A `Vector{AbstractOptimizerParameter}` of all optimizer parameters that were set to the model. +A `Vector{AbstractOptimizerAttribute}` of all optimizer attributes that were set. """ -struct ListOfOptimizerParametersSet <: AbstractOptimizerParameter end +struct ListOfOptimizerAttributesSet <: AbstractOptimizerAttribute end ## Model attributes From 9f2f9b9c136050259a19a9ff432688488399f796 Mon Sep 17 00:00:00 2001 From: Miles Lubin Date: Sun, 11 Feb 2018 16:55:36 -0500 Subject: [PATCH 4/4] narrow definition of vectorized set! --- src/attributes.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/attributes.jl b/src/attributes.jl index d0cc670bb7..4fd3f372ff 100644 --- a/src/attributes.jl +++ b/src/attributes.jl @@ -228,7 +228,7 @@ Assign a value respectively to the attribute `attr` of each constraint in the co """ function set! end # See note with get -set!(model::ModelLike, attr::AnyAttribute, idxs::Vector, vector_of_values::Vector) = set!.(model, attr, idxs, vector_of_values) +set!(model::ModelLike, attr::Union{AbstractVariableAttribute, AbstractConstraintAttribute}, idxs::Vector, vector_of_values::Vector) = set!.(model, attr, idxs, vector_of_values) function set!(model::ModelLike, attr::AnyAttribute, args...) throw(ArgumentError("ModelLike of type $(typeof(model)) does not support setting the attribute $attr"))