Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members

constraints.h

Go to the documentation of this file.
00001 /* -*- mode: C++; c-file-style: "stroustrup"; c-basic-offset: 4; indent-tabs-mode: nil; -*- */
00002 /*********************************************************************
00003  *
00004  * Filename : constraints.h (dbm)
00005  * C header.
00006  *
00007  * Definition of type, constants, and basic operations for constraints.
00008  *
00009  * This file is a part of the UPPAAL toolkit.
00010  * Copyright (c) 1995 - 2003, Uppsala University and Aalborg University.
00011  * All right reserved.
00012  *
00013  * v 1.2 reviewed.
00014  * $Id: constraints.h,v 1.20 2005/09/15 12:39:22 adavid Exp $
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 /** To distinguish normal integers and those
00031  * representing constraints. "raw" is used
00032  * because it represents an encoding and this
00033  * is the raw representation of it.
00034  */
00035 typedef int32_t raw_t;
00036 
00037 
00038 /** Basic clock constraint representation.
00039  * xi-xj <= value (with the special encoding)
00040  */
00041 #ifdef __cplusplus
00042 // C++ version: constructors
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; /**< indices for xi and xj */
00062     raw_t value;
00063 } constraint_t;
00064 #endif
00065 
00066 /** *Bound* constants.
00067  */
00068 enum
00069 {
00070     dbm_INFINITY = INT_MAX >> 1, /**< infinity                           */
00071     dbm_OVERFLOW = INT_MAX >> 2  /**< to detect overflow on computations */
00072 };
00073 
00074 
00075 /** Bound *strictness*. Vital constant values *DO NOT CHANGE*.
00076  */
00077 typedef enum
00078 {
00079     dbm_STRICT = 0, /**< strict less than constraints:  < x */
00080     dbm_WEAK = 1    /**< less or equal constraints   : <= x */
00081 }
00082 strictness_t;
00083 
00084 
00085 /** *Raw* encoded constants.
00086  */
00087 enum
00088 {
00089     dbm_LE_ZERO = 1,                       /**< Less Equal Zero                    */
00090     dbm_LS_INFINITY = (dbm_INFINITY << 1), /**< Less Strict than infinity          */
00091     dbm_LE_OVERFLOW = dbm_LS_INFINITY >> 1 /**< to detect overflow on computations */
00092 };
00093 
00094 
00095 /** Encoding of bound into (strict) less or less equal.
00096  * @param bound,strict: the bound to encode with the strictness.
00097  * @return encoded constraint ("raw").
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 /** Encoding of bound into (strict) less or less equal.
00107  * @param bound,isStrict: the bound to encode with a flag
00108  * telling if the bound is strict or not.
00109  * if isStrict is TRUE then dbm_STRICT is taken,
00110  * otherwise dbm_WEAK.
00111  * @return encoded constraint ("raw").
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 /** Decoding of raw representation: bound.
00128  * @param raw: encoded constraint (bound + strictness).
00129  * @return the decoded bound value.
00130  */
00131 static inline
00132 int32_t dbm_raw2bound(raw_t raw)
00133 {
00134     return (raw >> 1);
00135 }
00136 
00137 /** Make an encoded constraint strict.
00138  * @param raw: bound to make strict.
00139  * @return strict raw.
00140  */
00141 static inline
00142 raw_t dbm_strictRaw(raw_t raw)
00143 {
00144     assert(dbm_STRICT == 0);
00145     return raw & ~dbm_WEAK; // clear bit
00146 }
00147 
00148 /** Make an encoded constraint weak.
00149  * @param raw: bound to make weak.
00150  * @pre raw != dbm_LS_INFINITY because <= infinity
00151  * is wrong.
00152  * @return weak raw.
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; // set bit
00160 }
00161 
00162 /** Decoding of raw representation: strictness.
00163  * @param raw: encoded constraint (bound + strictness).
00164  * @return the decoded strictness.
00165  */
00166 static inline
00167 strictness_t dbm_raw2strict(raw_t raw)
00168 {
00169     return (strictness_t)(raw & 1);
00170 }
00171 
00172 
00173 /** Tests of strictness.
00174  * @param raw: encoded constraint (bound + strictness).
00175  * @return TRUE if the constraint is strict.
00176  * dbm_rawIsStrict(x) == !dbm_rawIsEq(x)
00177  */
00178 static inline
00179 BOOL dbm_rawIsStrict(raw_t raw)
00180 {
00181     return (BOOL)((raw & 1) ^ dbm_WEAK);
00182 }
00183 
00184 
00185 /** Tests of non strictness.
00186  * @param raw: encoded constraint (bound + strictness).
00187  * @return TRUE if the constraint is not strict.
00188  * dbm_rawIsStrict(x) == !dbm_rawIsEq(x)
00189  */
00190 static inline
00191 BOOL dbm_rawIsWeak(raw_t raw)
00192 {
00193     return (BOOL)((raw & 1) ^ dbm_STRICT);
00194 }
00195 
00196 
00197 /** Negate the strictness of a constraint.
00198  * @param strictness: the flag to negate.
00199  */
00200 static inline
00201 strictness_t dbm_negStrict(strictness_t strictness)
00202 {
00203     return (strictness_t)(strictness ^ 1);
00204 }
00205 
00206 
00207 /** Negate a constraint:
00208  * neg(<a) = <=-a
00209  * neg(<=a) = <-a
00210  * @param c: the constraint.
00211  */
00212 static inline
00213 raw_t dbm_negRaw(raw_t c)
00214 {
00215     /* Check that the trick is correct
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 /** "Weak" negate a constraint:
00225  * neg(<=a) = <= -a.
00226  * @pre c is weak.
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 /** A valid raw bound should not cause overflow in computations.
00239  * @param x: encoded constraint (bound + strictness)
00240  * @return TRUE if adding this constraint to any constraint
00241  * does not overflow.
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 /** Constraint addition on raw values : + constraints - excess bit.
00251  * @param x,y: encoded constraints to add.
00252  * @return encoded constraint x+y.
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 /** Constraint addition:
00267  * @param x,y: encoded constraints to add.
00268  * @return encoded constraint x+y.
00269  * @pre y finite.
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 /** Constraint addition.
00289  * @param x,y: encoded constraints to add.
00290  * @return encoded constraint x+y.
00291  * @pre x and y finite.
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 /** Specialized constraint addition.
00305  * @param x,y: finite encoded constraints to add.
00306  * @pre x & y finite, x or y weak.
00307  * @return encoded constraint x+y
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 /** Raw constraint increment:
00322  * @return constraint + increment with test infinity
00323  * @param c: constraint
00324  * @param i: increment
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 /** Raw constraint decrement:
00334  * @return constraint + decremen with test infinity
00335  * @param c: constraint
00336  * @param d: decrement
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 /** Convenience function to build a constraint.
00346  * @param i,j: indices.
00347  * @param bound: the bound.
00348  * @param strictness: strictness of the constraint.
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 /** 2nd convenience function to build a constraint.
00369  * @param i,j: indices.
00370  * @param bound: the bound.
00371  * @param isStrict: true if constraint is strict
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 /** Negation of a constraint.
00392  * Swap indices i,j, negate value, and toggle the strictness.
00393  * @param c: constraint to negate.
00394  * @return negated constraint.
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 /** Equality of constraints.
00408  * @param c1, c2: constraints.
00409  * @return TRUE if c1 == c2.
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 /** Comparison operator < defined if C++
00423  * @param a,b: constraints to compare.
00424  * @return true: if a < b
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 /** Negation operator for constraint_t.
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 /** Equality operator for constraint_t.
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 /* INCLUDE_DBM_CONSTRAINTS_H */

Generated on Fri Jun 30 00:02:45 2006 for Module dbm by  doxygen 1.4.2