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

mingraph_coding.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_coding.h (dbm)
00005  *
00006  * This file is a part of the UPPAAL toolkit.
00007  * Copyright (c) 1995 - 2003, Uppsala University and Aalborg University.
00008  * All right reserved.
00009  *
00010  * $Id: mingraph_coding.h,v 1.9 2005/09/29 16:10:42 adavid Exp $
00011  *
00012  *********************************************************************/
00013 
00014 #ifndef DBM_MINGRAPH_CODING_H
00015 #define DBM_MINGRAPH_CODING_H
00016 
00017 /**
00018  * @file
00019  * Contains format description
00020  * and coding/decoding primitives for mingraph.
00021  * The primitives are typed macros, ie, inlined
00022  * functions.
00023  */
00024 
00025 #ifdef __cplusplus
00026 extern "C" {
00027 #endif
00028 
00029 /** Encoding of infinity on 16 bits.
00030  */
00031 enum
00032 {
00033     dbm_INF16 = SHRT_MAX >> 1,
00034     dbm_LS_INF16 = dbm_INF16 << 1
00035 };
00036 
00037 
00038 /***************************************************************************
00039  * Format of the encoding: information+data where information = uint32_t[2]
00040  * and data is variable.
00041  *
00042  * Type information (reserved bits) uint32_t[0]:
00043  * 0x0000ffff : dimension
00044  * 0xffff0000 : encoding information
00045  * 0x00010000 : set if encoding of constraints on 16 bits
00046  * 0x00040000 : set if minimal reduction used, otherwise just copy
00047  *              without the diagonal
00048  * 0x00020000 : set if bit couples (i,j) are used, otherwise use
00049  *              a bit matrix to mark the saved (i,j) constraints saved.
00050  * 0x00180000 : bits to control the # of bits used to encode
00051  *              the couples (i,j). Used only if 0x00010000 is set.
00052  *              if 0x00000000 then 4 bits/index
00053  *              if 0x00080000 then 8 bits/index
00054  *              if 0x00100000 then 16 bits/index
00055  *              the value 0x00180000 is not used.
00056  * 0x00200000 : set if there are more than 0x3ff constraints saved,
00057  *              to avoid to use a full int to code the number of constraints.
00058  * 0xffc00000 : number of constraints if 0x00200000 is NOT set = nsaved
00059  *              The maximal number of constraints we can store there
00060  *              is 0x3ff = 0xffc00000 >> 22
00061  *
00062  * Size information uint32_t[1] : number of saved constraints = nsaved,
00063  * if 0x00200000 is set.
00064  *
00065  * Copy DBM data type:
00066  * int32_t[dim*(dim-1)] or int16_t[dim*(dim-1)]
00067  *
00068  * Bit matrix data type:
00069  * int32_t[nsaved] or int16_t[nsaved] +
00070  * uint32_t[bits2intsize(dim*dim)]
00071  *
00072  * Couple(i,j) data type:
00073  * int32_t[nsaved] or int16_t[nsaved] +
00074  * (i,j)of variable size * nsaved padded within int32_t
00075  ***************************************************************************/
00076 
00077 
00078 /* Basic information decoding from the type information.
00079  */
00080 static inline
00081 cindex_t mingraph_readDim(uint32_t info)
00082 {
00083     return 0x0000ffff & info;
00084 }
00085 
00086 static inline
00087 uint32_t mingraph_isCoded16(uint32_t info)
00088 {
00089     return 0x00010000 & info;
00090 }
00091 
00092 static inline
00093 uint32_t mingraph_isMinimal(uint32_t info)
00094 {
00095     return 0x00040000 & info;
00096 }
00097 
00098 static inline
00099 uint32_t mingraph_isCodedIJ(uint32_t info)
00100 {
00101     return 0x00020000 & info;
00102 }
00103 
00104 
00105 /* We need to test types of the encoding
00106  * based on the bits
00107  * 0x00010000 codes if constraints are on 16 bits
00108  * 0x00020000 codes couples i,j
00109  * 0x00040000 marks if minimal reduction used
00110  * There are 6 valid combination out of 8
00111  * possible:
00112  * 0x00000000 copy, 32 bits
00113  * 0x00010000 copy, 16 bits
00114  * 0x00020000 invalid
00115  * 0x00030000 invalid
00116  * 0x00040000 min. red. bit matrix, 32 bits
00117  * 0x00050000 min. red. bit matrix, 16 bits
00118  * 0x00060000 min. red. couples i,j, 32 bits
00119  * 0x00070000 min. red. couples i,j, 16 bits
00120  *
00121  * It is then possible to simplify the code
00122  * by making a jump to the right function
00123  * directly with the index being defined
00124  * as (info & 0x00070000) >> 16
00125  */
00126 static inline
00127 uint32_t mingraph_getTypeIndex(uint32_t info)
00128 {
00129     return (info & 0x00070000) >> 16;
00130 }
00131 
00132 
00133 /* Decode # of bits used for indices:
00134  * 0 -> 4 bits
00135  * 1 -> 8 bits
00136  * 2 -> 16 bits
00137  * 3 -> unused
00138  * shift the 19 precedent bits.
00139  */
00140 static inline
00141 uint32_t mingraph_typeOfIJ(uint32_t info)
00142 {
00143     return (0x00180000 & info) >> 19;
00144 }
00145 
00146 
00147 /* Getting the type information.
00148  */
00149 static inline
00150 uint32_t mingraph_getInfo(const int32_t *mingraph)
00151 {
00152     assert(mingraph);
00153     return (uint32_t) mingraph[0];
00154 }
00155 
00156 
00157 /* Simple wrapper.
00158  */
00159 static inline
00160 uint32_t mingraph_getTypeIndexFromPtr(const int32_t *mingraph)
00161 {
00162     assert(mingraph);
00163     return mingraph_getTypeIndex(mingraph_getInfo(mingraph));
00164 }
00165 
00166 
00167 /* simple wrapper
00168  */
00169 static inline
00170 cindex_t mingraph_readDimFromPtr(const int32_t *mingraph)
00171 {
00172     assert(mingraph);
00173     return mingraph_readDim(mingraph_getInfo(mingraph));
00174 }
00175 
00176 
00177 /* Getting number of constraints.
00178  */
00179 static inline
00180 size_t mingraph_getNbConstraints(const int32_t *mingraph)
00181 {
00182     assert(mingraph);
00183     return (mingraph[0] & 0x00200000) ? /* long format */
00184         (size_t) mingraph[1] :        /* next int    */
00185         ((size_t) mingraph[0]) >> 22; /* higher bits */
00186 }
00187 
00188 
00189 /* Getting the coded data =
00190  * 1 + dynamic offset
00191  */
00192 static inline
00193 const int32_t* mingraph_getCodedData(const int32_t *mingraph)
00194 {
00195     assert(mingraph);
00196     return mingraph + 1 +
00197         /* bit marking "many" constraints */
00198         ((mingraph[0] & 0x00200000) >> 21);
00199 }
00200 
00201 
00202 /* Restore a constraint on 32 bits:
00203  * - special detection for infinity
00204  * - restore signed int on 32 bits
00205  */
00206 static inline
00207 raw_t mingraph_raw16to32(int16_t raw16)
00208 {
00209     return (raw16 == dbm_LS_INF16) ?
00210         dbm_LS_INFINITY :
00211         (((int32_t)raw16 & 0x7fff) -
00212          ((int32_t)raw16 & 0x8000));
00213 }
00214 
00215 
00216 /* Restore a constraint on 32 bits:
00217  * - special detection for infinity
00218  * - restore signed int on 32 bits
00219  * @pre raw16 is not infinity!
00220  */
00221 static inline
00222 raw_t mingraph_finite16to32(int16_t raw16)
00223 {
00224     assert(raw16 != dbm_LS_INF16);
00225     return
00226         ((int32_t)raw16 & 0x7fff) -
00227         ((int32_t)raw16 & 0x8000);
00228 }
00229 
00230 
00231 /* Cut a constraint to 16 bits
00232  */
00233 static inline
00234 int16_t mingraph_raw32to16(raw_t raw32)
00235 {
00236     /* check that the range is correct
00237      */
00238     assert(raw32 == dbm_LS_INFINITY ||
00239            (raw32  < dbm_LS_INF16 &&
00240             -raw32 < dbm_LS_INF16));
00241     
00242     /* convert infinity 32 -> 16 bits
00243      * or simple type convertion
00244      */
00245     if (raw32 == dbm_LS_INFINITY)
00246     {
00247         return dbm_LS_INF16;
00248     }
00249     else
00250     {
00251         return (int16_t) raw32;
00252     }
00253 }
00254 
00255 
00256 /* Cut a finite constraint to 16 bits
00257  */
00258 static inline
00259 int16_t mingraph_finite32to16(raw_t raw32)
00260 {
00261     /* check that the range is correct
00262      */
00263     assert(raw32 != dbm_LS_INFINITY &&
00264            raw32  < dbm_LS_INF16 &&
00265            -raw32 < dbm_LS_INF16);
00266     
00267     return (int16_t) raw32;
00268 }
00269 
00270 
00271 /** Jump int16 integers, padded int32.
00272  * @param ints: int16 starting point (padded int32)
00273  * @param n: nb of int16 to jump
00274  * @return ints+n padded int32 as int32*
00275  */
00276 static inline
00277 const uint32_t* mingraph_jumpConstInt16(const int16_t *ints, size_t n)
00278 {
00279     return ((uint32_t*)ints) + ((n + 1) >> 1);
00280 }
00281 
00282 
00283 /* Remove constraints of the form xi >= 0 from the bit matrix.
00284  * @param dbm,dim: DBM of dimension dim
00285  * @param bitMatrix: bit matrix representing the minimal graph
00286  * @param nbConstraints: current number of constraints
00287  * @return new number of constraints
00288  * @post bitMatrix has the constraints xi>=0 removed
00289  */
00290 size_t dbm_cleanBitMatrix(const raw_t *dbm, cindex_t dim,
00291                           uint32_t *bitMatrix, size_t nbConstraints);
00292 
00293 
00294 /** Useful function for bit manipulation
00295  * return a negated bit and set it afterwards.
00296  * instead of having
00297  * if !base_getOneBit(bitMatrix, index) cnt++;
00298  * base_setOneBit(bitMatrix, index);
00299  * we use
00300  * cnt += mingraph_ngetAndSetBit(bitMatrix, index)
00301  * @param bits: bit array.
00302  * @param index: bit index.
00303  * Reminder: index >> 5 == index/32
00304  * index & 31 == index%32
00305  * index & 31 is the position of the bit for the
00306  * right integer bits[index >> 5].
00307  */
00308 static inline
00309 bit_t mingraph_ngetAndSetBit(uint32_t *bits, size_t index)
00310 {
00311     uint32_t nbit = /* negated bit */
00312         ((bits[index >> 5] >> (index & 31)) & 1) ^ 1;
00313     bits[index >> 5] |= (1 << (index & 31)); /* set the bit we just read */
00314     return (bit_t) nbit;
00315 }
00316 
00317 
00318 /* In loops reading constraints i,j out of a bit matrix
00319  * j is incremented everytime a bit is skipped so it is
00320  * necessary to fix i and j. It seems that for higher
00321  * dimensions, having a simple loop is better than the
00322  * arithmetic operations (potentially more expensive anyway).
00323  */
00324 #define FIX_IJ() while(j >= dim) { j -= dim; ++i; }
00325 /* #define FIX_IJ() do { i += j/dim; j %= dim; } while(0) */
00326 
00327 
00328 #ifdef __cplusplus
00329 }
00330 #endif
00331 
00332 #endif /* DBM_MINGRAPH_CODING_H */

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