@@ -1198,7 +1198,7 @@ namespace lp {
1198
1198
return false ;
1199
1199
}
1200
1200
1201
- void subs_qfront_by_fresh (unsigned k, protected_queue& q) {
1201
+ lia_move subs_qfront_by_fresh (unsigned k, protected_queue& q, unsigned j ) {
1202
1202
const lar_term& e = m_fresh_k2xt_terms.get_by_key (k).first ;
1203
1203
TRACE (" dioph_eq" , tout << " k:" << k << " , in " ;
1204
1204
print_term_o (create_term_from_espace (), tout) << std::endl;
@@ -1218,11 +1218,13 @@ namespace lp {
1218
1218
if (m_espace.has (j) && can_substitute (j))
1219
1219
q.push (j);
1220
1220
}
1221
+
1221
1222
// there is no change in m_l_matrix
1222
1223
TRACE (" dioph_eq" , tout << " after subs k:" << k << " \n " ;
1223
1224
print_term_o (create_term_from_espace (), tout) << std::endl;
1224
1225
tout << " m_lspace:{" ; print_lar_term_L (m_lspace.m_data , tout);
1225
1226
tout << " }, opened:" ; print_ml (m_lspace.to_term (), tout) << std::endl;);
1227
+ return tighten_on_espace (j);
1226
1228
}
1227
1229
1228
1230
void add_l_row_to_term_with_index (const mpq& coeff, unsigned ei) {
@@ -1231,7 +1233,7 @@ namespace lp {
1231
1233
}
1232
1234
}
1233
1235
1234
- void subs_qfront_by_S (unsigned k, protected_queue& q) {
1236
+ lia_move subs_qfront_by_S (unsigned k, protected_queue& q, unsigned j ) {
1235
1237
const mpq& e = m_sum_of_fixed[m_k2s[k]];
1236
1238
TRACE (" dio" , tout << " k:" << k << " , in " ;
1237
1239
print_term_o (create_term_from_espace (), tout) << std::endl;
@@ -1266,6 +1268,8 @@ namespace lp {
1266
1268
print_term_o (create_term_from_espace (), tout) << std::endl;
1267
1269
tout << " m_lspace:{" ; print_lar_term_L (m_lspace.to_term (), tout);
1268
1270
tout << " }, opened:" ; print_ml (m_lspace.to_term (), tout) << std::endl;);
1271
+
1272
+ return tighten_on_espace (j);
1269
1273
}
1270
1274
1271
1275
bool is_substituted_by_fresh (unsigned k) const {
@@ -1274,19 +1278,27 @@ namespace lp {
1274
1278
// The term giving the substitution is in form (+-)x_k + sum {a_i*x_i} + c = 0.
1275
1279
// We substitute x_k in t by (+-)coeff*(sum {a_i*x_i} + c), where coeff is
1276
1280
// the coefficient of x_k in t.
1277
- void subs_front_with_S_and_fresh (protected_queue& q) {
1281
+ lia_move subs_front_with_S_and_fresh (protected_queue& q, unsigned j) {
1282
+ process_fixed_in_espace ();
1283
+ auto r = tighten_on_espace (j);
1284
+ if (r == lia_move::conflict) return lia_move::conflict;
1278
1285
unsigned k = q.pop_front ();
1279
1286
if (!m_espace.has (k))
1280
- return ;
1287
+ return lia_move::undef ;
1281
1288
// we might substitute with a term from S or a fresh term
1282
1289
1283
1290
SASSERT (can_substitute (k));
1291
+ lia_move ret;
1284
1292
if (is_substituted_by_fresh (k)) {
1285
- subs_qfront_by_fresh (k, q);
1293
+ ret = subs_qfront_by_fresh (k, q, j );
1286
1294
}
1287
1295
else {
1288
- subs_qfront_by_S (k, q);
1296
+ ret = subs_qfront_by_S (k, q, j );
1289
1297
}
1298
+ if (ret == lia_move::conflict)
1299
+ return lia_move::conflict;
1300
+ if (r == lia_move::continue_with_check) return r;
1301
+ return ret;
1290
1302
}
1291
1303
1292
1304
lar_term l_term_from_row (unsigned k) const {
@@ -1355,9 +1367,15 @@ namespace lp {
1355
1367
return true ;
1356
1368
}
1357
1369
1358
- void subs_with_S_and_fresh (protected_queue& q) {
1359
- while (!q.empty ())
1360
- subs_front_with_S_and_fresh (q);
1370
+ lia_move subs_with_S_and_fresh (protected_queue& q, unsigned j) {
1371
+ lia_move r = lia_move::undef;
1372
+ while (!q.empty ()) {
1373
+ lia_move ret = subs_front_with_S_and_fresh (q, j);
1374
+ if (ret == lia_move::conflict) return lia_move::conflict;
1375
+ if (ret == lia_move::continue_with_check)
1376
+ r = ret;
1377
+ }
1378
+ return r;
1361
1379
}
1362
1380
1363
1381
unsigned term_weight (const lar_term& t) const {
@@ -1427,7 +1445,7 @@ namespace lp {
1427
1445
// Process sorted terms
1428
1446
TRACE (" dio" ,
1429
1447
tout << " changed terms:" ; for (auto j : sorted_changed_terms) tout << j << " " ; tout << std::endl;
1430
- // print_S(tout);
1448
+ print_S (tout);
1431
1449
// print_bounds(tout);
1432
1450
);
1433
1451
for (unsigned j : sorted_changed_terms) {
@@ -1490,37 +1508,12 @@ namespace lp {
1490
1508
m_espace.erase (j);
1491
1509
}
1492
1510
}
1493
- /* j is the index of the column representing a term
1494
- Return lia_move::conflict if a conflict was found, lia_move::continue_with_check if j became a fixed variable, and undef
1495
- otherwise
1496
- When we have a constraint x + y <= 8 then after the substitutions with S and fresh variables
1497
- we might have x + y = 7t - 1 <= 8, where t is a term. Then 7t <= 9, or t <= 9/7, and we can enforce t <= floor(9/7) = 1.
1498
- Then x + y = 7*1 - 1 <= 6: the bound is strenthgened. The constraint in this example comes from the upper bound on j, where
1499
- j is the slack variable in x + y - j = 0.
1500
- */
1501
- lia_move tighten_bounds_for_term_column (unsigned j) {
1502
- // q is the queue of variables that can be substituted in term_to_tighten
1503
- protected_queue q;
1504
- TRACE (" dio" , tout << " j:" << j << " , intitial term t: " ; print_lar_term_L (lra.get_term (j), tout) << std::endl;
1505
- for ( const auto & p : lra.get_term (j)) {
1506
- lra.print_column_info (p.var (), tout);
1507
- }
1508
- );
1509
- init_substitutions (lra.get_term (j), q);
1510
- if (q.empty ()) // todo: maybe still go ahead and process it?
1511
- return lia_move::undef;
1512
-
1513
- TRACE (" dio" , tout << " t:" ;
1514
- tout << " m_espace:" ;
1515
- print_term_o (create_term_from_espace (), tout) << std::endl;
1516
- tout << " m_lspace:" ;
1517
- print_lar_term_L (m_lspace.to_term (), tout) << std::endl;);
1518
- subs_with_S_and_fresh (q);
1519
- process_fixed_in_espace ();
1520
- SASSERT (subs_invariant (j));
1511
+
1512
+
1513
+ lia_move tighten_on_espace (unsigned j) {
1521
1514
mpq g = gcd_of_coeffs (m_espace.m_data , true );
1522
1515
TRACE (" dio" , tout << " after process_q_with_S\n t:" ; print_term_o (create_term_from_espace (), tout) << std::endl; tout << " g:" << g << std::endl;);
1523
-
1516
+
1524
1517
if (g.is_one ())
1525
1518
return lia_move::undef;
1526
1519
if (g.is_zero ()) {
@@ -1545,6 +1538,40 @@ namespace lp {
1545
1538
return lia_move::continue_with_check;
1546
1539
}
1547
1540
return lia_move::undef;
1541
+
1542
+ }
1543
+
1544
+ /* j is the index of the column representing a term
1545
+ Return lia_move::conflict if a conflict was found, lia_move::continue_with_check if j became a fixed variable, and undef
1546
+ otherwise
1547
+ When we have a constraint x + y <= 8 then after the substitutions with S and fresh variables
1548
+ we might have x + y = 7t - 1 <= 8, where t is a term. Then 7t <= 9, or t <= 9/7, and we can enforce t <= floor(9/7) = 1.
1549
+ Then x + y = 7*1 - 1 <= 6: the bound is strenthgened. The constraint in this example comes from the upper bound on j, where
1550
+ j is the slack variable in x + y - j = 0.
1551
+ */
1552
+ lia_move tighten_bounds_for_term_column (unsigned j) {
1553
+ // q is the queue of variables that can be substituted in term_to_tighten
1554
+ protected_queue q;
1555
+ TRACE (" dio" , tout << " j:" << j << " , intitial term t: " ; print_lar_term_L (lra.get_term (j), tout) << std::endl;
1556
+ for ( const auto & p : lra.get_term (j).ext_coeffs ()) {
1557
+ lra.print_column_info (p.var (), tout);
1558
+ }
1559
+ );
1560
+ init_substitutions (lra.get_term (j), q);
1561
+
1562
+ TRACE (" dio" , tout << " t:" ;
1563
+ tout << " m_espace:" ;
1564
+ print_term_o (create_term_from_espace (), tout) << std::endl;
1565
+ tout << " in lar_solver indices:\n " ;
1566
+ print_term_o (term_to_lar_solver (create_term_from_espace ()), tout) << " \n " ;
1567
+ tout << " m_lspace:" ;
1568
+ print_lar_term_L (m_lspace.to_term (), tout) << std::endl;);
1569
+ if (subs_with_S_and_fresh (q, j) == lia_move::conflict)
1570
+ return lia_move::conflict;
1571
+
1572
+ process_fixed_in_espace ();
1573
+ SASSERT (subs_invariant (j));
1574
+ return tighten_on_espace (j);
1548
1575
}
1549
1576
1550
1577
bool should_report_branch () const {
@@ -2492,7 +2519,7 @@ namespace lp {
2492
2519
out << " x" << j << " " ;
2493
2520
out << " {\n " ;
2494
2521
2495
- print_term_o (get_term_from_entry (i), out << " \t " ) << " , \n " ;
2522
+ print_term_o (get_term_from_entry (i), out << " \t " ) << " = 0 \n " ;
2496
2523
if (print_dep) {
2497
2524
auto l_term = l_term_from_row (i);
2498
2525
out << " \t m_l:{" ;
@@ -2515,15 +2542,15 @@ namespace lp {
2515
2542
for (const auto & p : m_e_matrix[i] ) {
2516
2543
if (var_is_fresh (p.var ())) {
2517
2544
has_fresh = true ;
2518
- out << " has fresh var:" << p.var () << " \n " ;
2519
2545
break ;
2520
2546
}
2521
2547
}
2522
2548
if (!has_fresh) {
2523
2549
for (const auto & p : get_term_from_entry (i)) {
2524
- out << " \t local(x" << p.var () << " )" ;
2525
- lra.print_column_info (local_to_lar_solver (p.var ()), out);
2526
- }
2550
+ out << " \t x" << p.var () << " : " << lra.get_bounds_string (local_to_lar_solver (p.var ())) << " \n " ;
2551
+ }
2552
+ } else {
2553
+ out << " \t has fresh vars\n " ;
2527
2554
}
2528
2555
}
2529
2556
out << " }\n " ;
0 commit comments