SemElem.hpp

Go to the documentation of this file.
00001 #ifndef wali_SEM_ELEM_GUARD
00002 #define wali_SEM_ELEM_GUARD 1
00003 
00004 /**
00005  * @author Nicholas Kidd
00006  */
00007 
00008 #include "wali/Common.hpp"
00009 #include "wali/ref_ptr.hpp"
00010 #include "wali/Countable.hpp"
00011 #include "wali/Printable.hpp"
00012 #include <string>
00013 
00014 namespace wali
00015 {
00016   /* forward declaration. class sem_elem_t
00017    * is defined first so that all of its methods
00018    * may be inlined by the compiler (typesafe macros)
00019    */
00020   class SemElem;
00021 
00022   /**
00023    * @typedef sem_elem_t
00024    * Handy typedef for working with reference counted
00025    * SemElem objects.
00026    */
00027   typedef ref_ptr<SemElem> sem_elem_t;
00028 
00029   /** 
00030    * @class SemElem
00031    * @brief base abstract class to be subclassed by user's semiring
00032    *
00033    * This abstract class provides the signature (or in Java interface) for a
00034    * Semiring Element (or Weight).  All pure abstract methods must be
00035    * defined by the user. 
00036    *
00037    * The constructor takes a boolean that turns reference counting on or
00038    * off. By default it is on. Please leave this as true less you know
00039    * you do not want the user weight objects to be garbage collected.
00040    * @see ref_ptr
00041    *
00042    * Some minimal testing is provided by
00043    *
00044    *   o   wali::test_semelem_impl(wali::sem_elem_t x)
00045    *
00046    * It performs tests such as the following:
00047    *   o   0 = 0
00048    *   o   1 = 1
00049    *   o   x = x
00050    *   o   x + 0 = x = 0 + x
00051    *   o   x * 0 = 0 = 0 * x
00052    *   o   x * 1 = x = 1 * x
00053    */
00054 
00055   class SemElem : public Printable, public Countable
00056   {
00057 
00058     public:
00059       static const std::string XMLTag;
00060 
00061     public:
00062 
00063       /**
00064        *  @brief SemElem constructor
00065        */ 
00066       //explicit SemElem( bool countme = true );
00067       explicit SemElem();
00068 
00069       /**
00070        *  @brief SemElem destructor is virtual and does nothing
00071        */
00072       virtual ~SemElem() {}
00073 
00074       /**
00075        *  return the One element of the semiring
00076        */
00077       virtual sem_elem_t one() const = 0;
00078 
00079       /**
00080        *  return the Zero element of the semiring
00081        */
00082       virtual sem_elem_t zero() const = 0;
00083 
00084       /**
00085        *  Perform the extend operation
00086        */
00087       virtual sem_elem_t extend( SemElem * se ) = 0;
00088 
00089       /**
00090        *  Perform the combine operation
00091        */
00092       virtual sem_elem_t combine( SemElem * se ) = 0;
00093 
00094       /**
00095        *  Equality comparison between two semiring elements
00096        */
00097       virtual bool equal( SemElem * se ) const = 0;
00098 
00099       /**
00100        *  Print the semiring element to the std::ostream o
00101        */
00102       virtual std::ostream& print( std::ostream & o ) const = 0;
00103 
00104       /**
00105        *  Used to print weights to XML. Default implementation
00106        *  simply calls this->toString() and sends the output
00107        *  to the passed in ostream o.
00108        */
00109       virtual std::ostream& marshall( std::ostream& o ) const;
00110 
00111       /**
00112        *  Used to print weights to XML. Outer wrapper that 
00113        *  places the appropriate tags and then calls the virtual
00114        *  method marshall.
00115        */
00116       std::ostream& marshallWeight( std::ostream& o ) const;
00117 
00118       /**
00119        *  Perfrom the diff operation
00120        *   NOTE: This method performs (this - se).  This is very
00121        *         important as diff is not commutative
00122        */
00123       virtual sem_elem_t diff( SemElem * se );
00124 
00125       /**
00126        *  Perform the quasi_one operation.
00127        *  Quasi one by default returns the One semiring element.
00128        *  If you are unsure of how to use Quasione then leave the
00129        *  default implementation.
00130        */
00131       virtual sem_elem_t quasi_one() const;
00132 
00133       /**
00134        *  Perform delta operation
00135        *   The delta operation is defined for the user but can be
00136        *   overridden to get better performance. The std::pair returned
00137        *   must have two properties
00138        *       1) the first element == this COMBINE se
00139        *       2) the second element == this DIFF se
00140        * 
00141        *  @param se is the weight to be combined/diffed with "this"
00142        *  
00143        *  @return std::pair<sem_elem_t,sem_elem_t> the delta
00144        */
00145       virtual std::pair<sem_elem_t,sem_elem_t> delta( SemElem * se );
00146 
00147       /**
00148        *  Perform the star operation (returns this^\inf)
00149        */
00150       sem_elem_t star();
00151 
00152       /** 
00153        * Wrapper method for extend that will remove the ref_ptr
00154        * to make the call to the user's code. 
00155        */
00156       sem_elem_t extend( sem_elem_t se ) 
00157       { 
00158         return extend( se.get_ptr() ); 
00159       }
00160 
00161       /** 
00162        * Wrapper method for combine that will remove the ref_ptr
00163        * to make the call to the user's code. 
00164        */
00165       sem_elem_t combine( sem_elem_t se ) 
00166       { 
00167         return combine( se.get_ptr() ); 
00168       }
00169 
00170       /** 
00171        * Wrapper method for equal that will remove the ref_ptr
00172        * to make the call to the user's code. 
00173        */
00174       bool equal( sem_elem_t se ) const 
00175       { 
00176         return equal( se.get_ptr() ); 
00177       }
00178 
00179       /**
00180        * Wrapper method for diff that will remove the ref_ptr
00181        * to make the call to the user's code. 
00182        */
00183       sem_elem_t diff( sem_elem_t se ) 
00184       { 
00185         return diff( se.get_ptr() ); 
00186       }
00187 
00188       /** 
00189        * Wrapper method for delta that will remove the ref_ptr
00190        * to make the call to the user's code. This is just a 
00191        * nice "typesafe macro" b/c sem_elem_t is used by WPDS
00192        */
00193       std::pair< sem_elem_t,sem_elem_t > delta( sem_elem_t se )
00194       {
00195         return delta( se.get_ptr() );
00196       }
00197 
00198   };
00199 
00200   /**
00201    * Simple test method that can be used when developing
00202    * a SemElem implementation. Tests include
00203    *
00204    *  o 0 = 0
00205    *  o 1 = 1
00206    *  o x = x
00207    *  o x + 0 = x = 0 + x
00208    *  o x * 0 = 0 = 0 * x
00209    *  o x * 1 = x = 1 * x
00210    */
00211   void test_semelem_impl(sem_elem_t x);
00212 
00213 }
00214 #endif  // wali_SEM_ELEM_GUARD
00215