3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-04-28 19:35:50 +00:00

debugging lia2maxsat

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
Nikolaj Bjorner 2013-12-08 12:17:33 -08:00
parent 370a4b66de
commit ddb30c51b5
5 changed files with 104 additions and 65 deletions

View file

@ -209,8 +209,10 @@ namespace opt {
}
bool context::is_maxsat(expr* fml, expr_ref_vector& terms,
vector<rational>& weights, symbol& id, unsigned& index) {
vector<rational>& weights, rational& offset,
bool& neg, symbol& id, unsigned& index) {
if (!is_app(fml)) return false;
neg = false;
app* a = to_app(fml);
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());
@ -219,25 +221,46 @@ namespace opt {
return true;
}
app_ref term(m);
if (is_minimize(fml, term, index)) {
offset = rational::zero();
if (is_minimize(fml, term, index) &&
get_pb_sum(term, terms, weights, offset)) {
TRACE("opt", tout << "try to convert minimization" << mk_pp(term, m) << "\n";);
rational coeff(0);
// minimize 2*x + 3*y
// <=>
// (assert-soft (not x) 2)
// (assert-soft (not y) 3)
//
if (get_pb_sum(term, terms, weights, coeff) && coeff.is_zero()) {
for (unsigned i = 0; i < weights.size(); ++i) {
if (!weights[i].is_pos()) {
return false;
}
for (unsigned i = 0; i < weights.size(); ++i) {
if (weights[i].is_neg()) {
offset += weights[i];
weights[i].neg();
}
for (unsigned i = 0; i < terms.size(); ++i) {
else {
terms[i] = m.mk_not(terms[i].get());
}
return true;
}
return true;
}
if (is_maximize(fml, term, index) &&
get_pb_sum(term, terms, weights, offset)) {
TRACE("opt", tout << "try to convert maximization" << mk_pp(term, m) << "\n";);
// maximize 2*x + 3*y - z
// <=>
// (assert-soft x 2)
// (assert-soft y 3)
// (assert-soft (not z) 1)
// offset := 6
// maximize = offset - penalty
//
for (unsigned i = 0; i < weights.size(); ++i) {
if (weights[i].is_neg()) {
weights[i].neg();
terms[i] = m.mk_not(terms[i].get());
}
offset += weights[i];
}
neg = true;
return true;
}
return false;
}
@ -281,9 +304,11 @@ namespace opt {
app_ref tr(m);
expr_ref_vector terms(m);
vector<rational> weights;
rational offset;
unsigned index;
symbol id;
if (is_maxsat(fml, terms, weights, id, index)) {
bool neg;
if (is_maxsat(fml, terms, weights, offset, neg, id, index)) {
objective& obj = m_objectives[index];
if (obj.m_type != O_MAXSMT) {
// change from maximize/minimize.
@ -298,6 +323,9 @@ namespace opt {
SASSERT(obj.m_id == id);
obj.m_terms.reset();
obj.m_terms.append(terms);
obj.m_offset = offset;
obj.m_neg = neg;
TRACE("opt", tout << "maxsat: " << id << " offset:" << offset << "\n";);
}
else if (is_maximize(fml, tr, index)) {
m_objectives[index].m_term = tr;
@ -390,51 +418,47 @@ namespace opt {
void context::display_assignment(std::ostream& out) {
for (unsigned i = 0; i < m_objectives.size(); ++i) {
objective const& obj = m_objectives[i];
switch(obj.m_type) {
case O_MAXSMT: {
symbol s = obj.m_id;
if (s != symbol::null) {
out << s << " : ";
}
maxsmt* ms = m_maxsmts.find(s);
out << ms->get_value() << "\n";
break;
}
default:
break;
}
display_objective(out, obj);
out << get_upper(i) << "\n";
}
m_optsmt.display_assignment(out);
}
void context::display_range_assignment(std::ostream& out) {
for (unsigned i = 0; i < m_objectives.size(); ++i) {
for (unsigned i = 0; i < m_objectives.size(); ++i) {
objective const& obj = m_objectives[i];
switch(obj.m_type) {
case O_MAXSMT: {
symbol s = obj.m_id;
if (s != symbol::null) {
out << s << " : ";
}
maxsmt* ms = m_maxsmts.find(s);
out << "[" << ms->get_lower() << ":" << ms->get_upper() << "]\n";
break;
}
default:
break;
}
display_objective(out, obj);
out << " [" << get_lower(i) << ":" << get_upper(i) << "]\n";
}
m_optsmt.display_range_assignment(out);
}
void context::display_objective(std::ostream& out, objective const& obj) const {
switch(obj.m_type) {
case O_MAXSMT: {
symbol s = obj.m_id;
if (s != symbol::null) {
out << s << " : ";
}
break;
}
default:
out << obj.m_term << " ";
break;
}
}
expr_ref context::get_lower(unsigned idx) {
if (idx > m_objectives.size()) {
throw default_exception("index out of bounds");
}
objective const& obj = m_objectives[idx];
switch(obj.m_type) {
case O_MAXSMT:
return to_expr(m_maxsmts.find(obj.m_id)->get_lower());
case O_MAXSMT: {
rational r = m_maxsmts.find(obj.m_id)->get_lower();
if (obj.m_neg) r.neg();
r += obj.m_offset;
return to_expr(inf_eps(r));
}
case O_MINIMIZE:
case O_MAXIMIZE:
return to_expr(m_optsmt.get_lower(obj.m_index));
@ -450,8 +474,12 @@ namespace opt {
}
objective const& obj = m_objectives[idx];
switch(obj.m_type) {
case O_MAXSMT:
return to_expr(m_maxsmts.find(obj.m_id)->get_upper());
case O_MAXSMT: {
rational r = m_maxsmts.find(obj.m_id)->get_upper();
if (obj.m_neg) r.neg();
r += obj.m_offset;
return to_expr(inf_eps(r));
}
case O_MINIMIZE:
case O_MAXIMIZE:
return to_expr(m_optsmt.get_upper(obj.m_index));