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

inline_fed.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 : inline_fed.h (dbm)
00005 //
00006 // Internal classes and inlined implementation of fed.h
00007 //
00008 // This file is a part of the UPPAAL toolkit.
00009 // Copyright (c) 1995 - 2003, Uppsala University and Aalborg University.
00010 // All right reserved.
00011 //
00012 // $Id: inline_fed.h,v 1.34 2005/10/24 18:34:09 adavid Exp $
00013 //
00014 ///////////////////////////////////////////////////////////////////
00015 
00016 #if defined(INCLUDE_DBM_INLINE_FED_H) || !defined(INCLUDE_DBM_FED_H)
00017 #error "dbm/inline_fed.h wrongly included!"
00018 #endif
00019 #define INCLUDE_DBM_INLINE_FED_H
00020 
00021 #include "base/FatalException.h"
00022 #include "base/ItemAllocator.h"
00023 #include "base/stats.h"
00024 #include "hash/tables.h"
00025 #include "debug/macros.h"
00026 
00027 /** @file
00028  * This file contains internal classes and inlined implementation of fed.h.
00029  */
00030 namespace dbm
00031 {
00032     /// @return true if ptr is a non null pointer, mainly for debugging.
00033     static inline bool isPointer(const void *ptr)
00034     {
00035         return (((uintptr_t)ptr) & 3) == 0 && ptr != NULL;
00036     }
00037 
00038     /********************************************************
00039      * DBMTable : hash table of idbm_t to internalize them. *
00040      ********************************************************/
00041 
00042     class DBMTable : public hash::TableDouble<idbm_t>
00043     {
00044     public:
00045         /// Default constructor, @see table.h
00046         DBMTable(): hash::TableDouble<idbm_t>(dbm_t::MAX_DIM_POWER, false){}
00047 
00048 #ifdef ENABLE_MONITOR
00049         /// this hash table should be empty now unless there have been leaks
00050         ~DBMTable() {
00051             if (nbBuckets) {
00052                 std::cerr << RED(BOLD) << nbBuckets
00053                           << (nbBuckets > 1 ? " DBMs are" : " DBM is")
00054                           << " left in the internal hash table!"NORMAL"\n";
00055             }
00056         }
00057 #endif
00058     };
00059     
00060     /// One instance for the DBM table.
00061     extern DBMTable dbm_table;
00062 
00063     /****************************************************
00064      * Allocation of DBMs: by new or internal allocator *
00065      ****************************************************/
00066 
00067 #ifdef ENABLE_DBM_NEW
00068 
00069     /// Clean-up function does nothing
00070     static inline void cleanUp() {}
00071 
00072     /** Allocate memory with new.
00073      * @param dim: dimension of the idbm_t to allocate.
00074      */
00075     static inline
00076     void* dbm_new(cindex_t dim)
00077     {
00078         return new int32_t[intsizeof(idbm_t)+dim*dim];
00079     }
00080 
00081     /** Deallocate memory as allocated by dbm_new.
00082      * @param dbm: idbm_t to deallocate.
00083      * @pre dbm != NULL
00084      */
00085     static inline
00086     void dbm_delete(idbm_t *dbm)
00087     {
00088         assert(dbm);
00089         delete [] reinterpret_cast<int32_t*>(dbm);
00090     }
00091 
00092 #else // ifndef ENABLE_DBM_NEW
00093 
00094     /** Allocate memory with a local allocator.
00095      * @param dim: dimension of the idbm_t to allocate.
00096      * DON'T INLINE because array_t will expand
00097      * every call too badly.
00098      */
00099     void* dbm_new(cindex_t dim);
00100 
00101     /** Deallocate memory as allocated by dbm_new.
00102      * @param dbm: idbm_t to deallocate.
00103      * @pre dbm != NULL
00104      * DON'T INLINE because array_t will expand
00105      * every call too badly.
00106      */
00107     void dbm_delete(idbm_t *dbm);
00108 
00109 #endif // ENABLE_DBM_NEW
00110 
00111     /**************************************************
00112      * idbm_t: internal DBM -- to be used in DBMTable *
00113      **************************************************/
00114     
00115     class idbm_t : public hash::TableDouble<idbm_t>::Bucket_t
00116     {
00117     public:
00118         /** Maximal dimension == 2^15-1
00119          * because (2^15)^2 == 2^30 constraints == 2^32 bytes
00120          * and we are in big big trouble then.
00121          * MAX_DIM is the maximum dimension *and* the access mask.
00122          * HASH_MASK contains the remaining bits for the hash value
00123          * HASHED_BIT mark if this DBM is in a hash tabled (hashed).
00124          */
00125         enum
00126         {
00127             HASHED_BIT = (1 << 31),
00128             HASH_MASK = ~(HASHED_BIT | dbm_t::MAX_DIM),
00129             DIM_MASK = dbm_t::MAX_DIM
00130         };
00131 
00132         /// @return dimension of this DBM.
00133         cindex_t getDimension() const {
00134             return info & DIM_MASK;
00135         }
00136 
00137         /// @return a freshly computed hash value
00138         uint32_t hash(uint32_t seed = 0) const {
00139             uint32_t dim = getDimension();
00140             return hash_computeI32(matrix, dim*dim, seed);
00141         }
00142 
00143         /// @return true if this DBM is in a hash table
00144         bool isHashed() const {
00145             return (info & HASHED_BIT) != 0;
00146         }
00147 
00148         /// @return true if this dbm can be modified.
00149         bool isMutable() const {
00150             assert(refCounter > 0);
00151             return refCounter == 1 && !isHashed();
00152         }
00153 
00154         /// Check if this dimPtr is mutable and try to make it so cheaply.
00155         bool tryMutable() {
00156             assert(refCounter > 0);
00157             if (refCounter > 1) return false;
00158             if (isHashed()) unhash();
00159             return true;
00160         }
00161 
00162         /// Unhash itself.
00163         /// @pre refCounter == 1 && isHashed()
00164         void unhash() {
00165             assert(refCounter == 1 && isHashed());
00166             dbm_table.remove(this);
00167             unmarkHashed();
00168         }
00169 
00170         /// @return recomputed hash value for this DBM
00171         /// and save it partially.
00172         uint32_t updateHash(uint32_t seed = 0) {
00173             uint32_t hashValue = hash(seed);
00174             info = (info & ~HASH_MASK) | (hashValue & HASH_MASK);
00175             return hashValue;
00176         }
00177         
00178         /// Mark 'this' as hashed
00179         void markHashed() {
00180             assert(!isHashed());
00181             info |= HASHED_BIT;
00182         }
00183         
00184         /// Unmark 'this' as hashed
00185         void unmarkHashed() {
00186             assert(isHashed());
00187             info &= ~HASHED_BIT;
00188         }
00189 
00190         /// Increment reference counter.
00191         void incRef() { refCounter++; }
00192 
00193         /// Decrement reference counter.
00194         /// @post 'this' may be deallocated.
00195         void decRef() {
00196             assert(refCounter > 0);
00197             if (--refCounter == 0) remove();
00198         }
00199 
00200         /// Simple decRef without remove() @pre refCounter > 1
00201         void decRefImmutable() {
00202             assert(refCounter > 1);
00203             refCounter--;
00204         }
00205 
00206         /// Simple remove for mutable idbm_t. @pre isMutable()
00207         void removeMutable() {
00208             assert(isMutable());
00209             dbm_delete(this);
00210         }
00211         
00212         /** Deallocate this idbm_t.
00213          * @pre refCounter == 0
00214          * Not inlined since the call is present very often
00215          * for every decRef, where decRef is called for
00216          * garbage collection.
00217          */
00218         void remove();
00219 
00220         /// @return writable DBM matrix, @pre isMutable()
00221         raw_t* dbm() {
00222             assert(isMutable());
00223             return matrix;
00224         }
00225 
00226         /// @return read-only DBM matrix.
00227         const raw_t* const_dbm() const {
00228             return matrix;
00229         }
00230 
00231         /// @return DBM matrix without pre-condition, careful...
00232         raw_t* getMatrix() {
00233             return matrix;
00234         }
00235 
00236         /// @return newly allocated idbm_t, @param dim: DBM dimension.
00237         static idbm_t* create(cindex_t dim) {
00238             return new (dbm_new(dim)) idbm_t(dim); // placement constructor
00239         }
00240 
00241         /// @return newly allocated idbm_t, @param arg: original to copy.
00242         static idbm_t* create(const idbm_t& arg) {
00243             return new (dbm_new(arg.getDimension())) idbm_t(arg); // placement constructor
00244         }
00245 
00246         /** Constructor: use placement constructor
00247          * to instantiate.
00248          * @param dim: dimension of the DBM.
00249          * @pre dim < 2^16, reasonable since such a
00250          * DBM would have 2^32 elements and we cannot
00251          * use a single such DBM.
00252          * @post DBM is not initialized!
00253          */
00254         idbm_t(cindex_t dim) {
00255             assert(dim > 0 && dim <= DIM_MASK);
00256             info = dim;
00257             refCounter = 1;
00258         }
00259         
00260         /** Constructor by copy: useful to get a mutable copy
00261          * of this DBM.
00262          * @param original: DBM to copy.
00263          */
00264         idbm_t(const idbm_t& original) {
00265             info = original.getDimension();
00266             refCounter = 1;
00267             dbm_copy(matrix, original.matrix, info);
00268         }
00269 
00270     private:
00271         /// Must never be called
00272         ~idbm_t() {
00273             FATAL("~idbm_t() called!");
00274         }
00275 
00276         /* Inherited variables from parent class:
00277          * idbm_t **previous, *next: for collision list of
00278          * the internal hash table.
00279          * uint32_t info: special coding is as follows
00280          * info & 0x80000000 = mutable bit = is not hashed
00281          * info & 0x7fff8000 = higher bits of hash value
00282          * info & 0x00007fff = dimension (default DBM_MAX_DIM)
00283          */
00284         uint32_t refCounter; //< reference counter
00285         raw_t matrix[];      //< DBM matrix
00286     };
00287 
00288     /*********************************
00289      * Allocation of fdbm_t & ifed_t *
00290      *********************************/
00291 
00292     /// Use a struct here to instantiate an ItemAllocator (and
00293     /// cheat gravely with the allocator). fdbm_t has a dbm_t as
00294     /// member, which implies a constructor, which bugs us very much.
00295     struct alloc_fdbm_t
00296     {
00297         ifed_t *next; //< list of DBMs for the federation
00298         idbm_t *idbm; //< DBM itself
00299     };
00300 
00301     /// Similarly for ifed_t
00302     struct alloc_ifed_t
00303     {
00304         uint32_t refCounter;
00305         size_t fedSize;
00306         cindex_t dim;
00307         fdbm_t* fhead;
00308     };
00309 
00310     /// Allocator instance.
00311     extern base::ItemAllocator<alloc_fdbm_t> fdbm_allocator;
00312     extern base::ItemAllocator<alloc_ifed_t> ifed_allocator;
00313 
00314     /********************************************************
00315      * Federation of DBMs: list containing individual DBMs. *
00316      ********************************************************/
00317 
00318     class fdbm_t
00319     {
00320     public:
00321         /// Copy a DBM into a newly created fdbm_t.
00322         /// @param adbm: the DBM to copy.
00323         /// @param nxt: list of DBMs to append.
00324         static fdbm_t* create(const raw_t* adbm, cindex_t dim, fdbm_t* nxt = NULL) {
00325             fdbm_t* fdbm = create(nxt);
00326             fdbm->idbm.newCopy(adbm, dim);
00327             return fdbm;
00328         }
00329         static fdbm_t* create(const dbm_t& adbm, fdbm_t* nxt = NULL) {
00330             fdbm_t* fdbm = create(nxt);
00331             fdbm->idbm.newCopy(adbm);
00332             return fdbm;
00333         }
00334 
00335         /// Copy start and append end to the copy.
00336         static fdbm_t* copy(const fdbm_t* start, fdbm_t* end = NULL);
00337 
00338         /// Wrapper methods.
00339         fdbm_t* copy()         const { return copy(this); }
00340         bool    isEmpty()      const { return idbm.isEmpty(); }
00341         cindex_t getDimension() const { return idbm.getDimension(); }
00342 
00343         /// Remove the list starting at fhead.
00344         static void removeAll(fdbm_t *fhead);
00345 
00346         /// Remove this fdbm_t and its DBM.
00347         void remove() {
00348             idbm.nil();
00349             fdbm_allocator.deallocate(reinterpret_cast<alloc_fdbm_t*>(this));
00350         }
00351 
00352         /// Remove this fdbm_t with @pre isEmpty()
00353         void removeEmpty() {
00354             assert(isEmpty());
00355             fdbm_allocator.deallocate(reinterpret_cast<alloc_fdbm_t*>(this));
00356         }
00357 
00358         /// Compute list size.
00359         size_t size() const {
00360             const fdbm_t* f = this;
00361             size_t s = 0;
00362             do { f = f->next; ++s; } while(f);
00363             return s;
00364         }
00365 
00366         /// @return the internal DBM.
00367         const dbm_t& const_dbmt() const { return idbm; }
00368         dbm_t& dbmt() { return idbm; }
00369 
00370         /// Unchecked access.
00371         raw_t* getMatrix() {
00372             return idbm.idbmt()->getMatrix();
00373         }
00374 
00375         /// @return start appended with end.
00376         static fdbm_t* append(fdbm_t *start, fdbm_t *end);
00377 
00378         /// @return next for iterations.
00379         fdbm_t** getNextMutable() { return &next; }
00380         const fdbm_t* getNext() const { return next; }
00381         fdbm_t* getNext() { return next; }
00382 
00383         /// Test its next pointer.
00384         bool hasNext(fdbm_t** nxt) const { return &next == nxt; }
00385 
00386         /// Change next for iterations.
00387         void setNext(fdbm_t* nxt) { next = nxt; }
00388 
00389         /// Remove this and return next;
00390         fdbm_t* removeAndNext() {
00391             fdbm_t *nxt = next;
00392             remove();
00393             return nxt;
00394         }
00395         /// Remove this and return next;
00396         fdbm_t* removeEmptyAndNext() {
00397             fdbm_t *nxt = next;
00398             removeEmpty();
00399             return nxt;
00400         }
00401 
00402     private:
00403         /// Creation of fdbm_t using an allocator.
00404         static fdbm_t* create(fdbm_t* nxt = NULL);
00405 
00406         /// Must never be called
00407         ~fdbm_t() {
00408             FATAL("~fdbm_t called!");
00409         }
00410 
00411         fdbm_t *next; //< next DBM in the list.
00412         dbm_t idbm;   //< (internal) DBM.
00413     };
00414 
00415     /***************************************
00416      * ifed_t: head of the federation list *
00417      ***************************************/
00418     
00419     /// Simple list of DBMs for light-weight computations.
00420     class dbmlist_t
00421     {
00422     public:
00423         dbmlist_t()
00424             : fedSize(0), fhead(NULL) {}
00425         dbmlist_t(size_t size, fdbm_t *flist)
00426             : fedSize(size), fhead(flist) {}
00427         dbmlist_t(const raw_t* arg, cindex_t dim)
00428             : fedSize(1), fhead(fdbm_t::create(arg, dim)) {}
00429         dbmlist_t(const dbm_t& arg)
00430             : fedSize(1), fhead(fdbm_t::create(arg)) {}
00431 
00432         /// Append a list of fdbm_t.
00433         dbmlist_t& append(dbmlist_t& arg) {
00434             fhead = fedSize > arg.fedSize
00435                 ? fdbm_t::append(arg.fhead, fhead)
00436                 : fdbm_t::append(fhead, arg.fhead);
00437             fedSize += arg.fedSize;
00438             return *this;
00439         }
00440         /// Append just one fdbm_t, not the whole list!
00441         dbmlist_t& append(fdbm_t* arg) {
00442             assert(arg);
00443             arg->setNext(fhead);
00444             fhead = arg;
00445             fedSize++;
00446             return *this;
00447         }
00448         /// Append a copy of arg, @pre dimension is the same as the other DBMs.
00449         raw_t* append(const raw_t* arg, cindex_t dim) {
00450             fhead = fdbm_t::create(arg, dim, fhead);
00451             fedSize++;
00452             return fhead->getMatrix();
00453         }
00454 
00455         /// Remove DBMs of 'this' that are included in arg
00456         /// and DBMs of arg that are included in 'this'.
00457         void removeIncluded(dbmlist_t& arg);
00458 
00459         /// Union of arg with this dbmlist_t, does inclusion checking
00460         /// @post dbmlist_t arg is invalid.
00461         dbmlist_t& unionWith(dbmlist_t& arg) {
00462             removeIncluded(arg);
00463             append(arg);
00464             return *this;
00465         }
00466 
00467         /// Simple reduction by inclusion check of DBMs.
00468         void reduce(cindex_t dim);
00469 
00470         /// Reduction by inclusion check + merge (by pairs) of DBMs.
00471         void mergeReduce(cindex_t dim, size_t jumpj = 0);
00472 
00473         /// @return the federation size.
00474         size_t size() const {
00475             assert((fedSize == 0) == (fhead == NULL));
00476             assert(fhead == NULL || fedSize == fhead->size());
00477             return fedSize;
00478         }
00479 
00480         /// Head of the list.
00481         const fdbm_t* const_head() const { return fhead; }
00482         fdbm_t* head() { return fhead; }
00483         fdbm_t** atHead() { return &fhead; }
00484 
00485         /// Update the federation size.
00486         void incSize(size_t n = 1) { fedSize+= n; }
00487         void decSize(size_t n = 1) { assert(fedSize >= n); fedSize-= n; }
00488 
00489         /// Brutal re-set of the list.
00490         void reset(fdbm_t *dbms = NULL, size_t size = 0) {
00491             fedSize = size;
00492             fhead = dbms;
00493         }
00494         void reset(dbmlist_t& l) { reset(l.fhead, l.fedSize); }
00495 
00496         /// @return 'this' intersected with arg. @pre same dimension.
00497         dbmlist_t& intersection(const raw_t* arg, cindex_t dim);
00498         dbmlist_t& intersection(const dbm_t& arg, cindex_t dim);
00499 
00500         /// @return a simple copy of this list of DBMs.
00501         dbmlist_t copyList() const {
00502             return dbmlist_t(fedSize, fdbm_t::copy(fhead));
00503         }
00504 
00505         /// Steal one DBM of a dbmlist_t.
00506         void steal(fdbm_t **dbm, dbmlist_t &owner) {
00507             steal(&fhead, dbm, owner);
00508         }
00509         /// @pre head is somewhere in this list of DBMs
00510         fdbm_t** steal(fdbm_t **head, fdbm_t **dbm, dbmlist_t &owner) {
00511             assert(owner.fedSize && dbm && *dbm && head);
00512             fdbm_t **atNext = (*dbm)->getNextMutable();
00513             fdbm_t *next = *atNext;
00514             *atNext = *head;
00515             *head = *dbm;
00516             *dbm = next;
00517             incSize();
00518             owner.decSize();
00519             return atNext;
00520         }
00521 
00522         /// Steal a list and append it at the end.
00523         void stealFromToEnd(fdbm_t **next, dbmlist_t &dbmList) {
00524             while(*next) next = (*next)->getNextMutable();
00525             *next = dbmList.fhead;
00526             incSize(dbmList.fedSize);
00527             dbmList.reset();
00528         }
00529 
00530         /// Swap DBM lists.
00531         void swap(dbmlist_t &arg) {
00532             size_t s = fedSize;
00533             fedSize = arg.fedSize;
00534             arg.fedSize = s;
00535             fdbm_t* h = fhead;
00536             fhead = arg.fhead;
00537             arg.fhead = h;
00538         }
00539 
00540         /// Copy ref.
00541         void copyRef(dbmlist_t &arg) {
00542             fedSize = arg.fedSize;
00543             fhead = arg.fhead;
00544         }
00545 
00546         /// Remove head of list. @pre size() > 0.
00547         void removeHead() {
00548             assert(fedSize && fhead);
00549             fhead = fhead->removeAndNext();
00550             decSize();
00551         }
00552 
00553 #ifndef NDEBUG
00554         /// Print for debugging only, use operator << on fed_t instead.
00555         void print(std::ostream& os = std::cerr) const;
00556         void err() const;
00557         void out() const;
00558 #endif
00559 
00560     protected:
00561         size_t fedSize; //< size of the federation
00562         fdbm_t* fhead;  //< federation head of the list (1st DBM)
00563     };
00564     
00565     class ifed_t : public dbmlist_t
00566     {
00567     public:
00568         /// Creation and initialization of ifed_t. @pre the dbm is not empty.
00569         static ifed_t* create(const raw_t* adbm, cindex_t dim, size_t nxtSize = 0, fdbm_t* nxt = NULL) {
00570             return create(dim, 1+nxtSize, fdbm_t::create(adbm, dim, nxt));
00571         }
00572         static ifed_t* create(const dbm_t& adbm, size_t nxtSize = 0, fdbm_t* nxt = NULL) {
00573             return create(adbm.const_idbmt()->getDimension(), 1+nxtSize, fdbm_t::create(adbm, nxt));
00574         }
00575         static ifed_t* create(cindex_t dim) { // initial empty
00576             return create(dim, 0, NULL);
00577         }
00578         static ifed_t* create(cindex_t dim, dbmlist_t dbmlist) {
00579             return create(dim, dbmlist.size(), dbmlist.head());
00580         }
00581 
00582         /// Update the 1st DBM, @pre size() > 0 and same dimension.
00583         void update(const raw_t* adbm, cindex_t adim) {
00584             assert(size() > 0 && adim == dim);
00585             fhead->dbmt().updateCopy(adbm, adim);
00586         }
00587         void update(const dbm_t& adbm) {
00588             assert(size() > 0 && adbm.getDimension() == dim);
00589             fhead->dbmt().updateCopy(adbm);
00590         }
00591 
00592         /// Check invariants.
00593         bool isOK() const {
00594             size_t n = 0;
00595             for(const fdbm_t* f = fhead; f != NULL; f = f->getNext(), n++) {
00596                 if (f->isEmpty() || f->getDimension() != dim) {
00597                     return false;
00598                 }
00599             }
00600             return fedSize == n;
00601         }
00602 
00603         /// @return dimension of this federation.
00604         cindex_t getDimension() const { return dim; }
00605 
00606         /// Change the dimension @pre isEmpty()
00607         void setDimension(cindex_t d) {
00608             assert(isEmpty());
00609             dim = d;
00610         }
00611 
00612         /// @return true if this federation is empty.
00613         bool isEmpty() const {
00614             assert((size() == 0) == (fhead == NULL));
00615             return fhead == NULL;
00616         }
00617 
00618         /// Compute a hash value that does not depend on the order of the DBMs.
00619         uint32_t hash(uint32_t seed = 0) const;
00620 
00621         /// Decrement reference count, maybe deallocate.
00622         void decRef() {
00623             assert(refCounter > 0);
00624             if (!--refCounter) remove();
00625         }
00626 
00627         /// Decrement reference count with @pre !isMutable()
00628         void decRefImmutable() {
00629             assert(refCounter > 1);
00630             --refCounter;
00631         }
00632 
00633         /// Increment reference count.
00634         void incRef() { ++refCounter; }
00635 
00636         /// @return if this ifed_t can be modified.
00637         bool isMutable() const {
00638             assert(refCounter > 0);
00639             return refCounter == 1;
00640         }
00641 
00642         /// Remove this ifed_t with @pre isMutable()
00643         void removeMutable() {
00644             assert(--refCounter == 0); // For debugging purposes.
00645             remove();
00646         }
00647 
00648         /// @return copy of this ifed_t with appended list.
00649         /// @pre other is mutable.
00650         ifed_t* copy(ifed_t *other) const {
00651             assert(other && other->isMutable() && other->dim == dim && other->isOK());
00652             other->fhead = fdbm_t::copy(fhead, other->fhead);
00653             other->fedSize += fedSize;
00654             return other;
00655         }
00656         ifed_t* copy(fdbm_t *end = NULL, size_t endSize = 0) const {
00657             assert(endSize == (end ? end->size() : 0));
00658             return create(getDimension(), size() + endSize, fdbm_t::copy(fhead, end));
00659         }
00660 
00661         /// Insert a dbm, @pre same dimension & not empty.
00662         void insert(const dbm_t& adbm) {
00663             assert(adbm.getDimension() == getDimension() && !adbm.isEmpty());
00664             fhead = fdbm_t::create(adbm, fhead);
00665             incSize();
00666         }
00667         void insert(const raw_t* adbm, cindex_t adim) {
00668             assert(adim == getDimension());
00669             fhead = fdbm_t::create(adbm, adim, fhead);
00670             incSize();
00671         }
00672 
00673         /// Deallocate the list + update state.
00674         void setEmpty() {
00675             assert(refCounter <= 1);
00676             fdbm_t::removeAll(fhead);
00677             reset();
00678         }
00679 
00680         /// Deallocate the list and set the new list.
00681         void setDBM(fdbm_t *fdbm) {
00682             fdbm_t::removeAll(fhead);
00683             fhead = fdbm;
00684             fedSize = 1;
00685             fdbm->setNext(NULL);
00686         }
00687 
00688     private:
00689         /// Allocation of an ifed_t (and a fdbm_t) with an allocator.
00690         static ifed_t* create(cindex_t dim, size_t size, fdbm_t* head);
00691 
00692         /// Deallocate this ifed and its list of DBMs.
00693         void remove();
00694 
00695         uint32_t refCounter; //< reference counter
00696         cindex_t dim;         //< dimension
00697     };
00698     
00699     /***********************************************************
00700      * Inlined implementation of template ClockOperation<TYPE> *
00701      ***********************************************************/
00702 
00703 #define TEMPLATE template<class TYPE> inline
00704 #define CLOCKOP ClockOperation<TYPE>
00705 
00706     TEMPLATE CLOCKOP::ClockOperation(TYPE* d, cindex_t c)
00707         : ptr(d), clock(c), incVal(0)
00708     {
00709         assert(ptr && c < d->getDimension());
00710     }
00711 
00712     TEMPLATE CLOCKOP& CLOCKOP::operator + (int32_t val)
00713     {
00714         incVal += val; // intended to be used that way
00715         return *this;
00716     }
00717 
00718     TEMPLATE CLOCKOP& CLOCKOP::operator - (int32_t val)
00719     {
00720         incVal -= val; // intended to be used that way
00721         return *this;
00722     }
00723 
00724     TEMPLATE CLOCKOP& CLOCKOP::operator += (int32_t val)
00725     {
00726         return (*this = *this + val);
00727     }
00728 
00729     TEMPLATE CLOCKOP& CLOCKOP::operator -= (int32_t val)
00730     {
00731         return (*this = *this - val);
00732     }
00733 
00734     TEMPLATE CLOCKOP& CLOCKOP::operator = (const CLOCKOP& op)
00735     {
00736         assert(ptr == op.ptr); // don't mix-up operations
00737         ptr->update(clock, op.clock, op.incVal);
00738         incVal = 0;
00739         return *this;
00740     }
00741 
00742     TEMPLATE CLOCKOP& CLOCKOP::operator = (int32_t val)
00743     {
00744         ptr->updateValue(clock, val);
00745         incVal = 0;
00746         return *this;
00747     }
00748 
00749     TEMPLATE bool CLOCKOP::operator <  (const CLOCKOP& x) const
00750     {
00751         assert(ptr == x.ptr); // clock - x.clock < x.incVal - incVal
00752         return ptr->satisfies(clock, x.clock, dbm_bound2raw(x.incVal-incVal, dbm_STRICT));
00753     }
00754 
00755     TEMPLATE bool CLOCKOP::operator <= (const CLOCKOP& x) const
00756     {
00757         assert(ptr == x.ptr); // clock - x.clock <= x.incVal - incVal
00758         return ptr->satisfies(clock, x.clock, dbm_bound2raw(x.incVal-incVal, dbm_WEAK));
00759     }
00760 
00761     TEMPLATE bool CLOCKOP::operator >  (const CLOCKOP& x) const
00762     {
00763         assert(ptr == x.ptr); // x.clock - clock < incVal - x.incVal
00764         return ptr->satisfies(x.clock, clock, dbm_bound2raw(incVal-x.incVal, dbm_STRICT));
00765     }
00766 
00767     TEMPLATE bool CLOCKOP::operator >= (const CLOCKOP& x) const
00768     {
00769         assert(ptr == x.ptr); // x.clock - clock <= incVal - x.incVal
00770         return ptr->satisfies(x.clock, clock, dbm_bound2raw(incVal-x.incVal, dbm_WEAK));
00771     }
00772 
00773     TEMPLATE bool CLOCKOP::operator == (const CLOCKOP& x) const
00774     {
00775         return (*this >= x) && (*this <= x);
00776     }
00777 
00778     TEMPLATE bool CLOCKOP::operator <  (int32_t v) const
00779     {
00780         return ptr->satisfies(clock, 0, dbm_bound2raw(v-incVal, dbm_STRICT));
00781     }
00782 
00783     TEMPLATE bool CLOCKOP::operator <= (int32_t v) const
00784     {
00785         return ptr->satisfies(clock, 0, dbm_bound2raw(v-incVal, dbm_WEAK));
00786     }
00787 
00788     TEMPLATE bool CLOCKOP::operator >  (int32_t v) const
00789     {
00790         return ptr->satisfies(0, clock, dbm_bound2raw(incVal-v, dbm_STRICT));
00791     }
00792 
00793     TEMPLATE bool CLOCKOP::operator >= (int32_t v) const
00794     {
00795         return ptr->satisfies(0, clock, dbm_bound2raw(incVal-v, dbm_WEAK));
00796     }
00797 
00798     TEMPLATE bool CLOCKOP::operator == (int32_t v) const
00799     {
00800         return (*this <= v) && (*this >= v);
00801     }
00802 
00803 #undef CLOCKOP
00804 #undef TEMPLATE
00805     
00806     /***********************************
00807      * Inlined implementation of dbm_t *
00808      ***********************************/
00809     
00810     inline dbm_t::dbm_t(cindex_t dim)
00811     {
00812         assert(dim);
00813         setEmpty(dim);
00814     }
00815 
00816     inline dbm_t::dbm_t(const raw_t* arg, cindex_t dim)
00817     {
00818         assert(arg && dim); 
00819         assertx(dbm_isValid(arg, dim));
00820         dbm_copy(setNew(dim), arg, dim);
00821     }
00822 
00823     inline dbm_t::dbm_t(const dbm_t& arg)
00824     {
00825         idbmPtr = arg.idbmPtr;
00826         incRef();
00827     }
00828 
00829     inline dbm_t::~dbm_t()
00830     {
00831         decRef();
00832     }
00833 
00834     inline cindex_t dbm_t::getDimension() const
00835     {
00836         return isEmpty() ? edim() : pdim();
00837     }
00838 
00839     inline void dbm_t::setDimension(cindex_t dim)
00840     {
00841         decRef();
00842         setEmpty(dim);
00843     }
00844 
00845     inline bool dbm_t::isEmpty() const
00846     {
00847         return uval() & 1;
00848     }
00849 
00850     inline void dbm_t::setEmpty()
00851     {
00852         setDimension(getDimension());
00853     }
00854 
00855     inline void dbm_t::nil()
00856     {
00857         setDimension(1);
00858     }
00859 
00860     inline uint32_t dbm_t::hash(uint32_t seed) const
00861     {
00862         return isEmpty() ? uval() : const_idbmt()->hash(seed);
00863     }
00864     
00865     inline bool dbm_t::sameAs(const dbm_t& arg) const
00866     {
00867         return idbmPtr == arg.idbmPtr;
00868     }
00869 
00870     inline void dbm_t::intern()
00871     {
00872         if (!isEmpty()) ptr_intern();
00873     }
00874 
00875     inline const raw_t* dbm_t::operator () () const
00876     {
00877         return isEmpty() ? NULL : const_dbm();
00878     }
00879 
00880     inline raw_t dbm_t::operator () (cindex_t i, cindex_t j) const
00881     {
00882         assert(i < getDimension() && j < getDimension() && !isEmpty());
00883         return const_dbm()[i*pdim()+j];
00884     }
00885 
00886     inline const raw_t* dbm_t::operator [] (cindex_t i) const
00887     {
00888         assert(i < getDimension() && !isEmpty());
00889         return const_dbm() + i*pdim();
00890     }
00891 
00892     inline raw_t* dbm_t::getDBM()
00893     {
00894         return isEmpty() ? setNew(edim()) : getCopy();
00895     }
00896 
00897     inline size_t dbm_t::analyzeForMinDBM(uint32_t *bitMatrix) const
00898     {
00899         assert(!isEmpty());
00900         return dbm_analyzeForMinDBM(const_dbm(), pdim(), bitMatrix);
00901     }
00902 
00903     inline int32_t* dbm_t::writeToMinDBMWithOffset(bool minimizeGraph,
00904                                                    bool tryConstraints16,
00905                                                    allocator_t c_alloc,
00906                                                    size_t offset) const
00907     {
00908         assert(!isEmpty());
00909         return dbm_writeToMinDBMWithOffset(const_dbm(), pdim(),
00910                                            (BOOL)minimizeGraph, (BOOL)tryConstraints16,
00911                                            c_alloc, offset);
00912     }
00913 
00914     inline int32_t* dbm_t::writeAnalyzedDBM(uint32_t *bitMatrix,
00915                                             size_t nbConstraints,
00916                                             BOOL tryConstraints16,
00917                                             allocator_t c_alloc,
00918                                             size_t offset) const
00919     {
00920         assert(!isEmpty());
00921         return dbm_writeAnalyzedDBM(const_dbm(), pdim(),
00922                                     bitMatrix, nbConstraints,
00923                                     (BOOL)tryConstraints16, c_alloc, offset);
00924     }
00925 
00926     inline dbm_t dbm_t::readFromMinDBM(cindex_t dim, mingraph_t ming)
00927     {
00928         assert(ming);
00929             assert(dim == dbm_getDimOfMinDBM(ming));
00930             dbm_t result(dim);
00931         dbm_readFromMinDBM(result.getDBM(), ming);
00932         return result;
00933     }
00934 
00935     inline size_t dbm_t::getSizeOfMinDBM(cindex_t dim, mingraph_t ming)
00936     {
00937         assert(dim == dbm_getDimOfMinDBM(ming));
00938         return dbm_getSizeOfMinDBM(ming);
00939     }
00940 
00941     inline relation_t dbm_t::relation(mingraph_t ming, raw_t* unpackBuffer) const
00942     {
00943         // A mingraph_t never represents empty DBMs.
00944                return isEmpty() ? base_SUBSET : dbm_relationWithMinDBM(const_dbm(), pdim(), ming, unpackBuffer);
00945     }
00946 
00947     inline dbm_t& dbm_t::operator = (const dbm_t& arg)
00948     {
00949         arg.incRef(); // first in case a = a;
00950         decRef();
00951         idbmPtr = arg.idbmPtr;
00952         return *this;
00953     }
00954 
00955     inline dbm_t& dbm_t::operator = (const raw_t* arg)
00956     {
00957         copyFrom(arg, getDimension());
00958         return *this;
00959     }
00960 
00961     inline bool dbm_t::operator == (const fed_t& arg) const
00962     {
00963         return arg == *this; // fed_t has the implementation
00964     }
00965 
00966     inline bool dbm_t::operator != (const dbm_t& arg) const
00967     {
00968         return !(*this == arg);
00969     }
00970 
00971     inline bool dbm_t::operator != (const raw_t* arg) const
00972     {
00973         return !(*this == arg);
00974     }
00975 
00976     inline bool dbm_t::operator != (const fed_t& arg) const
00977     {
00978         return !(*this == arg);
00979     }
00980     
00981     inline bool dbm_t::operator < (const dbm_t& arg) const
00982     {
00983         return relation(arg) == base_SUBSET;
00984     }
00985 
00986     inline bool dbm_t::operator < (const fed_t& arg) const
00987     {
00988         return arg > *this; // fed_t has the implementation
00989     }
00990 
00991     inline bool dbm_t::operator > (const dbm_t& arg) const
00992     {
00993         return relation(arg) == base_SUPERSET;
00994     }
00995 
00996     inline bool dbm_t::operator > (const fed_t& arg) const
00997     {
00998         return arg < *this; // fed_t has the implementation
00999     }
01000 
01001     inline bool dbm_t::operator <= (const fed_t& arg) const
01002     {
01003         return arg >= *this;  // fed_t has the implementation
01004     }
01005 
01006     inline bool dbm_t::operator <= (const raw_t* arg) const
01007     {
01008         return isEmpty() || dbm_isSubsetEq(const_dbm(), arg, pdim());
01009     }
01010 
01011     inline bool dbm_t::operator >= (const dbm_t& arg) const
01012     {
01013         return arg <= *this;
01014     }
01015 
01016     inline bool dbm_t::operator >= (const fed_t& arg) const
01017     {
01018         return arg <= *this; // fed_t has the implementation
01019     }
01020 
01021     inline bool dbm_t::operator >= (const raw_t* arg) const
01022     {
01023         return !isEmpty() && dbm_isSubsetEq(arg, const_dbm(), pdim());
01024     }
01025 
01026     inline relation_t dbm_t::relation(const fed_t& arg) const
01027     {
01028         return base_symRelation(arg.relation(*this)); // symmetric -- fed_t has the implementation
01029     }
01030 
01031     inline bool dbm_t::lt(const fed_t& arg) const
01032     {
01033         return arg.gt(*this); // fed_t has the implementation
01034     }
01035 
01036     inline bool dbm_t::gt(const fed_t& arg) const
01037     {
01038         return arg.lt(*this); // fed_t has the implementation
01039     }
01040 
01041     inline bool dbm_t::le(const fed_t& arg) const
01042     {
01043         return arg.ge(*this); // fed_t has the implementation
01044     }
01045 
01046     inline bool dbm_t::ge(const fed_t& arg) const
01047     {
01048         return arg.le(*this); // fed_t has the implementation
01049     }
01050 
01051     inline bool dbm_t::eq(const fed_t& arg) const
01052     {
01053         return arg.eq(*this); // fed_t has the implementation
01054     }
01055     
01056     inline relation_t dbm_t::exactRelation(const fed_t& arg) const
01057     {
01058         return base_symRelation(arg.exactRelation(*this)); // fed_t has the implementation
01059     }
01060 
01061     inline bool dbm_t::isInit() const
01062     {
01063         return !isEmpty() && dbm_isEqualToInit(const_dbm(), pdim());
01064     }
01065 
01066     inline bool dbm_t::isZero() const
01067     {
01068         return !isEmpty() && dbm_isEqualToZero(const_dbm(), pdim());
01069     }
01070 
01071     inline dbm_t& dbm_t::operator &= (const constraint_t& c)
01072     {
01073         constrain(c.i, c.j, c.value);
01074         return *this;
01075     }
01076 
01077     inline dbm_t& dbm_t::operator &= (const base::pointer_t<constraint_t>& c)
01078     {
01079         constrain(c.begin(), c.size());
01080         return *this;
01081     }
01082 
01083     inline dbm_t& dbm_t::operator &= (const std::vector<constraint_t>& vec)
01084     {
01085         constrain(&vec[0], vec.size());
01086         return *this;
01087     }
01088 
01089     inline bool dbm_t::constrain(cindex_t i, int32_t value)
01090     {
01091         return !isEmpty() && ptr_constrain(i, value);
01092     }
01093     
01094     inline bool dbm_t::constrain(cindex_t i, cindex_t j, raw_t c)
01095     {
01096         return !isEmpty() && ptr_constrain(i, j, c);
01097     }
01098 
01099     inline bool dbm_t::constrain(cindex_t i, cindex_t j, int32_t b, strictness_t s)
01100     {
01101         return !isEmpty() && ptr_constrain(i, j, dbm_bound2raw(b,s));
01102     }
01103 
01104     inline bool dbm_t::constrain(cindex_t i, cindex_t j, int32_t b, bool isStrict)
01105     {
01106         return !isEmpty() && ptr_constrain(i, j, dbm_boundbool2raw(b,(BOOL)isStrict));
01107     }
01108 
01109     inline bool dbm_t::constrain(const constraint_t& c)
01110     {
01111         return !isEmpty() && ptr_constrain(c.i, c.j, c.value);
01112     }
01113 
01114     inline bool dbm_t::constrain(const constraint_t *cnstr, size_t n)
01115     {
01116         assert(cnstr);
01117         return !isEmpty() && (n == 1 ? ptr_constrain(cnstr->i, cnstr->j, cnstr->value) : ptr_constrain(cnstr, n));
01118     }
01119 
01120     inline bool dbm_t::constrain(const cindex_t *table, const constraint_t *cnstr, size_t n)
01121     {
01122         return !isEmpty() && ptr_constrain(table, cnstr, n);
01123     }
01124 
01125     inline bool dbm_t::constrain(const cindex_t *table, const base::pointer_t<constraint_t>& vec)
01126     {
01127         return !isEmpty() && ptr_constrain(table, vec.begin(), vec.size());
01128     }
01129 
01130     inline bool dbm_t::constrain(const cindex_t *table, const std::vector<constraint_t>& vec)
01131     {
01132         return !isEmpty() && constrain(table, &vec[0], vec.size());
01133     }
01134 
01135     inline dbm_t& dbm_t::up()
01136     {
01137         if (!isEmpty()) ptr_up();
01138         return *this;
01139     }
01140 
01141     inline dbm_t& dbm_t::down()
01142     {
01143         if (!isEmpty()) ptr_down();
01144         return *this;
01145     }
01146     
01147     inline dbm_t& dbm_t::freeClock(cindex_t k)
01148     {
01149         if (!isEmpty()) ptr_freeClock(k);
01150         return *this;
01151     }
01152 
01153     inline dbm_t& dbm_t::freeUp(cindex_t k)
01154     {
01155         if (!isEmpty()) ptr_freeUp(k);
01156         return *this;
01157     }
01158 
01159     inline dbm_t& dbm_t::freeDown(cindex_t k)
01160     {
01161         if (!isEmpty()) ptr_freeDown(k);
01162         return *this;
01163     }
01164 
01165     inline dbm_t& dbm_t::freeAllUp()
01166     {
01167         if (!isEmpty()) ptr_freeAllUp();
01168         return *this;
01169     }
01170 
01171     inline dbm_t& dbm_t::freeAllDown()
01172     {
01173         if (!isEmpty()) ptr_freeAllDown();
01174         return *this;
01175     }
01176 
01177     inline void dbm_t::updateValue(cindex_t k, int32_t v)
01178     {
01179         if (!isEmpty()) ptr_updateValue(k, v);
01180     }
01181 
01182     inline void dbm_t::updateClock(cindex_t i, cindex_t j)
01183     {
01184         if (i != j && !isEmpty()) ptr_updateClock(i, j);
01185     }
01186 
01187     inline void dbm_t::updateIncrement(cindex_t i, int32_t v)
01188     {
01189         // There is no point in even trying not to copy because the lower
01190         // bounds are always going to be incremented.
01191         if (v != 0 && !isEmpty()) dbm_updateIncrement(getCopy(), pdim(), i, v);
01192     }
01193 
01194     inline bool dbm_t::satisfies(cindex_t i, cindex_t j, raw_t c) const
01195     {
01196         assert(i < getDimension() && j < getDimension());
01197         return !isEmpty() && dbm_satisfies(const_dbm(), pdim(), i, j, c);
01198     }
01199     
01200     inline bool dbm_t::satisfies(const constraint_t& c) const
01201     {
01202         return satisfies(c.i, c.j, c.value);
01203     }
01204 
01205     inline bool dbm_t::operator && (const constraint_t& c) const
01206     {
01207         return satisfies(c);
01208     }
01209     
01210     inline bool dbm_t::isUnbounded() const
01211     {
01212         return !isEmpty() && dbm_isUnbounded(const_dbm(), pdim());
01213     }
01214 
01215     inline dbm_t& dbm_t::relaxUp()
01216     {
01217         return relaxDownClock(0);
01218     }
01219 
01220     inline dbm_t& dbm_t::relaxDown()
01221     {
01222         return relaxUpClock(0);
01223     }
01224 
01225     inline dbm_t& dbm_t::relaxUpClock(cindex_t k)
01226     {
01227         if (!isEmpty()) ptr_relaxUpClock(k);
01228         return *this;
01229     }
01230 
01231     inline dbm_t& dbm_t::relaxDownClock(cindex_t k)
01232     {
01233         if (!isEmpty()) ptr_relaxDownClock(k);
01234         return *this;
01235     }
01236 
01237     inline dbm_t& dbm_t::relaxAll()
01238     {
01239         if (!isEmpty()) ptr_relaxAll();
01240         return *this;
01241     }
01242 
01243     inline bool dbm_t::delay(const DoubleValuation& point, double* t) const
01244     {
01245         return delay(point.begin(), point.size(), t);
01246     }
01247 
01248     inline void dbm_t::swapClocks(cindex_t x, cindex_t y)
01249     {
01250         if (!isEmpty()) ptr_swapClocks(x, y);
01251     }
01252 
01253 #ifndef CHECK_COW_EXTRAPOLATION
01254     inline void dbm_t::extrapolateMaxBounds(const int32_t *max)
01255     {
01256         if (!isEmpty()) dbm_extrapolateMaxBounds(getCopy(), pdim(), max);
01257     }
01258 
01259     inline void dbm_t::diagonalExtrapolateMaxBounds(const int32_t *max)
01260     {
01261         if (!isEmpty()) dbm_diagonalExtrapolateMaxBounds(getCopy(), pdim(), max);
01262     }
01263 
01264     inline void dbm_t::extrapolateLUBounds(const int32_t *lower, const int32_t *upper)
01265     {
01266         if (!isEmpty()) dbm_extrapolateLUBounds(getCopy(), pdim(), lower, upper);
01267     }
01268 
01269     inline void dbm_t::diagonalExtrapolateLUBounds(const int32_t *lower, const int32_t *upper)
01270     {
01271         if (!isEmpty()) dbm_diagonalExtrapolateLUBounds(getCopy(), pdim(), lower, upper);
01272     }
01273 #else
01274     inline void dbm_t::extrapolateMaxBounds(const int32_t *max)
01275     {
01276         if (!isEmpty()) ptr_extrapolateMaxBounds(max);
01277     }
01278 
01279     inline void dbm_t::diagonalExtrapolateMaxBounds(const int32_t *max)
01280     {
01281         if (!isEmpty()) ptr_diagonalExtrapolateMaxBounds(max);
01282     }
01283 
01284     inline void dbm_t::extrapolateLUBounds(const int32_t *lower, const int32_t *upper)
01285     {
01286         if (!isEmpty()) ptr_extrapolateLUBounds(lower, upper);
01287     }
01288 
01289     inline void dbm_t::diagonalExtrapolateLUBounds(const int32_t *lower, const int32_t *upper)
01290     {
01291         if (!isEmpty()) ptr_diagonalExtrapolateLUBounds(lower, upper);
01292     }
01293 #endif
01294 
01295     inline dbm_t::dbm_t(const ClockOperation<dbm_t>& op)
01296     {
01297         idbmPtr = op.getPtr()->idbmPtr;
01298         incRef();
01299         updateIncrement(op.getClock(), op.getVal());
01300     }
01301 
01302     inline ClockOperation<dbm_t> dbm_t::operator () (cindex_t clk)
01303     {
01304         assert(clk < getDimension());
01305         return ClockOperation<dbm_t>(this, clk);
01306     }
01307 
01308     inline bool dbm_t::isSubtractionEmpty(const raw_t* arg, cindex_t dim) const
01309     {
01310         assert(getDimension() == dim);
01311         assertx(dbm_isValid(arg, dim));
01312         // this - arg == empty if all DBMs of this <= arg because arg is a DBM.
01313         return isEmpty() || (dbm_relation(const_dbm(), arg, dim) & base_SUBSET) != 0;
01314     }
01315 
01316     inline bool dbm_t::isSubtractionEmpty(const dbm_t& arg) const
01317     {
01318         assert(getDimension() == arg.getDimension());
01319         return *this <= arg;
01320     }
01321 
01322     inline void dbm_t::newCopy(const raw_t* arg, cindex_t dim)
01323     {
01324         assert(arg && dim > 0);
01325         assertx(dbm_isValid(arg, dim));
01326         dbm_copy(setNew(dim), arg, dim);
01327     }
01328 
01329     inline void dbm_t::newCopy(const dbm_t& arg)
01330     {
01331         arg.idbmPtr->incRef();
01332         setPtr(arg.idbmPtr);
01333     }
01334     
01335     inline void dbm_t::updateCopy(const raw_t* arg, cindex_t dim)
01336     {
01337         assert(arg && dim > 0);
01338         assertx(dbm_isValid(arg, dim));
01339         idbmt()->decRef();
01340         dbm_copy(setNew(dim), arg, dim);
01341     }
01342 
01343     inline void dbm_t::updateCopy(const dbm_t& arg)
01344     {
01345         arg.idbmPtr->incRef();
01346         idbmt()->decRef();
01347         setPtr(arg.idbmPtr);
01348     }
01349 
01350     inline const idbm_t* dbm_t::const_idbmt() const
01351     {
01352         assert(isPointer(idbmPtr)); // stronger than !isEmpty()
01353         return idbmPtr;
01354     }
01355 
01356     inline idbm_t* dbm_t::idbmt()
01357     {
01358         assert(isPointer(idbmPtr)); // stronger than !isEmpty()
01359         return idbmPtr;
01360     }
01361     
01362     inline uintptr_t dbm_t::uval() const
01363     {
01364         return (uintptr_t) idbmPtr;
01365     }
01366 
01367     inline void dbm_t::incRef() const
01368     {
01369         if (!isEmpty()) idbmPtr->incRef();
01370     }
01371 
01372     inline void dbm_t::decRef() const
01373     {
01374         if (!isEmpty()) idbmPtr->decRef();
01375     }
01376 
01377     inline void dbm_t::empty(cindex_t dim)
01378     {
01379         idbmt()->decRef();
01380         setEmpty(dim);
01381     }
01382 
01383     inline void dbm_t::emptyImmutable(cindex_t dim)
01384     {
01385         idbmt()->decRefImmutable();
01386         setEmpty(dim);
01387     }
01388 
01389     inline void dbm_t::emptyMutable(cindex_t dim)
01390     {
01391         idbmt()->removeMutable();
01392         setEmpty(dim);
01393     }
01394 
01395     inline void dbm_t::setEmpty(cindex_t dim)
01396     {
01397         idbmPtr = (idbm_t*) ((dim << 1) | 1);
01398     }
01399 
01400     inline void dbm_t::setPtr(idbm_t* ptr)
01401     {
01402         assert(isPointer(ptr));
01403         idbmPtr = ptr;
01404     }
01405 
01406     inline cindex_t dbm_t::edim() const
01407     {
01408         assert(isEmpty());
01409         return uval() >> 1;
01410     }
01411 
01412     inline cindex_t dbm_t::pdim() const
01413     {
01414         return const_idbmt()->getDimension();
01415     }
01416 
01417     inline bool dbm_t::isMutable() const
01418     {
01419         return const_idbmt()->isMutable();
01420     }
01421 
01422     inline bool dbm_t::tryMutable()
01423     {
01424         return idbmt()->tryMutable();
01425     }
01426 
01427     inline const raw_t* dbm_t::const_dbm() const
01428     {
01429         return const_idbmt()->const_dbm();
01430     }
01431     
01432     inline raw_t* dbm_t::dbm()
01433     {
01434         return idbmt()->dbm();
01435     }
01436 
01437     inline raw_t* dbm_t::setNew(cindex_t dim)
01438     {
01439         assert(dim);
01440         setPtr(new (dbm_new(dim)) idbm_t(dim));
01441         return dbm();
01442     }
01443 
01444     inline raw_t* dbm_t::inew(cindex_t dim)
01445     {
01446         assert(!tryMutable());
01447         idbmt()->decRefImmutable();
01448         return setNew(dim);
01449     }
01450 
01451     inline raw_t* dbm_t::icopy(cindex_t dim)
01452     {
01453         assert(!tryMutable() && pdim() == dim);
01454         idbmt()->decRefImmutable();
01455         setPtr(new (dbm_new(dim)) idbm_t(*idbmPtr));
01456         return dbm();
01457     }
01458 
01459     inline raw_t* dbm_t::getNew()
01460     {
01461         RECORD_STAT();
01462         RECORD_SUBSTAT(tryMutable() ? "mutable" : "new");
01463         return tryMutable() ? dbm() : inew(pdim());
01464     }
01465 
01466     inline raw_t* dbm_t::getCopy()
01467     {
01468         RECORD_STAT();
01469         RECORD_SUBSTAT(tryMutable() ? "mutable" : "copy");
01470         return tryMutable() ? dbm() : icopy(pdim());
01471     }
01472 
01473     // Wrapper functions
01474  
01475     inline dbm_t zero(cindex_t dim)                         { return dbm_t(dim).setZero();       }
01476     inline dbm_t init(cindex_t dim)                         { return dbm_t(dim).setInit();       }
01477     inline dbm_t up(const dbm_t& d)                        { return dbm_t(d).up();              }
01478     inline dbm_t down(const dbm_t& d)                      { return dbm_t(d).down();            }
01479     inline dbm_t freeClock(const dbm_t& d, cindex_t x)      { return dbm_t(d).freeClock(x);      }
01480     inline dbm_t freeUp(const dbm_t& d, cindex_t k)         { return dbm_t(d).freeUp(k);         }
01481     inline dbm_t freeDown(const dbm_t& d, cindex_t k)       { return dbm_t(d).freeDown(k);       }
01482     inline dbm_t freeAllUp(const dbm_t& d)                 { return dbm_t(d).freeAllUp();       }
01483     inline dbm_t freeAllDown(const dbm_t& d)               { return dbm_t(d).freeAllDown();     }
01484     inline dbm_t relaxUp(const dbm_t& d)                   { return dbm_t(d).relaxUp();         }
01485     inline dbm_t relaxDown(const dbm_t& d)                 { return dbm_t(d).relaxDown();       }
01486     inline dbm_t relaxUpClock(const dbm_t& d, cindex_t k)   { return dbm_t(d).relaxUpClock(k);   }
01487     inline dbm_t relaxDownClock(const dbm_t& d, cindex_t k) { return dbm_t(d).relaxDownClock(k); }
01488 
01489     /***********************************************
01490      *  Inlined implementations of fed_t::iterator *
01491      ***********************************************/
01492 
01493     inline fed_t::iterator::iterator()
01494         : fdbm(const_cast<fdbm_t**>(&ENDF)), ifed(NULL) {}
01495 
01496     inline fed_t::iterator::iterator(ifed_t *ifd)
01497         : fdbm(ifd->atHead()), ifed(ifd) {}
01498 
01499     inline dbm_t& fed_t::iterator::operator *() const
01500     {
01501         assert(fdbm && *fdbm);
01502         return (*fdbm)->dbmt();
01503     }
01504 
01505     inline dbm_t* fed_t::iterator::operator ->() const
01506     {
01507         assert(fdbm && *fdbm);
01508         return &(*fdbm)->dbmt();
01509     }
01510 
01511     inline raw_t* fed_t::iterator::operator () () const
01512     {
01513         assert(fdbm && *fdbm);
01514         return (*fdbm)->dbmt().getDBM();
01515     }
01516 
01517     inline raw_t fed_t::iterator::operator () (cindex_t i, cindex_t j) const
01518     {
01519         assert(fdbm && *fdbm);
01520         return (*fdbm)->dbmt()(i,j);
01521     }
01522 
01523     inline fed_t::iterator& fed_t::iterator::operator ++()
01524     {
01525         assert(fdbm && *fdbm);
01526         fdbm = (*fdbm)->getNextMutable();
01527         return *this;
01528     }
01529 
01530     inline bool fed_t::iterator::null() const
01531     {
01532         assert(fdbm);
01533         return *fdbm == NULL;
01534     }
01535 
01536     inline bool fed_t::iterator::hasNext() const
01537     {
01538         assert(fdbm);
01539         return (*fdbm)->getNext() != NULL;
01540     }
01541 
01542     inline bool fed_t::iterator::operator == (const iterator& arg) const
01543     {
01544         assert(fdbm && arg.fdbm);
01545         return *fdbm == *arg.fdbm; // don't check ifed
01546     }
01547 
01548     inline bool fed_t::iterator::operator != (const iterator& arg) const
01549     {
01550         return !(*this == arg);
01551     }
01552 
01553     inline void fed_t::iterator::remove()
01554     {
01555         assert(fdbm && *fdbm);
01556         *fdbm = (*fdbm)->removeAndNext();
01557         ifed->decSize();
01558     }
01559 
01560     inline void fed_t::iterator::removeEmpty()
01561     {
01562         assert(fdbm && *fdbm);
01563         *fdbm = (*fdbm)->removeEmptyAndNext();
01564         ifed->decSize();
01565     }
01566 
01567     inline fdbm_t* fed_t::iterator::extract()
01568     {
01569         assert(fdbm && *fdbm);
01570         fdbm_t *current = *fdbm;
01571         *fdbm = current->getNext();
01572         ifed->decSize();
01573         return current;
01574     }
01575 
01576     inline void fed_t::iterator::insert(fdbm_t* dbm)
01577     {
01578         assert(fdbm);
01579         dbm->setNext(*fdbm);
01580         *fdbm = dbm;
01581         ifed->incSize();
01582     }
01583     
01584     inline fed_t::iterator fed_t::beginMutable()
01585     {
01586         setMutable();
01587         return fed_t::iterator(ifed());
01588     }
01589 
01590     inline const fed_t::iterator fed_t::endMutable() const
01591     {
01592         return fed_t::iterator();
01593     }
01594 
01595     inline fed_t::iterator fed_t::erase(iterator& iter)
01596     {
01597         assert(hasSame(*iter));
01598         iter.remove();
01599         return iter;
01600     }
01601 
01602     /*****************************************************
01603      *  Inlined implementations of fed_t::const_iterator *
01604      *****************************************************/
01605 
01606     inline fed_t::const_iterator::const_iterator(const fdbm_t* fed)
01607         : fdbm(fed) {}
01608     inline fed_t::const_iterator::const_iterator(const fed_t& fed)
01609         : fdbm(fed.ifed()->const_head()) {}
01610     inline fed_t::const_iterator::const_iterator()
01611         : fdbm(NULL) {}
01612 
01613     inline const dbm_t& fed_t::const_iterator::operator *() const
01614     {
01615         assert(fdbm);
01616         return fdbm->const_dbmt();
01617     }
01618 
01619     inline const dbm_t* fed_t::const_iterator::operator ->() const
01620     {
01621         assert(fdbm);
01622         return &fdbm->const_dbmt();
01623     }
01624 
01625     inline const raw_t* fed_t::const_iterator::operator () () const
01626     {
01627         assert(fdbm);
01628         return fdbm->const_dbmt()();
01629     }
01630 
01631     inline raw_t fed_t::const_iterator::operator () (cindex_t i, cindex_t j) const
01632     {
01633         assert(fdbm);
01634         return fdbm->const_dbmt()(i,j);
01635     }
01636 
01637     inline fed_t::const_iterator& fed_t::const_iterator::operator ++()
01638     {
01639         assert(fdbm);
01640         fdbm = fdbm->getNext();
01641         return *this;
01642     }
01643 
01644     inline bool fed_t::const_iterator::null() const
01645     {
01646         return fdbm == NULL;
01647     }
01648 
01649     inline bool fed_t::const_iterator::hasNext() const
01650     {
01651         assert(fdbm);
01652         return fdbm->getNext() != NULL;
01653     }
01654 
01655     inline bool fed_t::const_iterator::operator == (const const_iterator& arg) const
01656     {
01657         return fdbm == arg.fdbm;
01658     }
01659 
01660     inline bool fed_t::const_iterator::operator != (const const_iterator& arg) const
01661     {
01662         return fdbm != arg.fdbm;
01663     }
01664 
01665     inline fed_t::const_iterator fed_t::begin() const
01666     {
01667         return fed_t::const_iterator(ifed()->const_head());
01668     }
01669 
01670     inline const fed_t::const_iterator fed_t::end() const
01671     {
01672         return fed_t::const_iterator::ENDI;
01673     }
01674 
01675     /***********************************
01676      * Inlined implementation of fed_t *
01677      ***********************************/
01678 
01679     inline fed_t::fed_t(cindex_t dim)
01680         : ifedPtr(ifed_t::create(dim))
01681     {
01682         assert(dim >= 1);
01683     }
01684 
01685     inline fed_t::fed_t(const fed_t& arg)
01686         : ifedPtr(arg.ifedPtr)
01687     {
01688         incRef();
01689     }
01690 
01691     inline fed_t::fed_t(ifed_t* ifed)
01692         : ifedPtr(ifed)
01693     {}
01694 
01695     inline fed_t::fed_t(const dbm_t& arg)
01696         : ifedPtr(arg.isEmpty()
01697                   ? ifed_t::create(arg.edim())
01698                   : ifed_t::create(arg))
01699     {}
01700 
01701     inline fed_t::fed_t(const raw_t* arg, cindex_t dim)
01702         : ifedPtr(ifed_t::create(arg, dim))
01703     {}
01704 
01705     inline fed_t::~fed_t()
01706     {
01707         decRef();
01708     }
01709 
01710     inline size_t fed_t::size() const
01711     {
01712         return ifed()->size();
01713     }
01714 
01715     inline cindex_t fed_t::getDimension() const
01716     {
01717         return ifed()->getDimension();
01718     }
01719 
01720     inline bool fed_t::isEmpty() const
01721     {
01722         return ifed()->isEmpty();
01723     }
01724 
01725     inline void fed_t::nil()
01726     {
01727         setDimension(1);
01728     }
01729 
01730     inline fed_t& fed_t::reduce()
01731     {
01732         assert(isOK());
01733         ifed()->reduce(getDimension());
01734         return *this;
01735     }
01736 
01737     inline fed_t& fed_t::mergeReduce()
01738     {
01739         assert(isOK());
01740         ifed()->mergeReduce(getDimension());
01741         return *this;
01742     }
01743 
01744     inline fed_t& fed_t::unionWithC(fed_t arg)
01745     {
01746         return unionWith(arg);
01747     }
01748 
01749     inline fed_t& fed_t::appendC(fed_t arg)
01750     {
01751         return append(arg);
01752     }
01753 
01754     inline uint32_t fed_t::hash(uint32_t seed) const
01755     {
01756         return ifed()->hash(seed);
01757     }
01758 
01759     inline bool fed_t::sameAs(const fed_t& arg) const
01760     {
01761         return ifedPtr == arg.ifedPtr;
01762     }
01763 
01764     inline fed_t& fed_t::operator = (const fed_t& arg)
01765     {
01766         arg.incRef();
01767         decRef();
01768         ifedPtr = arg.ifedPtr;
01769         return *this;
01770     }
01771 
01772     inline bool fed_t::operator == (const fed_t& arg) const
01773     {
01774         return relation(arg) == base_EQUAL;
01775     }
01776 
01777     inline bool fed_t::operator == (const dbm_t& arg) const
01778     {
01779         return relation(arg) == base_EQUAL;
01780     }
01781 
01782     inline bool fed_t::operator == (const raw_t* arg) const
01783     {
01784         return relation(arg, getDimension()) == base_EQUAL;
01785     }
01786 
01787     inline bool fed_t::operator != (const fed_t& arg) const
01788     {
01789         return !(*this == arg);
01790     }
01791 
01792     inline bool fed_t::operator != (const dbm_t& arg) const
01793     {
01794         return !(*this == arg);
01795     }
01796 
01797     inline bool fed_t::operator != (const raw_t* arg) const
01798     {
01799         return !(*this == arg);
01800     }
01801 
01802     inline bool fed_t::operator <  (const fed_t& arg) const
01803     {
01804         return relation(arg) == base_SUBSET;
01805     }
01806 
01807     inline bool fed_t::operator <  (const dbm_t& arg) const
01808     {
01809         return relation(arg) == base_SUBSET;
01810     }
01811 
01812     inline bool fed_t::operator <  (const raw_t* arg) const
01813     {
01814         return relation(arg, getDimension()) == base_SUBSET;
01815     }
01816 
01817     inline bool fed_t::operator >  (const fed_t& arg) const
01818     {
01819         return relation(arg) == base_SUPERSET;
01820     }
01821 
01822     inline bool fed_t::operator >  (const dbm_t& arg) const
01823     {
01824         return relation(arg) == base_SUPERSET;
01825     }
01826 
01827     inline bool fed_t::operator >  (const raw_t* arg) const
01828     {
01829         return relation(arg, getDimension()) == base_SUPERSET;
01830     }
01831 
01832     inline bool fed_t::operator <= (const fed_t& arg) const
01833     {
01834         return (relation(arg) & base_SUBSET) != 0;
01835     }
01836 
01837     inline bool fed_t::operator <= (const raw_t* arg) const
01838     {
01839         return le(arg, getDimension());
01840     }
01841 
01842     inline bool fed_t::operator >= (const fed_t& arg) const
01843     {
01844                return (relation(arg) & base_SUPERSET) != 0;
01845     }
01846 
01847     inline bool fed_t::operator >= (const raw_t* arg) const
01848     {
01849         return isSupersetEq(arg, getDimension());
01850     }
01851     
01852     inline bool fed_t::eq(const fed_t& arg) const
01853     {
01854         return exactRelation(arg) == base_EQUAL;
01855     }
01856 
01857     inline bool fed_t::eq(const dbm_t& arg) const
01858     {
01859         return exactRelation(arg) == base_EQUAL;
01860     }
01861 
01862     inline bool fed_t::eq(const raw_t* arg, cindex_t dim) const
01863     {
01864         return exactRelation(arg, dim) == base_EQUAL;
01865     }
01866 
01867     inline bool fed_t::lt(const fed_t& arg) const
01868     {
01869         return exactRelation(arg) == base_SUBSET;
01870     }
01871 
01872     inline bool fed_t::lt(const dbm_t& arg) const
01873     {
01874         return exactRelation(arg) == base_SUBSET;
01875     }
01876 
01877     inline bool fed_t::lt(const raw_t* arg, cindex_t dim) const
01878     {
01879         return exactRelation(arg, dim) == base_SUBSET;
01880     }
01881 
01882     inline bool fed_t::gt(const fed_t& arg) const
01883     {
01884         return exactRelation(arg) == base_SUPERSET;
01885     }
01886 
01887     inline bool fed_t::gt(const dbm_t& arg) const
01888     {
01889         return exactRelation(arg) == base_SUPERSET;
01890     }
01891 
01892     inline bool fed_t::gt(const raw_t* arg, cindex_t dim) const
01893     {
01894         return exactRelation(arg, dim) == base_SUPERSET;
01895     }
01896 
01897     inline bool fed_t::ge(const fed_t& arg) const
01898     {
01899         return arg.le(*this);
01900     }
01901 
01902     inline bool fed_t::ge(const dbm_t& arg) const
01903     {
01904         return arg.isSubtractionEmpty(*this);
01905     }   
01906 
01907     inline bool fed_t::ge(const raw_t* arg, cindex_t dim) const
01908     {
01909         return isSubtractionEmpty(arg, dim, *this);
01910     }
01911 
01912     inline bool fed_t::le(const fed_t& arg) const
01913     {
01914         return isSubtractionEmpty(arg);
01915     }
01916 
01917     inline bool fed_t::le(const dbm_t& arg) const
01918     {
01919         return *this <= arg; // only case exact
01920     }
01921 
01922     inline fed_t& fed_t::add(const fed_t& arg)
01923     {
01924         fed_t f(arg);
01925         return append(f);
01926     }
01927 
01928     inline fed_t& fed_t::add(const dbm_t& arg)
01929     {
01930         assert(isOK() && arg.getDimension() == getDimension());
01931         if (!arg.isEmpty())
01932         {
01933             ifed()->insert(arg);
01934         }
01935         return *this;
01936     }
01937 
01938     inline fed_t& fed_t::add(const raw_t* arg, cindex_t dim)
01939     {
01940         assert(isOK() && dim == getDimension());
01941         assertx(dbm_isValid(arg, dim));
01942         ifed()->insert(arg, dim);
01943         return *this;
01944     }
01945 
01946     inline fed_t& fed_t::operator &= (const constraint_t& c)
01947     {
01948         constrain(c.i, c.j, c.value);
01949         return *this;
01950     }
01951 
01952     inline fed_t& fed_t::operator &= (const base::pointer_t<constraint_t>& c)
01953     {
01954         constrain(c.begin(), c.size());
01955         return *this;
01956     }
01957 
01958     inline fed_t& fed_t::operator &= (const std::vector<constraint_t>& vec)
01959     {
01960         constrain(&vec[0], vec.size());
01961         return *this;
01962     }
01963 
01964     inline bool fed_t::constrain(cindex_t i, cindex_t j, int32_t b, strictness_t s)
01965     {
01966         return constrain(i, j, dbm_bound2raw(b, s));
01967     }
01968 
01969     inline bool fed_t::constrain(cindex_t i, cindex_t j, int32_t b, bool isStrict)
01970     {
01971         return constrain(i, j, dbm_boundbool2raw(b, (BOOL)isStrict));
01972     }
01973     
01974     inline bool fed_t::constrain(const constraint_t& c)
01975     {
01976         return constrain(c.i, c.j, c.value);
01977     }
01978 
01979     inline bool fed_t::satisfies(const constraint_t& c) const
01980     {
01981         return satisfies(c.i, c.j, c.value);
01982     }
01983 
01984     inline bool fed_t::operator && (const constraint_t& c) const
01985     {
01986         return satisfies(c.i, c.j, c.value);
01987     }
01988 
01989     inline fed_t& fed_t::relaxUp()
01990     {
01991         return relaxDownClock(0); // see dbm.h
01992     }
01993 
01994     inline fed_t& fed_t::relaxDown()
01995     {
01996         return relaxUpClock(0); // see dbm.h
01997     }
01998 
01999     inline bool fed_t::removeIncludedIn(const dbm_t& arg)
02000     {
02001         assert(isOK());
02002         assert(getDimension() == arg.getDimension());
02003         return !arg.isEmpty() && removeIncludedIn(arg.const_dbm(), getDimension());
02004     }
02005 
02006     inline bool fed_t::contains(const IntValuation& point) const
02007     {
02008         return contains(point.begin(), point.size());
02009     }
02010 
02011     inline bool fed_t::contains(const DoubleValuation& point) const
02012     {
02013         return contains(point.begin(), point.size());
02014     }
02015 
02016     inline double fed_t::possibleBackDelay(const DoubleValuation& point) const
02017     {
02018         return possibleBackDelay(point.begin(), point.size());
02019     }
02020 
02021     inline bool fed_t::delay(const DoubleValuation& point, double* t) const
02022     {
02023         return delay(point.begin(), point.size(), t);
02024     }
02025 
02026     inline fed_t::fed_t(const ClockOperation<fed_t>& op)
02027         : ifedPtr(op.getPtr()->ifed()->copy())
02028     {
02029         updateIncrement(op.getClock(), op.getVal());
02030     }
02031 
02032     inline ClockOperation<fed_t> fed_t::operator () (cindex_t clk)
02033     {
02034         assert(clk < getDimension());
02035         return ClockOperation<fed_t>(this, clk);
02036     }
02037 
02038     inline bool fed_t::isSubtractionEmpty(const dbm_t& arg) const
02039     {
02040         return *this <= arg; // only exact case with "normal" relation
02041     }
02042 
02043     inline ifed_t* fed_t::ifed()
02044     {
02045         assert(isPointer(ifedPtr));
02046         return ifedPtr;
02047     }
02048 
02049     inline const ifed_t* fed_t::ifed() const
02050     {
02051         assert(isPointer(ifedPtr));
02052         return ifedPtr;
02053     }
02054 
02055     inline void fed_t::incRef() const
02056     {
02057         assert(isPointer(ifedPtr));
02058         ifedPtr->incRef();
02059     }
02060 
02061     inline void fed_t::decRef() const
02062     {
02063         assert(isPointer(ifedPtr));
02064         ifedPtr->decRef();
02065     }
02066 
02067     inline void fed_t::decRefImmutable() const
02068     {
02069         assert(isPointer(ifedPtr));
02070         ifedPtr->decRefImmutable();
02071     }
02072 
02073     inline bool fed_t::isMutable() const
02074     {
02075         return ifed()->isMutable();
02076     }
02077 
02078     inline bool fed_t::isOK() const
02079     {
02080         return ifed()->isOK();
02081     }
02082 
02083     inline void fed_t::setMutable()
02084     {
02085         if (!isMutable())
02086         {
02087             decRefImmutable();
02088             ifedPtr = ifed()->copy();
02089         }
02090         assert(isMutable());
02091     }
02092 
02093     inline const dbm_t& fed_t::const_dbmt() const
02094     {
02095         assert(size());
02096         return ifed()->const_head()->const_dbmt();
02097     }
02098 
02099     inline dbm_t& fed_t::dbmt()
02100     {
02101         assert(size() == 1 && isMutable());
02102         return ifed()->head()->dbmt();
02103     }
02104 
02105     // Trivial wrappers
02106 
02107     inline fed_t up(const fed_t& arg)                               { return fed_t(arg).up();              }
02108     inline fed_t down(const fed_t& arg)                             { return fed_t(arg).down();            }
02109     inline fed_t freeClock(const fed_t& arg, cindex_t x)             { return fed_t(arg).freeClock(x);      }
02110     inline fed_t freeUp(const fed_t& arg, cindex_t x)                { return fed_t(arg).freeUp(x);         }
02111     inline fed_t freeDown(const fed_t& arg, cindex_t x)              { return fed_t(arg).freeDown(x);       }
02112     inline fed_t freeAllUp(const fed_t& arg)                        { return fed_t(arg).freeAllUp();       }
02113     inline fed_t freeAllDown(const fed_t& arg)                      { return fed_t(arg).freeAllDown();     }
02114     inline fed_t relaxUp(const fed_t& arg)                          { return fed_t(arg).relaxUp();         }
02115     inline fed_t relaxDown(const fed_t& arg)                        { return fed_t(arg).relaxDown();       }
02116     inline fed_t relaxUpClock(const fed_t& arg, cindex_t k)          { return fed_t(arg).relaxUpClock(k);   }
02117     inline fed_t relaxDownClock(const fed_t& arg, cindex_t k)        { return fed_t(arg).relaxDownClock(k); }
02118     inline fed_t reduce(const fed_t& arg)                           { return fed_t(arg).reduce();          }
02119     inline fed_t expensiveReduce(const fed_t& arg)                  { return fed_t(arg).expensiveReduce(); }
02120     inline fed_t predt(const fed_t& g, const fed_t& b)              { return fed_t(g).predt(b);            }
02121     inline fed_t predt(const fed_t& g, const dbm_t& b)              { return fed_t(g).predt(b);            }
02122     inline fed_t predt(const fed_t& g, const raw_t* b, cindex_t dim) { return fed_t(g).predt(b, dim);       }
02123     inline fed_t predt(const dbm_t& g, const fed_t& b)              { return fed_t(g).predt(b);            }
02124     inline fed_t predt(const dbm_t& g, const dbm_t& b)              { return fed_t(g).predt(b);            }
02125     inline fed_t predt(const dbm_t& g, const raw_t* b, cindex_t dim) { return fed_t(g).predt(b, dim);       }
02126     inline fed_t predt(const raw_t* g, cindex_t dim, const fed_t& b) { return fed_t(g, dim).predt(b);       }
02127     inline fed_t predt(const raw_t* g, cindex_t dim, const dbm_t& b) { return fed_t(g, dim).predt(b);       }
02128     inline fed_t predt(const raw_t* g, const raw_t* b, cindex_t dim) { return fed_t(g, dim).predt(b, dim);  }
02129     
02130     /************ Operator overload -- trivial implementations ************/    
02131     
02132     inline dbm_t operator + (const dbm_t& a, const raw_t* b) { return dbm_t(a) += b; }
02133     inline dbm_t operator + (const fed_t& a, const raw_t* b) { return dbm_t(b, a.getDimension()) += a; }
02134     inline dbm_t operator + (const dbm_t& a, const dbm_t& b) { return dbm_t(a) += b; }
02135     inline dbm_t operator + (const dbm_t& a, const fed_t& b) { return dbm_t(a) += b; }
02136     inline dbm_t operator + (const fed_t& a, const dbm_t& b) { return dbm_t(b) += a; }
02137     inline dbm_t operator + (const fed_t& a, const fed_t& b) { return (dbm_t(a.getDimension()) += a) += b; }
02138 
02139     inline dbm_t operator & (const dbm_t& a, const raw_t* b) { return dbm_t(a) &= b; }
02140     inline fed_t operator & (const fed_t& a, const raw_t* b) { return fed_t(a) &= b; }
02141     inline dbm_t operator & (const dbm_t& a, const dbm_t& b) { return dbm_t(a) &= b; }
02142     inline fed_t operator & (const dbm_t& a, const fed_t& b) { return fed_t(b) &= a; }
02143     inline fed_t operator & (const fed_t& a, const dbm_t& b) { return fed_t(a) &= b; }
02144     inline fed_t operator & (const fed_t& a, const fed_t& b) { return fed_t(a) &= b; }
02145 
02146     inline dbm_t operator & (const dbm_t& a, const constraint_t& c) { return dbm_t(a) &= c; }
02147     inline dbm_t operator & (const constraint_t& c, const dbm_t& a) { return dbm_t(a) &= c; }
02148     inline fed_t operator & (const fed_t& a, const constraint_t& c) { return fed_t(a) &= c; }
02149     inline fed_t operator & (const constraint_t& c, const fed_t& a) { return fed_t(a) &= c; }
02150 
02151     inline dbm_t operator & (const dbm_t& a, const base::pointer_t<constraint_t>& c) { return dbm_t(a) &= c; }
02152     inline dbm_t operator & (const base::pointer_t<constraint_t>& c, const dbm_t& a) { return dbm_t(a) &= c; }
02153     inline fed_t operator & (const fed_t& a, const base::pointer_t<constraint_t>& c) { return fed_t(a) &= c; }
02154     inline fed_t operator & (const base::pointer_t<constraint_t>& c, const fed_t& a) { return fed_t(a) &= c; }
02155 
02156     inline dbm_t operator & (const dbm_t& a, const std::vector<constraint_t>& vec) { return dbm_t(a) &= vec; }
02157     inline dbm_t operator & (const std::vector<constraint_t>& vec, const dbm_t& a) { return dbm_t(a) &= vec; }
02158     inline fed_t operator & (const fed_t& a, const std::vector<constraint_t>& vec) { return fed_t(a) &= vec; }
02159     inline fed_t operator & (const std::vector<constraint_t>& vec, const fed_t& a) { return fed_t(a) &= vec; }
02160 
02161     inline fed_t operator | (const dbm_t& a, const raw_t* b) { return fed_t(a) |= b; }
02162     inline fed_t operator | (const fed_t& a, const raw_t* b) { return fed_t(a) |= b; }
02163     inline fed_t operator | (const dbm_t& a, const dbm_t& b) { return fed_t(a) |= b; }
02164     inline fed_t operator | (const fed_t& a, const dbm_t& b) { return fed_t(a) |= b; }
02165     inline fed_t operator | (const dbm_t& a, const fed_t& b) { return fed_t(b) |= a; }
02166     inline fed_t operator | (const fed_t& a, const fed_t& b) { return fed_t(a) |= b; }
02167 
02168     inline fed_t operator - (const fed_t& a, const raw_t* b) { return fed_t(a) -= b; }
02169     inline fed_t operator - (const fed_t& a, const dbm_t& b) { return fed_t(a) -= b; }
02170     inline fed_t operator - (const dbm_t& a, const fed_t& b) { return fed_t(a) -= b; }
02171     inline fed_t operator - (const fed_t& a, const fed_t& b) { return fed_t(a) -= b; }
02172 
02173     // Wrappers
02174 
02175     inline fed_t operator - (const dbm_t& a, const dbm_t& b)
02176     {
02177         assert(a.getDimension() == b.getDimension());
02178 
02179         return b.isEmpty()
02180             ? fed_t(a)
02181             : fed_t::subtract(a, b.const_dbm(), b.pdim());
02182     }
02183 
02184     inline fed_t operator - (const dbm_t& a, const raw_t* b)
02185     {
02186         return fed_t::subtract(a, b, a.getDimension());
02187     }
02188 
02189 }

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