3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-04-15 21:38:44 +00:00
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
Nikolaj Bjorner 2015-04-28 14:48:59 -07:00
parent ffc3a36dcb
commit a0f0b53686
7 changed files with 80 additions and 45 deletions

View file

@ -388,7 +388,6 @@ namespace opt {
}
break;
case O_MAXSMT: {
m_opt_solver->ensure_pb();
pb_util pb(m);
unsigned sz = obj.m_terms.size();
ptr_vector<expr> terms;
@ -475,6 +474,9 @@ namespace opt {
m_opt_solver->set_logic(m_logic);
m_solver = m_opt_solver.get();
}
if (opt_params(m_params).priority() == symbol("pareto")) {
m_opt_solver->ensure_pb();
}
}
void context::setup_arith_solver() {
@ -497,6 +499,9 @@ namespace opt {
m_maxsat_engine != symbol("sls")) {
return;
}
if (opt_params(m_params).priority() == symbol("pareto")) {
return;
}
m_params.set_bool("minimize_core_partial", true); // false);
m_params.set_bool("minimize_core", true);
m_sat_solver = mk_inc_sat_solver(m, m_params);

View file

@ -204,39 +204,53 @@ namespace opt {
m_valid_objectives[i] = true;
TRACE("opt", tout << (has_shared?"has shared":"non-shared") << "\n";);
if (m_context.get_context().update_model(has_shared)) {
if (has_shared) {
val2 = current_objective_value(i);
if (val2 != val) {
if (has_shared && val != current_objective_value(i)) {
decrement_value(i, val);
}
else {
set_model(i);
}
}
else {
SASSERT(has_shared);
// model is not final. We set the current objective to
// close to the optimal (ignoring types).
decrement_value(i, val);
}
m_objective_values[i] = val;
TRACE("opt", { tout << val << "\n";
tout << blocker << "\n";
model_smt2_pp(tout << "update model:\n", m, *m_models[i], 0); });
}
void opt_solver::set_model(unsigned i) {
model_ref mdl;
get_model(mdl);
m_models.set(i, mdl.get());
TRACE("opt", { tout << m_objective_values[i] << "\n";
tout << blocker << "\n";
model_smt2_pp(tout << "update model:\n", m, *mdl, 0); });
}
void opt_solver::decrement_value(unsigned i, inf_eps& val) {
lbool opt_solver::decrement_value(unsigned i, inf_eps& val) {
push_core();
expr_ref ge = mk_ge(i, val);
TRACE("opt", tout << ge << "\n";);
assert_expr(ge);
lbool is_sat = m_context.check(0, 0);
if (is_sat == l_true) {
set_model(i);
}
pop_core(1);
TRACE("opt", tout << is_sat << "\n";);
if (is_sat != l_true) {
// cop-out approximation
if (arith_util(m).is_real(m_objective_sorts[i].get())) {
val -= inf_eps(inf_rational(rational(0),true));
val -= inf_eps(inf_rational(rational(0), true));
}
else {
val -= inf_eps(inf_rational(rational(1)));
}
m_valid_objectives[i] = false;
}
return is_sat;
}
void opt_solver::get_unsat_core(ptr_vector<expr> & r) {
@ -309,7 +323,6 @@ namespace opt {
return get_optimizer().value(v);
}
expr_ref opt_solver::mk_ge(unsigned var, inf_eps const& val) {
smt::theory_opt& opt = get_optimizer();
smt::theory_var v = m_objective_vars[var];

View file

@ -134,7 +134,8 @@ namespace opt {
char const * logic = "", char const * status = "unknown", char const * attributes = "");
private:
void decrement_value(unsigned i, inf_eps& val);
lbool decrement_value(unsigned i, inf_eps& val);
void set_model(unsigned i);
};
}

View file

@ -69,10 +69,19 @@ namespace opt {
lbool optsmt::basic_opt() {
lbool is_sat = l_true;
expr_ref bound(m.mk_true(), m), tmp(m);
expr* vars[1];
solver::scoped_push _push(*m_s);
while (is_sat == l_true && !m_cancel) {
is_sat = m_s->check_sat(0, 0);
tmp = m.mk_fresh_const("b", m.mk_bool_sort());
vars[0] = tmp;
bound = m.mk_implies(tmp, bound);
m_s->assert_expr(bound);
is_sat = m_s->check_sat(1, vars);
if (is_sat == l_true) {
update_lower();
bound = update_lower();
}
}
@ -125,17 +134,23 @@ namespace opt {
expr_ref_vector ors(m), disj(m);
expr_ref fml(m), bound(m.mk_true(), m);
expr_ref fml(m), bound(m.mk_true(), m), tmp(m);
expr* vars[1];
{
for (unsigned i = 0; i < m_upper.size(); ++i) {
ors.push_back(m_s->mk_ge(i, m_upper[i]));
}
{
solver::scoped_push _push(*m_s);
fml = m.mk_or(ors.size(), ors.c_ptr());
m_s->assert_expr(fml);
tmp = m.mk_fresh_const("b", m.mk_bool_sort());
fml = m.mk_implies(tmp, fml);
vars[0] = tmp;
lbool is_sat = l_true;
solver::scoped_push _push(*m_s);
while (!m_cancel) {
is_sat = m_s->check_sat(0,0);
m_s->assert_expr(fml);
is_sat = m_s->check_sat(1,vars);
if (is_sat == l_true) {
disj.reset();
m_s->maximize_objectives(disj);
@ -151,7 +166,9 @@ namespace opt {
}
set_max(m_lower, m_s->get_objective_values(), disj);
fml = m.mk_or(ors.size(), ors.c_ptr());
m_s->assert_expr(fml);
tmp = m.mk_fresh_const("b", m.mk_bool_sort());
fml = m.mk_implies(tmp, fml);
vars[0] = tmp;
}
else if (is_sat == l_undef) {
return l_undef;
@ -181,7 +198,7 @@ namespace opt {
m_upper[idx] = v;
}
void optsmt::update_lower() {
expr_ref optsmt::update_lower() {
expr_ref_vector disj(m);
m_s->get_model(m_model);
m_s->maximize_objectives(disj);
@ -201,9 +218,7 @@ namespace opt {
IF_VERBOSE(3, verbose_stream() << disj << "\n";);
IF_VERBOSE(3, model_pp(verbose_stream(), *m_model););
expr_ref constraint(m);
constraint = m.mk_or(disj.size(), disj.c_ptr());
m_s->assert_expr(constraint);
return expr_ref(m.mk_or(disj.size(), disj.c_ptr()), m);
}
lbool optsmt::update_upper() {
@ -243,7 +258,7 @@ namespace opt {
IF_VERBOSE(2, verbose_stream() << "(optsmt lower bound for v" << m_vars[i] << " := " << m_upper[i] << ")\n";);
m_lower[i] = mid[i];
th.enable_record_conflict(0);
update_lower();
m_s->assert_expr(update_lower());
break;
case l_false:
IF_VERBOSE(2, verbose_stream() << "(optsmt conflict: " << th.conflict_minimize() << ") \n";);

View file

@ -80,7 +80,7 @@ namespace opt {
void set_max(vector<inf_eps>& dst, vector<inf_eps> const& src, expr_ref_vector& fmls);
void update_lower();
expr_ref update_lower();
lbool update_upper();

View file

@ -19,7 +19,7 @@ Notes:
#include"tactical.h"
#include"bit_blaster_model_converter.h"
#include"bit_blaster_rewriter.h"
#include"ast_smt2_pp.h"
#include"ast_pp.h"
#include"model_pp.h"
#include"rewriter_types.h"
@ -82,6 +82,7 @@ class bit_blaster_tactic : public tactic {
}
if (curr != new_curr) {
change = true;
TRACE("bit_blaster", tout << mk_pp(curr, m()) << " -> " << mk_pp(new_curr, m()) << "\n";);
g->update(idx, new_curr, new_pr, g->dep(idx));
}
}