mirror of
https://github.com/Z3Prover/z3
synced 2025-04-23 09:05:31 +00:00
Move tbv to util
This commit is contained in:
parent
a89be68050
commit
79ee543d25
9 changed files with 39 additions and 40 deletions
|
@ -25,7 +25,7 @@ Revision History:
|
|||
#include "muz/base/dl_context.h"
|
||||
#include "ast/scoped_proof.h"
|
||||
#include "ast/bv_decl_plugin.h"
|
||||
#include "muz/rel/tbv.h"
|
||||
#include "util/tbv.h"
|
||||
#include <iostream>
|
||||
|
||||
namespace datalog {
|
||||
|
|
|
@ -23,7 +23,6 @@ z3_add_component(rel
|
|||
doc.cpp
|
||||
karr_relation.cpp
|
||||
rel_context.cpp
|
||||
tbv.cpp
|
||||
udoc_relation.cpp
|
||||
COMPONENT_DEPENDENCIES
|
||||
muz
|
||||
|
|
|
@ -695,12 +695,36 @@ void doc_manager::check_equiv(ast_manager& m, expr* fml1, expr* fml2) {
|
|||
SASSERT(res == l_false);
|
||||
}
|
||||
|
||||
|
||||
expr_ref doc_manager::to_formula(ast_manager & m, tbv const& src) {
|
||||
expr_ref result(m);
|
||||
expr_ref_vector conj(m);
|
||||
for (unsigned i = 0; i < num_tbits(); ++i) {
|
||||
switch (src[i]) {
|
||||
case BIT_0:
|
||||
conj.push_back(m.mk_not(m.mk_const(symbol(i), m.mk_bool_sort())));
|
||||
break;
|
||||
case BIT_1:
|
||||
conj.push_back(m.mk_const(symbol(i), m.mk_bool_sort()));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
result = mk_and(m, conj.size(), conj.data());
|
||||
return result;
|
||||
}
|
||||
|
||||
expr_ref doc_manager::mk_var(ast_manager & m, unsigned i) {
|
||||
return expr_ref(m.mk_const(symbol(i), m.mk_bool_sort()), m);
|
||||
}
|
||||
|
||||
expr_ref doc_manager::to_formula(ast_manager& m, doc const& src) {
|
||||
expr_ref result(m);
|
||||
expr_ref_vector conj(m);
|
||||
conj.push_back(tbvm().to_formula(m, src.pos()));
|
||||
conj.push_back(to_formula(m, src.pos()));
|
||||
for (unsigned i = 0; i < src.neg().size(); ++i) {
|
||||
conj.push_back(m.mk_not(tbvm().to_formula(m, src.neg()[i])));
|
||||
conj.push_back(m.mk_not(to_formula(m, src.neg()[i])));
|
||||
}
|
||||
result = mk_and(m, conj.size(), conj.data());
|
||||
return result;
|
||||
|
@ -712,9 +736,9 @@ void doc_manager::project_expand(expr_ref& fml, bit_vector const& to_delete) {
|
|||
for (unsigned i = 0; i < num_tbits(); ++i) {
|
||||
if (to_delete.get(i)) {
|
||||
expr_safe_replace rep1(m), rep2(m);
|
||||
rep1.insert(tbvm().mk_var(m, i), m.mk_true());
|
||||
rep1.insert(mk_var(m, i), m.mk_true());
|
||||
rep1(fml, tmp1);
|
||||
rep2.insert(tbvm().mk_var(m, i), m.mk_false());
|
||||
rep2.insert(mk_var(m, i), m.mk_false());
|
||||
rep2(fml, tmp2);
|
||||
if (tmp1 == tmp2) {
|
||||
fml = tmp1;
|
||||
|
@ -731,7 +755,7 @@ void doc_manager::project_rename(expr_ref& fml, bit_vector const& to_delete) {
|
|||
expr_safe_replace rep(m);
|
||||
for (unsigned i = 0, j = 0; i < num_tbits(); ++i) {
|
||||
if (!to_delete.get(i)) {
|
||||
rep.insert(tbvm().mk_var(m, j), tbvm().mk_var(m, i));
|
||||
rep.insert(mk_var(m, j), mk_var(m, i));
|
||||
++j;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,10 +22,10 @@ Revision History:
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "muz/rel/tbv.h"
|
||||
#include "util/tbv.h"
|
||||
#include "util/union_find.h"
|
||||
#include "util/buffer.h"
|
||||
|
||||
#include "ast/ast.h"
|
||||
|
||||
class doc;
|
||||
template<typename M, typename T> class union_bvec;
|
||||
|
@ -101,6 +101,8 @@ private:
|
|||
void project_rename(expr_ref& fml, bit_vector const& to_delete);
|
||||
void project_expand(expr_ref& fml, bit_vector const& to_delete);
|
||||
expr_ref to_formula(ast_manager& m, doc const& src);
|
||||
expr_ref to_formula(ast_manager& m, tbv const& src);
|
||||
expr_ref mk_var(ast_manager& m, unsigned i);
|
||||
void check_equiv(ast_manager& m, expr* fml1, expr* fml2);
|
||||
};
|
||||
|
||||
|
|
|
@ -1,326 +0,0 @@
|
|||
/*++
|
||||
Copyright (c) 2014 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
tbv.cpp
|
||||
|
||||
Abstract:
|
||||
|
||||
ternary bit-vector utilities.
|
||||
|
||||
Author:
|
||||
|
||||
Nikolaj Bjorner (nbjorner) 2014-09-15
|
||||
|
||||
Revision History:
|
||||
|
||||
|
||||
--*/
|
||||
|
||||
#include "muz/rel/tbv.h"
|
||||
#include "util/hashtable.h"
|
||||
#include "ast/ast_util.h"
|
||||
|
||||
|
||||
static bool s_debug_alloc = false;
|
||||
|
||||
void tbv_manager::debug_alloc() {
|
||||
s_debug_alloc = true;
|
||||
}
|
||||
|
||||
tbv_manager::~tbv_manager() {
|
||||
DEBUG_CODE(
|
||||
for (auto t : allocated_tbvs)
|
||||
TRACE("doc", tout << "dangling: " << t << "\n";););
|
||||
}
|
||||
|
||||
void tbv_manager::reset() {
|
||||
m.reset();
|
||||
}
|
||||
tbv* tbv_manager::allocate() {
|
||||
tbv* r = static_cast<tbv*>(m.allocate());
|
||||
m.reset(*r);
|
||||
DEBUG_CODE(
|
||||
if (s_debug_alloc) {
|
||||
TRACE("doc", tout << allocated_tbvs.size() << " " << r << "\n";);
|
||||
}
|
||||
allocated_tbvs.insert(r);
|
||||
);
|
||||
return r;
|
||||
}
|
||||
tbv* tbv_manager::allocate1() {
|
||||
tbv* v = allocate();
|
||||
fill1(*v);
|
||||
return v;
|
||||
}
|
||||
tbv* tbv_manager::allocate0() {
|
||||
tbv* v = allocate();
|
||||
fill0(*v);
|
||||
return v;
|
||||
}
|
||||
tbv* tbv_manager::allocateX() {
|
||||
tbv* v = allocate();
|
||||
fillX(*v);
|
||||
return v;
|
||||
}
|
||||
tbv* tbv_manager::allocate(tbv const& bv) {
|
||||
tbv* r = allocate();
|
||||
copy(*r, bv);
|
||||
return r;
|
||||
}
|
||||
tbv* tbv_manager::allocate(uint64_t val) {
|
||||
tbv* v = allocate0();
|
||||
for (unsigned bit = std::min(64u, num_tbits()); bit-- > 0;) {
|
||||
if (val & (1ULL << bit)) {
|
||||
set(*v, bit, BIT_1);
|
||||
} else {
|
||||
set(*v, bit, BIT_0);
|
||||
}
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
tbv* tbv_manager::allocate(uint64_t val, unsigned hi, unsigned lo) {
|
||||
tbv* v = allocateX();
|
||||
SASSERT(64 >= num_tbits() && num_tbits() > hi && hi >= lo);
|
||||
set(*v, val, hi, lo);
|
||||
return v;
|
||||
}
|
||||
tbv* tbv_manager::allocate(tbv const& bv, unsigned const* permutation) {
|
||||
tbv* r = allocate();
|
||||
unsigned sz = num_tbits();
|
||||
for (unsigned i = 0; i < sz; ++i) {
|
||||
set(*r, permutation[i], bv[i]);
|
||||
}
|
||||
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++, BIT_0);
|
||||
else if (*bv == '1') set(*result, i++, BIT_1);
|
||||
else if (*bv == '*') i++;
|
||||
else if (*bv == 'x') 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;
|
||||
unsigned n = to_delete.size();
|
||||
for (i = 0, j = 0; i < n; ++i) {
|
||||
if (!to_delete.get(i)) {
|
||||
set(*r, j, src[i]);
|
||||
++j;
|
||||
}
|
||||
}
|
||||
SASSERT(num_tbits() == j);
|
||||
return r;
|
||||
}
|
||||
|
||||
void tbv_manager::set(tbv& dst, unsigned index, tbit value) {
|
||||
SASSERT(index < num_tbits());
|
||||
m.set(dst, 2*index, (value & 2) != 0);
|
||||
m.set(dst, 2*index+1, (value & 1) != 0);
|
||||
}
|
||||
|
||||
|
||||
void tbv_manager::set(tbv& dst, uint64_t val, unsigned hi, unsigned lo) {
|
||||
SASSERT(lo <= hi && hi < num_tbits());
|
||||
for (unsigned i = 0; i < hi - lo + 1; ++i) {
|
||||
set(dst, lo + i, (val & (1ULL << i))?BIT_1:BIT_0);
|
||||
}
|
||||
}
|
||||
void tbv_manager::set(tbv& dst, rational const& r, unsigned hi, unsigned lo) {
|
||||
SASSERT(lo <= hi && hi < num_tbits());
|
||||
if (r.is_uint64()) {
|
||||
set(dst, r.get_uint64(), hi, lo);
|
||||
return;
|
||||
}
|
||||
for (unsigned i = 0; i < hi - lo + 1; ++i) {
|
||||
if (bitwise_and(r, rational::power_of_two(i)).is_zero())
|
||||
set(dst, lo + i, BIT_0);
|
||||
else
|
||||
set(dst, lo + i, BIT_1);
|
||||
}
|
||||
}
|
||||
|
||||
void tbv_manager::set(tbv& dst, tbv const& other, unsigned hi, unsigned lo) {
|
||||
dst.set(other, 2*hi+1, 2*lo);
|
||||
}
|
||||
|
||||
|
||||
tbv* tbv_manager::allocate(rational const& r) {
|
||||
if (r.is_uint64()) {
|
||||
return allocate(r.get_uint64());
|
||||
}
|
||||
tbv* v = allocate0();
|
||||
for (unsigned bit = num_tbits(); bit > 0; ) {
|
||||
--bit;
|
||||
if (bitwise_and(r, rational::power_of_two(bit)).is_zero()) {
|
||||
set(*v, bit, BIT_0);
|
||||
} else {
|
||||
set(*v, bit, BIT_1);
|
||||
}
|
||||
}
|
||||
return v;
|
||||
}
|
||||
void tbv_manager::deallocate(tbv* bv) {
|
||||
#if 0
|
||||
DEBUG_CODE(
|
||||
if (!allocated_tbvs.contains(bv)) {
|
||||
std::cout << "double deallocate: " << bv << "\n";
|
||||
UNREACHABLE();
|
||||
}
|
||||
if (s_debug_alloc) {
|
||||
TRACE("doc", tout << "deallocate: " << bv << "\n";);
|
||||
}
|
||||
allocated_tbvs.erase(bv););
|
||||
#endif
|
||||
m.deallocate(bv);
|
||||
}
|
||||
void tbv_manager::copy(tbv& dst, tbv const& src) const {
|
||||
m.copy(dst, src);
|
||||
}
|
||||
tbv& tbv_manager::fill0(tbv& bv) const {
|
||||
// 10101010 = 2 + 8 + 32 + 128
|
||||
memset(bv.m_data, 2 + 8 + 32 + 128, m.num_bytes());
|
||||
return bv;
|
||||
}
|
||||
tbv& tbv_manager::fill1(tbv& bv) const {
|
||||
// 01010101 = 1 + 4 + 16 + 64
|
||||
memset(bv.m_data, 1 + 4 + 16 + 64, m.num_bytes());
|
||||
return bv;
|
||||
}
|
||||
tbv& tbv_manager::fillX(tbv& bv) const {
|
||||
m.fill1(bv);
|
||||
return bv;
|
||||
}
|
||||
|
||||
tbv& tbv_manager::set_or(tbv& dst, tbv const& src) const {
|
||||
m.set_or(dst, src);
|
||||
return dst;
|
||||
}
|
||||
bool tbv_manager::set_and(tbv& dst, tbv const& src) const {
|
||||
m.set_and(dst, src);
|
||||
return is_well_formed(dst);
|
||||
}
|
||||
|
||||
bool tbv_manager::is_well_formed(tbv const& dst) const {
|
||||
unsigned nw = m.num_words();
|
||||
unsigned w;
|
||||
for (unsigned i = 0; i + 1 < nw; ++i) {
|
||||
w = dst.get_word(i);
|
||||
w = w | (w << 1) | 0x55555555;
|
||||
if (w != 0xFFFFFFFF) return false;
|
||||
}
|
||||
if (nw > 0) {
|
||||
w = m.last_word(dst);
|
||||
w = w | (w << 1) | 0x55555555 | ~m.get_mask();
|
||||
if (w != 0xFFFFFFFF) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void tbv_manager::complement(tbv const& src, ptr_vector<tbv>& result) {
|
||||
tbv* r;
|
||||
unsigned n = num_tbits();
|
||||
for (unsigned i = 0; i < n; ++i) {
|
||||
switch (src.get(i)) {
|
||||
case BIT_0:
|
||||
r = allocate(src);
|
||||
set(*r, i, BIT_1);
|
||||
result.push_back(r);
|
||||
break;
|
||||
case BIT_1:
|
||||
r = allocate(src);
|
||||
set(*r, i, BIT_0);
|
||||
result.push_back(r);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool tbv_manager::equals(tbv const& a, tbv const& b) const {
|
||||
return m.equals(a, b);
|
||||
}
|
||||
unsigned tbv_manager::hash(tbv const& src) const {
|
||||
return m.hash(src);
|
||||
}
|
||||
bool tbv_manager::contains(tbv const& a, tbv const& b) const {
|
||||
return m.contains(a, b);
|
||||
}
|
||||
|
||||
bool tbv_manager::contains(tbv const& a, unsigned_vector const& colsa,
|
||||
tbv const& b, unsigned_vector const& colsb) const {
|
||||
for (unsigned i = 0; i < colsa.size(); ++i) {
|
||||
tbit bit_a = a[colsa[i]];
|
||||
if (bit_a == BIT_x) continue;
|
||||
if (bit_a != b[colsb[i]]) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool tbv_manager::intersect(tbv const& a, tbv const& b, tbv& result) {
|
||||
copy(result, a);
|
||||
return set_and(result, b);
|
||||
}
|
||||
|
||||
std::ostream& tbv_manager::display(std::ostream& out, tbv const& b, unsigned hi, unsigned lo) const {
|
||||
SASSERT(lo <= hi && hi < num_tbits());
|
||||
for (unsigned i = hi+1; i-- > lo; ) {
|
||||
switch (b.get(i)) {
|
||||
case BIT_0:
|
||||
out << '0';
|
||||
break;
|
||||
case BIT_1:
|
||||
out << '1';
|
||||
break;
|
||||
case BIT_x:
|
||||
out << 'x';
|
||||
break;
|
||||
case BIT_z:
|
||||
out << 'z';
|
||||
break;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
}
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
std::ostream& tbv_manager::display(std::ostream& out, tbv const& b) const {
|
||||
if (num_tbits() == 0) return out << "[]";
|
||||
return display(out, b, num_tbits()-1, 0);
|
||||
}
|
||||
|
||||
expr_ref tbv_manager::to_formula(ast_manager& m, tbv const& src) {
|
||||
expr_ref result(m);
|
||||
expr_ref_vector conj(m);
|
||||
for (unsigned i = 0; i < num_tbits(); ++i) {
|
||||
switch (src[i]) {
|
||||
case BIT_0:
|
||||
conj.push_back(m.mk_not(m.mk_const(symbol(i), m.mk_bool_sort())));
|
||||
break;
|
||||
case BIT_1:
|
||||
conj.push_back(m.mk_const(symbol(i), m.mk_bool_sort()));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
result = mk_and(m, conj.size(), conj.data());
|
||||
return result;
|
||||
}
|
||||
|
||||
expr_ref tbv_manager::mk_var(ast_manager& m, unsigned i) {
|
||||
return expr_ref(m.mk_const(symbol(i), m.mk_bool_sort()), m);
|
||||
}
|
|
@ -1,154 +0,0 @@
|
|||
/*++
|
||||
Copyright (c) 2014 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
tbv.h
|
||||
|
||||
Abstract:
|
||||
|
||||
ternary bit-vector utilities.
|
||||
|
||||
Author:
|
||||
|
||||
Nikolaj Bjorner (nbjorner) 2014-09-15
|
||||
|
||||
Revision History:
|
||||
|
||||
|
||||
--*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "util/fixed_bit_vector.h"
|
||||
#include "util/rational.h"
|
||||
#include "ast/ast.h"
|
||||
|
||||
class tbv;
|
||||
|
||||
enum tbit {
|
||||
BIT_z = 0x0,
|
||||
BIT_0 = 0x1,
|
||||
BIT_1 = 0x2,
|
||||
BIT_x = 0x3
|
||||
};
|
||||
|
||||
inline tbit neg(tbit t) {
|
||||
return (tbit)(t ^ 0x3);
|
||||
}
|
||||
|
||||
class tbv_manager {
|
||||
friend class tbv;
|
||||
fixed_bit_vector_manager m;
|
||||
ptr_vector<tbv> allocated_tbvs;
|
||||
public:
|
||||
tbv_manager(unsigned n): m(2*n) {}
|
||||
~tbv_manager();
|
||||
void reset();
|
||||
tbv* allocate();
|
||||
tbv* allocate1();
|
||||
tbv* allocate0();
|
||||
tbv* allocateX();
|
||||
tbv* allocate(tbv const& bv);
|
||||
tbv* allocate(uint64_t n);
|
||||
tbv* allocate(rational const& r);
|
||||
tbv* allocate(uint64_t n, unsigned hi, unsigned lo);
|
||||
tbv* allocate(tbv const& bv, unsigned const* permutation);
|
||||
tbv* allocate(char const* bv);
|
||||
|
||||
void deallocate(tbv* bv);
|
||||
|
||||
unsigned get_size_estimate_bytes(const tbv&) const { return m.num_bytes(); }
|
||||
|
||||
void copy(tbv& dst, tbv const& src) const;
|
||||
unsigned num_tbits() const { return m.num_bits()/2; }
|
||||
tbv& reset(tbv& bv) const { return fill0(bv); }
|
||||
tbv& fill0(tbv& bv) const;
|
||||
tbv& fill1(tbv& bv) const;
|
||||
tbv& fillX(tbv& bv) const;
|
||||
bool set_and(tbv& dst, tbv const& src) const;
|
||||
tbv& set_or(tbv& dst, tbv const& src) const;
|
||||
void complement(tbv const& src, ptr_vector<tbv>& result);
|
||||
bool equals(tbv const& a, tbv const& b) const;
|
||||
unsigned hash(tbv const& src) const;
|
||||
bool contains(tbv const& a, tbv const& b) const;
|
||||
bool contains(tbv const& a, unsigned_vector const& colsa,
|
||||
tbv const& b, unsigned_vector const& colsb) const;
|
||||
bool intersect(tbv const& a, tbv const& b, tbv& result);
|
||||
std::ostream& display(std::ostream& out, tbv const& b) const;
|
||||
std::ostream& display(std::ostream& out, tbv const& b, unsigned hi, unsigned lo) const;
|
||||
tbv* project(bit_vector const& to_delete, tbv const& src);
|
||||
bool is_well_formed(tbv const& b) const; // - does not contain BIT_z;
|
||||
void set(tbv& dst, uint64_t n, unsigned hi, unsigned lo);
|
||||
void set(tbv& dst, rational const& r, unsigned hi, unsigned lo);
|
||||
void set(tbv& dst, tbv const& other, unsigned hi, unsigned lo);
|
||||
void set(tbv& dst, unsigned index, tbit value);
|
||||
|
||||
|
||||
static void debug_alloc();
|
||||
expr_ref to_formula(ast_manager& m, tbv const& src);
|
||||
expr_ref mk_var(ast_manager& m, unsigned i);
|
||||
};
|
||||
|
||||
class tbv: private fixed_bit_vector {
|
||||
friend class fixed_bit_vector_manager;
|
||||
friend class tbv_manager;
|
||||
|
||||
public:
|
||||
|
||||
struct eq {
|
||||
tbv_manager& m;
|
||||
eq(tbv_manager& m):m(m) {}
|
||||
bool operator()(tbv const& d1, tbv const& d2) const {
|
||||
return m.equals(d1, d2);
|
||||
}
|
||||
bool operator()(tbv const* d1, tbv const* d2) const {
|
||||
return m.equals(*d1, *d2);
|
||||
}
|
||||
};
|
||||
|
||||
struct hash {
|
||||
tbv_manager& m;
|
||||
hash(tbv_manager& m):m(m) {}
|
||||
unsigned operator()(tbv const& d) const {
|
||||
return m.hash(d);
|
||||
}
|
||||
unsigned operator()(tbv const* d) const {
|
||||
return m.hash(*d);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
tbit operator[](unsigned idx) const { return (tbit)get(idx); }
|
||||
|
||||
|
||||
private:
|
||||
|
||||
|
||||
unsigned get(unsigned index) const {
|
||||
index *= 2;
|
||||
return (fixed_bit_vector::get(index) << 1) | (unsigned)fixed_bit_vector::get(index+1);
|
||||
}
|
||||
};
|
||||
|
||||
class tbv_ref {
|
||||
tbv_manager& mgr;
|
||||
tbv* d;
|
||||
public:
|
||||
tbv_ref(tbv_manager& mgr):mgr(mgr),d(nullptr) {}
|
||||
tbv_ref(tbv_manager& mgr, tbv* d):mgr(mgr),d(d) {}
|
||||
~tbv_ref() {
|
||||
if (d) mgr.deallocate(d);
|
||||
}
|
||||
tbv_ref& operator=(tbv* d2) {
|
||||
if (d) mgr.deallocate(d);
|
||||
d = d2;
|
||||
return *this;
|
||||
}
|
||||
tbv& operator*() { return *d; }
|
||||
tbv* operator->() { return d; }
|
||||
tbv* get() { return d; }
|
||||
tbv* detach() { tbv* result = d; d = nullptr; return result; }
|
||||
};
|
||||
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue