3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-08-19 17:50:23 +00:00

fixes to bugs exposed by regressions

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
Nikolaj Bjorner 2013-12-15 05:23:47 +02:00
parent 50f18a77af
commit fe5c42c90f
12 changed files with 325 additions and 85 deletions

View file

@ -322,6 +322,7 @@ namespace opt {
for (unsigned i = 0; i < m_orig_soft.size(); ++i) {
expr_ref val(m);
VERIFY(m_model->eval(m_orig_soft[i].get(), val));
TRACE("opt", tout << val << "\n";);
m_assignment.push_back(m.is_true(val));
}
TRACE("opt", tout << "maxsat cost: " << m_upper << "\n";

View file

@ -112,25 +112,18 @@ namespace opt {
for (unsigned i = 0; i < m_soft_constraints.size(); ++i) {
expr_ref tmp(m);
tmp = m_soft_constraints[i].get();
if (get_assignment(i)) {
m_s->assert_expr(tmp);
}
else {
if (!get_assignment(i)) {
tmp = m.mk_not(tmp);
m_s->assert_expr(tmp);
}
TRACE("opt", tout << "asserting: " << tmp << "\n";);
m_s->assert_expr(tmp);
}
}
void maxsmt::display_answer(std::ostream& out) const {
for (unsigned i = 0; i < m_soft_constraints.size(); ++i) {
out << mk_pp(m_soft_constraints[i], m);
if (get_assignment(i)) {
out << " |-> true\n";
}
else {
out << " |-> false\n";
}
out << mk_pp(m_soft_constraints[i], m)
<< (get_assignment(i)?" |-> true\n":" |-> false\n");
}
}

View file

@ -121,7 +121,7 @@ namespace opt {
lbool context::execute_min_max(unsigned index, bool committed) {
lbool result = m_optsmt.lex(index);
if (committed) m_optsmt.commit_assignment(index);
if (result == l_true && committed) m_optsmt.commit_assignment(index);
if (result == l_true) m_optsmt.get_model(m_model);
return result;
}
@ -129,7 +129,7 @@ namespace opt {
lbool context::execute_maxsat(symbol const& id, bool committed) {
maxsmt& ms = *m_maxsmts.find(id);
lbool result = ms(get_solver());
if (committed) ms.commit_assignment();
if (result == l_true && committed) ms.commit_assignment();
if (result == l_true) ms.get_model(m_model);
return result;
}

View file

@ -48,6 +48,7 @@ namespace smt {
*/
void get_assignment(svector<bool>& result) {
result.reset();
std::sort(m_cost_save.begin(), m_cost_save.end());
for (unsigned i = 0, j = 0; i < m_vars.size(); ++i) {
if (j < m_cost_save.size() && m_cost_save[j] == i) {
@ -58,43 +59,58 @@ namespace smt {
result.push_back(true);
}
}
TRACE("opt",
tout << "cost save: ";
for (unsigned i = 0; i < m_cost_save.size(); ++i) {
tout << m_cost_save[i] << " ";
}
tout << "\nvars: ";
for (unsigned i = 0; i < m_vars.size(); ++i) {
tout << mk_pp(m_vars[i].get(), get_manager()) << " ";
}
tout << "\nassignment";
for (unsigned i = 0; i < result.size(); ++i) {
tout << result[i] << " ";
}
tout << "\n";);
}
virtual void init_search_eh() {
context & ctx = get_context();
ast_manager& m = get_manager();
m_var2bool.reset();
for (unsigned i = 0; i < m_vars.size(); ++i) {
bool initialized = !m_var2bool.empty();
for (unsigned i = 0; !initialized && i < m_vars.size(); ++i) {
app* var = m_vars[i].get();
bool_var bv;
enode* x;
if (!ctx.e_internalized(var)) {
x = ctx.mk_enode(var, false, true, true);
}
else {
x = ctx.get_enode(var);
}
theory_var v;
SASSERT(!ctx.e_internalized(var));
enode* x = ctx.mk_enode(var, false, true, true);
if (ctx.b_internalized(var)) {
bv = ctx.get_bool_var(var);
}
else {
bv = ctx.mk_bool_var(var);
}
ctx.set_var_theory(bv, get_id());
ctx.set_var_theory(bv, get_id());
ctx.set_enode_flag(bv, true);
theory_var v = mk_var(x);
v = mk_var(x);
ctx.attach_th_var(x, this, v);
m_bool2var.insert(bv, v);
SASSERT(v == m_var2bool.size());
m_var2bool.push_back(bv);
SASSERT(ctx.bool_var2enode(bv));
}
for (unsigned i = 0; i < m_vars.size(); ++i) {
app* var = m_vars[i].get();
bool_var bv = ctx.get_bool_var(var);
lbool asgn = ctx.get_assignment(bv);
if (asgn == l_true) {
assign_eh(bv, true);
}
}
if (m_min_cost_atom) {
app* var = m_min_cost_atom;
if (!ctx.e_internalized(var)) {
@ -157,10 +173,7 @@ namespace smt {
}
virtual final_check_status final_check_eh() {
if (block(true)) {
return FC_DONE;
}
return FC_CONTINUE;
return FC_DONE;
}
virtual bool use_diseqs() const {
@ -171,7 +184,7 @@ namespace smt {
return false;
}
void reset() {
void reset() {
reset_eh();
}
@ -195,17 +208,9 @@ namespace smt {
virtual void new_eq_eh(theory_var v1, theory_var v2) { }
virtual void new_diseq_eh(theory_var v1, theory_var v2) { }
private:
class compare_cost {
theory_weighted_maxsat& m_th;
public:
compare_cost(theory_weighted_maxsat& t):m_th(t) {}
bool operator() (theory_var v, theory_var w) const {
return m_th.m_weights[v] > m_th.m_weights[w];
}
};
bool is_optimal() const {
return m_cost < m_min_cost;
}
bool block(bool is_final) {
if (m_vars.empty()) {
@ -225,18 +230,27 @@ namespace smt {
if (m_min_cost_atom) {
lits.push_back(~literal(m_min_cost_bv));
}
IF_VERBOSE(2,
verbose_stream() << "block: ";
for (unsigned i = 0; i < lits.size(); ++i) {
expr_ref tmp(m);
ctx.literal2expr(lits[i], tmp);
verbose_stream() << tmp << " ";
}
verbose_stream() << "\n";
);
TRACE("opt",
tout << "block" << (is_final?" final: ":": ");;
for (unsigned i = 0; i < lits.size(); ++i) {
expr_ref tmp(m);
ctx.literal2expr(lits[i], tmp);
tout << tmp << " ";
}
tout << "\n";
if (is_final && is_optimal()) {
tout << "costs: ";
for (unsigned i = 0; i < m_costs.size(); ++i) {
tout << mk_pp(get_enode(m_costs[i])->get_owner(), get_manager()) << " ";
}
tout << "\n";
ctx.display(tout);
}
);
ctx.mk_th_axiom(get_id(), lits.size(), lits.c_ptr());
if (is_final && m_cost < m_min_cost) {
if (is_final && is_optimal()) {
m_min_cost = weight;
m_cost_save.reset();
m_cost_save.append(m_costs);
@ -244,6 +258,19 @@ namespace smt {
return false;
}
private:
class compare_cost {
theory_weighted_maxsat& m_th;
public:
compare_cost(theory_weighted_maxsat& t):m_th(t) {}
bool operator() (theory_var v, theory_var w) const {
return m_th.m_weights[v] > m_th.m_weights[w];
}
};
};
}
@ -329,26 +356,36 @@ namespace opt {
lbool operator()() {
TRACE("opt", tout << "weighted maxsat\n";);
smt::theory_weighted_maxsat& wth = ensure_theory();
lbool result;
lbool is_sat = l_true;
{
solver::scoped_push _s(s);
for (unsigned i = 0; i < m_soft.size(); ++i) {
wth.assert_weighted(m_soft[i].get(), m_weights[i]);
}
result = s.check_sat_core(0,0);
SASSERT(result != l_true);
wth.get_assignment(m_assignment);
if (result == l_false) {
result = l_true;
while (l_true == is_sat) {
is_sat = s.check_sat_core(0,0);
if (is_sat == l_true) {
if (wth.is_optimal()) {
s.get_model(m_model);
}
wth.block(true);
if (s.get_context().inconsistent()) {
is_sat = l_false;
}
}
}
if (is_sat == l_false) {
wth.get_assignment(m_assignment);
is_sat = l_true;
}
}
m_upper = wth.get_min_cost();
if (result == l_true) {
if (is_sat == l_true) {
m_lower = m_upper;
}
TRACE("opt", tout << "min cost: " << m_upper << "\n";);
wth.reset();
return result;
return is_sat;
}
rational get_lower() const {
@ -360,10 +397,7 @@ namespace opt {
}
void get_model(model_ref& mdl) {
lbool is_sat = s.check_sat_core(0,0);
if (is_sat == l_true) {
s.get_model(mdl);
}
mdl = m_model.get();
}
};