@@ -411,6 +411,12 @@ function linear2test(model::MOI.ModelLike, config::TestConfig)
411411 @test MOI. get (model, MOI. ConstraintDual (), vc1) ≈ 0 atol= atol rtol= rtol
412412 @test MOI. get (model, MOI. ConstraintDual (), vc2) ≈ 1 atol= atol rtol= rtol
413413 end
414+
415+ if config. basis
416+ @test MOI. get (model, MOI. ConstraintBasisStatus (), vc1) == MOI. BASIC
417+ @test MOI. get (model, MOI. ConstraintBasisStatus (), vc2) == MOI. NONBASIC
418+ @test MOI. get (model, MOI. ConstraintBasisStatus (), c) == MOI. NONBASIC
419+ end
414420 end
415421end
416422
@@ -436,9 +442,9 @@ function linear3test(model::MOI.ModelLike, config::TestConfig)
436442 x = MOI. add_variable (model)
437443 @test MOI. get (model, MOI. NumberOfVariables ()) == 1
438444
439- MOI. add_constraint (model, MOI. SingleVariable (x), MOI. GreaterThan (0.0 ))
445+ vc = MOI. add_constraint (model, MOI. SingleVariable (x), MOI. GreaterThan (0.0 ))
440446 cf = MOI. ScalarAffineFunction ([MOI. ScalarAffineTerm (1.0 , x)], 0.0 )
441- MOI. add_constraint (model, cf, MOI. GreaterThan (3.0 ))
447+ c = MOI. add_constraint (model, cf, MOI. GreaterThan (3.0 ))
442448
443449 @test MOI. get (model, MOI. NumberOfConstraints {MOI.SingleVariable,MOI.GreaterThan{Float64}} ()) == 1
444450 @test MOI. get (model, MOI. NumberOfConstraints {MOI.ScalarAffineFunction{Float64},MOI.GreaterThan{Float64}} ()) == 1
@@ -459,6 +465,11 @@ function linear3test(model::MOI.ModelLike, config::TestConfig)
459465 @test MOI. get (model, MOI. ObjectiveValue ()) ≈ 3 atol= atol rtol= rtol
460466
461467 @test MOI. get (model, MOI. VariablePrimal (), x) ≈ 3 atol= atol rtol= rtol
468+
469+ if config. basis
470+ @test MOI. get (model, MOI. ConstraintBasisStatus (), vc) == MOI. BASIC
471+ @test MOI. get (model, MOI. ConstraintBasisStatus (), c) == MOI. NONBASIC
472+ end
462473 end
463474
464475 # max x
@@ -471,9 +482,9 @@ function linear3test(model::MOI.ModelLike, config::TestConfig)
471482 x = MOI. add_variable (model)
472483 @test MOI. get (model, MOI. NumberOfVariables ()) == 1
473484
474- MOI. add_constraint (model, MOI. SingleVariable (x), MOI. LessThan (0.0 ))
485+ vc = MOI. add_constraint (model, MOI. SingleVariable (x), MOI. LessThan (0.0 ))
475486 cf = MOI. ScalarAffineFunction ([MOI. ScalarAffineTerm (1.0 , x)], 0.0 )
476- MOI. add_constraint (model, cf, MOI. LessThan (3.0 ))
487+ c = MOI. add_constraint (model, cf, MOI. LessThan (3.0 ))
477488
478489 @test MOI. get (model, MOI. NumberOfConstraints {MOI.SingleVariable,MOI.LessThan{Float64}} ()) == 1
479490 @test MOI. get (model, MOI. NumberOfConstraints {MOI.ScalarAffineFunction{Float64},MOI.LessThan{Float64}} ()) == 1
@@ -496,6 +507,11 @@ function linear3test(model::MOI.ModelLike, config::TestConfig)
496507 @test MOI. get (model, MOI. ObjectiveValue ()) ≈ 0 atol= atol rtol= rtol
497508
498509 @test MOI. get (model, MOI. VariablePrimal (), x) ≈ 0 atol= atol rtol= rtol
510+
511+ if config. basis
512+ @test MOI. get (model, MOI. ConstraintBasisStatus (), vc) == MOI. NONBASIC
513+ @test MOI. get (model, MOI. ConstraintBasisStatus (), c) == MOI. BASIC
514+ end
499515 end
500516end
501517
@@ -1050,17 +1066,17 @@ function linear9test(model::MOI.ModelLike, config::TestConfig)
10501066 x = MOI. add_variable (model)
10511067 y = MOI. add_variable (model)
10521068
1053- MOI. add_constraints (model,
1069+ vc12 = MOI. add_constraints (model,
10541070 [MOI. SingleVariable (x), MOI. SingleVariable (y)],
10551071 [MOI. GreaterThan (30.0 ), MOI. GreaterThan (0.0 )]
10561072 )
10571073
1058- MOI. add_constraints (model,
1074+ c1 = MOI. add_constraints (model,
10591075 [MOI. ScalarAffineFunction (MOI. ScalarAffineTerm .([1.0 , - 1.5 ], [x, y]), 0.0 )],
10601076 [MOI. GreaterThan (0.0 )]
10611077 )
10621078
1063- MOI. add_constraints (model,
1079+ c23 = MOI. add_constraints (model,
10641080 [
10651081 MOI. ScalarAffineFunction (MOI. ScalarAffineTerm .([12.0 , 8.0 ], [x, y]), 0.0 ),
10661082 MOI. ScalarAffineFunction (MOI. ScalarAffineTerm .([1_000.0 , 300.0 ], [x, y]), 0.0 )
@@ -1086,6 +1102,14 @@ function linear9test(model::MOI.ModelLike, config::TestConfig)
10861102 @test MOI. get (model, MOI. ObjectiveValue ()) ≈ 79e4 / 11 atol= atol rtol= rtol
10871103 @test MOI. get (model, MOI. VariablePrimal (), x) ≈ 650 / 11 atol= atol rtol= rtol
10881104 @test MOI. get (model, MOI. VariablePrimal (), y) ≈ 400 / 11 atol= atol rtol= rtol
1105+
1106+ if config. basis
1107+ @test MOI. get (model, MOI. ConstraintBasisStatus (), vc12[1 ]) == MOI. BASIC
1108+ @test MOI. get (model, MOI. ConstraintBasisStatus (), vc12[2 ]) == MOI. BASIC
1109+ @test MOI. get (model, MOI. ConstraintBasisStatus (), c1[1 ]) == MOI. BASIC
1110+ @test MOI. get (model, MOI. ConstraintBasisStatus (), c23[1 ]) == MOI. NONBASIC
1111+ @test MOI. get (model, MOI. ConstraintBasisStatus (), c23[2 ]) == MOI. NONBASIC
1112+ end
10891113 end
10901114end
10911115
@@ -1110,7 +1134,7 @@ function linear10test(model::MOI.ModelLike, config::TestConfig)
11101134 x = MOI. add_variable (model)
11111135 y = MOI. add_variable (model)
11121136
1113- MOI. add_constraints (model,
1137+ vc = MOI. add_constraints (model,
11141138 [MOI. SingleVariable (x), MOI. SingleVariable (y)],
11151139 [MOI. GreaterThan (0.0 ), MOI. GreaterThan (0.0 )]
11161140 )
@@ -1135,6 +1159,13 @@ function linear10test(model::MOI.ModelLike, config::TestConfig)
11351159 @test MOI. get (model, MOI. DualStatus ()) == MOI. FEASIBLE_POINT
11361160 @test MOI. get (model, MOI. ConstraintDual (), c) ≈ - 1 atol= atol rtol= rtol
11371161 end
1162+
1163+ if config. basis
1164+ # There are multiple optimal bases. Either x or y can be in the optimal basis.
1165+ @test (MOI. get (model, MOI. ConstraintBasisStatus (), vc[1 ]) == MOI. BASIC ||
1166+ MOI. get (model, MOI. ConstraintBasisStatus (), vc[2 ])== MOI. BASIC)
1167+ @test MOI. get (model, MOI. ConstraintBasisStatus (), c) == MOI. NONBASIC_AT_UPPER
1168+ end
11381169 end
11391170
11401171 MOI. set (model, MOI. ObjectiveFunction {MOI.ScalarAffineFunction{Float64}} (), MOI. ScalarAffineFunction (MOI. ScalarAffineTerm .([1.0 , 1.0 ], [x, y]), 0.0 ))
@@ -1153,6 +1184,13 @@ function linear10test(model::MOI.ModelLike, config::TestConfig)
11531184 @test MOI. get (model, MOI. DualStatus ()) == MOI. FEASIBLE_POINT
11541185 @test MOI. get (model, MOI. ConstraintDual (), c) ≈ 1 atol= atol rtol= rtol
11551186 end
1187+
1188+ if config. basis
1189+ # There are multiple optimal bases. Either x or y can be in the optimal basis."
1190+ @test (MOI. get (model, MOI. ConstraintBasisStatus (), vc[1 ]) == MOI. BASIC ||
1191+ MOI. get (model, MOI. ConstraintBasisStatus (), vc[2 ])== MOI. BASIC)
1192+ @test MOI. get (model, MOI. ConstraintBasisStatus (), c) == MOI. NONBASIC_AT_LOWER
1193+ end
11561194 end
11571195
11581196 MOI. set (model, MOI. ConstraintSet (), c, MOI. Interval (2.0 , 12.0 ))
@@ -1168,6 +1206,13 @@ function linear10test(model::MOI.ModelLike, config::TestConfig)
11681206 @test MOI. get (model, MOI. PrimalStatus ()) == MOI. FEASIBLE_POINT
11691207 @test MOI. get (model, MOI. ObjectiveValue ()) ≈ 2.0 atol= atol rtol= rtol
11701208 @test MOI. get (model, MOI. ConstraintPrimal (), c) ≈ 2 atol= atol rtol= rtol
1209+
1210+ if config. basis
1211+ # There are multiple optimal bases. Either x or y can be in the optimal basis.
1212+ @test (MOI. get (model, MOI. ConstraintBasisStatus (), vc[1 ]) == MOI. BASIC ||
1213+ MOI. get (model, MOI. ConstraintBasisStatus (), vc[2 ])== MOI. BASIC)
1214+ @test MOI. get (model, MOI. ConstraintBasisStatus (), c) == MOI. NONBASIC_AT_LOWER
1215+ end
11711216 end
11721217
11731218 MOI. set (model, MOI. ObjectiveFunction {MOI.ScalarAffineFunction{Float64}} (), MOI. ScalarAffineFunction (MOI. ScalarAffineTerm .([1.0 , 1.0 ], [x, y]), 0.0 ))
@@ -1180,6 +1225,70 @@ function linear10test(model::MOI.ModelLike, config::TestConfig)
11801225 @test MOI. get (model, MOI. PrimalStatus ()) == MOI. FEASIBLE_POINT
11811226 @test MOI. get (model, MOI. ObjectiveValue ()) ≈ 12.0 atol= atol rtol= rtol
11821227 @test MOI. get (model, MOI. ConstraintPrimal (), c) ≈ 12 atol= atol rtol= rtol
1228+
1229+ if config. basis
1230+ # There are multiple optimal bases. Either x or y can be in the optimal basis.
1231+ @test (MOI. get (model, MOI. ConstraintBasisStatus (), vc[1 ]) == MOI. BASIC ||
1232+ MOI. get (model, MOI. ConstraintBasisStatus (), vc[2 ])== MOI. BASIC)
1233+ @test MOI. get (model, MOI. ConstraintBasisStatus (), c) == MOI. NONBASIC_AT_UPPER
1234+ end
1235+ end
1236+ end
1237+
1238+ # inactive ranged constraints
1239+ function linear10btest (model:: MOI.ModelLike , config:: TestConfig )
1240+ atol = config. atol
1241+ rtol = config. rtol
1242+ # minimize x + y
1243+ #
1244+ # s.t. -1 <= x + y <= 10
1245+ # x, y >= 0
1246+
1247+ @test MOIU. supports_default_copy_to (model, #= copy_names=# false )
1248+ @test MOI. supports (model, MOI. ObjectiveFunction {MOI.ScalarAffineFunction{Float64}} ())
1249+ @test MOI. supports (model, MOI. ObjectiveSense ())
1250+ @test MOI. supports_constraint (model, MOI. ScalarAffineFunction{Float64}, MOI. Interval{Float64})
1251+ @test MOI. supports_constraint (model, MOI. SingleVariable, MOI. GreaterThan{Float64})
1252+
1253+ MOI. empty! (model)
1254+ @test MOI. is_empty (model)
1255+
1256+ x = MOI. add_variable (model)
1257+ y = MOI. add_variable (model)
1258+
1259+ vc = MOI. add_constraints (model,
1260+ [MOI. SingleVariable (x), MOI. SingleVariable (y)],
1261+ [MOI. GreaterThan (0.0 ), MOI. GreaterThan (0.0 )]
1262+ )
1263+
1264+ c = MOI. add_constraint (model, MOI. ScalarAffineFunction (MOI. ScalarAffineTerm .([1.0 , 1.0 ], [x,y]), 0.0 ), MOI. Interval (- 1.0 , 10.0 ))
1265+
1266+ MOI. set (model, MOI. ObjectiveFunction {MOI.ScalarAffineFunction{Float64}} (), MOI. ScalarAffineFunction (MOI. ScalarAffineTerm .([1.0 , 1.0 ], [x, y]), 0.0 ))
1267+ MOI. set (model, MOI. ObjectiveSense (), MOI. MIN_SENSE)
1268+
1269+ if config. solve
1270+ @test MOI. get (model, MOI. TerminationStatus ()) == MOI. OPTIMIZE_NOT_CALLED
1271+
1272+ MOI. optimize! (model)
1273+
1274+ @test MOI. get (model, MOI. TerminationStatus ()) == config. optimal_status
1275+ @test MOI. get (model, MOI. PrimalStatus ()) == MOI. FEASIBLE_POINT
1276+ @test MOI. get (model, MOI. ObjectiveValue ()) ≈ 0.0 atol= atol rtol= rtol
1277+ @test MOI. get (model, MOI. ConstraintPrimal (), c) ≈ 0.0 atol= atol rtol= rtol
1278+
1279+ if config. duals
1280+ @test MOI. get (model, MOI. ResultCount ()) >= 1
1281+ @test MOI. get (model, MOI. DualStatus ()) == MOI. FEASIBLE_POINT
1282+ @test MOI. get (model, MOI. ConstraintDual (), c) ≈ 0.0 atol= atol rtol= rtol
1283+ @test MOI. get (model, MOI. ConstraintDual (), vc[1 ]) ≈ 1.0 atol= atol rtol= rtol
1284+ @test MOI. get (model, MOI. ConstraintDual (), vc[2 ]) ≈ 1.0 atol= atol rtol= rtol
1285+ end
1286+
1287+ if config. basis
1288+ @test (MOI. get (model, MOI. ConstraintBasisStatus (), vc[1 ]) == MOI. NONBASIC)
1289+ @test (MOI. get (model, MOI. ConstraintBasisStatus (), vc[1 ]) == MOI. NONBASIC)
1290+ @test MOI. get (model, MOI. ConstraintBasisStatus (), c) == MOI. BASIC
1291+ end
11831292 end
11841293end
11851294
@@ -1427,6 +1536,14 @@ function linear14test(model::MOI.ModelLike, config::TestConfig)
14271536 @test MOI. get (model, MOI. ConstraintDual (), clby) ≈ 0 atol= atol rtol= rtol
14281537 @test MOI. get (model, MOI. ConstraintDual (), clbz) ≈ 0 atol= atol rtol= rtol
14291538 @test MOI. get (model, MOI. ConstraintDual (), cubz) ≈ - 2 atol= atol rtol= rtol
1539+
1540+ if config. basis
1541+ @test MOI. get (model, MOI. ConstraintBasisStatus (), clbx) == MOI. NONBASIC
1542+ @test MOI. get (model, MOI. ConstraintBasisStatus (), clby) == MOI. BASIC
1543+ @test MOI. get (model, MOI. ConstraintBasisStatus (), clbz) == MOI. BASIC
1544+ @test MOI. get (model, MOI. ConstraintBasisStatus (), cubz) == MOI. NONBASIC
1545+ @test MOI. get (model, MOI. ConstraintBasisStatus (), c) == MOI. NONBASIC
1546+ end
14301547 end
14311548 end
14321549
@@ -1551,6 +1668,7 @@ const contlineartests = Dict("linear1" => linear1test,
15511668 " linear8c" => linear8ctest,
15521669 " linear9" => linear9test,
15531670 " linear10" => linear10test,
1671+ " linear10b" => linear10btest,
15541672 " linear11" => linear11test,
15551673 " linear12" => linear12test,
15561674 " linear13" => linear13test,
0 commit comments