mirror of
https://github.com/Z3Prover/z3
synced 2025-08-09 04:31:24 +00:00
update topological sort to use arrays instead of hash tables, expose Context over Z3Object for programmability
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
parent
0e6c64510a
commit
51ed13f96a
17 changed files with 103 additions and 96 deletions
|
@ -498,9 +498,9 @@ bool compare_nodes(ast const * n1, ast const * n2) {
|
|||
|
||||
template<typename T>
|
||||
inline unsigned ast_array_hash(T * const * array, unsigned size, unsigned init_value) {
|
||||
if (size == 0)
|
||||
return init_value;
|
||||
switch (size) {
|
||||
case 0:
|
||||
return init_value;
|
||||
case 1:
|
||||
return combine_hash(array[0]->hash(), init_value);
|
||||
case 2:
|
||||
|
@ -993,7 +993,7 @@ sort * basic_decl_plugin::mk_sort(decl_kind k, unsigned num_parameters, paramete
|
|||
}
|
||||
|
||||
func_decl * basic_decl_plugin::mk_eq_decl_core(char const * name, decl_kind k, sort * s, ptr_vector<func_decl> & cache) {
|
||||
unsigned id = s->get_decl_id();
|
||||
unsigned id = s->get_small_id();
|
||||
force_ptr_array_size(cache, id + 1);
|
||||
if (cache[id] == 0) {
|
||||
sort * domain[2] = { s, s};
|
||||
|
@ -1009,7 +1009,7 @@ func_decl * basic_decl_plugin::mk_eq_decl_core(char const * name, decl_kind k, s
|
|||
}
|
||||
|
||||
func_decl * basic_decl_plugin::mk_ite_decl(sort * s) {
|
||||
unsigned id = s->get_decl_id();
|
||||
unsigned id = s->get_small_id();
|
||||
force_ptr_array_size(m_ite_decls, id + 1);
|
||||
if (m_ite_decls[id] == 0) {
|
||||
sort * domain[3] = { m_bool_sort, s, s};
|
||||
|
|
|
@ -572,7 +572,7 @@ protected:
|
|||
|
||||
decl(ast_kind k, symbol const & name, decl_info * info):ast(k), m_name(name), m_info(info) {}
|
||||
public:
|
||||
unsigned get_decl_id() const { SASSERT(get_id() >= c_first_decl_id); return get_id() - c_first_decl_id; }
|
||||
unsigned get_small_id() const { SASSERT(get_id() >= c_first_decl_id); return get_id() - c_first_decl_id; }
|
||||
symbol const & get_name() const { return m_name; }
|
||||
decl_info * get_info() const { return m_info; }
|
||||
family_id get_family_id() const { return m_info == nullptr ? null_family_id : m_info->get_family_id(); }
|
||||
|
@ -671,6 +671,9 @@ protected:
|
|||
public:
|
||||
|
||||
sort* get_sort() const;
|
||||
|
||||
unsigned get_small_id() const { return get_id(); }
|
||||
|
||||
};
|
||||
|
||||
// -----------------------------------
|
||||
|
@ -2573,7 +2576,7 @@ typedef ast_ref_fast_mark2 expr_ref_fast_mark2;
|
|||
when N is deleted.
|
||||
*/
|
||||
class ast_mark {
|
||||
struct decl2uint { unsigned operator()(decl const & d) const { return d.get_decl_id(); } };
|
||||
struct decl2uint { unsigned operator()(decl const & d) const { return d.get_small_id(); } };
|
||||
obj_mark<expr> m_expr_marks;
|
||||
obj_mark<decl, bit_vector, decl2uint> m_decl_marks;
|
||||
public:
|
||||
|
|
|
@ -30,7 +30,7 @@ namespace euf {
|
|||
m_nodes.push_back(n);
|
||||
m_exprs.push_back(f);
|
||||
if (is_app(f) && num_args > 0) {
|
||||
unsigned id = to_app(f)->get_decl()->get_decl_id();
|
||||
unsigned id = to_app(f)->get_decl()->get_small_id();
|
||||
m_decl2enodes.reserve(id+1);
|
||||
m_decl2enodes[id].push_back(n);
|
||||
}
|
||||
|
@ -60,7 +60,7 @@ namespace euf {
|
|||
|
||||
|
||||
enode_vector const& egraph::enodes_of(func_decl* f) {
|
||||
unsigned id = f->get_decl_id();
|
||||
unsigned id = f->get_small_id();
|
||||
if (id < m_decl2enodes.size())
|
||||
return m_decl2enodes[id];
|
||||
return m_empty_enodes;
|
||||
|
@ -341,7 +341,7 @@ namespace euf {
|
|||
m_expr2enode[e->get_id()] = nullptr;
|
||||
n->~enode();
|
||||
if (is_app(e) && n->num_args() > 0)
|
||||
m_decl2enodes[to_app(e)->get_decl()->get_decl_id()].pop_back();
|
||||
m_decl2enodes[to_app(e)->get_decl()->get_small_id()].pop_back();
|
||||
m_nodes.pop_back();
|
||||
m_exprs.pop_back();
|
||||
};
|
||||
|
|
|
@ -162,7 +162,7 @@ namespace euf {
|
|||
bool merge_tf() const { return merge_enabled() && (class_size() > 1 || num_parents() > 0 || num_args() > 0); }
|
||||
|
||||
enode* get_arg(unsigned i) const { SASSERT(i < num_args()); return m_args[i]; }
|
||||
unsigned hash() const { return m_expr->hash(); }
|
||||
unsigned hash() const { return m_expr->get_id(); }
|
||||
|
||||
unsigned get_table_id() const { return m_table_id; }
|
||||
void set_table_id(unsigned t) { m_table_id = t; }
|
||||
|
@ -204,6 +204,8 @@ namespace euf {
|
|||
app* get_app() const { return to_app(m_expr); }
|
||||
func_decl* get_decl() const { return is_app(m_expr) ? to_app(m_expr)->get_decl() : nullptr; }
|
||||
unsigned get_expr_id() const { return m_expr->get_id(); }
|
||||
unsigned get_id() const { return m_expr->get_id(); }
|
||||
unsigned get_small_id() const { return m_expr->get_small_id(); }
|
||||
unsigned get_root_id() const { return m_root->m_expr->get_id(); }
|
||||
bool children_are_roots() const;
|
||||
enode* get_next() const { return m_next; }
|
||||
|
|
|
@ -162,7 +162,7 @@ struct static_features {
|
|||
|
||||
bool arith_k_sum_is_small() const { return m_arith_k_sum < rational(INT_MAX / 8); }
|
||||
|
||||
void inc_num_apps(func_decl const * d) { unsigned id = d->get_decl_id(); m_num_apps.reserve(id+1, 0); m_num_apps[id]++; }
|
||||
void inc_num_apps(func_decl const * d) { unsigned id = d->get_small_id(); m_num_apps.reserve(id+1, 0); m_num_apps[id]++; }
|
||||
void inc_theory_terms(family_id fid) { m_num_theory_terms.reserve(fid+1, 0); m_num_theory_terms[fid]++; }
|
||||
void inc_theory_atoms(family_id fid) { m_num_theory_atoms.reserve(fid+1, 0); m_num_theory_atoms[fid]++; }
|
||||
void inc_theory_constants(family_id fid) { m_num_theory_constants.reserve(fid+1, 0); m_num_theory_constants[fid]++; }
|
||||
|
|
|
@ -137,10 +137,7 @@ void substitution_tree::reset_registers(unsigned old_size) {
|
|||
unsigned substitution_tree::get_compatibility_measure(svector<subst> const & sv) {
|
||||
unsigned old_size = m_todo.size();
|
||||
unsigned measure = 0;
|
||||
svector<subst>::const_iterator it = sv.begin();
|
||||
svector<subst>::const_iterator end = sv.end();
|
||||
for (; it != end; ++it) {
|
||||
subst const & s = *it;
|
||||
for (subst const& s : sv) {
|
||||
unsigned ireg = s.first->get_idx();
|
||||
expr * out = s.second;
|
||||
expr * in = get_reg_value(ireg);
|
||||
|
@ -254,7 +251,7 @@ void substitution_tree::insert(expr * new_expr) {
|
|||
else {
|
||||
SASSERT(is_var(new_expr));
|
||||
sort * s = to_var(new_expr)->get_sort();
|
||||
unsigned id = s->get_decl_id();
|
||||
unsigned id = s->get_small_id();
|
||||
if (id >= m_vars.size())
|
||||
m_vars.resize(id+1);
|
||||
if (m_vars[id] == 0)
|
||||
|
@ -274,7 +271,7 @@ void substitution_tree::insert(app * new_expr) {
|
|||
m_todo.push_back(0);
|
||||
|
||||
func_decl * d = new_expr->get_decl();
|
||||
unsigned id = d->get_decl_id();
|
||||
unsigned id = d->get_small_id();
|
||||
|
||||
if (id >= m_roots.size())
|
||||
m_roots.resize(id+1);
|
||||
|
@ -439,7 +436,7 @@ void substitution_tree::erase(expr * e) {
|
|||
else {
|
||||
SASSERT(is_var(e));
|
||||
sort * s = to_var(e)->get_sort();
|
||||
unsigned id = s->get_decl_id();
|
||||
unsigned id = s->get_small_id();
|
||||
if (id >= m_vars.size() || m_vars[id] == 0)
|
||||
return;
|
||||
var_ref_vector * v = m_vars[id];
|
||||
|
@ -453,7 +450,7 @@ void substitution_tree::erase(expr * e) {
|
|||
*/
|
||||
void substitution_tree::erase(app * e) {
|
||||
func_decl * d = e->get_decl();
|
||||
unsigned id = d->get_decl_id();
|
||||
unsigned id = d->get_small_id();
|
||||
if (id >= m_roots.size() || !m_roots[id])
|
||||
return;
|
||||
|
||||
|
@ -732,7 +729,7 @@ bool substitution_tree::visit_vars(expr * e, st_visitor & st) {
|
|||
if (m_vars.empty())
|
||||
return true; // continue
|
||||
sort * s = e->get_sort();
|
||||
unsigned s_id = s->get_decl_id();
|
||||
unsigned s_id = s->get_small_id();
|
||||
if (s_id < m_vars.size()) {
|
||||
var_ref_vector * v = m_vars[s_id];
|
||||
if (v && !v->empty()) {
|
||||
|
@ -832,17 +829,14 @@ void substitution_tree::visit(expr * e, st_visitor & st, unsigned in_offset, uns
|
|||
if (visit_vars<Mode>(e, st)) {
|
||||
if (is_app(e)) {
|
||||
func_decl * d = to_app(e)->get_decl();
|
||||
unsigned id = d->get_decl_id();
|
||||
unsigned id = d->get_small_id();
|
||||
node * r = m_roots.get(id, 0);
|
||||
if (r)
|
||||
visit<Mode>(e, st, r);
|
||||
}
|
||||
else {
|
||||
SASSERT(is_var(e));
|
||||
ptr_vector<node>::iterator it = m_roots.begin();
|
||||
ptr_vector<node>::iterator end = m_roots.end();
|
||||
for (; it != end; ++it) {
|
||||
node * r = *it;
|
||||
for (node* r : m_roots) {
|
||||
if (r != nullptr) {
|
||||
var * v = r->m_subst[0].first;
|
||||
if (v->get_sort() == to_var(e)->get_sort())
|
||||
|
@ -868,16 +862,11 @@ void substitution_tree::gen(expr * e, st_visitor & v, unsigned in_offset, unsign
|
|||
|
||||
void substitution_tree::display(std::ostream & out) const {
|
||||
out << "substitution tree:\n";
|
||||
ptr_vector<node>::const_iterator it = m_roots.begin();
|
||||
ptr_vector<node>::const_iterator end = m_roots.end();
|
||||
for (; it != end; ++it)
|
||||
if (*it)
|
||||
display(out, *it, 0);
|
||||
for (node* n : m_roots)
|
||||
if (n)
|
||||
display(out, n, 0);
|
||||
bool found_var = false;
|
||||
ptr_vector<var_ref_vector>::const_iterator it2 = m_vars.begin();
|
||||
ptr_vector<var_ref_vector>::const_iterator end2 = m_vars.end();
|
||||
for (; it2 != end2; ++it2) {
|
||||
var_ref_vector * v = *it2;
|
||||
for (var_ref_vector* v : m_vars) {
|
||||
if (v == nullptr)
|
||||
continue; // m_vars may contain null pointers. See substitution_tree::insert.
|
||||
unsigned num = v->size();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue