/*
* JFLAP - Formal Languages and Automata Package
*
*
* Susan H. Rodger
* Computer Science Department
* Duke University
* August 27, 2009
* Copyright (c) 2002-2009
* All rights reserved.
* JFLAP is open source software. Please see the LICENSE for terms.
*
*/
package automata;
import java.util.*;
/**
* The unreachable states detector object can be used to find all unreachable
* states in an automaton (i.e. all states for which there exists no path from
* the initial state to that state).
*
* @author Ryan Cavalcante
*/
public class UnreachableStatesDetector {
/**
* Creates an instance of UnreachableStatesDetector
*
* @param automaton
* the automaton to search for unreachable states.
*/
public UnreachableStatesDetector(Automaton automaton) {
myAutomaton = automaton;
}
/**
* Initializes all nodes for DFS by creating a Node object for each State in
* states
and coloring them all white.
*
* @param states
* the set of states to create Nodes for.
*/
public void initializeNodes(State[] states) {
myNodes = new Node[states.length];
/** Color all vertices white. */
for (int k = 0; k < states.length; k++) {
Node node = new Node(states[k]);
node.colorWhite();
myNodes[k] = node;
}
}
/**
* Returns all states in automaton that are unreachable from the initial
* state. This method implements the standard depth first search algorithm
* for directed graphs.
*
* @return all states in the automaton that are unreachable from the initial
* state.
*/
public State[] getUnreachableStates() {
ArrayList list = new ArrayList();
State[] states = myAutomaton.getStates();
/** Create nodes for DFS. */
initializeNodes(states);
Node initialNode = getNodeForState(myAutomaton.getInitialState());
/** Start DFS at node representing initial state. */
visit(initialNode);
/**
* DFS has completed. Add all non-visited (white) nodes to list of
* unreachable states.
*/
for (int k = 0; k < myNodes.length; k++) {
if (myNodes[k].isWhite()) {
list.add(myNodes[k].getState());
}
}
return (State[]) list.toArray(new State[0]);
}
/**
* Returns Node object that contains state
.
*
* @param state
* the state
* @return Node object that contains state
.
*/
public Node getNodeForState(State state) {
/** Search through all nodes for state. */
for (int k = 0; k < myNodes.length; k++) {
Node node = myNodes[k];
if (node.getState() == state)
return node;
}
return null;
}
/**
* The visit method from the standard DFS algorithm for directed graphs. A
* recursive function which visits all neighbors of node
* (i.e. all states reachable by transitions out of node
),
* and then visits the neighbors of all those nodes and so on. In the end,
* all nodes reachable from node
will have been visited and
* colored black.
*/
public void visit(Node node) {
node.colorGrey();
Transition[] transitions = myAutomaton.getTransitionsFromState(node
.getState());
for (int k = 0; k < transitions.length; k++) {
Transition transition = transitions[k];
State toState = transition.getToState();
Node v = getNodeForState(toState);
if (v.isWhite()) {
visit(v);
}
}
node.colorBlack();
}
/** The automaton. */
protected Automaton myAutomaton;
/** Set of nodes for dfs. */
protected Node[] myNodes;
}