3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-05-07 15:55:46 +00:00

enable wcnf output for weighted maxsat problems

This commit is contained in:
Nikolaj Bjorner 2021-02-28 09:59:36 -08:00
parent b02cba6106
commit 13f05ae9dc
6 changed files with 115 additions and 60 deletions

View file

@ -20,14 +20,21 @@ Revision History:
#include "ast.h"
#include "display_dimacs.h"
std::ostream& display_dimacs(std::ostream& out, expr_ref_vector const& fmls, bool include_names) {
ast_manager& m = fmls.m();
struct dimacs_pp {
ast_manager& m;
unsigned_vector expr2var;
ptr_vector<expr> exprs;
unsigned num_vars = 0;
unsigned num_cls = fmls.size();
bool is_from_dimacs = true;
for (expr * f : fmls) {
unsigned num_vars { 0 };
dimacs_pp(ast_manager& m): m(m) {}
void reset() {
num_vars = 0;
expr2var.reset();
exprs.reset();
}
bool init_from_dimacs(expr* f) {
unsigned num_lits;
expr * const * lits;
if (m.is_or(f)) {
@ -42,10 +49,8 @@ std::ostream& display_dimacs(std::ostream& out, expr_ref_vector const& fmls, boo
expr * l = lits[j];
if (m.is_not(l))
l = to_app(l)->get_arg(0);
if (!is_uninterp_const(l)) {
is_from_dimacs = false;
break;
}
if (!is_uninterp_const(l))
return false;
symbol const& s = to_app(l)->get_decl()->get_name();
if (s.is_numerical() && s.get_num() > 0) {
if (expr2var.get(l->get_id(), UINT_MAX) == UINT_MAX) {
@ -55,43 +60,35 @@ std::ostream& display_dimacs(std::ostream& out, expr_ref_vector const& fmls, boo
}
continue;
}
is_from_dimacs = false;
break;
return false;
}
if (!is_from_dimacs) {
num_vars = 0;
expr2var.reset();
exprs.reset();
break;
return true;
}
void init_formula(expr* f) {
unsigned num_lits;
expr * const * lits;
if (m.is_or(f)) {
num_lits = to_app(f)->get_num_args();
lits = to_app(f)->get_args();
}
}
if (!is_from_dimacs) {
for (expr * f : fmls) {
unsigned num_lits;
expr * const * lits;
if (m.is_or(f)) {
num_lits = to_app(f)->get_num_args();
lits = to_app(f)->get_args();
}
else {
num_lits = 1;
lits = &f;
}
for (unsigned j = 0; j < num_lits; j++) {
expr * l = lits[j];
if (m.is_not(l))
l = to_app(l)->get_arg(0);
if (expr2var.get(l->get_id(), UINT_MAX) == UINT_MAX) {
num_vars++;
expr2var.setx(l->get_id(), num_vars, UINT_MAX);
exprs.setx(l->get_id(), l, nullptr);
}
else {
num_lits = 1;
lits = &f;
}
for (unsigned j = 0; j < num_lits; j++) {
expr * l = lits[j];
if (m.is_not(l))
l = to_app(l)->get_arg(0);
if (expr2var.get(l->get_id(), UINT_MAX) == UINT_MAX) {
num_vars++;
expr2var.setx(l->get_id(), num_vars, UINT_MAX);
exprs.setx(l->get_id(), l, nullptr);
}
}
}
out << "p cnf " << num_vars << " " << num_cls << "\n";
for (expr* f : fmls) {
void pp_formula(std::ostream& out, expr* f) {
unsigned num_lits;
expr * const * lits;
if (m.is_or(f)) {
@ -113,18 +110,61 @@ std::ostream& display_dimacs(std::ostream& out, expr_ref_vector const& fmls, boo
}
out << "0\n";
}
if (include_names && !is_from_dimacs) {
for (expr* e : exprs) {
void pp_defs(std::ostream& out) {
for (expr* e : exprs)
if (e && is_app(e)) {
symbol const& n = to_app(e)->get_decl()->get_name();
out << "c " << expr2var[e->get_id()] << " " << n << "\n";
}
}
};
std::ostream& display_dimacs(std::ostream& out, expr_ref_vector const& fmls, bool include_names) {
ast_manager& m = fmls.m();
dimacs_pp pp(m);
unsigned num_cls = fmls.size();
bool is_from_dimacs = true;
for (expr * f : fmls) {
is_from_dimacs = pp.init_from_dimacs(f);
if (!is_from_dimacs)
break;
}
if (!is_from_dimacs) {
pp.reset();
for (expr * f : fmls) {
pp.init_formula(f);
}
}
out << "p cnf " << pp.num_vars << " " << num_cls << "\n";
for (expr* f : fmls)
pp.pp_formula(out, f);
if (include_names && !is_from_dimacs)
pp.pp_defs(out);
return out;
}
std::ostream& display_wcnf(std::ostream& out, expr_ref_vector const& fmls, vector<std::pair<expr*,unsigned>> const& soft, bool include_names) {
NOT_IMPLEMENTED_YET();
std::ostream& display_wcnf(std::ostream& out, expr_ref_vector const& fmls, svector<std::pair<expr*,unsigned>> const& soft) {
ast_manager& m = fmls.m();
dimacs_pp pp(m);
for (expr* f : fmls)
pp.init_formula(f);
for (auto s : soft)
pp.init_formula(s.first);
out << "p wcnf " << pp.num_vars << " " << fmls.size() + soft.size() << "\n";
unsigned sum_soft = 1;
for (auto s : soft)
sum_soft += s.second;
for (expr* f : fmls) {
out << sum_soft << " ";
pp.pp_formula(out, f);
}
for (auto s : soft) {
out << s.second << " ";
pp.pp_formula(out, s.first);
}
pp.pp_defs(out);
return out;
}