acd: add ORDER_HEURISTIC for state-based ACD-transform

* spot/twaalgos/zlktree.cc, spot/twaalgos/zlktree.hh: Add the
acd_options::ORDER_HEURISTIC and use it by default in
acd_transform_sbacc().
* spot/misc/bitvect.hh (bitvect::count, bitvect::add_common): New
methods.
* tests/python/zlktree.ipynb: Adjust examples and discuss this
heuristic.
This commit is contained in:
Alexandre Duret-Lutz 2021-09-24 20:39:47 +02:00
parent 70ede35702
commit fea0be96c1
4 changed files with 1655 additions and 554 deletions

View file

@ -255,6 +255,16 @@ namespace spot
return *this;
}
bitvect& add_common(const bitvect& other1, const bitvect& other2)
{
SPOT_ASSERT(other1.size_ <= size_ && other2.size_ <= size_);
unsigned m = std::min(other2.block_count_,
std::min(other1.block_count_, block_count_));
for (size_t i = 0; i < m; ++i)
storage_[i] |= other1.storage_[i] & other2.storage_[i];
return *this;
}
bool intersects(const bitvect& other)
{
SPOT_ASSERT(other.size_ <= size_);
@ -302,6 +312,32 @@ namespace spot
== (storage_[i] & mask));
}
unsigned count() const
{
size_t i;
const size_t bpb = 8 * sizeof(bitvect::block_t);
size_t rest = size() % bpb;
size_t c = 0;
for (i = 0; i < block_count_; ++i)
{
block_t v = storage_[i];
if ((i == block_count_ - 1) && rest)
// The last block might not be fully used, scan only the
// relevant portion.
v &= (1UL << rest) - 1;
#ifdef __GNUC__
c += __builtin_popcountl(v);
#else
while (v)
{
++c;
v &= v - 1;
}
#endif
}
return c;
}
bool operator==(const bitvect& other) const
{
if (other.size_ != size_)