diff --git a/docs/src/submodules/Bridges/overview.md b/docs/src/submodules/Bridges/overview.md index 85717a6ae1..6c4467ecb4 100644 --- a/docs/src/submodules/Bridges/overview.md +++ b/docs/src/submodules/Bridges/overview.md @@ -104,14 +104,14 @@ in a [`Bridges.full_bridge_optimizer`](@ref). ```jldoctest julia> inner_optimizer = MOI.Utilities.Model{Float64}() -MOIU.GenericModel{Float64,MOIU.ModelFunctionConstraints{Float64}} +MOIU.GenericModel{Float64,MOIU.ObjectiveFunctionContainer{Float64},MOIU.SingleVariableConstraints{Float64},MOIU.ModelFunctionConstraints{Float64}} julia> optimizer = MOI.Bridges.full_bridge_optimizer(inner_optimizer, Float64) -MOIB.LazyBridgeOptimizer{MOIU.GenericModel{Float64,MOIU.ModelFunctionConstraints{Float64}}} +MOIB.LazyBridgeOptimizer{MOIU.GenericModel{Float64,MOIU.ObjectiveFunctionContainer{Float64},MOIU.SingleVariableConstraints{Float64},MOIU.ModelFunctionConstraints{Float64}}} with 0 variable bridges with 0 constraint bridges with 0 objective bridges -with inner model MOIU.GenericModel{Float64,MOIU.ModelFunctionConstraints{Float64}} +with inner model MOIU.GenericModel{Float64,MOIU.ObjectiveFunctionContainer{Float64},MOIU.SingleVariableConstraints{Float64},MOIU.ModelFunctionConstraints{Float64}} ``` That's all you have to do! Use `optimizer` as normal, and bridging will happen @@ -136,12 +136,12 @@ However, this will force the constraint to be bridged, even if the ```jldoctest julia> inner_optimizer = MOI.Utilities.Model{Float64}() -MOIU.GenericModel{Float64,MOIU.ModelFunctionConstraints{Float64}} +MOIU.GenericModel{Float64,MOIU.ObjectiveFunctionContainer{Float64},MOIU.SingleVariableConstraints{Float64},MOIU.ModelFunctionConstraints{Float64}} julia> optimizer = MOI.Bridges.Constraint.SplitInterval{Float64}(inner_optimizer) -MOIB.Constraint.SingleBridgeOptimizer{MOIB.Constraint.SplitIntervalBridge{Float64,F,S,LS,US} where US<:MOI.AbstractSet where LS<:MOI.AbstractSet where S<:MOI.AbstractSet where F<:MOI.AbstractFunction,MOIU.GenericModel{Float64,MOIU.ModelFunctionConstraints{Float64}}} +MOIB.Constraint.SingleBridgeOptimizer{MOIB.Constraint.SplitIntervalBridge{Float64,F,S,LS,US} where US<:MOI.AbstractSet where LS<:MOI.AbstractSet where S<:MOI.AbstractSet where F<:MOI.AbstractFunction,MOIU.GenericModel{Float64,MOIU.ObjectiveFunctionContainer{Float64},MOIU.SingleVariableConstraints{Float64},MOIU.ModelFunctionConstraints{Float64}}} with 0 constraint bridges -with inner model MOIU.GenericModel{Float64,MOIU.ModelFunctionConstraints{Float64}} +with inner model MOIU.GenericModel{Float64,MOIU.ObjectiveFunctionContainer{Float64},MOIU.SingleVariableConstraints{Float64},MOIU.ModelFunctionConstraints{Float64}} julia> x = MOI.add_variable(optimizer) MOI.VariableIndex(1) @@ -168,14 +168,14 @@ manually construct a [`Bridges.LazyBridgeOptimizer`](@ref). First, wrap an inner optimizer: ```jldoctest lazy_bridge_optimizer julia> inner_optimizer = MOI.Utilities.Model{Float64}() -MOIU.GenericModel{Float64,MOIU.ModelFunctionConstraints{Float64}} +MOIU.GenericModel{Float64,MOIU.ObjectiveFunctionContainer{Float64},MOIU.SingleVariableConstraints{Float64},MOIU.ModelFunctionConstraints{Float64}} julia> optimizer = MOI.Bridges.LazyBridgeOptimizer(inner_optimizer) -MOIB.LazyBridgeOptimizer{MOIU.GenericModel{Float64,MOIU.ModelFunctionConstraints{Float64}}} +MOIB.LazyBridgeOptimizer{MOIU.GenericModel{Float64,MOIU.ObjectiveFunctionContainer{Float64},MOIU.SingleVariableConstraints{Float64},MOIU.ModelFunctionConstraints{Float64}}} with 0 variable bridges with 0 constraint bridges with 0 objective bridges -with inner model MOIU.GenericModel{Float64,MOIU.ModelFunctionConstraints{Float64}} +with inner model MOIU.GenericModel{Float64,MOIU.ObjectiveFunctionContainer{Float64},MOIU.SingleVariableConstraints{Float64},MOIU.ModelFunctionConstraints{Float64}} ``` Then use [`Bridges.add_bridge`](@ref) to add individual bridges: diff --git a/docs/src/submodules/FileFormats/overview.md b/docs/src/submodules/FileFormats/overview.md index be44b28eaf..a138c645f3 100644 --- a/docs/src/submodules/FileFormats/overview.md +++ b/docs/src/submodules/FileFormats/overview.md @@ -65,7 +65,7 @@ To write a model `src` to a [MathOptFormat file](https://jump.dev/MathOptFormat/ use: ```jldoctest fileformats julia> src = MOI.Utilities.Model{Float64}() -MOIU.GenericModel{Float64,MOIU.ModelFunctionConstraints{Float64}} +MOIU.GenericModel{Float64,MOIU.ObjectiveFunctionContainer{Float64},MOIU.SingleVariableConstraints{Float64},MOIU.ModelFunctionConstraints{Float64}} julia> MOI.add_variable(src) MathOptInterface.VariableIndex(1) @@ -122,7 +122,7 @@ guess the format from the file extension. For example: ```jldoctest fileformats julia> src = MOI.Utilities.Model{Float64}() -MOIU.GenericModel{Float64,MOIU.ModelFunctionConstraints{Float64}} +MOIU.GenericModel{Float64,MOIU.ObjectiveFunctionContainer{Float64},MOIU.SingleVariableConstraints{Float64},MOIU.ModelFunctionConstraints{Float64}} julia> dest = MOI.FileFormats.Model(filename = "file.cbf.gz") A Conic Benchmark Format (CBF) model @@ -136,7 +136,7 @@ julia> src_2 = MOI.FileFormats.Model(filename = "file.cbf.gz") A Conic Benchmark Format (CBF) model julia> src = MOI.Utilities.Model{Float64}() -MOIU.GenericModel{Float64,MOIU.ModelFunctionConstraints{Float64}} +MOIU.GenericModel{Float64,MOIU.ObjectiveFunctionContainer{Float64},MOIU.SingleVariableConstraints{Float64},MOIU.ModelFunctionConstraints{Float64}} julia> dest = MOI.FileFormats.Model(filename = "file.cbf.gz") A Conic Benchmark Format (CBF) model @@ -180,7 +180,7 @@ In addition to [`write_to_file`](@ref) and [`read_from_file`](@ref), you can read and write directly from `IO` streams using `Base.write` and `Base.read!`: ```jldoctest julia> src = MOI.Utilities.Model{Float64}() -MOIU.GenericModel{Float64,MOIU.ModelFunctionConstraints{Float64}} +MOIU.GenericModel{Float64,MOIU.ObjectiveFunctionContainer{Float64},MOIU.SingleVariableConstraints{Float64},MOIU.ModelFunctionConstraints{Float64}} julia> dest = MOI.FileFormats.Model(format = MOI.FileFormats.FORMAT_MPS) A Mathematical Programming System (MPS) model diff --git a/docs/src/submodules/Utilities/overview.md b/docs/src/submodules/Utilities/overview.md index 669afbfdfa..1a2ed2b04c 100644 --- a/docs/src/submodules/Utilities/overview.md +++ b/docs/src/submodules/Utilities/overview.md @@ -21,7 +21,7 @@ given the extensibility of MOI, this might not cover all use cases. Create a model as follows: ```jldoctest julia> model = MOI.Utilities.Model{Float64}() -MOIU.GenericModel{Float64,MOIU.ModelFunctionConstraints{Float64}} +MOIU.GenericModel{Float64,MOIU.ObjectiveFunctionContainer{Float64},MOIU.SingleVariableConstraints{Float64},MOIU.ModelFunctionConstraints{Float64}} ``` ## Utilities.UniversalFallback @@ -36,8 +36,8 @@ like [`VariablePrimalStart`](@ref), so JuMP uses a combination of Universal fallback and [`Utilities.Model`](@ref) as a generic problem cache: ```jldoctest julia> model = MOI.Utilities.UniversalFallback(MOI.Utilities.Model{Float64}()) -MOIU.UniversalFallback{MOIU.GenericModel{Float64,MOIU.ModelFunctionConstraints{Float64}}} -fallback for MOIU.GenericModel{Float64,MOIU.ModelFunctionConstraints{Float64}} +MOIU.UniversalFallback{MOIU.GenericModel{Float64,MOIU.ObjectiveFunctionContainer{Float64},MOIU.SingleVariableConstraints{Float64},MOIU.ModelFunctionConstraints{Float64}}} +fallback for MOIU.GenericModel{Float64,MOIU.ObjectiveFunctionContainer{Float64},MOIU.SingleVariableConstraints{Float64},MOIU.ModelFunctionConstraints{Float64}} ``` !!! warning @@ -83,10 +83,10 @@ julia> MOI.Utilities.@model( (MOI.VectorAffineFunction,), # Typed vector functions true, # <:MOI.AbstractOptimizer? ) -MathOptInterface.Utilities.GenericOptimizer{T,MyNewModelFunctionConstraints{T}} where T +MathOptInterface.Utilities.GenericOptimizer{T,MathOptInterface.Utilities.ObjectiveFunctionContainer{T},MathOptInterface.Utilities.SingleVariableConstraints{T},MyNewModelFunctionConstraints{T}} where T julia> model = MyNewModel{Float64}() -MOIU.GenericOptimizer{Float64,MyNewModelFunctionConstraints{Float64}} +MOIU.GenericOptimizer{Float64,MOIU.ObjectiveFunctionContainer{Float64},MOIU.SingleVariableConstraints{Float64},MyNewModelFunctionConstraints{Float64}} ``` !!! warning @@ -112,7 +112,7 @@ julia> MOI.Utilities.@model( (MOI.VectorAffineFunction,), # Typed vector functions true, # is_optimizer ) -MathOptInterface.Utilities.GenericOptimizer{T,MathOptInterface.Utilities.VectorOfConstraints{MathOptInterface.VectorAffineFunction{T},MathOptInterface.Complements}} where T +MathOptInterface.Utilities.GenericOptimizer{T,MathOptInterface.Utilities.ObjectiveFunctionContainer{T},MathOptInterface.Utilities.SingleVariableConstraints{T},MathOptInterface.Utilities.VectorOfConstraints{MathOptInterface.VectorAffineFunction{T},MathOptInterface.Complements}} where T ``` However, `PathOptimizer` does not support some `SingleVariable`-in-Set constraints, so we must explicitly define: @@ -152,11 +152,11 @@ julia> model = MOI.Utilities.CachingOptimizer( MOI.Utilities.Model{Float64}(), PathOptimizer{Float64}(), ) -MOIU.CachingOptimizer{MOIU.GenericOptimizer{Float64,MOIU.VectorOfConstraints{MOI.VectorAffineFunction{Float64},MOI.Complements}},MOIU.GenericModel{Float64,MOIU.ModelFunctionConstraints{Float64}}} +MOIU.CachingOptimizer{MOIU.GenericOptimizer{Float64,MOIU.ObjectiveFunctionContainer{Float64},MOIU.SingleVariableConstraints{Float64},MOIU.VectorOfConstraints{MOI.VectorAffineFunction{Float64},MOI.Complements}},MOIU.GenericModel{Float64,MOIU.ObjectiveFunctionContainer{Float64},MOIU.SingleVariableConstraints{Float64},MOIU.ModelFunctionConstraints{Float64}}} in state EMPTY_OPTIMIZER in mode AUTOMATIC -with model cache MOIU.GenericModel{Float64,MOIU.ModelFunctionConstraints{Float64}} -with optimizer MOIU.GenericOptimizer{Float64,MOIU.VectorOfConstraints{MOI.VectorAffineFunction{Float64},MOI.Complements}} +with model cache MOIU.GenericModel{Float64,MOIU.ObjectiveFunctionContainer{Float64},MOIU.SingleVariableConstraints{Float64},MOIU.ModelFunctionConstraints{Float64}} +with optimizer MOIU.GenericOptimizer{Float64,MOIU.ObjectiveFunctionContainer{Float64},MOIU.SingleVariableConstraints{Float64},MOIU.VectorOfConstraints{MOI.VectorAffineFunction{Float64},MOI.Complements}} ``` A [`Utilities.CachingOptimizer`](@ref) may be in one of three possible states: @@ -176,11 +176,11 @@ Use [`Utilities.attach_optimizer`](@ref) to go from `EMPTY_OPTIMIZER` to julia> MOI.Utilities.attach_optimizer(model) julia> model -MOIU.CachingOptimizer{MOIU.GenericOptimizer{Float64,MOIU.VectorOfConstraints{MOI.VectorAffineFunction{Float64},MOI.Complements}},MOIU.GenericModel{Float64,MOIU.ModelFunctionConstraints{Float64}}} +MOIU.CachingOptimizer{MOIU.GenericOptimizer{Float64,MOIU.ObjectiveFunctionContainer{Float64},MOIU.SingleVariableConstraints{Float64},MOIU.VectorOfConstraints{MOI.VectorAffineFunction{Float64},MOI.Complements}},MOIU.GenericModel{Float64,MOIU.ObjectiveFunctionContainer{Float64},MOIU.SingleVariableConstraints{Float64},MOIU.ModelFunctionConstraints{Float64}}} in state ATTACHED_OPTIMIZER in mode AUTOMATIC -with model cache MOIU.GenericModel{Float64,MOIU.ModelFunctionConstraints{Float64}} -with optimizer MOIU.GenericOptimizer{Float64,MOIU.VectorOfConstraints{MOI.VectorAffineFunction{Float64},MOI.Complements}} +with model cache MOIU.GenericModel{Float64,MOIU.ObjectiveFunctionContainer{Float64},MOIU.SingleVariableConstraints{Float64},MOIU.ModelFunctionConstraints{Float64}} +with optimizer MOIU.GenericOptimizer{Float64,MOIU.ObjectiveFunctionContainer{Float64},MOIU.SingleVariableConstraints{Float64},MOIU.VectorOfConstraints{MOI.VectorAffineFunction{Float64},MOI.Complements}} ``` !!! info @@ -192,11 +192,11 @@ Use [`Utilities.reset_optimizer`](@ref) to go from `ATTACHED_OPTIMIZER` to julia> MOI.Utilities.reset_optimizer(model) julia> model -MOIU.CachingOptimizer{MOIU.GenericOptimizer{Float64,MOIU.VectorOfConstraints{MOI.VectorAffineFunction{Float64},MOI.Complements}},MOIU.GenericModel{Float64,MOIU.ModelFunctionConstraints{Float64}}} +MOIU.CachingOptimizer{MOIU.GenericOptimizer{Float64,MOIU.ObjectiveFunctionContainer{Float64},MOIU.SingleVariableConstraints{Float64},MOIU.VectorOfConstraints{MOI.VectorAffineFunction{Float64},MOI.Complements}},MOIU.GenericModel{Float64,MOIU.ObjectiveFunctionContainer{Float64},MOIU.SingleVariableConstraints{Float64},MOIU.ModelFunctionConstraints{Float64}}} in state EMPTY_OPTIMIZER in mode AUTOMATIC -with model cache MOIU.GenericModel{Float64,MOIU.ModelFunctionConstraints{Float64}} -with optimizer MOIU.GenericOptimizer{Float64,MOIU.VectorOfConstraints{MOI.VectorAffineFunction{Float64},MOI.Complements}} +with model cache MOIU.GenericModel{Float64,MOIU.ObjectiveFunctionContainer{Float64},MOIU.SingleVariableConstraints{Float64},MOIU.ModelFunctionConstraints{Float64}} +with optimizer MOIU.GenericOptimizer{Float64,MOIU.ObjectiveFunctionContainer{Float64},MOIU.SingleVariableConstraints{Float64},MOIU.VectorOfConstraints{MOI.VectorAffineFunction{Float64},MOI.Complements}} ``` !!! info @@ -209,10 +209,10 @@ Use [`Utilities.drop_optimizer`](@ref) to go from any state to `NO_OPTIMIZER`: julia> MOI.Utilities.drop_optimizer(model) julia> model -MOIU.CachingOptimizer{MOIU.GenericOptimizer{Float64,MOIU.VectorOfConstraints{MOI.VectorAffineFunction{Float64},MOI.Complements}},MOIU.GenericModel{Float64,MOIU.ModelFunctionConstraints{Float64}}} +MOIU.CachingOptimizer{MOIU.GenericOptimizer{Float64,MOIU.ObjectiveFunctionContainer{Float64},MOIU.SingleVariableConstraints{Float64},MOIU.VectorOfConstraints{MOI.VectorAffineFunction{Float64},MOI.Complements}},MOIU.GenericModel{Float64,MOIU.ObjectiveFunctionContainer{Float64},MOIU.SingleVariableConstraints{Float64},MOIU.ModelFunctionConstraints{Float64}}} in state NO_OPTIMIZER in mode AUTOMATIC -with model cache MOIU.GenericModel{Float64,MOIU.ModelFunctionConstraints{Float64}} +with model cache MOIU.GenericModel{Float64,MOIU.ObjectiveFunctionContainer{Float64},MOIU.SingleVariableConstraints{Float64},MOIU.ModelFunctionConstraints{Float64}} with optimizer nothing ``` @@ -222,11 +222,11 @@ Pass an empty optimizer to [`Utilities.reset_optimizer`](@ref) to go from julia> MOI.Utilities.reset_optimizer(model, PathOptimizer{Float64}()) julia> model -MOIU.CachingOptimizer{MOIU.GenericOptimizer{Float64,MOIU.VectorOfConstraints{MOI.VectorAffineFunction{Float64},MOI.Complements}},MOIU.GenericModel{Float64,MOIU.ModelFunctionConstraints{Float64}}} +MOIU.CachingOptimizer{MOIU.GenericOptimizer{Float64,MOIU.ObjectiveFunctionContainer{Float64},MOIU.SingleVariableConstraints{Float64},MOIU.VectorOfConstraints{MOI.VectorAffineFunction{Float64},MOI.Complements}},MOIU.GenericModel{Float64,MOIU.ObjectiveFunctionContainer{Float64},MOIU.SingleVariableConstraints{Float64},MOIU.ModelFunctionConstraints{Float64}}} in state EMPTY_OPTIMIZER in mode AUTOMATIC -with model cache MOIU.GenericModel{Float64,MOIU.ModelFunctionConstraints{Float64}} -with optimizer MOIU.GenericOptimizer{Float64,MOIU.VectorOfConstraints{MOI.VectorAffineFunction{Float64},MOI.Complements}} +with model cache MOIU.GenericModel{Float64,MOIU.ObjectiveFunctionContainer{Float64},MOIU.SingleVariableConstraints{Float64},MOIU.ModelFunctionConstraints{Float64}} +with optimizer MOIU.GenericOptimizer{Float64,MOIU.ObjectiveFunctionContainer{Float64},MOIU.SingleVariableConstraints{Float64},MOIU.VectorOfConstraints{MOI.VectorAffineFunction{Float64},MOI.Complements}} ``` Deciding when to attach and reset the optimizer is tedious, and you will often @@ -256,20 +256,20 @@ julia> model = MOI.Utilities.CachingOptimizer( MOI.Utilities.Model{Float64}(), MOI.Utilities.MANUAL, ) -MOIU.CachingOptimizer{MOI.AbstractOptimizer,MOIU.GenericModel{Float64,MOIU.ModelFunctionConstraints{Float64}}} +MOIU.CachingOptimizer{MOI.AbstractOptimizer,MOIU.GenericModel{Float64,MOIU.ObjectiveFunctionContainer{Float64},MOIU.SingleVariableConstraints{Float64},MOIU.ModelFunctionConstraints{Float64}}} in state NO_OPTIMIZER in mode MANUAL -with model cache MOIU.GenericModel{Float64,MOIU.ModelFunctionConstraints{Float64}} +with model cache MOIU.GenericModel{Float64,MOIU.ObjectiveFunctionContainer{Float64},MOIU.SingleVariableConstraints{Float64},MOIU.ModelFunctionConstraints{Float64}} with optimizer nothing julia> MOI.Utilities.reset_optimizer(model, PathOptimizer{Float64}()) julia> model -MOIU.CachingOptimizer{MOI.AbstractOptimizer,MOIU.GenericModel{Float64,MOIU.ModelFunctionConstraints{Float64}}} +MOIU.CachingOptimizer{MOI.AbstractOptimizer,MOIU.GenericModel{Float64,MOIU.ObjectiveFunctionContainer{Float64},MOIU.SingleVariableConstraints{Float64},MOIU.ModelFunctionConstraints{Float64}}} in state EMPTY_OPTIMIZER in mode MANUAL -with model cache MOIU.GenericModel{Float64,MOIU.ModelFunctionConstraints{Float64}} -with optimizer MOIU.GenericOptimizer{Float64,MOIU.VectorOfConstraints{MOI.VectorAffineFunction{Float64},MOI.Complements}} +with model cache MOIU.GenericModel{Float64,MOIU.ObjectiveFunctionContainer{Float64},MOIU.SingleVariableConstraints{Float64},MOIU.ModelFunctionConstraints{Float64}} +with optimizer MOIU.GenericOptimizer{Float64,MOIU.ObjectiveFunctionContainer{Float64},MOIU.SingleVariableConstraints{Float64},MOIU.VectorOfConstraints{MOI.VectorAffineFunction{Float64},MOI.Complements}} ``` ## Printing diff --git a/src/Utilities/model.jl b/src/Utilities/model.jl index fe270bb1f6..4d882d4ac7 100644 --- a/src/Utilities/model.jl +++ b/src/Utilities/model.jl @@ -666,7 +666,7 @@ struct LPModelFunctionConstraints{T} <: MOIU.StructOfConstraints MOIU.VectorOfConstraints{MOI.VectorAffineFunction{T}, MOI.Nonpositives} } end -const LPModel{T} = MOIU.GenericModel{T, LPModelFunctionConstraints{T}} +const LPModel{T} = MOIU.GenericModel{T,MOIU.ObjectiveFunctionContainer{T},MOIU.SingleVariableConstraints{T},LPModelFunctionConstraints{T}} ``` The type `LPModel` implements the MathOptInterface API except methods specific to optimizers like `optimize!` or `get` with `VariablePrimal`. @@ -718,9 +718,19 @@ macro model( func_typed = _struct_of_constraints_type(func_name, set_struct_types, false) T = esc(:T) generic = if is_optimizer - :(GenericOptimizer{$T,$func_typed}) + :(GenericOptimizer{ + $T, + ObjectiveFunctionContainer{$T}, + SingleVariableConstraints{$T}, + $func_typed, + }) else - :(GenericModel{$T,$func_typed}) + :(GenericModel{ + $T, + ObjectiveFunctionContainer{$T}, + SingleVariableConstraints{$T}, + $func_typed, + }) end model_code = :(const $esc_model_name{$T} = $generic) expr = Expr(:block) @@ -748,29 +758,23 @@ for (loop_name, loop_super_type) in [ global super_type = loop_super_type @eval begin """ - mutable struct $name{T,C} <: $super_type{T} - - Implements a models supporting - * an objective function of type - `MOI.SingleVariable`, `MOI.ScalarAffineFunction{T}` and - `MOI.ScalarQuadraticFunction{T}`, - * [`MathOptInterface.SingleVariable`](@ref)-in-`S` - constraints where `S` is [`MathOptInterface.EqualTo`](@ref), - [`MathOptInterface.GreaterThan`](@ref), [`MathOptInterface.LessThan`](@ref), - [`MathOptInterface.Interval`](@ref), [`MathOptInterface.Integer`](@ref), - [`MathOptInterface.ZeroOne`](@ref), [`MathOptInterface.Semicontinuous`](@ref) - or [`MathOptInterface.Semiinteger`](@ref). - * `F`-in-`S` constraints that are supported by `C`. - - The lower (resp. upper) bound of a variable of index `VariableIndex(i)` - is at the `i`th index of the vector stored in the field `variable_bounds.lower` - (resp. `variable_bounds.upper`). When no lower (resp. upper) bound is set, it is - `typemin(T)` (resp. `typemax(T)`) if `T <: AbstractFloat`. + mutable struct $name{T,O,V,C} <: $super_type{T} + + Implements a model supporting coefficients of type `T` and: + + * An objective function stored in `.objective::O` + * Variables and `SingleVariable` constraints stored in `.variable_bounds::V` + * `F`-in-`S` constraints (excluding `SingleVariable` constraints) + stored in `.constraints::C` + + All interactions should take place via the MOI interface, so the types + `O`, `V`, and `C` should implement the API as needed for their + functionality. """ - mutable struct $name{T,C} <: $super_type{T} + mutable struct $name{T,O,V,C} <: $super_type{T} name::String - objective::ObjectiveFunctionContainer{T} - variables::SingleVariableConstraints{T} + objective::O + variables::V constraints::C var_to_name::Dict{MOI.VariableIndex,String} # If `nothing`, the dictionary hasn't been constructed yet. @@ -780,11 +784,11 @@ for (loop_name, loop_super_type) in [ # A useful dictionary for extensions to store things. These are # _not_ copied between models! ext::Dict{Symbol,Any} - function $name{T,C}() where {T,C} - return new{T,C}( + function $name{T,O,V,C}() where {T,O,V,C} + return new{T,O,V,C}( EMPTYSTRING, - ObjectiveFunctionContainer{T}(), - SingleVariableConstraints{T}(), + O(), + V(), C(), Dict{MOI.VariableIndex,String}(), nothing, @@ -862,3 +866,17 @@ x = add_variable(model) ``` """ Model + +# This export makes the type be printed as: +# ```julia +# julia> Base.show(IOContext(stdout, :compact => true), MathOptInterface.Utilities.Model) +# Model{T} where T +# julia> print(MathOptInterface.Utilities.Model) +# MathOptInterface.Utilities.Model{T} where T +# julia> MathOptInterface.Utilities.Model +# MathOptInterface.Utilities.Model{T} where T (alias for MathOptInterface.Utilities.GenericModel{T, MathOptInterface.Utilities.ObjectiveFunctionContainer{T}, MathOptInterface.Utilities.SingleVariableConstraints{T}, MathOptInterface.Utilities.ModelFunctionConstraints{T}} where T) +# ``` +# As MOI is not doing `using .Utilities` and is not exporting `Model`, the user +# still needs to do `MOI.Utilities.Model` unless he does +# `using MathOptInterface.Utilities`. +export Model diff --git a/test/Utilities/copy.jl b/test/Utilities/copy.jl index e63d1bd71c..28e976aa6b 100644 --- a/test/Utilities/copy.jl +++ b/test/Utilities/copy.jl @@ -771,7 +771,12 @@ function _test_copy_of_constraints_passed_as_copy_accross_layers( dest = MOIU.CachingOptimizer( MOI.Bridges.full_bridge_optimizer( MOIU.UniversalFallback( - MOIU.GenericOptimizer{T,OnlyCopyConstraints{F,S}}(), + MOIU.GenericOptimizer{ + T, + MOI.Utilities.ObjectiveFunctionContainer{T}, + MOI.Utilities.SingleVariableConstraints{T}, + OnlyCopyConstraints{F,S}, + }(), ), T, ), diff --git a/test/Utilities/matrix_of_constraints.jl b/test/Utilities/matrix_of_constraints.jl index 06f4a3cb3f..0a6339fe83 100644 --- a/test/Utilities/matrix_of_constraints.jl +++ b/test/Utilities/matrix_of_constraints.jl @@ -29,6 +29,8 @@ MOI.Utilities.@product_of_sets( function _new_ScalarSets() return MOI.Utilities.GenericOptimizer{ Float64, + MOI.Utilities.ObjectiveFunctionContainer{Float64}, + MOI.Utilities.SingleVariableConstraints{Float64}, MOI.Utilities.MatrixOfConstraints{ Float64, MOI.Utilities.MutableSparseMatrixCSC{ @@ -52,6 +54,8 @@ MOI.Utilities.@product_of_sets( function _new_VectorSets() return MOI.Utilities.GenericOptimizer{ Int, + MOI.Utilities.ObjectiveFunctionContainer{Int}, + MOI.Utilities.SingleVariableConstraints{Int}, MOI.Utilities.MatrixOfConstraints{ Int, MOI.Utilities.MutableSparseMatrixCSC{ @@ -277,6 +281,8 @@ end function test_ScalarSets() optimizer = MOI.Utilities.GenericOptimizer{ Float64, + MOI.Utilities.ObjectiveFunctionContainer{Float64}, + MOI.Utilities.SingleVariableConstraints{Float64}, MOI.Utilities.MatrixOfConstraints{ Float64, MOI.Utilities.MutableSparseMatrixCSC{ @@ -305,6 +311,8 @@ end function test_modify() model = MOI.Utilities.GenericOptimizer{ Int, + MOI.Utilities.ObjectiveFunctionContainer{Int}, + MOI.Utilities.SingleVariableConstraints{Int}, MOI.Utilities.MatrixOfConstraints{ Int, MOI.Utilities.MutableSparseMatrixCSC{ @@ -343,6 +351,8 @@ function test_multicone() Indexing = MOI.Utilities.OneBasedIndexing model = MOI.Utilities.GenericOptimizer{ T, + MOI.Utilities.ObjectiveFunctionContainer{T}, + MOI.Utilities.SingleVariableConstraints{T}, ZerosOrNot{T}{ MOI.Utilities.MatrixOfConstraints{ T, diff --git a/test/Utilities/model.jl b/test/Utilities/model.jl index ff77e0bbb1..4c3718d2ad 100644 --- a/test/Utilities/model.jl +++ b/test/Utilities/model.jl @@ -101,11 +101,14 @@ function test_TestExternalModel_fields() @test !isdefined(TestExternalModel, :ExternalOptimizerFunctionConstraints) @test TestExternalModel.ExternalModel{Int} == MOI.Utilities.GenericModel{ Int, + MOI.Utilities.ObjectiveFunctionContainer{Int}, + MOI.Utilities.SingleVariableConstraints{Int}, TestExternalModel.ExternalModelFunctionConstraints{Int}, } - @test TestExternalModel.ExternalOptimizer{Int} == - MOI.Utilities.GenericOptimizer{ + model = MOI.Utilities.GenericOptimizer{ Int, + MOI.Utilities.ObjectiveFunctionContainer{Int}, + MOI.Utilities.SingleVariableConstraints{Int}, TestExternalModel.ExternalOptimizerScalarConstraints{ Int, MOI.Utilities.VectorOfConstraints{ @@ -118,6 +121,8 @@ function test_TestExternalModel_fields() }, }, } + @test TestExternalModel.ExternalOptimizer{Int} == model + return end