3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-04-15 21:38:44 +00:00

integrate v2 of lns

This commit is contained in:
Nikolaj Bjorner 2021-02-04 15:47:40 -08:00
parent dfb7c87448
commit 0ec567fe15
18 changed files with 254 additions and 105 deletions

View file

@ -121,6 +121,9 @@ public:
void assert_expr_core(expr *t) override { m_solver.assert_expr(t); } void assert_expr_core(expr *t) override { m_solver.assert_expr(t); }
void assert_expr_core2(expr *t, expr *a) override { NOT_IMPLEMENTED_YET(); } void assert_expr_core2(expr *t, expr *a) override { NOT_IMPLEMENTED_YET(); }
void set_phase(expr* e) override { m_solver.set_phase(e); } void set_phase(expr* e) override { m_solver.set_phase(e); }
phase* get_phase() override { return m_solver.get_phase(); }
void set_phase(phase* p) override { m_solver.set_phase(p); }
void move_to_front(expr* e) override { m_solver.move_to_front(e); }
expr_ref_vector cube(expr_ref_vector&, unsigned) override { return expr_ref_vector(m); } expr_ref_vector cube(expr_ref_vector&, unsigned) override { return expr_ref_vector(m); }
void get_levels(ptr_vector<expr> const& vars, unsigned_vector& depth) override { m_solver.get_levels(vars, depth); } void get_levels(ptr_vector<expr> const& vars, unsigned_vector& depth) override { m_solver.get_levels(vars, depth); }
expr_ref_vector get_trail() override { return m_solver.get_trail(); } expr_ref_vector get_trail() override { return m_solver.get_trail(); }

View file

@ -83,6 +83,18 @@ private:
memset(this, 0, sizeof(*this)); memset(this, 0, sizeof(*this));
} }
}; };
struct lns_maxres : public lns_context {
maxres& i;
lns_maxres(maxres& i) :i(i) {}
~lns_maxres() override {}
void update_model(model_ref& mdl) override { i.update_assignment(mdl); }
void relax_cores(vector<expr_ref_vector> const& cores) override { i.relax_cores(cores); }
rational cost(model& mdl) override { return i.cost(mdl); }
rational weight(expr* e) override { return i.m_asm2weight[e]; }
expr_ref_vector const& soft() override { return i.m_asms; }
};
unsigned m_index; unsigned m_index;
stats m_stats; stats m_stats;
expr_ref_vector m_B; expr_ref_vector m_B;
@ -95,6 +107,8 @@ private:
strategy_t m_st; strategy_t m_st;
rational m_max_upper; rational m_max_upper;
model_ref m_csmodel; model_ref m_csmodel;
lns_maxres m_lnsctx;
lns m_lns;
unsigned m_correction_set_size; unsigned m_correction_set_size;
bool m_found_feasible_optimum; bool m_found_feasible_optimum;
bool m_hill_climb; // prefer large weight soft clauses for cores bool m_hill_climb; // prefer large weight soft clauses for cores
@ -125,6 +139,8 @@ public:
m_mus(c.get_solver()), m_mus(c.get_solver()),
m_trail(m), m_trail(m),
m_st(st), m_st(st),
m_lnsctx(*this),
m_lns(s(), m_lnsctx),
m_correction_set_size(0), m_correction_set_size(0),
m_found_feasible_optimum(false), m_found_feasible_optimum(false),
m_hill_climb(true), m_hill_climb(true),
@ -507,9 +523,10 @@ public:
void update_model(expr* def, expr* value) { void update_model(expr* def, expr* value) {
SASSERT(is_uninterp_const(def)); SASSERT(is_uninterp_const(def));
if (m_csmodel) { if (m_csmodel)
m_csmodel->register_decl(to_app(def)->get_decl(), (*m_csmodel)(value)); m_csmodel->register_decl(to_app(def)->get_decl(), (*m_csmodel)(value));
} if (m_model)
m_model->register_decl(to_app(def)->get_decl(), (*m_model)(value));
} }
void process_unsat(exprs const& core, rational w) { void process_unsat(exprs const& core, rational w) {
@ -729,7 +746,7 @@ public:
fml = m.mk_and(b_i1, cls); fml = m.mk_and(b_i1, cls);
update_model(asum, fml); update_model(asum, fml);
} }
fml = m.mk_or(cs.size(), cs.c_ptr()); fml = m.mk_or(cs);
add(fml); add(fml);
} }
@ -742,21 +759,13 @@ public:
update_assignment(mdl); update_assignment(mdl);
} }
void improve_model(model_ref& mdl) { void improve_model(model_ref& mdl) {
if (!m_enable_lns) if (!m_enable_lns)
return; return;
flet<bool> _disable_lns(m_enable_lns, false); flet<bool> _disable_lns(m_enable_lns, false);
std::function<void(model_ref&)> update_model = [&](model_ref& mdl) { m_lns.climb(mdl);
update_assignment(mdl);
};
std::function<void(vector<expr_ref_vector> const&)> _relax_cores = [&](vector<expr_ref_vector> const& cores) {
relax_cores(cores);
};
lns lns(s(), update_model);
lns.set_conflicts(m_lns_conflicts);
lns.set_relax(_relax_cores);
lns.climb(mdl, m_asms);
} }
void relax_cores(vector<expr_ref_vector> const& cores) { void relax_cores(vector<expr_ref_vector> const& cores) {
@ -770,6 +779,13 @@ public:
process_unsat(wcores); process_unsat(wcores);
} }
rational cost(model& mdl) {
rational upper(0);
for (soft& s : m_soft)
if (!mdl.is_true(s.s))
upper += s.weight;
return upper;
}
void update_assignment(model_ref & mdl) { void update_assignment(model_ref & mdl) {
improve_model(mdl); improve_model(mdl);
@ -787,14 +803,7 @@ public:
TRACE("opt_verbose", tout << *mdl;); TRACE("opt_verbose", tout << *mdl;);
rational upper(0); rational upper = cost(*mdl);
for (soft& s : m_soft) {
TRACE("opt", tout << s.s << ": " << (*mdl)(s.s) << " " << s.weight << "\n";);
if (!mdl->is_true(s.s)) {
upper += s.weight;
}
}
if (upper > m_upper) { if (upper > m_upper) {
TRACE("opt", tout << "new upper: " << upper << " vs existing upper: " << m_upper << "\n";); TRACE("opt", tout << "new upper: " << upper << " vs existing upper: " << m_upper << "\n";);

View file

@ -25,12 +25,12 @@ Author:
namespace opt { namespace opt {
lns::lns(solver& s, std::function<void(model_ref& mdl)>& update_model) lns::lns(solver& s, lns_context& ctx)
: m(s.get_manager()), : m(s.get_manager()),
s(s), s(s),
ctx(ctx),
m_hardened(m), m_hardened(m),
m_soft(m), m_unprocessed(m)
m_update_model(update_model)
{} {}
void lns::set_lns_params() { void lns::set_lns_params() {
@ -39,7 +39,7 @@ namespace opt {
p.set_uint("restart.initial", 1000000); p.set_uint("restart.initial", 1000000);
p.set_uint("max_conflicts", m_max_conflicts); p.set_uint("max_conflicts", m_max_conflicts);
p.set_uint("simplify.delay", 1000000); p.set_uint("simplify.delay", 1000000);
// p.set_bool("gc.burst", true); // p.set_bool("gc.burst", true);
s.updt_params(p); s.updt_params(p);
} }
@ -52,17 +52,99 @@ namespace opt {
p.set_uint("gc.burst", sp.gc_burst()); p.set_uint("gc.burst", sp.gc_burst());
} }
unsigned lns::climb(model_ref& mdl, expr_ref_vector const& asms) { unsigned lns::climb(model_ref& mdl) {
IF_VERBOSE(1, verbose_stream() << "(opt.lns :climb)\n");
m_num_improves = 0; m_num_improves = 0;
params_ref old_p(s.get_params()); params_ref old_p(s.get_params());
save_defaults(old_p); save_defaults(old_p);
set_lns_params(); set_lns_params();
setup_assumptions(mdl, asms); update_best_model(mdl);
unsigned num_improved = improve_linear(mdl); for (unsigned i = 0; i < 2; ++i)
// num_improved += improve_rotate(mdl, asms); improve_bs();
IF_VERBOSE(1, verbose_stream() << "(opt.lns :relax-cores " << m_cores.size() << ")\n");
relax_cores();
s.updt_params(old_p); s.updt_params(old_p);
IF_VERBOSE(1, verbose_stream() << "(opt.lns :num-improves " << m_num_improves << " :remaining-soft " << m_soft.size() << ")\n"); IF_VERBOSE(1, verbose_stream() << "(opt.lns :num-improves " << m_num_improves << ")\n");
return num_improved; return m_num_improves;
}
void lns::update_best_model(model_ref& mdl) {
rational cost = ctx.cost(*mdl);
if (m_best_cost.is_zero() || m_best_cost >= cost) {
m_best_cost = cost;
m_best_model = mdl;
m_best_phase = s.get_phase();
m_best_bound = 0;
for (expr* e : ctx.soft())
if (!mdl->is_true(e))
m_best_bound += 1;
}
}
void lns::apply_best_model() {
s.set_phase(m_best_phase.get());
for (expr* e : m_unprocessed) {
s.move_to_front(e);
s.set_phase(e);
}
}
void lns::improve_bs() {
m_unprocessed.reset();
m_unprocessed.append(ctx.soft());
m_hardened.reset();
for (expr* a : ctx.soft())
m_is_assumption.mark(a);
shuffle(m_unprocessed.size(), m_unprocessed.c_ptr(), m_rand);
model_ref mdl = m_best_model->copy();
unsigned j = 0;
for (unsigned i = 0; i < m_unprocessed.size(); ++i) {
if (mdl->is_false(unprocessed(i))) {
expr_ref tmp(m_unprocessed.get(j), m);
m_unprocessed[j++] = m_unprocessed[i];
m_unprocessed[i] = tmp;
break;
}
}
for (unsigned i = j; i < m_unprocessed.size(); ++i) {
if (mdl->is_true(unprocessed(i))) {
expr_ref tmp(m_unprocessed.get(j), m);
m_unprocessed[j++] = m_unprocessed[i];
m_unprocessed[i] = tmp;
}
}
for (unsigned i = 0; i < 3 && !m_unprocessed.empty(); ++i)
improve_bs1();
}
void lns::improve_bs1() {
model_ref mdl = m_best_model->copy();
unsigned j = 0;
for (expr* e : m_unprocessed) {
if (!m.inc())
return;
if (mdl->is_true(e))
m_hardened.push_back(e);
else {
apply_best_model();
switch (improve_step(mdl, e)) {
case l_true:
m_hardened.push_back(e);
ctx.update_model(mdl);
update_best_model(mdl);
break;
case l_false:
m_hardened.push_back(m.mk_not(e));
break;
case l_undef:
m_unprocessed[j++] = e;
break;
}
}
}
m_unprocessed.shrink(j);
} }
struct lns::scoped_bounding { struct lns::scoped_bounding {
@ -72,12 +154,13 @@ namespace opt {
scoped_bounding(lns& l):m_lns(l) { scoped_bounding(lns& l):m_lns(l) {
if (!m_lns.m_enable_scoped_bounding) if (!m_lns.m_enable_scoped_bounding)
return; return;
if (m_lns.m_best_bound == 0)
return;
m_cores_are_valid = m_lns.m_cores_are_valid; m_cores_are_valid = m_lns.m_cores_are_valid;
m_lns.m_cores_are_valid = false; m_lns.m_cores_are_valid = false;
m_lns.s.push(); m_lns.s.push();
pb_util pb(m_lns.m); pb_util pb(m_lns.m);
// TBD: bound should to be adjusted for current best solution, not number of soft constraints left. expr_ref bound(pb.mk_at_most_k(m_lns.ctx.soft(), m_lns.m_best_bound - 1), m_lns.m);
expr_ref bound(pb.mk_at_most_k(m_lns.m_soft, m_lns.m_soft.size() - 1), m_lns.m);
m_lns.s.assert_expr(bound); m_lns.s.assert_expr(bound);
} }
~scoped_bounding() { ~scoped_bounding() {
@ -89,7 +172,7 @@ namespace opt {
}; };
void lns::relax_cores() { void lns::relax_cores() {
if (!m_cores.empty() && m_relax_cores && m_cores_are_valid) { if (!m_cores.empty() && m_cores_are_valid) {
std::sort(m_cores.begin(), m_cores.end(), [&](expr_ref_vector const& a, expr_ref_vector const& b) { return a.size() < b.size(); }); std::sort(m_cores.begin(), m_cores.end(), [&](expr_ref_vector const& a, expr_ref_vector const& b) { return a.size() < b.size(); });
unsigned num_disjoint = 0; unsigned num_disjoint = 0;
vector<expr_ref_vector> new_cores; vector<expr_ref_vector> new_cores;
@ -104,43 +187,14 @@ namespace opt {
new_cores.push_back(c); new_cores.push_back(c);
++num_disjoint; ++num_disjoint;
} }
m_relax_cores(new_cores); IF_VERBOSE(2, verbose_stream() << "num cores: " << m_cores.size() << " new cores: " << new_cores.size() << "\n");
ctx.relax_cores(new_cores);
} }
m_in_core.reset(); m_in_core.reset();
m_is_assumption.reset(); m_is_assumption.reset();
m_cores.reset(); m_cores.reset();
} }
void lns::setup_assumptions(model_ref& mdl, expr_ref_vector const& asms) {
m_hardened.reset();
m_soft.reset();
for (expr* a : asms) {
m_is_assumption.mark(a);
if (mdl->is_true(a))
m_hardened.push_back(a);
else
m_soft.push_back(a);
}
}
unsigned lns::improve_rotate(model_ref& mdl, expr_ref_vector const& asms) {
unsigned num_improved = 0;
repeat:
setup_assumptions(mdl, asms);
unsigned sz = m_hardened.size();
for (unsigned i = 0; i < sz; ++i) {
expr_ref tmp(m_hardened.get(i), m);
m_hardened[i] = m.mk_not(tmp);
unsigned reward = improve_linear(mdl);
if (reward > 1) {
num_improved += (reward - 1);
goto repeat;
}
setup_assumptions(mdl, asms);
}
return num_improved;
}
unsigned lns::improve_linear(model_ref& mdl) { unsigned lns::improve_linear(model_ref& mdl) {
scoped_bounding _scoped_bouding(*this); scoped_bounding _scoped_bouding(*this);
unsigned num_improved = 0; unsigned num_improved = 0;
@ -156,43 +210,42 @@ namespace opt {
set_lns_params(); set_lns_params();
} }
m_max_conflicts = max_conflicts; m_max_conflicts = max_conflicts;
relax_cores();
return num_improved; return num_improved;
} }
unsigned lns::improve_step(model_ref& mdl) { unsigned lns::improve_step(model_ref& mdl) {
unsigned num_improved = 0; unsigned num_improved = 0;
for (unsigned i = 0; m.inc() && i < m_soft.size(); ++i) { for (unsigned i = 0; m.inc() && i < m_unprocessed.size(); ++i) {
switch (improve_step(mdl, soft(i))) { switch (improve_step(mdl, unprocessed(i))) {
case l_undef: case l_undef:
break; break;
case l_false: case l_false:
TRACE("opt", tout << "pruned " << mk_bounded_pp(soft(i), m) << "\n";); TRACE("opt", tout << "pruned " << mk_bounded_pp(unprocessed(i), m) << "\n";);
m_hardened.push_back(m.mk_not(soft(i))); m_hardened.push_back(m.mk_not(unprocessed(i)));
for (unsigned k = i; k + 1 < m_soft.size(); ++k) for (unsigned k = i; k + 1 < m_unprocessed.size(); ++k)
m_soft[k] = soft(k + 1); m_unprocessed[k] = unprocessed(k + 1);
m_soft.pop_back(); m_unprocessed.pop_back();
--i; --i;
break; break;
case l_true: { case l_true: {
unsigned k = 0, offset = 0; unsigned k = 0, offset = 0;
for (unsigned j = 0; j < m_soft.size(); ++j) { for (unsigned j = 0; j < m_unprocessed.size(); ++j) {
if (mdl->is_true(soft(j))) { if (mdl->is_true(unprocessed(j))) {
if (j <= i) if (j <= i)
++offset; ++offset;
++m_num_improves; ++m_num_improves;
TRACE("opt", tout << "improved " << mk_bounded_pp(soft(j), m) << "\n";); TRACE("opt", tout << "improved " << mk_bounded_pp(unprocessed(j), m) << "\n";);
m_hardened.push_back(soft(j)); m_hardened.push_back(unprocessed(j));
++num_improved; ++num_improved;
} }
else { else {
m_soft[k++] = soft(j); m_unprocessed[k++] = unprocessed(j);
} }
} }
m_soft.shrink(k); m_unprocessed.shrink(k);
i -= offset; i -= offset;
IF_VERBOSE(1, verbose_stream() << "(opt.lns :num-improves " << m_num_improves << " :remaining-soft " << m_soft.size() << ")\n"); IF_VERBOSE(1, verbose_stream() << "(opt.lns :num-improves " << m_num_improves << " :remaining-soft " << m_unprocessed.size() << ")\n");
m_update_model(mdl); ctx.update_model(mdl);
break; break;
} }
} }
@ -209,12 +262,12 @@ namespace opt {
if (r == l_false) { if (r == l_false) {
expr_ref_vector core(m); expr_ref_vector core(m);
s.get_unsat_core(core); s.get_unsat_core(core);
bool all_assumed = true; bool all_assumed = true;
for (expr* c : core) for (expr* c : core)
all_assumed &= m_is_assumption.is_marked(c); all_assumed &= m_is_assumption.is_marked(c);
if (all_assumed) { IF_VERBOSE(2, verbose_stream() << "core " << all_assumed << " - " << core.size() << "\n");
m_cores.push_back(core); if (all_assumed)
} m_cores.push_back(core);
} }
return r; return r;
} }

View file

@ -26,39 +26,55 @@ Author:
namespace opt { namespace opt {
class lns_context {
public:
virtual ~lns_context() {}
virtual void update_model(model_ref& mdl) = 0;
virtual void relax_cores(vector<expr_ref_vector> const& cores) = 0;
virtual rational cost(model& mdl) = 0;
virtual rational weight(expr* e) = 0;
virtual expr_ref_vector const& soft() = 0;
};
class lns { class lns {
ast_manager& m; ast_manager& m;
solver& s; solver& s;
lns_context& ctx;
random_gen m_rand;
expr_ref_vector m_hardened; expr_ref_vector m_hardened;
expr_ref_vector m_soft; expr_ref_vector m_unprocessed;
unsigned m_max_conflicts { 1000 }; unsigned m_max_conflicts { 10000 };
unsigned m_num_improves { 0 }; unsigned m_num_improves { 0 };
bool m_cores_are_valid { true }; bool m_cores_are_valid { true };
bool m_enable_scoped_bounding { false }; bool m_enable_scoped_bounding { false };
unsigned m_best_bound { 0 };
rational m_best_cost;
model_ref m_best_model;
scoped_ptr<solver::phase> m_best_phase;
vector<expr_ref_vector> m_cores; vector<expr_ref_vector> m_cores;
expr_mark m_in_core; expr_mark m_in_core;
expr_mark m_is_assumption; expr_mark m_is_assumption;
struct scoped_bounding; struct scoped_bounding;
std::function<void(model_ref& m)> m_update_model; void update_best_model(model_ref& mdl);
std::function<void(vector<expr_ref_vector> const&)> m_relax_cores; void improve_bs();
void improve_bs1();
void apply_best_model();
expr* soft(unsigned i) const { return m_soft[i]; } expr* unprocessed(unsigned i) const { return m_unprocessed[i]; }
void set_lns_params(); void set_lns_params();
void save_defaults(params_ref& p); void save_defaults(params_ref& p);
unsigned improve_step(model_ref& mdl); unsigned improve_step(model_ref& mdl);
lbool improve_step(model_ref& mdl, expr* e); lbool improve_step(model_ref& mdl, expr* e);
void relax_cores(); void relax_cores();
unsigned improve_linear(model_ref& mdl); unsigned improve_linear(model_ref& mdl);
unsigned improve_rotate(model_ref& mdl, expr_ref_vector const& asms);
void setup_assumptions(model_ref& mdl, expr_ref_vector const& asms);
public: public:
lns(solver& s, std::function<void(model_ref&)>& update_model); lns(solver& s, lns_context& ctx);
void set_relax(std::function<void(vector<expr_ref_vector> const&)>& rc) { m_relax_cores = rc; }
void set_conflicts(unsigned c) { m_max_conflicts = c; } void set_conflicts(unsigned c) { m_max_conflicts = c; }
unsigned climb(model_ref& mdl, expr_ref_vector const& asms); unsigned climb(model_ref& mdl);
}; };
}; };

View file

@ -110,7 +110,10 @@ namespace opt {
void get_levels(ptr_vector<expr> const& vars, unsigned_vector& depth) override; void get_levels(ptr_vector<expr> const& vars, unsigned_vector& depth) override;
expr_ref_vector get_trail() override { return m_context.get_trail(); } expr_ref_vector get_trail() override { return m_context.get_trail(); }
expr_ref_vector cube(expr_ref_vector&, unsigned) override { return expr_ref_vector(m); } expr_ref_vector cube(expr_ref_vector&, unsigned) override { return expr_ref_vector(m); }
void set_phase(expr* e) override { NOT_IMPLEMENTED_YET(); } void set_phase(expr* e) override { m_context.set_phase(e); }
phase* get_phase() override { return m_context.get_phase(); }
void set_phase(phase* p) override { m_context.set_phase(p); }
void move_to_front(expr* e) override { m_context.move_to_front(e); }
void set_logic(symbol const& logic); void set_logic(symbol const& logic);

View file

@ -1914,7 +1914,8 @@ namespace sat {
m_next_simplify = m_config.m_simplify_delay; m_next_simplify = m_config.m_simplify_delay;
m_min_d_tk = 1.0; m_min_d_tk = 1.0;
m_search_lvl = 0; m_search_lvl = 0;
m_conflicts_since_gc = 0; if (m_learned.size() <= 2*m_clauses.size())
m_conflicts_since_gc = 0;
m_restart_next_out = 0; m_restart_next_out = 0;
m_asymm_branch.init_search(); m_asymm_branch.init_search();
m_stopwatch.reset(); m_stopwatch.reset();
@ -3784,6 +3785,14 @@ namespace sat {
} }
} }
void solver::move_to_front(bool_var b) {
if (b >= num_vars())
return;
bool_var next = m_case_split_queue.min_var();
auto next_act = m_activity[next];
set_activity(b, next_act + 1);
}
// ----------------------- // -----------------------
// //
// Iterators // Iterators

View file

@ -352,8 +352,9 @@ namespace sat {
bool was_eliminated(bool_var v) const { return m_eliminated[v]; } bool was_eliminated(bool_var v) const { return m_eliminated[v]; }
void set_eliminated(bool_var v, bool f) override; void set_eliminated(bool_var v, bool f) override;
bool was_eliminated(literal l) const { return was_eliminated(l.var()); } bool was_eliminated(literal l) const { return was_eliminated(l.var()); }
void set_phase(literal l) override { m_best_phase[l.var()] = m_phase[l.var()] = !l.sign(); } void set_phase(literal l) override { if (l.var() < num_vars()) m_best_phase[l.var()] = m_phase[l.var()] = !l.sign(); }
void set_phase(bool_var b, bool sign) { set_phase(literal(b, sign)); } bool_var get_phase(bool_var b) { return m_phase.get(b, false); }
void move_to_front(bool_var b);
unsigned scope_lvl() const { return m_scope_lvl; } unsigned scope_lvl() const { return m_scope_lvl; }
unsigned search_lvl() const { return m_search_lvl; } unsigned search_lvl() const { return m_search_lvl; }
bool at_search_lvl() const { return m_scope_lvl == m_search_lvl; } bool at_search_lvl() const { return m_scope_lvl == m_search_lvl; }

View file

@ -298,7 +298,27 @@ public:
bool is_not = m.is_not(e, e); bool is_not = m.is_not(e, e);
sat::bool_var b = m_map.to_bool_var(e); sat::bool_var b = m_map.to_bool_var(e);
if (b != sat::null_bool_var) if (b != sat::null_bool_var)
m_solver.set_phase(b, is_not); m_solver.set_phase(sat::literal(b, is_not));
}
class sat_phase : public phase, public sat::literal_vector {};
phase* get_phase() override {
sat_phase* p = alloc(sat_phase);
for (unsigned v = m_solver.num_vars(); v-- > 0; ) {
p->push_back(sat::literal(v, !m_solver.get_phase(v)));
}
return p;
}
void set_phase(phase* p) override {
for (auto lit : *static_cast<sat_phase*>(p))
m_solver.set_phase(lit);
}
void move_to_front(expr* e) override {
bool is_not = m.is_not(e, e);
sat::bool_var b = m_map.to_bool_var(e);
if (b != sat::null_bool_var)
m_solver.move_to_front(b);
} }
unsigned get_scope_level() const override { unsigned get_scope_level() const override {

View file

@ -150,6 +150,11 @@ namespace smt {
*/ */
lbool preferred_sat(expr_ref_vector const& asms, vector<expr_ref_vector>& cores); lbool preferred_sat(expr_ref_vector const& asms, vector<expr_ref_vector>& cores);
void set_phase(expr * e) { NOT_IMPLEMENTED_YET(); }
solver::phase* get_phase() { NOT_IMPLEMENTED_YET(); return nullptr; }
void set_phase(solver::phase* p) { NOT_IMPLEMENTED_YET(); }
void move_to_front(expr* e) { NOT_IMPLEMENTED_YET(); }
/** /**
\brief Return the model associated with the last check command. \brief Return the model associated with the last check command.
*/ */

View file

@ -158,9 +158,10 @@ namespace {
void assert_expr_core(expr * t) override { void assert_expr_core(expr * t) override {
m_context.assert_expr(t); m_context.assert_expr(t);
} }
void set_phase(expr* e) override { void set_phase(expr* e) override { m_context.set_phase(e); }
NOT_IMPLEMENTED_YET(); phase* get_phase() override { return m_context.get_phase(); }
} void set_phase(phase* p) override { m_context.set_phase(p); }
void move_to_front(expr* e) override { m_context.move_to_front(e); }
void assert_expr_core2(expr * t, expr * a) override { void assert_expr_core2(expr * t, expr * a) override {
if (m_name2assertion.contains(a)) { if (m_name2assertion.contains(a)) {

View file

@ -136,6 +136,9 @@ public:
} }
void set_phase(expr* e) override { m_solver1->set_phase(e); m_solver2->set_phase(e); } void set_phase(expr* e) override { m_solver1->set_phase(e); m_solver2->set_phase(e); }
solver::phase* get_phase() override { auto* p = m_solver1->get_phase(); if (!p) p = m_solver2->get_phase(); return p; }
void set_phase(solver::phase* p) override { m_solver1->set_phase(p); m_solver2->set_phase(p); }
void move_to_front(expr* e) override { m_solver1->move_to_front(e); m_solver2->move_to_front(e); }
void updt_params(params_ref const & p) override { void updt_params(params_ref const & p) override {
solver::updt_params(p); solver::updt_params(p);

View file

@ -112,6 +112,14 @@ public:
} }
virtual void set_phase(expr* e) = 0; virtual void set_phase(expr* e) = 0;
virtual void move_to_front(expr* e) = 0;
class phase { public: virtual ~phase() {} };
virtual phase* get_phase() = 0;
virtual void set_phase(phase* p) = 0;
void assert_expr(ptr_vector<expr> const& ts) { void assert_expr(ptr_vector<expr> const& ts) {
for (expr* e : ts) assert_expr(e); for (expr* e : ts) assert_expr(e);

View file

@ -69,6 +69,9 @@ public:
solver* base_solver() { return m_base.get(); } solver* base_solver() { return m_base.get(); }
void set_phase(expr* e) override { m_base->set_phase(e); } void set_phase(expr* e) override { m_base->set_phase(e); }
phase* get_phase() override { return m_base->get_phase(); }
void set_phase(phase* p) override { m_base->set_phase(p); }
void move_to_front(expr* e) override { m_base->move_to_front(e); }
solver* translate(ast_manager& m, params_ref const& p) override { UNREACHABLE(); return nullptr; } solver* translate(ast_manager& m, params_ref const& p) override { UNREACHABLE(); return nullptr; }
void updt_params(params_ref const& p) override { void updt_params(params_ref const& p) override {

View file

@ -80,6 +80,9 @@ public:
unsigned get_num_assertions() const override; unsigned get_num_assertions() const override;
expr * get_assertion(unsigned idx) const override; expr * get_assertion(unsigned idx) const override;
void set_phase(expr* e) override { } void set_phase(expr* e) override { }
phase* get_phase() override { return nullptr; }
void set_phase(phase* p) override { }
void move_to_front(expr* e) override { }
expr_ref_vector cube(expr_ref_vector& vars, unsigned ) override { expr_ref_vector cube(expr_ref_vector& vars, unsigned ) override {

View file

@ -152,6 +152,9 @@ public:
void collect_statistics(statistics & st) const override { m_solver->collect_statistics(st); } void collect_statistics(statistics & st) const override { m_solver->collect_statistics(st); }
void get_unsat_core(expr_ref_vector & r) override { m_solver->get_unsat_core(r); } void get_unsat_core(expr_ref_vector & r) override { m_solver->get_unsat_core(r); }
void set_phase(expr* e) override { m_solver->set_phase(e); } void set_phase(expr* e) override { m_solver->set_phase(e); }
phase* get_phase() override { return m_solver->get_phase(); }
void set_phase(phase* p) override { m_solver->set_phase(p); }
void move_to_front(expr* e) override { m_solver->move_to_front(e); }
void get_model_core(model_ref & mdl) override { void get_model_core(model_ref & mdl) override {
m_solver->get_model(mdl); m_solver->get_model(mdl);
if (mdl) { if (mdl) {

View file

@ -90,6 +90,9 @@ public:
void collect_statistics(statistics & st) const override { m_solver->collect_statistics(st); } void collect_statistics(statistics & st) const override { m_solver->collect_statistics(st); }
void get_unsat_core(expr_ref_vector & r) override { m_solver->get_unsat_core(r); } void get_unsat_core(expr_ref_vector & r) override { m_solver->get_unsat_core(r); }
void set_phase(expr* e) override { m_solver->set_phase(e); } void set_phase(expr* e) override { m_solver->set_phase(e); }
phase* get_phase() override { return m_solver->get_phase(); }
void set_phase(phase* p) override { m_solver->set_phase(p); }
void move_to_front(expr* e) override { m_solver->move_to_front(e); }
void get_model_core(model_ref & mdl) override { void get_model_core(model_ref & mdl) override {
m_solver->get_model(mdl); m_solver->get_model(mdl);
if (mdl) { if (mdl) {

View file

@ -97,6 +97,9 @@ public:
} }
} }
void set_phase(expr* e) override { m_solver->set_phase(e); } void set_phase(expr* e) override { m_solver->set_phase(e); }
phase* get_phase() override { return m_solver->get_phase(); }
void set_phase(phase* p) override { m_solver->set_phase(p); }
void move_to_front(expr* e) override { m_solver->move_to_front(e); }
void get_levels(ptr_vector<expr> const& vars, unsigned_vector& depth) override { void get_levels(ptr_vector<expr> const& vars, unsigned_vector& depth) override {
m_solver->get_levels(vars, depth); m_solver->get_levels(vars, depth);

View file

@ -2032,6 +2032,9 @@ namespace smtfd {
} }
void set_phase(expr* e) override {} void set_phase(expr* e) override {}
phase* get_phase() override { return nullptr; }
void set_phase(phase* p) override { }
void move_to_front(expr* e) override { }
void updt_params(params_ref const & p) override { void updt_params(params_ref const & p) override {
::solver::updt_params(p); ::solver::updt_params(p);