3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-04-29 20:05:51 +00:00

fix pb rewriter

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
Nikolaj Bjorner 2018-03-12 11:22:05 -07:00
parent f04e805fa4
commit e7d43ed516
16 changed files with 215 additions and 129 deletions

View file

@ -15,9 +15,6 @@ Author:
Notes:
TBD: also keep track of which fresh constants are introduced
to instruct model converter to delete them.
--*/
#include "ast/rewriter/bit_blaster/bit_blaster_rewriter.h"
#include "ast/bv_decl_plugin.h"
@ -95,6 +92,8 @@ struct blaster_rewriter_cfg : public default_rewriter_cfg {
func_decl_ref_vector m_keys;
expr_ref_vector m_values;
unsigned_vector m_keyval_lim;
func_decl_ref_vector m_newbits;
unsigned_vector m_newbits_lim;
bool m_blast_mul;
bool m_blast_add;
@ -121,7 +120,8 @@ struct blaster_rewriter_cfg : public default_rewriter_cfg {
m_out(m),
m_bindings(m),
m_keys(m),
m_values(m) {
m_values(m),
m_newbits(m) {
updt_params(p);
}
@ -163,6 +163,7 @@ struct blaster_rewriter_cfg : public default_rewriter_cfg {
void push() {
m_keyval_lim.push_back(m_keys.size());
m_newbits_lim.push_back(m_newbits.size());
}
unsigned get_num_scopes() const {
@ -181,6 +182,10 @@ struct blaster_rewriter_cfg : public default_rewriter_cfg {
m_keys.resize(lim);
m_values.resize(lim);
m_keyval_lim.resize(new_sz);
lim = m_newbits_lim[new_sz];
m_newbits.shrink(lim);
m_newbits_lim.shrink(new_sz);
}
}
@ -189,10 +194,13 @@ struct blaster_rewriter_cfg : public default_rewriter_cfg {
void start_rewrite() {
m_keypos = m_keys.size();
}
void end_rewrite(obj_map<func_decl, expr*>& const2bits) {
void end_rewrite(obj_map<func_decl, expr*>& const2bits, ptr_vector<func_decl> & newbits) {
for (unsigned i = m_keypos; i < m_keys.size(); ++i) {
const2bits.insert(m_keys[i].get(), m_values[i].get());
}
for (func_decl* f : m_newbits) newbits.push_back(f);
}
template<typename V>
@ -215,6 +223,7 @@ struct blaster_rewriter_cfg : public default_rewriter_cfg {
m_out.reset();
for (unsigned i = 0; i < bv_size; i++) {
m_out.push_back(m().mk_fresh_const(0, b));
m_newbits.push_back(to_app(m_out.back())->get_decl());
}
r = mk_mkbv(m_out);
m_const2bits.insert(f, r);
@ -650,7 +659,7 @@ struct bit_blaster_rewriter::imp : public rewriter_tpl<blaster_rewriter_cfg> {
void push() { m_cfg.push(); }
void pop(unsigned s) { m_cfg.pop(s); }
void start_rewrite() { m_cfg.start_rewrite(); }
void end_rewrite(obj_map<func_decl, expr*>& const2bits) { m_cfg.end_rewrite(const2bits); }
void end_rewrite(obj_map<func_decl, expr*>& const2bits, ptr_vector<func_decl> & newbits) { m_cfg.end_rewrite(const2bits, newbits); }
unsigned get_num_scopes() const { return m_cfg.get_num_scopes(); }
};
@ -703,6 +712,6 @@ void bit_blaster_rewriter::start_rewrite() {
m_imp->start_rewrite();
}
void bit_blaster_rewriter::end_rewrite(obj_map<func_decl, expr*>& const2bits) {
m_imp->end_rewrite(const2bits);
void bit_blaster_rewriter::end_rewrite(obj_map<func_decl, expr*>& const2bits, ptr_vector<func_decl> & newbits) {
m_imp->end_rewrite(const2bits, newbits);
}

View file

@ -33,13 +33,15 @@ public:
ast_manager & m() const;
unsigned get_num_steps() const;
void cleanup();
obj_map<func_decl, expr*> const& const2bits() const;
void start_rewrite();
void end_rewrite(obj_map<func_decl, expr*>& const2bits);
void end_rewrite(obj_map<func_decl, expr*>& const2bits, ptr_vector<func_decl> & newbits);
void operator()(expr * e, expr_ref & result, proof_ref & result_proof);
void push();
void pop(unsigned num_scopes);
unsigned get_num_scopes() const;
private:
obj_map<func_decl, expr*> const& const2bits() const;
};
#endif

View file

@ -255,11 +255,11 @@ br_status pb_rewriter::mk_app_core(func_decl * f, unsigned num_args, expr * cons
rational slack(0);
m_args.reset();
m_coeffs.reset();
for (unsigned i = 0; i < sz; ++i) {
m_args.push_back(vec[i].first);
m_coeffs.push_back(vec[i].second);
SASSERT(vec[i].second.is_pos());
slack += vec[i].second;
for (auto const& kv : vec) {
m_args.push_back(kv.first);
m_coeffs.push_back(kv.second);
SASSERT(kv.second.is_pos());
slack += kv.second;
all_unit &= m_coeffs.back().is_one();
}
if (is_eq) {
@ -287,7 +287,9 @@ br_status pb_rewriter::mk_app_core(func_decl * f, unsigned num_args, expr * cons
}
else {
expr_ref_vector conj(m), disj(m);
for (unsigned i = 0; i < m_args.size(); ++i) {
unsigned j = 0;
sz = m_args.size();
for (unsigned i = 0; i < sz; ++i) {
rational& c = m_coeffs[i];
if (slack < c + k) {
conj.push_back(m_args[i]);
@ -299,29 +301,25 @@ br_status pb_rewriter::mk_app_core(func_decl * f, unsigned num_args, expr * cons
disj.push_back(m_args[i]);
}
else {
continue;
m_args[j] = m_args[i];
m_coeffs[j] = m_coeffs[i];
++j;
}
m_args[i] = m_args.back();
m_coeffs[i] = m_coeffs.back();
--i;
m_args.pop_back();
m_coeffs.pop_back();
}
sz = m_coeffs.size();
if (slack < k) {
conj.push_back(m.mk_false());
m_args.shrink(j);
m_coeffs.shrink(j);
sz = j;
if (k.is_pos() && sz > 0 && slack >= k) {
disj.push_back(m_util.mk_ge(sz, m_coeffs.c_ptr(), m_args.c_ptr(), k));
}
else if (k.is_pos() && sz > 0) {
conj.push_back(m_util.mk_ge(sz, m_coeffs.c_ptr(), m_args.c_ptr(), k));
if (!disj.empty()) {
conj.push_back(mk_or(disj));
}
result = mk_and(conj);
if (!disj.empty()) {
disj.push_back(result);
result = mk_or(disj);
}
if (!disj.empty() || conj.size() > 1) {
if (disj.size() > 1 || conj.size() > 1) {
st = BR_REWRITE3;
}
}
}
break;
}

View file

@ -45,25 +45,25 @@ void pb_rewriter_util<PBU>::unique(typename PBU::args_t& args, typename PBU::num
}
}
// remove constants
for (unsigned i = 0; i < args.size(); ++i) {
unsigned j = 0, sz = args.size();
for (unsigned i = 0; i < sz; ++i) {
if (m_util.is_true(args[i].first)) {
k -= args[i].second;
std::swap(args[i], args[args.size()-1]);
args.pop_back();
--i;
}
else if (m_util.is_false(args[i].first)) {
std::swap(args[i], args[args.size()-1]);
args.pop_back();
--i;
// no-op
}
else {
args[j++] = args[i];
}
}
args.shrink(j);
// sort and coalesce arguments:
typename PBU::compare cmp;
std::sort(args.begin(), args.end(), cmp);
// coallesce
unsigned i, j;
unsigned i;
for (i = 0, j = 1; j < args.size(); ++j) {
if (args[i].first == args[j].first) {
args[i].second += args[j].second;