3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-06-23 06:13:40 +00:00

fix lexicographic product for MaxSMT

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
Nikolaj Bjorner 2014-10-01 13:49:23 -07:00
parent 0914748184
commit 0b1c180808
10 changed files with 96 additions and 130 deletions

View file

@ -187,7 +187,7 @@ namespace opt {
expr_ref fml(m); expr_ref fml(m);
expr* r = m_soft_aux[i].get(); expr* r = m_soft_aux[i].get();
m_soft2index.insert(r, i); m_soft2index.insert(r, i);
fml = m.mk_or(r, m_soft[i].get()); fml = m.mk_or(r, m_soft[i]);
m_soft_constraints.push_back(fml); m_soft_constraints.push_back(fml);
m_asm_set.insert(r); m_asm_set.insert(r);
SASSERT(m_weights[i].is_int()); SASSERT(m_weights[i].is_int());
@ -233,7 +233,7 @@ namespace opt {
new_assignment.reset(); new_assignment.reset();
s().get_model(model); s().get_model(model);
for (unsigned i = 0; i < m_soft.size(); ++i) { for (unsigned i = 0; i < m_soft.size(); ++i) {
VERIFY(model->eval(m_soft[i].get(), val)); VERIFY(model->eval(m_soft[i], val));
new_assignment.push_back(m.is_true(val)); new_assignment.push_back(m.is_true(val));
if (!new_assignment[i]) { if (!new_assignment[i]) {
new_upper += m_weights[i]; new_upper += m_weights[i];
@ -393,7 +393,7 @@ namespace opt {
out << "[" << c.m_lower << ":" << c.m_mid << ":" << c.m_upper << "]\n"; out << "[" << c.m_lower << ":" << c.m_mid << ":" << c.m_upper << "]\n";
} }
for (unsigned i = 0; i < m_soft.size(); ++i) { for (unsigned i = 0; i < m_soft.size(); ++i) {
out << mk_pp(m_soft[i].get(), m) << " " << m_weights[i] << "\n"; out << mk_pp(m_soft[i], m) << " " << m_weights[i] << "\n";
} }
} }
}; };

View file

@ -43,34 +43,24 @@ Notes:
*/ */
namespace opt { namespace opt {
struct fu_malik::imp { class fu_malik : public maxsmt_solver_base {
ast_manager& m;
solver& m_s;
filter_model_converter& m_fm; filter_model_converter& m_fm;
expr_ref_vector m_soft; expr_ref_vector m_aux_soft;
expr_ref_vector m_orig_soft;
expr_ref_vector m_aux; expr_ref_vector m_aux;
svector<bool> m_assignment;
unsigned m_upper;
unsigned m_lower;
model_ref m_model; model_ref m_model;
imp(context& c, expr_ref_vector const& soft): public:
m(c.get_manager()), fu_malik(context& c, weights_t& ws, expr_ref_vector const& soft):
m_s(c.get_solver()), maxsmt_solver_base(c, ws, soft),
m_fm(c.fm()), m_fm(c.fm()),
m_soft(soft), m_aux_soft(soft),
m_orig_soft(soft), m_aux(m)
m_aux(m),
m_upper(0),
m_lower(0)
{ {
m_upper = m_soft.size() + 1; m_upper = rational(m_aux_soft.size() + 1);
m_assignment.resize(m_soft.size(), false); m_lower.reset();
m_assignment.resize(m_aux_soft.size(), false);
} }
solver& s() { return m_s; }
/** /**
\brief One step of the Fu&Malik algorithm. \brief One step of the Fu&Malik algorithm.
@ -96,9 +86,8 @@ namespace opt {
} }
} }
void collect_statistics(statistics& st) const { void collect_statistics(statistics& st) const {
st.update("opt-fm-num-steps", m_soft.size() + 2 - m_upper); st.update("opt-fm-num-steps", m_aux_soft.size() + 2 - m_upper.get_unsigned());
} }
void set_union(expr_set const& set1, expr_set const& set2, expr_set & set) const { void set_union(expr_set const& set1, expr_set const& set2, expr_set & set) const {
@ -115,9 +104,9 @@ namespace opt {
} }
lbool step() { lbool step() {
IF_VERBOSE(1, verbose_stream() << "(opt.max_sat step " << m_soft.size() + 2 - m_upper << ")\n";); IF_VERBOSE(1, verbose_stream() << "(opt.max_sat step " << m_aux_soft.size() + 2 - m_upper.get_unsigned() << ")\n";);
expr_ref_vector assumptions(m), block_vars(m); expr_ref_vector assumptions(m), block_vars(m);
for (unsigned i = 0; i < m_soft.size(); ++i) { for (unsigned i = 0; i < m_aux_soft.size(); ++i) {
assumptions.push_back(m.mk_not(m_aux[i].get())); assumptions.push_back(m.mk_not(m_aux[i].get()));
} }
lbool is_sat = s().check_sat(assumptions.size(), assumptions.c_ptr()); lbool is_sat = s().check_sat(assumptions.size(), assumptions.c_ptr());
@ -131,7 +120,7 @@ namespace opt {
SASSERT(!core.empty()); SASSERT(!core.empty());
// Update soft-constraints and aux_vars // Update soft-constraints and aux_vars
for (unsigned i = 0; i < m_soft.size(); ++i) { for (unsigned i = 0; i < m_aux_soft.size(); ++i) {
bool found = false; bool found = false;
for (unsigned j = 0; !found && j < core.size(); ++j) { for (unsigned j = 0; !found && j < core.size(); ++j) {
@ -145,14 +134,14 @@ namespace opt {
m_aux[i] = m.mk_fresh_const("aux", m.mk_bool_sort()); m_aux[i] = m.mk_fresh_const("aux", m.mk_bool_sort());
m_fm.insert(block_var->get_decl()); m_fm.insert(block_var->get_decl());
m_fm.insert(to_app(m_aux[i].get())->get_decl()); m_fm.insert(to_app(m_aux[i].get())->get_decl());
m_soft[i] = m.mk_or(m_soft[i].get(), block_var); m_aux_soft[i] = m.mk_or(m_aux_soft[i].get(), block_var);
block_vars.push_back(block_var); block_vars.push_back(block_var);
tmp = m.mk_or(m_soft[i].get(), m_aux[i].get()); tmp = m.mk_or(m_aux_soft[i].get(), m_aux[i].get());
s().assert_expr(tmp); s().assert_expr(tmp);
} }
SASSERT (!block_vars.empty()); SASSERT (!block_vars.empty());
assert_at_most_one(block_vars); assert_at_most_one(block_vars);
IF_VERBOSE(1, verbose_stream() << "(opt.max_sat # of non-blocked soft constraints: " << m_soft.size() - block_vars.size() << ")\n";); IF_VERBOSE(1, verbose_stream() << "(opt.max_sat # of non-blocked soft constraints: " << m_aux_soft.size() - block_vars.size() << ")\n";);
return l_false; return l_false;
} }
@ -181,9 +170,9 @@ namespace opt {
// TBD: bug when cancel flag is set, fu_malik returns is_sat == l_true instead of l_undef // TBD: bug when cancel flag is set, fu_malik returns is_sat == l_true instead of l_undef
lbool operator()() { virtual lbool operator()() {
lbool is_sat = l_true; lbool is_sat = l_true;
if (m_soft.empty()) { if (m_aux_soft.empty()) {
return is_sat; return is_sat;
} }
solver::scoped_push _sp(s()); solver::scoped_push _sp(s());
@ -191,14 +180,14 @@ namespace opt {
TRACE("opt", TRACE("opt",
tout << "soft constraints:\n"; tout << "soft constraints:\n";
for (unsigned i = 0; i < m_soft.size(); ++i) { for (unsigned i = 0; i < m_aux_soft.size(); ++i) {
tout << mk_pp(m_soft[i].get(), m) << "\n"; tout << mk_pp(m_aux_soft[i].get(), m) << "\n";
}); });
for (unsigned i = 0; i < m_soft.size(); ++i) { for (unsigned i = 0; i < m_aux_soft.size(); ++i) {
m_aux.push_back(m.mk_fresh_const("p", m.mk_bool_sort())); m_aux.push_back(m.mk_fresh_const("p", m.mk_bool_sort()));
m_fm.insert(to_app(m_aux.back())->get_decl()); m_fm.insert(to_app(m_aux.back())->get_decl());
tmp = m.mk_or(m_soft[i].get(), m_aux[i].get()); tmp = m.mk_or(m_aux_soft[i].get(), m_aux[i].get());
s().assert_expr(tmp); s().assert_expr(tmp);
} }
@ -209,13 +198,13 @@ namespace opt {
while (is_sat == l_false); while (is_sat == l_false);
if (is_sat == l_true) { if (is_sat == l_true) {
// Get a list satisfying m_soft // Get a list satisfying m_aux_soft
s().get_model(m_model); s().get_model(m_model);
m_lower = m_upper; m_lower = m_upper;
m_assignment.reset(); m_assignment.reset();
for (unsigned i = 0; i < m_orig_soft.size(); ++i) { for (unsigned i = 0; i < m_soft.size(); ++i) {
expr_ref val(m); expr_ref val(m);
VERIFY(m_model->eval(m_orig_soft[i].get(), val)); VERIFY(m_model->eval(m_soft[i], val));
TRACE("opt", tout << val << "\n";); TRACE("opt", tout << val << "\n";);
m_assignment.push_back(m.is_true(val)); m_assignment.push_back(m.is_true(val));
} }
@ -227,43 +216,22 @@ namespace opt {
return is_sat; return is_sat;
} }
void get_model(model_ref& mdl) { virtual void get_model(model_ref& mdl) {
mdl = m_model.get(); mdl = m_model.get();
} }
virtual rational get_lower() const {
return rational(m_aux_soft.size())-m_upper;
}
virtual rational get_upper() const {
return rational(m_aux_soft.size())-m_lower;
}
}; };
fu_malik::fu_malik(context& c, expr_ref_vector& soft_constraints) { maxsmt_solver_base* mk_fu_malik(context& c, weights_t & ws, expr_ref_vector const& soft) {
m_imp = alloc(imp, c, soft_constraints); return alloc(fu_malik, c, ws, soft);
}
fu_malik::~fu_malik() {
dealloc(m_imp);
}
lbool fu_malik::operator()() {
return (*m_imp)();
}
rational fu_malik::get_lower() const {
return rational(m_imp->m_soft.size()-m_imp->m_upper);
}
rational fu_malik::get_upper() const {
return rational(m_imp->m_soft.size()-m_imp->m_lower);
}
bool fu_malik::get_assignment(unsigned idx) const {
return m_imp->m_assignment[idx];
}
void fu_malik::set_cancel(bool f) {
// no-op
}
void fu_malik::collect_statistics(statistics& st) const {
m_imp->collect_statistics(st);
}
void fu_malik::get_model(model_ref& m) {
m_imp->get_model(m);
} }
void fu_malik::updt_params(params_ref& p) {
// no-op
}
}; };

View file

@ -29,21 +29,8 @@ Notes:
namespace opt { namespace opt {
class fu_malik : public maxsmt_solver { maxsmt_solver_base* mk_fu_malik(context& c, weights_t & ws, expr_ref_vector const& soft);
struct imp;
imp* m_imp;
public:
fu_malik(context& c, expr_ref_vector& soft_constraints);
virtual ~fu_malik();
virtual lbool operator()();
virtual rational get_lower() const;
virtual rational get_upper() const;
virtual bool get_assignment(unsigned idx) const;
virtual void set_cancel(bool f);
virtual void collect_statistics(statistics& st) const;
virtual void get_model(model_ref& m);
virtual void updt_params(params_ref& p);
};
}; };

View file

@ -162,7 +162,7 @@ namespace opt {
m_aux2index.reset(); m_aux2index.reset();
m_core_activity.reset(); m_core_activity.reset();
for (unsigned i = 0; i < sz; ++i) { for (unsigned i = 0; i < sz; ++i) {
bool tt = is_true(m_model, m_soft[i].get()); bool tt = is_true(m_model, m_soft[i]);
m_seed.push_back(tt); m_seed.push_back(tt);
m_aux. push_back(mk_fresh(m.mk_bool_sort())); m_aux. push_back(mk_fresh(m.mk_bool_sort()));
m_aux_active.push_back(false); m_aux_active.push_back(false);
@ -380,7 +380,7 @@ namespace opt {
if (m_seed[i]) { if (m_seed[i]) {
// already an assumption // already an assumption
} }
else if (is_true(mdl, m_soft[i].get())) { else if (is_true(mdl, m_soft[i])) {
m_seed[i] = true; m_seed[i] = true;
m_asms.push_back(m_aux[i].get()); m_asms.push_back(m_aux[i].get());
} }
@ -420,7 +420,7 @@ namespace opt {
} }
DEBUG_CODE( DEBUG_CODE(
for (unsigned i = 0; i < num_soft(); ++i) { for (unsigned i = 0; i < num_soft(); ++i) {
SASSERT(is_true(mdl, m_soft[i].get()) == m_seed[i]); SASSERT(is_true(mdl, m_soft[i]) == m_seed[i]);
}); });
return true; return true;
@ -545,7 +545,7 @@ namespace opt {
void ensure_active(unsigned i) { void ensure_active(unsigned i) {
if (!is_active(i)) { if (!is_active(i)) {
expr_ref fml(m); expr_ref fml(m);
fml = m.mk_implies(m_aux[i].get(), m_soft[i].get()); fml = m.mk_implies(m_aux[i].get(), m_soft[i]);
s().assert_expr(fml); s().assert_expr(fml);
m_aux_active[i] = true; m_aux_active[i] = true;
} }

View file

@ -84,6 +84,7 @@ private:
expr_ref_vector m_trail; expr_ref_vector m_trail;
strategy_t m_st; strategy_t m_st;
rational m_max_upper; rational m_max_upper;
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
bool m_add_upper_bound_block; // restrict upper bound with constraint bool m_add_upper_bound_block; // restrict upper bound with constraint
unsigned m_max_num_cores; // max number of cores per round. unsigned m_max_num_cores; // max number of cores per round.
@ -105,6 +106,7 @@ public:
m_mss(c.get_solver(), m), m_mss(c.get_solver(), m),
m_trail(m), m_trail(m),
m_st(st), m_st(st),
m_found_feasible_optimum(false),
m_hill_climb(true), m_hill_climb(true),
m_add_upper_bound_block(false), m_add_upper_bound_block(false),
m_max_num_cores(UINT_MAX), m_max_num_cores(UINT_MAX),
@ -122,6 +124,8 @@ public:
(m.is_not(l, l) && is_uninterp_const(l)); (m.is_not(l, l) && is_uninterp_const(l));
} }
void add_soft(expr* e, rational const& w) { void add_soft(expr* e, rational const& w) {
TRACE("opt", tout << mk_pp(e, m) << "\n";); TRACE("opt", tout << mk_pp(e, m) << "\n";);
expr_ref asum(m), fml(m); expr_ref asum(m), fml(m);
@ -372,13 +376,14 @@ public:
SASSERT(is_true(m_asms[i].get())); SASSERT(is_true(m_asms[i].get()));
}); });
for (unsigned i = 0; i < m_soft.size(); ++i) { for (unsigned i = 0; i < m_soft.size(); ++i) {
m_assignment[i] = is_true(m_soft[i].get()); m_assignment[i] = is_true(m_soft[i]);
} }
m_upper = m_lower; m_upper = m_lower;
m_found_feasible_optimum = true;
} }
lbool operator()() { virtual lbool operator()() {
switch(m_st) { switch(m_st) {
case s_mus: case s_mus:
return mus_solver(); return mus_solver();
@ -781,7 +786,7 @@ public:
rational upper(0); rational upper(0);
expr_ref tmp(m); expr_ref tmp(m);
for (unsigned i = 0; i < m_soft.size(); ++i) { for (unsigned i = 0; i < m_soft.size(); ++i) {
expr* n = m_soft[i].get(); expr* n = m_soft[i];
VERIFY(mdl->eval(n, tmp)); VERIFY(mdl->eval(n, tmp));
if (!m.is_true(tmp)) { if (!m.is_true(tmp)) {
upper += m_weights[i]; upper += m_weights[i];
@ -796,7 +801,7 @@ public:
m_model = mdl; m_model = mdl;
for (unsigned i = 0; i < m_soft.size(); ++i) { for (unsigned i = 0; i < m_soft.size(); ++i) {
m_assignment[i] = is_true(m_soft[i].get()); m_assignment[i] = is_true(m_soft[i]);
} }
m_upper = upper; m_upper = upper;
// verify_assignment(); // verify_assignment();
@ -811,7 +816,7 @@ public:
expr_ref_vector nsoft(m); expr_ref_vector nsoft(m);
expr_ref fml(m); expr_ref fml(m);
for (unsigned i = 0; i < m_soft.size(); ++i) { for (unsigned i = 0; i < m_soft.size(); ++i) {
nsoft.push_back(mk_not(m, m_soft[i].get())); nsoft.push_back(mk_not(m, m_soft[i]));
} }
fml = u.mk_lt(nsoft.size(), m_weights.c_ptr(), nsoft.c_ptr(), m_upper); fml = u.mk_lt(nsoft.size(), m_weights.c_ptr(), nsoft.c_ptr(), m_upper);
s().assert_expr(fml); s().assert_expr(fml);
@ -864,12 +869,25 @@ public:
m_lower.reset(); m_lower.reset();
m_trail.reset(); m_trail.reset();
for (unsigned i = 0; i < m_soft.size(); ++i) { for (unsigned i = 0; i < m_soft.size(); ++i) {
add_soft(m_soft[i].get(), m_weights[i]); add_soft(m_soft[i], m_weights[i]);
} }
m_max_upper = m_upper; m_max_upper = m_upper;
m_found_feasible_optimum = false;
add_upper_bound_block(); add_upper_bound_block();
} }
virtual void commit_assignment() {
if (m_found_feasible_optimum) {
TRACE("opt", tout << "Committing feasible solution\n";);
for (unsigned i = 0; i < m_asms.size(); ++i) {
s().assert_expr(m_asms[i].get());
}
}
else {
maxsmt_solver_base::commit_assignment();
}
}
void verify_assignment() { void verify_assignment() {
IF_VERBOSE(0, verbose_stream() << "verify assignment\n";); IF_VERBOSE(0, verbose_stream() << "verify assignment\n";);
ref<solver> sat_solver = mk_inc_sat_solver(m, m_params); ref<solver> sat_solver = mk_inc_sat_solver(m, m_params);
@ -878,7 +896,7 @@ public:
} }
expr_ref n(m); expr_ref n(m);
for (unsigned i = 0; i < m_soft.size(); ++i) { for (unsigned i = 0; i < m_soft.size(); ++i) {
n = m_soft[i].get(); n = m_soft[i];
if (!m_assignment[i]) { if (!m_assignment[i]) {
n = mk_not(m, n); n = mk_not(m, n);
} }

View file

@ -41,7 +41,7 @@ namespace opt {
m_upper.reset(); m_upper.reset();
for (unsigned i = 0; i < m_soft.size(); ++i) { for (unsigned i = 0; i < m_soft.size(); ++i) {
expr_ref tmp(m); expr_ref tmp(m);
m_model->eval(m_soft[i].get(), tmp, true); m_model->eval(m_soft[i], tmp, true);
m_assignment[i] = m.is_true(tmp); m_assignment[i] = m.is_true(tmp);
if (!m_assignment[i]) { if (!m_assignment[i]) {
m_upper += m_weights[i]; m_upper += m_weights[i];

View file

@ -30,6 +30,7 @@ Notes:
#include "opt_context.h" #include "opt_context.h"
#include "theory_wmaxsat.h" #include "theory_wmaxsat.h"
#include "ast_util.h" #include "ast_util.h"
#include "pb_decl_plugin.h"
namespace opt { namespace opt {
@ -38,12 +39,13 @@ namespace opt {
context& c, vector<rational> const& ws, expr_ref_vector const& soft): context& c, vector<rational> const& ws, expr_ref_vector const& soft):
m(c.get_manager()), m(c.get_manager()),
m_c(c), m_c(c),
m_cancel(false), m_soft(m), m_cancel(false),
m_soft(soft),
m_weights(ws),
m_assertions(m) { m_assertions(m) {
c.get_base_model(m_model); c.get_base_model(m_model);
SASSERT(m_model); SASSERT(m_model);
updt_params(c.params()); updt_params(c.params());
init_soft(ws, soft);
} }
void maxsmt_solver_base::updt_params(params_ref& p) { void maxsmt_solver_base::updt_params(params_ref& p) {
@ -54,11 +56,17 @@ namespace opt {
return m_c.get_solver(); return m_c.get_solver();
} }
void maxsmt_solver_base::init_soft(vector<rational> const& weights, expr_ref_vector const& soft) { void maxsmt_solver_base::commit_assignment() {
m_weights.reset(); expr_ref tmp(m);
m_soft.reset(); rational k(0);
m_weights.append(weights); for (unsigned i = 0; i < m_soft.size(); ++i) {
m_soft.append(soft); if (get_assignment(i)) {
k += m_weights[i];
}
}
pb_util pb(m);
tmp = pb.mk_ge(m_weights.size(), m_weights.c_ptr(), m_soft.c_ptr(), k);
s().assert_expr(tmp);
} }
void maxsmt_solver_base::init() { void maxsmt_solver_base::init() {
@ -67,7 +75,7 @@ namespace opt {
m_assignment.reset(); m_assignment.reset();
for (unsigned i = 0; i < m_weights.size(); ++i) { for (unsigned i = 0; i < m_weights.size(); ++i) {
expr_ref val(m); expr_ref val(m);
VERIFY(m_model->eval(m_soft[i].get(), val)); VERIFY(m_model->eval(m_soft[i], val));
m_assignment.push_back(m.is_true(val)); m_assignment.push_back(m.is_true(val));
if (!m_assignment.back()) { if (!m_assignment.back()) {
m_upper += m_weights[i]; m_upper += m_weights[i];
@ -178,7 +186,7 @@ namespace opt {
m_msolver = mk_sls(m_c, m_weights, m_soft_constraints); m_msolver = mk_sls(m_c, m_weights, m_soft_constraints);
} }
else if (is_maxsat_problem(m_weights) && maxsat_engine == symbol("fu_malik")) { else if (is_maxsat_problem(m_weights) && maxsat_engine == symbol("fu_malik")) {
m_msolver = alloc(fu_malik, m_c, m_soft_constraints); m_msolver = mk_fu_malik(m_c, m_weights, m_soft_constraints);
} }
else { else {
if (maxsat_engine != symbol::null && maxsat_engine != symbol("wmax")) { if (maxsat_engine != symbol::null && maxsat_engine != symbol("wmax")) {
@ -217,12 +225,6 @@ namespace opt {
// TBD: have to use a different solver // TBD: have to use a different solver
// because we don't push local scope any longer. // because we don't push local scope any longer.
return; return;
solver::scoped_push _sp(s());
commit_assignment();
if (l_true != s().check_sat(0,0)) {
IF_VERBOSE(0, verbose_stream() << "could not verify assignment\n";);
UNREACHABLE();
}
} }
bool maxsmt::get_assignment(unsigned idx) const { bool maxsmt::get_assignment(unsigned idx) const {
@ -265,14 +267,8 @@ namespace opt {
} }
void maxsmt::commit_assignment() { void maxsmt::commit_assignment() {
for (unsigned i = 0; i < m_soft_constraints.size(); ++i) { if (m_msolver) {
expr_ref tmp(m); m_msolver->commit_assignment();
tmp = m_soft_constraints[i].get();
if (!get_assignment(i)) {
tmp = mk_not(m, tmp);
}
TRACE("opt", tout << "committing: " << tmp << "\n";);
s().assert_expr(tmp);
} }
} }

View file

@ -61,9 +61,9 @@ namespace opt {
ast_manager& m; ast_manager& m;
context& m_c; context& m_c;
volatile bool m_cancel; volatile bool m_cancel;
expr_ref_vector m_soft; const expr_ref_vector m_soft;
expr_ref_vector m_assertions;
vector<rational> m_weights; vector<rational> m_weights;
expr_ref_vector m_assertions;
rational m_lower; rational m_lower;
rational m_upper; rational m_upper;
model_ref m_model; model_ref m_model;
@ -80,9 +80,9 @@ namespace opt {
virtual void set_cancel(bool f) { m_cancel = f; if (f) s().cancel(); else s().reset_cancel(); } virtual void set_cancel(bool f) { m_cancel = f; if (f) s().cancel(); else s().reset_cancel(); }
virtual void collect_statistics(statistics& st) const { } virtual void collect_statistics(statistics& st) const { }
virtual void get_model(model_ref& mdl) { mdl = m_model.get(); } virtual void get_model(model_ref& mdl) { mdl = m_model.get(); }
virtual void commit_assignment();
void set_model() { s().get_model(m_model); } void set_model() { s().get_model(m_model); }
virtual void updt_params(params_ref& p); virtual void updt_params(params_ref& p);
virtual void init_soft(weights_t& weights, expr_ref_vector const& soft);
solver& s(); solver& s();
void init(); void init();
void set_mus(bool f); void set_mus(bool f);
@ -114,7 +114,7 @@ namespace opt {
class maxsmt { class maxsmt {
ast_manager& m; ast_manager& m;
context& m_c; context& m_c;
scoped_ptr<maxsmt_solver> m_msolver; scoped_ptr<maxsmt_solver_base> m_msolver;
volatile bool m_cancel; volatile bool m_cancel;
expr_ref_vector m_soft_constraints; expr_ref_vector m_soft_constraints;
expr_ref_vector m_answer; expr_ref_vector m_answer;

View file

@ -1204,10 +1204,7 @@ namespace opt {
maxsmt& ms = *m_maxsmts.find(obj.m_id); maxsmt& ms = *m_maxsmts.find(obj.m_id);
for (unsigned i = 0; i < obj.m_terms.size(); ++i) { for (unsigned i = 0; i < obj.m_terms.size(); ++i) {
VERIFY(m_model->eval(obj.m_terms[i], val)); VERIFY(m_model->eval(obj.m_terms[i], val));
CTRACE("opt",ms.get_assignment(i) != (m.mk_true() == val), // TBD: check that optimal was not changed.
tout << mk_pp(obj.m_terms[i], m) << " evaluates to " << val << "\n";
model_smt2_pp(tout, m, *m_model, 0););
SASSERT(ms.get_assignment(i) == (m.mk_true() == val));
} }
break; break;
} }

View file

@ -43,7 +43,7 @@ namespace opt {
lbool is_sat = l_true; lbool is_sat = l_true;
bool was_sat = false; bool was_sat = false;
for (unsigned i = 0; i < m_soft.size(); ++i) { for (unsigned i = 0; i < m_soft.size(); ++i) {
wth().assert_weighted(m_soft[i].get(), m_weights[i]); wth().assert_weighted(m_soft[i], m_weights[i]);
} }
while (l_true == is_sat) { while (l_true == is_sat) {
is_sat = s().check_sat(0,0); is_sat = s().check_sat(0,0);