SymbolStorage.hpp

Go to the documentation of this file.
00001 #ifndef wali_nwa_SymbolStorage_GUARD
00002 #define wali_nwa_SymbolStorage_GUARD 1
00003 
00004 /**
00005  * @author Amanda Burton
00006  */
00007 
00008 #include "opennwa/deprecate.h"
00009 #include "opennwa/NwaFwd.hpp"
00010 
00011 // ::wali
00012 #include "wali/Printable.hpp"
00013 #include "wali/Common.hpp"
00014 #include "wali/Key.hpp"
00015 
00016 // ::std
00017 #include <assert.h>
00018 
00019 namespace opennwa
00020 {
00021     namespace details
00022     {
00023       
00024     class SymbolStorage : public wali::Printable
00025     { 
00026       public:
00027         typedef Symbol Sym;
00028         typedef std::set<Sym>::const_iterator const_iterator;
00029 
00030         static std::string const & XMLSymbolTag() {
00031           static std::string ret = "Symbol";
00032           return ret;
00033         }
00034 
00035         static std::string const & XMLNameAttr() {
00036           static std::string ret = "name";
00037           return ret;
00038         }
00039 
00040       //
00041       // Methods
00042       //
00043 
00044       public:
00045       //Constructors and Destructor
00046       SymbolStorage( );
00047       SymbolStorage( const SymbolStorage & other );
00048       SymbolStorage & operator=( const SymbolStorage & other );
00049   
00050       //Accessors
00051 
00052       /**
00053        *
00054        * @brief provides access to all symbols 
00055        *
00056        * This method provides access to all symbols in the form of a set of symbols.
00057        *
00058        * @return a set containing all symbols 
00059        * 
00060        */
00061       const std::set<Sym> & getSymbols( ) const;
00062 
00063       /**
00064        *
00065        * @brief tests whether the given symbol is a valid symbol
00066        *
00067        * This method determines whether the given symbol is a valid symbol in the 
00068        * symbol pool.  If it is, true is returned, otherwise, false is returned.
00069        *
00070        * @param - sym: the symbol to test
00071        * @return true if the given symbol is a valid symbol
00072        *
00073        */
00074       bool isSymbol( Sym sym ) const;
00075             
00076       /**
00077        *
00078        * @brief add the given symbol 
00079        *
00080        * This method adds the given symbol.  If the symbol already exists,
00081        * false is returned.  Otherwise, true is returned.
00082        *
00083        * @param - sym: the symbol to add
00084        * @return false if the symbol already exists, true otherwise
00085        *
00086        */
00087       bool addSymbol( Sym sym );
00088 
00089       /**
00090        *
00091        * @brief add all the symbols in the given collection to this collection 
00092        *
00093        * This method adds all of the symbols in the given collection of symbols to this
00094        * collection of symbols.
00095        *
00096        * @param - symSet: the collection of symbols to add to this collection of symbols
00097        *
00098        */
00099       void addAllSymbols( SymbolStorage symSet );
00100 
00101       /** 
00102        *
00103        * @brief remove the given symbol
00104        *
00105        * This method removes the given symbol.  If the symbol does not exist, false is 
00106        * returned.  Otherwise, true is returned.
00107        *
00108        * @param - sym: the symbol to remove
00109        * @return false if the symbol does not exist, true otherwise
00110        *
00111        */
00112       bool removeSymbol( Sym sym );
00113 
00114       /**
00115        *
00116        * @brief remove all the symbols in the given collection from this collection
00117        *
00118        * This method removes all of the symbols in the given collection of symbols
00119        * from this collection of symbols.
00120        *
00121        * @param - symSet: the collection of symbols to remove from this collection 
00122        *
00123        */
00124       void removeAll( SymbolStorage symSet );
00125 
00126       /**
00127        *
00128        * @brief removes all symbols 
00129        *
00130        * This method removes all symbols from this collection.  
00131        *
00132        */
00133       void clearSymbols( );
00134 
00135       //Utilities
00136       
00137       /** 
00138        *
00139        * @brief print the collection of symbols
00140        *
00141        * This method prints out the symbol set to the output stream provided.
00142        *
00143        * @param - o: the output stream to print to
00144        * @return the output stream that was printed to 
00145        *
00146        */
00147       std::ostream & print( std::ostream & o ) const;
00148       
00149       /** 
00150        *
00151        * @brief tests whether this collection of symbols is equivalent to the collection
00152        *        of symbols 'other'
00153        *
00154        * This method tests the equivalence of this set of symbols and the set of symbols
00155        * 'other'.
00156        *
00157        * @param - other: the SymbolStorage to which to compare this SymbolStorage 
00158        * @return true if this SymbolStorage is equivalent to the SymbolStorage 'other'
00159        *
00160        */
00161       bool operator==( const SymbolStorage & other ) const;
00162 
00163        /**
00164        * 
00165        * @brief provides access to the symbols in the collection 
00166        *
00167        * This method provides access to the symbols in this collection through an iterator.
00168        *
00169        * @return the starting point of an iterator through the symbols
00170        *
00171        */
00172       const_iterator beginSymbols( ) const;
00173 
00174       /**
00175        * 
00176        * @brief provides access to the symbols in the collection 
00177        *
00178        * This method provides access to the symbols in the collection through an iterator.
00179        *
00180        * @return one place past the exit point of an iterator through the symbols
00181        *
00182        */
00183       const_iterator endSymbols( ) const;
00184 
00185       /**
00186        *
00187        * @brief returns the number of symbols in this collection
00188        *
00189        * This method returns the number of symbols in this collection.
00190        *
00191        * @return the number of symbols in this collection
00192        *
00193        */
00194       size_t sizeSymbols( ) const;
00195 
00196       private:
00197         std::set<Sym> symbols;
00198     };
00199 
00200     //Accessors
00201 
00202     /**
00203      *
00204      * @brief provides access to all symbols 
00205      *
00206      * @return a set containing all symbols 
00207      * 
00208      */
00209     inline
00210     const std::set<SymbolStorage::Sym> & SymbolStorage::getSymbols( ) const
00211     {
00212       return symbols;  
00213     }
00214 
00215     /**
00216      *
00217      * @brief tests whether the given symbol is a valid symbol
00218      *
00219      * @param - sym: the symbol to test
00220      * @return true if the given symbol is a valid symbol
00221      *
00222      */
00223     inline
00224     bool SymbolStorage::isSymbol( Sym sym ) const
00225     {
00226       return (symbols.count(sym) > 0);
00227     }
00228     
00229     /**
00230      *
00231      * @brief removes all symbols 
00232      *
00233      * This method removes all symbols from this collection.  
00234      *
00235      */
00236     inline
00237     void SymbolStorage::clearSymbols( )
00238     {
00239       symbols.clear();
00240 
00241       // Epsilon is always a symbol of the NWA.
00242       addSymbol( EPSILON );
00243     }
00244 
00245     //Utilities
00246     
00247     /**
00248      * 
00249      * @brief provides access to the symbols in the collection 
00250      *
00251      * @return the starting point of an iterator through the symbols
00252      *
00253      */
00254     inline
00255     SymbolStorage::const_iterator SymbolStorage::beginSymbols( ) const
00256     {
00257       return symbols.begin();
00258     } 
00259 
00260     /**
00261      * 
00262      * @brief provides access to the symbols in the collection 
00263      *
00264      * @return one place past the exit point of an iterator through the symbols
00265      *
00266      */
00267     inline
00268     SymbolStorage::const_iterator SymbolStorage::endSymbols( ) const
00269     {
00270       return symbols.end();
00271     }    
00272 
00273     /**
00274      *
00275      * @brief returns the number of symbols in this collection
00276      *
00277      * @return the number of symbols in this collection
00278      *
00279      */
00280     inline
00281     size_t SymbolStorage::sizeSymbols( ) const
00282     {
00283       return symbols.size();
00284     }
00285 
00286     /**
00287      *
00288      *  This class is used to label the transitions of an NWA.
00289      *
00290      */
00291     class Label
00292     {
00293       public:
00294         typedef Symbol Sym;
00295         typedef std::set<Sym>::const_iterator const_iterator;
00296        
00297       //
00298       // Methods
00299       //
00300 
00301       public:
00302       //Constructors and Destructor
00303       //Note: The default starting state for a label is to represent the 
00304       //absence of symbols.  If the representation of wild is desired, then makeWild() 
00305       //must be called.  At any point the collecion can be returned to this default
00306       //state by calling makeAbsent().
00307       Label( );
00308       Label( const Label & other );
00309       Label & operator=( const Label & other );
00310   
00311       /**
00312        *
00313        * @brief tests whether this collection represents the wild symbol
00314        *
00315        * This method determines whether this collection represents the wild symbol.
00316        * It returns true if the collection represents the wild symbol. 
00317        *
00318        * @return true if this collection represents the wild symbol
00319        *
00320        */
00321       bool isWild( const SymbolStorage & symbolPool ) const;
00322 
00323       /**
00324        *
00325        * @brief make this collection represent wild
00326        *
00327        * This method erases any symbols currently in this collection and converts the 
00328        * collection to represent the wild symbol.
00329        *
00330        */
00331       void makeWild( );
00332 
00333       /**
00334        *
00335        * @brief tests whether this collection represents the absence of all symbols
00336        *
00337        * This method determines whether this collection represents the absence of all
00338        * symbols.  It returns true if the collection represents the absence of all 
00339        * symbols. 
00340        *
00341        * @return true if this collection represents the absence of all symbols
00342        *
00343        */
00344       bool isAbsent( const SymbolStorage & symbolPool ) const;
00345 
00346       /**
00347        *
00348        * @brief make this collection represent the absence of all symbols
00349        *
00350        * This method erases any symbols currently in this collection and converts the
00351        * collection to represent the absence of all symbols.
00352        *
00353        */
00354       void makeAbsent( );
00355 
00356       /**
00357        *
00358        * @brief tests whether the given symbol is a member of this collection
00359        *
00360        * This method determines whether the given symbol is a member of this collection.
00361        * It returns true if the symbol is a member and false otherwise.
00362        *
00363        * @param - sym: the symbol to test
00364        * @return true if the symbol is a member of this collection of symbols
00365        *
00366        */
00367       bool containsSymbol( Sym sym ) const;
00368 
00369       /**
00370        *
00371        * @brief provides access to some symbol in this collection
00372        *
00373        * This method provides access to some symbol in this collection.
00374        *
00375        * @return some symbol in this collection of symbols
00376        *
00377        */
00378       Sym getAnySymbol( const SymbolStorage & symbolPool ) const;
00379             
00380       /**
00381        *
00382        * @brief add the given symbol 
00383        *
00384        * This method adds the given symbol.  If the symbol already exists,
00385        * false is returned.  Otherwise, true is returned.
00386        *
00387        * @param - sym: the symbol to add
00388        * @return false if the symbol already exists, true otherwise
00389        *
00390        */
00391       bool addSymbol( Sym sym );
00392 
00393       /**
00394        *
00395        * @brief add all the symbols in the given collection to this collection 
00396        *
00397        * This method adds all of the symbols in the given collection of symbols to this
00398        * collection of symbols.
00399        *
00400        * @param - symSet: the collection of symbols to add to this collection of symbols
00401        *
00402        */
00403       void addAll( Label lbl, const SymbolStorage & symbolPool );
00404 
00405       /** 
00406        *
00407        * @brief remove the given symbol
00408        *
00409        * This method removes the given symbol.  If the symbol does not exist, false is 
00410        * returned.  Otherwise, true is returned.
00411        *
00412        * @param - sym: the symbol to remove
00413        * @return false if the symbol does not exist, true otherwise
00414        *
00415        */
00416       bool removeSymbol( Sym sym );
00417 
00418       /**
00419        *
00420        * @brief remove all the symbols in the given collection from this collection
00421        *
00422        * This method removes all of the symbols in the given collection of symbols
00423        * from this collection of symbols.
00424        *
00425        * @param - symSet: the collection of symbols to remove from this collection 
00426        *
00427        */
00428       void removeAll( Label lbl, const SymbolStorage & symbolPool );
00429 
00430       //Utilities
00431       
00432       /** 
00433        *
00434        * @brief print the collection of symbols
00435        *
00436        * This method prints out the symbol set to the output stream provided.
00437        *
00438        * @param - o: the output stream to print to
00439        * @return the output stream that was printed to 
00440        *
00441        */
00442       std::ostream & print( std::ostream & o, const SymbolStorage & symbolPool ) const;
00443       
00444       /** 
00445        *
00446        * @brief tests whether this collection of symbols is equivalent to the collection
00447        *        of symbols 'other'
00448        *
00449        * This method tests the equivalence of this set of symbols and the set of symbols
00450        * 'other'.
00451        *
00452        * @param - other: the SymbolStorage to which to compare this SymbolStorage 
00453        * @return true if this SymbolStorage is equivalent to the SymbolStorage 'other'
00454        *
00455        */
00456       bool operator==( const Label & other ) const;
00457 
00458       /**
00459        *
00460        * @brief provides access to all symbols in the collection
00461        *
00462        * This method provides access to all symbols in the collection in the form of a 
00463        * set of symbols.
00464        *
00465        * @return a set containing all symbols in this collection
00466        * 
00467        */
00468       const std::set<Sym> getSymbolsIn( const SymbolStorage & symbolPool ) const;
00469 
00470       /**
00471        *
00472        * @brief provides access to all symbols not in the collection
00473        *
00474        * This method provides access to all symbols not in the collection in the form  
00475        * of a set of symbols.
00476        *
00477        * @return a set containing all symbols not in this collection
00478        * 
00479        */
00480       const std::set<Sym> getSymbolsNotIn( const SymbolStorage & symbolPool ) const;
00481 
00482       /**
00483        *
00484        * @brief returns the number of symbols in this collection
00485        *
00486        * This method returns the number of symbols in this collection.
00487        *
00488        * @return the number of symbols in this collection
00489        *
00490        */
00491       size_t sizeSymbolsIn( const SymbolStorage & symbolPool ) const;
00492 
00493       /**
00494        *
00495        * @brief returns the number of symbols not in this collection
00496        *
00497        * This method returns the number of symbols not in this collection.
00498        *
00499        * @return the number of symbols not in this collection
00500        *
00501        */
00502       size_t sizeSymbolsNotIn( const SymbolStorage & symbolPool ) const;
00503 
00504       //
00505       // Variables
00506       //
00507       
00508       protected:
00509       
00510       std::set<Sym> syms;
00511       bool neg;
00512 
00513     };
00514 
00515 
00516     /**
00517      *
00518      * @brief tests whether the given symbol is a member of this collection
00519      *
00520      * @param - sym: the symbol to test
00521      * @return true if the symbol is a member of this collection of states
00522      *
00523      */
00524     inline
00525     bool Label::containsSymbol( Sym sym ) const
00526     {
00527       size_t count = syms.count(sym);
00528       if (neg) {
00529         //syms records symbols not on the edge, so
00530         //if the symbol is not in syms, it is in the collection
00531         return count == 0;
00532       }
00533       else {
00534         //syms records symbols on the edge, so
00535         //if the symbol is in syms, it is in the collection
00536         return count > 0;
00537       }
00538     }
00539 
00540 
00541     /**
00542      *
00543      * @brief add the given symbol 
00544      *
00545      * @param - sym: the symbol to add
00546      * @return false if the symbol already exists, true otherwise
00547      *
00548      */
00549     inline
00550     bool Label::addSymbol( Sym sym )
00551     {
00552       if( containsSymbol(sym) )
00553         return false;
00554 
00555       if( neg )
00556       {
00557         //syms records symbols not on the edge, so remove sym from syms
00558         syms.erase(sym);
00559       }
00560       else
00561       {
00562         //syms records symbols on the edge, so add sym to syms
00563         syms.insert(sym);
00564       }
00565       return true;
00566     }
00567 
00568 
00569 
00570     /**
00571      *
00572      * @brief returns the number of symbols in this collection
00573      *
00574      * @return the number of symbols in this collection
00575      *
00576      */
00577     inline
00578     size_t Label::sizeSymbolsIn( const SymbolStorage & symbolPool ) const
00579     {
00580       if( neg )
00581         return (symbolPool.sizeSymbols() - syms.size());
00582       else
00583         return syms.size();
00584     }
00585 
00586     /**
00587      *
00588      * @brief returns the number of symbols not in this collection
00589      *
00590      * @return the number of symbols not in this collection
00591      *
00592      */
00593     inline
00594     size_t Label::sizeSymbolsNotIn( const SymbolStorage & symbolPool ) const
00595     {
00596       if( neg )
00597         return syms.size();
00598       else
00599         return (symbolPool.sizeSymbols() - syms.size());
00600     }
00601 
00602 
00603   }
00604 }
00605 #endif