@@ -41,8 +41,8 @@ mutable struct ConstraintInfo
4141end 
4242
4343#  Dummy callback function for internal use only. Responsible for updating the
44- #  objective bound and  saving the mip gap.
45- function  __internal_callback__ (tree:: Ptr{Cvoid} , info:: Ptr{Cvoid} )
44+ #  objective bound,  saving the mip gap, and calling the user's callback .
45+ function  _internal_callback (tree:: Ptr{Cvoid} , info:: Ptr{Cvoid} )
4646    callback_data =  unsafe_pointer_to_objref (info):: CallbackData 
4747    model =  callback_data. model
4848    callback_data. tree =  tree
@@ -115,11 +115,6 @@ mutable struct Optimizer <: MOI.ModelLike
115115    See the GLPK pdf documentation for a full list of parameters. 
116116    """  
117117    function  Optimizer (; presolve =  false , method =  SIMPLEX, kwargs... )
118-         #  GLPK.jl has a lot of pre-emptive checks to catch cases where the C API
119-         #  might throw an uninformative error. However, in benchmarks, this takes
120-         #  a non-negligible amount of time (e.g. 20% in add_constraints). Until
121-         #  someone complains otherwise, we're going to disable these checks
122-         GLPK. jl_set_preemptive_check (false )
123118        model =  new ()
124119        model. presolve =  presolve
125120        model. method =  method
@@ -135,10 +130,10 @@ mutable struct Optimizer <: MOI.ModelLike
135130        model. intopt_param =  GLPK. IntoptParam ()
136131        model. simplex_param =  GLPK. SimplexParam ()
137132
138-         #  We initialize a default callback (__internal_callback__ ) to manage the
139-         #  user's callback, and to update the objective bound.
133+         #  We initialize a default callback (_internal_callback ) to manage the
134+         #  user's callback, and to update the objective bound and MIP gap .
140135        model. callback_data =  CallbackData (model)
141-         model. intopt_param. cb_func =  @cfunction (__internal_callback__ , Cvoid, (Ptr{Cvoid}, Ptr{Cvoid}))
136+         model. intopt_param. cb_func =  @cfunction (_internal_callback , Cvoid, (Ptr{Cvoid}, Ptr{Cvoid}))
142137        model. intopt_param. cb_info =  pointer_from_objref (model. callback_data)
143138        model. callback_function =  (cb_data) ->  nothing 
144139
@@ -286,21 +281,28 @@ MOI.supports(::Optimizer, ::MOI.RawStatusString) = true
286281MOI. supports (:: Optimizer , :: MOI.RawParameter ) =  true 
287282
288283function  MOI. set (model:: Optimizer , param:: MOI.RawParameter , value)
289-     model. params[param. name] =  value
290-     set_parameter (model, param. name, value)
284+     if  typeof (param. name) !=  String
285+         error (" GLPK.jl requires strings as arguments to `RawParameter`." 
286+     end 
287+     model. params[Symbol (param. name)] =  value
288+     set_parameter (model, Symbol (param. name), value)
291289    return 
292290end 
293291
294292function  MOI. get (model:: Optimizer , param:: MOI.RawParameter )
295-     if  (model. method ==  SIMPLEX ||  model. method ==  EXACT) &&  param. name in  fieldnames (GLPK. SimplexParam)
296-         return  getfield (model. simplex_param, param. name)
297-     elseif  model. method ==  INTERIOR &&  param. name in  fieldnames (GLPK. InteriorParam)
298-         return  getfield (model. interior_param, param. name)
293+     if  typeof (param. name) !=  String
294+         error (" GLPK.jl requires strings as arguments to `RawParameter`." 
295+     end 
296+     name =  Symbol (param. name)
297+     if  (model. method ==  SIMPLEX ||  model. method ==  EXACT) &&  name in  fieldnames (GLPK. SimplexParam)
298+         return  getfield (model. simplex_param, name)
299+     elseif  model. method ==  INTERIOR &&  name in  fieldnames (GLPK. InteriorParam)
300+         return  getfield (model. interior_param, name)
299301    end 
300-     if  param . name in  fieldnames (GLPK. IntoptParam)
301-         return  getfield (model. intopt_param, param . name)
302+     if  name in  fieldnames (GLPK. IntoptParam)
303+         return  getfield (model. intopt_param, name)
302304    end 
303-     error (" Unable to get RawParameter. Invalid name: $(param . name) " 
305+     error (" Unable to get RawParameter. Invalid name: $(name) " 
304306end 
305307
306308MOI. Utilities. supports_default_copy_to (:: Optimizer , :: Bool ) =  true 
432434function  _rebuild_name_to_variable (model:: Optimizer )
433435    model. name_to_variable =  Dict {String, MOI.VariableIndex} ()
434436    for  (index, info) in  model. variable_info
435-         if  info. name  ==   " " 
437+         if  isempty ( info. name) 
436438            continue 
437439        end 
438440        if  haskey (model. name_to_variable, info. name)
@@ -719,7 +721,17 @@ function _set_variable_bound(
719721    else 
720722        upper >=  GLPK. DBL_MAX ?  GLPK. LO :  GLPK. DB
721723    end 
722-     GLPK. set_col_bnds (model. inner, column, bound_type, lower, upper)
724+     if  upper <  lower
725+         #  Here, we disable GLPK's pre-emptive checks, because otherwise GLPK
726+         #  will through an error complaining about invalid bounds when `upper <
727+         #  lower`. This let's us throw `INFEASIBLE` instead of erroring.
728+         prev_preemptive =  GLPK. jl_get_preemptive_check ()
729+         GLPK. jl_set_preemptive_check (false )
730+         GLPK. set_col_bnds (model. inner, column, bound_type, lower, upper)
731+         GLPK. jl_set_preemptive_check (prev_preemptive)
732+     else 
733+         GLPK. set_col_bnds (model. inner, column, bound_type, lower, upper)
734+     end 
723735    return 
724736end 
725737
@@ -834,7 +846,7 @@ function MOI.add_constraint(
834846    info =  _info (model, f. variable)
835847    #  See https://github.com/JuliaOpt/GLPKMathProgInterface.jl/pull/15
836848    #  for why this is necesary. GLPK interacts weirdly with binary variables and
837-     #  bound modification. So lets  set binary variables as "Integer" with [0,1]
849+     #  bound modification. So let's  set binary variables as "Integer" with [0,1]
838850    #  bounds that we enforce just before solve.
839851    GLPK. set_col_kind (model. inner, info. column, GLPK. IV)
840852    info. type =  BINARY
@@ -1137,7 +1149,7 @@ function MOI.get(
11371149        elseif  info. type in  _type_enums (S)
11381150            constraint_name =  info. type_constraint_name
11391151        end 
1140-         if  constraint_name  ==   " " 
1152+         if  isempty ( constraint_name) 
11411153            continue 
11421154        elseif  constraint_name ==  name
11431155            if  index ===  nothing 
@@ -1173,7 +1185,7 @@ end
11731185
11741186function  _rebuild_name_to_constraint_index_util (model:: Optimizer , dict, F)
11751187    for  (index, info) in  dict
1176-         info. name  ==   " " &&  continue 
1188+         isempty ( info. name)  &&  continue 
11771189        if  haskey (model. name_to_constraint_index, info. name)
11781190            model. name_to_constraint_index =  nothing 
11791191            error (" Duplicate variable name detected: $(info. name) " 
0 commit comments