3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-04-23 09:05:31 +00:00

fix at-most-1 constraint compiler bug

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
Nikolaj Bjorner 2016-10-22 18:50:16 -07:00
parent bb6d826908
commit 23b9d3ef55
17 changed files with 369 additions and 62 deletions

View file

@ -297,12 +297,16 @@ public:
sort_assumptions(mutex);
ptr_vector<expr> core(mutex.size(), mutex.c_ptr());
remove_soft(core, m_asms);
rational weight(0);
rational weight(0), sum1(0), sum2(0);
for (unsigned i = 0; i < mutex.size(); ++i) {
sum1 += get_weight(mutex[i].get());
}
while (!mutex.empty()) {
expr_ref soft = mk_or(mutex);
rational w = get_weight(mutex.back());
weight = w - weight;
m_lower += weight*rational(mutex.size()-1);
sum2 += weight*rational(mutex.size());
add_soft(soft, weight);
mutex.pop_back();
while (!mutex.empty() && get_weight(mutex.back()) == w) {
@ -310,6 +314,7 @@ public:
}
weight = w;
}
SASSERT(sum1 == sum2);
}
lbool check_sat_hill_climb(expr_ref_vector& asms1) {
@ -398,7 +403,7 @@ public:
while (is_sat == l_false) {
core.reset();
s().get_unsat_core(core);
//verify_core(core);
// verify_core(core);
model_ref mdl;
get_mus_model(mdl);
is_sat = minimize_core(core);
@ -772,8 +777,6 @@ public:
for (unsigned i = 0; i < m_soft.size(); ++i) {
m_assignment[i] = is_true(m_soft[i]);
}
DEBUG_CODE(verify_assignment(););

View file

@ -181,6 +181,43 @@ namespace opt {
clear_state();
}
void context::get_hard_constraints(expr_ref_vector& hard) {
hard.append(m_scoped_state.m_hard);
}
expr_ref context::get_objective(unsigned i) {
SASSERT(i < num_objectives());
objective const& o = m_scoped_state.m_objectives[i];
expr_ref result(m), zero(m);
expr_ref_vector args(m);
switch (o.m_type) {
case O_MAXSMT:
zero = m_arith.mk_numeral(rational(0), false);
for (unsigned i = 0; i < o.m_terms.size(); ++i) {
args.push_back(m.mk_ite(o.m_terms[i], zero, m_arith.mk_numeral(o.m_weights[i], false)));
}
result = m_arith.mk_add(args.size(), args.c_ptr());
break;
case O_MAXIMIZE:
result = o.m_term;
if (m_arith.is_arith_expr(result)) {
result = m_arith.mk_uminus(result);
}
else if (m_bv.is_bv(result)) {
result = m_bv.mk_bv_neg(result);
}
else {
UNREACHABLE();
}
break;
case O_MINIMIZE:
result = o.m_term;
break;
}
return result;
}
unsigned context::add_soft_constraint(expr* f, rational const& w, symbol const& id) {
clear_state();
return m_scoped_state.add(f, w, id);
@ -1328,14 +1365,21 @@ namespace opt {
}
std::string context::to_string() const {
return to_string(m_scoped_state.m_hard, m_scoped_state.m_objectives);
}
std::string context::to_string_internal() const {
return to_string(m_hard_constraints, m_objectives);
}
std::string context::to_string(expr_ref_vector const& hard, vector<objective> const& objectives) const {
smt2_pp_environment_dbg env(m);
ast_pp_util visitor(m);
std::ostringstream out;
#define PP(_e_) ast_smt2_pp(out, _e_, env);
visitor.collect(m_scoped_state.m_hard);
visitor.collect(hard);
for (unsigned i = 0; i < m_scoped_state.m_objectives.size(); ++i) {
objective const& obj = m_scoped_state.m_objectives[i];
for (unsigned i = 0; i < objectives.size(); ++i) {
objective const& obj = objectives[i];
switch(obj.m_type) {
case O_MAXIMIZE:
case O_MINIMIZE:
@ -1351,33 +1395,34 @@ namespace opt {
}
visitor.display_decls(out);
visitor.display_asserts(out, m_scoped_state.m_hard, m_pp_neat);
for (unsigned i = 0; i < m_scoped_state.m_objectives.size(); ++i) {
objective const& obj = m_scoped_state.m_objectives[i];
visitor.display_asserts(out, hard, m_pp_neat);
for (unsigned i = 0; i < objectives.size(); ++i) {
objective const& obj = objectives[i];
switch(obj.m_type) {
case O_MAXIMIZE:
out << "(maximize ";
PP(obj.m_term);
ast_smt2_pp(out, obj.m_term, env);
out << ")\n";
break;
case O_MINIMIZE:
out << "(minimize ";
PP(obj.m_term);
ast_smt2_pp(out, obj.m_term, env);
out << ")\n";
break;
case O_MAXSMT:
for (unsigned j = 0; j < obj.m_terms.size(); ++j) {
out << "(assert-soft ";
PP(obj.m_terms[j]);
ast_smt2_pp(out, obj.m_terms[j], env);
rational w = obj.m_weights[j];
if (w.is_int()) {
out << " :weight " << w;
}
else {
out << " :dweight " << w;
}
w.display_decimal(out << " :weight ", 3, true);
if (obj.m_id != symbol::null) {
out << " :id " << obj.m_id;
if (is_smt2_quoted_symbol(obj.m_id)) {
out << " :id " << mk_smt2_quoted_symbol(obj.m_id);
}
else {
out << " :id " << obj.m_id;
}
}
out << ")\n";
}

View file

@ -175,6 +175,8 @@ namespace opt {
unsigned add_objective(app* t, bool is_max);
void add_hard_constraint(expr* f);
void get_hard_constraints(expr_ref_vector& hard);
expr_ref get_objective(unsigned i);
virtual void push();
virtual void pop(unsigned n);
@ -208,7 +210,7 @@ namespace opt {
std::string to_string() const;
virtual unsigned num_objectives() { return m_objectives.size(); }
virtual unsigned num_objectives() { return m_scoped_state.m_objectives.size(); }
virtual expr_ref mk_gt(unsigned i, model_ref& model);
virtual expr_ref mk_ge(unsigned i, model_ref& model);
virtual expr_ref mk_le(unsigned i, model_ref& model);
@ -284,6 +286,9 @@ namespace opt {
void display_objective(std::ostream& out, objective const& obj) const;
void display_bounds(std::ostream& out, bounds_t const& b) const;
std::string to_string(expr_ref_vector const& hard, vector<objective> const& objectives) const;
std::string to_string_internal() const;
void validate_lex();