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