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:
parent
9377779e58
commit
839e3fbb7c
20 changed files with 1158 additions and 8 deletions
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue