00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include <ppl-config.h>
00025
00026 #include "Bit_Row.defs.hh"
00027 #include "assert.hh"
00028 #include <climits>
00029
00030 namespace PPL = Parma_Polyhedra_Library;
00031
00032 unsigned long
00033 PPL::Bit_Row::first() const {
00034 const mp_size_t vec_size = vec->_mp_size;
00035 PPL_ASSERT(vec_size >= 0);
00036 mp_size_t li = 0;
00037 mp_srcptr p = vec->_mp_d;
00038 for (; li < vec_size; ++li, ++p) {
00039 const mp_limb_t limb = *p;
00040 if (limb != 0)
00041 return li*PPL_BITS_PER_GMP_LIMB + Implementation::first_one(limb);
00042 }
00043 return ULONG_MAX;
00044 }
00045
00046 unsigned long
00047 PPL::Bit_Row::next(unsigned long position) const {
00048 ++position;
00049
00050
00051
00052
00053
00054
00055
00056
00057 mp_size_t li = position / PPL_BITS_PER_GMP_LIMB;
00058 const mp_size_t vec_size = vec->_mp_size;
00059 PPL_ASSERT(vec_size >= 0);
00060 if (li >= vec_size)
00061 return ULONG_MAX;
00062
00063
00064 mp_srcptr p = vec->_mp_d + li;
00065
00066
00067 mp_limb_t limb = *p & (~(mp_limb_t) 0) << (position % PPL_BITS_PER_GMP_LIMB);
00068
00069 while (true) {
00070 if (limb != 0)
00071 return li*PPL_BITS_PER_GMP_LIMB + Implementation::first_one(limb);
00072 ++li;
00073 if (li == vec_size)
00074 break;
00075 ++p;
00076 limb = *p;
00077 }
00078 return ULONG_MAX;
00079 }
00080
00081 unsigned long
00082 PPL::Bit_Row::last() const {
00083 mp_size_t li = vec->_mp_size;
00084 PPL_ASSERT(li >= 0);
00085 if (li == 0)
00086 return ULONG_MAX;
00087 --li;
00088 const mp_srcptr p = vec->_mp_d + li;
00089 const mp_limb_t limb = *p;
00090 PPL_ASSERT(limb != 0);
00091 return li*PPL_BITS_PER_GMP_LIMB + Implementation::last_one(limb);
00092 }
00093
00094 unsigned long
00095 PPL::Bit_Row::prev(unsigned long position) const {
00096 if (position == 0)
00097 return ULONG_MAX;
00098
00099 --position;
00100
00101 const mp_size_t vec_size = vec->_mp_size;
00102 PPL_ASSERT(vec_size > 0);
00103 mp_size_t li = position / PPL_BITS_PER_GMP_LIMB;
00104
00105 mp_limb_t limb;
00106 mp_srcptr p = vec->_mp_d;
00107
00108
00109 if (li >= vec_size) {
00110 li = vec_size - 1;
00111 p += li;
00112 limb = *p;
00113 }
00114 else {
00115 const mp_limb_t mask
00116 = (~(mp_limb_t) 0)
00117 >> (PPL_BITS_PER_GMP_LIMB - 1 - position % PPL_BITS_PER_GMP_LIMB);
00118 p += li;
00119 limb = *p & mask;
00120 }
00121
00122 while (true) {
00123 if (limb != 0)
00124 return li*PPL_BITS_PER_GMP_LIMB + Implementation::last_one(limb);
00125 if (li == 0)
00126 break;
00127 --li;
00128 --p;
00129 limb = *p;
00130 }
00131 return ULONG_MAX;
00132 }
00133
00134 bool
00135 PPL::Bit_Row::operator[](const unsigned long k) const {
00136 const mp_size_t vec_size = vec->_mp_size;
00137 PPL_ASSERT(vec_size >= 0);
00138
00139 unsigned long i = k / GMP_NUMB_BITS;
00140 if (i >= static_cast<unsigned long>(vec_size))
00141 return false;
00142
00143 mp_limb_t limb = *(vec->_mp_d + i);
00144 return (limb >> (k % GMP_NUMB_BITS)) & 1;
00145 }
00146
00147 void
00148 PPL::Bit_Row::set_until(unsigned long k) {
00149
00150 while (k-- > 0)
00151 mpz_setbit(vec, k);
00152 }
00153
00155 int
00156 PPL::compare(const Bit_Row& x, const Bit_Row& y) {
00157 const mp_size_t x_size = x.vec->_mp_size;
00158 PPL_ASSERT(x_size >= 0);
00159 const mp_size_t y_size = y.vec->_mp_size;
00160 PPL_ASSERT(y_size >= 0);
00161 mp_size_t size = (x_size > y_size ? y_size : x_size);
00162 mp_srcptr xp = x.vec->_mp_d;
00163 mp_srcptr yp = y.vec->_mp_d;
00164 while (size > 0) {
00165 const mp_limb_t xl = *xp;
00166 const mp_limb_t yl = *yp;
00167 if (xl != yl) {
00168
00169 const mp_limb_t diff = xl ^ yl;
00170
00171 const mp_limb_t mask = diff & ~(diff-1);
00172 return (xl & mask) ? 1 : -1;
00173 }
00174 ++xp;
00175 ++yp;
00176 --size;
00177 }
00178 return x_size == y_size ? 0 : (x_size > y_size ? 1 : -1);
00179 }
00180
00182 bool
00183 PPL::subset_or_equal(const Bit_Row& x, const Bit_Row& y) {
00184 mp_size_t x_size = x.vec->_mp_size;
00185 PPL_ASSERT(x_size >= 0);
00186 mp_size_t y_size = y.vec->_mp_size;
00187 PPL_ASSERT(y_size >= 0);
00188 if (x_size > y_size)
00189 return false;
00190 mp_srcptr xp = x.vec->_mp_d;
00191 mp_srcptr yp = y.vec->_mp_d;
00192 while (x_size > 0) {
00193 if (*xp & ~*yp)
00194 return false;
00195 ++xp;
00196 ++yp;
00197 --x_size;
00198 }
00199 return true;
00200 }
00201
00203 bool
00204 PPL::subset_or_equal(const Bit_Row& x, const Bit_Row& y,
00205 bool& strict_subset) {
00206 mp_size_t x_size = x.vec->_mp_size;
00207 PPL_ASSERT(x_size >= 0);
00208 mp_size_t y_size = y.vec->_mp_size;
00209 PPL_ASSERT(y_size >= 0);
00210 if (x_size > y_size)
00211 return false;
00212 mp_srcptr xp = x.vec->_mp_d;
00213 mp_srcptr yp = y.vec->_mp_d;
00214 strict_subset = (x_size < y_size);
00215 mp_limb_t xl;
00216 mp_limb_t yl;
00217 if (strict_subset) {
00218 while (x_size > 0) {
00219 xl = *xp;
00220 yl = *yp;
00221 if (xl & ~yl)
00222 return false;
00223 strict_subset_next:
00224 ++xp;
00225 ++yp;
00226 --x_size;
00227 }
00228 }
00229 else {
00230 while (x_size > 0) {
00231 xl = *xp;
00232 yl = *yp;
00233 if (xl != yl) {
00234 if (xl & ~yl)
00235 return false;
00236 strict_subset = true;
00237 goto strict_subset_next;
00238 }
00239 ++xp;
00240 ++yp;
00241 --x_size;
00242 }
00243 }
00244 return true;
00245 }
00246
00248 bool
00249 PPL::strict_subset(const Bit_Row& x, const Bit_Row& y) {
00250 mp_size_t x_size = x.vec->_mp_size;
00251 PPL_ASSERT(x_size >= 0);
00252 mp_size_t y_size = y.vec->_mp_size;
00253 PPL_ASSERT(y_size >= 0);
00254 if (x_size > y_size)
00255 return false;
00256 bool different = (x_size < y_size);
00257 mp_srcptr xp = x.vec->_mp_d;
00258 mp_srcptr yp = y.vec->_mp_d;
00259 while (x_size > 0) {
00260 const mp_limb_t xl = *xp;
00261 const mp_limb_t yl = *yp;
00262 if (xl & ~yl)
00263 return false;
00264 if (!different && xl != yl)
00265 different = true;
00266 ++xp;
00267 ++yp;
00268 --x_size;
00269 }
00270 return different;
00271 }
00272
00274 bool
00275 PPL::operator==(const Bit_Row& x, const Bit_Row& y) {
00276 const mp_size_t x_vec_size = x.vec->_mp_size;
00277 PPL_ASSERT(x_vec_size >= 0);
00278 const mp_size_t y_vec_size = y.vec->_mp_size;
00279 PPL_ASSERT(y_vec_size >= 0);
00280
00281 if (x_vec_size != y_vec_size)
00282 return false;
00283
00284 return mpn_cmp(x.vec->_mp_d, y.vec->_mp_d, x_vec_size) == 0;
00285 }
00286
00288 bool
00289 PPL::operator!=(const Bit_Row& x, const Bit_Row& y) {
00290 const mp_size_t x_vec_size = x.vec->_mp_size;
00291 PPL_ASSERT(x_vec_size >= 0);
00292 const mp_size_t y_vec_size = y.vec->_mp_size;
00293 PPL_ASSERT(y_vec_size >= 0);
00294
00295 if (x_vec_size != y_vec_size)
00296 return true;
00297
00298 return mpn_cmp(x.vec->_mp_d, y.vec->_mp_d, x_vec_size) != 0;
00299 }
00300
00301 bool
00302 PPL::Bit_Row::OK() const {
00303 const mp_size_t vec_size = vec->_mp_size;
00304 const mp_size_t vec_alloc = vec->_mp_alloc;
00305 return vec_size >= 0
00306 && vec_alloc >= vec_size
00307 && (vec_size == 0 || mpz_getlimbn(vec, vec_size-1) != 0);
00308 }
00309
00310 void
00311 PPL::Bit_Row::union_helper(const Bit_Row& y, const Bit_Row& z) {
00312 mp_size_t y_size = y.vec->_mp_size;
00313 mp_size_t z_size = z.vec->_mp_size;
00314 PPL_ASSERT(y_size <= z_size);
00315 PPL_ASSERT(vec->_mp_alloc >= z_size);
00316 vec->_mp_size = z_size;
00317 mp_srcptr yp = y.vec->_mp_d;
00318 mp_srcptr zp = z.vec->_mp_d;
00319 mp_ptr p = vec->_mp_d;
00320 z_size -= y_size;
00321 while (y_size > 0) {
00322 *p = *yp | * zp;
00323 ++yp;
00324 ++zp;
00325 ++p;
00326 --y_size;
00327 }
00328 while (z_size > 0) {
00329 *p = *zp;
00330 ++zp;
00331 ++p;
00332 --z_size;
00333 }
00334 }