diff --git a/src/ast/sls/sls_bv_lookahead.cpp b/src/ast/sls/sls_bv_lookahead.cpp index f9f0c7ffb..69d092d00 100644 --- a/src/ast/sls/sls_bv_lookahead.cpp +++ b/src/ast/sls/sls_bv_lookahead.cpp @@ -95,7 +95,7 @@ namespace sls { for (unsigned i = 0; i < sz; ++i) add_updates(vars[(start + i) % sz]); CTRACE("bv", !m_best_expr, tout << "no guided move\n";); - return apply_update(m_last_atom, m_best_expr, m_best_value, "increasing move"); + return apply_update(m_last_atom, m_best_expr, m_best_value, move_type::guided_t); } /** @@ -117,7 +117,8 @@ namespace sls { auto& v = wval(e); m_v_updated.set_bw(v.bw); v.get_variant(m_v_updated, m_ev.m_rand); - return apply_update(nullptr, e, m_v_updated, "random update"); + ++m_stats.random_flip_count; + return apply_update(m_last_atom, e, m_v_updated, move_type::random_t); } /** @@ -153,7 +154,7 @@ namespace sls { v.sub1(m_v_updated); break; } - return apply_update(nullptr, e, m_v_updated, "random move"); + return apply_update(m_last_atom, e, m_v_updated, move_type::move_t); } /** @@ -243,7 +244,7 @@ namespace sls { auto& v = wval(e); m_v_updated.set_bw(v.bw); m_v_updated.set_zero(); - apply_update(nullptr, e, m_v_updated, "reset"); + apply_update(nullptr, e, m_v_updated, move_type::reset_t); } } } @@ -517,7 +518,18 @@ namespace sls { * The update is committed. */ - bool bv_lookahead::apply_update(expr* p, expr* t, bvect const& new_value, char const* reason) { + std::ostream& operator<<(std::ostream& out, bv_lookahead::move_type t) { + switch (t) { + case bv_lookahead::move_type::guided_t: return out << "guided"; + case bv_lookahead::move_type::random_t: return out << "random"; + case bv_lookahead::move_type::move_t: return out << "move"; + case bv_lookahead::move_type::reset_t: return out << "reset"; + default: + return out; + } + } + + bool bv_lookahead::apply_update(expr* p, expr* t, bvect const& new_value, move_type mt) { if (!t || m.is_bool(t) || !wval(t).can_set(new_value)) return false; @@ -553,27 +565,32 @@ namespace sls { continue; if (ctx.is_true(v) == v1) continue; - if (!p || e == p) + + if (e == p) continue; TRACE("bv", tout << "updated truth value " << v << ": " << mk_bounded_pp(e, m) << "\n";); -#if 0 unsigned num_unsat = ctx.unsat().size(); +#if 0 + TRACE("bv", tout << "update flip " << mk_bounded_pp(e, m) << "\n";); auto r = ctx.reward(v); auto lit = sat::literal(v, !ctx.is_true(v)); bool is_bv_lit = is_bv_literal(lit); - verbose_stream() << "flip " << is_bv_literal(lit) << " " << mk_bounded_pp(e, m) << " " << lit << " " << r << " num unsat " << ctx.unsat().size() << "\n"; - - ctx.flip(v); - + sat::bool_var_set rotated; + unsigned budget = 100; + bool rot = ctx.try_rotate(v, rotated, budget); + verbose_stream() << "try-rotate " << rot << " " << rotated.size() << "\n"; + verbose_stream() << "flip " << ((!p || e == p) ? "top " : "not top ") << is_bv_literal(lit) << " " << mk_bounded_pp(e, m) << " " << lit << " " << r << " num unsat " << num_unsat << " -> " << ctx.unsat().size() << "\n"; verbose_stream() << "new unsat " << ctx.unsat().size() << "\n"; - if (num_unsat < ctx.unsat().size()) { - verbose_stream() << "flip back\n"; - ctx.flip(v); - } #endif + +#if 1 + if (allow_costly_flips(mt)) + ctx.flip(v); +#endif + } m_ev.set_bool_value(to_app(e), v1); } @@ -589,12 +606,20 @@ namespace sls { } m_in_update_stack.reset(); m_ev.clear_bool_values(); - TRACE("bv", tout << reason << " " << mk_bounded_pp(t, m) + TRACE("bv", tout << mt << " " << mk_bounded_pp(t, m) << " := " << new_value << " score " << m_top_score << "\n";); return true; } + bool bv_lookahead::allow_costly_flips(move_type mt) { + if (mt == move_type::reset_t) + return true; + if (mt != move_type::random_t) + return false; + return m_stats.random_flip_count % 100 == 0; + } + void bv_lookahead::insert_update(expr* e) { TRACE("sls_verbose", tout << "insert update " << mk_bounded_pp(e, m) << "\n"); diff --git a/src/ast/sls/sls_bv_lookahead.h b/src/ast/sls/sls_bv_lookahead.h index e91ed5455..4b01d0e97 100644 --- a/src/ast/sls/sls_bv_lookahead.h +++ b/src/ast/sls/sls_bv_lookahead.h @@ -53,6 +53,7 @@ namespace sls { unsigned m_moves = 0; unsigned m_restarts = 0; unsigned m_num_propagations = 0; + unsigned random_flip_count = 0; }; struct bool_info { @@ -109,10 +110,15 @@ namespace sls { void set_touched(app* e, unsigned t) { get_bool_info(e).touched = t; } void inc_touched(app* e) { ++get_bool_info(e).touched; } + enum class move_type { random_t, guided_t, move_t, reset_t }; + friend std::ostream& operator<<(std::ostream& out, move_type mt); + + + bool allow_costly_flips(move_type mt); void try_set(expr* u, bvect const& new_value); void try_flip(expr* u); void add_updates(expr* u); - bool apply_update(expr* p, expr* t, bvect const& new_value, char const* reason); + bool apply_update(expr* p, expr* t, bvect const& new_value, move_type mt); bool apply_random_move(ptr_vector const& vars); bool apply_guided_move(ptr_vector const& vars); bool apply_random_update(ptr_vector const& vars); diff --git a/src/ast/sls/sls_context.h b/src/ast/sls/sls_context.h index 3eca47726..975ce84bc 100644 --- a/src/ast/sls/sls_context.h +++ b/src/ast/sls/sls_context.h @@ -69,6 +69,7 @@ namespace sls { virtual sat::clause_info const& get_clause(unsigned idx) const = 0; virtual ptr_iterator get_use_list(sat::literal lit) = 0; virtual void flip(sat::bool_var v) = 0; + virtual bool try_rotate(sat::bool_var v, sat::bool_var_set& rotated, unsigned& budget) = 0; virtual double reward(sat::bool_var v) = 0; virtual double get_weigth(unsigned clause_idx) = 0; virtual bool is_true(sat::literal lit) = 0; @@ -175,6 +176,7 @@ namespace sls { void add_clause(expr* f); void add_clause(sat::literal_vector const& lits); void flip(sat::bool_var v) { s.flip(v); } + bool try_rotate(sat::bool_var v, sat::bool_var_set& rotated, unsigned& budget) { return s.try_rotate(v, rotated, budget); } double reward(sat::bool_var v) { return s.reward(v); } indexed_uint_set const& unsat() const { return s.unsat(); } unsigned rand() { return m_rand(); } diff --git a/src/ast/sls/sls_smt_plugin.h b/src/ast/sls/sls_smt_plugin.h index cd044d2b2..f099fb264 100644 --- a/src/ast/sls/sls_smt_plugin.h +++ b/src/ast/sls/sls_smt_plugin.h @@ -148,6 +148,9 @@ namespace sls { void flip(sat::bool_var v) override { m_ddfw->flip(v); } + bool try_rotate(sat::bool_var v, sat::bool_var_set& rotated, unsigned& budget) override { + return m_ddfw->try_rotate(v, rotated, budget); + } double reward(sat::bool_var v) override { return m_ddfw->reward(v); } double get_weigth(unsigned clause_idx) override { return m_ddfw->get_clause_info(clause_idx).m_weight; } bool is_true(sat::literal lit) override { diff --git a/src/ast/sls/sls_smt_solver.cpp b/src/ast/sls/sls_smt_solver.cpp index 621092bdf..90ba06f8c 100644 --- a/src/ast/sls/sls_smt_solver.cpp +++ b/src/ast/sls/sls_smt_solver.cpp @@ -85,6 +85,7 @@ namespace sls { sat::clause_info const& get_clause(unsigned idx) const override { return m_ddfw.get_clause_info(idx); } ptr_iterator get_use_list(sat::literal lit) override { return m_ddfw.use_list(lit); } void flip(sat::bool_var v) override { if (m_dirty) m_ddfw.reinit(), m_dirty = false; m_ddfw.flip(v); } + bool try_rotate(sat::bool_var v, sat::bool_var_set& rotated, unsigned& budget) override { if (m_dirty) m_ddfw.reinit(), m_dirty = false; return m_ddfw.try_rotate(v, rotated, budget); } double reward(sat::bool_var v) override { return m_ddfw.reward(v); } double get_weigth(unsigned clause_idx) override { return m_ddfw.get_clause_info(clause_idx).m_weight; } bool is_true(sat::literal lit) override { return m_ddfw.get_value(lit.var()) != lit.sign(); }