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