@@ -267,6 +267,21 @@ function pass_constraints(
267
267
end
268
268
end
269
269
270
+ function copy_free_variables (dest:: MOI.ModelLike , idxmap:: IndexMap , vis_src, copy_variables:: Function )
271
+ if length (vis_src) != length (keys (idxmap. varmap))
272
+ vars = copy_variables (dest, length (vis_src) - length (idxmap. varmap))
273
+ i = 1
274
+ for vi in vis_src
275
+ if ! haskey (idxmap. varmap, vi)
276
+ idxmap. varmap[vi] = vars[i]
277
+ i += 1
278
+ end
279
+ end
280
+ @assert i == length (vars) + 1
281
+ @assert length (vis_src) == length (idxmap. varmap)
282
+ end
283
+ end
284
+
270
285
function default_copy_to (dest:: MOI.ModelLike , src:: MOI.ModelLike )
271
286
Base. depwarn (" default_copy_to(dest, src) is deprecated, use default_copy_to(dest, src, true) instead or default_copy_to(dest, src, false) if you do not want to copy names." , :default_copy_to )
272
287
default_copy_to (dest, src, true )
@@ -292,24 +307,29 @@ function default_copy_to(dest::MOI.ModelLike, src::MOI.ModelLike, copy_names::Bo
292
307
vector_of_variables_types = [S for (F, S) in constraint_types
293
308
if F == MOI. VectorOfVariables]
294
309
295
- vector_of_variables_not_added = [
296
- copy_vector_of_variables (dest, src, idxmap, S)
297
- for S in vector_of_variables_types
298
- ]
299
- single_variable_not_added = [
300
- copy_single_variable (dest, src, idxmap, S)
301
- for S in single_variable_types
302
- ]
303
-
304
- if length (vis_src) != length (keys (idxmap. varmap))
305
- # Copy free variables
306
- variables_not_added = setdiff (Set (vis_src), keys (idxmap. varmap))
307
- vars = MOI. add_variables (dest, length (variables_not_added))
308
- for (vi, var) in zip (variables_not_added, vars)
309
- idxmap. varmap[vi] = var
310
- end
310
+ # The `NLPBlock` assumes that the order of variables does not change (#849)
311
+ if MOI. NLPBlock () in MOI. get (src, MOI. ListOfModelAttributesSet ())
312
+ vector_of_variables_not_added = [
313
+ MOI. get (src, MOI. ListOfConstraintIndices {MOI.VectorOfVariables, S} ())
314
+ for S in vector_of_variables_types
315
+ ]
316
+ single_variable_not_added = [
317
+ MOI. get (src, MOI. ListOfConstraintIndices {MOI.SingleVariable, S} ())
318
+ for S in single_variable_types
319
+ ]
320
+ else
321
+ vector_of_variables_not_added = [
322
+ copy_vector_of_variables (dest, src, idxmap, S)
323
+ for S in vector_of_variables_types
324
+ ]
325
+ single_variable_not_added = [
326
+ copy_single_variable (dest, src, idxmap, S)
327
+ for S in single_variable_types
328
+ ]
311
329
end
312
330
331
+ copy_free_variables (dest, idxmap, vis_src, MOI. add_variables)
332
+
313
333
# Copy variable attributes
314
334
pass_attributes (dest, src, copy_names, idxmap, vis_src)
315
335
@@ -652,14 +672,7 @@ function allocate_load(dest::MOI.ModelLike, src::MOI.ModelLike, copy_names::Bool
652
672
allocate_single_variable (dest, src, idxmap, S)
653
673
end
654
674
655
- if length (vis_src) != length (keys (idxmap. varmap))
656
- # Allocate free variables
657
- variables_not_added = setdiff (Set (vis_src), keys (idxmap. varmap))
658
- vars = allocate_variables (dest, length (variables_not_added))
659
- for (vi, var) in zip (variables_not_added, vars)
660
- idxmap. varmap[vi] = var
661
- end
662
- end
675
+ copy_free_variables (dest, idxmap, vis_src, allocate_variables)
663
676
664
677
# Allocate variable attributes
665
678
pass_attributes (dest, src, copy_names, idxmap, vis_src, allocate)
0 commit comments