00001 /*
00002 This product contains certain software code or other information
00003 ("AT&T Software") proprietary to AT&T Corp. ("AT&T"). The AT&T
00004 Software is provided to you "AS IS". YOU ASSUME TOTAL RESPONSIBILITY
00005 AND RISK FOR USE OF THE AT&T SOFTWARE. AT&T DOES NOT MAKE, AND
00006 EXPRESSLY DISCLAIMS, ANY EXPRESS OR IMPLIED WARRANTIES OF ANY KIND
00007 WHATSOEVER, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
00008 MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, WARRANTIES OF
00009 TITLE OR NON-INFRINGEMENT OF ANY INTELLECTUAL PROPERTY RIGHTS, ANY
00010 WARRANTIES ARISING BY USAGE OF TRADE, COURSE OF DEALING OR COURSE OF
00011 PERFORMANCE, OR ANY WARRANTY THAT THE AT&T SOFTWARE IS "ERROR FREE" OR
00012 WILL MEET YOUR REQUIREMENTS.
00013
00014 Unless you accept a license to use the AT&T Software, you shall not
00015 reverse compile, disassemble or otherwise reverse engineer this
00016 product to ascertain the source code for any AT&T Software.
00017
00018 (c) AT&T Corp. All rights reserved. AT&T is a registered trademark of AT&T Corp.
00019
00020 ***********************************************************************
00021
00022 History:
00023
00024 24/11/99 - initial release by Hartmut Liefke, liefke@seas.upenn.edu
00025 Dan Suciu, suciu@research.att.com
00026 */
00027
00028 //**************************************************************************
00029 //**************************************************************************
00030
00031 // This module contains the implementation of finite state machines
00032
00033 #ifndef FSM_HPP
00034 #define FSM_HPP
00035
00036 #include "Types.hpp"
00037 #include "MemStreamer.hpp"
00038
00039 //#define FSM_NEGATE // Enables Negation of FSMs
00040 //#define FSM_PRINT // Enables Print-functions for FSMs
00041 //#define FSM_STORE // Enables Store/Load functions for FSMs
00042
00043 // We distinguish three types of edges:
00044
00045 #define EDGETYPE_LABEL 0 // A normal label edge
00046 // A particular instance of label edges are
00047 // pound-edges - i.e. edges with the '#' symbol!
00048 #define EDGETYPE_NEGLABELLIST 1 // An edge that captures everything minus certain labels
00049 #define EDGETYPE_EMPTY 2 // An empty edge. This is only used for
00050 // non-deterministic FSMs
00051
00052 class MemStreamer;
00053 class Input;
00054
00055 // We use the following two MemStreamers
00056 extern MemStreamer *fsmtmpmem; // For temporary transformations -
00057 // used for example for making FSMs deterministic or minimal
00058 extern MemStreamer *fsmmem; // For usual objects, such as FSM edges, states
00059
00060
00061 struct FSMLabel
00062 // A label in the FSM within the 'EDGETYPE_NEGLABELLIST' edge
00063 // Labels are concatenated in a single-chained list
00064 {
00065 TLabelID labelid; // The label ID
00066 FSMLabel *next; // The next label
00067
00068 FSMLabel(TLabelID mylabelid,FSMLabel *mynext=NULL)
00069 {
00070 labelid=mylabelid;
00071 next=mynext;
00072 }
00073
00074 void *operator new(size_t size, MemStreamer *mem);
00075 #ifdef SPECIAL_DELETE
00076 void operator delete(void *ptr,MemStreamer *mem) {}
00077 #endif
00078 void operator delete(void *ptr) {}
00079 };
00080
00081 //**************************************************************************
00082 //**************************************************************************
00083
00084 struct FSMStateSetItem;
00085 class FSMEdge;
00086 class FSM;
00087
00088 class FSMState
00089 // Represents a state in the FSM
00090 {
00091 friend FSM;
00092 friend FSMEdge;
00093 unsigned isfinal:1; // Final state?
00094 unsigned isaccepting:1; // Determines whether the FSM in that (final) state
00095 // will definitely accept
00096 // the word, no matter what comes afterwards
00097 // In other words: all following states are final states
00098 unsigned isoutcomplete:1; // Describes whether the outgoing edges capture *all*
00099 // cases of labels
00100 unsigned haspoundsahead:1; // Is true, iff there are pound-edge that can be
00101 // reached from this state
00102 unsigned stateid:10; // The identifier of the state
00103 FSMEdge *outedges; // The list of outgoing edges
00104 FSMState *next; // The next state (all states in the FSM are concatenated in a list)
00105
00106 // Depending on the current type of state, we keep some additional info
00107 union
00108 {
00109 FSMStateSetItem *origstateset; // This is used for the conversion from nondet=>det
00110 // Contains a reference to the set of nondet. states
00111 // represented by this det. state
00112 void *data;
00113 long tmpval;
00114 };
00115
00116 char PruneRedundantStatesRecurs(); // Markes states that are either not reachable
00117 // from the start state or states that never lead
00118 // to final states
00119 char FindAcceptingStatesRecurs(); // Sets attribute 'isaccepting' for the states appropriately
00120 char HasPoundsAheadRecurs(); // Determines for the state whether there are pound-edges
00121 // reachable from that state
00122
00123 void EliminateRedundantPoundEdges();// This function eliminate redundant outgoing pound-edges
00124 // Pound-edges are not needed, if all cases are captured
00125 // by an outgoing negative edge
00126
00127 void ComputeOutCompleteness(); // Determines whether the state is 'out-complete'
00128 // and sets 'outcomplete' accordingly
00129
00130 public:
00131
00132 FSMState() {}
00133 FSMState(unsigned mystateid,char myisfinal=0);
00134 FSMState(unsigned mystateid,FSMStateSetItem *myorigdataset);
00135
00136 void *operator new(size_t size, MemStreamer *mem) { return mem->GetByteBlock(size);}
00137 void operator delete(void *ptr) {}
00138 void *operator new[](size_t size, MemStreamer *mem) { return mem->GetByteBlock(size);}
00139 void operator delete[](void *ptr) {}
00140 #ifdef SPECIAL_DELETE
00141 void operator delete(void *ptr,MemStreamer *mem) {}
00142 void operator delete[](void *ptr,MemStreamer *mem) {}
00143 #endif
00144
00145 FSMEdge *GetOutEdges() { return outedges; }
00146 FSMStateSetItem *GetOrigStateSet() { return origstateset; }
00147
00148 void SetFinal(char myisfinal=1) { isfinal=myisfinal; }
00149 char IsFinal() { return isfinal; }
00150 char IsOutComplete() { return isoutcomplete; }
00151 char IsAccepting() { return isaccepting; }
00152 char HasPoundsAhead() { return haspoundsahead; }
00153 int GetStateID() { return stateid; }
00154 FSMState *GetNextStateInList() { return next; }
00155
00156 FSMEdge *FindNegEdge(); // Find the one negative outgoing edge for this state
00157 // if there is one
00158
00159 FSMState *GetNextState(TLabelID labelid,char *overpoundedge=NULL);
00160 // Determines the next state (in an det. FSM!) that would be reached
00161 // by reading label 'labelid'. '*overpoundedge' is set to 1, if the
00162 // corresponding transition edge is a pound-edge.
00163 #ifdef FSM_PRINT
00164 void Print(); // Prints the state and the outgoing edges
00165 #endif
00166 #ifdef FSM_STORE
00167 void Store(MemStreamer *mem); // Stores the state and the outgoing edges
00168 // in memstreamer 'mem'
00169
00170 void Load(unsigned char * &ptr,FSMState *statearray,MemStreamer *fsmmem);
00171 // Initializes the state and loads the outgoing edges from the data in 'ptr'
00172 #endif
00173 };
00174
00175 //********************************************************************************
00176
00177 class FSMEdge
00178 // Represents an edge in the FSM
00179 {
00180 friend FSMState;
00181 friend FSM;
00182
00183 unsigned type; // Type of the edge (EDGETYPE_...)
00184 FSMState *nextstate; // The state that is reached by this edge
00185
00186 // Depending on the type, we store different info
00187 union{
00188 FSMLabel *labellist; // EDGETYPE_NEGLABELLIST ==> We store a list of labels
00189 TLabelID labelid; // EDGETYPE_LABEL ==> We store a single label
00190 };
00191
00192 public:
00193 FSMEdge *next; // The next outgoing edge of the same state
00194
00195 void *operator new(size_t size, MemStreamer *mem);
00196 void operator delete(void *ptr) {}
00197 #ifdef SPECIAL_DELETE
00198 void operator delete(void *ptr,MemStreamer *mem) {}
00199 #endif
00200
00201 FSMEdge() {}
00202
00203 FSMEdge(FSMState *tostate,TLabelID mylabel);
00204 FSMEdge(FSMState *tostate);
00205 FSMEdge(FSMState *tostate,FSMLabel *mylabels);
00206
00207 unsigned GetType() { return type; }
00208 FSMState *GetNextState() { return nextstate; }
00209 FSMLabel *GetLabelList() { return labellist; }
00210 FSMLabel **GetLabelListRef() { return &labellist; }
00211 TLabelID GetLabelID() { return labelid; }
00212
00213 char DoesMatchLabel(TLabelID labelid);
00214 // Checks whether the edge matches label 'labelid'
00215
00216 #ifdef FSM_PRINT
00217 void PrintLabelList(); // Prints the label list, if the type is EDGETYPE_NEGLABELLIST
00218 void Print(); // Prints the edge information
00219 #endif
00220 #ifdef FSM_STORE
00221 void Store(MemStreamer *mem); // Stores the edge in memstreamer 'mem'
00222 void Load(unsigned char * &ptr,FSMState *statearray,MemStreamer *fsmmem);
00223 // Loads the edge information from the data in 'ptr'
00224 #endif
00225 };
00226
00227 //**************************************************************************
00228 //**************************************************************************
00229
00230 struct StateEqualPair;
00231 struct StateEqualPairListItem;
00232
00233 class FSM
00234 // The representation of a (deterministic or non-deterministic) FSM
00235 {
00236 FSMState *statelist, // The list of FSM states
00237 **laststatelistref; // The reference to the last FSM state
00238 FSMState *startstate; // The start state
00239 unsigned long isdeterministic:1; // Is the automaton deterministic?
00240 unsigned curidx:30; // The number of states and at the same time
00241 // the index for the next state
00242
00243 void PruneRedundantStates(); // Eliminates states that are not reachable from the
00244 // start state and states that never lead to final states
00245
00246 //**********
00247 #ifdef FSM_NEGATE
00248 // Functions for negating a given FSM
00249 void CompleteDetState(FSMState *state,FSMState *deadstate);
00250 // Completes the deterministic state by adding edges for the missing
00251 // labels. The edges lead to 'deadstate'
00252
00253 void CompleteDetFSM();
00254 // Completes all deterministic states in the FSM
00255 #endif
00256
00257 public:
00258
00259 inline void *operator new(size_t size, MemStreamer *mem)
00260 {
00261 return mem->GetByteBlock(size);
00262 }
00263
00264 inline void operator delete(void *ptr) {}
00265 #ifdef SPECIAL_DELETE
00266 inline void operator delete(void *ptr,MemStreamer *mem) {}
00267 #endif
00268
00269 FSM()
00270 {
00271 isdeterministic=0;
00272 curidx=0;
00273 statelist=NULL;
00274 laststatelistref=&statelist;
00275 }
00276
00277 unsigned GetStateCount() { return curidx; }
00278
00279 FSMState *CreateState(char isfinal=0); // Creates a state
00280 FSMState *CreateState(FSMStateSetItem *list); // Creates a deterministic state
00281 // with a set of corresponding nondet. states
00282
00283 FSMEdge *CreateLabelEdge(FSMState *fromstate,FSMState *tostate,TLabelID labelid);
00284 // Creates an EDGETYPE_LABEL edge
00285 FSMEdge *CreateNegEdge(FSMState *fromstate,FSMState *tostate,FSMLabel *labellist=NULL);
00286 // Creates an EDGETYPE_NEGLABELLIST edge
00287 FSMEdge *CreateEmptyEdge(FSMState *fromstate,FSMState *tostate);
00288 // Creates an EDGETYPE_EMPTY edge
00289
00290 void SetStartState(FSMState *mystartstate) { startstate=mystartstate; }
00291 FSMState *GetStartState() { return startstate; }
00292 FSMState *GetStateList() { return statelist; }
00293
00294 FSM *MakeDeterministic(); // The main function for making an FSM deterministic
00295 FSM *Minimize(); // The main function to minimize a deterministic FSM
00296
00297 void AddFSM(FSMState *fromstate,FSMState *tostate,FSM *fsm);
00298 // Adds the FSM 'fsm' into the current FSM between 'fromstate' and 'tostate'
00299
00300 void EliminateRedundantPoundEdges();
00301 // Eliminates states that will never lead to final states
00302 // and states that are not reachable from the start state
00303
00304 void ComputeOutCompleteness();
00305 // Computes for the state whether it is out-complete,
00306 // i.e. whether there exists an edge for each possible label
00307
00308 void FindAcceptingStates();
00309 // Determines all (final) states that will definitely lead to an acceptance of
00310 // the word, no matter what comes afterwards
00311 // In other words: all following states are final states
00312
00313 void ComputeStatesHasPoundsAhead();
00314 // Determines all states that have 'pound'-edges ahead
00315
00316 #ifdef FSM_NEGATE
00317 FSM *CreateNegateFSM(); // Computes the negated FSM
00318 #endif
00319
00320 FSM *CreateReverseFSM(); // Computes the reverse FSM
00321
00322 #ifdef FSM_PRINT
00323 void Print();
00324 #endif
00325 #ifdef FSM_STORE
00326 void Store(MemStreamer *mem);
00327 void Load(unsigned char * &ptr,MemStreamer *fsmmem);
00328 #endif
00329 //************
00330 /*
00331 FSMState *CreateIntersectState(FSMState *origstate1,FSMState *origstate2);
00332 void IntersectFSMS(FSM *fsm1,FSM *fsm2);
00333 */
00334 };
00335
00336 extern TLabelID elementpoundlabelid;
00337 extern TLabelID attribpoundlabelid;
00338
00339 #endif
1.2.11.1 written by Dimitri van Heesch,
© 1997-2001