Adding selective edge sorting and state merging

The merging is (possibly) more expensive but also
merges more states when applied to all states.

* spot/graph/graph.hh: edge sorting
* spot/twa/twagraph.cc,
spot/twa/twagraph.hh: selective state merging
* tests/core/twagraph.cc: Adjusting tests
This commit is contained in:
philipp 2021-08-12 00:04:29 +02:00 committed by Florian Renkin
parent 2c267dd894
commit 786599ed20
4 changed files with 280 additions and 1 deletions

View file

@ -1226,6 +1226,51 @@ namespace spot
std::stable_sort(edges_.begin() + 1, edges_.end(), p);
}
/// \brief Sort edges of the given states
///
/// \tparam Predicate : Comparison type
/// \param p : Comparison callable
/// \param to_sort_ptr : which states to sort. If null, all will be sorted
/// \note No need to call chain_edges_, they are in a coherent state.
/// todo: If pred does not involve bdd action other than id -> parallelize
template<bool Stable = false, class Predicate = std::less<edge_storage_t>>
void sort_edges_of_(Predicate p = Predicate(),
const std::vector<bool>* to_sort_ptr = nullptr)
{
SPOT_ASSERT((to_sort_ptr == nullptr)
|| (to_sort_ptr->size() == num_states()));
//std::cerr << "\nbefore\n";
//dump_storage(std::cerr);
auto pi = [&](unsigned t1, unsigned t2)
{return p(edges_[t1], edges_[t2]); };
std::vector<unsigned> sort_idx_;
for (unsigned i = 0; i < num_states(); ++i)
{
if (to_sort_ptr && !(*to_sort_ptr)[i])
continue;
sort_idx_.clear();
unsigned t = states_[i].succ;
do
{
sort_idx_.push_back(t);
t = edges_[t].next_succ;
} while (t != 0);
if constexpr (Stable)
std::stable_sort(sort_idx_.begin(), sort_idx_.end(), pi);
else
std::sort(sort_idx_.begin(), sort_idx_.end(), pi);
// Update the graph
states_[i].succ = sort_idx_.front();
states_[i].succ_tail = sort_idx_.back();
const unsigned n_outs_n1 = sort_idx_.size() - 1;
for (unsigned k = 0; k < n_outs_n1; ++k)
edges_[sort_idx_[k]].next_succ = sort_idx_[k+1];
edges_[sort_idx_.back()].next_succ = 0; // terminal
}
// Done
}
/// \brief Reconstruct the chain of outgoing edges
///
/// Should be called only when it is known that all edges