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

add ddnf tests, add facility to solve QF_NRA + QF_UF(and other theories) in joint solver to allow broader use of QF_NRA core

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
Nikolaj Bjorner 2015-05-09 19:40:34 -07:00
parent 9377779e58
commit 839e3fbb7c
20 changed files with 1158 additions and 8 deletions

View file

@ -123,6 +123,13 @@ namespace datalog {
class ddnf_mgr {
struct stats {
unsigned m_num_inserts;
unsigned m_num_comparisons;
stats() { reset(); }
void reset() { memset(this, 0, sizeof(*this)); }
};
unsigned m_num_bits;
ddnf_node* m_root;
ddnf_node_vector m_noderefs;
@ -131,6 +138,8 @@ namespace datalog {
ddnf_node::hash m_hash;
ddnf_node::eq m_eq;
ddnf_nodes m_nodes;
svector<bool> m_marked;
stats m_stats;
public:
ddnf_mgr(unsigned n): m_num_bits(n), m_noderefs(*this), m_internalized(false), m_tbv(n),
m_hash(m_tbv), m_eq(m_tbv),
@ -154,6 +163,31 @@ namespace datalog {
n->dec_ref();
}
void reset_accumulate() {
m_marked.resize(m_nodes.size());
for (unsigned i = 0; i < m_marked.size(); ++i) {
m_marked[i] = false;
}
}
void accumulate(tbv const& t, unsigned_vector& acc) {
ddnf_node* n = find(t);
ptr_vector<ddnf_node> todo;
todo.push_back(n);
while (!todo.empty()) {
n = todo.back();
todo.pop_back();
unsigned id = n->get_id();
if (m_marked[id]) continue;
acc.push_back(id);
m_marked[id] = true;
unsigned sz = n->num_children();
for (unsigned i = 0; i < sz; ++i) {
todo.push_back((*n)[i]);
}
}
}
ddnf_node* insert(tbv const& t) {
SASSERT(!m_internalized);
ptr_vector<tbv const> new_tbvs;
@ -173,6 +207,9 @@ namespace datalog {
return m_tbv.allocate(v, hi, lo);
}
tbv_manager& get_tbv_manager() {
return m_tbv;
}
unsigned size() const {
return m_noderefs.size();
@ -183,13 +220,21 @@ namespace datalog {
return find(t)->descendants();
}
void display(std::ostream& out) const {
void display_statistics(std::ostream& out) const {
std::cout << "Number of insertions: " << m_stats.m_num_inserts << "\n";
std::cout << "Number of comparisons: " << m_stats.m_num_comparisons << "\n";
std::cout << "Number of nodes: " << size() << "\n";
}
void display(std::ostream& out) const {
for (unsigned i = 0; i < m_noderefs.size(); ++i) {
m_noderefs[i]->display(out);
out << "\n";
}
}
private:
ddnf_node* find(tbv const& t) {
@ -207,9 +252,11 @@ namespace datalog {
SASSERT(m_tbv.contains(root.get_tbv(), new_tbv));
if (&root == new_n) return;
++m_stats.m_num_inserts;
bool inserted = false;
for (unsigned i = 0; i < root.num_children(); ++i) {
ddnf_node& child = *(root[i]);
++m_stats.m_num_comparisons;
if (m_tbv.contains(child.get_tbv(), new_tbv)) {
inserted = true;
insert(child, new_n, new_intersections);
@ -227,11 +274,16 @@ namespace datalog {
// checking for subset
if (m_tbv.contains(new_tbv, child.get_tbv())) {
subset_children.push_back(&child);
++m_stats.m_num_comparisons;
}
else if (m_tbv.intersect(child.get_tbv(), new_tbv, *intr)) {
// this means there is a non-full intersection
new_intersections.push_back(intr);
intr = m_tbv.allocate();
m_stats.m_num_comparisons += 2;
}
else {
m_stats.m_num_comparisons += 2;
}
}
m_tbv.deallocate(intr);
@ -284,10 +336,38 @@ namespace datalog {
for (; it != end; ++it) {
dst.insert(*it);
}
}
}
};
ddnf_core::ddnf_core(unsigned n) {
m_imp = alloc(ddnf_mgr, n);
}
ddnf_core::~ddnf_core() {
dealloc(m_imp);
}
ddnf_node* ddnf_core::insert(tbv const& t) {
return m_imp->insert(t);
}
tbv_manager& ddnf_core::get_tbv_manager() {
return m_imp->get_tbv_manager();
}
unsigned ddnf_core::size() const {
return m_imp->size();
}
void ddnf_core::reset_accumulate() {
return m_imp->reset_accumulate();
}
void ddnf_core::accumulate(tbv const& t, unsigned_vector& acc) {
return m_imp->accumulate(t, acc);
}
void ddnf_core::display(std::ostream& out) const {
m_imp->display(out);
}
void ddnf_core::display_statistics(std::ostream& out) const {
m_imp->display_statistics(out);
}
void ddnf_node::add_child(ddnf_node* n) {
//SASSERT(!m_tbv.is_subset(n->m_tbv));
m_children.push_back(n);

View file

@ -24,6 +24,9 @@ Revision History:
#include "statistics.h"
#include "dl_engine_base.h"
class tbv;
class tbv_manager;
namespace datalog {
class context;
@ -41,6 +44,28 @@ namespace datalog {
virtual void display_certificate(std::ostream& out) const;
virtual expr_ref get_answer();
};
class ddnf_node;
class ddnf_mgr;
class ddnf_core {
ddnf_mgr* m_imp;
public:
ddnf_core(unsigned n);
~ddnf_core();
ddnf_node* insert(tbv const& t);
tbv_manager& get_tbv_manager();
unsigned size() const;
//
// accumulate labels covered by the stream of tbvs,
// such that labels that are covered by the current
// tbv but not the previous tbvs are included.
//
void reset_accumulate();
void accumulate(tbv const& t, unsigned_vector& labels);
void display(std::ostream& out) const;
void display_statistics(std::ostream& out) const;
};
};
#endif

View file

@ -99,6 +99,20 @@ tbv* tbv_manager::allocate(tbv const& bv, unsigned const* permutation) {
}
return r;
}
tbv* tbv_manager::allocate(char const* bv) {
tbv* result = allocateX();
unsigned i = 0, sz = num_tbits();
while(*bv && i < sz) {
if (*bv == '0') set(*result, i++, tbit::BIT_0);
else if (*bv == '1') set(*result, i++, tbit::BIT_1);
else if (*bv == '*') i++;
else if (i == 0 && (*bv == ' ' || *bv == '\t')) ;
else break;
++bv;
}
return result;
}
tbv* tbv_manager::project(bit_vector const& to_delete, tbv const& src) {
tbv* r = allocate();
unsigned i, j;

View file

@ -55,6 +55,7 @@ public:
tbv* allocate(rational const& r);
tbv* allocate(uint64 n, unsigned hi, unsigned lo);
tbv* allocate(tbv const& bv, unsigned const* permutation);
tbv* allocate(char const* bv);
void deallocate(tbv* bv);