1   /*
2    *  State.java
3    *
4    *  Copyright (c) 1998-2005, The University of Sheffield.
5    *
6    *  This file is part of GATE (see http://gate.ac.uk/), and is free
7    *  software, licenced under the GNU Library General Public License,
8    *  Version 2, June 1991 (in the distribution as file licence.html,
9    *  and also available at http://gate.ac.uk/gate/licence.html).
10   *
11   *  Valentin Tablan, 11/Apr/2000
12   *
13   *  $Id: State.java,v 1.39 2005/01/11 13:51:34 ian Exp $
14   */
15  
16  package gate.fsm;
17  
18  import java.util.Iterator;
19  
20  import gate.jape.*;
21  import gate.util.SimpleArraySet;
22  
23  /**
24   * This class implements a Finite State Machine state.
25   *
26   */
27  public class State implements JapeConstants {
28  
29    /** Debug flag
30     */
31    private static final boolean DEBUG = false;
32  
33    /**
34     * Build a new state.
35     */
36    public State() {
37      myIndex = State.index++;
38      isFinal = false;
39    }
40  
41    /**
42     * Reports if this state is a final one.
43     * Note: A state has an associated action if and only if it is final.
44     */
45    public boolean isFinal() {
46      return isFinal;
47    }
48  
49    /**
50     * Gets the set of transitions for this state.
51     *
52     * @return a Set contining objects of type gate.fsm.Transition
53     */
54  // >>> DAM, was Set
55  /*
56    public Set getTransitions() {
57      return transitions;
58    }
59  */
60  // >>> DAM, TransArray optimization
61    public SimpleArraySet getTransitions() {
62      return transitions;
63    }
64  // >>> DAM, end
65    /** Sets the action associated to this FINAL state. An action is actually
66     * a gate.jape.RightHandSide object.
67     * NOTE: only a final state has an associated action so after a call to this
68     * method this state will be a final one.
69     */
70    protected void setAction(RightHandSide rhs) {
71      action = rhs;
72      isFinal = (action != null);
73    }
74  
75    /** Sets the value for fileIndex. File index is the index in the jape
76     * definition file of the rule that contains as right hand side the action
77     * associated to this state. This value is only intended for final states.
78     */
79    protected void setFileIndex(int i) { fileIndex = i; }
80  
81    /** Sets the value for priority. Priority is the priority in the jape
82     * definition file of the rule that contains as right hand side the action
83     * associated to this state. This value is only intended for final states.
84     */
85    protected void setPriority(int i) { priority = i; }
86  
87    /**
88     * Gets the action associated to this state.
89     *
90     * @return a RightHandSide object
91     */
92    public RightHandSide getAction() {
93      return action;
94    }
95  
96    /**
97     * Returns the index in the definition file of the rule that generated this
98     * state.
99     * The value for fileIndex is correct only on final states!
100    */
101   int getFileIndex() { return fileIndex; }
102 
103   /**
104    * Returns the priority in the definition file of the rule that generated
105    * this state.
106    * This value is correct only on final states!
107    */
108   int getPriority() { return priority; }
109 
110   /**
111    * Adds a new transition to the list of outgoing transitions for this state.
112    *
113    * @param transition the transition to be added
114    */
115   public void addTransition(Transition transition) {
116     transitions.add(transition);
117   } // addTransition
118 
119   /**
120    * Gets the index of this state. Each state has a unique index (a int value).
121    * This value is not actually used by any of the algorithms. It is useful only
122    * as a way of refering to states in string representations so it is used by
123    * toString and GML related methods.
124    *
125    * @return the index associated to this state
126    */
127   protected int getIndex() {
128     return myIndex;
129   }// getIndex
130 
131   /**
132    * Returns a GML (graph modelling language) representation for the edges
133    * corresponding to transitions departing from this state in the
134    * transition graph of the FSM to which this state belongs
135    *
136    * @return a string value contining the GML text
137    */
138   public String getEdgesGML() {
139 ///    String res = "";
140     StringBuffer res = new StringBuffer(gate.Gate.STRINGBUFFER_SIZE);
141 
142     Iterator transIter = transitions.iterator();
143     BasicPatternElement bpe;
144 
145     while(transIter.hasNext()) {
146       Transition currentTrans = (Transition)transIter.next();
147 /*      res += "edge [ source " + myIndex +
148              " target " + currentTrans.getTarget().getIndex() +
149              " label \"" + currentTrans.shortDesc() + ":";
150 */
151         res.append("edge [ source ");
152         res.append(myIndex);
153         res.append(" target ");
154         res.append(currentTrans.getTarget().getIndex());
155         res.append(" label \"");
156         res.append(currentTrans.shortDesc());
157         res.append(":");
158 
159              bpe = currentTrans.getConstraints();
160              if(bpe == null) ///res += "null";
161                 res.append("null");
162              else ///res += bpe.shortDesc();
163                 res.append(bpe.shortDesc());
164 ///             res += " :" + currentTrans.getBindings() +              "\" ]\n";
165              res.append(" :");
166              res.append(currentTrans.getBindings());
167              res.append("\" ]\n");
168     }
169     return res.toString();
170   } // getEdgesGML
171 
172   /**
173    * Returns a textual description of this state
174    *
175    * @return a String value.
176    */
177   public String toString() {
178 ///    String res = "State " + myIndex;
179     StringBuffer res = new StringBuffer(gate.Gate.STRINGBUFFER_SIZE);
180 
181     if(isFinal()) ///res += "\nFinal!";
182         res.append("\nFinal!");
183 
184     ///res += "\nTransitions:\n";
185     res.append("\nTransitions:\n");
186 
187     Iterator transIter = transitions.iterator();
188     while(transIter.hasNext()){
189       ///res += transIter.next().toString();
190       res.append(transIter.next().toString());
191     }
192     return res.toString();
193   }
194 
195 
196   /**
197    * A set of objects of type gata.fsm.Transition representing the outgoing
198    * transitions.
199    */
200 // >>> DAM was
201 /*
202   private Set transitions = new HashSet();
203 */
204 // >>> DAM, TransArray optimization
205   private SimpleArraySet transitions = new SimpleArraySet();
206 // >>> DAM, end
207 
208   /**
209    * Is this state a final one?
210    */
211   protected boolean isFinal = false;
212 
213   /**
214    * The right hand side associated to the rule for which this state recognizes
215    * the lhs.
216    */
217   protected RightHandSide action = null;
218 
219   /**
220    * The unique index of this state.
221    */
222   protected int myIndex;
223 
224   /**
225    * The class data member used for generating unique indices for State
226    * instances.
227    */
228   protected static int index = 0;
229 
230   /**
231    * The index in the definition file of the rule that was used for creating
232    * this state.
233    * NOTE: this member is consistent only for FINAL STATES!
234    */
235   protected int fileIndex = 0;
236 
237   /**
238    * The priority of the rule from which this state derived.
239    *
240    */
241   protected int priority = -1;
242 
243 } // State
244