@@ -17,6 +17,7 @@ mutable struct _CacheModel
1717 objective:: Expr
1818 sense:: MOI.OptimizationSense
1919 complements_map:: Dict{Int,Int}
20+ defined_variables:: Dict{Int,Expr}
2021
2122 function _CacheModel ()
2223 return new (
@@ -32,6 +33,7 @@ mutable struct _CacheModel
3233 :(),
3334 MOI. FEASIBILITY_SENSE,
3435 Dict {Int,Int} (),
36+ Dict {Int,Expr} (),
3537 )
3638 end
3739end
@@ -179,7 +181,7 @@ function _parse_expr(io::IO, model::_CacheModel)
179181 elseif char == ' v'
180182 index = _next (Int, io, model)
181183 _read_til_newline (io, model)
182- return MOI . VariableIndex (index + 1 )
184+ return _to_variable (model, index )
183185 else
184186 @assert char == ' n'
185187 ret = _next (Float64, io, model)
@@ -188,6 +190,13 @@ function _parse_expr(io::IO, model::_CacheModel)
188190 end
189191end
190192
193+ function _to_variable (model:: _CacheModel , index:: Int )
194+ if index >= length (model. variable_primal)
195+ return model. defined_variables[index]
196+ end
197+ return MOI. VariableIndex (index + 1 )
198+ end
199+
191200function _to_model (data:: _CacheModel ; use_nlp_block:: Bool )
192201 model = MOI. Utilities. UniversalFallback (MOI. Utilities. Model {Float64} ())
193202 x = MOI. add_variables (model, length (data. variable_primal))
@@ -394,12 +403,7 @@ function _parse_header(io::IO, model::_CacheModel)
394403 # them
395404 _read_til_newline (io, model)
396405 # Line 10
397- # We don't support reading common subexpressions
398- for _ in 1 : 5
399- if _next (Int, io, model) > 0
400- error (" Unable to parse NL file : we don't support common exprs" )
401- end
402- end
406+ # We support subexpressions, but we don't need to know the details yet.
403407 _read_til_newline (io, model)
404408 # ==========================================================================
405409 # Deal with the integrality of variables. This is quite complicated, so go
@@ -478,13 +482,24 @@ function _parse_section(io::IO, ::Val{'S'}, model::_CacheModel)
478482 return
479483end
480484
481- function _parse_section (:: IO , :: Val{'V'} , :: _CacheModel )
482- return error (
483- " Unable to parse NL file: defined variable definitions ('V' sections)" *
484- " are not yet supported. To request support, please open an issue at " *
485- " https://github.com/jump-dev/MathOptInterface.jl with a reproducible " *
486- " example." ,
487- )
485+ function _parse_section (io:: IO , :: Val{'V'} , model:: _CacheModel )
486+ i = _next (Int, io, model)
487+ j = _next (Int, io, model)
488+ k = _next (Int, io, model)
489+ _read_til_newline (io, model)
490+ affine_terms = Expr (:call , :+ )
491+ for l in 1 : j
492+ p_l = _to_variable (model, _next (Int, io, model))
493+ c_l = _next (Float64, io, model)
494+ _read_til_newline (io, model)
495+ push! (affine_terms. args, Expr (:call , :* , c_l, p_l))
496+ end
497+ expr = _parse_expr (io, model)
498+ if j > 0
499+ expr = Expr (:call , :+ , affine_terms, expr)
500+ end
501+ model. defined_variables[i] = expr
502+ return
488503end
489504
490505function _parse_section (:: IO , :: Val{'L'} , :: _CacheModel )
0 commit comments