package rationals;
/**
* Defines a Transition (an edge from a state to a state) in an Automaton
*
* This class defines the notion of transition of an automaton. a transition is
* a triple <em>(q , l , q')</em> where <em>q, q'</em> are states and
* <em>l</em> a label. States <em>q</em> and <em>q'</em> must belong to
* the same automaton <em>A</em> and the transition may only be used with this
* automaton <em>A</em>.
*
* @author yroos@lifl.fr
* @version 1.0
* @see Automaton
*/
public class Transition {
private int hash = Integer.MIN_VALUE;
private State start;
private Object label;
private State end;
/**
* Creates a new transition <em>(q , l , q')</em>.
*
* @param start
* the state <em>q</em> for this transition <em>(q , l , q')</em>.
* @param label
* the label <em>l</em>
* @param end
* the state <em>q'</em> for this transition <em>(q , l , q')</em>.
*/
public Transition(State start, Object label, State end) {
this.start = start;
this.label = label;
this.end = end;
}
/**
* Creates a new (invalid) transition. This transition is meant to be updated
* internally by an automaton.
*
* @param start
* the starting state.
*/
Transition(State start) {
this.start = start;
}
/**
* Returns the starting state of this transition.
*
* @return the starting state of this transition, that is the state <em>q</em>
* for this transition <em>(q , l , q')</em>.
*/
public State start() {
return start;
}
/**
* Returns the label this transition.
*
* @return the label state of this transition, that is the object <em>l</em>
* for this transition <em>(q , l , q')</em>.
*/
public Object label() {
return label;
}
/**
* Returns the ending state of this transition.
*
* @return the ending state of this transition, that is the state <em>q'</em>
* for this transition <em>(q , l , q')</em>.
*/
public State end() {
return end;
}
/**
* returns a textual representation of this transition.
*
* @return a textual representation of this transition based
*/
public String toString() {
if (label == null) {
return "(" + start + " , 1 , " + end + ")";
} else {
return "(" + start + " , " + label + " , " + end + ")";
}
}
/**
* Determines if this transition is equal to the parameter.
*
* @param o
* any object.
* @return true iff this transition is equal to the parameter. That is if
* <tt>o</tt> is a transition which is composed same states and
* label (in the sense of method <tt>equals</tt>).
*/
public boolean equals(Object o) {
if (o == null)
return false;
try {
Transition t = (Transition) o;
if (label != t.label) {
if (label == null || t.label == null)
return false;
if (!t.label.equals(label))
return false;
}
return (start == t.start()) && (end == t.end());
} catch (ClassCastException x) {
return false;
}
}
/**
* Returns a hashcode value for this transition.
*
* @return a hashcode value for this transition.
*/
public int hashCode() {
/* store computed value */
if (hash != Integer.MIN_VALUE)
return hash;
int x, y, z;
if (start == null)
x = 0;
else
x = start.hashCode();
if (end == null)
y = 0;
else
y = end.hashCode();
if (label == null)
z = 0;
else
z = label.hashCode();
int t = new java.awt.Point(x, y).hashCode();
return hash = new java.awt.Point(t, z).hashCode();
}
/**
* Replaces the label for this transition
* <p>
* WARNING: this method is extremely dangerous as it does not update the
* alphabet of the automaton this transition is part of. Be sure you know what
* you are doing or else everything could break down
*
* @param msg
*/
void setLabel(Object obj) {
this.label = obj;
}
}