Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Merge pull request #6 from sergey-v-galtsev/dead_states

States beeing unreachable from init state are considered dead in Fsm::DeadStates() now.
  • Loading branch information...
commit 1f20273f467a6421c21842380c1892808f85b27e 2 parents 397da77 + d193181
@dprokoptsev dprokoptsev authored
Showing with 47 additions and 41 deletions.
  1. +46 −40 pire/fsm.cpp
  2. +1 −1  pire/fsm.h
View
86 pire/fsm.cpp
@@ -632,54 +632,60 @@ Fsm& Fsm::Reverse()
yset<size_t> Fsm::DeadStates() const
{
- // Build an FSM with inverted transitions
- Fsm inverted;
- inverted.Resize(Size());
- for (TransitionTable::const_iterator j = m_transitions.begin(), je = m_transitions.end(); j != je; ++j) {
- for (TransitionRow::const_iterator k = j->begin(), ke = j->end(); k != ke; ++k) {
- for (StatesSet::const_iterator toSt = k->second.begin(), toSte = k->second.end(); toSt != toSte; ++toSt) {
- // We only care if the states are connected or not regerdless through what letter
- inverted.Connect(*toSt, j - m_transitions.begin(), 0);
+ yset<size_t> res;
+
+ for (int invert = 0; invert <= 1; ++invert) {
+ Fsm digraph;
+ digraph.Resize(Size());
+ for (TransitionTable::const_iterator j = m_transitions.begin(), je = m_transitions.end(); j != je; ++j) {
+ for (TransitionRow::const_iterator k = j->begin(), ke = j->end(); k != ke; ++k) {
+ for (StatesSet::const_iterator toSt = k->second.begin(), toSte = k->second.end(); toSt != toSte; ++toSt) {
+ // We only care if the states are connected or not regerdless through what letter
+ if (invert) {
+ // Build an FSM with inverted transitions
+ digraph.Connect(*toSt, j - m_transitions.begin(), 0);
+ } else {
+ digraph.Connect(j - m_transitions.begin(), *toSt, 0);
+ }
+ }
}
}
- }
- yvector<bool> unchecked(Size(), true);
- yvector<bool> useless(Size(), true);
- ydeque<size_t> queue;
-
- // Put all final states into queue, marking them useful
- for (size_t i = 0; i < Size(); ++i)
- if (IsFinal(i)) {
- useless[i] = false;
- queue.push_back(i);
- }
+ yvector<bool> unchecked(Size(), true);
+ yvector<bool> useless(Size(), true);
+ ydeque<size_t> queue;
- // Do the breadth-first search, marking all states
- // from which already marked states are reachable
- while (!queue.empty()) {
- size_t to = queue.front();
- queue.pop_front();
-
- // All the states that are connected to this state in inverted transition matrix are useful
- const StatesSet& connections = (inverted.m_transitions[to])[0];
- for (StatesSet::const_iterator fr = connections.begin(), fre = connections.end(); fr != fre; ++fr) {
- // Enqueue the state for further traversal if it hasnt been already checked
- if (unchecked[*fr] && useless[*fr]) {
- useless[*fr] = false;
- queue.push_back(*fr);
+ // Put all final (or initial) states into queue, marking them useful
+ for (size_t i = 0; i < Size(); ++i)
+ if ((invert && IsFinal(i)) || (!invert && Initial() == i)) {
+ useless[i] = false;
+ queue.push_back(i);
}
- }
- // Now we consider this state checked
- unchecked[to] = false;
- }
+ // Do the breadth-first search, marking all states
+ // from which already marked states are reachable
+ while (!queue.empty()) {
+ size_t to = queue.front();
+ queue.pop_front();
+
+ // All the states that are connected to this state in the transition matrix are useful
+ const StatesSet& connections = (digraph.m_transitions[to])[0];
+ for (StatesSet::const_iterator fr = connections.begin(), fre = connections.end(); fr != fre; ++fr) {
+ // Enqueue the state for further traversal if it hasnt been already checked
+ if (unchecked[*fr] && useless[*fr]) {
+ useless[*fr] = false;
+ queue.push_back(*fr);
+ }
+ }
- yset<size_t> res;
+ // Now we consider this state checked
+ unchecked[to] = false;
+ }
- for (size_t i = 0; i < Size(); ++i) {
- if (useless[i]) {
- res.insert(i);
+ for (size_t i = 0; i < Size(); ++i) {
+ if (useless[i]) {
+ res.insert(i);
+ }
}
}
View
2  pire/fsm.h
@@ -104,7 +104,7 @@ namespace Pire {
/// Creates an FSM which matches reversed strings matched by current FSM.
Fsm& Reverse();
- /// Returns a set of states from which no final states are reachable
+ /// Returns a set of states from which no final states are reachable or that are not reachable from the start state.
yset<size_t> DeadStates() const;
/// Removes all dead end paths from FSM
Please sign in to comment.
Something went wrong with that request. Please try again.