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:
parent
f04e805fa4
commit
e7d43ed516
16 changed files with 215 additions and 129 deletions
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue