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