00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #ifndef INCLUDE_DBM_CONSTRAINTS_H
00019 #define INCLUDE_DBM_CONSTRAINTS_H
00020
00021 #include <limits.h>
00022 #include <assert.h>
00023 #include "base/inttypes.h"
00024
00025 #ifdef __cplusplus
00026 #include <iostream>
00027 extern "C" {
00028 #endif
00029
00030
00031
00032
00033
00034
00035 typedef int32_t raw_t;
00036
00037
00038
00039
00040
00041 #ifdef __cplusplus
00042
00043 struct constraint_t
00044 {
00045 constraint_t() {}
00046 constraint_t(const constraint_t &c)
00047 : i(c.i), j(c.j), value(c.value) {}
00048 constraint_t(cindex_t ci, cindex_t cj, raw_t vij)
00049 : i(ci), j(cj), value(vij) {}
00050 constraint_t(cindex_t ci, cindex_t cj, int32_t bound, bool isStrict)
00051 : i(ci), j(cj), value((bound << 1) | (isStrict ^ 1)) {}
00052
00053 bool operator == (const constraint_t& b) const;
00054
00055 cindex_t i,j;
00056 raw_t value;
00057 };
00058 #else
00059 typedef struct
00060 {
00061 cindex_t i,j;
00062 raw_t value;
00063 } constraint_t;
00064 #endif
00065
00066
00067
00068 enum
00069 {
00070 dbm_INFINITY = INT_MAX >> 1,
00071 dbm_OVERFLOW = INT_MAX >> 2
00072 };
00073
00074
00075
00076
00077 typedef enum
00078 {
00079 dbm_STRICT = 0,
00080 dbm_WEAK = 1
00081 }
00082 strictness_t;
00083
00084
00085
00086
00087 enum
00088 {
00089 dbm_LE_ZERO = 1,
00090 dbm_LS_INFINITY = (dbm_INFINITY << 1),
00091 dbm_LE_OVERFLOW = dbm_LS_INFINITY >> 1
00092 };
00093
00094
00095
00096
00097
00098
00099 static inline
00100 raw_t dbm_bound2raw(int32_t bound, strictness_t strict)
00101 {
00102 return (bound << 1) | strict;
00103 }
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113 #ifdef __cplusplus
00114 static inline
00115 raw_t dbm_boundbool2raw(int32_t bound, bool isStrict)
00116 {
00117 return (bound << 1) | (isStrict ^ 1);
00118 }
00119 #else
00120 static inline
00121 raw_t dbm_boundbool2raw(int32_t bound, BOOL isStrict)
00122 {
00123 return (bound << 1) | (isStrict ^ 1);
00124 }
00125 #endif
00126
00127
00128
00129
00130
00131 static inline
00132 int32_t dbm_raw2bound(raw_t raw)
00133 {
00134 return (raw >> 1);
00135 }
00136
00137
00138
00139
00140
00141 static inline
00142 raw_t dbm_strictRaw(raw_t raw)
00143 {
00144 assert(dbm_STRICT == 0);
00145 return raw & ~dbm_WEAK;
00146 }
00147
00148
00149
00150
00151
00152
00153
00154 static inline
00155 raw_t dbm_weakRaw(raw_t raw)
00156 {
00157 assert(dbm_WEAK == 1);
00158 assert(raw != dbm_LS_INFINITY);
00159 return raw | dbm_WEAK;
00160 }
00161
00162
00163
00164
00165
00166 static inline
00167 strictness_t dbm_raw2strict(raw_t raw)
00168 {
00169 return (strictness_t)(raw & 1);
00170 }
00171
00172
00173
00174
00175
00176
00177
00178 static inline
00179 BOOL dbm_rawIsStrict(raw_t raw)
00180 {
00181 return (BOOL)((raw & 1) ^ dbm_WEAK);
00182 }
00183
00184
00185
00186
00187
00188
00189
00190 static inline
00191 BOOL dbm_rawIsWeak(raw_t raw)
00192 {
00193 return (BOOL)((raw & 1) ^ dbm_STRICT);
00194 }
00195
00196
00197
00198
00199
00200 static inline
00201 strictness_t dbm_negStrict(strictness_t strictness)
00202 {
00203 return (strictness_t)(strictness ^ 1);
00204 }
00205
00206
00207
00208
00209
00210
00211
00212 static inline
00213 raw_t dbm_negRaw(raw_t c)
00214 {
00215
00216
00217 assert(1 - c ==
00218 dbm_bound2raw(-dbm_raw2bound(c),
00219 dbm_negStrict(dbm_raw2strict(c))));
00220 return 1 - c;
00221 }
00222
00223
00224
00225
00226
00227
00228 static inline
00229 raw_t dbm_weakNegRaw(raw_t c)
00230 {
00231 assert(dbm_rawIsWeak(c));
00232 assert(2 - c ==
00233 dbm_bound2raw(-dbm_raw2bound(c), dbm_WEAK));
00234 return 2 - c;
00235 }
00236
00237
00238
00239
00240
00241
00242
00243 static inline
00244 BOOL dbm_isValidRaw(raw_t x)
00245 {
00246 return (BOOL)(x == dbm_LS_INFINITY || (x < dbm_LE_OVERFLOW && -x < dbm_LE_OVERFLOW));
00247 }
00248
00249
00250
00251
00252
00253
00254 static inline
00255 raw_t dbm_addRawRaw(raw_t x, raw_t y)
00256 {
00257 assert(x <= dbm_LS_INFINITY);
00258 assert(y <= dbm_LS_INFINITY);
00259 assert(dbm_isValidRaw(x));
00260 assert(dbm_isValidRaw(y));
00261 return (x == dbm_LS_INFINITY || y == dbm_LS_INFINITY) ?
00262 dbm_LS_INFINITY : (x + y) - ((x | y) & 1);
00263 }
00264
00265
00266
00267
00268
00269
00270
00271 static inline
00272 raw_t dbm_addRawFinite(raw_t x, raw_t y)
00273 {
00274 assert(x <= dbm_LS_INFINITY);
00275 assert(y < dbm_LS_INFINITY);
00276 assert(dbm_isValidRaw(x));
00277 assert(dbm_isValidRaw(y));
00278 return x == dbm_LS_INFINITY ? dbm_LS_INFINITY : (x + y) - ((x | y) & 1);
00279 }
00280
00281 static inline
00282 raw_t dbm_addFiniteRaw(raw_t x, raw_t y)
00283 {
00284 return dbm_addRawFinite(y, x);
00285 }
00286
00287
00288
00289
00290
00291
00292
00293 static inline
00294 raw_t dbm_addFiniteFinite(raw_t x, raw_t y)
00295 {
00296 assert(x < dbm_LS_INFINITY);
00297 assert(y < dbm_LS_INFINITY);
00298 assert(dbm_isValidRaw(x));
00299 assert(dbm_isValidRaw(y));
00300 return (x + y) - ((x | y) & 1);
00301 }
00302
00303
00304
00305
00306
00307
00308
00309 static inline
00310 raw_t dbm_addFiniteWeak(raw_t x, raw_t y)
00311 {
00312 assert(x < dbm_LS_INFINITY);
00313 assert(y < dbm_LS_INFINITY);
00314 assert(dbm_isValidRaw(x));
00315 assert(dbm_isValidRaw(y));
00316 assert((x | y) & 1);
00317 return x + y - 1;
00318 }
00319
00320
00321
00322
00323
00324
00325
00326 static inline
00327 raw_t dbm_rawInc(raw_t c, raw_t i)
00328 {
00329 return c < dbm_LS_INFINITY ? c + i : c;
00330 }
00331
00332
00333
00334
00335
00336
00337
00338 static inline
00339 raw_t dbm_rawDec(raw_t c, raw_t d)
00340 {
00341 return c < dbm_LS_INFINITY ? c - d : c;
00342 }
00343
00344
00345
00346
00347
00348
00349
00350 static inline
00351 constraint_t dbm_constraint(cindex_t i, cindex_t j,
00352 int32_t bound, strictness_t strictness)
00353 {
00354 #ifdef __cplusplus
00355 return constraint_t(i, j, dbm_bound2raw(bound, strictness));
00356 #else
00357 constraint_t c =
00358 {
00359 i:i,
00360 j:j,
00361 value:dbm_bound2raw(bound, strictness)
00362 };
00363 return c;
00364 #endif
00365 }
00366
00367
00368
00369
00370
00371
00372
00373 static inline
00374 constraint_t dbm_constraint2(cindex_t i, cindex_t j,
00375 int32_t bound, BOOL isStrict)
00376 {
00377 #ifdef __cplusplus
00378 return constraint_t(i, j, dbm_boundbool2raw(bound, isStrict));
00379 #else
00380 constraint_t c =
00381 {
00382 i:i,
00383 j:j,
00384 value:dbm_boundbool2raw(bound, isStrict)
00385 };
00386 return c;
00387 #endif
00388 }
00389
00390
00391
00392
00393
00394
00395
00396 static inline
00397 constraint_t dbm_negConstraint(constraint_t c)
00398 {
00399 cindex_t tmp = c.i;
00400 c.i = c.j;
00401 c.j = tmp;
00402 c.value = dbm_negRaw(c.value);
00403 return c;
00404 }
00405
00406
00407
00408
00409
00410
00411 static inline
00412 BOOL dbm_areConstraintsEqual(constraint_t c1, constraint_t c2)
00413 {
00414 return (BOOL)(c1.i == c2.i &&
00415 c1.j == c2.j &&
00416 c1.value == c2.value);
00417 }
00418
00419
00420 #ifdef __cplusplus
00421
00422
00423
00424
00425
00426 static inline
00427 bool operator < (const constraint_t& a, const constraint_t& b)
00428 {
00429 return (a.i < b.i)
00430 || (a.i == b.i && a.j < b.j)
00431 || (a.i == b.i && a.j == b.j && a.value < b.value);
00432 }
00433
00434
00435
00436 static inline
00437 constraint_t operator !(const constraint_t& c)
00438 {
00439 return constraint_t(c.j, c.i, dbm_negRaw(c.value));
00440 }
00441
00442
00443
00444 inline
00445 bool constraint_t::operator == (const constraint_t& b) const
00446 {
00447 return i == b.i && j == b.j && value == b.value;
00448 }
00449
00450 }
00451 #endif
00452
00453 #endif