@@ -377,13 +377,15 @@ mutable struct _ReadCache
377
377
constraint_name:: String
378
378
num_constraints:: Int
379
379
name_to_variable:: Dict{String,MOI.VariableIndex}
380
+ has_default_bound:: Set{MOI.VariableIndex}
380
381
function _ReadCache ()
381
382
return new (
382
383
MOI. ScalarAffineFunction (MOI. ScalarAffineTerm{Float64}[], 0.0 ),
383
384
MOI. ScalarAffineFunction (MOI. ScalarAffineTerm{Float64}[], 0.0 ),
384
385
" " ,
385
386
0 ,
386
387
Dict {String,MOI.VariableIndex} (),
388
+ Set {MOI.VariableIndex} (),
387
389
)
388
390
end
389
391
end
@@ -403,6 +405,10 @@ function _get_variable_from_name(model::Model, cache::_ReadCache, name::String)
403
405
end
404
406
x = MOI. add_variable (model)
405
407
MOI. set (model, MOI. VariableName (), x, name)
408
+ # By default, all variables have a lower bound of 0 unless otherwise
409
+ # specified.
410
+ MOI. add_constraint (model, x, MOI. GreaterThan (0.0 ))
411
+ push! (cache. has_default_bound, x)
406
412
cache. name_to_variable[name] = x
407
413
return x
408
414
end
@@ -596,7 +602,9 @@ function _parse_section(
596
602
)
597
603
tokens = _tokenize (line)
598
604
if length (tokens) == 2 && tokens[2 ] == " free"
599
- return # Do nothing. Variable is free
605
+ x = _get_variable_from_name (model, cache, tokens[1 ])
606
+ _delete_default_lower_bound_if_present (model, cache, x)
607
+ return
600
608
end
601
609
lb, ub, name = - Inf , Inf , " "
602
610
if length (tokens) == 5
@@ -629,17 +637,35 @@ function _parse_section(
629
637
end
630
638
x = _get_variable_from_name (model, cache, name)
631
639
if lb == ub
640
+ _delete_default_lower_bound_if_present (model, cache, x)
632
641
MOI. add_constraint (model, x, MOI. EqualTo (lb))
633
642
elseif - Inf < lb < ub < Inf
643
+ _delete_default_lower_bound_if_present (model, cache, x)
634
644
MOI. add_constraint (model, x, MOI. Interval (lb, ub))
635
645
elseif - Inf < lb
646
+ _delete_default_lower_bound_if_present (model, cache, x)
636
647
MOI. add_constraint (model, x, MOI. GreaterThan (lb))
637
648
else
649
+ if ub < 0
650
+ # We only need to delete the default lower bound if the upper bound
651
+ # is less than 0.
652
+ _delete_default_lower_bound_if_present (model, cache, x)
653
+ end
638
654
MOI. add_constraint (model, x, MOI. LessThan (ub))
639
655
end
640
656
return
641
657
end
642
658
659
+ function _delete_default_lower_bound_if_present (model, cache, x)
660
+ if ! (x in cache. has_default_bound)
661
+ return
662
+ end
663
+ c = MOI. ConstraintIndex {MOI.VariableIndex,MOI.GreaterThan{Float64}} (x. value)
664
+ MOI. delete (model, c)
665
+ delete! (cache. has_default_bound, x)
666
+ return
667
+ end
668
+
643
669
# _KW_INTEGER
644
670
645
671
function _parse_section (:: typeof (_KW_INTEGER), model, cache, line)
0 commit comments