Fix acceptance check in scc_map: trivial SCCs are not accepting.

Also compute useless SCCs.

* src/tgbaalgos/scc.cc (scc_map::scc::trivial): New field.
(scc_stats::useless_scc_map): New field.
* src/tgbaalgos/scc.cc (scc_map::build_map): Mark SCCs that are
not trivial.
(scc_map::accepting): Always return false for trivial SCC.
(build_scc_stats): Fill in useless_scc_map.
This commit is contained in:
Alexandre Duret-Lutz 2009-11-18 15:18:40 +01:00
parent ac5dda1032
commit 99981153e6
3 changed files with 27 additions and 1 deletions

View file

@ -1,3 +1,15 @@
2009-11-18 Alexandre Duret-Lutz <adl@lrde.epita.fr>
Fix acceptance check in scc_map: trivial SCCs are not accepting.
Also compute useless SCCs.
* src/tgbaalgos/scc.cc (scc_map::scc::trivial): New field.
(scc_stats::useless_scc_map): New field.
* src/tgbaalgos/scc.cc (scc_map::build_map): Mark SCCs that are
not trivial.
(scc_map::accepting): Always return false for trivial SCC.
(build_scc_stats): Fill in useless_scc_map.
2009-11-18 Alexandre Duret-Lutz <adl@lrde.epita.fr> 2009-11-18 Alexandre Duret-Lutz <adl@lrde.epita.fr>
Make it easy to filter states while iterating over an automaton. Make it easy to filter states while iterating over an automaton.

View file

@ -77,6 +77,8 @@ namespace spot
bool bool
scc_map::accepting(unsigned n) const scc_map::accepting(unsigned n) const
{ {
if (scc_map_[n].trivial)
return false;
return acc_set_of(n) == aut_->all_acceptance_conditions(); return acc_set_of(n) == aut_->all_acceptance_conditions();
} }
@ -288,6 +290,8 @@ namespace spot
root_.front().succ.insert(succs.begin(), succs.end()); root_.front().succ.insert(succs.begin(), succs.end());
root_.front().conds.insert(conds.begin(), conds.end()); root_.front().conds.insert(conds.begin(), conds.end());
root_.front().supp &= supp; root_.front().supp &= supp;
// This SCC is no longer trivial.
root_.front().trivial = false;
} }
// recursively update supp_rec // recursively update supp_rec
@ -417,6 +421,10 @@ namespace spot
res.acc_paths = d.acc_paths[init]; res.acc_paths = d.acc_paths[init];
res.dead_paths = d.dead_paths[init]; res.dead_paths = d.dead_paths[init];
res.useless_scc_map.reserve(res.scc_total);
for (unsigned n = 0; n < res.scc_total; ++n)
res.useless_scc_map[n] = !d.acc_paths[n];
return res; return res;
} }

View file

@ -56,6 +56,9 @@ namespace spot
unsigned dead_paths; unsigned dead_paths;
unsigned self_loops; unsigned self_loops;
/// A map of the useless SCCs.
std::vector<bool> useless_scc_map;
std::ostream& dump(std::ostream& out) const; std::ostream& dump(std::ostream& out) const;
}; };
@ -150,7 +153,8 @@ namespace spot
{ {
public: public:
scc(int index) : index(index), acc(bddfalse), scc(int index) : index(index), acc(bddfalse),
supp(bddtrue), supp_rec(bddfalse) {}; supp(bddtrue), supp_rec(bddfalse),
trivial(true) {};
/// Index of the SCC. /// Index of the SCC.
int index; int index;
/// The union of all acceptance conditions of transitions which /// The union of all acceptance conditions of transitions which
@ -166,6 +170,8 @@ namespace spot
bdd supp_rec; bdd supp_rec;
/// Successor SCC. /// Successor SCC.
succ_type succ; succ_type succ;
/// Trivial SCC have one state and no self-loops.
bool trivial;
}; };
const tgba* aut_; // Automata to decompose. const tgba* aut_; // Automata to decompose.