Skip to content

Commit 46f7064

Browse files
authored
Merge pull request #1031 from JuliaOpt/od/abstractoptimizer
Make AbstractModel <: AbstractOptimizer
2 parents fb303dc + d7334c1 commit 46f7064

2 files changed

Lines changed: 54 additions & 5 deletions

File tree

src/Utilities/model.jl

Lines changed: 32 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,9 @@ function _getlocr(constrs::Vector{<:ConstraintEntry},
8282
end
8383

8484
# Implementation of MOI for AbstractModel
85-
abstract type AbstractModel{T} <: MOI.ModelLike end
85+
abstract type AbstractModelLike{T} <: MOI.ModelLike end
86+
abstract type AbstractOptimizer{T} <: MOI.AbstractOptimizer end
87+
const AbstractModel{T} = Union{AbstractModelLike{T}, AbstractOptimizer{T}}
8688

8789
getconstrloc(model::AbstractModel, ci::CI) = model.constrmap[ci.value]
8890

@@ -806,7 +808,18 @@ _broadcastfield(b, s::SymbolFS) = :($b(f, model.$(_field(s))))
806808
# This macro is for expert/internal use only. Prefer the concrete Model type
807809
# instantiated below.
808810
"""
809-
macro model(model_name, scalar_sets, typed_scalar_sets, vector_sets, typed_vector_sets, scalar_functions, typed_scalar_functions, vector_functions, typed_vector_functions)
811+
macro model(
812+
model_name,
813+
scalar_sets,
814+
typed_scalar_sets,
815+
vector_sets,
816+
typed_vector_sets,
817+
scalar_functions,
818+
typed_scalar_functions,
819+
vector_functions,
820+
typed_vector_functions,
821+
is_optimizer = false
822+
)
810823
811824
Creates a type `model_name` implementing the MOI model interface and containing
812825
`scalar_sets` scalar sets `typed_scalar_sets` typed scalar sets, `vector_sets`
@@ -838,6 +851,12 @@ addition to being different between constraints `F`-in-`S` for the same types
838851
use the the value of the index directly in a dictionary representing a mapping
839852
between constraint indices and something else.
840853
854+
If `is_optimizer = true`, the resulting struct is a subtype of
855+
of `MOIU.AbstractOptimizer`, which is a subtype of
856+
[`MathOptInterface.AbstractOptimizer`](@ref), otherwise, it is a subtype of
857+
`MOIU.AbstractModelLike`, which is a subtype of
858+
[`MathOptInterface.ModelLike`](@ref).
859+
841860
### Examples
842861
843862
The model describing an linear program would be:
@@ -850,7 +869,9 @@ The model describing an linear program would be:
850869
(), # untyped scalar functions
851870
(MOI.ScalarAffineFunction,), # typed scalar functions
852871
(MOI.VectorOfVariables,), # untyped vector functions
853-
(MOI.VectorAffineFunction,)) # typed vector functions
872+
(MOI.VectorAffineFunction,), # typed vector functions
873+
false
874+
)
854875
```
855876
856877
Let `MOI` denote `MathOptInterface`, `MOIU` denote `MOI.Utilities` and
@@ -900,13 +921,19 @@ end
900921
The type `LPModel` implements the MathOptInterface API except methods specific
901922
to solver models like `optimize!` or `getattribute` with `VariablePrimal`.
902923
"""
903-
macro model(model_name, ss, sst, vs, vst, sf, sft, vf, vft)
924+
macro model(model_name, ss, sst, vs, vst, sf, sft, vf, vft, is_optimizer = false)
904925
scalar_sets = [SymbolSet.(ss.args, false); SymbolSet.(sst.args, true)]
905926
vector_sets = [SymbolSet.(vs.args, false); SymbolSet.(vst.args, true)]
906927

907928
scname = esc(Symbol(string(model_name) * "ScalarConstraints"))
908929
vcname = esc(Symbol(string(model_name) * "VectorConstraints"))
930+
909931
esc_model_name = esc(model_name)
932+
header = if is_optimizer
933+
:($(esc(model_name)){T} <: AbstractOptimizer{T})
934+
else
935+
:($(esc(model_name)){T} <: AbstractModelLike{T})
936+
end
910937

911938
scalar_funs = [SymbolFun.(sf.args, false, Ref(scname));
912939
SymbolFun.(sft.args, true, Ref(scname))]
@@ -924,7 +951,7 @@ macro model(model_name, ss, sst, vs, vst, sf, sft, vf, vft)
924951
end
925952

926953
modeldef = quote
927-
mutable struct $esc_model_name{T} <: AbstractModel{T}
954+
mutable struct $header
928955
name::String
929956
senseset::Bool
930957
sense::$MOI.OptimizationSense

test/Utilities/model.jl

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,28 @@ module TestExternalModel
2727
(),
2828
()
2929
)
30+
MathOptInterface.Utilities.@model(ExternalOptimizer,
31+
(MathOptInterface.ZeroOne, NewSet,),
32+
(),
33+
(),
34+
(),
35+
(NewFunction,),
36+
(),
37+
(),
38+
(),
39+
true
40+
)
41+
end
42+
43+
@testset "Super-types" begin
44+
model = TestExternalModel.ExternalModel{Float64}()
45+
optimizer = TestExternalModel.ExternalOptimizer{Float64}()
46+
@test isa(model, MOIU.AbstractModelLike{Float64})
47+
@test !isa(model, MOIU.AbstractOptimizer{Float64})
48+
@test !isa(model, MOI.AbstractOptimizer)
49+
@test !isa(optimizer, MOIU.AbstractModelLike{Float64})
50+
@test isa(optimizer, MOIU.AbstractOptimizer{Float64})
51+
@test isa(optimizer, MOI.AbstractOptimizer)
3052
end
3153

3254
@testset "External @model" begin

0 commit comments

Comments
 (0)