diff --git a/src/math/polysat/fixplex.h b/src/math/polysat/fixplex.h index cdfd947fb..e617872e5 100644 --- a/src/math/polysat/fixplex.h +++ b/src/math/polysat/fixplex.h @@ -28,6 +28,7 @@ Author: #include "util/uint_set.h" #include "util/dependency.h" #include "util/ref.h" +#include "util/params.h" inline rational to_rational(uint64_t n) { return rational(n, rational::ui64()); } inline unsigned trailing_zeros(unsigned short n) { return trailing_zeros((uint32_t)n); } @@ -55,6 +56,7 @@ namespace polysat { virtual void restore_ineq() = 0; virtual bool inconsistent() const = 0; virtual unsigned_vector const& get_unsat_core() const = 0; + virtual void updt_params(params_ref const& p) = 0; }; @@ -170,14 +172,15 @@ namespace polysat { reslimit& m_limit; mutable manager m; mutable matrix M; - unsigned m_max_iterations { UINT_MAX }; - unsigned m_num_non_integral { 0 }; + unsigned m_max_iterations = UINT_MAX; + unsigned m_num_non_integral = 0; var_heap m_to_patch; vector m_vars; vector m_rows; vector m_var_eqs; - bool m_bland { false }; - unsigned m_blands_rule_threshold { 1000 }; + bool m_bland = false ; + unsigned m_blands_rule_threshold = 1000; + var_t m_last_pivot_var = null_var; random_gen m_random; uint_set m_left_basis; unsigned_vector m_unsat_core; @@ -198,16 +201,19 @@ namespace polysat { svector m_vars_to_untouch; public: - fixplex(reslimit& lim): + fixplex(params_ref const& p, reslimit& lim): m_limit(lim), M(m), - m_to_patch(1024) {} + m_to_patch(1024) { + updt_params(p); + } ~fixplex() override; void push() override; void pop(unsigned n) override; bool inconsistent() const override { return m_inconsistent; } + void updt_params(params_ref const& p) override; lbool make_feasible() override; void add_row(var_t base, unsigned num_vars, var_t const* vars, rational const* coeffs) override; diff --git a/src/math/polysat/fixplex_def.h b/src/math/polysat/fixplex_def.h index efbb26e74..17aa73d2d 100644 --- a/src/math/polysat/fixplex_def.h +++ b/src/math/polysat/fixplex_def.h @@ -82,6 +82,12 @@ namespace polysat { reset(); } + + template + void fixplex::updt_params(params_ref const& p) { + m_max_iterations = p.get_uint("max_iterations", m_max_iterations); + } + template void fixplex::push() { m_trail.push_back(trail_i::inc_level_i); @@ -145,6 +151,7 @@ namespace polysat { return l_false; ++m_stats.m_num_checks; m_left_basis.reset(); + m_last_pivot_var = null_var; unsigned num_iterations = 0; unsigned num_repeated = 0; var_t v = null_var; @@ -407,6 +414,8 @@ namespace polysat { numeral const& b = r.coeff(); if (x == y) continue; + if (y == m_last_pivot_var) + continue; if (!has_minimal_trailing_zeros(y, b)) continue; numeral new_y_value = solve_for(row_value - b * value(y), b); @@ -469,7 +478,7 @@ namespace polysat { row r = base2row(x); for (auto const& c : M.col_entries(r)) { var_t y = c.var(); - if (x == y || y >= result) + if (x == y || y >= result || y == m_last_pivot_var) continue; numeral const& b = c.coeff(); if (can_improve(y, b)) { @@ -798,7 +807,8 @@ namespace polysat { */ template void fixplex::pivot(var_t x, var_t y, numeral const& b, numeral const& new_value) { - ++m_stats.m_num_pivots; + ++m_stats.m_num_pivots; + m_last_pivot_var = x; SASSERT(is_base(x)); SASSERT(!is_base(y)); var_info& xI = m_vars[x]; diff --git a/src/math/polysat/linear_solver.cpp b/src/math/polysat/linear_solver.cpp index e2e127442..bb4ff01a2 100644 --- a/src/math/polysat/linear_solver.cpp +++ b/src/math/polysat/linear_solver.cpp @@ -64,22 +64,22 @@ namespace polysat { if (!b) { switch (sz) { case 8: - b = alloc(fixplex>, s.m_lim); + b = alloc(fixplex>, s.params(), s.m_lim); break; case 16: - b = alloc(fixplex>, s.m_lim); + b = alloc(fixplex>, s.params(), s.m_lim); break; case 32: - b = alloc(fixplex>, s.m_lim); + b = alloc(fixplex>, s.params(), s.m_lim); break; case 64: - b = alloc(fixplex, s.m_lim); + b = alloc(fixplex, s.params(), s.m_lim); break; case 128: NOT_IMPLEMENTED_YET(); break; case 256: - b = alloc(fixplex>, s.m_lim); + b = alloc(fixplex>, s.params(), s.m_lim); break; default: NOT_IMPLEMENTED_YET(); diff --git a/src/math/polysat/solver.h b/src/math/polysat/solver.h index 2b806b5e3..671848357 100644 --- a/src/math/polysat/solver.h +++ b/src/math/polysat/solver.h @@ -19,6 +19,7 @@ Author: #include #include "util/statistics.h" +#include "util/params.h" #include "math/polysat/boolean.h" #include "math/polysat/constraint.h" #include "math/polysat/clause_builder.h" @@ -60,6 +61,7 @@ namespace polysat { typedef ptr_vector constraints; reslimit& m_lim; + params_ref m_params; viable m_viable; // viable sets per variable scoped_ptr_vector m_pdd; dep_value_manager m_value_manager; @@ -326,6 +328,8 @@ namespace polysat { void collect_statistics(statistics& st) const; + params_ref& params() { return m_params; } + }; class assignments_pp { diff --git a/src/test/fixplex.cpp b/src/test/fixplex.cpp index 48ed03cd3..a41a8baea 100644 --- a/src/test/fixplex.cpp +++ b/src/test/fixplex.cpp @@ -12,10 +12,12 @@ namespace polysat { typedef uint64_ext::numeral numeral; struct solver_scope { + params_ref p; reslimit lim; }; struct scoped_fp : public solver_scope, public fixplex { - scoped_fp(): fixplex(lim) {} + + scoped_fp(): fixplex(p, lim) {} void run() { std::cout << *this << "\n"; @@ -369,6 +371,27 @@ namespace polysat { std::cout << "number of failures: " << num_bad << "\n"; } + static void save_scenario( + vector>> const& rows, + svector const& ineqs, + vector> const& bounds) { + std::cout << "static void scenario() {"; + std::cout << " vector>> rows\n;"; + std::cout << " svector ineqs\n;"; + std::cout << " vector> bounds\n"; + for (auto row : rows) { + std::cout << " rows.push_back(svector>());\n"; + for (auto col : row) + std::cout << " rows.back().push_back(std::make_pair(" << col.first << ", " << col.second << ");\n"; + } + for (auto ineq : ineqs) + std::cout << " ineqs.push_back(ineq(" << ineq.v << ", " << ineq.w << " " << ineq.strict << ");\n"; + for (auto bound : bounds) + std::cout << " bounds.push_back(mod_interval(" << bound.lo << ", " << bound.hi << ");\n"; + std::cout << " test_lp(rows, ineqs, bounds);\n}\n"; + } + + static void test_lp( vector>> const& rows, svector const& ineqs, @@ -395,6 +418,10 @@ namespace polysat { }; scoped_fp fp; + params_ref p; + p.set_uint("max_iterations", 100); + fp.updt_params(p); + for (auto& row : rows) { vector coeffs; svector vars;