diff --git a/ChangeLog b/ChangeLog index 087bbeba9..54ccc26d6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +2011-02-04 Alexandre Duret-Lutz + + Add a way to count the number of sub-transitions. + + * src/tgbaalgos/stats.hh (tgba_sub_statistics): New class. + (sub_stats_reachable): New function. + * src/tgbaalgos/stats.cc (sub_stats_bfs): New class. + (tgba_sub_statistics::dump, sub_stats_reachable): New function. + * src/tgbatest/ltl2tgba.cc (-kt): New option. + * src/tgbatest/ltl2tgba.test: Use -kt. + 2011-02-03 Alexandre Duret-Lutz Read guard of the form !(x) in neverclaims. diff --git a/src/tgbaalgos/stats.cc b/src/tgbaalgos/stats.cc index dccdef772..5ac85f884 100644 --- a/src/tgbaalgos/stats.cc +++ b/src/tgbaalgos/stats.cc @@ -1,4 +1,4 @@ -// Copyright (C) 2008 Laboratoire de Recherche et Développement +// Copyright (C) 2008, 2011 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 @@ -54,6 +54,49 @@ namespace spot private: tgba_statistics& s_; }; + + class sub_stats_bfs: public stats_bfs + { + public: + sub_stats_bfs(const tgba* a, tgba_sub_statistics& s) + : stats_bfs(a, s), s_(s), seen_(bddtrue) + { + } + + void + process_link(const state*, int, const state*, int, + const tgba_succ_iterator* it) + { + ++s_.transitions; + + bdd cond = it->current_condition(); + bdd newvars = bdd_exist(bdd_support(cond), seen_); + if (newvars != bddtrue) + { + seen_ &= newvars; + int count = 0; + while (newvars != bddtrue) + { + ++count; + newvars = bdd_high(newvars); + } + // If we discover one new variable, that means that all + // transitions we counted so far are actually double + // subtransitions. If we have two new variables, they where + // quadruple transitions, etc. + s_.sub_transitions <<= count; + } + while (cond != bddfalse) + { + cond -= bdd_satoneset(cond, seen_, bddtrue); + ++s_.sub_transitions; + } + } + + private: + tgba_sub_statistics& s_; + bdd seen_; + }; } // anonymous @@ -64,12 +107,28 @@ namespace spot return out; } + std::ostream& tgba_sub_statistics::dump(std::ostream& out) const + { + out << "sub trans.: " << sub_transitions << std::endl; + this->tgba_statistics::dump(out); + return out; + } + tgba_statistics stats_reachable(const tgba* g) { - tgba_statistics s = {0, 0}; + tgba_statistics s; stats_bfs d(g, s); d.run(); return s; } + + tgba_sub_statistics + sub_stats_reachable(const tgba* g) + { + tgba_sub_statistics s; + sub_stats_bfs d(g, s); + d.run(); + return s; + } } diff --git a/src/tgbaalgos/stats.hh b/src/tgbaalgos/stats.hh index 38383248d..dc2b0d6e2 100644 --- a/src/tgbaalgos/stats.hh +++ b/src/tgbaalgos/stats.hh @@ -1,4 +1,4 @@ -// Copyright (C) 2008 Laboratoire de Recherche et Développement +// Copyright (C) 2008, 2011 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 @@ -38,11 +38,22 @@ namespace spot unsigned transitions; unsigned states; + tgba_statistics() { transitions = 0; states = 0; } + std::ostream& dump(std::ostream& out) const; + }; + + struct tgba_sub_statistics: public tgba_statistics + { + unsigned sub_transitions; + + tgba_sub_statistics() { sub_transitions = 0; } std::ostream& dump(std::ostream& out) const; }; /// \brief Compute statistics for an automaton. tgba_statistics stats_reachable(const tgba* g); + /// \brief Compute subended statistics for an automaton. + tgba_sub_statistics sub_stats_reachable(const tgba* g); /// @} } diff --git a/src/tgbatest/ltl2tgba.cc b/src/tgbatest/ltl2tgba.cc index adf950cb0..676b7148a 100644 --- a/src/tgbatest/ltl2tgba.cc +++ b/src/tgbatest/ltl2tgba.cc @@ -259,6 +259,9 @@ syntax(char* prog) << std::endl << " -ks display statistics on the automaton (size only)" << std::endl + << " -kt display statistics on the automaton (size + " + << "subtransitions)" + << std::endl << " -K dump the graph of SCCs in dot format" << std::endl << " -KV verbosely dump the graph of SCCs in dot format" << std::endl @@ -486,6 +489,10 @@ main(int argc, char** argv) { output = 12; } + else if (!strcmp(argv[formula_index], "-kt")) + { + output = 13; + } else if (!strcmp(argv[formula_index], "-K")) { output = 10; @@ -534,7 +541,7 @@ main(int argc, char** argv) } else if (!strcmp(argv[formula_index], "-O")) { - output = 13; + output = 14; opt_minimize = true; } else if (!strcmp(argv[formula_index], "-p")) @@ -1146,6 +1153,9 @@ main(int argc, char** argv) stats_reachable(a).dump(std::cout); break; case 13: + sub_stats_reachable(a).dump(std::cout); + break; + case 14: if (minimized == 0) { std::cout << "this is not an obligation property"; diff --git a/src/tgbatest/ltl2tgba.test b/src/tgbatest/ltl2tgba.test index 515ec8704..326c219e6 100755 --- a/src/tgbatest/ltl2tgba.test +++ b/src/tgbatest/ltl2tgba.test @@ -63,7 +63,8 @@ done # Make sure '!(Ga U b)' has 3 states and 6 transitions, # before and after degeneralization. for opt in '' -D -DS; do - ../ltl2tgba -ks -f -R3 $opt '!(Ga U b)' > stdout + ../ltl2tgba -kt -f -R3 $opt '!(Ga U b)' > stdout + grep 'sub trans.: 11$' stdout grep 'transitions: 6$' stdout grep 'states: 3$' stdout done @@ -71,7 +72,8 @@ done # Make sure 'Ga U b' has 4 states and 6 transitions, # before and after degeneralization. for opt in '' -D -DS; do - ../ltl2tgba -ks -f -R3 $opt 'Ga U b' > stdout + ../ltl2tgba -kt -f -R3 $opt 'Ga U b' > stdout + grep 'sub trans.: 12$' stdout grep 'transitions: 6$' stdout grep 'states: 4$' stdout done