3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-04-12 12:08:18 +00:00

fix tests

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
Nikolaj Bjorner 2018-06-20 08:22:15 -07:00
parent 81e5589bc8
commit 792bf6c10b
8 changed files with 81 additions and 74 deletions

View file

@ -321,10 +321,10 @@ public:
void found_optimum() { void found_optimum() {
IF_VERBOSE(1, verbose_stream() << "found optimum\n";); IF_VERBOSE(1, verbose_stream() << "found optimum\n";);
m_lower.reset(); m_lower.reset();
for (unsigned i = 0; i < m_soft.size(); ++i) { for (soft& s : m_soft) {
m_assignment[i] = m_model->is_true(m_soft[i]); s.is_true = m_model->is_true(s.s);
if (!m_assignment[i]) { if (!s.is_true) {
m_lower += m_weights[i]; m_lower += s.weight;
} }
} }
m_upper = m_lower; m_upper = m_lower;
@ -375,24 +375,22 @@ public:
} }
// 1. remove all core literals from m_asms // 1. remove all core literals from m_asms
// 2. re-add literals of higher weight than min-weight. // 2. re-add literals of higher weight than min-weight.
// 3. 'core' stores the core literals that are split afterwards // 3. 'core' stores the core literals that are
// re-encoded as assumptions, afterwards
remove_soft(core, m_asms); remove_soft(core, m_asms);
split_core(core); split_core(core);
cores.push_back(core); cores.push_back(core);
if (core.size() >= m_max_core_size) {
break; if (core.size() >= m_max_core_size) break;
} if (cores.size() >= m_max_num_cores) break;
if (cores.size() >= m_max_num_cores) {
break;
}
is_sat = check_sat_hill_climb(m_asms); is_sat = check_sat_hill_climb(m_asms);
} }
TRACE("opt", TRACE("opt",
tout << "num cores: " << cores.size() << "\n"; tout << "sat: " << is_sat << " num cores: " << cores.size() << "\n";
for (auto const& c : cores) { for (auto const& c : cores) display_vec(tout, c);
display_vec(tout, c); tout << "num assumptions: " << m_asms.size() << "\n";);
}
tout << "num satisfying: " << m_asms.size() << "\n";);
return is_sat; return is_sat;
} }
@ -411,7 +409,6 @@ public:
if (mdl->is_false(a)) { if (mdl->is_false(a)) {
cs.push_back(a); cs.push_back(a);
} }
// TRACE("opt", tout << mk_pp(a, m) << ": " << (*mdl)(a) << "\n";);
} }
TRACE("opt", display_vec(tout << "new correction set: ", cs);); TRACE("opt", display_vec(tout << "new correction set: ", cs););
} }
@ -475,8 +472,8 @@ public:
unsigned max_core_size(vector<exprs> const& cores) { unsigned max_core_size(vector<exprs> const& cores) {
unsigned result = 0; unsigned result = 0;
for (unsigned i = 0; i < cores.size(); ++i) { for (auto const& c : cores) {
result = std::max(cores[i].size(), result); result = std::max(c.size(), result);
} }
return result; return result;
} }
@ -725,13 +722,11 @@ public:
rational upper(0); rational upper(0);
unsigned i = 0; for (soft& s : m_soft) {
for (expr* s : m_soft) { TRACE("opt", tout << s.s << ": " << (*mdl)(s.s) << " " << s.weight << "\n";);
TRACE("opt", tout << mk_pp(s, m) << ": " << (*mdl)(s) << " " << m_weights[i] << "\n";); if (!mdl->is_true(s.s)) {
if (!mdl->is_true(s)) { upper += s.weight;
upper += m_weights[i];
} }
++i;
} }
if (upper > m_upper) { if (upper > m_upper) {
@ -748,9 +743,8 @@ public:
TRACE("opt", tout << "updated upper: " << upper << "\nmodel\n" << *m_model;); TRACE("opt", tout << "updated upper: " << upper << "\nmodel\n" << *m_model;);
i = 0; for (soft& s : m_soft) {
for (expr* s : m_soft) { s.is_true = m_model->is_true(s.s);
m_assignment[i++] = m_model->is_true(s);
} }
// DEBUG_CODE(verify_assignment();); // DEBUG_CODE(verify_assignment(););
@ -766,11 +760,13 @@ public:
if (!m_add_upper_bound_block) return; if (!m_add_upper_bound_block) return;
pb_util u(m); pb_util u(m);
expr_ref_vector nsoft(m); expr_ref_vector nsoft(m);
vector<rational> weights;
expr_ref fml(m); expr_ref fml(m);
for (expr* s : m_soft) { for (soft& s : m_soft) {
nsoft.push_back(mk_not(m, s)); nsoft.push_back(mk_not(m, s.s));
weights.push_back(s.weight);
} }
fml = u.mk_lt(nsoft.size(), m_weights.c_ptr(), nsoft.c_ptr(), m_upper); fml = u.mk_lt(nsoft.size(), weights.c_ptr(), nsoft.c_ptr(), m_upper);
TRACE("opt", tout << "block upper bound " << fml << "\n";);; TRACE("opt", tout << "block upper bound " << fml << "\n";);;
s().assert_expr(fml); s().assert_expr(fml);
} }
@ -832,9 +828,7 @@ public:
void verify_core(exprs const& core) { void verify_core(exprs const& core) {
IF_VERBOSE(3, verbose_stream() << "verify core\n";); IF_VERBOSE(3, verbose_stream() << "verify core\n";);
ref<solver> smt_solver = mk_smt_solver(m, m_params, symbol()); ref<solver> smt_solver = mk_smt_solver(m, m_params, symbol());
for (unsigned i = 0; i < s().get_num_assertions(); ++i) { smt_solver->assert_expr(s().get_assertions());
smt_solver->assert_expr(s().get_assertion(i));
}
smt_solver->assert_expr(core); smt_solver->assert_expr(core);
lbool is_sat = smt_solver->check_sat(0, nullptr); lbool is_sat = smt_solver->check_sat(0, nullptr);
if (is_sat == l_true) { if (is_sat == l_true) {
@ -845,13 +839,11 @@ public:
void verify_assignment() { void verify_assignment() {
IF_VERBOSE(1, verbose_stream() << "verify assignment\n";); IF_VERBOSE(1, verbose_stream() << "verify assignment\n";);
ref<solver> smt_solver = mk_smt_solver(m, m_params, symbol()); ref<solver> smt_solver = mk_smt_solver(m, m_params, symbol());
for (unsigned i = 0; i < s().get_num_assertions(); ++i) { smt_solver->assert_expr(s().get_assertions());
smt_solver->assert_expr(s().get_assertion(i));
}
expr_ref n(m); expr_ref n(m);
for (unsigned i = 0; i < m_soft.size(); ++i) { for (soft& s : m_soft) {
n = m_soft[i]; n = s.s;
if (!m_assignment[i]) { if (!s.is_true) {
n = mk_not(m, n); n = mk_not(m, n);
} }
smt_solver->assert_expr(n); smt_solver->assert_expr(n);

View file

@ -34,16 +34,17 @@ Notes:
namespace opt { namespace opt {
maxsmt_solver_base::maxsmt_solver_base( maxsmt_solver_base::maxsmt_solver_base(
maxsat_context& c, vector<rational> const& ws, expr_ref_vector const& soft): maxsat_context& c, vector<rational> const& ws, expr_ref_vector const& softs):
m(c.get_manager()), m(c.get_manager()),
m_c(c), m_c(c),
m_soft(soft),
m_weights(ws),
m_assertions(m), m_assertions(m),
m_trail(m) { m_trail(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());
for (unsigned i = 0; i < ws.size(); ++i) {
m_soft.push_back(soft(expr_ref(softs.get(i), m), ws[i], false));
}
} }
void maxsmt_solver_base::updt_params(params_ref& p) { void maxsmt_solver_base::updt_params(params_ref& p) {
@ -56,17 +57,21 @@ namespace opt {
void maxsmt_solver_base::commit_assignment() { void maxsmt_solver_base::commit_assignment() {
expr_ref tmp(m); expr_ref tmp(m);
expr_ref_vector fmls(m);
rational k(0), cost(0); rational k(0), cost(0);
for (unsigned i = 0; i < m_soft.size(); ++i) { vector<rational> weights;
if (get_assignment(i)) { for (soft const& s : m_soft) {
k += m_weights[i]; if (s.is_true) {
k += s.weight;
} }
else { else {
cost += m_weights[i]; cost += s.weight;
} }
weights.push_back(s.weight);
fmls.push_back(s.s);
} }
pb_util pb(m); pb_util pb(m);
tmp = pb.mk_ge(m_weights.size(), m_weights.c_ptr(), m_soft.c_ptr(), k); tmp = pb.mk_ge(weights.size(), weights.c_ptr(), fmls.c_ptr(), k);
TRACE("opt", tout << "cost: " << cost << "\n" << tmp << "\n";); TRACE("opt", tout << "cost: " << cost << "\n" << tmp << "\n";);
s().assert_expr(tmp); s().assert_expr(tmp);
} }
@ -74,19 +79,14 @@ namespace opt {
bool maxsmt_solver_base::init() { bool maxsmt_solver_base::init() {
m_lower.reset(); m_lower.reset();
m_upper.reset(); m_upper.reset();
m_assignment.reset(); for (soft& s : m_soft) {
for (unsigned i = 0; i < m_weights.size(); ++i) { s.is_true = m.is_true(s.s);
m_assignment.push_back(m.is_true(m_soft[i])); if (!s.is_true) m_upper += s.weight;
if (!m_assignment.back()) {
m_upper += m_weights[i];
}
} }
TRACE("opt", TRACE("opt",
tout << "upper: " << m_upper << " assignments: "; tout << "upper: " << m_upper << " assignments: ";
for (unsigned i = 0; i < m_weights.size(); ++i) { for (soft& s : m_soft) tout << (s.is_true?"T":"F");
tout << (m_assignment[i]?"T":"F");
}
tout << "\n";); tout << "\n";);
return true; return true;
} }
@ -141,6 +141,7 @@ namespace opt {
maxsmt_solver_base::scoped_ensure_theory::scoped_ensure_theory(maxsmt_solver_base& s) { maxsmt_solver_base::scoped_ensure_theory::scoped_ensure_theory(maxsmt_solver_base& s) {
m_wth = s.ensure_wmax_theory(); m_wth = s.ensure_wmax_theory();
} }
maxsmt_solver_base::scoped_ensure_theory::~scoped_ensure_theory() { maxsmt_solver_base::scoped_ensure_theory::~scoped_ensure_theory() {
if (m_wth) { if (m_wth) {
m_wth->reset_local(); m_wth->reset_local();
@ -159,11 +160,13 @@ namespace opt {
lbool maxsmt_solver_base::find_mutexes(obj_map<expr, rational>& new_soft) { lbool maxsmt_solver_base::find_mutexes(obj_map<expr, rational>& new_soft) {
m_lower.reset(); m_lower.reset();
for (unsigned i = 0; i < m_soft.size(); ++i) { expr_ref_vector fmls(m);
new_soft.insert(m_soft[i], m_weights[i]); for (soft& s : m_soft) {
new_soft.insert(s.s, s.weight);
fmls.push_back(s.s);
} }
vector<expr_ref_vector> mutexes; vector<expr_ref_vector> mutexes;
lbool is_sat = s().find_mutexes(m_soft, mutexes); lbool is_sat = s().find_mutexes(fmls, mutexes);
if (is_sat != l_true) { if (is_sat != l_true) {
return is_sat; return is_sat;
} }

View file

@ -56,17 +56,26 @@ namespace opt {
// //
class maxsmt_solver_base : public maxsmt_solver { class maxsmt_solver_base : public maxsmt_solver {
protected: protected:
struct soft {
expr_ref s;
rational weight;
bool is_true;
soft(expr_ref& s, rational const& w, bool t): s(s), weight(w), is_true(t) {}
soft(soft const& other):s(other.s), weight(other.weight), is_true(other.is_true) {}
soft& operator=(soft const& other) { s = other.s; weight = other.weight; is_true = other.is_true; return *this; }
};
ast_manager& m; ast_manager& m;
maxsat_context& m_c; maxsat_context& m_c;
const expr_ref_vector m_soft; vector<soft> m_soft;
vector<rational> m_weights;
expr_ref_vector m_assertions; expr_ref_vector m_assertions;
expr_ref_vector m_trail; expr_ref_vector m_trail;
rational m_lower; rational m_lower;
rational m_upper; rational m_upper;
model_ref m_model; model_ref m_model;
svector<symbol> m_labels; svector<symbol> m_labels;
svector<bool> m_assignment; // truth assignment to soft constraints //const expr_ref_vector m_soft;
//vector<rational> m_weights;
//svector<bool> m_assignment; // truth assignment to soft constraints
params_ref m_params; // config params_ref m_params; // config
public: public:
@ -75,7 +84,7 @@ namespace opt {
~maxsmt_solver_base() override {} ~maxsmt_solver_base() override {}
rational get_lower() const override { return m_lower; } rational get_lower() const override { return m_lower; }
rational get_upper() const override { return m_upper; } rational get_upper() const override { return m_upper; }
bool get_assignment(unsigned index) const override { return m_assignment[index]; } bool get_assignment(unsigned index) const override { return m_soft[index].is_true; }
void collect_statistics(statistics& st) const override { } void collect_statistics(statistics& st) const override { }
void get_model(model_ref& mdl, svector<symbol>& labels) override { mdl = m_model.get(); labels = m_labels;} void get_model(model_ref& mdl, svector<symbol>& labels) override { mdl = m_model.get(); labels = m_labels;}
virtual void commit_assignment(); virtual void commit_assignment();

View file

@ -114,9 +114,7 @@ namespace opt {
} }
void update_assignment() { void update_assignment() {
for (unsigned i = 0; i < m_soft.size(); ++i) { for (soft& s : m_soft) s.is_true = is_true(s.s);
m_assignment[i] = is_true(m_soft[i]);
}
} }
bool is_true(expr* e) { bool is_true(expr* e) {

View file

@ -124,10 +124,7 @@ namespace opt {
} }
void update_assignment() { void update_assignment() {
m_assignment.reset(); for (soft& s : m_soft) s.is_true = is_true(s.s);
for (unsigned i = 0; i < m_soft.size(); ++i) {
m_assignment.push_back(is_true(m_soft[i]));
}
} }
struct compare_asm { struct compare_asm {

View file

@ -64,6 +64,13 @@ void solver::get_assertions(expr_ref_vector& fmls) const {
} }
} }
expr_ref_vector solver::get_assertions() const {
expr_ref_vector result(get_manager());
get_assertions(result);
return result;
}
struct scoped_assumption_push { struct scoped_assumption_push {
expr_ref_vector& m_vec; expr_ref_vector& m_vec;
scoped_assumption_push(expr_ref_vector& v, expr* e): m_vec(v) { v.push_back(e); } scoped_assumption_push(expr_ref_vector& v, expr* e): m_vec(v) { v.push_back(e); }

View file

@ -179,6 +179,8 @@ public:
*/ */
void get_assertions(expr_ref_vector& fmls) const; void get_assertions(expr_ref_vector& fmls) const;
expr_ref_vector get_assertions() const;
/** /**
\brief The number of tracked assumptions (see assert_expr(t, a)). \brief The number of tracked assumptions (see assert_expr(t, a)).
*/ */

View file

@ -88,8 +88,7 @@ static void test(app* var, expr_ref& fml) {
std::cout << "projected: " << mk_pp(pr, m) << "\n"; std::cout << "projected: " << mk_pp(pr, m) << "\n";
// projection is consistent with model. // projection is consistent with model.
expr_ref tmp(m); VERIFY(md->is_true(pr));
VERIFY(md->eval(pr, tmp) && m.is_true(tmp));
// projection implies E x. fml // projection implies E x. fml
{ {