mirror of
https://github.com/Z3Prover/z3
synced 2025-04-28 11:25:51 +00:00
arrays (#4684)
* arrays Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com> * arrays Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com> * na Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com> * arrays Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com> * na Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com> * fill Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com> * update drat and fix euf bugs Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com> * na Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com> * na Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com> * na Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com> * const qualifiers Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com> * na Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com> * reorg ba Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com> * reorg Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com> * build warnings Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
parent
d56dd1db7b
commit
796e2fd9eb
79 changed files with 2571 additions and 1850 deletions
|
@ -53,7 +53,7 @@ namespace array {
|
|||
mdl.register_decl(f, fi);
|
||||
|
||||
for (euf::enode* p : euf::enode_parents(n)) {
|
||||
if (!a.is_select(p->get_expr()))
|
||||
if (!a.is_select(p->get_expr()) || p->get_arg(0)->get_root() != n->get_root())
|
||||
continue;
|
||||
args.reset();
|
||||
for (unsigned i = 1; i < p->num_args(); ++i)
|
||||
|
@ -74,4 +74,73 @@ namespace array {
|
|||
values.set(n->get_root_id(), m.mk_app(get_id(), OP_AS_ARRAY, 1, &p));
|
||||
}
|
||||
|
||||
|
||||
bool solver::have_different_model_values(theory_var v1, theory_var v2) {
|
||||
euf::enode* else1 = nullptr, * else2 = nullptr;
|
||||
euf::enode* n1 = var2enode(v1), *n2 = var2enode(v2);
|
||||
euf::enode* r1 = n1->get_root(), * r2 = n2->get_root();
|
||||
expr* e1 = n1->get_expr();
|
||||
expr* e;
|
||||
if (!a.is_array(e1))
|
||||
return true;
|
||||
auto find_else = [&](theory_var v, euf::enode* r) {
|
||||
var_data& d = get_var_data(find(v));
|
||||
for (euf::enode* c : d.m_lambdas)
|
||||
if (a.is_const(c->get_expr(), e))
|
||||
return expr2enode(e)->get_root();
|
||||
for (euf::enode* p : euf::enode_parents(r))
|
||||
for (euf::enode* pe : euf::enode_class(p))
|
||||
if (a.is_default(pe->get_expr()))
|
||||
return pe->get_root();
|
||||
return (euf::enode*)nullptr;
|
||||
};
|
||||
else1 = find_else(v1, r1);
|
||||
else2 = find_else(v2, r2);
|
||||
if (else1 && else2 && else1->get_root() != else2->get_root() && has_large_domain(e1))
|
||||
return true;
|
||||
struct eq {
|
||||
solver& s;
|
||||
eq(solver& s) :s(s) {}
|
||||
bool operator()(euf::enode* n1, euf::enode* n2) const {
|
||||
SASSERT(s.a.is_select(n1->get_expr()));
|
||||
SASSERT(s.a.is_select(n2->get_expr()));
|
||||
for (unsigned i = n1->num_args(); i-- > 1; )
|
||||
if (n1->get_arg(i)->get_root() != n2->get_arg(i)->get_root())
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
};
|
||||
struct hash {
|
||||
solver& s;
|
||||
hash(solver& s) :s(s) {}
|
||||
unsigned operator()(euf::enode* n) const {
|
||||
SASSERT(s.a.is_select(n->get_expr()));
|
||||
unsigned h = 33;
|
||||
for (unsigned i = n->num_args(); i-- > 1; )
|
||||
h = hash_u_u(h, n->get_arg(i)->get_root_id());
|
||||
return h;
|
||||
}
|
||||
};
|
||||
eq eq_proc(*this);
|
||||
hash hash_proc(*this);
|
||||
hashtable<euf::enode*, hash, eq> table(DEFAULT_HASHTABLE_INITIAL_CAPACITY, hash_proc, eq_proc);
|
||||
euf::enode* p2 = nullptr;
|
||||
auto maps_diff = [&](euf::enode* p, euf::enode* else_, euf::enode* r) {
|
||||
return table.find(p, p2) ? p2->get_root() != r : (else_ && else_ != r);
|
||||
};
|
||||
auto table_diff = [&](euf::enode* r1, euf::enode* r2, euf::enode* else1) {
|
||||
table.reset();
|
||||
for (euf::enode* p : euf::enode_parents(r1))
|
||||
if (a.is_select(p->get_expr()) && r1 == p->get_arg(0)->get_root())
|
||||
table.insert(p);
|
||||
for (euf::enode* p : euf::enode_parents(r2))
|
||||
if (a.is_select(p->get_expr()) && r2 == p->get_arg(0)->get_root())
|
||||
if (maps_diff(p, else1, p->get_root()))
|
||||
return true;
|
||||
return false;
|
||||
};
|
||||
|
||||
return table_diff(r1, r2, else1) || table_diff(r2, r1, else2);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue