@@ -9,57 +9,33 @@ function _range_infeasibility!(
99 variables,
1010 lb_con:: Dict{MOI.VariableIndex,MOI.ConstraintIndex} ,
1111 ub_con:: Dict{MOI.VariableIndex,MOI.ConstraintIndex} ,
12- ) where {T}
12+ :: Type{S} ,
13+ ) where {T,S}
1314 range_consistent = true
14-
15- affine_cons = vcat (
16- MOI. get (
17- optimizer. original_model,
18- MOI. ListOfConstraintIndices{
19- MOI. ScalarAffineFunction{T},
20- MOI. EqualTo{T},
21- }(),
22- ),
23- MOI. get (
24- optimizer. original_model,
25- MOI. ListOfConstraintIndices{
26- MOI. ScalarAffineFunction{T},
27- MOI. LessThan{T},
28- }(),
29- ),
30- MOI. get (
31- optimizer. original_model,
32- MOI. ListOfConstraintIndices{
33- MOI. ScalarAffineFunction{T},
34- MOI. GreaterThan{T},
35- }(),
36- ),
15+ for con in MOI. get (
16+ optimizer. original_model,
17+ MOI. ListOfConstraintIndices{
18+ MOI. ScalarAffineFunction{T},
19+ S,
20+ }(),
3721 )
38-
39- for con in affine_cons
4022 if ! _in_time (optimizer)
4123 return range_consistent
4224 end
4325 func = MOI. get (optimizer. original_model, MOI. ConstraintFunction (), con)
44- failed = false
45- list_of_variables = MOI. VariableIndex[]
46- interval = _eval_variables (func) do var_idx
47- push! (list_of_variables, var_idx)
48- # this only fails if we allow continuing after bounds issues
49- if ! haskey (variables, var_idx)
50- failed = true
51- return Interval (- Inf , Inf )
52- end
53- return variables[var_idx]
54- end
55- if failed
26+ interval = @time _eval_variables (variables, func):: Union{Nothing,Interval{T}}
27+ if isnothing (interval)
5628 continue
5729 end
5830 set = MOI. get (optimizer. original_model, MOI. ConstraintSet (), con)
5931 if _invalid_range (set, interval)
32+ if optimizer. verbose
33+ println (" Found one inconsistent range" )
34+ end
6035 cons = Set {MOI.ConstraintIndex} ()
6136 push! (cons, con)
62- for var in list_of_variables
37+ for t in func. terms
38+ var = t. variable
6339 if haskey (lb_con, var)
6440 push! (cons, lb_con[var])
6541 end
@@ -81,6 +57,20 @@ function _range_infeasibility!(
8157 return range_consistent
8258end
8359
60+ function _range_infeasibility! (
61+ optimizer:: Optimizer ,
62+ :: Type{T} ,
63+ variables,
64+ lb_con:: Dict{MOI.VariableIndex,MOI.ConstraintIndex} ,
65+ ub_con:: Dict{MOI.VariableIndex,MOI.ConstraintIndex} ,
66+ ) where {T}
67+ range_consistent = true
68+ range_consistent &= _range_infeasibility! (optimizer, T, variables, lb_con, ub_con, MOI. EqualTo{T})
69+ range_consistent &= _range_infeasibility! (optimizer, T, variables, lb_con, ub_con, MOI. LessThan{T})
70+ range_consistent &= _range_infeasibility! (optimizer, T, variables, lb_con, ub_con, MOI. GreaterThan{T})
71+ return range_consistent
72+ end
73+
8474function _invalid_range (set:: MOI.EqualTo , interval)
8575 rhs = set. value
8676 return interval. lo > rhs || interval. hi < rhs
@@ -135,20 +125,17 @@ end
135125# This type and the associated function were inspired by JuMP.jl and
136126# MathOptInterface.jl
137127
138- function _eval_variables (value_fn:: Function , t:: MOI.ScalarAffineTerm )
139- return t. coefficient * value_fn (t. variable)
140- end
141-
142128function _eval_variables (
143- value_fn :: Function ,
129+ map :: AbstractDict{MOI.VariableIndex,U} ,
144130 f:: MOI.ScalarAffineFunction{T} ,
145- ) where {T}
146- # TODO : this conversion exists in JuMP, but not in MOI
147- S = Base. promote_op (value_fn, MOI. VariableIndex)
148- U = MOI. MA. promote_operation (* , T, S)
131+ ) where {T,U}
149132 out = convert (U, f. constant)
150- for t in f. terms
151- out += _eval_variables (value_fn, t)
133+ @time for t in f. terms
134+ if haskey (map, t. variable)
135+ out += t. coefficient * map[t. variable]
136+ else
137+ return
138+ end
152139 end
153140 return out
154141end
0 commit comments