[14] | 1 | /**CFile*********************************************************************** |
---|
| 2 | |
---|
| 3 | FileName [mvfMvf.c] |
---|
| 4 | |
---|
| 5 | PackageName [mvf] |
---|
| 6 | |
---|
| 7 | Synopsis [Routines to create, manipulate and free multi-valued functions.] |
---|
| 8 | |
---|
| 9 | SeeAlso [mvf.h] |
---|
| 10 | |
---|
| 11 | Author [Tom Shiple] |
---|
| 12 | |
---|
| 13 | Copyright [Copyright (c) 1994-1996 The Regents of the Univ. of California. |
---|
| 14 | All rights reserved. |
---|
| 15 | |
---|
| 16 | Permission is hereby granted, without written agreement and without license |
---|
| 17 | or royalty fees, to use, copy, modify, and distribute this software and its |
---|
| 18 | documentation for any purpose, provided that the above copyright notice and |
---|
| 19 | the following two paragraphs appear in all copies of this software. |
---|
| 20 | |
---|
| 21 | IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR |
---|
| 22 | DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT |
---|
| 23 | OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF |
---|
| 24 | CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
---|
| 25 | |
---|
| 26 | THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, |
---|
| 27 | INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND |
---|
| 28 | FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN |
---|
| 29 | "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO PROVIDE |
---|
| 30 | MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.] |
---|
| 31 | |
---|
| 32 | ******************************************************************************/ |
---|
| 33 | |
---|
| 34 | #include "mvfInt.h" |
---|
| 35 | |
---|
| 36 | static char rcsid[] UNUSED = "$Id: mvfMvf.c,v 1.6 2002/09/08 21:48:24 fabio Exp $"; |
---|
| 37 | |
---|
| 38 | /**AutomaticStart*************************************************************/ |
---|
| 39 | |
---|
| 40 | /*---------------------------------------------------------------------------*/ |
---|
| 41 | /* Static function prototypes */ |
---|
| 42 | /*---------------------------------------------------------------------------*/ |
---|
| 43 | |
---|
| 44 | |
---|
| 45 | /**AutomaticEnd***************************************************************/ |
---|
| 46 | |
---|
| 47 | |
---|
| 48 | /*---------------------------------------------------------------------------*/ |
---|
| 49 | /* Definition of exported functions */ |
---|
| 50 | /*---------------------------------------------------------------------------*/ |
---|
| 51 | |
---|
| 52 | /**Function******************************************************************** |
---|
| 53 | |
---|
| 54 | Synopsis [Initializes the mvf package.] |
---|
| 55 | |
---|
| 56 | SideEffects [] |
---|
| 57 | |
---|
| 58 | SeeAlso [Mvf_End] |
---|
| 59 | |
---|
| 60 | ******************************************************************************/ |
---|
| 61 | void |
---|
| 62 | Mvf_Init(void) |
---|
| 63 | { |
---|
| 64 | } |
---|
| 65 | |
---|
| 66 | |
---|
| 67 | /**Function******************************************************************** |
---|
| 68 | |
---|
| 69 | Synopsis [Ends the mvf package.] |
---|
| 70 | |
---|
| 71 | SideEffects [] |
---|
| 72 | |
---|
| 73 | SeeAlso [Mvf_Init] |
---|
| 74 | |
---|
| 75 | ******************************************************************************/ |
---|
| 76 | void |
---|
| 77 | Mvf_End(void) |
---|
| 78 | { |
---|
| 79 | } |
---|
| 80 | |
---|
| 81 | |
---|
| 82 | /**Function******************************************************************** |
---|
| 83 | |
---|
| 84 | Synopsis [Allocates a multi-valued function of n components.] |
---|
| 85 | |
---|
| 86 | Description [Allocates a multi-valued function of n components. Each |
---|
| 87 | component is initialized to the zero MDD.] |
---|
| 88 | |
---|
| 89 | SideEffects [] |
---|
| 90 | |
---|
| 91 | SeeAlso [Mvf_FunctionAddMintermsToComponent Mvf_FunctionCreateFromVariable] |
---|
| 92 | |
---|
| 93 | ******************************************************************************/ |
---|
| 94 | Mvf_Function_t * |
---|
| 95 | Mvf_FunctionAlloc( |
---|
| 96 | mdd_manager *mddManager, |
---|
| 97 | int n) |
---|
| 98 | { |
---|
| 99 | int i; |
---|
| 100 | array_t *mddArray = array_alloc(mdd_t *, n); |
---|
| 101 | |
---|
| 102 | for (i = 0; i < n; i++) { |
---|
| 103 | array_insert(mdd_t *, mddArray, i, mdd_zero(mddManager)); |
---|
| 104 | } |
---|
| 105 | return ((Mvf_Function_t *) mddArray); |
---|
| 106 | } |
---|
| 107 | |
---|
| 108 | |
---|
| 109 | /**Function******************************************************************** |
---|
| 110 | |
---|
| 111 | Synopsis [Adds a set of minterms to the ith component of a function.] |
---|
| 112 | |
---|
| 113 | Description [Adds a set of minterms, represented by the onset of an MDD g, |
---|
| 114 | to the onset of the ith component of a function. The MDD g is not freed.] |
---|
| 115 | |
---|
| 116 | SideEffects [] |
---|
| 117 | |
---|
| 118 | SeeAlso [Mvf_FunctionAlloc] |
---|
| 119 | |
---|
| 120 | ******************************************************************************/ |
---|
| 121 | void |
---|
| 122 | Mvf_FunctionAddMintermsToComponent( |
---|
| 123 | Mvf_Function_t *function, |
---|
| 124 | int i, |
---|
| 125 | mdd_t *g) |
---|
| 126 | { |
---|
| 127 | mdd_t *oldComponent; |
---|
| 128 | mdd_t *newComponent; |
---|
| 129 | array_t *mddArray = (array_t *) function; |
---|
| 130 | |
---|
| 131 | assert((i >= 0) && (i < array_n(mddArray))); |
---|
| 132 | |
---|
| 133 | oldComponent = array_fetch(mdd_t *, mddArray, i); |
---|
| 134 | newComponent = mdd_or(oldComponent, g, 1, 1); |
---|
| 135 | mdd_free(oldComponent); |
---|
| 136 | array_insert(mdd_t *, mddArray, i, newComponent); |
---|
| 137 | } |
---|
| 138 | |
---|
| 139 | |
---|
| 140 | /**Function******************************************************************** |
---|
| 141 | |
---|
| 142 | Synopsis [Returns the MDD representation of the relation (var == function).] |
---|
| 143 | |
---|
| 144 | Description [Given a variable x, represented by MDD var "mddId", and a |
---|
| 145 | function f:y->z, represented by "function", where x and z take the same |
---|
| 146 | number of values, returns the MDD for a (binary) function F(x,y) such that |
---|
| 147 | F(x,y) = 1 iff x = f(y). In the binary case it reduces to F(x,y) = x XNOR |
---|
| 148 | f(y). Intuitively it describes a function of multi-valued variables by the |
---|
| 149 | characteristic function of its input-output relation.] |
---|
| 150 | |
---|
| 151 | SideEffects [] |
---|
| 152 | |
---|
| 153 | ******************************************************************************/ |
---|
| 154 | mdd_t * |
---|
| 155 | Mvf_FunctionBuildRelationWithVariable( |
---|
| 156 | Mvf_Function_t *function, |
---|
| 157 | int mddId) |
---|
| 158 | { |
---|
| 159 | int i; |
---|
| 160 | mvar_type mddVar; |
---|
| 161 | array_t *mddArray = (array_t *) function; |
---|
| 162 | mdd_manager *mddManager = Mvf_FunctionReadMddManager(function); |
---|
| 163 | mdd_t *sumOfFactors = mdd_zero(mddManager); |
---|
| 164 | |
---|
| 165 | mddVar = array_fetch(mvar_type, mdd_ret_mvar_list(mddManager), mddId); |
---|
| 166 | assert(mddVar.values == Mvf_FunctionReadNumComponents(function)); |
---|
| 167 | |
---|
| 168 | for (i = 0; i < array_n(mddArray); i++) { |
---|
| 169 | mdd_t *varLiteral; |
---|
| 170 | mdd_t *factor; |
---|
| 171 | mdd_t *tmp; |
---|
| 172 | mdd_t *fComponent = array_fetch(mdd_t *, mddArray, i); |
---|
| 173 | |
---|
| 174 | varLiteral = mdd_eq_c(mddManager, mddId, i); |
---|
| 175 | factor = mdd_and(fComponent, varLiteral, 1, 1); |
---|
| 176 | mdd_free(varLiteral); |
---|
| 177 | |
---|
| 178 | /* Take the or of the sumOfFactors so far and the new factor */ |
---|
| 179 | tmp = mdd_or(sumOfFactors, factor, 1, 1); |
---|
| 180 | mdd_free(factor); |
---|
| 181 | mdd_free(sumOfFactors); |
---|
| 182 | sumOfFactors = tmp; |
---|
| 183 | } |
---|
| 184 | |
---|
| 185 | return sumOfFactors; |
---|
| 186 | } |
---|
| 187 | |
---|
| 188 | |
---|
| 189 | /**Function******************************************************************** |
---|
| 190 | |
---|
| 191 | Synopsis [Returns the number of components of a multi-valued function.] |
---|
| 192 | |
---|
| 193 | Description [Returns the number of components of a multi-valued function. |
---|
| 194 | This is the same number as the value of the parameter passed to |
---|
| 195 | Mvf_FunctionAlloc.] |
---|
| 196 | |
---|
| 197 | SideEffects [] |
---|
| 198 | |
---|
| 199 | SeeAlso [Mvf_FunctionAlloc] |
---|
| 200 | |
---|
| 201 | ******************************************************************************/ |
---|
| 202 | int |
---|
| 203 | Mvf_FunctionReadNumComponents( |
---|
| 204 | Mvf_Function_t *function) |
---|
| 205 | { |
---|
| 206 | return (array_n((array_t *) function)); |
---|
| 207 | } |
---|
| 208 | |
---|
| 209 | |
---|
| 210 | /**Function******************************************************************** |
---|
| 211 | |
---|
| 212 | Synopsis [Returns the MDD manager of a multi-valued function.] |
---|
| 213 | |
---|
| 214 | Description [Returns the MDD manager of a multi-valued function. This |
---|
| 215 | procedure assumes that the function has at least one component.] |
---|
| 216 | |
---|
| 217 | SideEffects [] |
---|
| 218 | |
---|
| 219 | SeeAlso [Mvf_FunctionAlloc] |
---|
| 220 | |
---|
| 221 | ******************************************************************************/ |
---|
| 222 | mdd_manager * |
---|
| 223 | Mvf_FunctionReadMddManager( |
---|
| 224 | Mvf_Function_t *function) |
---|
| 225 | { |
---|
| 226 | mdd_t *component = array_fetch(mdd_t *, (array_t *) function, 0); |
---|
| 227 | |
---|
| 228 | return (mdd_get_manager(component)); |
---|
| 229 | } |
---|
| 230 | |
---|
| 231 | |
---|
| 232 | /**Function******************************************************************** |
---|
| 233 | |
---|
| 234 | Synopsis [Duplicates a multi-valued output function.] |
---|
| 235 | |
---|
| 236 | Description [Returns a new multi-valued output function, whose constituent |
---|
| 237 | MDDs have been duplicated. Assumes that function is not NULL.] |
---|
| 238 | |
---|
| 239 | SideEffects [] |
---|
| 240 | |
---|
| 241 | SeeAlso [Mvf_FunctionFree] |
---|
| 242 | |
---|
| 243 | ******************************************************************************/ |
---|
| 244 | Mvf_Function_t * |
---|
| 245 | Mvf_FunctionDuplicate( |
---|
| 246 | Mvf_Function_t *function) |
---|
| 247 | { |
---|
| 248 | return ((Mvf_Function_t *) mdd_array_duplicate((array_t *) function)); |
---|
| 249 | } |
---|
| 250 | |
---|
| 251 | |
---|
| 252 | /**Function******************************************************************** |
---|
| 253 | |
---|
| 254 | Synopsis [Frees a multi-valued output function.] |
---|
| 255 | |
---|
| 256 | Description [Frees a multi-valued output function. Does nothing if |
---|
| 257 | function is NULL.] |
---|
| 258 | |
---|
| 259 | SideEffects [] |
---|
| 260 | |
---|
| 261 | SeeAlso [Mvf_FunctionAlloc] |
---|
| 262 | |
---|
| 263 | ******************************************************************************/ |
---|
| 264 | void |
---|
| 265 | Mvf_FunctionFree( |
---|
| 266 | Mvf_Function_t *function) |
---|
| 267 | { |
---|
| 268 | mdd_array_free((array_t *) function); |
---|
| 269 | } |
---|
| 270 | |
---|
| 271 | |
---|
| 272 | /**Function******************************************************************** |
---|
| 273 | |
---|
| 274 | Synopsis [Frees an array of multi-valued output functions.] |
---|
| 275 | |
---|
| 276 | Description [Frees an array of multi-valued output functions. Does nothing |
---|
| 277 | if functionArray is NULL.] |
---|
| 278 | |
---|
| 279 | SideEffects [] |
---|
| 280 | |
---|
| 281 | SeeAlso [Mvf_FunctionFree] |
---|
| 282 | |
---|
| 283 | ******************************************************************************/ |
---|
| 284 | void |
---|
| 285 | Mvf_FunctionArrayFree( |
---|
| 286 | array_t *functionArray) |
---|
| 287 | { |
---|
| 288 | int i; |
---|
| 289 | |
---|
| 290 | if (functionArray != NIL(array_t)) { |
---|
| 291 | for (i = 0; i < array_n(functionArray); i++) { |
---|
| 292 | Mvf_Function_t *function = array_fetch(Mvf_Function_t *, functionArray, i); |
---|
| 293 | Mvf_FunctionFree(function); |
---|
| 294 | } |
---|
| 295 | array_free(functionArray); |
---|
| 296 | } |
---|
| 297 | } |
---|
| 298 | |
---|
| 299 | /**Function******************************************************************** |
---|
| 300 | |
---|
| 301 | Synopsis [Returns a copy of the ith component of a multi-valued function.] |
---|
| 302 | |
---|
| 303 | Synopsis [Returns a copy of the MDD giving the minterms for which a |
---|
| 304 | multi-valued function evaluates to its ith value.] |
---|
| 305 | |
---|
| 306 | SideEffects [] |
---|
| 307 | |
---|
| 308 | SeeAlso [Mvf_FunctionAlloc Mvf_FunctionCreateFromVariable] |
---|
| 309 | |
---|
| 310 | ******************************************************************************/ |
---|
| 311 | mdd_t * |
---|
| 312 | Mvf_FunctionObtainComponent( |
---|
| 313 | Mvf_Function_t *function, |
---|
| 314 | int i) |
---|
| 315 | { |
---|
| 316 | mdd_t *component = array_fetch(mdd_t *, (array_t *) function, i); |
---|
| 317 | return (mdd_dup(component)); |
---|
| 318 | } |
---|
| 319 | |
---|
| 320 | /**Function******************************************************************** |
---|
| 321 | |
---|
| 322 | Synopsis [Returns the ith component of a multi-valued function.] |
---|
| 323 | |
---|
| 324 | Synopsis [Returns the MDD giving the minterms for which a |
---|
| 325 | multi-valued function evaluates to its ith value. The user should not free |
---|
| 326 | this MDD.] |
---|
| 327 | |
---|
| 328 | SideEffects [] |
---|
| 329 | |
---|
| 330 | SeeAlso [Mvf_FunctionObtainComponent Mvf_FunctionAlloc |
---|
| 331 | Mvf_FunctionCreateFromVariable] |
---|
| 332 | |
---|
| 333 | ******************************************************************************/ |
---|
| 334 | mdd_t * |
---|
| 335 | Mvf_FunctionReadComponent( |
---|
| 336 | Mvf_Function_t *function, |
---|
| 337 | int i) |
---|
| 338 | { |
---|
| 339 | mdd_t *component = array_fetch(mdd_t *, (array_t *) function, i); |
---|
| 340 | return (component); |
---|
| 341 | } |
---|
| 342 | |
---|
| 343 | |
---|
| 344 | /**Function******************************************************************** |
---|
| 345 | |
---|
| 346 | Synopsis [Creates the multi-output function for a variable.] |
---|
| 347 | |
---|
| 348 | Description [Given a variable, creates a function with as many components as |
---|
| 349 | values of the variable. The ith component of the function is true exactly |
---|
| 350 | when the variable is equal to the ith value (i.e. fi(x) = (x==i), where x is |
---|
| 351 | the variable specified by mddId). For the case where x is binary valued, |
---|
| 352 | the result is \[!x, x\]. Assumes that mddId is non-negative.] |
---|
| 353 | |
---|
| 354 | SideEffects [] |
---|
| 355 | |
---|
| 356 | SeeAlso [Mvf_FunctionAlloc] |
---|
| 357 | |
---|
| 358 | ******************************************************************************/ |
---|
| 359 | Mvf_Function_t * |
---|
| 360 | Mvf_FunctionCreateFromVariable( |
---|
| 361 | mdd_manager *mddManager, |
---|
| 362 | int mddId) |
---|
| 363 | { |
---|
| 364 | int i; |
---|
| 365 | array_t *mvar_list = mdd_ret_mvar_list(mddManager); |
---|
| 366 | mvar_type varInfo; |
---|
| 367 | array_t *result; |
---|
| 368 | |
---|
| 369 | assert(mddId >= 0); |
---|
| 370 | |
---|
| 371 | varInfo = array_fetch(mvar_type, mvar_list, mddId); |
---|
| 372 | result = array_alloc(mdd_t *, varInfo.values); |
---|
| 373 | |
---|
| 374 | for(i = 0; i < varInfo.values; i++) { |
---|
| 375 | mdd_t *literal; |
---|
| 376 | |
---|
| 377 | literal = mdd_eq_c(mddManager, mddId, i); |
---|
| 378 | array_insert(mdd_t *, result, i, literal); |
---|
| 379 | } |
---|
| 380 | |
---|
| 381 | return ((Mvf_Function_t *) result); |
---|
| 382 | } |
---|
| 383 | |
---|
| 384 | |
---|
| 385 | /**Function******************************************************************** |
---|
| 386 | |
---|
| 387 | Synopsis [Substitutes a set of variables by a set of functions in a function.] |
---|
| 388 | |
---|
| 389 | Description [Given a multi-valued function f, an array of variables |
---|
| 390 | x1,...,xk, and an array of multi-valued functions g1,...,gk, iteratively |
---|
| 391 | calls Mvf_MddComposeWithFunction to substitute each xi by gi. The |
---|
| 392 | parameters of the ith call to Mvf_MddComposeWithFunction are the result of |
---|
| 393 | composing the first i-1 variables, xi, and gi. The multi-valued function gi |
---|
| 394 | must not depend on xi.] |
---|
| 395 | |
---|
| 396 | SideEffects [] |
---|
| 397 | |
---|
| 398 | SeeAlso [Mvf_MddComposeWithFunction] |
---|
| 399 | |
---|
| 400 | ******************************************************************************/ |
---|
| 401 | Mvf_Function_t * |
---|
| 402 | Mvf_FunctionComposeWithFunctionArray( |
---|
| 403 | Mvf_Function_t *f, |
---|
| 404 | array_t *mddIdArray /* of int */, |
---|
| 405 | array_t *functionArray /* of Mvf_Function_t* */) |
---|
| 406 | { |
---|
| 407 | Mvf_Function_t *result; |
---|
| 408 | int i; |
---|
| 409 | |
---|
| 410 | assert(array_n(mddIdArray) == array_n(functionArray)); |
---|
| 411 | |
---|
| 412 | /* Make an initial copy of the function */ |
---|
| 413 | result = Mvf_FunctionDuplicate(f); |
---|
| 414 | |
---|
| 415 | for(i = 0; i < array_n(mddIdArray); i++) { |
---|
| 416 | Mvf_Function_t *tmp; |
---|
| 417 | int mddId = array_fetch(int, mddIdArray, i); |
---|
| 418 | Mvf_Function_t *g = array_fetch(Mvf_Function_t *, functionArray, i); |
---|
| 419 | |
---|
| 420 | tmp = Mvf_FunctionComposeWithFunction(result, mddId, g); |
---|
| 421 | |
---|
| 422 | Mvf_FunctionFree(result); |
---|
| 423 | result = tmp; |
---|
| 424 | } |
---|
| 425 | |
---|
| 426 | return result; |
---|
| 427 | } |
---|
| 428 | |
---|
| 429 | |
---|
| 430 | /**Function******************************************************************** |
---|
| 431 | |
---|
| 432 | Synopsis [Substitutes a variable by a function in a function.] |
---|
| 433 | |
---|
| 434 | Description [Given a multi-valued function f, a variable x (mddId), and a |
---|
| 435 | multi-valued function g, the procedure replaces every appearance of x in f |
---|
| 436 | by function g. That is, if the function f is f(..., x, ...), then the |
---|
| 437 | result is f(..., g(), ...). The number of values that x can take and the |
---|
| 438 | number of components of g must be equal. The algorithm first computes the |
---|
| 439 | sum of factors (x==i)*gi for every value i in the domain of x, where gi is |
---|
| 440 | the ith component of g. Then, for each component fi of f, the sum of |
---|
| 441 | factors is conjuncted with fi, and x is existentially quantified. The |
---|
| 442 | function g must not depend on x. The result depends on all the variables of |
---|
| 443 | g and all the variables of f, except for x.] |
---|
| 444 | |
---|
| 445 | SideEffects [] |
---|
| 446 | |
---|
| 447 | SeeAlso [Mvf_MddComposeWithFunction] |
---|
| 448 | |
---|
| 449 | ******************************************************************************/ |
---|
| 450 | Mvf_Function_t * |
---|
| 451 | Mvf_FunctionComposeWithFunction( |
---|
| 452 | Mvf_Function_t *f, |
---|
| 453 | int mddId, |
---|
| 454 | Mvf_Function_t *g) |
---|
| 455 | { |
---|
| 456 | mdd_t *sumOfFactors; |
---|
| 457 | array_t *result; |
---|
| 458 | array_t *values; |
---|
| 459 | int i; |
---|
| 460 | mdd_manager *mddManager = Mvf_FunctionReadMddManager(f); |
---|
| 461 | |
---|
| 462 | /* Allocate array to hold values for the literal and the result */ |
---|
| 463 | result = array_alloc(mdd_t *, array_n(f)); |
---|
| 464 | |
---|
| 465 | /* |
---|
| 466 | * Create the sum of factors (x==i * gi). This function will verify that the |
---|
| 467 | * domain of x and the range of g have the same cardinality. |
---|
| 468 | */ |
---|
| 469 | sumOfFactors = Mvf_FunctionBuildRelationWithVariable(g, mddId); |
---|
| 470 | |
---|
| 471 | /* |
---|
| 472 | * Result is an array of mdd_t * , result[i] = Exists(x) (f[i] * sumOfFactors) |
---|
| 473 | * The array values holds now the index of the variable to smooth out. |
---|
| 474 | */ |
---|
| 475 | values = array_alloc(int, 1); |
---|
| 476 | array_insert(int, values, 0, mddId); |
---|
| 477 | for(i = 0; i < array_n(f); i++) { |
---|
| 478 | mdd_t *functionUnit = array_fetch(mdd_t *, f, i); |
---|
| 479 | mdd_t *tmp = mdd_and_smooth(mddManager, functionUnit, sumOfFactors, values); |
---|
| 480 | |
---|
| 481 | array_insert(mdd_t *, result, i, tmp); |
---|
| 482 | } |
---|
| 483 | |
---|
| 484 | /* Clean up */ |
---|
| 485 | array_free(values); |
---|
| 486 | mdd_free(sumOfFactors); |
---|
| 487 | |
---|
| 488 | return ((Mvf_Function_t *) result); |
---|
| 489 | } |
---|
| 490 | |
---|
| 491 | |
---|
| 492 | /**Function******************************************************************** |
---|
| 493 | |
---|
| 494 | Synopsis [Substitutes a variable by a function in an mdd_t *.] |
---|
| 495 | |
---|
| 496 | Description [Given a binary-valued function f, a variable x, and a |
---|
| 497 | multi-valued function g, the procedure replaces every appearance of x in f |
---|
| 498 | by function g. That is, if the function f is f(..., x, ...), then the |
---|
| 499 | result is f(..., g(), ...). The number of values that x can take and the |
---|
| 500 | number of components of g must be equal. The algorithm first computes the |
---|
| 501 | sum of factors (x==i)*gi for every value i in the domain of x, where gi is |
---|
| 502 | the ith component of g, then conjuncts this with f, and finally |
---|
| 503 | existentially quantifies x. The function g must not depend on x. The |
---|
| 504 | result depends on all the variables of g and all the variables of f, except |
---|
| 505 | for x.] |
---|
| 506 | |
---|
| 507 | SideEffects [] |
---|
| 508 | |
---|
| 509 | ******************************************************************************/ |
---|
| 510 | mdd_t * |
---|
| 511 | Mvf_MddComposeWithFunction( |
---|
| 512 | mdd_t *f, |
---|
| 513 | int mddId, |
---|
| 514 | Mvf_Function_t *g) |
---|
| 515 | { |
---|
| 516 | mdd_t *sumOfFactors; |
---|
| 517 | mdd_t *result; |
---|
| 518 | array_t *values; |
---|
| 519 | mdd_manager *mddManager = mdd_get_manager(f); |
---|
| 520 | |
---|
| 521 | /* |
---|
| 522 | * Create the sum of factors (x==i * gi). This function will verify that the |
---|
| 523 | * domain of x and the range of g have the same cardinality. |
---|
| 524 | */ |
---|
| 525 | sumOfFactors = Mvf_FunctionBuildRelationWithVariable(g, mddId); |
---|
| 526 | |
---|
| 527 | /* Result is an mdd_t * , result = Exists(x) (f * sumOfFactors) */ |
---|
| 528 | values = array_alloc(int, 1); |
---|
| 529 | array_insert(int, values, 0, mddId); |
---|
| 530 | result = mdd_and_smooth(mddManager, f, sumOfFactors, values); |
---|
| 531 | |
---|
| 532 | /* Clean up */ |
---|
| 533 | array_free(values); |
---|
| 534 | mdd_free(sumOfFactors); |
---|
| 535 | |
---|
| 536 | return result; |
---|
| 537 | } |
---|
| 538 | |
---|
| 539 | |
---|
| 540 | /**Function******************************************************************** |
---|
| 541 | |
---|
| 542 | Synopsis [Returns true if a multi-valued function is deterministic, else |
---|
| 543 | false.] |
---|
| 544 | |
---|
| 545 | Description [Returns true if a multi-valued function is deterministic, else |
---|
| 546 | false. A function is deterministic if, for every minterm over the input |
---|
| 547 | space of the function, the function takes at most one value. The complexity |
---|
| 548 | of this procedure is linear in the number of values the function can |
---|
| 549 | take.] |
---|
| 550 | |
---|
| 551 | SideEffects [] |
---|
| 552 | |
---|
| 553 | SeeAlso [Mvf_FunctionTestIsCompletelySpecified Mvf_FunctionTestIsWellFormed] |
---|
| 554 | |
---|
| 555 | ******************************************************************************/ |
---|
| 556 | boolean |
---|
| 557 | Mvf_FunctionTestIsDeterministic( |
---|
| 558 | Mvf_Function_t *function) |
---|
| 559 | { |
---|
| 560 | int i; |
---|
| 561 | array_t *mddArray = (array_t *) function; |
---|
| 562 | int numComponents = array_n(mddArray); |
---|
| 563 | mdd_t *sum; |
---|
| 564 | |
---|
| 565 | if (numComponents == 0) { |
---|
| 566 | return TRUE; |
---|
| 567 | } |
---|
| 568 | |
---|
| 569 | sum = mdd_dup(array_fetch(mdd_t *, mddArray, 0)); |
---|
| 570 | |
---|
| 571 | for (i = 1; i < numComponents; i++) { |
---|
| 572 | mdd_t *temp = sum; |
---|
| 573 | mdd_t *ithComponent = array_fetch(mdd_t *, mddArray, i); |
---|
| 574 | boolean intersectionIsEmpty = mdd_lequal(ithComponent, sum, 1, 0); |
---|
| 575 | |
---|
| 576 | /* If the intersection is not empty, then return FALSE. */ |
---|
| 577 | if (!intersectionIsEmpty) { |
---|
| 578 | mdd_free(sum); |
---|
| 579 | return FALSE; |
---|
| 580 | } |
---|
| 581 | |
---|
| 582 | sum = mdd_or(temp, ithComponent, 1, 1); |
---|
| 583 | mdd_free(temp); |
---|
| 584 | } |
---|
| 585 | mdd_free(sum); |
---|
| 586 | |
---|
| 587 | /* The components are pairwise disjoint. */ |
---|
| 588 | return TRUE; |
---|
| 589 | } |
---|
| 590 | |
---|
| 591 | |
---|
| 592 | /**Function******************************************************************** |
---|
| 593 | |
---|
| 594 | Synopsis [Returns true if a multi-valued function is completely specified, else |
---|
| 595 | false.] |
---|
| 596 | |
---|
| 597 | Description [Returns true if a multi-valued function is completely |
---|
| 598 | specified, else false. A function is completely specified if, for every |
---|
| 599 | minterm over the input space of the function, the function takes at least |
---|
| 600 | one value. The complexity of this procedure is linear in the number of |
---|
| 601 | values the function can take.] |
---|
| 602 | |
---|
| 603 | SideEffects [] |
---|
| 604 | |
---|
| 605 | SeeAlso [Mvf_FunctionTestIsDeterministic Mvf_FunctionTestIsWellFormed] |
---|
| 606 | |
---|
| 607 | ******************************************************************************/ |
---|
| 608 | boolean |
---|
| 609 | Mvf_FunctionTestIsCompletelySpecified( |
---|
| 610 | Mvf_Function_t *function) |
---|
| 611 | { |
---|
| 612 | mdd_t *sum = Mvf_FunctionComputeDomain(function); |
---|
| 613 | boolean sumIsTautology = mdd_is_tautology(sum, 1); |
---|
| 614 | |
---|
| 615 | mdd_free(sum); |
---|
| 616 | return sumIsTautology; |
---|
| 617 | } |
---|
| 618 | |
---|
| 619 | |
---|
| 620 | /**Function******************************************************************** |
---|
| 621 | |
---|
| 622 | Synopsis [Returns true if a multi-valued function is constant, else |
---|
| 623 | false.] |
---|
| 624 | |
---|
| 625 | Description [Returns true if a multi-valued function is constant, else |
---|
| 626 | false. A function is constant if exactly one component is the tautology, |
---|
| 627 | and the remaining components are zero. If the function is a constant, then |
---|
| 628 | "value" is set to the constant value of the function. The complexity of this |
---|
| 629 | procedure is linear in the number of values the function can take.] |
---|
| 630 | |
---|
| 631 | SideEffects [] |
---|
| 632 | |
---|
| 633 | SeeAlso [Mvf_FunctionTestIsNonDeterministicConstant] |
---|
| 634 | |
---|
| 635 | ******************************************************************************/ |
---|
| 636 | boolean |
---|
| 637 | Mvf_FunctionTestIsConstant( |
---|
| 638 | Mvf_Function_t *function, |
---|
| 639 | int *constantValue /* return value */ ) |
---|
| 640 | { |
---|
| 641 | int i; |
---|
| 642 | array_t *mddArray = (array_t *) function; |
---|
| 643 | int numComponents = array_n(mddArray); |
---|
| 644 | int numTautComps = 0; |
---|
| 645 | |
---|
| 646 | for (i = 0; i < numComponents; i++) { |
---|
| 647 | mdd_t *ithComponent = array_fetch(mdd_t *, mddArray, i); |
---|
| 648 | |
---|
| 649 | if (mdd_is_tautology(ithComponent, 1)) { |
---|
| 650 | *constantValue = i; |
---|
| 651 | numTautComps++; |
---|
| 652 | } |
---|
| 653 | else if (!mdd_is_tautology(ithComponent, 0)) { |
---|
| 654 | /* this component is not 1 nor 0, so function can't be a constant */ |
---|
| 655 | return FALSE; |
---|
| 656 | } |
---|
| 657 | /* else, must be the zero function */ |
---|
| 658 | } |
---|
| 659 | |
---|
| 660 | return (numTautComps == 1); |
---|
| 661 | } |
---|
| 662 | |
---|
| 663 | |
---|
| 664 | /**Function******************************************************************** |
---|
| 665 | |
---|
| 666 | Synopsis [Returns true if a multi-valued function is a non-deterministic |
---|
| 667 | constant, else false.] |
---|
| 668 | |
---|
| 669 | Description [Returns true if a multi-valued function is a non-deterministic |
---|
| 670 | constant, else false. A function is a non-deterministic constant if more |
---|
| 671 | than one component is the tautology, and the remaining components are zero. |
---|
| 672 | The complexity of this procedure is linear in the number of values the |
---|
| 673 | function can take.] |
---|
| 674 | |
---|
| 675 | SideEffects [] |
---|
| 676 | |
---|
| 677 | SeeAlso [Mvf_FunctionTestIsConstant] |
---|
| 678 | |
---|
| 679 | ******************************************************************************/ |
---|
| 680 | boolean |
---|
| 681 | Mvf_FunctionTestIsNonDeterministicConstant( |
---|
| 682 | Mvf_Function_t *function) |
---|
| 683 | { |
---|
| 684 | int i; |
---|
| 685 | array_t *mddArray = (array_t *) function; |
---|
| 686 | int numComponents = array_n(mddArray); |
---|
| 687 | int numTautComps = 0; |
---|
| 688 | |
---|
| 689 | for (i = 0; i < numComponents; i++) { |
---|
| 690 | mdd_t *ithComponent = array_fetch(mdd_t *, mddArray, i); |
---|
| 691 | |
---|
| 692 | if (mdd_is_tautology(ithComponent, 1)) { |
---|
| 693 | numTautComps++; |
---|
| 694 | } |
---|
| 695 | else if (!mdd_is_tautology(ithComponent, 0)) { |
---|
| 696 | /* this component is not 1 nor 0, so function can't be a non-det constant */ |
---|
| 697 | return FALSE; |
---|
| 698 | } |
---|
| 699 | /* else, must be the zero function */ |
---|
| 700 | } |
---|
| 701 | |
---|
| 702 | return (numTautComps > 1); |
---|
| 703 | } |
---|
| 704 | |
---|
| 705 | |
---|
| 706 | /**Function******************************************************************** |
---|
| 707 | |
---|
| 708 | Synopsis [Computes the domain of a multi-valued function.] |
---|
| 709 | |
---|
| 710 | Description [Returns an MDD representing the set of minterms which turn on |
---|
| 711 | some component of a function. In other words, returns the union of the |
---|
| 712 | onsets of the components. The domain is the tautology if and only if the |
---|
| 713 | function is completely specified.] |
---|
| 714 | |
---|
| 715 | SideEffects [] |
---|
| 716 | |
---|
| 717 | SeeAlso [Mvf_FunctionTestIsCompletelySpecified] |
---|
| 718 | |
---|
| 719 | ******************************************************************************/ |
---|
| 720 | mdd_t * |
---|
| 721 | Mvf_FunctionComputeDomain( |
---|
| 722 | Mvf_Function_t *function) |
---|
| 723 | { |
---|
| 724 | array_t *mddArray = (array_t *) function; |
---|
| 725 | mdd_manager *mddManager = Mvf_FunctionReadMddManager(function); |
---|
| 726 | mdd_t *sum = mdd_multiway_or(mddManager, mddArray); |
---|
| 727 | |
---|
| 728 | return sum; |
---|
| 729 | } |
---|
| 730 | |
---|
| 731 | |
---|
| 732 | /**Function******************************************************************** |
---|
| 733 | |
---|
| 734 | Synopsis [Returns true if a function is deterministic and completely |
---|
| 735 | specified, else false.] |
---|
| 736 | |
---|
| 737 | SideEffects [] |
---|
| 738 | |
---|
| 739 | SeeAlso [Mvf_FunctionTestIsDeterministic |
---|
| 740 | Mvf_FunctionTestIsCompletelySpecified] |
---|
| 741 | |
---|
| 742 | ******************************************************************************/ |
---|
| 743 | boolean |
---|
| 744 | Mvf_FunctionTestIsWellFormed( |
---|
| 745 | Mvf_Function_t *function) |
---|
| 746 | { |
---|
| 747 | return (Mvf_FunctionTestIsDeterministic(function) |
---|
| 748 | && Mvf_FunctionTestIsCompletelySpecified(function)); |
---|
| 749 | } |
---|
| 750 | |
---|
| 751 | |
---|
| 752 | /**Function******************************************************************** |
---|
| 753 | |
---|
| 754 | Synopsis [Returns true if two multi-valued functions are equal, else false.] |
---|
| 755 | |
---|
| 756 | Description [Returns true if two multi-valued functions are equal, else |
---|
| 757 | false. Two functions are equal if they have the same number of components, |
---|
| 758 | and the ith component of one is equal to the ith component of the other.] |
---|
| 759 | |
---|
| 760 | SideEffects [] |
---|
| 761 | |
---|
| 762 | ******************************************************************************/ |
---|
| 763 | boolean |
---|
| 764 | Mvf_FunctionTestIsEqualToFunction( |
---|
| 765 | Mvf_Function_t *function1, |
---|
| 766 | Mvf_Function_t *function2) |
---|
| 767 | { |
---|
| 768 | int i; |
---|
| 769 | array_t *mddArray1 = (array_t *) function1; |
---|
| 770 | array_t *mddArray2 = (array_t *) function2; |
---|
| 771 | int numComponents = array_n(mddArray1); |
---|
| 772 | |
---|
| 773 | if (numComponents != array_n(mddArray2)) { |
---|
| 774 | return FALSE; |
---|
| 775 | } |
---|
| 776 | |
---|
| 777 | for (i = 0; i < numComponents; i++) { |
---|
| 778 | mdd_t *mdd1 = array_fetch(mdd_t *, mddArray1, i); |
---|
| 779 | mdd_t *mdd2 = array_fetch(mdd_t *, mddArray2, i); |
---|
| 780 | if (!mdd_equal(mdd1, mdd2)) { |
---|
| 781 | return FALSE; |
---|
| 782 | } |
---|
| 783 | } |
---|
| 784 | |
---|
| 785 | return TRUE; |
---|
| 786 | } |
---|
| 787 | |
---|
| 788 | |
---|
| 789 | /**Function******************************************************************** |
---|
| 790 | |
---|
| 791 | Synopsis [Returns the set of minterms on which two functions agree.] |
---|
| 792 | |
---|
| 793 | Description [Returns the set of minterms on which two functions agree. For |
---|
| 794 | f = \[f1, f2, ..., fn\] and g = \[g1, g2, ..., gn\], the returned set is: |
---|
| 795 | AND(i = 1, ..., n) (fi XNOR gi). For the special case where f and g are |
---|
| 796 | binary valued, this function computes (f XNOR g). It is an error if the two |
---|
| 797 | functions have a different number of components.] |
---|
| 798 | |
---|
| 799 | SideEffects [] |
---|
| 800 | |
---|
| 801 | ******************************************************************************/ |
---|
| 802 | mdd_t * |
---|
| 803 | Mvf_FunctionsComputeEquivalentSet( |
---|
| 804 | Mvf_Function_t *function1, |
---|
| 805 | Mvf_Function_t *function2) |
---|
| 806 | { |
---|
| 807 | int i; |
---|
| 808 | array_t *mddArray1 = (array_t *) function1; |
---|
| 809 | array_t *mddArray2 = (array_t *) function2; |
---|
| 810 | int numComponents = array_n(mddArray1); |
---|
| 811 | mdd_manager *mddManager = Mvf_FunctionReadMddManager(function1); |
---|
| 812 | mdd_t *product = mdd_one(mddManager); |
---|
| 813 | |
---|
| 814 | assert(numComponents == array_n(mddArray2)); |
---|
| 815 | |
---|
| 816 | for (i = 0; i < numComponents; i++) { |
---|
| 817 | mdd_t *mdd1 = array_fetch(mdd_t *, mddArray1, i); |
---|
| 818 | mdd_t *mdd2 = array_fetch(mdd_t *, mddArray2, i); |
---|
| 819 | mdd_t *xnor = mdd_xnor(mdd1, mdd2); |
---|
| 820 | mdd_t *temp = product; |
---|
| 821 | |
---|
| 822 | product = mdd_and(temp, xnor, 1, 1); |
---|
| 823 | mdd_free(temp); |
---|
| 824 | mdd_free(xnor); |
---|
| 825 | } |
---|
| 826 | |
---|
| 827 | return product; |
---|
| 828 | } |
---|
| 829 | |
---|
| 830 | |
---|
| 831 | /**Function******************************************************************** |
---|
| 832 | |
---|
| 833 | Synopsis [Calls bdd_cofactor on each component of a multi-valued function.] |
---|
| 834 | |
---|
| 835 | Description [Calls bdd_cofactor on each component of a multi-valued |
---|
| 836 | function, cofactoring with respect to wrtMDD. Returns the cofactored |
---|
| 837 | function. It is an error to call this function with a multi-valued |
---|
| 838 | function that contains null MDDs or with a null wrtMdd.] |
---|
| 839 | |
---|
| 840 | SideEffects [] |
---|
| 841 | |
---|
| 842 | ******************************************************************************/ |
---|
| 843 | Mvf_Function_t * |
---|
| 844 | Mvf_FunctionCofactor( |
---|
| 845 | Mvf_Function_t * function, |
---|
| 846 | mdd_t * wrtMdd) |
---|
| 847 | { |
---|
| 848 | int i; |
---|
| 849 | array_t *mddArray = (array_t *) function; |
---|
| 850 | int numComponents = array_n(mddArray); |
---|
| 851 | array_t *newFunction = array_alloc(mdd_t *, numComponents); |
---|
| 852 | |
---|
| 853 | for(i = 0; i < numComponents; i++) { |
---|
| 854 | mdd_t *component = array_fetch(mdd_t *, mddArray, i); |
---|
| 855 | mdd_t *cofactor = bdd_cofactor(component, wrtMdd); |
---|
| 856 | |
---|
| 857 | array_insert(mdd_t *, newFunction, i, cofactor); |
---|
| 858 | } |
---|
| 859 | return((Mvf_Function_t *)newFunction); |
---|
| 860 | } |
---|
| 861 | |
---|
| 862 | |
---|
| 863 | /**Function******************************************************************** |
---|
| 864 | |
---|
| 865 | Synopsis [Calls bdd_minimize on each component of a multi-valued function.] |
---|
| 866 | |
---|
| 867 | Description [Calls bdd_minimize on each component of a multi-valued function |
---|
| 868 | f, minimizing with respect to the care function c. The returned function |
---|
| 869 | agrees with f wherever c is true, and may or may not agree with f wherever c |
---|
| 870 | is false. It is an error to call this function with a multi-valued function |
---|
| 871 | that contains null MDDs or with a null care.] |
---|
| 872 | |
---|
| 873 | SideEffects [] |
---|
| 874 | |
---|
| 875 | ******************************************************************************/ |
---|
| 876 | Mvf_Function_t * |
---|
| 877 | Mvf_FunctionMinimize( |
---|
| 878 | Mvf_Function_t *f, |
---|
| 879 | mdd_t *c) |
---|
| 880 | { |
---|
| 881 | int i; |
---|
| 882 | array_t *mddArray = (array_t *) f; |
---|
| 883 | int numComponents = array_n(mddArray); |
---|
| 884 | array_t *newFunction = array_alloc(mdd_t *, numComponents); |
---|
| 885 | |
---|
| 886 | for(i = 0; i < numComponents; i++) { |
---|
| 887 | mdd_t *component = array_fetch(mdd_t *, mddArray, i); |
---|
| 888 | mdd_t *minimize = bdd_minimize(component, c); |
---|
| 889 | |
---|
| 890 | array_insert(mdd_t *, newFunction, i, minimize); |
---|
| 891 | } |
---|
| 892 | return((Mvf_Function_t *)newFunction); |
---|
| 893 | } |
---|
| 894 | |
---|
| 895 | |
---|
| 896 | /**Function******************************************************************** |
---|
| 897 | |
---|
| 898 | Synopsis [Returns the number of BDD nodes of an array of multi-valued |
---|
| 899 | functions.] |
---|
| 900 | |
---|
| 901 | Description [Returns the number of BDD nodes of an array of multi-valued |
---|
| 902 | functions. A node shared by several functions is counted only once.] |
---|
| 903 | |
---|
| 904 | SideEffects [] |
---|
| 905 | |
---|
| 906 | ******************************************************************************/ |
---|
| 907 | long |
---|
| 908 | Mvf_FunctionArrayComputeNumBddNodes( |
---|
| 909 | array_t * functionArray) |
---|
| 910 | { |
---|
| 911 | int i; |
---|
| 912 | long numNodes; |
---|
| 913 | array_t *mddArray = array_alloc(mdd_t *, 0); |
---|
| 914 | |
---|
| 915 | /* Build an array of all MDDs */ |
---|
| 916 | for(i = 0; i < array_n(functionArray); i++) { |
---|
| 917 | int j; |
---|
| 918 | array_t *function = (array_t *)array_fetch(Mvf_Function_t *, functionArray, i); |
---|
| 919 | |
---|
| 920 | for(j = 0; j < array_n(function); j++) { |
---|
| 921 | mdd_t *component = array_fetch(mdd_t *, function, j); |
---|
| 922 | array_insert_last(mdd_t *, mddArray, component); |
---|
| 923 | } |
---|
| 924 | } |
---|
| 925 | |
---|
| 926 | /* Compute the reduced number of bdd nodes */ |
---|
| 927 | numNodes = mdd_size_multiple(mddArray); |
---|
| 928 | array_free(mddArray); |
---|
| 929 | |
---|
| 930 | return(numNodes); |
---|
| 931 | } |
---|
| 932 | |
---|
| 933 | |
---|
| 934 | /**Function******************************************************************** |
---|
| 935 | |
---|
| 936 | Synopsis [Returns the number of BDD nodes of a multi-valued function.] |
---|
| 937 | |
---|
| 938 | SideEffects [] |
---|
| 939 | |
---|
| 940 | ******************************************************************************/ |
---|
| 941 | long |
---|
| 942 | Mvf_FunctionComputeNumBddNodes( |
---|
| 943 | Mvf_Function_t * function) |
---|
| 944 | { |
---|
| 945 | return(mdd_size_multiple((array_t *)function)); |
---|
| 946 | } |
---|
| 947 | |
---|
| 948 | |
---|
| 949 | /**Function******************************************************************** |
---|
| 950 | |
---|
| 951 | Synopsis [Returns the index of the first component of a multi-valued |
---|
| 952 | function that is equal to the tautology.] |
---|
| 953 | |
---|
| 954 | Description [Returns the index of the first component of a multi-valued |
---|
| 955 | function that is equal to the tautology. If the multi-valued function is |
---|
| 956 | deterministic, this component is unique. Returns -1 if such a component is |
---|
| 957 | not found. It is an error to call this function with a multi-valued function |
---|
| 958 | that contains null MDDs.] |
---|
| 959 | |
---|
| 960 | SideEffects [] |
---|
| 961 | |
---|
| 962 | ******************************************************************************/ |
---|
| 963 | int |
---|
| 964 | Mvf_FunctionFindFirstTrueComponent( |
---|
| 965 | Mvf_Function_t * function) |
---|
| 966 | { |
---|
| 967 | int i; |
---|
| 968 | array_t *mddArray = (array_t *) function; |
---|
| 969 | |
---|
| 970 | for(i = 0; i < array_n(mddArray); i++) { |
---|
| 971 | mdd_t *component = array_fetch(mdd_t *, mddArray, i); |
---|
| 972 | if (mdd_is_tautology(component, 1)) { |
---|
| 973 | return(i); |
---|
| 974 | } |
---|
| 975 | } |
---|
| 976 | return(-1); |
---|
| 977 | } |
---|
| 978 | |
---|
| 979 | /**Function******************************************************************** |
---|
| 980 | |
---|
| 981 | Synopsis [Hashes A multi-valued function.] |
---|
| 982 | |
---|
| 983 | Description [Hashes A multi-valued function. Each component's top variable id |
---|
| 984 | is multiplied by the index of component (+ 1). Returns the sum of this computation |
---|
| 985 | on every component. It is an error to call this function with a null |
---|
| 986 | multi-valued function.] |
---|
| 987 | |
---|
| 988 | SideEffects [] |
---|
| 989 | |
---|
| 990 | ******************************************************************************/ |
---|
| 991 | int |
---|
| 992 | Mvf_FunctionComputeHashValue( |
---|
| 993 | Mvf_Function_t * function) |
---|
| 994 | { |
---|
| 995 | int i; |
---|
| 996 | int result = 0; |
---|
| 997 | array_t *mddArray = (array_t *) function; |
---|
| 998 | |
---|
| 999 | for(i = 0; i < array_n(mddArray); i++) { |
---|
| 1000 | mdd_t *component = array_fetch(mdd_t *, mddArray, i); |
---|
| 1001 | result += (mdd_top_var_id(component)) * (i + 1); |
---|
| 1002 | } |
---|
| 1003 | return(result); |
---|
| 1004 | } |
---|
| 1005 | |
---|
| 1006 | |
---|
| 1007 | |
---|
| 1008 | /**Function******************************************************************** |
---|
| 1009 | |
---|
| 1010 | Synopsis [Computes the variables in the true support of a function.] |
---|
| 1011 | |
---|
| 1012 | Description [Computes the variables in the true support of a function. Does |
---|
| 1013 | this by taking the union of the result of mdd_get_support on each component |
---|
| 1014 | of the function. Returns the support as an (ascending) ordered array of MDD |
---|
| 1015 | ids. If the function is a constant, then a NULL array is returned, and the |
---|
| 1016 | constant value of the function is written in the "value" variable.] |
---|
| 1017 | |
---|
| 1018 | SideEffects [] |
---|
| 1019 | |
---|
| 1020 | SeeAlso [Mvf_FunctionTestIsConstant] |
---|
| 1021 | |
---|
| 1022 | ******************************************************************************/ |
---|
| 1023 | array_t * |
---|
| 1024 | Mvf_FunctionComputeSupport( |
---|
| 1025 | Mvf_Function_t *function, |
---|
| 1026 | mdd_manager *mddMgr, |
---|
| 1027 | int *value) |
---|
| 1028 | { |
---|
| 1029 | int i; |
---|
| 1030 | mdd_t *component; |
---|
| 1031 | array_t *totalSupportArray; |
---|
| 1032 | var_set_t *totalSupportSet; |
---|
| 1033 | int numMddVars = array_n(mdd_ret_mvar_list(mddMgr)); |
---|
| 1034 | |
---|
| 1035 | /* |
---|
| 1036 | * Handle the case where function is just a constant. |
---|
| 1037 | */ |
---|
| 1038 | if (Mvf_FunctionTestIsConstant(function, value)) { |
---|
| 1039 | return NIL(array_t); |
---|
| 1040 | } |
---|
| 1041 | |
---|
| 1042 | /* |
---|
| 1043 | * Accumulate the union of supports of the function components into a bit |
---|
| 1044 | * array. |
---|
| 1045 | */ |
---|
| 1046 | totalSupportArray = array_alloc(int, 0); |
---|
| 1047 | totalSupportSet = var_set_new(numMddVars); |
---|
| 1048 | |
---|
| 1049 | Mvf_FunctionForEachComponent(function, i, component) { |
---|
| 1050 | int j; |
---|
| 1051 | int mddVarId; |
---|
| 1052 | array_t *support = mdd_get_support(mddMgr, component); |
---|
| 1053 | |
---|
| 1054 | arrayForEachItem(int, support, j, mddVarId) { |
---|
| 1055 | var_set_set_elt(totalSupportSet, mddVarId); |
---|
| 1056 | } |
---|
| 1057 | array_free(support); |
---|
| 1058 | } |
---|
| 1059 | |
---|
| 1060 | /* Convert the bit array to an array of mdd ids. */ |
---|
| 1061 | for (i = 0; i < numMddVars; i++) { |
---|
| 1062 | if (var_set_get_elt(totalSupportSet, i)) { |
---|
| 1063 | array_insert_last(int, totalSupportArray, i); |
---|
| 1064 | } |
---|
| 1065 | } |
---|
| 1066 | var_set_free(totalSupportSet); |
---|
| 1067 | |
---|
| 1068 | return totalSupportArray; |
---|
| 1069 | } |
---|
| 1070 | |
---|
| 1071 | /*---------------------------------------------------------------------------*/ |
---|
| 1072 | /* Definition of internal functions */ |
---|
| 1073 | /*---------------------------------------------------------------------------*/ |
---|
| 1074 | |
---|
| 1075 | |
---|
| 1076 | /*---------------------------------------------------------------------------*/ |
---|
| 1077 | /* Definition of static functions */ |
---|
| 1078 | /*---------------------------------------------------------------------------*/ |
---|
| 1079 | |
---|