mirror of
https://github.com/Z3Prover/z3
synced 2025-04-08 10:25:18 +00:00
161 lines
4 KiB
C++
161 lines
4 KiB
C++
/*++
|
|
Copyright (c) 2006 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
ast_list.h
|
|
|
|
Abstract:
|
|
|
|
Quick hack to have lists of ASTs.
|
|
The lists have hash-consing.
|
|
This is a substitute for the old expr_lists implemented on top of the ASTs.
|
|
The new lists live in a different manager and do not affect the ast_manager.
|
|
|
|
Author:
|
|
|
|
Leonardo de Moura (leonardo) 2011-01-06.
|
|
|
|
Revision History:
|
|
|
|
--*/
|
|
#ifndef _AST_LIST_H_
|
|
#define _AST_LIST_H_
|
|
|
|
#include"ast.h"
|
|
|
|
template<typename AST>
|
|
class ast_list_manager_tpl;
|
|
|
|
template<typename AST>
|
|
class ast_list_tpl {
|
|
public:
|
|
typedef ast_list_tpl list;
|
|
private:
|
|
unsigned m_id;
|
|
unsigned m_is_nil:1;
|
|
unsigned m_ref_count:31;
|
|
AST * m_head;
|
|
list * m_tail;
|
|
|
|
ast_list_tpl():
|
|
m_is_nil(true),
|
|
m_ref_count(0),
|
|
m_head(0),
|
|
m_tail(0) {
|
|
}
|
|
|
|
ast_list_tpl(AST * h, list * t):
|
|
m_is_nil(false),
|
|
m_ref_count(0),
|
|
m_head(h),
|
|
m_tail(t) {
|
|
}
|
|
|
|
friend class ast_list_manager_tpl<AST>;
|
|
|
|
struct hash_proc;
|
|
friend struct hash_proc;
|
|
|
|
struct hash_proc {
|
|
unsigned operator()(ast_list_tpl * l) const {
|
|
unsigned h1 = l->m_head ? l->m_head->get_id() : 5;
|
|
unsigned h2 = l->m_tail ? l->m_tail->get_id() : 7;
|
|
return hash_u_u(h1, h2);
|
|
}
|
|
};
|
|
|
|
struct eq_proc;
|
|
friend struct eq_proc;
|
|
|
|
struct eq_proc {
|
|
bool operator()(ast_list_tpl * l1, ast_list_tpl * l2) const {
|
|
return l1->m_head == l2->m_head && l1->m_tail == l2->m_tail;
|
|
}
|
|
};
|
|
|
|
typedef ptr_hashtable<list, hash_proc, eq_proc> table; // for hash consing
|
|
|
|
public:
|
|
unsigned get_id() const { return m_id; }
|
|
unsigned get_ref_count() const { return m_ref_count; }
|
|
unsigned hash() const { return m_id; }
|
|
|
|
friend inline bool is_nil(list const * l) { return l->m_is_nil == true; }
|
|
friend inline bool is_cons(list const * l) { return !is_nil(l); }
|
|
friend inline AST * head(list const * l) { SASSERT(is_cons(l)); return l->m_head; }
|
|
friend inline list * tail(list const * l) { SASSERT(is_cons(l)); return l->m_tail; }
|
|
};
|
|
|
|
template<typename AST>
|
|
class ast_list_manager_tpl {
|
|
public:
|
|
typedef ast_list_tpl<AST> list;
|
|
typedef obj_hashtable<list> list_set;
|
|
private:
|
|
typedef typename list::table table;
|
|
ast_manager & m_manager;
|
|
small_object_allocator m_allocator;
|
|
table m_table;
|
|
id_gen m_id_gen;
|
|
list m_nil;
|
|
|
|
public:
|
|
ast_list_manager_tpl(ast_manager & m):
|
|
m_manager(m),
|
|
m_nil() {
|
|
m_nil.m_id = m_id_gen.mk();
|
|
m_nil.m_ref_count = 1;
|
|
}
|
|
|
|
void inc_ref(list * l) {
|
|
if (l != 0) {
|
|
l->m_ref_count++;
|
|
}
|
|
}
|
|
|
|
void dec_ref(list * l) {
|
|
while (l != 0) {
|
|
SASSERT(l->m_ref_count > 0);
|
|
l->m_ref_count--;
|
|
if (l->m_ref_count > 0)
|
|
return;
|
|
SASSERT(l != &m_nil);
|
|
m_table.erase(l);
|
|
m_manager.dec_ref(l->m_head);
|
|
m_id_gen.recycle(l->m_id);
|
|
list * old_l = l;
|
|
l = l->m_tail;
|
|
m_allocator.deallocate(sizeof(list), old_l);
|
|
}
|
|
}
|
|
|
|
list * mk_nil() { return &m_nil; }
|
|
|
|
list * mk_cons(AST * h, list * l) {
|
|
list tmp(h, l);
|
|
list * r = 0;
|
|
if (m_table.find(&tmp, r))
|
|
return r;
|
|
r = new (m_allocator.allocate(sizeof(list))) list(h, l);
|
|
m_manager.inc_ref(h);
|
|
inc_ref(l);
|
|
r->m_id = m_id_gen.mk();
|
|
m_table.insert(r);
|
|
return r;
|
|
}
|
|
};
|
|
|
|
typedef ast_list_tpl<expr> expr_list;
|
|
typedef ast_list_manager_tpl<expr> expr_list_manager;
|
|
|
|
typedef ast_list_tpl<quantifier> quantifier_list;
|
|
typedef ast_list_manager_tpl<quantifier> quantifier_list_manager;
|
|
|
|
typedef obj_ref<expr_list, expr_list_manager> expr_list_ref;
|
|
typedef obj_ref<quantifier_list, quantifier_list_manager> quantifier_list_ref;
|
|
typedef ref_vector<expr_list, expr_list_manager> expr_list_ref_vector;
|
|
typedef ref_vector<quantifier_list, quantifier_list_manager> quantifier_list_ref_vector;
|
|
|
|
#endif
|