Skip to content

Commit 3c9b748

Browse files
committed
Add flag to to make subtype of AbstractOptimizer
1 parent e1908aa commit 3c9b748

2 files changed

Lines changed: 51 additions & 7 deletions

File tree

src/Utilities/model.jl

Lines changed: 30 additions & 6 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.AbstractOptimizer 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,9 @@ 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 stuct is a subtype of
855+
`MOIU.AbstractOptimizer`, otherwise, it is a subtype of `MOIU.AbstractModelLike`.
856+
841857
### Examples
842858
843859
The model describing an linear program would be:
@@ -850,7 +866,9 @@ The model describing an linear program would be:
850866
(), # untyped scalar functions
851867
(MOI.ScalarAffineFunction,), # typed scalar functions
852868
(MOI.VectorOfVariables,), # untyped vector functions
853-
(MOI.VectorAffineFunction,)) # typed vector functions
869+
(MOI.VectorAffineFunction,) # typed vector functions
870+
true
871+
)
854872
```
855873
856874
Let `MOI` denote `MathOptInterface`, `MOIU` denote `MOI.Utilities` and
@@ -868,7 +886,7 @@ struct LPModelVectorConstraints{T, F <: MOI.AbstractVectorFunction} <: MOIU.Cons
868886
nonnegatives::Vector{MOIU.ConstraintEntry{F, MOI.Nonnegatives}}
869887
nonpositives::Vector{MOIU.ConstraintEntry{F, MOI.Nonpositives}}
870888
end
871-
mutable struct LPModel{T} <: MOIU.AbstractModel{T}
889+
mutable struct LPModel{T} <: MOI.AbstractOptimizer
872890
name::String
873891
sense::MOI.OptimizationSense
874892
objective::Union{MOI.SingleVariable, MOI.ScalarAffineFunction{T}, MOI.ScalarQuadraticFunction{T}}
@@ -900,13 +918,19 @@ end
900918
The type `LPModel` implements the MathOptInterface API except methods specific
901919
to solver models like `optimize!` or `getattribute` with `VariablePrimal`.
902920
"""
903-
macro model(model_name, ss, sst, vs, vst, sf, sft, vf, vft)
921+
macro model(model_name, ss, sst, vs, vst, sf, sft, vf, vft, is_optimizer = false)
904922
scalar_sets = [SymbolSet.(ss.args, false); SymbolSet.(sst.args, true)]
905923
vector_sets = [SymbolSet.(vs.args, false); SymbolSet.(vst.args, true)]
906924

907925
scname = esc(Symbol(string(model_name) * "ScalarConstraints"))
908926
vcname = esc(Symbol(string(model_name) * "VectorConstraints"))
927+
909928
esc_model_name = esc(model_name)
929+
header = if is_optimizer
930+
:($(esc(model_name)){T} <: AbstractOptimizer{T})
931+
else
932+
:($(esc(model_name)){T} <: AbstractModelLike{T})
933+
end
910934

911935
scalar_funs = [SymbolFun.(sf.args, false, Ref(scname));
912936
SymbolFun.(sft.args, true, Ref(scname))]
@@ -924,7 +948,7 @@ macro model(model_name, ss, sst, vs, vst, sf, sft, vf, vft)
924948
end
925949

926950
modeldef = quote
927-
mutable struct $esc_model_name{T} <: AbstractModel{T}
951+
mutable struct $header
928952
name::String
929953
senseset::Bool
930954
sense::$MOI.OptimizationSense

test/Utilities/model.jl

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,28 @@ module TestExternalModel
2525
(NewFunction,),
2626
(),
2727
(),
28-
()
28+
(),
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(optimizer, MOIU.AbstractModelLike{Float64})
49+
@test isa(optimizer, MOIU.AbstractOptimizer{Float64})
3050
end
3151

3252
@testset "External @model" begin

0 commit comments

Comments
 (0)