/*
* 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 gui.action.OpenAction;
import gui.environment.EnvironmentFrame;
import java.awt.Color;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.io.File;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.swing.JButton;
import javax.swing.JOptionPane;
import javax.swing.JTextArea;
import debug.EDebug;
import automata.event.AutomataStateEvent;
import automata.event.AutomataStateListener;
import automata.event.AutomataTransitionEvent;
import automata.event.AutomataTransitionListener;
import automata.event.AutomataNoteEvent;
import automata.event.AutomataNoteListener;
import automata.mealy.MooreMachine;
import automata.turing.TuringMachine;
import gui.viewer.AutomatonPane;
/**
* The automata object is the root class for the representation of all forms of
* automata, including FSA, PDA, and Turing machines. This object does NOT
* simulate the behavior of any of those machines; it simply maintains a
* structure that holds and maintains the data necessary to represent such a
* machine.
*
* @see automata.State
* @see automata.Transition
*
* @author Thomas Finley
*/
public class Automaton implements Serializable, Cloneable {
/**
* Creates an instance of Automaton
. The created instance
* has no states and no transitions.
*/
public Automaton() {
states = new HashSet();
transitions = new HashSet();
finalStates = new HashSet();
initialState = null;
}
/**
* Creates a clone of this automaton.
*
* @return a clone of this automaton, or null
if the clone
* failed
*/
public Object clone() {
Automaton a;
// Try to create a new object.
try {
// I am a bad person for writing this hack.
// if (this instanceof TuringMachine)
// a = new TuringMachine(((TuringMachine) this).tapes());
// else
a = (Automaton) getClass().newInstance();
} catch (Throwable e) {
// Well golly, we're sure screwed now!
System.err.println("Warning: clone of automaton failed!");
return null;
}
a.setEnvironmentFrame(this.getEnvironmentFrame());
// Copy over the states.
HashMap map = new HashMap(); // Old states to new states.
Iterator it = states.iterator();
while (it.hasNext()) {
State state = (State) it.next();
State nstate = new State(state.getID(),
new Point(state.getPoint()), a);
// copyRelevantDataForBlocks(nstate, state, a);
nstate.setLabel(state.getLabel());
nstate.setName(state.getName());
map.put(state, nstate);
a.addState(nstate);
/*
* If it is a Moore machine, set the state output.
*/
if(this instanceof MooreMachine)
{
MooreMachine m = (MooreMachine) a;
m.setOutput(nstate, ((MooreMachine)this).getOutput(state));
}
}
// Set special states.
it = finalStates.iterator();
while (it.hasNext()) {
State state = (State) it.next();
a.addFinalState((State) map.get(state));
}
a.setInitialState((State) map.get(getInitialState()));
// Copy over the transitions.
it = states.iterator();
while (it.hasNext()) {
State state = (State) it.next();
Transition[] ts = getTransitionsFromState(state);
State from = (State) map.get(state);
for (int i = 0; i < ts.length; i++) {
State to = (State) map.get(ts[i].getToState());
Transition toBeAdded = (Transition) ts[i].clone(); //call clone instead of copy so that the gui stuff can get appropriately updated
toBeAdded.setFromState(from);
toBeAdded.setToState(to);
// a.addTransition(ts[i].copy(from, to));
a.addTransition(toBeAdded);
}
}
for(int k = 0; k < this.getNotes().size(); k++){
Note curNote = (Note)this.getNotes().get(k);
a.addNote(new Note(curNote.getAutoPoint(), curNote.getText()));
((Note)a.getNotes().get(k)).setView(curNote.getView());
//for undo, we must initialize the clone to our view
}
// Should be done now!
return a;
}
/**
* Turn a into b. This code is copied from the clone method and tweaked. If I am daring, I will remove it from clone and call this.
*
* @param dest
* @param src
*/
public static void become(Automaton dest, Automaton src){
dest.clear();
// Copy over the states.
HashMap map = new HashMap(); // Old states to new states.
Iterator it = src.states.iterator();
while (it.hasNext()) {
State state = (State) it.next();
State nstate = new State(state.getID(),
new Point(state.getPoint()), dest);
nstate.setLabel(state.getLabel());
nstate.setName(state.getName());
map.put(state, nstate);
dest.addState(nstate);
/*
* If it is a Moore machine, set the state output.
*/
if(src instanceof MooreMachine)
{
MooreMachine m = (MooreMachine) dest;
m.setOutput(nstate, ((MooreMachine)src).getOutput(state));
}
}
// Set special states.
it = src.finalStates.iterator();
while (it.hasNext()) {
State state = (State) it.next();
dest.addFinalState((State) map.get(state));
}
dest.setInitialState((State) map.get(src.getInitialState()));
// Copy over the transitions.
it = src.states.iterator();
while (it.hasNext()) {
State state = (State) it.next();
Transition[] ts = src.getTransitionsFromState(state);
State from = (State) map.get(state);
for (int i = 0; i < ts.length; i++) {
State to = (State) map.get(ts[i].getToState());
Transition toBeAdded = (Transition) ts[i].clone(); //call clone instead of copy so that the gui stuff can get appropriately updated
toBeAdded.setFromState(from);
toBeAdded.setToState(to);
// dest.addTransition(ts[i].copy(from, to));
dest.addTransition(toBeAdded);
}
}
for(int k = 0; k < src.getNotes().size(); k++){
Note curNote = (Note)src.getNotes().get(k);
dest.addNote(new Note(curNote.getAutoPoint(), curNote.getText()));
((Note)dest.getNotes().get(k)).initializeForView(curNote.getView());
}
dest.setEnvironmentFrame(src.getEnvironmentFrame());
}
/**
* Retrieves all transitions that eminate from a state.
*
* @param from
* the State
from which returned transitions
* should come from
* @return an array of the Transition
objects emanating from
* this state
*/
public Transition[] getTransitionsFromState(State from) {
Transition[] toReturn = (Transition[]) transitionArrayFromStateMap
.get(from);
if (toReturn == null) {
List list = (List) transitionFromStateMap.get(from);
toReturn = (Transition[]) list.toArray(new Transition[0]);
transitionArrayFromStateMap.put(from, toReturn);
}
return toReturn;
}
/**
* Retrieves all transitions that travel from a state.
*
* @param to
* the State
to which all returned transitions
* should go to
* @return an array of all Transition
objects going to the
* State
*/
public Transition[] getTransitionsToState(State to) {
Transition[] toReturn = (Transition[]) transitionArrayToStateMap
.get(to);
if (toReturn == null) {
List list = (List) transitionToStateMap.get(to);
toReturn = (Transition[]) list.toArray(new Transition[0]);
transitionArrayToStateMap.put(to, toReturn);
}
return toReturn;
}
/**
* Retrieves all transitions going from one given state to another given
* state.
*
* @param from
* the state all returned transitions should come from
* @param to
* the state all returned transitions should go to
* @return an array of all transitions coming from from
and
* going to to
*/
public Transition[] getTransitionsFromStateToState(State from, State to) {
Transition[] t = getTransitionsFromState(from);
ArrayList list = new ArrayList();
for (int i = 0; i < t.length; i++)
if (t[i].getToState() == to)
list.add(t[i]);
return (Transition[]) list.toArray(new Transition[0]);
}
/**
* Retrieves all transitions.
*
* @return an array containing all transitions for this automaton
*/
public Transition[] getTransitions() {
if (cachedTransitions == null)
cachedTransitions = (Transition[]) transitions
.toArray(new Transition[0]);
return cachedTransitions;
}
/**
* Adds a Transition
to this automaton. This method may do
* nothing if the transition is already in the automaton.
*
* @param trans
* the transition object to add to the automaton
*/
public void addTransition(Transition trans) {
if (!getTransitionClass().isInstance(trans) || trans == null) {
throw (new IncompatibleTransitionException());
}
if (transitions.contains(trans))
return;
if(trans.getToState() == null || trans.getFromState() == null) return;
transitions.add(trans);
if(transitionFromStateMap == null) transitionFromStateMap = new HashMap();
List list = (List) transitionFromStateMap.get(trans.getFromState());
list.add(trans);
if(transitionToStateMap == null) transitionToStateMap = new HashMap();
list = (List)transitionToStateMap.get(trans.getToState()) ;
list.add(trans);
transitionArrayFromStateMap.remove(trans.getFromState());
transitionArrayToStateMap.remove(trans.getToState());
cachedTransitions = null;
distributeTransitionEvent(new AutomataTransitionEvent(this, trans,
true, false));
}
/**
* Replaces a Transition
in this automaton with another
* transition with the same from and to states. This method will delete the
* old if the transition is already in the automaton.
*
* @param oldTrans
* the transition object to add to the automaton
* @param newTrans
* the transition object to add to the automaton
*/
public void replaceTransition(Transition oldTrans, Transition newTrans) {
if (!getTransitionClass().isInstance(newTrans)) {
throw new IncompatibleTransitionException();
}
if (oldTrans.equals(newTrans)) {
return;
}
if (transitions.contains(newTrans)) {
removeTransition(oldTrans);
return;
}
if (!transitions.remove(oldTrans)) {
throw new IllegalArgumentException(
"Replacing transition that not already in the automaton!");
}
transitions.add(newTrans);
List list = (List) transitionFromStateMap.get(oldTrans.getFromState());
list.set(list.indexOf(oldTrans), newTrans);
list = (List) transitionToStateMap.get(oldTrans.getToState());
list.set(list.indexOf(oldTrans), newTrans);
transitionArrayFromStateMap.remove(oldTrans.getFromState());
transitionArrayToStateMap.remove(oldTrans.getToState());
cachedTransitions = null;
distributeTransitionEvent(new AutomataTransitionEvent(this, newTrans,
true, false));
}
/**
* Removes a Transition
from this automaton.
*
* @param trans
* the transition object to remove from this automaton.
*/
public void removeTransition(Transition trans) {
transitions.remove(trans);
List l = (List) transitionFromStateMap.get(trans.getFromState());
l.remove(trans);
l = (List) transitionToStateMap.get(trans.getToState());
l.remove(trans);
// Remove cached arrays.
transitionArrayFromStateMap.remove(trans.getFromState());
transitionArrayToStateMap.remove(trans.getToState());
cachedTransitions = null;
distributeTransitionEvent(new AutomataTransitionEvent(this, trans,
false, false));
}
/**
* Moves objects from Array to List
*
* @param point
* @return
*/
public static List makeListFromArray(Object[] array) {
List list = new ArrayList();
for (int k = 0; k < array.length; k++) {
list.add(array[k]);
}
return list;
}
/**
* Creates a state, inserts it in this automaton, and returns that state.
* The ID for the state is set appropriately.
*
* @param point
* the point to put the state at
*/
public State createState(Point point) {
int i = 0;
while (getStateWithID(i) != null)
i++;
State state = new State(i, point, this);
addState(state);
return state;
}
/**
* Creates a state, inserts it in this automaton, and returns that state.
* The ID for the state is set appropriately.
*
* @param point
* the point to put the state at
*/
public final State createStateWithId(Point point, int i) {
State state = new State(i, point, this);
addState(state);
return state;
}
/**
* Adds a new state to this automata. Clients should use the createState
* method instead.
*
* @param state
* the state to add
*/
protected final void addState(State state) {
states.add(state);
transitionFromStateMap.put(state, new LinkedList());
transitionToStateMap.put(state, new LinkedList());
cachedStates = null;
distributeStateEvent(new AutomataStateEvent(this, state, true, false,
false));
}
/**
* Removes a state from the automaton. This will also remove all transitions
* associated with this state.
*
* @param state
* the state to remove
*/
public void removeState(State state) {
Transition[] t = getTransitionsFromState(state);
for (int i = 0; i < t.length; i++)
removeTransition(t[i]);
t = getTransitionsToState(state);
for (int i = 0; i < t.length; i++)
removeTransition(t[i]);
distributeStateEvent(new AutomataStateEvent(this, state, false, false,
false));
states.remove(state);
finalStates.remove(state);
if (state == initialState)
initialState = null;
transitionFromStateMap.remove(state);
transitionToStateMap.remove(state);
transitionArrayFromStateMap.remove(state);
transitionArrayToStateMap.remove(state);
cachedStates = null;
// Iterator statIt = states.iterator();
// while (statIt.hasNext()) {
// State temp = (State) statIt.next();
// if (temp.getParentBlock() != null) {
// if (temp.getParentBlock().equals(state)) {
// removeState(temp);
// }
// }
// }
}
/**
* Sets the new initial state to initialState
and returns
* what used to be the initial state, or null
if there was no
* initial state. The state specified should already exist in the automata.
*
* @param initialState
* the new initial state
* @return the old initial state, or null
if there was no
* initial state
*/
public State setInitialState(State initialState) {
State oldInitialState = this.initialState;
this.initialState = initialState;
distributeStateEvent(new AutomataStateEvent(this, initialState, false, false,
true));
return oldInitialState;
}
/**
* Returns the start state for this automaton.
*
* @return the start state for this automaton
*/
public State getInitialState() {
return this.initialState;
}
/**
* Returns an array that contains every state in this automaton. The array
* is gauranteed to be in order of ascending state IDs.
*
* @return an array containing all the states in this automaton
*/
public State[] getStates() {
if (cachedStates == null) {
cachedStates = (State[]) states.toArray(new State[0]);
Arrays.sort(cachedStates, new Comparator() {
public int compare(Object o1, Object o2) {
return ((State) o1).getID() - ((State) o2).getID();
}
public boolean equals(Object o) {
return this == o;
}
});
}
return cachedStates;
}
public void selectStatesWithinBounds(Rectangle bounds){
State[] states = getStates();
for(int k = 0; k < states.length; k++){
states[k].setSelect(false);
if(bounds.contains(states[k].getPoint())){
states[k].setSelect(true);
}
}
}
public ArrayList getNotes() {
return myNotes;
}
public void addNote(Note note){
myNotes.add(note);
distributeNoteEvent(new AutomataNoteEvent(this, note, true, false));
}
public void deleteNote(Note note){
for(int k = 0; k < myNotes.size(); k++){
if(note == myNotes.get(k)) myNotes.remove(k);
}
distributeNoteEvent(new AutomataNoteEvent(this, note, true, false));
}
/**
* Adds a single final state to the set of final states. Note that the
* general automaton can have an unlimited number of final states, and
* should have at least one. The state that is added should already be one
* of the existing states.
*
* @param finalState
* a new final state to add to the collection of final states
*/
public void addFinalState(State finalState) {
cachedFinalStates = null;
finalStates.add(finalState);
distributeStateEvent(new AutomataStateEvent(this, finalState, false, false,
true));
}
/**
* Removes a state from the set of final states. This will not remove a
* state from the list of states; it shall merely make it nonfinal.
*
* @param state
* the state to make not a final state
*/
public void removeFinalState(State state) {
cachedFinalStates = null;
finalStates.remove(state);
distributeStateEvent(new AutomataStateEvent(this, state, false, false,
true));
}
/**
* Returns an array that contains every state in this automaton that is a
* final state. The array is not necessarily gauranteed to be in any
* particular order.
*
* @return an array containing all final states of this automaton
*/
public State[] getFinalStates() {
if (cachedFinalStates == null)
cachedFinalStates = (State[]) finalStates.toArray(new State[0]);
return cachedFinalStates;
}
/**
* Determines if the state passed in is in the set of final states.
*
* @param state
* the state to determine if is final
* @return true
if the state is a final state in this
* automaton, false
if it is not
*/
public boolean isFinalState(State state) {
return finalStates.contains(state);
}
/**
* Determines if the state passed in is the initial states.
* Added for JFLAP 6.3
* @param state
* the state to determine if is final
* @return true
if the state is a final state in this
* automaton, false
if it is not
*/
public boolean isInitialState(State state) {
return (state.equals(initialState));
}
/**
* Returns the State
in this automaton with this ID.
*
* @param id
* the ID to look for
* @return the instance of State
in this automaton with this
* ID, or null
if no such state exists
*/
public State getStateWithID(int id) {
Iterator it = states.iterator();
while (it.hasNext()) {
State state = (State) it.next();
if (state.getID() == id)
return state;
}
return null;
}
/**
* Tells if the passed in object is indeed a state in this automaton.
*
* @param state
* the state to check for membership in the automaton
* @return true
if this state is in the automaton, false
otherwise
*/
public boolean isState(State state) {
return states.contains(state);
}
/**
* Returns the particular class that added transition objects should be a
* part of. Subclasses may wish to override in case they want to restrict
* the type of transitions their automaton will respect. By default this
* method simply returns the class object for the abstract class automata.Transition
.
*
* @see #addTransition
* @see automata.Transition
* @return the Class
object that all added transitions should
* derive from
*/
protected Class getTransitionClass() {
return automata.Transition.class;
}
/**
* Returns a string representation of this Automaton
.
*/
public String toString() {
StringBuffer buffer = new StringBuffer();
buffer.append(super.toString());
buffer.append('\n');
State[] states = getStates();
for (int s = 0; s < states.length; s++) {
if (initialState == states[s])
buffer.append("--> ");
buffer.append(states[s]);
if (isFinalState(states[s]))
buffer.append(" **FINAL**");
buffer.append('\n');
Transition[] transitions = getTransitionsFromState(states[s]);
for (int t = 0; t < transitions.length; t++) {
buffer.append('\t');
buffer.append(transitions[t]);
buffer.append('\n');
}
}
return buffer.toString();
}
/**
* Adds a AutomataStateListener
to this automata.
*
* @param listener
* the listener to add
*/
public void addStateListener(AutomataStateListener listener) {
stateListeners.add(listener);
}
/**
* Adds a AutomataTransitionListener
to this automata.
*
* @param listener
* the listener to add
*/
public void addTransitionListener(AutomataTransitionListener listener) {
transitionListeners.add(listener);
}
/**
* Adds a AutomataNoteListener
to this automata.
*
* @param listener
* the listener to add
*/
public void addNoteListener(AutomataNoteListener listener) {
noteListeners.add(listener);
}
/**
* Gives an automata state change event to all state listeners.
*
* @param event
* the event to distribute
*/
void distributeStateEvent(AutomataStateEvent event) {
Iterator it = stateListeners.iterator();
while (it.hasNext()) {
AutomataStateListener listener = (AutomataStateListener) it.next();
listener.automataStateChange(event);
}
}
/**
* Removes a AutomataStateListener
from this automata.
*
* @param listener
* the listener to remove
*/
public void removeStateListener(AutomataStateListener listener) {
stateListeners.remove(listener);
}
/**
* Removes a AutomataTransitionListener
from this automata.
*
* @param listener
* the listener to remove
*/
public void removeTransitionListener(AutomataTransitionListener listener) {
transitionListeners.remove(listener);
}
/**
* Removes a AutomataNoteListener
from this automata.
*
* @param listener
* the listener to remove
*/
public void removeNoteListener(AutomataNoteListener listener) {
noteListeners.remove(listener);
}
/**
* Gives an automata transition change event to all transition listeners.
*
* @param event
* the event to distribute
*/
void distributeTransitionEvent(AutomataTransitionEvent event) {
Iterator it = transitionListeners.iterator();
while (it.hasNext()) {
AutomataTransitionListener listener = (AutomataTransitionListener) it
.next();
listener.automataTransitionChange(event);
}
}
/**
* Gives an automata note change event to all state listeners.
*
* @param event
* the event to distribute
*/
void distributeNoteEvent(AutomataNoteEvent event) {
Iterator it = noteListeners.iterator();
while (it.hasNext()) {
AutomataNoteListener listener = (AutomataNoteListener) it.next();
listener.automataNoteChange(event);
}
}
/**
* This handles deserialization so that the listener sets are reset to avoid
* null pointer exceptions when one tries to add listeners to the object.
*
* @deprecated
* @param in
* the input stream for the object
*/
private void readObject(java.io.ObjectInputStream in)
throws java.io.IOException, ClassNotFoundException {
// Reset all nonread objects.
/* resetForLoad();
// Do the reading in of objects.
int version = in.readInt();
if (version >= 0) { // Adjust by version.
// The reading for version 0 of this object.
Set s = (Set) in.readObject();
Iterator it = s.iterator();
while (it.hasNext())
addState((State) it.next());
initialState = (State) in.readObject();
finalStates = (Set) in.readObject();
// Let the class take care of the transition stuff.
Set trans = (Set) in.readObject();
it = trans.iterator();
while (it.hasNext())
addTransition((Transition) it.next());
if (this instanceof TuringMachine) {
((TuringMachine) this).tapes = in.readInt();
}
}
while (!in.readObject().equals("SENT"))
; // Read until sentinel.
*/
}
/**
* This handles serialization. No longer used.
*/
private void writeObject(java.io.ObjectOutputStream out)
throws java.io.IOException {
/*
out.writeInt(0); // Version of the stream.
// Version 0 outstuff...
out.writeObject(states);
out.writeObject(initialState);
out.writeObject(finalStates);
out.writeObject(transitions);
if (this instanceof TuringMachine) {
out.writeInt(((TuringMachine) this).tapes);
}
out.writeObject("SENT"); // The sentinel object.
*/
}
// /**
// * Gets the map of blocks for this automaton.
// *
// * @return the map of blocks
// */
// public Map getBlockMap() {
// return blockMap;
// }
/**
* Gets the Environment Frame the automaton is in.
* @return the environment frame.
*/
public EnvironmentFrame getEnvironmentFrame() {
return myEnvFrame;
}
/**
* Changes the environment frame this automaton is in.
* @param frame the environment frame
*/
public void setEnvironmentFrame(EnvironmentFrame frame) {
myEnvFrame = frame;
}
public void setFilePath(String name){
fileName = name;
}
public String getFileName(){
int last = fileName.lastIndexOf("\\");
if(last == -1) last = fileName.lastIndexOf("/");
return fileName.substring(last+1);
}
public String getFilePath(){
int last = fileName.lastIndexOf("\\");
if(last == -1) last = fileName.lastIndexOf("/");
return fileName.substring(0, last+1);
}
public int hashCode(){
// EDebug.print("The Hash is that is hashed, is truly hashed");
int ret = 0;
for (Object o: states)
ret+= ((State) o).specialHash();
for (Object o:transitions)
ret+=((Transition) o).specialHash();
for (Object o: myNotes)
ret+=((Note) o).specialHash();
ret+=finalStates.hashCode();
ret+=initialState == null? 0: (int)(initialState.specialHash()*Math.PI);
// EDebug.print(ret);
return ret;
}
// AUTOMATA SPECIFIC CRAP
// This includes lots of stuff not strictly necessary for the
// defintion of automata, but stuff that makes it at least
// somewhat efficient in the process.
private String fileName = ""; // Jinghui bug fixing.
private EnvironmentFrame myEnvFrame = null;
/** The collection of states in this automaton. */
protected Set states;
/** The cached array of states. */
private State[] cachedStates = null;
/** The cached array of transitions. */
private Transition[] cachedTransitions = null;
/** The cached array of final states. */
private State[] cachedFinalStates = null;
/**
* The collection of final states in this automaton. This is a subset of the
* "states" collection.
*/
protected Set finalStates;
/** The initial state. */
protected State initialState = null;
/** The list of transitions in this automaton. */
protected Set transitions;
/**
* A mapping from states to a list holding transitions from those states.
*/
private HashMap transitionFromStateMap = new HashMap();
/**
* A mapping from state to a list holding transitions to those states.
*/
private HashMap transitionToStateMap = new HashMap();
/**
* A mapping from states to an array holding transitions from a state. This
* is a sort of cashing.
*/
private HashMap transitionArrayFromStateMap = new HashMap();
/**
* A mapping from states to an array holding transitions from a state. This
* is a sort of cashing.
*/
private HashMap transitionArrayToStateMap = new HashMap();
// /**
// * A mapping from the name of an automaton to the automaton. Used for
// * referencing the same automaton from multiple buliding blocks
// */
// private HashMap blockMap = new HashMap();
private ArrayList myNotes = new ArrayList();
public Color myColor = new Color(255, 255, 150);
// LISTENER STUFF
// Structures related to this object as something that generates
// events, in particular as it pertains to the removal and
// addition of states and transtions.
private transient HashSet transitionListeners = new HashSet();
private transient HashSet stateListeners = new HashSet();
private transient HashSet noteListeners = new HashSet();
/**
* Reset all non-transient data structures.
*/
protected void clear(){
HashSet t = new HashSet(transitions);
for (Object o:t)
removeTransition((Transition)o);
transitions = new HashSet();
t = new HashSet(states);
for (Object o:t)
removeState((State)o);
states = new HashSet();
finalStates = new HashSet();
initialState = null;
cachedStates = null;
cachedTransitions = null;
cachedFinalStates = null;
transitionFromStateMap = new HashMap();
transitionToStateMap = new HashMap();
transitionArrayFromStateMap = new HashMap();
transitionArrayToStateMap = new HashMap();
while (myNotes.size() != 0){
AutomatonPane ap = ((Note) myNotes.get(0)).getView();
ap.remove((Note)myNotes.get(0));
ap.repaint();
deleteNote((Note)myNotes.get(0));
}
}
}