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

tuning pb/max

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
Nikolaj Bjorner 2014-05-06 04:01:10 -07:00
parent 7ade3f2c04
commit d2db8007d8
9 changed files with 79 additions and 39 deletions

View file

@ -116,6 +116,15 @@ namespace opt {
// if (m_bvsls) m_bvsls->display(out);
}
void opt(model_ref& mdl) {
if (m_engine == symbol("pb")) {
pbsls_opt(mdl);
}
else {
bvsls_opt(mdl);
}
}
protected:
typedef bvsls_opt_engine::optimization_result opt_result;
@ -123,12 +132,7 @@ namespace opt {
lbool r = m_solver->check_sat(num_assumptions, assumptions);
if (r == l_true) {
m_solver->get_model(m_model);
if (m_engine == symbol("pb")) {
pbsls_opt();
}
else {
bvsls_opt();
}
opt(m_model);
}
return r;
}
@ -191,7 +195,7 @@ namespace opt {
}
}
void pbsls_opt() {
void pbsls_opt(model_ref& mdl) {
#pragma omp critical (sls_solver)
{
if (m_pbsls) {
@ -201,7 +205,7 @@ namespace opt {
m_pbsls = alloc(smt::pb_sls, m);
}
}
m_pbsls->set_model(m_model);
m_pbsls->set_model(mdl);
m_pbsls->updt_params(m_params);
for (unsigned i = 0; i < m_solver->get_num_assertions(); ++i) {
m_pbsls->add(m_solver->get_assertion(i));
@ -213,7 +217,7 @@ namespace opt {
m_pbsls->get_model(m_model);
}
void bvsls_opt() {
void bvsls_opt(model_ref& mdl) {
#pragma omp critical (sls_solver)
{
m_bvsls = alloc(bvsls_opt_engine, m, m_params);
@ -223,7 +227,7 @@ namespace opt {
opt_result res(m);
res.is_sat = l_undef;
try {
res = m_bvsls->optimize(objective, m_model, true);
res = m_bvsls->optimize(objective, mdl, true);
}
catch (...) {

View file

@ -43,8 +43,10 @@ namespace opt {
m_dump_benchmarks(false),
m_fm(alloc(filter_model_converter, m)) {
m_logic = l;
if (m_logic != symbol::null)
if (m_logic != symbol::null) {
m_context.set_logic(m_logic);
}
m_params.updt_params(p);
m_params.m_relevancy_lvl = 0;
}

View file

@ -66,7 +66,10 @@ namespace opt {
maxsmt_solver_base(solver* s, ast_manager& m):
m_s(s), m(m), m_cancel(false), m_soft(m),
m_enable_sls(false), m_enable_sat(false),
m_sls_enabled(false), m_sat_enabled(false) {}
m_sls_enabled(false), m_sat_enabled(false) {
m_s->get_model(m_model);
SASSERT(m_model);
}
virtual ~maxsmt_solver_base() {}
virtual rational get_lower() const { return m_lower; }
@ -173,9 +176,11 @@ namespace opt {
if (m_enable_sls && !m_sls_enabled && probe_bv()) {
m_params.set_uint("restarts", 20);
unsigned lvl = m_s->get_scope_level();
m_s = alloc(sls_solver, m, m_s.get(), m_soft, m_weights, m_params);
sls_solver* sls = alloc(sls_solver, m, m_s.get(), m_soft, m_weights, m_params);
m_s = sls;
while (lvl > 0) { m_s->push(); --lvl; }
m_sls_enabled = true;
sls->opt(m_model);
}
}
@ -598,9 +603,21 @@ namespace opt {
}
}
lbool is_sat = l_true;
bool was_sat = false;
fml = m.mk_true();
while (l_true == is_sat) {
IF_VERBOSE(1, verbose_stream() << "(wmaxsat.pb solve with upper bound: " << m_upper << ")\n";);
m_upper.reset();
for (unsigned i = 0; i < m_soft.size(); ++i) {
VERIFY(m_model->eval(nsoft[i].get(), val));
TRACE("opt", tout << "eval " << mk_pp(m_soft[i].get(), m) << " " << val << "\n";);
m_assignment[i] = !m.is_true(val);
if (!m_assignment[i]) {
m_upper += m_weights[i];
}
}
TRACE("opt", tout << "new upper: " << m_upper << "\n";);
fml = u.mk_lt(nsoft.size(), m_weights.c_ptr(), nsoft.c_ptr(), m_upper);
TRACE("opt", s().display(tout<<"looping\n"););
solver::scoped_push _scope2(s());
s().assert_expr(fml);
@ -609,24 +626,10 @@ namespace opt {
is_sat = l_undef;
}
if (is_sat == l_true) {
m_upper.reset();
s().get_model(m_model);
for (unsigned i = 0; i < m_soft.size(); ++i) {
VERIFY(m_model->eval(nsoft[i].get(), val));
TRACE("opt", tout << "eval " << mk_pp(m_soft[i].get(), m) << " " << val << "\n";);
m_assignment[i] = !m.is_true(val);
if (!m_assignment[i]) {
m_upper += m_weights[i];
}
}
TRACE("opt", tout << "new upper: " << m_upper << "\n";);
IF_VERBOSE(1, verbose_stream() << "(wmaxsat.pb solve with upper bound: " << m_upper << ")\n";);
fml = m.mk_not(u.mk_ge(nsoft.size(), m_weights.c_ptr(), nsoft.c_ptr(), m_upper));
was_sat = true;
}
}
if (is_sat == l_false && was_sat) {
if (is_sat == l_false) {
is_sat = l_true;
m_lower = m_upper;
}