Main Page   Class Hierarchy   Compound List   File List   Compound Members   File Members  

FSM.hpp

Go to the documentation of this file.
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

Generated on Sat Oct 13 16:08:37 2001 for XMILL by doxygen1.2.11.1 written by Dimitri van Heesch, © 1997-2001