/*
* 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.fsa;
import automata.Automaton;
import automata.State;
import automata.Transition;
/**
* The FSA label handler is an object that can convert a finite state automaton
* with transition labels of more than one character in length into an
* equivalent finite state automaton with all transition labels exactly one
* character in length.
*
* @author Ryan Cavalcante
*/
public class FSALabelHandler {
/**
* Creates an instance of FSALabelHandler
.
*/
private FSALabelHandler() {
}
/**
* Returns true if automaton
has labels with multiple
* characters, instead of single character labels.
*
* @param automaton
* the automaton.
* @return true if automaton
has labels with multiple
* characters, instead of single character labels.
*/
public static boolean hasMultipleCharacterLabels(Automaton automaton) {
Transition[] transitions = automaton.getTransitions();
for (int k = 0; k < transitions.length; k++) {
FSATransition transition = (FSATransition) transitions[k];
String label = transition.getLabel();
if (label.length() > 1)
return true;
}
return false;
}
/**
* Changes transition
in automaton
to several
* transitions each with labels of one character in length. This algorithm
* introduces new states in automaton
.
*
* @param transition
* the transition to break up into several transitions of one
* character (in length) a piece.
* @param automaton
* the automaton that has the transition.
*/
public static void handleLabel(Transition transition, Automaton automaton) {
/*
* FSATransition trans = (FSATransition) transition; String label =
* trans.getLabel(); String firstChar = label.substring(0,1); String
* restOfLabel = label.substring(1);
*
* StatePlacer sp = new StatePlacer();
*
* State newState =
* automaton.createState(sp.getPointForState(automaton)); Transition
* newTrans1 = new FSATransition(trans.getFromState(), newState,
* firstChar); Transition newTrans2 = new FSATransition(newState,
* trans.getToState(), restOfLabel); automaton.addTransition(newTrans1);
* automaton.addTransition(newTrans2);
* automaton.removeTransition(transition); if(restOfLabel.length() > 1)
* handleLabel(newTrans2, automaton);
*/
FSATransition trans = (FSATransition) transition;
State from = transition.getFromState(), f = from, to = transition
.getToState();
automaton.removeTransition(trans);
String label = trans.getLabel();
int length = label.length();
for (int i = 0; i < length; i++) {
State going = i == length - 1 ? to : automaton
.createState(new java.awt.Point((f.getPoint().x
* (length - i - 1) + to.getPoint().x * (i + 1))
/ length, (f.getPoint().y * (length - i - 1) + to
.getPoint().y
* (i + 1))
/ length));
Transition newTrans = new FSATransition(from, going, label
.substring(i, i + 1));
automaton.addTransition(newTrans);
from = going;
}
}
public static void splitLabel(Transition transition, Automaton automaton){
FSATransition trans = (FSATransition) transition;
State from = transition.getFromState(), f = from, to = transition
.getToState();
automaton.removeTransition(trans);
String label = trans.getLabel();
for(int i=label.charAt(label.indexOf("[")+1); i<=label.charAt(label.indexOf("[")+3); i++){
Transition newTrans = new FSATransition(from, to, Character.toString((char)i));
automaton.addTransition(newTrans);
}
}
/**
* Changes all transitions in automaton
into transitions with
* at most one character per label. This could introduce more states into
* automaton
.
*
* @param automaton
* the automaton.
*/
public static FiniteStateAutomaton removeMultipleCharacterLabels(
Automaton automaton) {
FiniteStateAutomaton fsa = (FiniteStateAutomaton) automaton.clone();
Transition[] transitions = fsa.getTransitions();
for (int k = 0; k < transitions.length; k++) {
FSATransition transition = (FSATransition) transitions[k];
String label = transition.getLabel();
if (label.length() > 1) {
handleLabel(transition, fsa);
}
}
return fsa;
}
/**
* Changes all transitions in automaton
into transitions with
* at most one character per label. This could introduce more states into
* automaton
.
*
* @param automaton
* the automaton.
*/
public static void removeMultipleCharacterLabelsFromAutomaton(Automaton automaton) {
Transition[] transitions = automaton.getTransitions();
for (int k = 0; k < transitions.length; k++) {
FSATransition transition = (FSATransition) transitions[k];
String label = transition.getLabel();
if (label.length() > 1) {
handleLabel(transition, automaton);
}
}
}
}