Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
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
dprokoptsev committed Jul 27, 2012
2 parents 397da77 + d193181 commit 1f20273
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 41 deletions.
86 changes: 46 additions & 40 deletions pire/fsm.cpp
Expand Up @@ -632,54 +632,60 @@ Fsm& Fsm::Reverse()


yset<size_t> Fsm::DeadStates() const yset<size_t> Fsm::DeadStates() const
{ {
// Build an FSM with inverted transitions yset<size_t> res;
Fsm inverted;
inverted.Resize(Size()); for (int invert = 0; invert <= 1; ++invert) {
for (TransitionTable::const_iterator j = m_transitions.begin(), je = m_transitions.end(); j != je; ++j) { Fsm digraph;
for (TransitionRow::const_iterator k = j->begin(), ke = j->end(); k != ke; ++k) { digraph.Resize(Size());
for (StatesSet::const_iterator toSt = k->second.begin(), toSte = k->second.end(); toSt != toSte; ++toSt) { for (TransitionTable::const_iterator j = m_transitions.begin(), je = m_transitions.end(); j != je; ++j) {
// We only care if the states are connected or not regerdless through what letter for (TransitionRow::const_iterator k = j->begin(), ke = j->end(); k != ke; ++k) {
inverted.Connect(*toSt, j - m_transitions.begin(), 0); 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> unchecked(Size(), true);
yvector<bool> useless(Size(), true); yvector<bool> useless(Size(), true);
ydeque<size_t> queue; 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);
}


// Do the breadth-first search, marking all states // Put all final (or initial) states into queue, marking them useful
// from which already marked states are reachable for (size_t i = 0; i < Size(); ++i)
while (!queue.empty()) { if ((invert && IsFinal(i)) || (!invert && Initial() == i)) {
size_t to = queue.front(); useless[i] = false;
queue.pop_front(); queue.push_back(i);

// 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);
} }
}


// Now we consider this state checked // Do the breadth-first search, marking all states
unchecked[to] = false; // 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) { for (size_t i = 0; i < Size(); ++i) {
if (useless[i]) { if (useless[i]) {
res.insert(i); res.insert(i);
}
} }
} }


Expand Down
2 changes: 1 addition & 1 deletion pire/fsm.h
Expand Up @@ -104,7 +104,7 @@ namespace Pire {
/// Creates an FSM which matches reversed strings matched by current FSM. /// Creates an FSM which matches reversed strings matched by current FSM.
Fsm& Reverse(); 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; yset<size_t> DeadStates() const;


/// Removes all dead end paths from FSM /// Removes all dead end paths from FSM
Expand Down

0 comments on commit 1f20273

Please sign in to comment.