mirror of
https://github.com/Z3Prover/z3
synced 2025-06-22 05:43:39 +00:00
tbv utilities
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
parent
cd12fa8461
commit
d9dafe7b94
6 changed files with 282 additions and 3 deletions
141
src/muz/ddnf/tbv.cpp
Normal file
141
src/muz/ddnf/tbv.cpp
Normal file
|
@ -0,0 +1,141 @@
|
||||||
|
/*++
|
||||||
|
Copyright (c) 2014 Microsoft Corporation
|
||||||
|
|
||||||
|
Module Name:
|
||||||
|
|
||||||
|
tbv.cpp
|
||||||
|
|
||||||
|
Abstract:
|
||||||
|
|
||||||
|
ternary bit-vector utilities.
|
||||||
|
|
||||||
|
Author:
|
||||||
|
|
||||||
|
Nikolaj Bjorner (nbjorner) 2014-09-15
|
||||||
|
|
||||||
|
Revision History:
|
||||||
|
|
||||||
|
|
||||||
|
--*/
|
||||||
|
|
||||||
|
#include "tbv.h"
|
||||||
|
|
||||||
|
tbv* tbv_manager::allocate() {
|
||||||
|
return reinterpret_cast<tbv*>(m.allocate());
|
||||||
|
}
|
||||||
|
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) {
|
||||||
|
return reinterpret_cast<tbv*>(m.allocate(bv));
|
||||||
|
}
|
||||||
|
tbv* tbv_manager::allocate(uint64 val) {
|
||||||
|
tbv* v = allocate0();
|
||||||
|
for (unsigned bit = num_tbits(); bit > 0;) {
|
||||||
|
--bit;
|
||||||
|
if (val & (1ULL << bit)) {
|
||||||
|
v->set(bit, BIT_1);
|
||||||
|
} else {
|
||||||
|
v->set(bit, BIT_0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
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()) {
|
||||||
|
v->set(bit, BIT_0);
|
||||||
|
} else {
|
||||||
|
v->set(bit, BIT_1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
void tbv_manager::deallocate(tbv* bv) {
|
||||||
|
m.deallocate(bv);
|
||||||
|
}
|
||||||
|
void tbv_manager::copy(tbv& dst, tbv const& src) const {
|
||||||
|
m.copy(dst, src);
|
||||||
|
}
|
||||||
|
tbv& tbv_manager::fill0(tbv& bv) const {
|
||||||
|
// 01010101 = 1 + 4 + 16 + 64
|
||||||
|
memset(bv.m_data, 1 + 4 + 16 + 64, m.num_bytes());
|
||||||
|
return bv;
|
||||||
|
}
|
||||||
|
tbv& tbv_manager::fill1(tbv& bv) const {
|
||||||
|
// 10101010 = 2 + 8 + 32 + 128
|
||||||
|
memset(bv.m_data, 2 + 8 + 32 + 128, m.num_bytes());
|
||||||
|
return bv;
|
||||||
|
}
|
||||||
|
tbv& tbv_manager::fillX(tbv& bv) const {
|
||||||
|
m.fill1(bv);
|
||||||
|
return bv;
|
||||||
|
}
|
||||||
|
tbv& tbv_manager::set_and(tbv& dst, tbv const& src) const {
|
||||||
|
m.set_and(dst, src);
|
||||||
|
return dst;
|
||||||
|
}
|
||||||
|
tbv& tbv_manager::set_or(tbv& dst, tbv const& src) const {
|
||||||
|
m.set_or(dst, src);
|
||||||
|
return dst;
|
||||||
|
}
|
||||||
|
tbv& tbv_manager::set_neg(tbv& dst) const {
|
||||||
|
m.set_neg(dst);
|
||||||
|
return dst;
|
||||||
|
}
|
||||||
|
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::intersect(tbv const& a, tbv const& b, tbv& result) {
|
||||||
|
copy(result, a);
|
||||||
|
set_and(result, b);
|
||||||
|
for (unsigned i = 0; i < num_tbits(); ++i) {
|
||||||
|
if (result.get(i) == BIT_z) return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::ostream& tbv_manager::display(std::ostream& out, tbv const& b) const {
|
||||||
|
for (unsigned i = 0; i < num_tbits(); ++i) {
|
||||||
|
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;
|
||||||
|
}
|
97
src/muz/ddnf/tbv.h
Normal file
97
src/muz/ddnf/tbv.h
Normal file
|
@ -0,0 +1,97 @@
|
||||||
|
/*++
|
||||||
|
Copyright (c) 2014 Microsoft Corporation
|
||||||
|
|
||||||
|
Module Name:
|
||||||
|
|
||||||
|
tbv.h
|
||||||
|
|
||||||
|
Abstract:
|
||||||
|
|
||||||
|
ternary bit-vector utilities.
|
||||||
|
|
||||||
|
Author:
|
||||||
|
|
||||||
|
Nikolaj Bjorner (nbjorner) 2014-09-15
|
||||||
|
|
||||||
|
Revision History:
|
||||||
|
|
||||||
|
|
||||||
|
--*/
|
||||||
|
|
||||||
|
#ifndef _TBV_H_
|
||||||
|
#define _TBV_H_
|
||||||
|
|
||||||
|
#include "fixed_bit_vector.h"
|
||||||
|
#include "rational.h"
|
||||||
|
|
||||||
|
class tbv;
|
||||||
|
|
||||||
|
class tbv_manager {
|
||||||
|
static const unsigned BIT_0 = 0x1;
|
||||||
|
static const unsigned BIT_1 = 0x2;
|
||||||
|
static const unsigned BIT_x = 0x3;
|
||||||
|
static const unsigned BIT_z = 0x0;
|
||||||
|
fixed_bit_vector_manager m;
|
||||||
|
public:
|
||||||
|
tbv_manager(unsigned n): m(2*n) {}
|
||||||
|
tbv* allocate();
|
||||||
|
tbv* allocate1();
|
||||||
|
tbv* allocate0();
|
||||||
|
tbv* allocateX();
|
||||||
|
tbv* allocate(tbv const& bv);
|
||||||
|
tbv* allocate(uint64 n);
|
||||||
|
tbv* allocate(rational const& r);
|
||||||
|
void deallocate(tbv* bv);
|
||||||
|
|
||||||
|
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;
|
||||||
|
tbv& set_and(tbv& dst, tbv const& src) const;
|
||||||
|
tbv& set_or(tbv& dst, tbv const& src) const;
|
||||||
|
tbv& set_neg(tbv& dst) const;
|
||||||
|
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 intersect(tbv const& a, tbv const& b, tbv& result);
|
||||||
|
std::ostream& display(std::ostream& out, tbv const& b) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct hash {
|
||||||
|
tbv_manager& m;
|
||||||
|
hash(tbv_manager& m):m(m) {}
|
||||||
|
unsigned operator()(tbv const& d) const {
|
||||||
|
return m.hash(d);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
private:
|
||||||
|
void set(unsigned index, unsigned value) {
|
||||||
|
SASSERT(value <= 3);
|
||||||
|
fixed_bit_vector::set(2*index, (value & 2) != 0);
|
||||||
|
fixed_bit_vector::set(2*index+1, (value & 1) != 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned get(unsigned index) const {
|
||||||
|
index *= 2;
|
||||||
|
return (fixed_bit_vector::get(index) << 1) | (unsigned)fixed_bit_vector::get(index+1);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* _TBV_H_ */
|
|
@ -141,6 +141,7 @@ int main(int argc, char ** argv) {
|
||||||
TST(optional);
|
TST(optional);
|
||||||
TST(bit_vector);
|
TST(bit_vector);
|
||||||
TST(fixed_bit_vector);
|
TST(fixed_bit_vector);
|
||||||
|
TST(tbv);
|
||||||
TST(string_buffer);
|
TST(string_buffer);
|
||||||
TST(map);
|
TST(map);
|
||||||
TST(diff_logic);
|
TST(diff_logic);
|
||||||
|
|
39
src/test/tbv.cpp
Normal file
39
src/test/tbv.cpp
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
#include "tbv.h"
|
||||||
|
|
||||||
|
static void tst1(unsigned num_bits) {
|
||||||
|
tbv_manager m(num_bits);
|
||||||
|
|
||||||
|
tbv* b1 = m.allocate1();
|
||||||
|
tbv* b0 = m.allocate0();
|
||||||
|
tbv* bX = m.allocateX();
|
||||||
|
tbv* bN = m.allocate(31);
|
||||||
|
m.display(std::cout, *b0) << "\n";
|
||||||
|
m.display(std::cout, *b1) << "\n";
|
||||||
|
m.display(std::cout, *bX) << "\n";
|
||||||
|
m.display(std::cout, *bN) << "\n";
|
||||||
|
SASSERT(!m.equals(*b1,*b0));
|
||||||
|
SASSERT(!m.equals(*b1,*bX));
|
||||||
|
SASSERT(!m.equals(*b0,*bX));
|
||||||
|
m.set_and(*bX,*b0);
|
||||||
|
SASSERT(m.equals(*b0,*bX));
|
||||||
|
SASSERT(!m.equals(*b1,*bX));
|
||||||
|
m.copy(*bX,*b1);
|
||||||
|
SASSERT(m.equals(*b1,*bX));
|
||||||
|
SASSERT(!m.equals(*b0,*bX));
|
||||||
|
m.fillX(*bX);
|
||||||
|
VERIFY(m.intersect(*bX,*b0,*bN));
|
||||||
|
SASSERT(m.equals(*b0, *bN));
|
||||||
|
VERIFY(!m.intersect(*b0,*b1,*bN));
|
||||||
|
m.deallocate(b0);
|
||||||
|
m.deallocate(b1);
|
||||||
|
m.deallocate(bX);
|
||||||
|
m.deallocate(bN);
|
||||||
|
}
|
||||||
|
|
||||||
|
void tst_tbv() {
|
||||||
|
tst1(31);
|
||||||
|
tst1(11);
|
||||||
|
tst1(15);
|
||||||
|
tst1(16);
|
||||||
|
tst1(17);
|
||||||
|
}
|
|
@ -52,7 +52,7 @@ fixed_bit_vector* fixed_bit_vector_manager::allocate1() {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
fixed_bit_vector* fixed_bit_vector_manager::allocate(fixed_bit_vector& bv) {
|
fixed_bit_vector* fixed_bit_vector_manager::allocate(fixed_bit_vector const& bv) {
|
||||||
fixed_bit_vector* result = allocate();
|
fixed_bit_vector* result = allocate();
|
||||||
copy(*result, bv);
|
copy(*result, bv);
|
||||||
return result;
|
return result;
|
||||||
|
|
|
@ -33,7 +33,6 @@ class fixed_bit_vector_manager {
|
||||||
unsigned m_num_bytes;
|
unsigned m_num_bytes;
|
||||||
unsigned m_num_words;
|
unsigned m_num_words;
|
||||||
unsigned m_mask;
|
unsigned m_mask;
|
||||||
unsigned num_bytes() const { return m_num_bytes; }
|
|
||||||
|
|
||||||
static unsigned num_words(unsigned num_bits) {
|
static unsigned num_words(unsigned num_bits) {
|
||||||
return (num_bits + 31) / 32;
|
return (num_bits + 31) / 32;
|
||||||
|
@ -45,11 +44,12 @@ public:
|
||||||
fixed_bit_vector* allocate();
|
fixed_bit_vector* allocate();
|
||||||
fixed_bit_vector* allocate1();
|
fixed_bit_vector* allocate1();
|
||||||
fixed_bit_vector* allocate0();
|
fixed_bit_vector* allocate0();
|
||||||
fixed_bit_vector* allocate(fixed_bit_vector& bv);
|
fixed_bit_vector* allocate(fixed_bit_vector const& bv);
|
||||||
void deallocate(fixed_bit_vector* bv);
|
void deallocate(fixed_bit_vector* bv);
|
||||||
|
|
||||||
void copy(fixed_bit_vector& dst, fixed_bit_vector const& src) const;
|
void copy(fixed_bit_vector& dst, fixed_bit_vector const& src) const;
|
||||||
unsigned num_words() const { return m_num_words; }
|
unsigned num_words() const { return m_num_words; }
|
||||||
|
unsigned num_bytes() const { return m_num_bytes; }
|
||||||
unsigned num_bits() const { return m_num_bits; }
|
unsigned num_bits() const { return m_num_bits; }
|
||||||
fixed_bit_vector& reset(fixed_bit_vector& bv) const { return fill0(bv); }
|
fixed_bit_vector& reset(fixed_bit_vector& bv) const { return fill0(bv); }
|
||||||
fixed_bit_vector& fill0(fixed_bit_vector& bv) const;
|
fixed_bit_vector& fill0(fixed_bit_vector& bv) const;
|
||||||
|
@ -66,6 +66,7 @@ public:
|
||||||
|
|
||||||
class fixed_bit_vector {
|
class fixed_bit_vector {
|
||||||
friend class fixed_bit_vector_manager;
|
friend class fixed_bit_vector_manager;
|
||||||
|
friend class tbv_manager;
|
||||||
unsigned m_data[1];
|
unsigned m_data[1];
|
||||||
|
|
||||||
static unsigned get_pos_mask(unsigned bit_idx) {
|
static unsigned get_pos_mask(unsigned bit_idx) {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue