00001 #ifndef NARY_H 00002 #define NARY_H 00003 00004 #include "bit_vector/bit_vector.h" 00005 #include "common/suif_vector.h" 00006 00007 00008 template <class Rel> 00009 class NaryL { 00010 suif_vector<Rel> *_values; 00011 Rel _default_value; 00012 public: 00013 NaryL(); /* default is top */ 00014 NaryL(const NaryL &other); 00015 NaryL(const Rel &default_value); 00016 NaryL operator~() const; 00017 static NaryL do_negate(const NaryL &val); 00018 NaryL &operator =(const NaryL &other); 00019 bool operator ==(const NaryL &other) const; 00020 bool operator !=(const NaryL &other) const; 00021 00022 Rel& operator[](size_t i); /* expand */ 00023 Rel operator[](size_t i) const; 00024 00025 Rel get_value(size_t i) const; 00026 void set_value(size_t i, const Rel &val); 00027 00028 bool is_empty() const; 00029 size_t size() const; /* for this dimension */ 00030 void set_default_value(const Rel &default_value); 00031 Rel get_default_value() const; 00032 size_t significant_bit_count() const; 00033 bool do_meet_with_test(const NaryL &other); 00034 static NaryL do_meet(const NaryL &val1, const NaryL &val2); 00035 protected: 00036 void expand_to(size_t); 00037 }; 00038 00039 #include <common/suif_vector.h> 00040 00041 template <class Rel> 00042 NaryL<Rel>::NaryL() : 00043 _values(new suif_vector<Rel>), 00044 _default_value() 00045 {} 00046 00047 00048 /* default is top */ 00049 template <class Rel> 00050 NaryL<Rel>::NaryL(const NaryL &other) : 00051 _values(new suif_vector<Rel>), 00052 _default_value(other._default_value) 00053 { 00054 for (suif_vector<Rel>::iterator iter = other._values->begin(); 00055 iter != other._values->end(); iter++) { 00056 _values->push_back(*iter); 00057 } 00058 } 00059 00060 template <class Rel> 00061 NaryL<Rel>::NaryL(const Rel &default_value) : 00062 _values(new suif_vector<Rel>), 00063 _default_value(default_value) 00064 { 00065 } 00066 00067 template <class Rel> 00068 NaryL<Rel> NaryL<Rel>::do_negate(const NaryL &val) { 00069 assert(val.is_empty()); 00070 return(NaryL<Rel>(do_negate(val._default_value))); 00071 } 00072 00073 template <class Rel> 00074 NaryL<Rel> &NaryL<Rel>::operator =(const NaryL &other) { 00075 _values->clear(); 00076 for (suif_vector<Rel>::iterator iter = other._values->begin(); 00077 iter != other._values->end(); iter++) { 00078 _values->push_back(*iter); 00079 } 00080 00081 _default_value = other._default_value; 00082 return(*this); 00083 } 00084 00085 template <class Rel> 00086 bool NaryL<Rel>::operator !=(const NaryL &other) const { 00087 return(!(*this == other)); 00088 } 00089 00090 template <class Rel> 00091 bool NaryL<Rel>::operator ==(const NaryL &other) const { 00092 if (_default_value != other._default_value) return false; 00093 if (size() != other.size()) return false; 00094 size_t m = size(); 00095 for (size_t i = 0; i < m ; i++) { 00096 if ((*_values)[i] != (*other._values)[i]) 00097 return(false); 00098 } 00099 return(true); 00100 } 00101 00102 template <class Rel> 00103 bool NaryL<Rel>::is_empty() const { 00104 return(size() == 0); 00105 } 00106 00107 template <class Rel> 00108 size_t NaryL<Rel>::size() const { 00109 return(_values->size()); 00110 } 00111 00112 template <class Rel> 00113 void NaryL<Rel>::expand_to(size_t i) { 00114 while(i >= size()) 00115 _values->push_back(_default_value); 00116 } 00117 00118 template <class Rel> 00119 Rel& NaryL<Rel>::operator[](size_t i) { 00120 expand_to(i); 00121 return((*_values)[i]); 00122 } 00123 00124 template <class Rel> 00125 Rel NaryL<Rel>::operator[](size_t i) const { 00126 if ( i < size()) 00127 return((*_values)[i]); 00128 return(_default_value); 00129 } 00130 00131 00132 00133 template <class Rel> 00134 Rel NaryL<Rel>::get_value(size_t i) const { 00135 if (i >= size()) 00136 return(_default_value); 00137 return((*_values)[i]); 00138 } 00139 00140 template <class Rel> 00141 void NaryL<Rel>::set_value(size_t i, const Rel &val) { 00142 if (i >= size() && val == _default_value ) return; 00143 expand_to(i); 00144 (*_values)[i] = val; 00145 } 00146 00147 00148 template <class Rel> 00149 void NaryL<Rel>::set_default_value(const Rel &default_value) { 00150 assert(is_empty()); 00151 _default_value = default_value; 00152 } 00153 00154 template <class Rel> 00155 Rel NaryL<Rel>::get_default_value() const { 00156 return(_default_value); 00157 } 00158 00159 /* clearly, this could be cached as long as all modification 00160 * is done through this 00161 */ 00162 template <class Rel> 00163 size_t NaryL<Rel>::significant_bit_count() const { 00164 size_t m = size(); 00165 for (suif_vector<Rel>::iterator it = _values->begin(); 00166 it != _values->end(); it++) { 00167 size_t n = (*it).significant_bit_count(); 00168 if (n > m) m = n; 00169 } 00170 return(m); 00171 } 00172 00173 template <class Rel> 00174 bool NaryL<Rel>::do_meet_with_test(const NaryL &other) { 00175 NaryL val = do_meet(*this, other); 00176 if (val == *this) return false; 00177 *this = val; 00178 return(true); 00179 } 00180 00181 template <class Rel> 00182 NaryL<Rel> NaryL<Rel>::do_meet(const NaryL &val1, const NaryL &val2) { 00183 Rel new_default = val1._default_value.do_meet(val1._default_value, 00184 val2._default_value); 00185 NaryL new_nary(new_default); 00186 size_t m = val1.size(); 00187 size_t n = val2.size(); 00188 if (n > m) m = n; 00189 for (size_t i = 0; i < m; i++) 00190 { 00191 Rel rel_val1 = val1[i]; 00192 Rel rel_val2 = val2[i]; 00193 new_nary.set_value(i, rel_val1.do_meet(rel_val1, rel_val2)); 00194 } 00195 return(new_nary); 00196 } 00197 00198 00199 00200 #endif /* NARY_H */