mirror of
https://github.com/Z3Prover/z3
synced 2025-04-08 18:31:49 +00:00
fix wmaxsat
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
parent
ddd0bf875d
commit
15b64261dd
|
@ -99,6 +99,7 @@ namespace smt {
|
|||
ctx.attach_th_var(x, this, v);
|
||||
m_bool2var.insert(bv, v);
|
||||
SASSERT(v == m_var2bool.size());
|
||||
SASSERT(i == v);
|
||||
m_var2bool.push_back(bv);
|
||||
SASSERT(ctx.bool_var2enode(bv));
|
||||
}
|
||||
|
@ -157,7 +158,7 @@ namespace smt {
|
|||
}
|
||||
|
||||
virtual void assign_eh(bool_var v, bool is_true) {
|
||||
IF_VERBOSE(3, verbose_stream() << "Assign " << v << " " << is_true << "\n";);
|
||||
TRACE("opt", tout << "Assign " << mk_pp(m_vars[m_bool2var[v]].get(), get_manager()) << " " << is_true << "\n";);
|
||||
if (is_true) {
|
||||
context& ctx = get_context();
|
||||
theory_var tv = m_bool2var[v];
|
||||
|
@ -167,7 +168,7 @@ namespace smt {
|
|||
m_cost += w;
|
||||
m_costs.push_back(tv);
|
||||
if (m_cost > m_min_cost) {
|
||||
block(false);
|
||||
block();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -212,9 +213,47 @@ namespace smt {
|
|||
return m_cost < m_min_cost;
|
||||
}
|
||||
|
||||
bool block(bool is_final) {
|
||||
expr_ref mk_block() {
|
||||
ast_manager& m = get_manager();
|
||||
expr_ref_vector disj(m);
|
||||
compare_cost compare_cost(*this);
|
||||
svector<theory_var> costs(m_costs);
|
||||
std::sort(costs.begin(), costs.end(), compare_cost);
|
||||
rational weight(0);
|
||||
for (unsigned i = 0; i < costs.size() && weight < m_min_cost; ++i) {
|
||||
weight += m_weights[costs[i]];
|
||||
disj.push_back(m.mk_not(m_vars[costs[i]].get()));
|
||||
}
|
||||
if (m_min_cost_atom) {
|
||||
disj.push_back(m.mk_not(m_min_cost_atom));
|
||||
}
|
||||
if (is_optimal()) {
|
||||
m_min_cost = weight;
|
||||
m_cost_save.reset();
|
||||
m_cost_save.append(m_costs);
|
||||
}
|
||||
|
||||
expr_ref result(m.mk_or(disj.size(), disj.c_ptr()), m);
|
||||
|
||||
TRACE("opt",
|
||||
tout << result << "\n";
|
||||
if (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";
|
||||
get_context().display(tout);
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
|
||||
void block() {
|
||||
if (m_vars.empty()) {
|
||||
return true;
|
||||
return;
|
||||
}
|
||||
ast_manager& m = get_manager();
|
||||
context& ctx = get_context();
|
||||
|
@ -231,35 +270,18 @@ namespace smt {
|
|||
lits.push_back(~literal(m_min_cost_bv));
|
||||
}
|
||||
TRACE("opt",
|
||||
tout << "block" << (is_final?" final: ":": ");;
|
||||
tout << "block: ";
|
||||
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 && is_optimal()) {
|
||||
m_min_cost = weight;
|
||||
m_cost_save.reset();
|
||||
m_cost_save.append(m_costs);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
|
||||
class compare_cost {
|
||||
theory_weighted_maxsat& m_th;
|
||||
|
@ -368,10 +390,8 @@ namespace opt {
|
|||
if (wth.is_optimal()) {
|
||||
s.get_model(m_model);
|
||||
}
|
||||
wth.block(true);
|
||||
if (s.get_context().inconsistent()) {
|
||||
is_sat = l_false;
|
||||
}
|
||||
expr_ref fml = wth.mk_block();
|
||||
s.assert_expr(fml);
|
||||
}
|
||||
}
|
||||
if (is_sat == l_false) {
|
||||
|
|
Loading…
Reference in a new issue