@@ -46,6 +46,37 @@ function JuMP.build_variable(
46
46
return _TaggedLogicalVariable (lvar, tag. tag_data)
47
47
end
48
48
49
+ # Helper functions to extract the core variable object
50
+ _get_variable (v:: _TaggedLogicalVariable ) = v. variable
51
+ _get_variable (v) = v
52
+
53
+ # Helper function to add start value and fix value
54
+ function _add_logical_info (bvref, var:: LogicalVariable )
55
+ if ! isnothing (var. fix_value)
56
+ JuMP. fix (bvref, var. fix_value)
57
+ end
58
+ if ! isnothing (var. start_value)
59
+ JuMP. set_start_value (bvref, var. start_value)
60
+ end
61
+ return
62
+ end
63
+ function _add_logical_info (bvref, var:: _TaggedLogicalVariable )
64
+ return _add_logical_info (bvref, var. variable)
65
+ end
66
+
67
+ # Dispatch on logical variable type to create a binary variable
68
+ function _make_binary_variable (model, :: LogicalVariable , name)
69
+ return JuMP. @variable (model, base_name = name, binary = true )
70
+ end
71
+ function _make_binary_variable (model, var:: _TaggedLogicalVariable , name)
72
+ return JuMP. @variable (
73
+ model,
74
+ base_name = name,
75
+ binary = true ,
76
+ variable_type = var. tag_data
77
+ )
78
+ end
79
+
49
80
"""
50
81
JuMP.add_variable(model::Model, v::LogicalVariable,
51
82
name::String = "")::LogicalVariableRef
@@ -59,10 +90,16 @@ function JuMP.add_variable(
59
90
name:: String = " "
60
91
)
61
92
is_gdp_model (model) || error (" Can only add logical variables to `GDPModel`s." )
62
- data = LogicalVariableData (v, name)
93
+ # add the logical variable
94
+ data = LogicalVariableData (_get_variable (v), name)
63
95
idx = _MOIUC. add_item (_logical_variables (model), data)
96
+ lvref = LogicalVariableRef (model, idx)
64
97
_set_ready_to_optimize (model, false )
65
- return LogicalVariableRef (model, idx)
98
+ # add the assocviated binary variables
99
+ bvref = _make_binary_variable (model, v, name)
100
+ _add_logical_info (bvref, v)
101
+ _indicator_to_binary (model)[lvref] = bvref
102
+ return lvref
66
103
end
67
104
68
105
# Base extensions
77
114
# end
78
115
79
116
# Define helpful getting functions
80
- function _variable_object (data:: LogicalVariableData{<:_TaggedLogicalVariable} )
81
- return data. variable. variable
82
- end
83
- function _variable_object (data:: LogicalVariableData )
84
- return data. variable
85
- end
86
117
function _variable_object (lvref:: LogicalVariableRef )
87
118
dict = _logical_variables (JuMP. owner_model (lvref))
88
- return _variable_object ( dict[JuMP. index (lvref)])
119
+ return dict[JuMP. index (lvref)]. variable
89
120
end
90
121
91
122
# Define helpful setting functions
92
- function _set_variable_object (data:: LogicalVariableData{<:_TaggedLogicalVariable} , var)
93
- tag = data. variable. tag_data
94
- data. variable = _TaggedLogicalVariable (var, tag)
95
- return
96
- end
97
- function _set_variable_object (data:: LogicalVariableData , var)
98
- data. variable = var
99
- return
100
- end
101
123
function _set_variable_object (lvref:: LogicalVariableRef , var:: LogicalVariable )
102
124
model = JuMP. owner_model (lvref)
103
- dict = _logical_variables (model)
104
- _set_variable_object (dict[JuMP. index (lvref)], var)
125
+ _logical_variables (model)[JuMP. index (lvref)]. variable = var
105
126
_set_ready_to_optimize (model, false )
106
127
return
107
128
end
@@ -158,6 +179,7 @@ function JuMP.set_name(vref::LogicalVariableRef, name::String)
158
179
data = gdp_data (model)
159
180
data. logical_variables[index (vref)]. name = name
160
181
_set_ready_to_optimize (model, false )
182
+ JuMP. set_name (binary_variable (vref), name)
161
183
return
162
184
end
163
185
@@ -183,6 +205,7 @@ function JuMP.set_start_value(
183
205
)
184
206
new_var = LogicalVariable (JuMP. fix_value (vref), value)
185
207
_set_variable_object (vref, new_var)
208
+ JuMP. set_start_value (binary_variable (vref), value)
186
209
return
187
210
end
188
211
"""
@@ -215,6 +238,7 @@ new one.
215
238
function JuMP. fix (vref:: LogicalVariableRef , value:: Bool )
216
239
new_var = LogicalVariable (value, JuMP. start_value (vref))
217
240
_set_variable_object (vref, new_var)
241
+ JuMP. fix (binary_variable (vref), value)
218
242
return
219
243
end
220
244
@@ -226,9 +250,22 @@ Delete the fixed value of a logical variable.
226
250
function JuMP. unfix (vref:: LogicalVariableRef )
227
251
new_var = LogicalVariable (nothing , JuMP. start_value (vref))
228
252
_set_variable_object (vref, new_var)
253
+ JuMP. unfix (binary_variable (vref))
229
254
return
230
255
end
231
256
257
+ """
258
+ binary_variable(vref::LogicalVariableRef)::JuMP.AbstractVariableRef
259
+
260
+ Returns the underlying binary variable for the logical variable `vref` which
261
+ is used in the reformulated model. This is helpful to embed logical variables
262
+ in algebraic constraints.
263
+ """
264
+ function binary_variable (vref:: LogicalVariableRef )
265
+ model = JuMP. owner_model (vref)
266
+ return _indicator_to_binary (model)[vref]
267
+ end
268
+
232
269
"""
233
270
JuMP.delete(model::JuMP.AbstractModel, vref::LogicalVariableRef)::Nothing
234
271
@@ -241,24 +278,25 @@ function JuMP.delete(model::JuMP.AbstractModel, vref::LogicalVariableRef)
241
278
# delete any disjunct constraints associated with the logical variables in the disjunction
242
279
if haskey (_indicator_to_constraints (model), vref)
243
280
crefs = _indicator_to_constraints (model)[vref]
244
- delete .(model, crefs)
281
+ JuMP . delete .(model, crefs)
245
282
delete! (_indicator_to_constraints (model), vref)
246
283
end
247
284
# delete any disjunctions that have the logical variable
248
285
for (didx, ddata) in _disjunctions (model)
249
286
if vref in ddata. constraint. indicators
250
- delete (model, DisjunctionRef (model, didx))
287
+ JuMP . delete (model, DisjunctionRef (model, didx))
251
288
end
252
289
end
253
290
# delete any logical constraints involving the logical variables
254
291
for (cidx, cdata) in _logical_constraints (model)
255
292
lvars = _get_logical_constraint_variables (model, cdata. constraint)
256
293
if vref in lvars
257
- delete (model, LogicalConstraintRef (model, cidx))
294
+ JuMP . delete (model, LogicalConstraintRef (model, cidx))
258
295
end
259
296
end
260
297
# delete the logical variable
261
298
delete! (dict, vidx)
299
+ JuMP. delete (model, binary_variable (vref))
262
300
delete! (_indicator_to_binary (model), vref)
263
301
# not ready to optimize
264
302
_set_ready_to_optimize (model, false )
0 commit comments