@@ -323,7 +323,6 @@ namespace lp {
323
323
int_solver& lia;
324
324
lar_solver& lra;
325
325
explanation m_infeas_explanation;
326
- indexed_vector<mpq> m_indexed_work_vector;
327
326
bool m_report_branch = false ;
328
327
329
328
// set F
@@ -345,6 +344,32 @@ namespace lp {
345
344
}
346
345
return r;
347
346
}
347
+
348
+ bool has (unsigned k) const {
349
+ return k < m_index.size () && m_index[k] >= 0 ;
350
+ }
351
+
352
+ const mpq& operator [](unsigned j) const {
353
+ SASSERT (j >= 0 && j < m_index.size ());
354
+ SASSERT (m_index[j] >= 0 && m_index[j] < m_data.size ());
355
+ return m_data[m_index[j]].coeff ();
356
+ }
357
+
358
+ void erase (unsigned k) {
359
+ if (k >= m_index.size () || m_index[k] == -1 )
360
+ return ;
361
+
362
+ unsigned idx = m_index[k];
363
+ // If not last element, move last element to idx position
364
+ if (idx != m_data.size () - 1 ) {
365
+ m_data[idx] = m_data.back ();
366
+ m_index[m_data[idx].var ()] = idx;
367
+ }
368
+
369
+ m_data.pop_back ();
370
+ m_index[k] = -1 ;
371
+ SASSERT (invariant ());
372
+ }
348
373
void add (const mpq& a, unsigned j) {
349
374
SASSERT (!a.is_zero ());
350
375
// Expand m_index if needed
@@ -426,7 +451,8 @@ namespace lp {
426
451
427
452
};
428
453
429
- term_with_index m_term_with_index;
454
+ term_with_index m_l_terms_workspace;
455
+ term_with_index m_substitution_workspace;
430
456
431
457
bijection m_k2s;
432
458
bij_map<lar_term> m_fresh_k2xt_terms;
@@ -881,7 +907,7 @@ namespace lp {
881
907
open_l_term_to_work_vector (ei, c);
882
908
clear_e_row (ei);
883
909
mpq denom (1 );
884
- for (const auto & p: m_indexed_work_vector ) {
910
+ for (const auto & p: m_substitution_workspace. m_data ) {
885
911
unsigned lj = add_var (p.var ());
886
912
m_e_matrix.add_columns_up_to (lj);
887
913
m_e_matrix.add_new_element (ei, lj, p.coeff ());
@@ -1189,31 +1215,30 @@ namespace lp {
1189
1215
print_term_o (create_term_from_ind_c (), tout) << std::endl;
1190
1216
tout << " subs with e:" ;
1191
1217
print_lar_term_L (e, tout) << std::endl;);
1192
- mpq coeff = - m_indexed_work_vector [k]; // need to copy since it will be zeroed
1193
- m_indexed_work_vector .erase (k); // m_indexed_work_vector [k] = 0;
1218
+ mpq coeff = - m_substitution_workspace [k]; // need to copy since it will be zeroed
1219
+ m_substitution_workspace .erase (k); // m_work_vector_1 [k] = 0;
1194
1220
1195
1221
SASSERT (e.get_coeff (k).is_one ());
1196
1222
1197
1223
for (const auto & p : e) {
1198
1224
unsigned j = p.var ();
1199
1225
if (j == k)
1200
1226
continue ;
1201
- m_indexed_work_vector. add_value_at_index (j, p.coeff ()*coeff);
1227
+ m_substitution_workspace. add ( p.coeff ()*coeff, j );
1202
1228
// do we need to add j to the queue?
1203
- if (!var_is_fresh (j) && !m_indexed_work_vector[j].is_zero () &&
1204
- can_substitute (j))
1229
+ if (!var_is_fresh (j) && m_substitution_workspace.has (j) && can_substitute (j))
1205
1230
q.push (j);
1206
1231
}
1207
1232
// there is no change in m_l_matrix
1208
1233
TRACE (" dioph_eq" , tout << " after subs k:" << k << " \n " ;
1209
1234
print_term_o (create_term_from_ind_c (), tout) << std::endl;
1210
- tout << " m_term_with_index:{" ; print_lar_term_L (m_term_with_index .m_data , tout);
1211
- tout << " }, opened:" ; print_ml (m_term_with_index .to_term (), tout) << std::endl;);
1235
+ tout << " m_term_with_index:{" ; print_lar_term_L (m_l_terms_workspace .m_data , tout);
1236
+ tout << " }, opened:" ; print_ml (m_l_terms_workspace .to_term (), tout) << std::endl;);
1212
1237
}
1213
1238
1214
1239
void add_l_row_to_term_with_index (const mpq& coeff, unsigned ei) {
1215
1240
for (const auto & p: m_l_matrix.m_rows [ei]) {
1216
- m_term_with_index .add (coeff * p.coeff (), p.var ());
1241
+ m_l_terms_workspace .add (coeff * p.coeff (), p.var ());
1217
1242
}
1218
1243
}
1219
1244
@@ -1223,8 +1248,8 @@ namespace lp {
1223
1248
print_term_o (create_term_from_ind_c (), tout) << std::endl;
1224
1249
tout << " subs with e:" ;
1225
1250
print_entry (m_k2s[k], tout) << std::endl;);
1226
- mpq coeff = m_indexed_work_vector [k]; // need to copy since it will be zeroed
1227
- m_indexed_work_vector .erase (k); // m_indexed_work_vector [k] = 0;
1251
+ mpq coeff = m_substitution_workspace [k]; // need to copy since it will be zeroed
1252
+ m_substitution_workspace .erase (k); // m_work_vector_1 [k] = 0;
1228
1253
1229
1254
const auto & e_row = m_e_matrix.m_rows [m_k2s[k]];
1230
1255
auto it = std::find_if (e_row.begin (), e_row.end (),
@@ -1241,18 +1266,18 @@ namespace lp {
1241
1266
unsigned j = p.var ();
1242
1267
if (j == k)
1243
1268
continue ;
1244
- m_indexed_work_vector. add_value_at_index (j, p.coeff () * coeff);
1269
+ m_substitution_workspace. add ( p.coeff () * coeff, j );
1245
1270
// do we need to add j to the queue?
1246
- if (!var_is_fresh (j) && !m_indexed_work_vector[j]. is_zero ( ) &&
1271
+ if (!var_is_fresh (j) && m_substitution_workspace. has (j ) &&
1247
1272
can_substitute (j))
1248
1273
q.push (j);
1249
1274
}
1250
1275
m_c += coeff * e;
1251
1276
add_l_row_to_term_with_index (coeff, sub_index (k));
1252
1277
TRACE (" dioph_eq" , tout << " after subs k:" << k << " \n " ;
1253
1278
print_term_o (create_term_from_ind_c (), tout) << std::endl;
1254
- tout << " m_term_with_index:{" ; print_lar_term_L (m_term_with_index .to_term (), tout);
1255
- tout << " }, opened:" ; print_ml (m_term_with_index .to_term (), tout) << std::endl;);
1279
+ tout << " m_term_with_index:{" ; print_lar_term_L (m_l_terms_workspace .to_term (), tout);
1280
+ tout << " }, opened:" ; print_ml (m_l_terms_workspace .to_term (), tout) << std::endl;);
1256
1281
}
1257
1282
1258
1283
bool is_substituted_by_fresh (unsigned k) const {
@@ -1263,7 +1288,7 @@ namespace lp {
1263
1288
// the coefficient of x_k in t.
1264
1289
void subs_front_in_indexed_vector (protected_queue& q) {
1265
1290
unsigned k = q.pop_front ();
1266
- if (m_indexed_work_vector[k]. is_zero ( ))
1291
+ if (!m_substitution_workspace. has (k ))
1267
1292
return ;
1268
1293
// we might substitute with a term from S or a fresh term
1269
1294
@@ -1362,25 +1387,23 @@ namespace lp {
1362
1387
1363
1388
term_o create_term_from_ind_c () {
1364
1389
term_o t;
1365
- for (const auto & p : m_indexed_work_vector ) {
1390
+ for (const auto & p : m_substitution_workspace. m_data ) {
1366
1391
t.add_monomial (p.coeff (), p.var ());
1367
1392
}
1368
1393
t.c () = m_c;
1369
1394
return t;
1370
1395
}
1371
1396
1372
- void fill_indexed_work_vector_from_term (const lar_term& lar_t ) {
1373
- m_indexed_work_vector.clear ();
1374
- m_indexed_work_vector.resize (m_e_matrix.column_count ());
1397
+ void init_substitutions (const lar_term& lar_t ) {
1398
+ m_substitution_workspace.clear ();
1375
1399
m_c = 0 ;
1376
- m_term_with_index .clear ();
1400
+ m_l_terms_workspace .clear ();
1377
1401
for (const auto & p : lar_t ) {
1378
1402
SASSERT (p.coeff ().is_int ());
1379
1403
if (is_fixed (p.j ()))
1380
1404
m_c += p.coeff () * lia.lower_bound (p.j ()).x ;
1381
1405
else
1382
- m_indexed_work_vector.set_value (p.coeff (),
1383
- lar_solver_to_local (p.j ()));
1406
+ m_substitution_workspace.add (p.coeff (), lar_solver_to_local (p.j ()));
1384
1407
}
1385
1408
}
1386
1409
unsigned lar_solver_to_local (unsigned j) const {
@@ -1404,13 +1427,13 @@ namespace lp {
1404
1427
}
1405
1428
TRACE (" dioph_eq" , tout << " j:" << j << " , t: " ;
1406
1429
print_lar_term_L (term_to_tighten, tout) << std::endl;);
1407
- fill_indexed_work_vector_from_term (term_to_tighten);
1430
+ init_substitutions (term_to_tighten);
1408
1431
TRACE (" dioph_eq" , tout << " t orig:" ;
1409
1432
print_lar_term_L (term_to_tighten, tout) << std::endl;
1410
1433
tout << " from ind:" ;
1411
1434
print_term_o (create_term_from_ind_c (), tout) << std::endl;
1412
1435
tout << " m_tmp_l:" ;
1413
- print_lar_term_L (m_term_with_index .to_term (), tout) << std::endl;);
1436
+ print_lar_term_L (m_l_terms_workspace .to_term (), tout) << std::endl;);
1414
1437
subs_indexed_vector_with_S_and_fresh (q);
1415
1438
// if(
1416
1439
// fix_vars(term_to_tighten + open_ml(m_tmp_l)) !=
@@ -1421,13 +1444,13 @@ namespace lp {
1421
1444
print_term_o (create_term_from_ind_c (), tout) << std::endl;
1422
1445
tout << " term_to_tighten:" ;
1423
1446
print_lar_term_L (term_to_tighten, tout) << std::endl;
1424
- tout << " m_tmp_l:" ; print_lar_term_L (m_term_with_index .to_term (), tout) << std::endl;
1447
+ tout << " m_tmp_l:" ; print_lar_term_L (m_l_terms_workspace .to_term (), tout) << std::endl;
1425
1448
tout << " open_ml:" ;
1426
- print_lar_term_L (open_ml (m_term_with_index .to_term ()), tout) << std::endl;
1449
+ print_lar_term_L (open_ml (m_l_terms_workspace .to_term ()), tout) << std::endl;
1427
1450
tout << " term_to_tighten + open_ml:" ;
1428
- print_term_o (term_to_tighten + open_ml (m_term_with_index .to_term ()), tout)
1451
+ print_term_o (term_to_tighten + open_ml (m_l_terms_workspace .to_term ()), tout)
1429
1452
<< std::endl;
1430
- term_o ls = fix_vars (term_to_tighten + open_ml (m_term_with_index .to_term ()));
1453
+ term_o ls = fix_vars (term_to_tighten + open_ml (m_l_terms_workspace .to_term ()));
1431
1454
tout << " ls:" ; print_term_o (ls,tout) << std::endl;
1432
1455
term_o rs = term_to_lar_solver (remove_fresh_vars (create_term_from_ind_c ()));
1433
1456
tout << " rs:" ; print_term_o (rs, tout ) << std::endl;
@@ -1438,9 +1461,9 @@ namespace lp {
1438
1461
);
1439
1462
1440
1463
SASSERT (
1441
- fix_vars (term_to_tighten + open_ml (m_term_with_index .to_term ())) ==
1464
+ fix_vars (term_to_tighten + open_ml (m_l_terms_workspace .to_term ())) ==
1442
1465
term_to_lar_solver (remove_fresh_vars (create_term_from_ind_c ())));
1443
- mpq g = gcd_of_coeffs (m_indexed_work_vector , true );
1466
+ mpq g = gcd_of_coeffs (m_substitution_workspace. m_data , true );
1444
1467
TRACE (" dioph_eq" , tout << " after process_q_with_S\n t:" ;
1445
1468
print_term_o (create_term_from_ind_c (), tout) << std::endl;
1446
1469
tout << " g:" << g << std::endl;
@@ -1474,7 +1497,7 @@ namespace lp {
1474
1497
if (m_c > rs || (is_strict && m_c == rs)) {
1475
1498
u_dependency* dep =
1476
1499
lra.join_deps (explain_fixed (lra.get_term (j)),
1477
- explain_fixed_in_meta_term (m_term_with_index .m_data ));
1500
+ explain_fixed_in_meta_term (m_l_terms_workspace .m_data ));
1478
1501
dep = lra.join_deps (
1479
1502
dep, lra.get_bound_constraint_witnesses_for_column (j));
1480
1503
for (constraint_index ci : lra.flatten (dep)) {
@@ -1487,7 +1510,7 @@ namespace lp {
1487
1510
if (m_c < rs || (is_strict && m_c == rs)) {
1488
1511
u_dependency* dep =
1489
1512
lra.join_deps (explain_fixed (lra.get_term (j)),
1490
- explain_fixed_in_meta_term (m_term_with_index .m_data ));
1513
+ explain_fixed_in_meta_term (m_l_terms_workspace .m_data ));
1491
1514
dep = lra.join_deps (
1492
1515
dep, lra.get_bound_constraint_witnesses_for_column (j));
1493
1516
for (constraint_index ci : lra.flatten (dep)) {
@@ -1497,7 +1520,7 @@ namespace lp {
1497
1520
}
1498
1521
}
1499
1522
1500
- // m_indexed_work_vector contains the coefficients of the term
1523
+ // m_work_vector_1 contains the coefficients of the term
1501
1524
// m_c contains the constant term
1502
1525
// m_tmp_l is the linear combination of the equations that removes the
1503
1526
// substituted variables.
@@ -1542,7 +1565,7 @@ namespace lp {
1542
1565
lconstraint_kind kind =
1543
1566
upper ? lconstraint_kind::LE : lconstraint_kind::GE;
1544
1567
u_dependency* dep = prev_dep;
1545
- dep = lra.join_deps (dep, explain_fixed_in_meta_term (m_term_with_index .m_data ));
1568
+ dep = lra.join_deps (dep, explain_fixed_in_meta_term (m_l_terms_workspace .m_data ));
1546
1569
u_dependency* j_bound_dep = upper
1547
1570
? lra.get_column_upper_bound_witness (j)
1548
1571
: lra.get_column_lower_bound_witness (j);
@@ -2192,33 +2215,26 @@ namespace lp {
2192
2215
return r;
2193
2216
}
2194
2217
2195
- void make_space_in_work_vector (unsigned j) {
2196
- if (j >= m_indexed_work_vector.data_size ())
2197
- m_indexed_work_vector.resize (j + 1 );
2198
- }
2199
-
2200
2218
void open_l_term_to_work_vector (unsigned ei, mpq& c) {
2201
- m_indexed_work_vector .clear ();
2219
+ m_substitution_workspace .clear ();
2202
2220
for (const auto & p: m_l_matrix.m_rows [ei]) {
2203
2221
const lar_term& t = lra.get_term (p.var ());
2204
2222
for (const auto & q: t.ext_coeffs ()) {
2205
2223
if (is_fixed (q.var ())) {
2206
2224
c += p.coeff ()*q.coeff ()*lia.lower_bound (q.var ()).x ;
2207
2225
} else {
2208
- make_space_in_work_vector (q.var ());
2209
- m_indexed_work_vector.add_value_at_index (q.var (), p.coeff () * q.coeff ());
2226
+ m_substitution_workspace.add (p.coeff () * q.coeff (), q.var ());
2210
2227
}
2211
2228
}
2212
2229
}
2213
2230
}
2214
2231
2215
2232
// it clears the row, and puts the term in the work vector
2216
2233
void move_row_to_work_vector (unsigned ei) {
2217
- m_indexed_work_vector.clear ();
2218
- m_indexed_work_vector.resize (m_e_matrix.column_count ());
2234
+ m_substitution_workspace.clear ();
2219
2235
auto & row = m_e_matrix.m_rows [ei];
2220
2236
for (const auto & cell : row)
2221
- m_indexed_work_vector. set_value (cell.coeff (), cell.var ());
2237
+ m_substitution_workspace. add (cell.coeff (), cell.var ());
2222
2238
clear_e_row (ei);
2223
2239
}
2224
2240
0 commit comments