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

mingraph.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 : mingraph.h (dbm)
00005  *
00006  * Minimal graph representation, encoded with the cheapest format
00007  * possible.
00008  *
00009  * This file is a part of the UPPAAL toolkit.
00010  * Copyright (c) 1995 - 2003, Uppsala University and Aalborg University.
00011  * All right reserved.
00012  *
00013  * $Id: mingraph.h,v 1.22 2005/09/29 16:10:43 adavid Exp $
00014  *
00015  **********************************************************************/
00016 
00017 #ifndef INCLUDE_DBM_MINGRAPH_H
00018 #define INCLUDE_DBM_MINGRAPH_H
00019 
00020 #include "base/c_allocator.h"
00021 #include "base/intutils.h"
00022 #include "dbm/dbm.h"
00023 
00024 #ifdef __cplusplus
00025 extern "C" {
00026 #endif
00027 
00028 /*************************************************************************
00029  * For practical reasons we assume that DBM dimensions are
00030  * <= 2^16-1. This is large enough since the size needed is
00031  * dim*dim integers per DBM and for dim=2^16 we need 2^32 integers
00032  * for only 1 DBM, which go well beyond the addressable memory in 32 bits.
00033  *************************************************************************/
00034 
00035 
00036 /**
00037  * @file 
00038  *
00039  * Support for minimum graph representation.
00040  *
00041  * The minimal graph is represented internally by the cheapest format
00042  * possible, and in some cases it may even not be reduced. In addition
00043  * to this, the size of the minimal graph depends on the actual input
00044  * DBM, which makes the size of the allocated memory unpredictable
00045  * from the caller point of view.
00046  *
00047  *
00048  *
00049  * @section allocation How allocation works
00050  *
00051  * The idea is to have generic implementation that can be used with
00052  * standard allocation schemes (malloc, new) and with custom
00053  * allocators. This interface is in C to make it easy to wrap to other
00054  * languages so we use a generic function to allocate memory.  The
00055  * type of this function is 
00056  * \code 
00057  * int32_t* function(uint32_t size, void *data) 
00058  * \endcode 
00059  * where: 
00060  * - \a size is the size in \c int to allocate, and it returns a
00061  *   pointer to a \c int32_t[size]
00062  * - \a data is other custom data.
00063  *
00064  * Possible wrappers are:
00065  * - for a custom allocator Alloc:
00066  *   \code
00067  *   int32_t *alloc(uint32_t size, void *data) {
00068  *     return ((Alloc*)data)->alloc(size);
00069  *   }
00070  *   \endcode
00071  *   defined as base_allocate in base/DataAllocator.h
00072  * - for malloc:
00073  *   \code
00074  *   int32_t *alloc(uint32_t size, void *) {
00075  *     return (int32_t*) malloc(size*sizeof(int32_t));
00076  *   }
00077  *   \endcode
00078  *   defined as base_malloc in base/c_allocator.h
00079  * - for new:
00080  *   \code
00081  *   int32_t *alloc(uint32_t size, void *) {
00082  *     return new int32_t[size];
00083  *   }
00084  *   \endcode
00085  *   defined as base_new in base/DataAllocator.h
00086  *
00087  * The allocator function and the custom data are packed
00088  * together inside the allocator_t type.
00089  *
00090  * @see base/c_allocator.h
00091  * @see dbm_writeToMinDBMWithOffset()
00092  */
00093 
00094 
00095 /** Style typedef: to make the difference clear
00096  * between just allocated memory and the minimal
00097  * graph representation.
00098  */
00099 typedef const int32_t* mingraph_t;
00100 
00101 
00102 
00103 /** Save a DBM in minimal representation.
00104  *
00105  * The API supports allocation of larger data structures than needed
00106  * for the actual zone representation. When the \a offset argument is
00107  * bigger than zero, \a offset extra integers are allocated and the
00108  * zone is written with the given offset. Thus when \c
00109  * int32_t[data_size] is needed to represent the reduced zone, an \c
00110  * int32_t array of size \coffset+data_size\c is allocated. The
00111  * first \a offset elements can be used by the caller. It is important
00112  * to notice that the other functions typically expect a pointer to
00113  * the actual zone data and not to the beginning of the allocated
00114  * block. Thus in the following piece of code, most functions expect
00115  * \c mg and not \c memory:
00116  *
00117  * \code 
00118  * int32_t *memory = dbm_writeToMinDBMWithOffset(...);
00119  * mingraph_t mg = &memory[offset]; 
00120  * \endcode 
00121  * 
00122  * \b NOTES:
00123  * - if \a offset is 0 and \a dim is 1, NULL may be returned.
00124  *   NULL is valid as an input to the other functions.
00125  * - it could be possible to send as argument the maximal
00126  *   value of the constraints that can be deduced from
00127  *   the maximal constants but this would tie the algorithm
00128  *   to the extrapolation.
00129  *
00130  *
00131  * @param dbm: the DBM to save.
00132  * @param dim: its dimension.
00133  * @param minimizeGraph: activate minimized graph
00134  * reduction. If it is FALSE, then the DBM is copied
00135  * without its diagonal.
00136  * @param tryConstraints16: flag to try to save
00137  * constraints on 16 bits, will cost dim*dim time.
00138  * @param c_alloc: C allocator wrapper
00139  * @param offset: offset for allocation.
00140  * @return allocated memory.
00141  * @pre
00142  * - dbm is a raw_t[dim*dim]
00143  * - allocFunction allocates memory in integer units
00144  * - dbm is closed.
00145  * - dim > 0 (at least ref clock)
00146  * @post the returned memory is of size offset+something
00147  *  unknown from the caller point of view.
00148  */
00149 int32_t* dbm_writeToMinDBMWithOffset(const raw_t* dbm, cindex_t dim,
00150                                      BOOL minimizeGraph,
00151                                      BOOL tryConstraints16,
00152                                      allocator_t c_alloc,
00153                                      size_t offset);
00154 
00155 
00156 /** Save a pre-analyzed DBM in minimal representation.
00157  * @param dbm: the DBM to save.
00158  * @param dim: its dimension.
00159  * @param bitMatrix: bit matrix resulting from the
00160  * analysis (ie dbm_analyzeForMinDBM).
00161  * @param nbConstraints: number of constraints in the
00162  * bit matrix.
00163  * @param tryConstraints16: flag to try to save
00164  * constraints on 16 bits, will cost dim*dim time.
00165  * @param allocFunction: the allocation function.
00166  * @param offset: offset for allocation.
00167  * @return allocated memory.
00168  * @pre
00169  * - dbm is a raw_t[dim*dim]
00170  * - allocFunction allocates memory in integer units
00171  * - dbm is closed.
00172  * - dim > 0 (at least ref clock)
00173  * - bitMatrix != NULL, obtained from dbm_analyzeForMinDBM
00174  * - nbConstraints = number of bits set in bitMatrix
00175  * - bitMatrix is a uint32_t[bits2intsize(dim*dim)]
00176  * @post
00177  * - the returned memory is of size offset+something
00178  *   unknown from the caller point of view.
00179  * - bitMatrix is cleaned from the constraints xi >= 0
00180  */
00181 int32_t* dbm_writeAnalyzedDBM(const raw_t *dbm, cindex_t dim,
00182                               uint32_t *bitMatrix,
00183                               size_t nbConstraints,
00184                               BOOL tryConstraints16,
00185                               allocator_t c_alloc,
00186                               size_t offset);
00187 
00188 
00189 /** 
00190  * Analyze a DBM for its minimal graph representation. Computes the
00191  * smallest number of constraints needed to represent the same zone as
00192  * the full DBM in \a dbm. The result in returned in \a bitMatrix: If
00193  * the bit \f$ i \cdot dim + j\f$ is set, then the constraint
00194  * \f$(i,j)\f$ of \a dbm is needed.
00195  * @param dbm: DBM.
00196  * @param dim: dimension.
00197  * @param bitMatrix: bit matrix.
00198  * @return
00199  * - number of needed constraints to save
00200  * - bit matrix that marks which constraints belong to the minimal graph
00201  * @pre bitMatrix is a uint32_t[bits2intsize(dim*dim)]
00202  */
00203 size_t dbm_analyzeForMinDBM(const raw_t *dbm, cindex_t dim, uint32_t *bitMatrix);
00204 
00205 
00206 /**
00207  * This is a post-processing function for dbm_analyzeForMinDBM
00208  * to remove constraints of the form x>=0 that are part of the
00209  * minimal graph but that do not give much information.
00210  * @param dbm,dim: DBM of dimension dim
00211  * @param bitMatrix: bit matrix (already computed minimal graph)
00212  * @param nbConstraints: the number of constraints of the minimal graph.
00213  * @return the updated number of constraints of the modified minimal
00214  * graph where constraints x>=0 may have been removed.
00215  * @pre dbm_analyzeForMinDBM has been called before and nbConstraints
00216  * corresponds to the number of constraints of the minimal graph.
00217  */
00218 size_t dbm_cleanBitMatrix(const raw_t *dbm, cindex_t dim, uint32_t *bitMatrix, size_t nbConstraints);
00219 
00220 
00221 /**
00222  * Get back the minimal graph from the internal representation.
00223  * It might be the case that the minimal graph is recomputed if
00224  * the DBM was copied.
00225  * @param ming: internal representation of the minimal graph.
00226  * @param bitMatrix: bit matrix of the minimal graph to write.
00227  * @param isUnpacked: says if buffer contains the unpacked DBM already.
00228  * @param buffer: where to uncompress the full DBM if needed.
00229  * @return the number of constraints part of the minimal graph.
00230  * @pre let dim be the dimension of ming, bitMatrix is a uint32_t[bit2intsize(dim*dim)],
00231  * buffer is a raw_t[dim*dim], and if isUnpacked is true then buffer contains
00232  * the full DBM of ming.
00233  * @post if ming is the result of saving a given dbm A, then the resulting
00234  * bitMatrix is the same as the one given by dbm_analyzeForMinDBM(A,dim,bitMatrix)
00235  * + buffer always contains the unpacked mingraph.
00236  */
00237 size_t dbm_getBitMatrixFromMinDBM(uint32_t *bitMatrix, mingraph_t ming,
00238                                   BOOL isUnpacked, raw_t *buffer);
00239 
00240 
00241 /**
00242  * Convert a bit matrix marking constraints to an array of indices.
00243  * Encoding: i[k] = (index[k] & 0xffff) and j[k] = (index[k] >> 16)
00244  * @param bitMatrix: the bit matrix to convert.
00245  * @param nbConstraints: number of set bit in the matrix.
00246  * @param index: the index array to write.
00247  * @param dim: dimension of the bit matrix.
00248  * @pre index is a indexij_t[dim*(dim-1)] and bits on the
00249  * diagonal are not marked, nbConstraints <= dim*(dim-1).
00250  */
00251 void dbm_bitMatrix2indices(const uint32_t *bitMatrix, size_t nbConstraints,
00252                            uint32_t *index, cindex_t dim);
00253 
00254 
00255 /** Read a DBM from its minimal DBM representation.
00256  * @param dbm: where to write.
00257  * @param minDBM: the minimal representation to read from.
00258  * @pre
00259  * - dbm is a raw_t[dim*dim] where dim = dbm_getDimOfMinDBM(minDBM)
00260  * - minDBM points to the data of the minDBM directly. There is no
00261  *   offset.
00262  * @return dimension of DBM and unpacked DBM in dbm.
00263  */
00264 cindex_t dbm_readFromMinDBM(raw_t *dbm, mingraph_t minDBM);
00265 
00266 
00267 /** Dimension of a DBM from its packed minimal representation.
00268  * @param minDBM: the minimal DBM data directly, without offset.
00269  * @return dimension of DBM.
00270  */
00271 cindex_t dbm_getDimOfMinDBM(mingraph_t minDBM);
00272 
00273 
00274 /** Size of the representation of the MinDBM.
00275  * This is the size of the allocated memory (without offset) for the
00276  * minimal representation. It is at most dim*(dim-1)+1 because in the
00277  * worst case the DBM is copied without its diagonal and we need one
00278  * integer to store the size.
00279  * @param minDBM: minimal DBM representation (without offset).
00280  * @return size in int32_t allocated for the representation.
00281  * NOTE: the write function allocates exactly
00282  * int32_t[offset+dbm_getSizeOfMinDBM(minDBM)]
00283  */
00284 size_t dbm_getSizeOfMinDBM(mingraph_t minDBM);
00285 
00286 
00287 /** Equality test with a full DBM.
00288  * Unfortunately, this may be expensive (dim^3) if the
00289  * minimal graph format is used.
00290  * @param dbm: full DBM.
00291  * @param dim: dimension of dbm.
00292  * @param minDBM: minimal DBM representation (without offset).
00293  * @pre dbm is a raw_t[dim*dim] and dim > 0 (at least ref clock)
00294  * @return TRUE if the DBMs are the same, FALSE otherwise.
00295  */
00296 BOOL dbm_isEqualToMinDBM(const raw_t *dbm, cindex_t dim, mingraph_t minDBM);
00297 
00298 
00299 /** Equality test between 2 minimal graphs (saved
00300  * with the same function and flags).
00301  * @param mg1,mg2: minimal graph arguments.
00302  * @return TRUE if the graphs are the same, provided
00303  * they were saved with the same flags, FALSE otherwise.
00304  */
00305 static inline
00306 BOOL dbm_areMinDBMVerbatimEqual(mingraph_t mg1, mingraph_t mg2)
00307 {
00308     assert(mg1 && mg2); /* mingraph_t == const int* */
00309     return (BOOL)
00310         (*mg1 == *mg2 && base_areEqual(mg1+1, mg2+1, dbm_getSizeOfMinDBM(mg1)-1));
00311 }
00312 
00313 
00314 /** Equality test with a full DBM.
00315  * This variant of the equality test may be used if the
00316  * DBM has already been analyzed or if you need to reuse
00317  * the result of the analysis.
00318  * @param dbm: full DBM.
00319  * @param dim: dimension of dbm.
00320  * @param bitMatrix: bit matrix resulting from the analysis
00321  * of dbm (dbm_analyzeforMinDBM).
00322  * @param nbConstraints: number of constraints marked in
00323  * the bit matrix = number of bits set.
00324  * @param minDBM: minimal DBM representation (without offset).
00325  * @pre
00326  * - dbm is a raw_t[dim*dim] and dim > 0 (at least ref clock)
00327  * - bitMatrix is a uint32_t[bits2intsize(dim*dim)]
00328  * @return TRUE if the DBMs are the same, FALSE otherwise.
00329  * @post the bitMatrix may have the bits for the constraints on
00330  * the 1st row cleaned and nbConstraints will be updated accordingly.
00331  */
00332 BOOL dbm_isAnalyzedDBMEqualToMinDBM(const raw_t *dbm, cindex_t dim,
00333                                     uint32_t *bitMatrix,
00334                                     size_t *nbConstraints,
00335                                     mingraph_t minDBM);
00336 
00337 
00338 /** Another variant for equality checking:
00339  * this one may unpack the minimal graph if needed.
00340  * It needs a buffer as an input to do so.
00341  * @param dbm, dim: full DBM of dimension dim.
00342  * @param minDBM: minimal DBM representation (without offset).
00343  * @param buffer: buffer to unpack the DBM if needed
00344  * @pre
00345  * - dbm is a raw_t[dim*dim] and dim > 0 (at leat ref clock)
00346  * - buffer != NULL is a raw_t[dim*dim]
00347  * @post
00348  * - buffer may be written or not. If you want to know
00349  *   it, you can set buffer[0] = 0, and test afterwards
00350  *   if buffer[0] == 0. If mingraph is unpacked then it
00351  *   is guaranteed that buffer[0] == dbm_LE_ZERO, otherwise
00352  *   buffer is untouched.
00353  * @return TRUE if the DBMs are the same, FALSE otherwise.
00354  */
00355 BOOL dbm_isUnpackedEqualToMinDBM(const raw_t *dbm, cindex_t dim,
00356                                  mingraph_t minDBM, raw_t *buffer);
00357 
00358 
00359 /** Relation between a full DBM and a minimal representation
00360  * DBM. The relation may be exact or not:
00361  * if the relation is exact then
00362  *   dbm_EQUAL is returned if dbm == minDBM
00363  *   dbm_SUBSET is returned if dbm < minDBM
00364  *   dbm_SUPERSET is returned if dbm > minDBM
00365  *   dbm_DIFFERENT is returned if dbm not comparable with minDBM
00366  * else
00367  *   dbm_SUBSET is returned if dbm <= minDBM
00368  *   dbm_DIFFERENT otherwise
00369  *
00370  * @param dbm: full DBM to test.
00371  * @param dim: its dimension.
00372  * @param minDBM: minimal DBM representation.
00373  * @param unpackBuffer: memory space to unpack.
00374  *  if unpackBuffer == NULL then the relation is not exact
00375  *  if unpackBuffer != NULL then assume that buffer = raw_t[dim*dim]
00376  *  to be able to unpack the DBM and compute an exact relation.
00377  *
00378  * NOTE: unpackBuffer is sent as an argument to avoid stackoverflow
00379  * if using stack allocation. The needed size is in dim*dim*sizeof(int).
00380  * It is NOT guaranteed that unpackBuffer will be written. The dbm
00381  * MAY be unpacked only if relation != subset and unpackBuffer != NULL.
00382  *
00383  * @pre
00384  * - dbm is closed and not empty
00385  * - dbm is a raw_t[dim*dim] (full DBM)
00386  * - dim > 0 (at least ref clock)
00387  * @return relation as described above.
00388  */
00389 relation_t dbm_relationWithMinDBM(const raw_t *dbm, cindex_t dim,
00390                                   mingraph_t minDBM, raw_t *unpackBuffer);
00391 
00392 
00393 /** Variant of the previous relation function.
00394  * This may be cheaper if what count is to know
00395  * (subset or equal) or different or superset.
00396  * if unpackBuffer != NULL then
00397  *   dbm_EQUAL or dbm_SUBSET is returned if dbm == minDBM
00398  *   dbm_SUBSET is returned if dbm < minDBM
00399  *   dbm_SUPERSET is returned if dbm > minDBM
00400  *   dbm_DIFFERENT is returned if dbm not comparable with minDBM
00401  * else
00402  *   dbm_SUBSET is returned if dbm <= minDBM
00403  *   dbm_DIFFERENT is returned otherwise
00404  *
00405  * @param dbm: full DBM to test.
00406  * @param dim: its dimension.
00407  * @param minDBM: minimal DBM representation.
00408  * @param unpackBuffer: memory space to unpack.
00409  *  if unpackBuffer == NULL then the relation is not exact
00410  *  if unpackBuffer != NULL then assume that buffer = raw_t[dim*dim]
00411  *  to be able to unpack the DBM and compute an exact relation.
00412  * @pre
00413  * - dbm is closed and not empty
00414  * - dbm is a raw_t[dim*dim] (full DBM)
00415  * - dim > 0 (at least ref clock)
00416  * @return relation as described above.
00417  */
00418 relation_t dbm_approxRelationWithMinDBM(const raw_t *dbm, cindex_t dim,
00419                                         mingraph_t minDBM, raw_t *unpackBuffer);
00420 
00421 
00422 /** Convex union.
00423  * This may cost dim^3 in time since the minimal DBM has
00424  * to be unpacked to a full DBM.
00425  * Computes dbm = dbm + minDBM
00426  * @param dbm: dbm to make the union with.
00427  * @param dim: its dimension.
00428  * @param minDBM: minDBM to add to dbm (without offset).
00429  * @param unpackBuffer: memory space to unpack the DBM.
00430  * @pre
00431  * - dbm is a raw_t[dim*dim] and dim > 0 (at least ref clock).
00432  * - DBMs have the same dimensions
00433  * - unpackBuffer != NULL and is a raw_t[dim*dim]
00434  */
00435 void dbm_convexUnionWithMinDBM(raw_t *dbm, cindex_t dim,
00436                                mingraph_t minDBM, raw_t *unpackBuffer);
00437 
00438 
00439 /** Simple type to allow for statistics on the different internal
00440  * formats used. The format are not user controllable and should
00441  * not be read from outside. For the tuple representation, it is
00442  * not said here if it is (i,j,c_ij) or a bunch of c_ij and (i,j).
00443  */
00444 typedef enum
00445 {
00446     dbm_MINDBM_TRIVIAL = 0,  /**< only clock ref, dim == 1           */
00447     dbm_MINDBM_COPY32,       /**< 32 bits, dbm copy without diagonal */
00448     dbm_MINDBM_BITMATRIX32,  /**< 32 bits, c_ij and a bit matrix     */
00449     dbm_MINDBM_TUPLES32,     /**< 32 bits, c_ij and tuples (i,j)     */
00450     dbm_MINDBM_COPY16,       /**< 16 bits, dbm copy without diagonal */
00451     dbm_MINDBM_BITMATRIX16,  /**< 16 bits, c_ij and a bit matrix     */
00452     dbm_MINDBM_TUPLES16,     /**< 16 bits, c_ij and tuples (i,j)     */
00453     dbm_MINDBM_ERROR         /**< should never be the case */
00454 }
00455 representationOfMinDBM_t;
00456 
00457 
00458 /** @return the type of the internal format used.
00459  * @param minDBM: minimal representation (without offset)
00460  * to read.
00461  */
00462 representationOfMinDBM_t dbm_getRepresentationType(mingraph_t minDBM);
00463     
00464 
00465 
00466 #ifdef __cplusplus
00467 }
00468 #endif
00469 
00470 #endif /* INCLUDE_DBM_MINGRAPH_H */

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