mirror of
https://github.com/Z3Prover/z3
synced 2025-04-23 09:05:31 +00:00
move theory_var_list into id_var_list and utilities from smt-enode into it, prepare for theory variables in egraph
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
parent
fa9cf0fa0c
commit
d4e92d4aca
11 changed files with 332 additions and 193 deletions
|
@ -781,10 +781,10 @@ namespace smt {
|
|||
|
||||
if (r2->m_th_var_list.get_next() == nullptr && r1->m_th_var_list.get_next() == nullptr) {
|
||||
// Common case: r2 and r1 have at most one theory var.
|
||||
theory_id t2 = r2->m_th_var_list.get_th_id();
|
||||
theory_id t1 = r1->m_th_var_list.get_th_id();
|
||||
theory_var v2 = m_fparams.m_new_core2th_eq ? get_closest_var(n2, t2) : r2->m_th_var_list.get_th_var();
|
||||
theory_var v1 = m_fparams.m_new_core2th_eq ? get_closest_var(n1, t1) : r1->m_th_var_list.get_th_var();
|
||||
theory_id t2 = r2->m_th_var_list.get_id();
|
||||
theory_id t1 = r1->m_th_var_list.get_id();
|
||||
theory_var v2 = m_fparams.m_new_core2th_eq ? get_closest_var(n2, t2) : r2->m_th_var_list.get_var();
|
||||
theory_var v1 = m_fparams.m_new_core2th_eq ? get_closest_var(n1, t1) : r1->m_th_var_list.get_var();
|
||||
TRACE("merge_theory_vars",
|
||||
tout << "v2: " << v2 << " #" << r2->get_owner_id() << ", v1: " << v1 << " #" << r1->get_owner_id()
|
||||
<< ", t2: " << t2 << ", t1: " << t1 << "\n";);
|
||||
|
@ -805,8 +805,8 @@ namespace smt {
|
|||
push_new_th_diseqs(r1, v2, get_theory(t2));
|
||||
}
|
||||
else if (v1 != null_theory_var && v2 == null_theory_var) {
|
||||
r2->m_th_var_list.set_th_var(v1);
|
||||
r2->m_th_var_list.set_th_id(t1);
|
||||
r2->m_th_var_list.set_var(v1);
|
||||
r2->m_th_var_list.set_id(t1);
|
||||
TRACE("merge_theory_vars", tout << "push_new_th_diseqs v1: " << v1 << ", t1: " << t1 << "\n";);
|
||||
push_new_th_diseqs(r2, v1, get_theory(t1));
|
||||
}
|
||||
|
@ -819,8 +819,8 @@ namespace smt {
|
|||
|
||||
theory_var_list * l2 = r2->get_th_var_list();
|
||||
while (l2) {
|
||||
theory_id t2 = l2->get_th_id();
|
||||
theory_var v2 = m_fparams.m_new_core2th_eq ? get_closest_var(n2, t2) : l2->get_th_var();
|
||||
theory_id t2 = l2->get_id();
|
||||
theory_var v2 = m_fparams.m_new_core2th_eq ? get_closest_var(n2, t2) : l2->get_var();
|
||||
SASSERT(v2 != null_theory_var);
|
||||
SASSERT(t2 != null_theory_id);
|
||||
theory_var v1 = m_fparams.m_new_core2th_eq ? get_closest_var(n1, t2) : r1->get_th_var(t2);
|
||||
|
@ -838,8 +838,8 @@ namespace smt {
|
|||
|
||||
theory_var_list * l1 = r1->get_th_var_list();
|
||||
while (l1) {
|
||||
theory_id t1 = l1->get_th_id();
|
||||
theory_var v1 = m_fparams.m_new_core2th_eq ? get_closest_var(n1, t1) : l1->get_th_var();
|
||||
theory_id t1 = l1->get_id();
|
||||
theory_var v1 = m_fparams.m_new_core2th_eq ? get_closest_var(n1, t1) : l1->get_var();
|
||||
SASSERT(v1 != null_theory_var);
|
||||
SASSERT(t1 != null_theory_id);
|
||||
theory_var v2 = r2->get_th_var(t1);
|
||||
|
@ -973,13 +973,13 @@ namespace smt {
|
|||
// restore theory vars
|
||||
if (r2->m_th_var_list.get_next() == nullptr) {
|
||||
// common case: r2 has at most one variable
|
||||
theory_var v2 = r2->m_th_var_list.get_th_var();
|
||||
theory_var v2 = r2->m_th_var_list.get_var();
|
||||
if (v2 != null_theory_var) {
|
||||
theory_id t2 = r2->m_th_var_list.get_th_id();
|
||||
theory_id t2 = r2->m_th_var_list.get_id();
|
||||
if (get_theory(t2)->get_enode(v2)->get_root() != r2) {
|
||||
SASSERT(get_theory(t2)->get_enode(v2)->get_root() == r1);
|
||||
r2->m_th_var_list.set_th_var(null_theory_var); //remove variable from r2
|
||||
r2->m_th_var_list.set_th_id(null_theory_id);
|
||||
r2->m_th_var_list.set_var(null_theory_var); //remove variable from r2
|
||||
r2->m_th_var_list.set_id(null_theory_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1019,8 +1019,8 @@ namespace smt {
|
|||
theory_var_list * new_l2 = nullptr;
|
||||
theory_var_list * l2 = r2->get_th_var_list();
|
||||
while (l2) {
|
||||
theory_var v2 = l2->get_th_var();
|
||||
theory_id t2 = l2->get_th_id();
|
||||
theory_var v2 = l2->get_var();
|
||||
theory_id t2 = l2->get_id();
|
||||
|
||||
if (get_theory(t2)->get_enode(v2)->get_root() != r2) {
|
||||
SASSERT(get_theory(t2)->get_enode(v2)->get_root() == r1);
|
||||
|
@ -1043,7 +1043,7 @@ namespace smt {
|
|||
new_l2->set_next(nullptr);
|
||||
}
|
||||
else {
|
||||
r2->m_th_var_list.set_th_var(null_theory_var);
|
||||
r2->m_th_var_list.set_var(null_theory_var);
|
||||
r2->m_th_var_list.set_next(nullptr);
|
||||
}
|
||||
}
|
||||
|
@ -1070,7 +1070,7 @@ namespace smt {
|
|||
TRACE("add_diseq_inconsistent", tout << "add_diseq #" << n1->get_owner_id() << " #" << n2->get_owner_id() << " inconsistency, scope_lvl: " << m_scope_lvl << "\n";);
|
||||
//return false;
|
||||
|
||||
theory_id t1 = r1->m_th_var_list.get_th_id();
|
||||
theory_id t1 = r1->m_th_var_list.get_id();
|
||||
if (t1 == null_theory_id) return false;
|
||||
return get_theory(t1)->use_diseqs();
|
||||
}
|
||||
|
@ -1078,15 +1078,15 @@ namespace smt {
|
|||
// Propagate disequalities to theories
|
||||
if (r1->m_th_var_list.get_next() == nullptr && r2->m_th_var_list.get_next() == nullptr) {
|
||||
// common case: r2 and r1 have at most one theory var.
|
||||
theory_id t1 = r1->m_th_var_list.get_th_id();
|
||||
theory_var v1 = m_fparams.m_new_core2th_eq ? get_closest_var(n1, t1) : r1->m_th_var_list.get_th_var();
|
||||
theory_var v2 = m_fparams.m_new_core2th_eq ? get_closest_var(n2, t1) : r2->m_th_var_list.get_th_var();
|
||||
theory_id t1 = r1->m_th_var_list.get_id();
|
||||
theory_var v1 = m_fparams.m_new_core2th_eq ? get_closest_var(n1, t1) : r1->m_th_var_list.get_var();
|
||||
theory_var v2 = m_fparams.m_new_core2th_eq ? get_closest_var(n2, t1) : r2->m_th_var_list.get_var();
|
||||
TRACE("add_diseq", tout << "one theory diseq\n";
|
||||
tout << v1 << " != " << v2 << "\n";
|
||||
tout << "th1: " << t1 << " th2: " << r2->m_th_var_list.get_th_id() << "\n";
|
||||
tout << "th1: " << t1 << " th2: " << r2->m_th_var_list.get_id() << "\n";
|
||||
);
|
||||
if (t1 != null_theory_id && v1 != null_theory_var && v2 != null_theory_var &&
|
||||
t1 == r2->m_th_var_list.get_th_id()) {
|
||||
t1 == r2->m_th_var_list.get_id()) {
|
||||
if (get_theory(t1)->use_diseqs())
|
||||
push_new_th_diseq(t1, v1, v2);
|
||||
}
|
||||
|
@ -1094,8 +1094,8 @@ namespace smt {
|
|||
else {
|
||||
theory_var_list * l1 = r1->get_th_var_list();
|
||||
while (l1) {
|
||||
theory_id t1 = l1->get_th_id();
|
||||
theory_var v1 = m_fparams.m_new_core2th_eq ? get_closest_var(n1, t1) : l1->get_th_var();
|
||||
theory_id t1 = l1->get_id();
|
||||
theory_var v1 = m_fparams.m_new_core2th_eq ? get_closest_var(n1, t1) : l1->get_var();
|
||||
theory * th = get_theory(t1);
|
||||
TRACE("add_diseq", tout << m.get_family_name(t1) << "\n";);
|
||||
if (th->use_diseqs()) {
|
||||
|
@ -1586,7 +1586,7 @@ namespace smt {
|
|||
enode * e = get_enode(n);
|
||||
theory_var_list * l = e->get_th_var_list();
|
||||
while (l) {
|
||||
theory_id th_id = l->get_th_id();
|
||||
theory_id th_id = l->get_id();
|
||||
theory * th = get_theory(th_id);
|
||||
// I don't want to invoke relevant_eh twice for the same n.
|
||||
if (th != propagated_th)
|
||||
|
@ -4509,7 +4509,7 @@ namespace smt {
|
|||
// contains a parent application.
|
||||
|
||||
theory_var_list * l = n->get_th_var_list();
|
||||
theory_id th_id = l->get_th_id();
|
||||
theory_id th_id = l->get_id();
|
||||
|
||||
for (enode * parent : enode::parents(n)) {
|
||||
app* p = parent->get_owner();
|
||||
|
@ -4548,7 +4548,7 @@ namespace smt {
|
|||
// the theories of (array int int) and (array (array int int) int).
|
||||
// Remark: The inconsistency is not going to be detected if they are
|
||||
// not marked as shared.
|
||||
return get_theory(th_id)->is_shared(l->get_th_var());
|
||||
return get_theory(th_id)->is_shared(l->get_var());
|
||||
}
|
||||
default:
|
||||
return true;
|
||||
|
|
|
@ -282,7 +282,7 @@ namespace smt {
|
|||
<< mk_pp(m.get_sort(lhs->get_owner()), m) << "\n";);
|
||||
theory_var_list * l = lhs->get_th_var_list();
|
||||
while (l) {
|
||||
theory_id th_id = l->get_th_id();
|
||||
theory_id th_id = l->get_id();
|
||||
theory * th = get_theory(th_id);
|
||||
TRACE("check_th_diseq_propagation", tout << "checking theory: " << m.get_family_name(th_id) << "\n";);
|
||||
// if the theory doesn't use diseqs, then the diseqs are not propagated.
|
||||
|
|
|
@ -93,13 +93,7 @@ namespace smt {
|
|||
}
|
||||
|
||||
unsigned enode::get_num_th_vars() const {
|
||||
unsigned r = 0;
|
||||
theory_var_list const * l = get_th_var_list();
|
||||
while(l) {
|
||||
r++;
|
||||
l = l->get_next();
|
||||
}
|
||||
return r;
|
||||
return m_th_var_list.size();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -109,44 +103,14 @@ namespace smt {
|
|||
with a variable of theory th_id
|
||||
*/
|
||||
theory_var enode::get_th_var(theory_id th_id) const {
|
||||
if (m_th_var_list.get_th_var() == null_theory_var)
|
||||
return null_theory_var;
|
||||
theory_var_list const * l = &m_th_var_list;
|
||||
while (l) {
|
||||
if (l->get_th_id() == th_id) {
|
||||
return l->get_th_var();
|
||||
}
|
||||
l = l->get_next();
|
||||
}
|
||||
return null_theory_var;
|
||||
return m_th_var_list.find(th_id);
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Add the entry (v, id) to the list of theory variables.
|
||||
*/
|
||||
void enode::add_th_var(theory_var v, theory_id id, region & r) {
|
||||
#ifdef Z3DEBUG
|
||||
unsigned old_size = get_num_th_vars();
|
||||
#endif
|
||||
SASSERT(get_th_var(id) == null_theory_var);
|
||||
if (m_th_var_list.get_th_var() == null_theory_var) {
|
||||
m_th_var_list.set_th_var(v);
|
||||
m_th_var_list.set_th_id(id);
|
||||
m_th_var_list.set_next(nullptr);
|
||||
}
|
||||
else {
|
||||
theory_var_list * l = &m_th_var_list;
|
||||
while (l->get_next() != nullptr) {
|
||||
SASSERT(l->get_th_id() != id);
|
||||
l = l->get_next();
|
||||
}
|
||||
SASSERT(l);
|
||||
SASSERT(l->get_next() == 0);
|
||||
theory_var_list * new_cell = new (r) theory_var_list(id, v);
|
||||
l->set_next(new_cell);
|
||||
}
|
||||
SASSERT(get_num_th_vars() == old_size + 1);
|
||||
SASSERT(get_th_var(id) == v);
|
||||
m_th_var_list.add_var(v, id, r);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -154,16 +118,7 @@ namespace smt {
|
|||
The enode must have an entry (v', id)
|
||||
*/
|
||||
void enode::replace_th_var(theory_var v, theory_id id) {
|
||||
SASSERT(get_th_var(id) != null_theory_var);
|
||||
theory_var_list * l = get_th_var_list();
|
||||
while (l) {
|
||||
if (l->get_th_id() == id) {
|
||||
l->set_th_var(v);
|
||||
return;
|
||||
}
|
||||
l = l->get_next();
|
||||
}
|
||||
UNREACHABLE();
|
||||
m_th_var_list.replace(v, id);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -171,33 +126,7 @@ namespace smt {
|
|||
enode is associated with a variable of the given theory.
|
||||
*/
|
||||
void enode::del_th_var(theory_id id) {
|
||||
SASSERT(get_th_var(id) != null_theory_var);
|
||||
if (m_th_var_list.get_th_id() == id) {
|
||||
theory_var_list * next = m_th_var_list.get_next();
|
||||
if (next == nullptr) {
|
||||
// most common case
|
||||
m_th_var_list.set_th_var(null_theory_var);
|
||||
m_th_var_list.set_th_id(null_theory_id);
|
||||
m_th_var_list.set_next(nullptr);
|
||||
}
|
||||
else {
|
||||
m_th_var_list = *next;
|
||||
}
|
||||
}
|
||||
else {
|
||||
theory_var_list * prev = get_th_var_list();
|
||||
theory_var_list * l = prev->get_next();
|
||||
while (l) {
|
||||
SASSERT(prev->get_next() == l);
|
||||
if (l->get_th_id() == id) {
|
||||
prev->set_next(l->get_next());
|
||||
return;
|
||||
}
|
||||
prev = l;
|
||||
l = l->get_next();
|
||||
}
|
||||
UNREACHABLE();
|
||||
}
|
||||
m_th_var_list.del_var(id);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -18,11 +18,12 @@ Revision History:
|
|||
--*/
|
||||
#pragma once
|
||||
|
||||
#include "util/id_var_list.h"
|
||||
#include "util/approx_set.h"
|
||||
#include "ast/ast.h"
|
||||
#include "smt/smt_types.h"
|
||||
#include "smt/smt_eq_justification.h"
|
||||
#include "smt/smt_theory_var_list.h"
|
||||
#include "util/approx_set.h"
|
||||
|
||||
|
||||
namespace smt {
|
||||
|
||||
|
@ -48,6 +49,7 @@ namespace smt {
|
|||
unknown performance penalty for this. */
|
||||
|
||||
typedef ptr_vector<enode> app2enode_t; // app -> enode
|
||||
typedef id_var_list<null_family_id, null_theory_var> theory_var_list;
|
||||
|
||||
class tmp_enode;
|
||||
|
||||
|
@ -91,7 +93,7 @@ namespace smt {
|
|||
then the congruent f(b) in m_parents will also be relevant.
|
||||
*/
|
||||
enode_vector m_parents; //!< Parent enodes of the equivalence class.
|
||||
theory_var_list m_th_var_list; //!< List of theories that 'care' about this enode.
|
||||
id_var_list<> m_th_var_list; //!< List of theories that 'care' about this enode.
|
||||
trans_justification m_trans; //!< A justification for the enode being equal to its root.
|
||||
bool m_proof_is_logged; //!< Indicates that the proof for the enode being equal to its root is in the log.
|
||||
signed char m_lbl_hash; //!< It is different from -1, if enode is used in a pattern
|
||||
|
@ -105,7 +107,7 @@ namespace smt {
|
|||
|
||||
|
||||
theory_var_list * get_th_var_list() {
|
||||
return m_th_var_list.get_th_var() == null_theory_var ? nullptr : &m_th_var_list;
|
||||
return m_th_var_list.get_var() == null_theory_var ? nullptr : &m_th_var_list;
|
||||
}
|
||||
|
||||
friend class set_merge_tf_trail;
|
||||
|
@ -356,11 +358,11 @@ namespace smt {
|
|||
iterator end() { return iterator(this, this); }
|
||||
|
||||
theory_var_list const * get_th_var_list() const {
|
||||
return m_th_var_list.get_th_var() == null_theory_var ? nullptr : &m_th_var_list;
|
||||
return m_th_var_list.get_var() == null_theory_var ? nullptr : &m_th_var_list;
|
||||
}
|
||||
|
||||
bool has_th_vars() const {
|
||||
return m_th_var_list.get_th_var() != null_theory_var;
|
||||
return m_th_var_list.get_var() != null_theory_var;
|
||||
}
|
||||
|
||||
unsigned get_num_th_vars() const;
|
||||
|
|
|
@ -1,74 +0,0 @@
|
|||
/*++
|
||||
Copyright (c) 2006 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
smt_theory_var_list.h
|
||||
|
||||
Abstract:
|
||||
|
||||
<abstract>
|
||||
|
||||
Author:
|
||||
|
||||
Leonardo de Moura (leonardo) 2008-02-19.
|
||||
|
||||
Revision History:
|
||||
|
||||
--*/
|
||||
#pragma once
|
||||
|
||||
#include "smt/smt_types.h"
|
||||
|
||||
namespace smt {
|
||||
|
||||
class theory_var_list {
|
||||
int m_th_id:8;
|
||||
int m_th_var:24;
|
||||
theory_var_list * m_next;
|
||||
|
||||
public:
|
||||
theory_var_list():
|
||||
m_th_id(null_theory_id),
|
||||
m_th_var(null_theory_var),
|
||||
m_next(nullptr) {
|
||||
}
|
||||
|
||||
theory_var_list(theory_id t, theory_var v, theory_var_list * n = nullptr):
|
||||
m_th_id(t),
|
||||
m_th_var(v),
|
||||
m_next(n) {
|
||||
}
|
||||
|
||||
theory_id get_th_id() const {
|
||||
return m_th_id;
|
||||
}
|
||||
|
||||
theory_var get_th_var() const {
|
||||
return m_th_var;
|
||||
}
|
||||
|
||||
theory_var_list * get_next() const {
|
||||
return m_next;
|
||||
}
|
||||
|
||||
void set_th_id(theory_id id) {
|
||||
m_th_id = id;
|
||||
}
|
||||
|
||||
void set_th_var(theory_var v) {
|
||||
m_th_var = v;
|
||||
}
|
||||
|
||||
void set_next(theory_var_list * next) {
|
||||
m_next = next;
|
||||
}
|
||||
};
|
||||
|
||||
// 32 bit machine
|
||||
static_assert(sizeof(expr*) != 4 || sizeof(theory_var_list) == sizeof(theory_var_list *) + sizeof(int), "32 bit");
|
||||
// 64 bit machine
|
||||
static_assert(sizeof(expr*) != 8 || sizeof(theory_var_list) == sizeof(theory_var_list *) + sizeof(int) + /* a structure must be aligned */ sizeof(int), "64 bit");
|
||||
};
|
||||
|
||||
|
|
@ -498,7 +498,7 @@ namespace smt {
|
|||
TRACE("array_shared", tout << "new shared var: #" << r->get_owner_id() << "\n";);
|
||||
r->set_mark();
|
||||
to_unmark.push_back(r);
|
||||
theory_var r_th_var = r->get_th_var(get_id());
|
||||
theory_var r_th_var = r->get_var(get_id());
|
||||
SASSERT(r_th_var != null_theory_var);
|
||||
result.push_back(r_th_var);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue