diff --git a/src/math/lp/dioph_eq.cpp b/src/math/lp/dioph_eq.cpp index e857a728c..ffa17eb3a 100644 --- a/src/math/lp/dioph_eq.cpp +++ b/src/math/lp/dioph_eq.cpp @@ -1156,6 +1156,12 @@ namespace lp { return lra.print_expl(out, ex); } + bool var_is_fresh(unsigned j) const { + bool ret = m_fresh_k2xt_terms.has_second_key(j); + SASSERT(!ret || m_var_register.local_to_external(j) == UINT_MAX); + return ret; + } + bool has_fresh_var(unsigned row_index) const { for (const auto& p : m_e_matrix.m_rows[row_index]) { if (var_is_fresh(p.var())) @@ -1363,7 +1369,7 @@ namespace lp { return weight; } - bool term_has_int_inv_vars(unsigned j) const { + bool term_has_int_inf_vars(unsigned j) const { for (const auto & p: lra.get_term(j)) { if (lia.column_is_int_inf(p.var())) return true; @@ -1381,7 +1387,7 @@ namespace lp { !lra.column_has_term(j) || lra.column_is_free(j) || !lia.column_is_int(j) || - !term_has_int_inv_vars(j)) { + !term_has_int_inf_vars(j)) { cleanup.push_back(j); continue; } @@ -1396,8 +1402,7 @@ namespace lp { lia_move r = lia_move::undef; // Process sorted terms TRACE("dio", - tout << "changed terms:"; - for (auto j : sorted_changed_terms) lra.print_term(lra.get_term(j), tout) << " - x" < 10) + return lia_move::undef; + struct bound_consumer { imp& i; bound_consumer(imp& i) : i(i) {} @@ -227,11 +233,8 @@ namespace lp { bound_consumer bc(*this); std_vector ibounds; lp_bound_propagator bp(bc, ibounds); - bp.init(); - unsigned num_refined_bounds = 0; - - auto set_conflict = [&](unsigned j, u_dependency * d1, u_dependency * d2) { + auto set_conflict = [&](u_dependency * d1, u_dependency * d2) { ++settings().stats().m_bounds_tightening_conflicts; for (auto e : lra.flatten(d1)) m_ex->push_back(e); @@ -239,6 +242,7 @@ namespace lp { m_ex->push_back(e); }; + bool bounds_refined = false; auto refine_bound = [&](implied_bound const& ib) { unsigned j = ib.m_j; rational bound = ib.m_bound; @@ -249,43 +253,46 @@ namespace lp { return l_undef; auto d = ib.explain_implied(); if (lra.column_has_upper_bound(j) && lra.column_upper_bound(j) < bound) { - set_conflict(j, d, lra.get_column_upper_bound_witness(j)); + set_conflict(d, lra.get_column_upper_bound_witness(j)); return l_false; } - - lra.update_column_type_and_bound(j, ib.m_strict ? lconstraint_kind::GT : lconstraint_kind::GE, bound, d); - ++num_refined_bounds; - } else { + lra.update_column_type_and_bound(j, ib.m_strict ? lconstraint_kind::GT : lconstraint_kind::GE, bound, d); + } + else { if (lra.column_is_int(j)) bound = floor(bound); if (lra.column_has_upper_bound(j) && lra.column_upper_bound(j) <= bound) return l_undef; auto d = ib.explain_implied(); if (lra.column_has_lower_bound(j) && lra.column_lower_bound(j) > bound) { - set_conflict(j, d, lra.get_column_lower_bound_witness(j)); + set_conflict(d, lra.get_column_lower_bound_witness(j)); return l_false; } - lra.update_column_type_and_bound(j, ib.m_strict ? lconstraint_kind::LT : lconstraint_kind::LE, bound, d); - ++num_refined_bounds; } + ++settings().stats().m_bounds_tightenings; + bounds_refined = true; return l_true; }; for (unsigned row_index = 0; row_index < lra.row_count(); ++row_index) { + bp.init(); bound_analyzer_on_row, lp_bound_propagator>::analyze_row( lra.A_r().m_rows[row_index], zero_of_type>(), bp); - settings().stats().m_bounds_tightenings += static_cast(ibounds.size()); for (auto const& ib : ibounds) if (l_false == refine_bound(ib)) return lia_move::conflict; - ibounds.clear(); + } + + if (bounds_refined) { + lra.trail().push(value_trail(m_bounds_refine_depth)); + ++m_bounds_refine_depth; } - return num_refined_bounds > 0 ? lia_move::continue_with_check : lia_move::undef; + return bounds_refined ? lia_move::continue_with_check : lia_move::undef; } @@ -318,7 +325,6 @@ namespace lp { if (r == lia_move::undef && should_hnf_cut()) r = hnf_cut(); if (r == lia_move::undef && should_gomory_cut()) r = gomory(lia).get_gomory_cuts(2); if (r == lia_move::undef && should_solve_dioph_eq()) r = solve_dioph_eq(); - if (r == lia_move::undef) lra.remove_fixed_vars_from_base(); if (r == lia_move::undef) r = int_branch(lia)(); if (settings().get_cancel_flag()) r = lia_move::undef; return r; diff --git a/src/math/lp/lar_solver.h b/src/math/lp/lar_solver.h index 641d1640f..7962888e7 100644 --- a/src/math/lp/lar_solver.h +++ b/src/math/lp/lar_solver.h @@ -160,7 +160,7 @@ class lar_solver : public column_namer { public: bool validate_blocker() const { return m_validate_blocker; } bool & validate_blocker() { return m_validate_blocker; } - void update_column_type_and_bound(unsigned j, lconstraint_kind kind, const mpq& right_side, u_dependency* dep); + void update_column_type_and_bound(unsigned j, lconstraint_kind kind, const mpq& right_side, u_dependency* dep); private: void require_nbasis_sort() { m_mpq_lar_core_solver.m_r_solver.m_nbasis_sort_counter = 0; } void update_column_type_and_bound_with_ub(lpvar j, lconstraint_kind kind, const mpq& right_side, u_dependency* dep); diff --git a/src/math/lp/lp_settings.h b/src/math/lp/lp_settings.h index 49eecb178..842c91bc2 100644 --- a/src/math/lp/lp_settings.h +++ b/src/math/lp/lp_settings.h @@ -138,7 +138,6 @@ struct statistics { unsigned m_dio_rewrite_conflicts = 0; unsigned m_dio_branching_sats = 0; unsigned m_dio_branching_conflicts = 0; - unsigned m_dio_bound_propagation_conflicts = 0; unsigned m_bounds_tightening_conflicts = 0; unsigned m_bounds_tightenings = 0; ::statistics m_st = {}; @@ -186,7 +185,6 @@ struct statistics { st.update("arith-dio-branching-conflicts", m_dio_branching_conflicts); st.update("arith-bounds-tightening-conflicts", m_bounds_tightening_conflicts); st.update("arith-bounds-tightenings", m_bounds_tightenings); - st.update("arith-dio-propagation-conflicts", m_dio_bound_propagation_conflicts); st.copy(m_st); } }; @@ -260,7 +258,7 @@ private: bool m_dio_enable_gomory_cuts = false; bool m_dio_enable_hnf_cuts = true; unsigned m_dio_branching_period = 100; // do branching rarely - unsigned m_dio_report_branch_with_term_tigthening_period = 10000000; + unsigned m_dio_report_branch_with_term_tigthening_period = 10000000; // period of reporting the branch with term tigthening public: bool print_external_var_name() const { return m_print_external_var_name; }