3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-06-20 21:03:39 +00:00

working on bcd2

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
Nikolaj Bjorner 2014-04-17 15:37:03 -07:00
parent 7237be768b
commit ae1656a92c
3 changed files with 183 additions and 78 deletions

View file

@ -426,8 +426,19 @@ namespace opt {
neg = false; neg = false;
app* a = to_app(fml); app* a = to_app(fml);
if (m_objective_fns.find(a->get_decl(), index) && m_objectives[index].m_type == O_MAXSMT) { if (m_objective_fns.find(a->get_decl(), index) && m_objectives[index].m_type == O_MAXSMT) {
terms.append(a->get_num_args(), a->get_args()); for (unsigned i = 0; i < a->get_num_args(); ++i) {
weights.append(m_objectives[index].m_weights); expr* arg = a->get_arg(i);
if (m.is_true(arg)) {
}
else if (false && m.is_false(arg)) {
offset += m_objectives[index].m_weights[i];
}
else {
terms.push_back(arg);
weights.push_back(m_objectives[index].m_weights[i]);
}
}
id = m_objectives[index].m_id; id = m_objectives[index].m_id;
return true; return true;
} }

View file

@ -6,11 +6,12 @@ Module Name:
weighted_maxsat.cpp weighted_maxsat.cpp
Abstract: Abstract:
Weighted MAXSAT module Weighted MAXSAT module
Author: Author:
Anh-Dung Phan (t-anphan) 2013-10-16 Nikolaj Bjorner (nbjorner) 2014-4-17
Notes: Notes:
@ -107,49 +108,77 @@ namespace opt {
// //
class bcd2 : public maxsmt_solver_base { class bcd2 : public maxsmt_solver_base {
struct wcore { struct wcore {
expr* m_r;
unsigned_vector m_R; unsigned_vector m_R;
rational m_lower; rational m_lower;
rational m_mid; rational m_mid;
rational m_upper; rational m_upper;
}; };
typedef obj_hashtable<expr> expr_set;
pb_util pb;
expr_ref_vector m_relax; // index |-> expr
obj_map<expr, unsigned> m_relax2index; // expr |-> index
expr_ref_vector m_trail;
expr_set m_asm_set;
vector<wcore> m_cores;
vector<rational> m_sigmas;
void set2vector(expr_set const& set, expr_ref_vector & es) const {
es.reset();
expr_set::iterator it = set.begin(), end = set.end();
for (; it != end; ++it) {
es.push_back(*it);
}
}
void init() {
m_relax.reset();
m_trail.reset();
m_asm_set.reset();
m_cores.reset();
m_sigmas.reset();
for (unsigned i = 0; i < m_soft.size(); ++i) {
m_relax.push_back(mk_fresh());
m_relax2index.insert(m_relax.back(), i);
m_sigmas.push_back(m_weights[i]);
}
}
public: public:
bcd2(solver* s, ast_manager& m): bcd2(solver* s, ast_manager& m):
maxsmt_solver_base(s, m) {} maxsmt_solver_base(s, m),
pb(m),
m_relax(m),
m_trail(m) {}
virtual ~bcd2() {} virtual ~bcd2() {}
virtual lbool operator()() { virtual lbool operator()() {
expr_ref fml(m), val(m); expr_ref fml(m), r(m);
app_ref r(m); init();
vector<wcore> cores;
obj_map<expr, unsigned> ans2core; // answer literal to core index
lbool is_sat = l_undef; lbool is_sat = l_undef;
expr_ref_vector rs(m), asms(m); expr_ref_vector asms(m);
vector<rational> sigmas(m_weights); // sigma_j := w_j if soft clause has not been satisfied
bool first = true; bool first = true;
init(); init();
for (unsigned i = 0; i < m_soft.size(); ++i) { for (unsigned i = 0; i < m_soft.size(); ++i) {
r = m.mk_fresh_const("r", m.mk_bool_sort()); fml = m.mk_implies(m_relax[i].get(), m_soft[i].get());
m_mc->insert(r->get_decl());
fml = m.mk_or(m_soft[i].get(), r);
s().assert_expr(fml); // does not get asserted in model-based mode. s().assert_expr(fml); // does not get asserted in model-based mode.
rs.push_back(r); m_asm_set.insert(m_relax[i].get());
asms.push_back(m.mk_not(r));
SASSERT(m_weights[i].is_int()); // TBD: re-normalize weights if non-integral. SASSERT(m_weights[i].is_int()); // TBD: re-normalize weights if non-integral.
} }
m_upper += rational(1); // TBD: assuming integral weights m_upper += rational(1); // TBD: assuming integral weights
solver::scoped_push _s(s()); solver::scoped_push _scope1(s());
while (m_lower < m_upper) { while (m_lower < m_upper) {
solver::scoped_push __s(s()); solver::scoped_push _scope2(s());
assert_cores();
set2vector(m_asm_set, asms);
if (m_cancel) { if (m_cancel) {
return l_undef; return l_undef;
} }
for (unsigned i = 0; i < cores.size(); ++i) {
assert_core(cores[i]);
NOT_IMPLEMENTED_YET();
// need assumptions here as well.
}
is_sat = s().check_sat(asms.size(), asms.c_ptr()); is_sat = s().check_sat(asms.size(), asms.c_ptr());
switch(is_sat) { switch(is_sat) {
case l_undef: case l_undef:
@ -157,78 +186,133 @@ namespace opt {
case l_true: { case l_true: {
s().get_model(m_model); s().get_model(m_model);
m_upper.reset(); m_upper.reset();
for (unsigned i = 0; i < m_soft.size(); ++i) { update_assignment();
VERIFY(m_model->eval(m_soft[i].get(), val)); update_sigmas();
m_assignment[i] = m.is_true(val);
}
for (unsigned i = 0; i < cores.size(); ++i) {
wcore& c_i = cores[i];
unsigned_vector const& R = c_i.m_R;
c_i.m_upper.reset();
for (unsigned j = 0; j <R.size(); ++j) {
unsigned r_j = R[j];
if (!m_assignment[r_j]) {
c_i.m_upper += m_weights[r_j];
sigmas[r_j] = m_weights[r_j];
}
else {
sigmas[r_j].reset();
}
}
c_i.m_mid = div(c_i.m_lower + c_i.m_upper, rational(2));
m_upper += c_i.m_upper;
}
first = false; first = false;
break; break;
} }
case l_false: { case l_false: {
ptr_vector<expr> core; ptr_vector<expr> unsat_core;
uint_set subC, soft; uint_set subC, soft;
rational delta(0), lower(0); s().get_unsat_core(unsat_core);
wcore c_s; core2indices(unsat_core, subC, soft);
s().get_unsat_core(core); SASSERT(unsat_core.size() == subC.num_elems() + soft.num_elems());
core2indices(core, ans2core, subC, soft);
for (uint_set::iterator it = subC.begin(); it != subC.end(); ++it) {
unsigned j = *it;
c_s.m_R.push_back(j);
lower += cores[j].m_lower;
rational new_delta = rational(1) + cores[j].m_upper - cores[j].m_mid;
SASSERT(new_delta.is_pos());
if (delta.is_zero() || delta > new_delta) {
delta = new_delta;
}
}
if (soft.num_elems() == 0 && subC.num_elems() == 1) { if (soft.num_elems() == 0 && subC.num_elems() == 1) {
SASSERT(core.size() == 1);
unsigned s = *subC.begin(); unsigned s = *subC.begin();
wcore& c_s = cores[s]; wcore& c_s = m_cores[s];
c_s.m_lower = refine(c_s.m_R, c_s.m_mid); c_s.m_lower = refine(c_s.m_R, c_s.m_mid);
} }
else { else {
wcore c_s;
rational delta = min_of_delta(subC);
rational lower = sum_of_lower(subC);
union_Rs(subC, c_s.m_R);
r = mk_fresh();
relax(subC, soft, c_s.m_R, delta); relax(subC, soft, c_s.m_R, delta);
c_s.m_lower = refine(c_s.m_R, lower + delta - rational(1)); c_s.m_lower = refine(c_s.m_R, lower + delta - rational(1));
c_s.m_upper = rational(first?0:1); c_s.m_upper = rational(first?1:0);
for (unsigned i = 0; i < c_s.m_R.size(); ++i) { c_s.m_upper += sum_of_sigmas(c_s.m_R);
c_s.m_upper += sigmas[c_s.m_R[i]]; c_s.m_mid = div(c_s.m_lower + c_s.m_upper, rational(2));
} c_s.m_r = r;
c_s.m_mid = div(c_s.m_lower + c_s.m_upper, rational(2)); m_asm_set.insert(r);
subtract(cores, subC); subtract(m_cores, subC);
cores.push_back(c_s); m_cores.push_back(c_s);
} }
break; break;
} }
} }
m_lower = compute_lower(cores); m_lower = compute_lower();
} }
return is_sat; return is_sat;
} }
private: private:
rational compute_lower(vector<wcore> const& cores) {
expr* mk_fresh() {
app_ref r(m);
r = m.mk_fresh_const("r", m.mk_bool_sort());
m_trail.push_back(r);
m_mc->insert(r->get_decl());
return r;
}
void update_assignment() {
expr_ref val(m);
for (unsigned i = 0; i < m_soft.size(); ++i) {
VERIFY(m_model->eval(m_soft[i].get(), val));
m_assignment[i] = m.is_true(val);
}
}
void update_sigmas() {
for (unsigned i = 0; i < m_cores.size(); ++i) {
wcore& c_i = m_cores[i];
unsigned_vector const& R = c_i.m_R;
c_i.m_upper.reset();
for (unsigned j = 0; j < R.size(); ++j) {
unsigned r_j = R[j];
if (!m_assignment[r_j]) {
c_i.m_upper += m_weights[r_j];
m_sigmas[r_j] = m_weights[r_j];
}
else {
m_sigmas[r_j].reset();
}
}
c_i.m_mid = div(c_i.m_lower + c_i.m_upper, rational(2));
m_upper += c_i.m_upper;
}
}
/**
* Minimum of two (positive) numbers. Zero is treated as +infinity.
*/
rational min_z(rational const& a, rational const& b) {
if (a.is_zero()) return b;
if (b.is_zero()) return a;
if (a < b) return a;
return b;
}
rational min_of_delta(uint_set const& subC) {
rational delta(0);
for (uint_set::iterator it = subC.begin(); it != subC.end(); ++it) {
unsigned j = *it;
wcore const& core = m_cores[j];
rational new_delta = rational(1) + core.m_upper - core.m_mid;
SASSERT(new_delta.is_pos());
delta = min_z(delta, new_delta);
}
return delta;
}
rational sum_of_lower(uint_set const& subC) {
rational lower(0);
for (uint_set::iterator it = subC.begin(); it != subC.end(); ++it) {
lower += m_cores[*it].m_lower;
}
return lower;
}
rational sum_of_sigmas(unsigned_vector const& R) {
rational sum(0);
for (unsigned i = 0; i < R.size(); ++i) {
sum += m_sigmas[R[i]];
}
return sum;
}
void union_Rs(uint_set const& subC, unsigned_vector& R) {
for (uint_set::iterator it = subC.begin(); it != subC.end(); ++it) {
R.append(m_cores[*it].m_R);
}
}
rational compute_lower() {
rational result(0); rational result(0);
for (unsigned i = 0; i < cores.size(); ++i) { for (unsigned i = 0; i < m_cores.size(); ++i) {
result += cores[i].m_lower; result += m_cores[i].m_lower;
} }
return result; return result;
} }
@ -242,19 +326,21 @@ namespace opt {
} }
++j; ++j;
} }
else {
m_asm_set.remove(cores[i].m_r);
}
} }
cores.resize(j); cores.resize(j);
} }
void core2indices( void core2indices(
ptr_vector<expr> const& core, ptr_vector<expr> const& core,
obj_map<expr, unsigned> const& ans2core,
uint_set& subC, uint_set& subC,
uint_set& soft) uint_set& soft)
{ {
for (unsigned i = 0; i < core.size(); ++i) { for (unsigned i = 0; i < core.size(); ++i) {
unsigned j; unsigned j;
if (ans2core.find(core[i], j)) { if (m_relax2index.find(core[i], j)) {
subC.insert(j); subC.insert(j);
} }
else { else {
@ -268,9 +354,18 @@ namespace opt {
} }
void relax(uint_set& subC, uint_set& soft, unsigned_vector& R, rational& delta) { void relax(uint_set& subC, uint_set& soft, unsigned_vector& R, rational& delta) {
NOT_IMPLEMENTED_YET(); for (uint_set::iterator it = soft.begin(); it != soft.end(); ++it) {
R.push_back(*it);
delta = min_z(delta, m_weights[*it]);
m_asm_set.remove(m_relax[*it].get());
}
} }
void assert_cores() {
for (unsigned i = 0; i < m_cores.size(); ++i) {
assert_core(m_cores[i]);
}
}
void assert_core(wcore const& core) { void assert_core(wcore const& core) {
expr_ref fml(m); expr_ref fml(m);
vector<rational> ws; vector<rational> ws;
@ -280,8 +375,8 @@ namespace opt {
ws.push_back(m_weights[idx]); ws.push_back(m_weights[idx]);
rs.push_back(m_soft[idx].get()); // TBD: check rs.push_back(m_soft[idx].get()); // TBD: check
} }
// TBD: fml = pb.mk_le(ws.size(), ws.c_ptr(), rs.c_ptr(), core.m_mid); fml = pb.mk_le(ws.size(), ws.c_ptr(), rs.c_ptr(), core.m_mid);
NOT_IMPLEMENTED_YET(); fml = m.mk_implies(core.m_r, fml);
s().assert_expr(fml); s().assert_expr(fml);
} }
}; };
@ -1033,7 +1128,6 @@ namespace opt {
void updt_params(params_ref& p) { void updt_params(params_ref& p) {
opt_params _p(p); opt_params _p(p);
m_engine = _p.wmaxsat_engine(); m_engine = _p.wmaxsat_engine();
std::cout << m_engine << "\n";
m_maxsmt = 0; m_maxsmt = 0;
} }
}; };

View file

@ -11,7 +11,7 @@ Abstract:
Author: Author:
Anh-Dung Phan (t-anphan) 2013-10-16 Nikolaj Bjorner (nbjorner) 2014-4-17
Notes: Notes: