@@ -13,6 +13,7 @@ optimizer bridges should be used instead.
1313"""
1414mutable struct UniversalFallback{MT} <: MOI.ModelLike
1515 model:: MT
16+ objective:: Union{MOI.AbstractScalarFunction, Nothing}
1617 constraints:: OrderedDict{Tuple{DataType, DataType}, OrderedDict} # See https://github.com/JuliaOpt/JuMP.jl/issues/1152 and https://github.com/JuliaOpt/JuMP.jl/issues/2238
1718 nextconstraintid:: Int64
1819 con_to_name:: Dict{CI, String}
@@ -23,6 +24,7 @@ mutable struct UniversalFallback{MT} <: MOI.ModelLike
2324 conattr:: Dict{MOI.AbstractConstraintAttribute, Dict{CI, Any}}
2425 function UniversalFallback {MT} (model:: MOI.ModelLike ) where {MT}
2526 new {typeof(model)} (model,
27+ nothing ,
2628 OrderedDict {Tuple{DataType, DataType}, OrderedDict} (),
2729 0 ,
2830 Dict {CI, String} (),
@@ -39,10 +41,11 @@ function Base.show(io::IO, U::UniversalFallback)
3941 s (n) = n == 1 ? " " : " s"
4042 indent = " " ^ get (io, :indent , 0 )
4143 MOIU. print_with_acronym (io, summary (U))
44+ ! (U. objective === nothing ) && print (io, " \n $(indent) with objective" )
4245 for (attr, name) in ( (U. constraints, " constraint" ),
43- (U. optattr, " optimizer attribute" ),
44- (U. modattr, " model attribute" ),
45- (U. varattr, " variable attribute" ),
46+ (U. optattr, " optimizer attribute" ),
47+ (U. modattr, " model attribute" ),
48+ (U. varattr, " variable attribute" ),
4649 (U. conattr, " constraint attribute" ) )
4750 n = length (attr)
4851 if n > 0
@@ -54,11 +57,12 @@ function Base.show(io::IO, U::UniversalFallback)
5457end
5558
5659function MOI. is_empty (uf:: UniversalFallback )
57- return MOI. is_empty (uf. model) && isempty (uf. constraints) &&
60+ return MOI. is_empty (uf. model) && uf . objective === nothing && isempty (uf. constraints) &&
5861 isempty (uf. modattr) && isempty (uf. varattr) && isempty (uf. conattr)
5962end
6063function MOI. empty! (uf:: UniversalFallback )
6164 MOI. empty! (uf. model)
65+ uf. objective = nothing
6266 empty! (uf. constraints)
6367 uf. nextconstraintid = 0
6468 empty! (uf. con_to_name)
@@ -156,6 +160,9 @@ function MOI.delete(uf::UniversalFallback, vi::VI)
156160 for d in values (uf. varattr)
157161 delete! (d, vi)
158162 end
163+ if uf. objective != = nothing
164+ uf. objective = remove_variable (uf. objective, vi)
165+ end
159166 for (_, constraints) in uf. constraints
160167 _remove_variable (uf, constraints, vi)
161168 end
@@ -167,6 +174,9 @@ function MOI.delete(uf::UniversalFallback, vis::Vector{VI})
167174 delete! (d, vi)
168175 end
169176 end
177+ if uf. objective != = nothing
178+ uf. objective = remove_variable (uf. objective, vis)
179+ end
170180 for (_, constraints) in uf. constraints
171181 _remove_vector_of_variables (uf, constraints, vis)
172182 for vi in vis
@@ -248,6 +258,9 @@ function MOI.get(uf::UniversalFallback, listattr::MOI.ListOfOptimizerAttributesS
248258end
249259function MOI. get (uf:: UniversalFallback , listattr:: MOI.ListOfModelAttributesSet )
250260 list = MOI. get (uf. model, listattr)
261+ if uf. objective != = nothing
262+ push! (list, MOI. ObjectiveFunction {typeof(uf.objective)} ())
263+ end
251264 for attr in keys (uf. modattr)
252265 push! (list, attr)
253266 end
@@ -268,6 +281,54 @@ function MOI.get(uf::UniversalFallback, listattr::MOI.ListOfConstraintAttributes
268281 return list
269282end
270283
284+ # Objective
285+ function MOI. set (uf:: UniversalFallback , attr:: MOI.ObjectiveSense ,
286+ sense:: MOI.OptimizationSense ) where T
287+ if sense == MOI. FEASIBILITY_SENSE
288+ uf. objective = nothing
289+ end
290+ MOI. set (uf. model, attr, sense)
291+ end
292+ function MOI. get (uf:: UniversalFallback ,
293+ attr:: MOI.ObjectiveFunctionType )
294+ if uf. objective === nothing
295+ return MOI. get (uf. model, attr)
296+ else
297+ return typeof (uf. objective)
298+ end
299+ end
300+ function MOI. get (uf:: UniversalFallback ,
301+ attr:: MOI.ObjectiveFunction{F} ):: F where F
302+ if uf. objective === nothing
303+ return MOI. get (uf. model, attr)
304+ else
305+ return uf. objective
306+ end
307+ end
308+ function MOI. set (uf:: UniversalFallback ,
309+ attr:: MOI.ObjectiveFunction ,
310+ func:: MOI.AbstractScalarFunction )
311+ if MOI. supports (uf. model, attr)
312+ MOI. set (uf. model, attr, func)
313+ # Clear any fallback objective
314+ uf. objective = nothing
315+ else
316+ uf. objective = copy (func)
317+ # Clear any `model` objective
318+ sense = MOI. get (uf. model, MOI. ObjectiveSense ())
319+ MOI. set (uf. model, MOI. ObjectiveSense (), MOI. FEASIBILITY_SENSE)
320+ MOI. set (uf. model, MOI. ObjectiveSense (), sense)
321+ end
322+ end
323+
324+ function MOI. modify (uf:: UniversalFallback , obj:: MOI.ObjectiveFunction , change:: MOI.AbstractFunctionModification ) where F
325+ if uf. objective === nothing
326+ MOI. modify (uf. model, obj, change)
327+ else
328+ uf. objective = modify_function (uf. objective, change)
329+ end
330+ end
331+
271332# Name
272333# The names of constraints not supported by `uf.model` need to be handled
273334function MOI. set (uf:: UniversalFallback , attr:: MOI.ConstraintName , ci:: CI{F, S} , name:: String ) where {F, S}
@@ -430,9 +491,6 @@ function MOI.set(uf::UniversalFallback, ::MOI.ConstraintSet, ci::CI{F,S}, set::S
430491 end
431492end
432493
433- # Objective
434- MOI. modify (uf:: UniversalFallback , obj:: MOI.ObjectiveFunction , change:: MOI.AbstractFunctionModification ) = MOI. modify (uf. model, obj, change)
435-
436494# Variables
437495MOI. add_variable (uf:: UniversalFallback ) = MOI. add_variable (uf. model)
438496MOI. add_variables (uf:: UniversalFallback , n) = MOI. add_variables (uf. model, n)
0 commit comments