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

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 : fed.h
00005 //
00006 // C++ federation & DBMs
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: fed.h,v 1.37 2005/10/17 17:11:13 adavid Exp $
00013 //
00014 ///////////////////////////////////////////////////////////////////
00015 
00016 #ifndef INCLUDE_DBM_FED_H
00017 #define INCLUDE_DBM_FED_H
00018 
00019 #include <stdexcept>
00020 #include <vector>
00021 #include <string>
00022 #include "base/pointer.h"
00023 #include "base/Object.h"
00024 #include "dbm/dbm.h"
00025 #include "dbm/mingraph.h"
00026 #include "dbm/Valuation.h"
00027 
00028 /** @file
00029  * This API offers access to DBMs and federations
00030  * (of DBMs) through 2 classes: dbm_t and fed_t.
00031  * These classes hide memory management and reference
00032  * counting. Copy-on-write semantics is implemented.
00033  */
00034 namespace dbm
00035 {
00036     // Class to access clock names in an abstract way.
00037     class ClockAccessor : public base::Object
00038     {
00039     public:
00040         virtual ~ClockAccessor() {}
00041 
00042         /// @return the name of a given clock (index).
00043         /// The reference clock corresponds to index 0.
00044         virtual const std::string getClockName(cindex_t index) const = 0;
00045     };
00046 
00047     // internal classes
00048     class idbm_t;
00049     class ifed_t;
00050     class fdbm_t;
00051     class dbmlist_t;
00052 
00053     // public classes
00054     class dbm_t;
00055     class fed_t;
00056 
00057     /// Wrapper class for clock operations, @see dbm_t
00058     template<class TYPE>
00059     class ClockOperation
00060     {
00061     public:
00062         /// Clock increment and decrement.
00063         ClockOperation& operator + (int32_t val);
00064         ClockOperation& operator - (int32_t val);
00065         ClockOperation& operator += (int32_t val);
00066         ClockOperation& operator -= (int32_t val);
00067 
00068         /// Execute(update) clock (+value ignored) = clock + value.
00069         /// @pre this->dbm == op.dbm
00070         ClockOperation& operator = (const ClockOperation& op);
00071 
00072         /// Execute(updateValue) clock = value.
00073         ClockOperation& operator = (int32_t val);
00074 
00075         /// Check if clock constraints are satisfied.
00076         /// Semantics: does there exist a point such that it
00077         /// satisfies the constraint.
00078         /// @pre we are using the same dbm_t (or fed_t)
00079 
00080         bool operator <  (const ClockOperation& x) const;
00081         bool operator <= (const ClockOperation& x) const;
00082         bool operator >  (const ClockOperation& x) const;
00083         bool operator >= (const ClockOperation& x) const;
00084         bool operator == (const ClockOperation& x) const;
00085         bool operator <  (int32_t v) const;
00086         bool operator <= (int32_t v) const;
00087         bool operator >  (int32_t v) const;
00088         bool operator >= (int32_t v) const;
00089         bool operator == (int32_t v) const;
00090 
00091         /// The constructor should be used only by dbm_t or fed_t
00092         /// since ClockOperation is a convenience class.
00093         /// @param d: dbm that generated this clock operation.
00094         /// @param c: index of the clock to manipulate.
00095         /// @pre c < d->getDimension()
00096         ClockOperation(TYPE* d, cindex_t c);
00097             
00098         /// Access to the arguments of the operation.
00099         TYPE* getPtr()     const { return ptr; }
00100         cindex_t getClock() const { return clock; }
00101         int32_t getVal()   const { return incVal; }
00102 
00103     private:
00104         TYPE* ptr;      /// related dbm_t or fed_t, no reference count
00105         cindex_t clock;  /// clock to read/write
00106         int32_t incVal; /// increment value to apply
00107     };
00108 
00109 
00110     /***********************************************************************
00111      * dbm_t: DBM type. A DBM is basically a matrix of dimension >= 1,
00112      * ALWAYS >= 1.
00113      *
00114      * Special features:
00115      *
00116      * - sharing of DBMs (intern()): a cheap way to save memory
00117      *   for DBMs that are to be kept but not modified is to share
00118      *   identical DBMs (by using a hash table internally). Different
00119      *   dbm_t may point to the same idbm_t data. Another effect of
00120      *   this call is that if 2 dbm_t have had their intern() methods
00121      *   called, then test for equality is reduced to pointer testing,
00122      *   which is provided by the sameAs method.
00123      *
00124      * - direct access to the DBM matrix: read-only access is
00125      *   straight-forward (with the () operator). Read-write access
00126      *   (getDBM()) is more subtle because there may be no DBM allocated or
00127      *   the internal DBM may be shared with another dbm_t. Furthermore,
00128      *   the invariant of dbm_t is that it has a DBM matrix iff it is
00129      *   closed and non empty. Thus, when asking for a read-write
00130      *   direct access, we may need to allocate and copy internally.
00131      *   After the direct access, the invariant must also hold.
00132      *   Direct access must not be mixed with accessing the original
00133      *   dbm_t in case the matrix is deallocated for some reason.
00134      *
00135      * - relation with fed_t (the federation type): relation(xx) and
00136      *   the operators == != < > ... have the semantics of set inclusion
00137      *   check with DBMs pair-wise. These relations are exact when a
00138      *   dbm_t is compared with a dbm_t but are approximate when a dbm_t
00139      *   is compared with a fed_t, since the semantics is DBM inclusion
00140      *   check! We do not detect if a union of DBM is equal (semantically
00141      *   with respect to sets) to another DBM with the relation(xx) methods
00142      *   and < > <= .. operators. The (semantic) exact relation is provided
00143      *   by the exactRelation(xx) and le lt ge.. methods. The results from
00144      *   the approximate relations are safe, in the sense that EQUAL, SUBSET,
00145      *   and SUPERSET are reliable. However, DIFFERENT could be refined, we
00146      *   don't know. This is enough for most cases. The special case
00147      *   dbm_t >= fed_t is an exact comparison.
00148      *
00149      * - the closed form is maintained internally.
00150      *
00151      * - interaction with "raw matrices" is supported, ie, it is possible
00152      *   to use DBMs as arrays raw_t[dim*dim] where dim is the dimension
00153      *   of the DBMs. However, in these cases, it is assumed that these
00154      *   DBMs are valid, which is, dbm_isValid(dbm, dim) holds.
00155      *
00156      * - convenient operations:
00157      *   Assume you have declared dbm_t a,b;
00158      *   then you can write the following expressions:
00159      *   a(2) = a(3) + 3; is the clock update x2 = x3 + 3 for the DBM a
00160      *   a(1) = 0; is the clock update value (also called reset) x1 = 0
00161      *   a(1) += 3; is the clock increment x1 += 3
00162      *   b &= dbm_t(a(2) + 2); is the intersection of the result of
00163      *   x2 += 2 in for the DBM a and b (though a is not changed).
00164      *   if (a(2) < a(1) + 2) tests if the clock constraint x2 < x1 + 2 holds
00165      *   with respect to the DBM a.
00166      *   See the interface of ClockOperation.
00167      *   IMPORTANT: YOU ARE NOT SUPPOSED TO USE dbm_t::ClockOperation EXPLICITELY
00168      *   like declaring dbm_t::ClockOperation = .. and hack with it: this would
00169      *   give wrong results because of how + and - are implemented. This
00170      *   is kept simple here for efficiency and simplicity and
00171      *   let the compiler do its magic and optimize the final compiled
00172      *   inlined expressions!
00173      *
00174      ************************************************************************/
00175 
00176     class dbm_t
00177     {
00178         friend class fed_t;
00179         friend class dbmlist_t;
00180     public:
00181         // Define maximal dimension as a bit mask.
00182         // 2^15-1 means trouble anyway (2^15-1)^2 bytes per DBM!
00183         enum
00184         {
00185             MAX_DIM_POWER = 15,
00186             MAX_DIM = ((1 << MAX_DIM_POWER) - 1),
00187         };
00188 
00189         /// Initialize a dbm_t to empty DBM of a given dimension.
00190         /// @param dim: dimension of the DBM.
00191         /// @post isEmpty()
00192         explicit dbm_t(cindex_t dim = 1);
00193 
00194         /// Standard copy constructor.
00195         dbm_t(const dbm_t& arg);
00196 
00197         /// Copy constructor from a DBM matrix.
00198         /// @post isEmpty() iff dim == 0
00199         dbm_t(const raw_t* arg, cindex_t dim);
00200 
00201         ~dbm_t();
00202 
00203         /// @return the dimension of this DBM.
00204         cindex_t getDimension() const;
00205 
00206         /// @return string representation of the
00207         /// constraints of this DBM. A clock
00208         /// is always positive, so "true" simply means
00209         /// all clocks positive.
00210         std::string toString(const ClockAccessor&) const;
00211 
00212         /** Wrapper for dbm_getSizeOfMinDBM. Here for other compatibility reasons.
00213          * @pre dimension == getDimension()
00214          */
00215         static size_t getSizeOfMinDBM(cindex_t dim, mingraph_t);
00216         
00217         /** Construct a dbm_t from a mingraph_t. Not as a constructor
00218          * for other compatibility reasons.
00219          * @pre dimension == getDimension()
00220          */
00221         static dbm_t readFromMinDBM(cindex_t dim, mingraph_t);
00222 
00223         /// Change the dimension of this DBM.
00224         /// The resulting DBM is empty. @post isEmpty()
00225         void setDimension(cindex_t dim);
00226 
00227         /// @return true if it is empty.
00228         bool isEmpty() const;
00229 
00230         /// Empty this DBM.
00231         void setEmpty();
00232 
00233         /// Short for setDimension(1), has the effect of deallocating the DBM.
00234         void nil();
00235         
00236         /// @return true if this DBM contains the zero point.
00237         bool hasZero() const;
00238 
00239         /// @return a hash value.
00240         uint32_t hash(uint32_t seed = 0) const;
00241 
00242         /// @return true if arg has the same internal idbmPtr.
00243         bool sameAs(const dbm_t& arg) const;
00244 
00245         /// Try to share the DBM.
00246         void intern();
00247 
00248         /// Copy from a DBM.
00249         void copyFrom(const raw_t *src, cindex_t dim);
00250 
00251         /// Copy to a DBM.
00252         /// @pre dbm_isValid(dst, dim) and dim == getDimension()
00253         void copyTo(raw_t *dst, cindex_t dim) const;
00254         
00255         // Overload of operators () and []:
00256         // dbm_t::()    -> DBM matrix
00257         // dbm_t::(i)   -> Clock access for clock i
00258         // dbm_t::(i,j) -> read contraint DBM[i,j]
00259         // dbm_t::[i]   -> return matrix row i.
00260 
00261         /// @return read-only pointer to the internal DBM matrix.
00262         /// @post non null pointer iff !isEmpty()
00263         const raw_t* operator () () const;
00264         
00265         /// @return DBM[i,j]
00266         /// @pre !isEmpty() && i < getDimension() && j < getDimension() otherwise segfault.
00267         raw_t operator () (cindex_t i, cindex_t j) const;
00268 
00269         /// @return row DBM[i]
00270         /// @pre !isEmpty() && i < getDimension()
00271         const raw_t* operator [] (cindex_t i) const;
00272 
00273         /// @return a read-write access pointer to the internal DBM.
00274         /// @post return non null pointer iff getDimension() > 0
00275         raw_t* getDBM();
00276 
00277         /** Compute the minimal set of constraints to represent
00278          * this DBM.
00279          * @see dbm_analyzeForMinDBM.
00280          * @return the number of constraints of the set.
00281          * @pre bitMatrix is a uint32_t[bits2intsize(dim*dim)] and !isEmpty()
00282          */
00283         size_t analyzeForMinDBM(uint32_t *bitMatrix) const;
00284 
00285         /** Compute & save the minimal set of constraints.
00286          * @param tryConstraints16: flag to try to save
00287          * constraints on 16 bits, will cost dim*dim time.
00288          * @param c_alloc: C allocator wrapper
00289          * @param offset: offset for allocation.
00290          * @return allocated memory.
00291          * @pre !isEmpty().
00292          */
00293         int32_t* writeToMinDBMWithOffset(bool minimizeGraph,
00294                                          bool tryConstraints16,
00295                                          allocator_t c_alloc,
00296                                          size_t offset) const;
00297 
00298         /** Similar to writeToMinDBMWithOffset but works with
00299          * a pre-analyzed DBM.
00300          * @pre !isEmpty() and bitMatrix corresponds to its
00301          * analysis (otherwise nonsense will be written).
00302          * @see dbm_writeAnalyzedDBM.
00303          * @post bitMatrix is cleaned from the constraints xi>=0.
00304          */
00305         int32_t* writeAnalyzedDBM(uint32_t *bitMatrix,
00306                                   size_t nbConstraints,
00307                                   BOOL tryConstraints16,
00308                                   allocator_t c_alloc,
00309                                   size_t offset) const;
00310 
00311         /** Relation with a mingraph_t, @see dbm_relationWithMinDBM.
00312          * @pre unpackBuffer is a raw_t[dim*dim].
00313          */
00314         relation_t relation(mingraph_t ming, raw_t* unpackBuffer) const;
00315 
00316         /// Overload of standard operators.
00317         /// The raw_t* arguments are assumed to be matrices of the same
00318         /// dimension of this dbm_t (and dbm_isValid also holds).
00319 
00320         dbm_t& operator = (const dbm_t&);
00321         dbm_t& operator = (const raw_t*);
00322 
00323         /// Comparisons have the semantics of set inclusion.
00324         /// Equality of dimensions is checked.
00325         /// Comparisons agains fed_t are approximate and cheap
00326         /// since done between DBMs pair-wise. See the header.
00327 
00328         bool operator == (const dbm_t&) const;
00329         bool operator == (const fed_t&) const;
00330         bool operator == (const raw_t*) const;
00331         bool operator != (const dbm_t&) const;
00332         bool operator != (const fed_t&) const;
00333         bool operator != (const raw_t*) const;
00334         bool operator <  (const dbm_t&) const;
00335         bool operator <  (const fed_t&) const;
00336         bool operator <  (const raw_t*) const;
00337         bool operator >  (const dbm_t&) const;
00338         bool operator >  (const fed_t&) const;
00339         bool operator >  (const raw_t*) const;
00340         bool operator <= (const dbm_t&) const;
00341         bool operator <= (const fed_t&) const;
00342         bool operator <= (const raw_t*) const;
00343         bool operator >= (const dbm_t&) const;
00344         bool operator >= (const fed_t&) const; // exact
00345         bool operator >= (const raw_t*) const;
00346 
00347         /// Relation (wrt inclusion, approximate only for fed_t).
00348         /// @return this (relation) arg.
00349 
00350         relation_t relation(const dbm_t& arg) const;
00351         relation_t relation(const fed_t& arg) const;
00352         relation_t relation(const raw_t* arg, cindex_t dim) const;
00353 
00354         /// Exact (expensive) relations (for fed_t only).
00355 
00356         bool lt(const fed_t& arg) const; // this less than arg
00357         bool gt(const fed_t& arg) const; // this greater than arg
00358         bool le(const fed_t& arg) const; // this less (than) or equal arg
00359         bool ge(const fed_t& arg) const; // this greater (than) or equal arg
00360         bool eq(const fed_t& arg) const; // this equal arg
00361         relation_t exactRelation(const fed_t& arg) const;
00362 
00363         /// Set this zone to zero (origin).
00364         /// @param tau: tau clock, @see dbm.h
00365         /// @post !isEmpty() iff dim > 0.
00366         dbm_t& setZero();
00367 
00368         /// (re-)initialize the DBM with no constraint.
00369         /// @post !isEmpty() iff dim > 0.
00370         dbm_t& setInit();
00371 
00372         /// @return dbm_isEqualToInit(DBM), @see dbm.h
00373         bool isInit() const;
00374 
00375         /// @return dbm_isEqualToZero(DBM), @see dbm.h
00376         bool isZero() const;
00377 
00378         /** Computes the biggest lower cost in the zone.
00379          *  This corresponds to the value
00380          *  \f$\sup\{ c \mid \exists v \in Z : c =
00381          *  \inf \{ c' \mid v[cost\mapsto c'] \in Z \} \}\f$
00382          */
00383         int32_t getUpperMinimumCost(int32_t cost) const;
00384 
00385         /// Only for compatibility with priced DBMs.
00386         int32_t getInfimum() const { return 0; }
00387 
00388         /// Convex union operator (+).
00389         /// @pre same dimension.
00390 
00391         dbm_t& operator += (const dbm_t&);
00392         dbm_t& operator += (const fed_t&); // += argument.convexHull()
00393         dbm_t& operator += (const raw_t*);
00394 
00395         /// Intersection and constraint operator (&).
00396         /// @pre same dimension, compatible indices,
00397         /// and i != j for the constraints.
00398 
00399         dbm_t& operator &= (const dbm_t&);
00400         dbm_t& operator &= (const raw_t*);
00401         dbm_t& operator &= (const constraint_t&);
00402         dbm_t& operator &= (const base::pointer_t<constraint_t>&);
00403         dbm_t& operator &= (const std::vector<constraint_t>&);
00404 
00405         /** Methods for constraining: with one or more constraints.
00406          * Variants with @param table: indirection table for the indices.
00407          * - clock xi == value
00408          * - clocks xi-xj < cij or <= cij (constraint = c)
00409          * - clocks xi-xj < or <= b depending on strictness (strictness_t or bool).
00410          * - or several constraints at once.
00411          * @pre compatible indices, i != j for the constraints, and
00412          * table is an cindex_t[getDimension()]
00413          * @return !isEmpty()
00414          */
00415         bool constrain(cindex_t i, int32_t value);
00416         bool constrain(cindex_t i, cindex_t j, raw_t c);
00417         bool constrain(cindex_t i, cindex_t j, int32_t b, strictness_t s);
00418         bool constrain(cindex_t i, cindex_t j, int32_t b, bool isStrict);
00419         bool constrain(const constraint_t& c);
00420         bool constrain(const constraint_t *c, size_t n);
00421         bool constrain(const cindex_t *table, const constraint_t *c, size_t n);
00422         bool constrain(const cindex_t *table, const base::pointer_t<constraint_t>&);
00423         bool constrain(const cindex_t *table, const std::vector<constraint_t>&);
00424 
00425         /// @return false if there is no intersection with the argument
00426         /// or true if there *may* be an intersection.
00427         /// @pre same dimension.
00428 
00429         bool intersects(const dbm_t&) const;
00430         bool intersects(const fed_t&) const;
00431         bool intersects(const raw_t*, cindex_t dim) const; // dim here for safety check
00432 
00433         /// Delay (strongest post-condition). Remove upper bounds.
00434         /// @return this
00435         dbm_t& up();
00436 
00437         /// Inverse delay (weakest pre-condition). Remove lower bounds.
00438         /// @return this
00439         dbm_t& down();
00440 
00441         /// Free clock (unconstrain). Remove constraints on a particular
00442         /// clock, both upper and lower bounds.
00443         /// @return this. @post freeClock(c) == freeUp(c).freeDown(c)
00444         dbm_t& freeClock(cindex_t clock);
00445 
00446         /// Free upper or lower bounds only for a particular clock or
00447         /// for all clocks. @pre 0 < clock < getDimension()
00448         /// @return this. @see dbm.h
00449 
00450         dbm_t& freeUp(cindex_t clock);
00451         dbm_t& freeDown(cindex_t clock);
00452         dbm_t& freeAllUp();
00453         dbm_t& freeAllDown();
00454 
00455         /** Update methods where x & y are clocks, v an integer value.
00456          * x := v     -> updateValue
00457          * x := y     -> updateClock
00458          * x := x + v -> updateIncrement
00459          * x := y + v -> update
00460          * @pre 0 < x and y < getDimension(), v < infinity, and v is
00461          * s.t. the clocks stay positive.
00462          */
00463         void updateValue(cindex_t x, int32_t v);
00464         void updateClock(cindex_t x, cindex_t y);
00465         void updateIncrement(cindex_t x, int32_t v);
00466         void update(cindex_t x, cindex_t y, int32_t v);
00467 
00468         /// Check if the DBM satisfies a constraint c_ij.
00469         /// @pre i != j, i and j < getDimension()
00470 
00471         bool satisfies(cindex_t i, cindex_t j, raw_t c) const;
00472         bool satisfies(const constraint_t& c) const;
00473         bool operator && (const constraint_t& c) const;
00474 
00475         /// @return true if this DBM contains points that can delay arbitrarily.
00476         bool isUnbounded() const;
00477 
00478         /// Make upper or lower finite bounds non strict.
00479         /// @see dbm.h.
00480         /// @return this.
00481         dbm_t& relaxUp();
00482         dbm_t& relaxDown();
00483 
00484         /// Similar for all bounds of a particular clock.
00485         /// @see dbm.h. Special for clock == 0:
00486         /// relaxUp(0) = relaxDown() and relaxDown(0) = relaxUp().
00487         dbm_t& relaxUpClock(cindex_t clock);
00488         dbm_t& relaxDownClock(cindex_t clock);
00489 
00490         /// Make all constraints (except infinity) non strict.
00491         dbm_t& relaxAll();
00492 
00493         /// Test point inclusion.
00494         /// @pre same dimension.
00495 
00496         bool contains(const IntValuation& point) const;
00497         bool contains(const int32_t* point, cindex_t dim) const;
00498         bool contains(const DoubleValuation& point) const;
00499         bool contains(const double* point, cindex_t dim) const;
00500 
00501         /** Compute the 'almost min' necessary delay from
00502          * a point to enter this federation. If this point
00503          * is already contained in this federation, 0.0 is
00504          * returned. The result is 'almost min' since we
00505          * want a discrete value, which is not possible in
00506          * case of strict constraints.
00507          * @pre dim == getDimension() and point[0] == 0.0
00508          * otherwise the computation will not work.
00509          * @return true if it is possible to reach this DBM
00510          * by delaying, or false if this DBM is empty or it
00511          * is not possible to reach it by delaying.
00512          * The delay is written in t.
00513          */
00514         bool delay(const DoubleValuation& point, double* t) const;
00515         bool delay(const double* point, cindex_t dim, double* t) const;
00516 
00517         /// Extrapolations: @see dbm_##method functions in dbm.h.
00518         /// @pre max, lower, and upper are int32_t[getDimension()]
00519 
00520         void extrapolateMaxBounds(const int32_t *max);
00521         void diagonalExtrapolateMaxBounds(const int32_t *max);
00522         void extrapolateLUBounds(const int32_t *lower, const int32_t *upper);
00523         void diagonalExtrapolateLUBounds(const int32_t *lower, const int32_t *upper);
00524 
00525         /** Resize this DBM: bitSrc marks the subset of clocks (out from
00526          * a larger total set) that are in this DBM and bitDst marks the
00527          * subset of clocks we want to change to. Resizing means keep the
00528          * constraints of the clocks that are kept, remove the constraints
00529          * of the clocks that are removed, and add free constraints (infinity)
00530          * for the new clocks.
00531          * @see dbm_shrinkExpand in dbm.h.
00532          * @param bitSrc,bitDst,bitSize: bit strings of (int) size bitSize
00533          * that mark the source and destination active clocks.
00534          * @param table: redirection table to write.
00535          * @pre bitSrc & bitDst are uint32_t[bitSize] and
00536          * table is a uint32_t[32*bitSize]
00537          * @post the indirection table is written.
00538          */
00539         void resize(const uint32_t *bitSrc, const uint32_t *bitDst,
00540                     size_t bitSize, cindex_t *table);
00541 
00542         /** Resize and change clocks of this DBM.
00543          * The updated DBM will have its clocks i coming from target[i]
00544          * in the original DBM.
00545          * @param target is the table that says where to put the current
00546          * clocks in the target DBM. If target[i] = ~0 then a new free
00547          * clock is inserted.
00548          * @pre newDim > 0, target is a cindex_t[newDim], and
00549          * for all i < newDim, target[i] < getDimension().
00550          */
00551         void changeClocks(const cindex_t *target, cindex_t newDim);
00552 
00553         /// Swap clocks x and y.
00554         void swapClocks(cindex_t x, cindex_t y);
00555 
00556         /** Get a clock valuation and change only the clocks
00557          * that are marked free.
00558          * @param cval: clock valuation to write.
00559          * @param freeC: free clocks to write. If freeC = NULL then all
00560          * clocks are considered free.
00561          * @return cval
00562          * @throw std::out_of_range if the generation fails
00563          * if isEmpty() or cval too constrained.
00564          * @post if freeC != NULL, forall i < dim: freeC[i] = false
00565          */
00566         DoubleValuation& getValuation(DoubleValuation& cval, bool *freeC = NULL) const 
00567             throw(std::out_of_range);
00568         
00569         /// Special constructor to copy the result of a pending operation.
00570         /// @param op: clock operation.
00571         dbm_t(const ClockOperation<dbm_t>& op);
00572 
00573         /// @see ClockOperation for more details.
00574         /// @pre clk > 0 except for clock constraint tests
00575         /// and clk < getDimension()
00576         ClockOperation<dbm_t> operator () (cindex_t clk);
00577 
00578         /** @return (this-arg).isEmpty() but it is able to
00579          * stop the subtraction early if it is not empty and
00580          * it does not modify itself.
00581          * @pre same dimension.
00582          */
00583         bool isSubtractionEmpty(const raw_t* arg, cindex_t dim) const;
00584         bool isSubtractionEmpty(const fed_t& arg) const;
00585         bool isSubtractionEmpty(const dbm_t& arg) const;
00586 
00587         /************************
00588          * Low-level operations *
00589          ************************/
00590 
00591         /// Simplified copy with @pre isEmpty()
00592         void newCopy(const raw_t *arg, cindex_t dim);
00593 
00594         /// Simplified copy with @pre isEmpty() && !arg.isEmpty()
00595         void newCopy(const dbm_t& arg);
00596 
00597         /// Simplified copy with @pre !isEmpty()
00598         void updateCopy(const raw_t* arg, cindex_t dim);
00599 
00600         /// Simplified copy with @pre !isEmpty() && !arg.isEmpty()
00601         void updateCopy(const dbm_t& arg);
00602 
00603         /// Const access to its idbm_t, @pre !isEmpty()
00604         const idbm_t* const_idbmt() const;
00605 
00606         /// @return idbmPtr as a pointer @pre !isEmpty()
00607         idbm_t* idbmt();
00608 
00609         /// Explicit const access to the DBM matrix.
00610         /// Note: const_dbm() and dbm() have different assertions.
00611         /// @pre !isEmpty()
00612         const raw_t* const_dbm() const;
00613 
00614         /// Mutable access to the DBM matrix.
00615         /// @pre isMutable()
00616         raw_t* dbm();
00617 
00618         /// @return dimension with @pre isEmpty()
00619         cindex_t edim() const;
00620 
00621         /// @return dimension with @pre !isEmpty()
00622         cindex_t pdim() const;
00623         
00624         /// @return true if this fed_t can be modified, @pre isPointer()
00625         bool isMutable() const;
00626 
00627         /// Set and return a new writable DBM, @pre !isEmpty()
00628         raw_t* getNew();
00629 
00630         /// Set and return a writable copy of this DBM, @pre !isEmpty()
00631         raw_t* getCopy();
00632         
00633     private:
00634 
00635         /// @return idbmPtr as an int.
00636         uintptr_t uval() const;
00637 
00638         /// Wrapper for idbmPtr.
00639         void incRef() const;
00640 
00641         /// Wrapper for idbmPtr.
00642         void decRef() const;
00643 
00644         /// Specialized versions to remove idbmPtr and setEmpty(dim), @pre !isEmpty()
00645         void empty(cindex_t dim);
00646         void emptyImmutable(cindex_t dim);
00647         void emptyMutable(cindex_t dim);
00648 
00649         /// Set idbmPtr to empty with dimension dim.
00650         void setEmpty(cindex_t dim);
00651 
00652         /// Set a pointer for idbmPtr.
00653         void setPtr(idbm_t* ptr);
00654 
00655         /// Check and try to make idbmPtr mutable cheaply (eg if reference
00656         /// counter is equal to 1 and the DBM is in the hash, then it is cheap).
00657         /// @pre !isEmpty()
00658         bool tryMutable();
00659 
00660         /// Set idbmPtr to a newly allocated DBM with explicit dimension.
00661         /// @pre getDimension() > 0
00662         raw_t* setNew(cindex_t dim);
00663 
00664         /// Allocate new DBM and return the matrix.
00665         /// @pre !isEmpty() && !tryMutable()
00666         raw_t* inew(cindex_t dim);
00667 
00668         /// Copy its DBM and return the matrix.
00669         /// @pre !isEmpty() && !tryMutable()
00670         raw_t* icopy(cindex_t dim);
00671 
00672         /// Implementations of previous methods with @pre isPointer()
00673         /// useful for fed_t since the invariant states that there is
00674         /// no empty dbm_t in fed_t.
00675 
00676         void ptr_intern();
00677         dbm_t& ptr_convexUnion(const raw_t *arg, cindex_t dim);
00678         bool ptr_intersectionIsArg(const raw_t *arg, cindex_t dim);
00679         bool ptr_constrain(cindex_t i, cindex_t j, raw_t c); // pre i != j
00680         bool ptr_constrain(cindex_t k, int32_t value);  // pre k != 0
00681         bool ptr_constrain(const constraint_t *cnstr, size_t n);
00682         bool ptr_constrain(const cindex_t *table, const constraint_t *cnstr, size_t n);
00683         void ptr_up();
00684         void ptr_down();
00685         void ptr_freeClock(cindex_t k); // pre k != 0
00686         void ptr_updateValue(cindex_t i, int32_t v); // pre i != 0
00687         void ptr_updateClock(cindex_t i, cindex_t j); // pre i != j, i !=0, j != 0
00688         void ptr_update(cindex_t i, cindex_t j, int32_t v); // pre i != 0, j != 0
00689         void ptr_freeUp(cindex_t k); // pre k != 0
00690         void ptr_freeDown(cindex_t k); // pre k != 0
00691         void ptr_freeAllUp();
00692         void ptr_freeAllDown();
00693         void ptr_relaxDownClock(cindex_t k);
00694         void ptr_relaxUpClock(cindex_t k);
00695         void ptr_relaxAll();
00696         bool ptr_getValuation(DoubleValuation& cval, bool *freeC) const;
00697         void ptr_swapClocks(cindex_t x, cindex_t y);
00698 #ifdef CHECK_COW_EXTRAPOLATION
00699         void ptr_extrapolateMaxBounds(const int32_t *max);
00700         void ptr_diagonalExtrapolateMaxBounds(const int32_t *max);
00701         void ptr_extrapolateLUBounds(const int32_t *lower, const int32_t *upper);
00702         void ptr_diagonalExtrapolateLUBounds(const int32_t *lower, const int32_t *upper);
00703 #endif
00704 
00705         // Coding of dimPtr:
00706         // - if dbm_t is empty, idbmPtr = (dim << 1) | 1
00707         // - if dbm_t is not empty idbmPtr = pointer to idbm_t and (idbmPtr & 3) == 0
00708 
00709     /// Internal pointer or special coding for empty.
00710         idbm_t* idbmPtr;
00711     };
00712 
00713 
00714     /***************************************************************
00715      * fed_t: federation type.
00716      *
00717      * Special features:
00718      *
00719      * - direct reference transfer: similarly to dbm_t.
00720      *
00721      * - sharing of DBMs: this is a call-back for dbm_t.
00722      *
00723      * - raw_t* argument must satisfy dbm_isValid(..)
00724      *
00725      * - relations: see dbm_t, the exact relation operations (wrt
00726      *   set inclusion) are exactRelation and the methods le lt gt ge eq.
00727      *   Approximate relations are relation, < > <= >= == !=.
00728      *
00729      * - convenient operations: like dbm_t but for all the internal
00730      *   DBMs. This is a call-back for all the dbm_t that are in fed_t.
00731      *
00732      * - methods marked as dummy wrappers: these are for copy arguments.
00733      *   In the cases where the compiler wants a fed_t&, it
00734      *   won't be happy to find a fed_t, so we define a number of
00735      *   dummy wrappers to make it understand that the thing on the
00736      *   stack may be taken as a reference argument too.
00737      *
00738      ***************************************************************/
00739 
00740     class fed_t
00741     {
00742     public:
00743         /// Initialize a fed_t to empty federation of a given dimension.
00744         /// @param dim: dimension of the federation.
00745         /// @post isEmpty()
00746         explicit fed_t(cindex_t dim = 1);
00747 
00748         /// Standard copy constructor.
00749         fed_t(const fed_t& arg);
00750 
00751         /// Wrap a DBM in a federation.
00752         fed_t(const dbm_t& arg);
00753 
00754         /// Copy a DBM matrix in a federation.
00755         fed_t(const raw_t* arg, cindex_t dim);
00756 
00757         ~fed_t();
00758 
00759         /// @return the number of DBMs in this federation.
00760         size_t size() const;
00761 
00762         /// @return the dimension of this federation.
00763         cindex_t getDimension() const;
00764 
00765         /// Change the dimension of this federation.
00766         /// The resulting federation is empty. @post isEmpty()
00767         void setDimension(cindex_t dim);
00768 
00769         /// @return true if it is empty.
00770         bool isEmpty() const;
00771 
00772         /// Empty this federation.
00773         void setEmpty();
00774 
00775         /// Short for setDimension(1), has the effect of deallocating the DBMs.
00776         void nil();
00777         
00778         /// @return true if this DBM contains the zero point.
00779         bool hasZero() const;
00780 
00781         /// @return string representation of the
00782         /// constraints of this federation. A clock
00783         /// is always positive, so "true" simply means
00784         /// all clocks positive.
00785         std::string toString(const ClockAccessor&) const;
00786 
00787         /** Computes the biggest lower cost in the zone.
00788          *  This corresponds to the value
00789          *  \f$\sup\{ c \mid \exists v \in Z : c =
00790          *  \inf \{ c' \mid v[cost\mapsto c'] \in Z \} \}\f$
00791          */
00792         int32_t getUpperMinimumCost(int cost) const;
00793 
00794         /// Only for compatibility with priced federations.
00795         int32_t getInfimum() const { return 0; }
00796 
00797         /// @return a hash value that does not depend on the order of the DBMs
00798         /// but call reduce before to get a reliable value.
00799         uint32_t hash(uint32_t seed = 0) const;
00800 
00801         /// @return true if arg has the same internal ifedPtr.
00802         bool sameAs(const fed_t& arg) const;
00803 
00804         /// Try to share the DBMs. Side-effect: affects all copies of this fed_t.
00805         void intern();
00806 
00807         /// Overload of standard operators.
00808         /// The raw_t* arguments are assumed to be matrices of the same
00809         /// dimension of this dbm_t (and dbm_isValid also holds).
00810         
00811         fed_t& operator = (const fed_t&);
00812         fed_t& operator = (const dbm_t&);
00813         fed_t& operator = (const raw_t*);
00814 
00815         /// Comparisons have the semantics of set inclusion.
00816         /// Comparisons agains fed_t are approximate and cheap
00817         /// since done between DBMs pair-wise. See dbm_t.
00818         /// @pre same dimension for the operators < > <= >=, use
00819         /// relation if you don't know.
00820 
00821         bool operator == (const fed_t&) const;
00822         bool operator == (const dbm_t&) const;
00823         bool operator == (const raw_t*) const;
00824         bool operator != (const fed_t&) const;
00825         bool operator != (const dbm_t&) const;
00826         bool operator != (const raw_t*) const;
00827         bool operator <  (const fed_t&) const;
00828         bool operator <  (const dbm_t&) const;
00829         bool operator <  (const raw_t*) const;
00830         bool operator >  (const fed_t&) const;
00831         bool operator >  (const dbm_t&) const;
00832         bool operator >  (const raw_t*) const;
00833         bool operator <= (const fed_t&) const;
00834         bool operator <= (const dbm_t&) const; // exact
00835         bool operator <= (const raw_t*) const; // exact
00836         bool operator >= (const fed_t&) const;
00837         bool operator >= (const dbm_t&) const;
00838         bool operator >= (const raw_t*) const;
00839         
00840         /// Relation (wrt inclusion, approximate).
00841         /// @return this (relation) arg.
00842 
00843         relation_t relation(const fed_t& arg) const;
00844         relation_t relation(const dbm_t& arg) const;
00845         relation_t relation(const raw_t* arg, cindex_t dim) const;
00846 
00847         /// Specialized relation test: >= arg (approximate).
00848         bool isSupersetEq(const raw_t* arg, cindex_t dim) const;
00849 
00850         /// Exact (expensive) relations. See comments on dbm_t. eq: equal,
00851         /// lt: less than, gt: greater than, le: less or equal, ge: greater or equal.
00852         /// @pre same dimension for eq,lt,le,gt,ge
00853 
00854         bool eq(const fed_t& arg) const;
00855         bool eq(const dbm_t& arg) const;
00856         bool eq(const raw_t* arg, cindex_t dim) const;
00857         bool lt(const fed_t& arg) const;
00858         bool lt(const dbm_t& arg) const;
00859         bool lt(const raw_t* arg, cindex_t dim) const;
00860         bool gt(const fed_t& arg) const;
00861         bool gt(const dbm_t& arg) const;
00862         bool gt(const raw_t* arg, cindex_t dim) const;
00863         bool le(const fed_t& arg) const;
00864         bool le(const dbm_t& arg) const;
00865         bool le(const raw_t* arg, cindex_t dim) const;
00866         bool ge(const fed_t& arg) const;
00867         bool ge(const dbm_t& arg) const;
00868         bool ge(const raw_t* arg, cindex_t dim) const;
00869 
00870         relation_t exactRelation(const fed_t& arg) const;
00871         relation_t exactRelation(const dbm_t& arg) const;
00872         relation_t exactRelation(const raw_t* arg, cindex_t dim) const;
00873 
00874         /// Set this federation to zero (origin).
00875         /// @post size() == 1 if dim > 1, 0 otherwise.
00876         fed_t& setZero();
00877 
00878         /// (re-)initialize the federation with no constraint.
00879         /// @post size() == 1 if dim > 1, 0 otherwise.
00880         fed_t& setInit();
00881         
00882         /// Convex union of its DBMs.
00883         fed_t& convexHull();
00884         
00885         /// (Set) union operator (|). Inclusion is checked and the
00886         /// operation has the effect of reduce() on the argument.
00887         /// @pre same dimension.
00888         
00889         fed_t& operator |= (const fed_t&);
00890         fed_t& operator |= (const dbm_t&);
00891         fed_t& operator |= (const raw_t*);
00892 
00893         /// Union of 2 fed_t. @post arg.isEmpty()
00894         fed_t& unionWith(fed_t& arg);
00895         fed_t& unionWithC(fed_t arg); // dummy wrapper
00896 
00897         /// Simply add (list concatenation) DBMs to this federation.
00898         /// @pre same dimension.
00899 
00900         fed_t& add(const fed_t& arg);
00901         fed_t& add(const dbm_t& arg);
00902         fed_t& add(const raw_t* arg, cindex_t dim);
00903 
00904         /// Append arg to 'this', @post arg.isEmpty()
00905         fed_t& append(fed_t& arg);
00906         fed_t& appendC(fed_t arg); // dummy wrapper
00907         void append(fdbm_t* arg); // low level
00908 
00909         /// Convex union operator (+). Every DBM of the federation
00910         /// is unified with the argument. To get the convex hull of
00911         /// everything, call this->convexHull() += arg;
00912         /// @pre same dimension.
00913 
00914         fed_t& operator += (const fed_t&);
00915         fed_t& operator += (const dbm_t&);
00916         fed_t& operator += (const raw_t*);
00917 
00918         /// Intersection and constraint operator (&).
00919         /// @pre same dimension, compatible indices,
00920         /// and i != j for the constraints.
00921 
00922         fed_t& operator &= (const fed_t&);
00923         fed_t& operator &= (const dbm_t&);
00924         fed_t& operator &= (const raw_t*);
00925         fed_t& operator &= (const constraint_t&);
00926         fed_t& operator &= (const base::pointer_t<constraint_t>&);
00927         fed_t& operator &= (const std::vector<constraint_t>&);
00928 
00929         /// (Set) subtraction operator (-).
00930         /// @pre same dimension.
00931 
00932         fed_t& operator -= (const fed_t&);
00933         fed_t& operator -= (const dbm_t&);
00934         fed_t& operator -= (const raw_t*);
00935 
00936         /// Methods for constraining: with one or more constraints.
00937         /// Variants with @param table: indirection table for the indices.
00938         /// @pre compatible indices, i != j for the constraints, and
00939         /// table is an cindex_t[getDimension()]. @see dbm_t.
00940 
00941         bool constrain(cindex_t i, int32_t value);
00942         bool constrain(cindex_t i, cindex_t j, raw_t c);
00943         bool constrain(cindex_t i, cindex_t j, int32_t b, strictness_t s);
00944         bool constrain(cindex_t i, cindex_t j, int32_t b, bool isStrict);
00945         bool constrain(const constraint_t& c);
00946         bool constrain(const constraint_t *c, size_t n);
00947         bool constrain(const cindex_t *table, const constraint_t *c, size_t n);
00948         bool constrain(const cindex_t *table, const base::pointer_t<constraint_t>&);
00949         bool constrain(const cindex_t *table, const std::vector<constraint_t>&);
00950         
00951         /// @return false if there is no intersection with the argument
00952         /// or true if there *may* be an intersection.
00953         /// @pre same dimensions.
00954 
00955         bool intersects(const fed_t&) const;
00956         bool intersects(const dbm_t&) const;
00957         bool intersects(const raw_t*, cindex_t dim) const;
00958         
00959         /// Delay (strongest post-condition) for all the DBMs.
00960         fed_t& up();
00961 
00962         /// Inverse delay (weakest pre-condition) for all the DBMs.
00963         fed_t& down();
00964 
00965         /// Free clock (unconstraint) for all the DBMs.
00966         fed_t& freeClock(cindex_t clock);
00967 
00968         /// Free upper or lower bounds only for a particular clock or
00969         /// for all clocks. @pre 0 < clock < getDimension()
00970         /// @return this. @see dbm.h
00971 
00972         fed_t& freeUp(cindex_t clock);
00973         fed_t& freeDown(cindex_t clock);
00974         fed_t& freeAllUp();
00975         fed_t& freeAllDown();
00976 
00977         /// Update methods where x & y are clocks, v an integer value.
00978         /// x := v     -> updateValue
00979         /// x := y     -> updateClock
00980         /// x := x + v -> updateIncrement
00981         /// x := y + v -> update
00982         /// @pre 0 < x and y < getDimension(), v < infinity, and v is
00983         /// s.t. the clocks stay positive.
00984 
00985         void updateValue(cindex_t x, int32_t v);
00986         void updateClock(cindex_t x, cindex_t y);
00987         void updateIncrement(cindex_t x, int32_t v);
00988         void update(cindex_t x, cindex_t y, int32_t v);
00989         
00990         /// @return true if this federation satisfies a constraint c_ij.
00991         /// @pre i != j, i and j < getDimension()
00992         
00993         bool satisfies(cindex_t i, cindex_t j, raw_t c) const;
00994         bool satisfies(const constraint_t& c) const;
00995         bool operator && (const constraint_t& c) const;
00996 
00997         /// @return true if this federation has points that can delay infinitely.
00998         bool isUnbounded() const;
00999         
01000         /// Make upper or lower finite bounds non strict for all the DBMs.
01001         /// @see dbm.h.
01002         /// @return this.
01003         fed_t& relaxUp();
01004         fed_t& relaxDown();
01005 
01006         /// Similar for all bounds of a particular clock for all the DBMs.
01007         /// @see dbm.h. Special for clock == 0:
01008         /// relaxUp(0) = relaxDown() and relaxDown(0) = relaxUp().
01009         fed_t& relaxUpClock(cindex_t clock);
01010         fed_t& relaxDownClock(cindex_t clock);
01011 
01012         /// Make all constraints (except infinity) non strict for all the DBMs.
01013         fed_t& relaxAll();
01014 
01015         /// Remove redundant DBMs (if included in ONE other DBM).
01016         /// @post side effect: all copies of this fed_t are affected so
01017         /// do not mix iterators and reduce().
01018         /// @return this.
01019         fed_t& reduce();
01020 
01021         /// This method is useful only for experiments.
01022         fed_t& noReduce() { return *this; }
01023 
01024         /// Remove redundant DBMs (if included in the UNION of the other DBMs).
01025         /// @post same side effect as reduce().
01026         /// @return this.
01027         fed_t& expensiveReduce();
01028 
01029         /// Try to merge DBMs by pairs.
01030         /// @post same side effect as reduce().
01031         /// @return this.
01032         fed_t& mergeReduce();
01033 
01034         /// Use a heuristic to recompute parts of the federation as
01035         /// part=convexHull(part)-(convexHull(part)-part)
01036         /// @return this.
01037         fed_t& convexReduce();
01038 
01039         /// Try to replace this by convexHull(this)-(convexHull(this)-this)
01040         /// @return this.
01041         fed_t& expensiveConvexReduce();
01042 
01043         /// Find partitions in the federation and reduce them separately.
01044         /// @return this.
01045         fed_t& partitionReduce();
01046 
01047         /// @return true if a point (discrete or "real") is included
01048         /// in this federation (ie in one of its DBMs).
01049         /// @pre same dimension.
01050 
01051         bool contains(const IntValuation& point) const;
01052         bool contains(const int32_t* point, cindex_t dim) const;
01053         bool contains(const DoubleValuation& point) const;
01054         bool contains(const double* point, cindex_t dim) const;
01055 
01056         /** @return the 'almost max' possible delay backward from
01057          * a point while still staying inside the federation. It
01058          * is 'almost max' since we want a discrete value, which
01059          * cannot me the max when we have strict constraints.
01060          * The precision is 0.5. 0.0 may be returned if the point
01061          * is too close to a border.
01062          * @param point: the point to go backward from.
01063          * @pre dim = getDimension() && contains(point)
01064          */
01065         double possibleBackDelay(const DoubleValuation& point) const;
01066         double possibleBackDelay(const double* point, cindex_t dim) const;
01067 
01068         /** Compute the 'almost min' necessary delay from
01069          * a point to enter this federation. If this point
01070          * is already contained in this federation, 0.0 is
01071          * returned. The result is 'almost min' since we
01072          * want a discrete value, which is not possible in
01073          * case of strict constraints.
01074          * @pre dim == getDimension() and point[0] == 0.0
01075          * otherwise the computation will not work.
01076          * @return true if it is possible to reach this DBM
01077          * by delaying, or false if this DBM is empty or it
01078          * is not possible to reach it by delaying.
01079          * The delay is written in t.
01080          */
01081         bool delay(const DoubleValuation& point, double* t) const;
01082         bool delay(const double* point, cindex_t dim, double* t) const;
01083 
01084         /// Extrapolations: @see dbm_##method functions in dbm.h.
01085         /// @pre max, lower, and upper are int32_t[getDimension()]
01086 
01087         void extrapolateMaxBounds(const int32_t *max);
01088         void diagonalExtrapolateMaxBounds(const int32_t *max);
01089         void extrapolateLUBounds(const int32_t *lower, const int32_t *upper);
01090         void diagonalExtrapolateLUBounds(const int32_t *lower, const int32_t *upper);
01091         
01092         /** "Split-extrapolation". Split the DBMs with the diagonal
01093          * constraints given in argument, apply extrapolateMaxBounds
01094          * on the result, and make sure that the resulting DBMs are
01095          * still constrained by these diagonals.
01096          * @param begin .. end give the diagonal constraints for
01097          * splitting (from begin (inclusive) to end (exclusive)).
01098          * @param max is the array of maximal bounds.
01099          */
01100         void splitExtrapolate(const constraint_t *begin, const constraint_t *end,
01101                               const int32_t *max);
01102         
01103         /** Resize all the DBMs of this federation, @see dbm_t.
01104          * @see dbm_shrinkExpand in dbm.h.
01105          * @param bitSrc,bitDst,bitSize: bit strings of (int) size bitSize
01106          * that mark the source and destination active clocks.
01107          * @param table: redirection table to write.
01108          * @pre bitSrc & bitDst are uint32_t[bitSize] and
01109          * table is a uint32_t[32*bitSize]
01110          * @post the indirection table is written.
01111          */
01112         void resize(const uint32_t *bitSrc, const uint32_t *bitDst,
01113                     size_t bitSize, cindex_t *table);
01114 
01115         /** Resize and change clocks of all the DBMs of this federation.
01116          * The updated DBMs will have its clocks i coming from target[i]
01117          * in the original DBM.
01118          * @param target is the table that says where to put the current
01119          * clocks in the target DBMs. If target[i] = ~0 then a new free
01120          * clock is inserted.
01121          * @pre newDim > 0, target is a cindex_t[newDim], and
01122          * for all i < newDim, target[i] < getDimension().
01123          */
01124         void changeClocks(const cindex_t *target, cindex_t newDim);
01125 
01126         /// Swap clocks x and y.
01127         void swapClocks(cindex_t x, cindex_t y);
01128 
01129         /** Get a clock valuation and change only the clocks
01130          * that are marked free. The point will belong to one
01131          * DBM of this federation, it is unspecified which one.
01132          * @param cval: clock valuation to write.
01133          * @param freeC: free clocks to write, if freeC == NULL, then
01134          * all clocks are considered free.
01135          * @return cval
01136          * @throw std::out_of_range if the generation fails
01137          * if isEmpty() or cval too constrained.
01138          * @post if freeC != NULL, forall i < dim: freeC[i] = false
01139          * @pre same dimension.
01140          */
01141         DoubleValuation& getValuation(DoubleValuation& cval, bool *freeC = NULL) const 
01142             throw(std::out_of_range);
01143 
01144         /** predt operation: temporal predecessor of this federation
01145          * avoiding 'bad'.
01146          * @post the points in the resulting federation may delay
01147          * (and stay in the result) until they belong to this federation
01148          * without entering bad.
01149          * @pre same dimension.
01150          */
01151         fed_t& predt(const fed_t& bad);
01152         fed_t& predt(const dbm_t& bad);
01153         fed_t& predt(const raw_t* bad, cindex_t dim);
01154 
01155         /// @return true if this fed_t is included in predt(good,bad)
01156         /// This test may terminate earlier than calling le(predt(good,bad))
01157         /// because predt does not have to be computed in full sometimes.
01158         bool isIncludedInPredt(const fed_t& good, const fed_t& bad) const;
01159 
01160         /// Identify test to know if this federation has a specific DBM.
01161         /// If (dbm_t) arg is empty, then it is trivially true (if same dimension).
01162         bool has(const dbm_t& arg) const;
01163         bool has(const raw_t* arg, cindex_t dim) const;
01164 
01165         /// Similar but test with exact same dbm_t. Note: an empty federation
01166         /// is an empty list and an empty DBM is an empty zone. Both are
01167         /// compatible since they contain no point but empty_fed.hasSame(empty_dbm)
01168         /// will return false even if the dimensions are the same since an empty
01169         /// fed_t contains no dbm_t at all.
01170         bool hasSame(const dbm_t& arg) const;
01171 
01172         /** Remove the DBMs that are included in DBMs of arg (pair-wise
01173          * inclusion checking). WARNING: If sameAs(arg) then you will
01174          * empty this federation *and* the argument.
01175          * @pre same dimension.
01176          * @return !(arg <= *this) if arg is a dbm_t.
01177          */
01178         void removeIncludedIn(const fed_t& arg);
01179         bool removeIncludedIn(const dbm_t& arg);
01180         bool removeIncludedIn(const raw_t* arg, cindex_t dim);
01181         
01182         /// Special constructor to copy the result of a pending operation.
01183         /// @param op: clock operation.
01184         fed_t(const ClockOperation<fed_t>& op);
01185 
01186         /** Overload of operator (): () or (i,j) make no sense here.
01187          * fed_t::(i) -> clock access for clock i.
01188          * @see ClockOperation for more details.
01189          * @pre clk > 0 except for clock constraint tests
01190          * and clk < getDimension().
01191          */
01192         ClockOperation<fed_t> operator () (cindex_t clk);
01193 
01194         /** @return (this-arg).isEmpty() but it is able to
01195          * stop the subtraction early if it is not empty and
01196          * it does not modify itself.
01197          * @pre dbm_isValid(arg, dim) and dim == getDimension()
01198          */
01199         bool isSubtractionEmpty(const raw_t* arg, cindex_t dim) const;
01200         bool isSubtractionEmpty(const dbm_t& arg) const;
01201         bool isSubtractionEmpty(const fed_t& arg) const;
01202         static bool isSubtractionEmpty(const raw_t* dbm, cindex_t dim, const fed_t& fed);
01203 
01204         /// Subtract DBM arg1 - DBM arg2 wrapper function.
01205         static fed_t subtract(const raw_t* arg1, const raw_t* arg2, cindex_t dim);
01206         static fed_t subtract(const dbm_t& arg1, const raw_t* arg2, cindex_t dim);
01207 
01208         /** Clean-up the federation of its empty dbm_t.
01209          * Normally this is never needed except if the mutable
01210          * iterator is used and makes some dbm_t empty.
01211          */
01212         void removeEmpty();
01213 
01214         /** @return true if this fed_t has an empty dbm_t in its list.
01215          * Normally this should never occur, unless you play with dbm_t
01216          * manually with the iterator. This is used mainly for testing.
01217          */
01218         bool hasEmpty() const;
01219 
01220         /// Mutable iterator -> iterate though dbm_t
01221         class iterator
01222         {
01223         public:
01224             /// End of list.
01225             static const fdbm_t *ENDF;
01226 
01227             /// Special constructor to end iterations.
01228             iterator();
01229 
01230             /// Initialize the iterator of a federation.
01231             /// @param fed: federation.
01232             iterator(ifed_t* fed);
01233 
01234             /// Dereference to dbm_t, @pre !null()
01235             dbm_t& operator *() const;
01236 
01237             /// Dereference to dbm_t*, @pre !null()
01238             dbm_t* operator ->() const;
01239             
01240             /// Mutable access to the matrix as for fed_t, @pre !null()
01241             raw_t* operator () () const;
01242             raw_t operator () (cindex_t i, cindex_t j) const;
01243 
01244             /// Increment iterator, @pre !null()
01245             iterator& operator ++();
01246 
01247             /// Test if there are DBMs left on the list.
01248             bool null() const;
01249 
01250             /// @return true if there is another DBM after, @pre !null()
01251             bool hasNext() const;
01252 
01253             /// Equality test of the internal fdbm_t*
01254             bool operator == (const iterator& arg) const;
01255             bool operator != (const iterator& arg) const;
01256 
01257             /// Remove (and deallocate) current dbm_t.
01258             void remove();
01259 
01260             /// Remove (and deallocate) current empty dbm_t.
01261             void removeEmpty();
01262 
01263             /// Extract the current DBM from the list.
01264             /// The result->getNext() points to the rest of the list.
01265             fdbm_t* extract();
01266 
01267             /// Insert a DBM in the list at the current position.
01268             void insert(fdbm_t* dbm);
01269 
01270         private:
01271             fdbm_t **fdbm; /// list of DBMs
01272             ifed_t *ifed;  /// to update the size
01273         };
01274 
01275         /// Const iterator -> iterate though dbm_t
01276         class const_iterator
01277         {
01278         public:
01279             /// Const iterator for end of list.
01280             static const const_iterator ENDI;
01281             
01282             /// Constructor: @param fed: federation.
01283             const_iterator(const fdbm_t* fed);
01284             const_iterator(const fed_t& fed);
01285             const_iterator();
01286 
01287             /// Dereference to dbm_t
01288             const dbm_t& operator *() const;
01289 
01290             /// Dereference to dbm_t*, @pre !null()
01291             const dbm_t* operator ->() const;
01292 
01293             /// Access to the matrix as for fed_t
01294             const raw_t* operator () () const;
01295             raw_t operator () (cindex_t i, cindex_t j) const;
01296 
01297             /// Increment iterator, @pre !null()
01298             const_iterator& operator ++();
01299 
01300             /// Test if there are DBMs left on the list.
01301             bool null() const;
01302 
01303             /// @return true if there is another DBM after, @pre !null()
01304             bool hasNext() const;
01305 
01306             /// Equality test of the internal fdbm_t*
01307             bool operator == (const const_iterator& arg) const;
01308             bool operator != (const const_iterator& arg) const;
01309 
01310         private:
01311             const fdbm_t *fdbm; /// list of DBMs
01312         };
01313 
01314         /// Access to iterators. Limitation: you cannot modify the original
01315         /// fed_t object otherwise the iterator will be invalidated. In
01316         /// addition, you cannot copy the original either if the non const
01317         /// iterator is used.
01318 
01319         const_iterator begin() const;
01320         const const_iterator end() const;
01321         iterator beginMutable();
01322         const iterator endMutable() const;
01323 
01324         // Standard erase method for the iterator.
01325         iterator erase(iterator& iter);
01326 
01327         /** Dump its list of ifed_t and reload them. This is
01328          * useful for testing mainly but can be extended later
01329          * for saving or loading a fed_t.
01330          * @param mem: a ifed_t[size()]
01331          * @post isEmpty()
01332          * @return size()
01333          */
01334         size_t write(fdbm_t** mem);
01335 
01336         /** Symmetric: read.
01337          * @param fed,size: a ifed_t[size]
01338          * @post the ifed list is re-linked and belongs to this fed_t.
01339          */
01340         void read(fdbm_t** fed, size_t size);
01341 
01342         /// @return its first dbm_t, @pre size() > 0
01343         const dbm_t& const_dbmt() const;
01344 
01345         /// Remove a dbm_t from this fed_t. The match uses dbm_t::sameAs(..)
01346         /// @return true if arg was removed, false otherwise.
01347         bool removeThisDBM(const dbm_t &dbm);
01348 
01349         /// Ensure this ifed_t is mutable.
01350         void setMutable();
01351 
01352     private:
01353         // You are not supposed to read this part :)
01354 
01355         // Internal constructor.
01356         fed_t(ifed_t* ifed);
01357 
01358         /// @return ifedPtr with basic checks.
01359         ifed_t* ifed();
01360         const ifed_t* ifed() const;
01361 
01362         /// Call-backs to ifed_t.
01363         bool isMutable() const;
01364         bool isOK() const;
01365         void incRef() const;
01366         void decRef() const;
01367         void decRefImmutable() const;
01368 
01369         /// @return its dbm_t, @pre size() >= 1
01370         dbm_t& dbmt();
01371 
01372         /// Convert its linked list to an array.
01373         /// @pre ar is of size size()
01374         void toArray(const raw_t** ar) const;
01375 
01376         /// Internal subtraction implemention (*this - arg).
01377         /// @pre !isEmpty() && isMutable()
01378         void ptr_subtract(const raw_t* arg, cindex_t dim);
01379 
01380         /// Similarly with a DBM. @pre isPointer()
01381         relation_t ptr_relation(const raw_t* arg, cindex_t dim) const;
01382 
01383         ifed_t *ifedPtr;
01384     };
01385 
01386 
01387     /**********************************************
01388      * Operator overloads with const arguments.
01389      * + : convex union (result = always DBM)
01390      * & : intersection/constraining
01391      * | : set union
01392      * - : set subtraction
01393      * @pre same dimension for the arguments!
01394      * @see dbm_t and fed_t
01395      **********************************************/
01396     
01397     dbm_t operator + (const dbm_t& a, const raw_t* b);
01398     dbm_t operator + (const fed_t& a, const raw_t* b);
01399     dbm_t operator + (const dbm_t& a, const dbm_t& b);
01400     dbm_t operator + (const dbm_t& a, const fed_t& b);
01401     dbm_t operator + (const fed_t& a, const dbm_t& b);
01402     dbm_t operator + (const fed_t& a, const fed_t& b);
01403 
01404     dbm_t operator & (const dbm_t& a, const raw_t* b);
01405     fed_t operator & (const fed_t& a, const raw_t* b);
01406     dbm_t operator & (const dbm_t& a, const dbm_t& b);
01407     fed_t operator & (const dbm_t& a, const fed_t& b);
01408     fed_t operator & (const fed_t& a, const dbm_t& b);
01409     fed_t operator & (const fed_t& a, const fed_t& b);
01410 
01411     dbm_t operator & (const dbm_t& a, const constraint_t& c);
01412     dbm_t operator & (const constraint_t& c, const dbm_t& a);
01413     fed_t operator & (const fed_t& a, const constraint_t& c);
01414     fed_t operator & (const constraint_t& c, const fed_t& a);
01415 
01416     dbm_t operator & (const dbm_t& a, const base::pointer_t<constraint_t>& c);
01417     dbm_t operator & (const base::pointer_t<constraint_t>& c, const dbm_t& a);
01418     fed_t operator & (const fed_t& a, const base::pointer_t<constraint_t>& c);
01419     fed_t operator & (const base::pointer_t<constraint_t>& c, const fed_t& a);
01420 
01421     dbm_t operator & (const dbm_t& a, const std::vector<constraint_t>& vec);
01422     dbm_t operator & (const std::vector<constraint_t>& vec, const dbm_t& a);
01423     fed_t operator & (const fed_t& a, const std::vector<constraint_t>& vec);
01424     fed_t operator & (const std::vector<constraint_t>& vec, const fed_t& a);
01425 
01426     fed_t operator | (const dbm_t& a, const raw_t* b);
01427     fed_t operator | (const fed_t& a, const raw_t* b);
01428     fed_t operator | (const dbm_t& a, const dbm_t& b);
01429     fed_t operator | (const fed_t& a, const dbm_t& b);
01430     fed_t operator | (const dbm_t& a, const fed_t& b);
01431     fed_t operator | (const fed_t& a, const fed_t& b);
01432 
01433     fed_t operator - (const dbm_t& a, const raw_t* b);
01434     fed_t operator - (const fed_t& a, const raw_t* b);
01435     fed_t operator - (const dbm_t& a, const dbm_t& b);
01436     fed_t operator - (const fed_t& a, const dbm_t& b);
01437     fed_t operator - (const dbm_t& a, const fed_t& b);
01438     fed_t operator - (const fed_t& a, const fed_t& b);
01439 
01440     /// Create zero or init dbm_t with a given dimension.
01441 
01442     dbm_t zero(cindex_t dim);
01443     dbm_t init(cindex_t dim);
01444 
01445     /// Straight-forward wrapper functions:
01446     /// @return dbm_t(arg).function(other arguments)
01447 
01448     dbm_t up(const dbm_t& arg);
01449     dbm_t down(const dbm_t& arg);
01450     dbm_t freeClock(const dbm_t& arg, cindex_t clock);
01451     dbm_t freeUp(const dbm_t& arg, cindex_t k);
01452     dbm_t freeDown(const dbm_t& arg, cindex_t k);
01453     dbm_t freeAllUp(const dbm_t& arg);
01454     dbm_t freeAllDown(const dbm_t& arg);
01455     dbm_t relaxUp(const dbm_t& arg);
01456     dbm_t relaxDown(const dbm_t& arg);
01457     dbm_t relaxUpClock(const dbm_t& arg, cindex_t k);
01458     dbm_t relaxDownClock(const dbm_t& arg, cindex_t k);
01459 
01460     /// Straight-forward wrapper functions:
01461     /// @return fed_t(arg).function(other arguments)
01462 
01463     fed_t up(const fed_t& arg);
01464     fed_t down(const fed_t& arg);
01465     fed_t freeClock(const fed_t& arg, cindex_t x);
01466     fed_t freeUp(const fed_t& arg, cindex_t k);
01467     fed_t freeDown(const fed_t& arg, cindex_t x);
01468     fed_t freeAllUp(const fed_t& arg);
01469     fed_t freeAllDown(const fed_t& arg);
01470     fed_t relaxUp(const fed_t& arg);
01471     fed_t relaxDown(const fed_t& arg);
01472     fed_t relaxUpClock(const fed_t& arg, cindex_t k);
01473     fed_t relaxDownClock(const fed_t& arg, cindex_t k);
01474     fed_t reduce(const fed_t& arg);
01475     fed_t expensiveReduce(const fed_t& arg);
01476     fed_t predt(const fed_t& good, const fed_t& bad);
01477     fed_t predt(const fed_t& good, const dbm_t& bad);
01478     fed_t predt(const fed_t& good, const raw_t* bad, cindex_t dim);
01479     fed_t predt(const dbm_t& good, const fed_t& bad);
01480     fed_t predt(const dbm_t& good, const dbm_t& bad);
01481     fed_t predt(const dbm_t& good, const raw_t* bad, cindex_t dim);
01482     fed_t predt(const raw_t* good, cindex_t dim, const fed_t& bad);
01483     fed_t predt(const raw_t* good, cindex_t dim, const dbm_t& bad);
01484     fed_t predt(const raw_t* good, const raw_t* bad, cindex_t dim);
01485 
01486     /// Clean-up function useful for testing. Deallocate internally
01487     /// allocated DBMs that are currently free.
01488     void cleanUp();
01489 }
01490 
01491 #include "dbm/inline_fed.h"
01492 
01493 #endif // INCLUDE_DBM_FED_H

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