/* * (C) Copyright 2001 Arnaud Bailly (arnaud.oqube@gmail.com), * Yves Roos (yroos@lifl.fr) and others. * * Licensed under the Apache License, Version 2.0 (the License); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an AS IS BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ 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<L> { private int hashCodeCache = Integer.MIN_VALUE; private State start; private L 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, L 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 L 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 */ @Override public String toString() { if (label == null) { return "(" + start + " , epsilon , " + 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>). */ @Override public boolean equals(Object o) { if (!(o instanceof Transition)) return false; @SuppressWarnings("unchecked") Transition<L> t = (Transition<L>) 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()); } /** * Returns a hashcode value for this transition. * * @return a hashcode value for this transition. */ @Override public int hashCode() { /* store computed value */ if (hashCodeCache != Integer.MIN_VALUE) return hashCodeCache; int x = start == null ? 0 : start.hashCode(); int y = end == null ? 0 : end.hashCode(); int z = label == null ? 0 : label.hashCode(); int hash = 17; hash = hash * 31 + x; hash = hash * 31 + y; hash = hash * 31 + z; hashCodeCache = hash; return hash; } /** * 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(L obj) { this.label = obj; } }