3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-04-24 01:25:31 +00:00

add bvmax tactic, add proviso for non-0 lower bounds in elim01

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
Nikolaj Bjorner 2014-03-23 18:03:20 -07:00
parent ea261c930d
commit 0181f0f9df
8 changed files with 121 additions and 14 deletions

View file

@ -122,8 +122,7 @@ namespace opt {
virtual void get_unsat_core(ptr_vector<expr> & r) {}
virtual std::string reason_unknown() const { return std::string("unknown"); }
void display_assignment(std::ostream& out);
void display_range_assignment(std::ostream& out);
virtual void display_assignment(std::ostream& out);
static void collect_param_descrs(param_descrs & r);
void updt_params(params_ref& p);

View file

@ -44,6 +44,7 @@ namespace opt {
m_logic = l;
if (m_logic != symbol::null)
m_context.set_logic(m_logic);
m_params.m_relevancy_lvl = 0;
}
unsigned opt_solver::m_dump_count = 0;

View file

@ -29,6 +29,9 @@ Notes:
#include "tactic.h"
#include "model_smt2_pp.h"
#include "pb_sls.h"
#include "qfbv_tactic.h"
#include "card2bv_tactic.h"
#include "tactic2solver.h"
namespace smt {
@ -450,6 +453,7 @@ namespace opt {
volatile bool m_cancel;
params_ref m_params;
opt_solver m_solver;
ref<solver> m_sat_solver;
scoped_ptr<imp> m_imp;
smt::pb_sls m_sls;
@ -511,6 +515,9 @@ namespace opt {
if (m_engine == symbol("pwmax")) {
return pb_solve();
}
if (m_engine == symbol("bvmax")) {
return pb2sat_solve();
}
if (m_engine == symbol("wpm2")) {
return wpm2_solve();
}
@ -520,7 +527,11 @@ namespace opt {
if (m_engine == symbol("sls")) {
return sls_solve();
}
return incremental_solve();
if (m_engine == symbol::null || m_engine == symbol("wmax")) {
return incremental_solve();
}
IF_VERBOSE(0, verbose_stream() << "(unknown engine " << m_engine << " using default 'wmax')\n";);
return incremental_solve();
}
rational get_lower() const {
@ -535,6 +546,25 @@ namespace opt {
mdl = m_model.get();
}
void set_cancel(bool f) {
if (m_sat_solver) {
m_sat_solver->set_cancel(f);
}
m_sls.set_cancel(f);
m_cancel = f;
m_solver.set_cancel(f);
m_imp->m_cancel = f;
m_imp->m_solver.set_cancel(f);
}
void collect_statistics(statistics& st) const {
m_solver.collect_statistics(st);
if (m_sat_solver) {
m_sat_solver->collect_statistics(st);
}
}
class scoped_ensure_theory {
smt::theory_weighted_maxsat* m_wth;
public:
@ -732,7 +762,6 @@ namespace opt {
// convert bounds constraint into pseudo-Boolean
lbool pb_solve() {
pb_util u(m);
expr_ref fml(m), val(m);
@ -778,6 +807,63 @@ namespace opt {
return is_sat;
}
//
// convert bounds constraint into pseudo-Boolean,
// then treat pseudo-Booleans as bit-vectors and
// sorting circuits.
//
lbool pb2sat_solve() {
pb_util u(m);
expr_ref fml(m), val(m);
app_ref b(m);
expr_ref_vector nsoft(m);
m_lower = m_upper = rational::zero();
tactic_ref pb2bv = mk_card2bv_tactic(m, m_params);
tactic_ref bv2sat = mk_qfbv_tactic(m, m_params);
tactic_ref tac = and_then(pb2bv.get(), bv2sat.get());
m_sat_solver = mk_tactic2solver(m, tac.get(), m_params);
unsigned sz = s.get_num_assertions();
for (unsigned i = 0; i < sz; ++i) {
m_sat_solver->assert_expr(s.get_assertion(i));
}
for (unsigned i = 0; i < m_soft.size(); ++i) {
m_upper += m_weights[i];
b = m.mk_fresh_const("b", m.mk_bool_sort());
// TODO: s.mc().insert(b->get_decl());
fml = m.mk_or(m_soft[i].get(), b);
m_sat_solver->assert_expr(fml);
nsoft.push_back(b);
}
lbool is_sat = l_true;
bool was_sat = false;
while (l_true == is_sat) {
is_sat = m_sat_solver->check_sat(0,0);
if (m_cancel) {
is_sat = l_undef;
}
if (is_sat == l_true) {
m_sat_solver->get_model(m_model);
m_upper = rational::zero();
for (unsigned i = 0; i < m_soft.size(); ++i) {
VERIFY(m_model->eval(nsoft[i].get(), val));
m_assignment[i] = !m.is_true(val);
if (!m_assignment[i]) {
m_upper += m_weights[i];
}
}
IF_VERBOSE(1, verbose_stream() << "(wmaxsat.pb with upper bound: " << m_upper << ")\n";);
fml = m.mk_not(u.mk_ge(nsoft.size(), m_weights.c_ptr(), nsoft.c_ptr(), m_upper));
m_sat_solver->assert_expr(fml);
was_sat = true;
}
}
if (is_sat == l_false && was_sat) {
is_sat = l_true;
m_lower = m_upper;
}
return is_sat;
}
expr* mk_not(expr* e) {
if (m.is_not(e, e)) {
return e;
@ -1285,14 +1371,10 @@ namespace opt {
return m_imp->m_assignment[idx];
}
void wmaxsmt::set_cancel(bool f) {
m_imp->m_sls.set_cancel(f);
m_imp->m_cancel = f;
m_imp->m_solver.set_cancel(f);
m_imp->m_imp->m_cancel = f;
m_imp->m_imp->m_solver.set_cancel(f);
m_imp->set_cancel(f);
}
void wmaxsmt::collect_statistics(statistics& st) const {
m_imp->m_solver.collect_statistics(st);
m_imp->collect_statistics(st);
}
void wmaxsmt::get_model(model_ref& mdl) {
m_imp->get_model(mdl);