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 */