stats: add options to count unreachable states and transitions

Based on a request from Pierre Ganty.

* spot/twaalgos/stats.cc, spot/twaalgos/stats.hh,
bin/common_aoutput.cc, bin/common_aoutput.hh: Implement those
options.
* tests/core/format.test: Add test case.
* doc/org/autfilt.org: Update doc.
* NEWS: Mention them.
This commit is contained in:
Alexandre Duret-Lutz 2022-10-19 16:30:00 +02:00
parent 52ed3d1e8f
commit de29ba9e4c
7 changed files with 197 additions and 52 deletions

View file

@ -1,6 +1,6 @@
// -*- coding: utf-8 -*-
// Copyright (C) 2008, 2011-2018, 2020 Laboratoire de Recherche et
// Développement de l'Epita (LRDE).
// Copyright (C) 2008, 2011-2018, 2020, 2022 Laboratoire de Recherche
// et Développement de l'Epita (LRDE).
// Copyright (C) 2004 Laboratoire d'Informatique de Paris 6 (LIP6),
// département Systèmes Répartis Coopératifs (SRC), Université Pierre
// et Marie Curie.
@ -33,6 +33,16 @@
namespace spot
{
unsigned long long
count_all_transitions(const const_twa_graph_ptr& g)
{
unsigned long long tr = 0;
bdd v = g->ap_vars();
for (auto& e: g->edges())
tr += bdd_satcountset(e.cond, v);
return tr;
}
namespace
{
class stats_bfs: public twa_reachable_iterator_breadth_first
@ -82,6 +92,7 @@ namespace spot
};
template<typename SU, typename EU>
void dfs(const const_twa_graph_ptr& ge, SU state_update, EU edge_update)
{
@ -344,10 +355,73 @@ namespace spot
<< std::string(beg, end + 2) << ", ";
tmp << e.what();
throw std::runtime_error(tmp.str());
}
}
void printable_size::print(std::ostream& os, const char* pos) const
{
char p = 'r';
if (*pos == '[')
{
p = pos[1];
if (pos[2] != ']' || !(p == 'r' || p == 'u' || p == 'a'))
{
const char* end = strchr(pos + 1, ']');
std::ostringstream tmp;
tmp << "while processing %"
<< std::string(pos, end + 2) << ", "
<< "only [a], [r], or [u] is supported.";
throw std::runtime_error(tmp.str());
}
}
switch (p)
{
case 'r':
os << reachable_;
return;
case 'a':
os << all_;
return;
case 'u':
os << all_ - reachable_;
return;
}
SPOT_UNREACHABLE();
return;
}
void printable_long_size::print(std::ostream& os, const char* pos) const
{
char p = 'r';
if (*pos == '[')
{
p = pos[1];
if (pos[2] != ']' || !(p == 'r' || p == 'u' || p == 'a'))
{
const char* end = strchr(pos + 1, ']');
std::ostringstream tmp;
tmp << "while processing %"
<< std::string(pos, end + 2) << ", "
<< "only [a], [r], or [u] is supported.";
throw std::runtime_error(tmp.str());
}
}
switch (p)
{
case 'r':
os << reachable_;
return;
case 'a':
os << all_;
return;
case 'u':
os << all_ - reachable_;
return;
}
SPOT_UNREACHABLE();
return;
}
stat_printer::stat_printer(std::ostream& os, const char* format)
: format_(format)
@ -376,15 +450,15 @@ namespace spot
if (has('t'))
{
twa_sub_statistics s = sub_stats_reachable(aut);
states_ = s.states;
edges_ = s.edges;
trans_ = s.transitions;
states_.set(s.states, aut->num_states());
edges_.set(s.edges, aut->num_edges());
trans_.set(s.transitions, count_all_transitions(aut));
}
else if (has('s') || has('e'))
{
twa_statistics s = stats_reachable(aut);
states_ = s.states;
edges_ = s.edges;
states_.set(s.states, aut->num_states());
edges_.set(s.edges, aut->num_edges());
}
if (has('a'))

View file

@ -1,6 +1,6 @@
// -*- coding: utf-8 -*-
// Copyright (C) 2008, 2011-2017, 2020 Laboratoire de Recherche et
// Développement de l'Epita (LRDE).
// Copyright (C) 2008, 2011-2017, 2020, 2022 Laboratoire de Recherche
// et Développement de l'Epita (LRDE).
// Copyright (C) 2004 Laboratoire d'Informatique de Paris 6 (LIP6),
// département Systèmes Répartis Coopératifs (SRC), Université Pierre
// et Marie Curie.
@ -55,6 +55,9 @@ namespace spot
/// \brief Compute sub statistics for an automaton.
SPOT_API twa_sub_statistics sub_stats_reachable(const const_twa_ptr& g);
/// \brief Count all transtitions, even unreachable ones.
SPOT_API unsigned long long
count_all_transitions(const const_twa_graph_ptr& g);
class SPOT_API printable_formula: public printable_value<formula>
{
@ -102,6 +105,36 @@ namespace spot
void print(std::ostream& os, const char* pos) const override;
};
class SPOT_API printable_size final:
public spot::printable
{
unsigned reachable_ = 0;
unsigned all_ = 0;
public:
void set(unsigned reachable, unsigned all)
{
reachable_ = reachable;
all_ = all;
}
void print(std::ostream& os, const char* pos) const override;
};
class SPOT_API printable_long_size final:
public spot::printable
{
unsigned long long reachable_ = 0;
unsigned long long all_ = 0;
public:
void set(unsigned long long reachable, unsigned long long all)
{
reachable_ = reachable;
all_ = all;
}
void print(std::ostream& os, const char* pos) const override;
};
/// \brief prints various statistics about a TGBA
///
/// This object can be configured to display various statistics
@ -123,9 +156,9 @@ namespace spot
const char* format_;
printable_formula form_;
printable_value<unsigned> states_;
printable_value<unsigned> edges_;
printable_value<unsigned long long> trans_;
printable_size states_;
printable_size edges_;
printable_long_size trans_;
printable_value<unsigned> acc_;
printable_scc_info scc_;
printable_value<unsigned> nondetstates_;