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

(mev) bug fix in expanding array equalities

The stores were processed in the wrong order so that

  (store (store a x y) x u)

was reduced to

  (store a x y)

instead of

  (store a x u)
This commit is contained in:
Arie Gurfinkel 2017-06-21 20:54:22 -04:00
parent e62e563e2d
commit d5ca902bf6

View file

@ -291,13 +291,13 @@ struct evaluator_cfg : public default_rewriter_cfg {
else { else {
conj.push_back(m().mk_eq(else1, else2)); conj.push_back(m().mk_eq(else1, else2));
} }
args1.push_back(a);
args2.push_back(b);
if (args_are_unique1 && args_are_unique2 && !stores1.empty()) { if (args_are_unique1 && args_are_unique2 && !stores1.empty()) {
return mk_array_eq(stores1, else1, stores2, else2, conj, result); return mk_array_eq_core(stores1, else1, stores2, else2, conj, result);
} }
// TBD: this is too inefficient. // TBD: this is too inefficient.
args1.push_back(a);
args2.push_back(b);
stores1.append(stores2); stores1.append(stores2);
for (unsigned i = 0; i < stores1.size(); ++i) { for (unsigned i = 0; i < stores1.size(); ++i) {
args1.resize(1); args1.append(stores1[i].size() - 1, stores1[i].c_ptr()); args1.resize(1); args1.append(stores1[i].size() - 1, stores1[i].c_ptr());
@ -338,20 +338,22 @@ struct evaluator_cfg : public default_rewriter_cfg {
typedef hashtable<expr*const*, args_hash, args_eq> args_table; typedef hashtable<expr*const*, args_hash, args_eq> args_table;
br_status mk_array_eq(vector<expr_ref_vector> const& stores1, expr* else1, br_status mk_array_eq_core(vector<expr_ref_vector> const& stores1, expr* else1,
vector<expr_ref_vector> const& stores2, expr* else2, vector<expr_ref_vector> const& stores2, expr* else2,
expr_ref_vector& conj, expr_ref& result) { expr_ref_vector& conj, expr_ref& result) {
unsigned arity = stores1[0].size()-1; // TBD: fix arity. unsigned arity = stores1[0].size()-1; // TBD: fix arity.
args_hash ah(arity); args_hash ah(arity);
args_eq ae(arity); args_eq ae(arity);
args_table table1(DEFAULT_HASHTABLE_INITIAL_CAPACITY, ah, ae); args_table table1(DEFAULT_HASHTABLE_INITIAL_CAPACITY, ah, ae);
args_table table2(DEFAULT_HASHTABLE_INITIAL_CAPACITY, ah, ae); args_table table2(DEFAULT_HASHTABLE_INITIAL_CAPACITY, ah, ae);
for (unsigned i = 0; i < stores1.size(); ++i) { // stores with smaller index take precedence
for (unsigned i = stores1.size(); i > 0; ) {
--i;
table1.insert(stores1[i].c_ptr()); table1.insert(stores1[i].c_ptr());
} }
for (unsigned i = stores2.size(); i > 0; ) {
--i; for (unsigned i = 0, sz = stores2.size(); i < sz; ++i) {
if (table2.contains(stores2[i].c_ptr())) { if (table2.contains(stores2[i].c_ptr())) {
// first insertion takes precedence. // first insertion takes precedence.
continue; continue;
@ -361,7 +363,7 @@ struct evaluator_cfg : public default_rewriter_cfg {
expr* val = stores2[i][arity]; expr* val = stores2[i][arity];
if (table1.find(stores2[i].c_ptr(), args)) { if (table1.find(stores2[i].c_ptr(), args)) {
switch (compare(args[arity], val)) { switch (compare(args[arity], val)) {
case l_true: table1.remove(stores2[i].c_ptr()); break; case l_true: table1.remove(args); break;
case l_false: result = m().mk_false(); return BR_DONE; case l_false: result = m().mk_false(); return BR_DONE;
default: conj.push_back(m().mk_eq(val, args[arity])); break; default: conj.push_back(m().mk_eq(val, args[arity])); break;
} }