@@ -1075,7 +1075,12 @@ namespace lp {
1075
1075
}
1076
1076
1077
1077
template <typename K>
1078
- mpq gcd_of_coeffs (const K& k) {
1078
+ mpq gcd_of_coeffs (const K& k, bool check_for_one) {
1079
+ if (check_for_one)
1080
+ for (const auto & p : k)
1081
+ if (p.coeff ().is_one () || p.coeff ().is_minus_one ())
1082
+ return mpq (1 );
1083
+
1079
1084
mpq g (0 );
1080
1085
for (const auto & p : k) {
1081
1086
SASSERT (p.coeff ().is_int ());
@@ -1125,10 +1130,10 @@ namespace lp {
1125
1130
// If there is no conflict the entry is divided, normalized, by gcd.
1126
1131
// The function returns true if and only if there is no conflict. In the case of a conflict a branch
1127
1132
// can be returned as well.
1128
- bool normalize_e_by_gcd (unsigned ei) {
1133
+ bool normalize_e_by_gcd (unsigned ei, mpq& g ) {
1129
1134
mpq & e = m_sum_of_fixed[ei];
1130
1135
TRACE (" dioph_eq" , print_entry (ei, tout) << std::endl;);
1131
- mpq g = gcd_of_coeffs (m_e_matrix.m_rows [ei]);
1136
+ g = gcd_of_coeffs (m_e_matrix.m_rows [ei], false );
1132
1137
if (g.is_zero () || g.is_one ()) {
1133
1138
SASSERT (g.is_one () || e.is_zero ());
1134
1139
return true ;
@@ -1159,20 +1164,6 @@ namespace lp {
1159
1164
return false ;
1160
1165
}
1161
1166
1162
- // iterate over F: return true if no conflict is found and false otherwise
1163
- bool normalize_by_gcd () {
1164
- for (unsigned l = 0 ; l < m_e_matrix.row_count (); l++) {
1165
- if (!belongs_to_f (l)) continue ;
1166
- if (!normalize_e_by_gcd (l)) {
1167
- SASSERT (entry_invariant (l));
1168
- m_conflict_index = l;
1169
- return false ;
1170
- }
1171
- SASSERT (entry_invariant (l));
1172
- }
1173
- return true ;
1174
- }
1175
-
1176
1167
void init_term_from_constraint (term_o& t, const lar_base_constraint& c) {
1177
1168
for (const auto & p : c.coeffs ()) {
1178
1169
t.add_monomial (p.first , p.second );
@@ -1438,7 +1429,7 @@ namespace lp {
1438
1429
SASSERT (
1439
1430
fix_vars (term_to_tighten + open_ml (m_term_with_index.to_term ())) ==
1440
1431
term_to_lar_solver (remove_fresh_vars (create_term_from_ind_c ())));
1441
- mpq g = gcd_of_coeffs (m_indexed_work_vector);
1432
+ mpq g = gcd_of_coeffs (m_indexed_work_vector, true );
1442
1433
TRACE (" dioph_eq" , tout << " after process_q_with_S\n t:" ;
1443
1434
print_term_o (create_term_from_ind_c (), tout) << std::endl;
1444
1435
tout << " g:" << g << std::endl;
@@ -1578,23 +1569,10 @@ namespace lp {
1578
1569
}
1579
1570
1580
1571
lia_move process_f () {
1581
- bool progress = true ;
1582
- while (progress) {
1583
- if (!normalize_by_gcd ()) {
1584
- if (m_report_branch) {
1585
- lra.stats ().m_dio_branch_from_proofs ++;
1586
- m_report_branch = false ;
1587
- return lia_move::branch;
1588
- } else {
1589
- lra.stats ().m_dio_normalize_conflicts ++;
1590
- }
1591
- return lia_move::conflict;
1592
- }
1593
- progress = rewrite_eqs ();
1594
- if (m_conflict_index != UINT_MAX) {
1595
- lra.stats ().m_dio_rewrite_conflicts ++;
1596
- return lia_move::conflict;
1597
- }
1572
+ while (rewrite_eqs ()) {}
1573
+ if (m_conflict_index != UINT_MAX) {
1574
+ lra.stats ().m_dio_rewrite_conflicts ++;
1575
+ return lia_move::conflict;
1598
1576
}
1599
1577
return lia_move::undef;
1600
1578
}
@@ -1956,7 +1934,7 @@ namespace lp {
1956
1934
return ret;
1957
1935
}
1958
1936
SASSERT (ret == lia_move::undef);
1959
- m_max_number_of_iterations = std::max (( unsigned )5 , ( unsigned ) m_max_number_of_iterations/2 ) ;
1937
+ m_max_number_of_iterations = ( unsigned )m_max_number_of_iterations/2 ;
1960
1938
1961
1939
return lia_move::undef;
1962
1940
}
@@ -2336,13 +2314,28 @@ namespace lp {
2336
2314
return false ;
2337
2315
}
2338
2316
}
2317
+
2339
2318
auto [ahk, k, k_sign] = find_minimal_abs_coeff (ei);
2340
2319
if (ahk.is_one ()) {
2341
2320
TRACE (" dioph_eq" , tout << " push to S:\n " ; print_entry (ei, tout););
2342
2321
move_entry_from_f_to_s (k, ei);
2343
2322
eliminate_var_in_f (ei, k, k_sign);
2344
2323
return true ;
2345
2324
}
2325
+ mpq gcd;
2326
+ if (!normalize_e_by_gcd (ei, gcd)) {
2327
+ m_conflict_index = ei;
2328
+ return false ;
2329
+ }
2330
+ if (!gcd.is_one ()){
2331
+ ahk /= gcd;
2332
+ if (ahk.is_one ()) {
2333
+ TRACE (" dioph_eq" , tout << " push to S:\n " ; print_entry (ei, tout););
2334
+ move_entry_from_f_to_s (k, ei);
2335
+ eliminate_var_in_f (ei, k, k_sign);
2336
+ return true ;
2337
+ }
2338
+ }
2346
2339
2347
2340
if (n == 0 || the_smallest_ahk > ahk) {
2348
2341
n = 1 ;
@@ -2358,7 +2351,7 @@ namespace lp {
2358
2351
kh_sign = k_sign;
2359
2352
}
2360
2353
}
2361
- if (h == - 1 ) return false ;
2354
+ if (h == UINT_MAX ) return false ;
2362
2355
SASSERT (!the_smallest_ahk.is_one ());
2363
2356
fresh_var_step (h, kh, the_smallest_ahk * mpq (kh_sign));
2364
2357
return true ;
0 commit comments