VIS
|
00001 00034 #include "mvfInt.h" 00035 00036 static char rcsid[] UNUSED = "$Id: mvfMvf.c,v 1.6 2002/09/08 21:48:24 fabio Exp $"; 00037 00040 /*---------------------------------------------------------------------------*/ 00041 /* Static function prototypes */ 00042 /*---------------------------------------------------------------------------*/ 00043 00044 00048 /*---------------------------------------------------------------------------*/ 00049 /* Definition of exported functions */ 00050 /*---------------------------------------------------------------------------*/ 00051 00061 void 00062 Mvf_Init(void) 00063 { 00064 } 00065 00066 00076 void 00077 Mvf_End(void) 00078 { 00079 } 00080 00081 00094 Mvf_Function_t * 00095 Mvf_FunctionAlloc( 00096 mdd_manager *mddManager, 00097 int n) 00098 { 00099 int i; 00100 array_t *mddArray = array_alloc(mdd_t *, n); 00101 00102 for (i = 0; i < n; i++) { 00103 array_insert(mdd_t *, mddArray, i, mdd_zero(mddManager)); 00104 } 00105 return ((Mvf_Function_t *) mddArray); 00106 } 00107 00108 00121 void 00122 Mvf_FunctionAddMintermsToComponent( 00123 Mvf_Function_t *function, 00124 int i, 00125 mdd_t *g) 00126 { 00127 mdd_t *oldComponent; 00128 mdd_t *newComponent; 00129 array_t *mddArray = (array_t *) function; 00130 00131 assert((i >= 0) && (i < array_n(mddArray))); 00132 00133 oldComponent = array_fetch(mdd_t *, mddArray, i); 00134 newComponent = mdd_or(oldComponent, g, 1, 1); 00135 mdd_free(oldComponent); 00136 array_insert(mdd_t *, mddArray, i, newComponent); 00137 } 00138 00139 00154 mdd_t * 00155 Mvf_FunctionBuildRelationWithVariable( 00156 Mvf_Function_t *function, 00157 int mddId) 00158 { 00159 int i; 00160 mvar_type mddVar; 00161 array_t *mddArray = (array_t *) function; 00162 mdd_manager *mddManager = Mvf_FunctionReadMddManager(function); 00163 mdd_t *sumOfFactors = mdd_zero(mddManager); 00164 00165 mddVar = array_fetch(mvar_type, mdd_ret_mvar_list(mddManager), mddId); 00166 assert(mddVar.values == Mvf_FunctionReadNumComponents(function)); 00167 00168 for (i = 0; i < array_n(mddArray); i++) { 00169 mdd_t *varLiteral; 00170 mdd_t *factor; 00171 mdd_t *tmp; 00172 mdd_t *fComponent = array_fetch(mdd_t *, mddArray, i); 00173 00174 varLiteral = mdd_eq_c(mddManager, mddId, i); 00175 factor = mdd_and(fComponent, varLiteral, 1, 1); 00176 mdd_free(varLiteral); 00177 00178 /* Take the or of the sumOfFactors so far and the new factor */ 00179 tmp = mdd_or(sumOfFactors, factor, 1, 1); 00180 mdd_free(factor); 00181 mdd_free(sumOfFactors); 00182 sumOfFactors = tmp; 00183 } 00184 00185 return sumOfFactors; 00186 } 00187 00188 00202 int 00203 Mvf_FunctionReadNumComponents( 00204 Mvf_Function_t *function) 00205 { 00206 return (array_n((array_t *) function)); 00207 } 00208 00209 00222 mdd_manager * 00223 Mvf_FunctionReadMddManager( 00224 Mvf_Function_t *function) 00225 { 00226 mdd_t *component = array_fetch(mdd_t *, (array_t *) function, 0); 00227 00228 return (mdd_get_manager(component)); 00229 } 00230 00231 00244 Mvf_Function_t * 00245 Mvf_FunctionDuplicate( 00246 Mvf_Function_t *function) 00247 { 00248 return ((Mvf_Function_t *) mdd_array_duplicate((array_t *) function)); 00249 } 00250 00251 00264 void 00265 Mvf_FunctionFree( 00266 Mvf_Function_t *function) 00267 { 00268 mdd_array_free((array_t *) function); 00269 } 00270 00271 00284 void 00285 Mvf_FunctionArrayFree( 00286 array_t *functionArray) 00287 { 00288 int i; 00289 00290 if (functionArray != NIL(array_t)) { 00291 for (i = 0; i < array_n(functionArray); i++) { 00292 Mvf_Function_t *function = array_fetch(Mvf_Function_t *, functionArray, i); 00293 Mvf_FunctionFree(function); 00294 } 00295 array_free(functionArray); 00296 } 00297 } 00298 00311 mdd_t * 00312 Mvf_FunctionObtainComponent( 00313 Mvf_Function_t *function, 00314 int i) 00315 { 00316 mdd_t *component = array_fetch(mdd_t *, (array_t *) function, i); 00317 return (mdd_dup(component)); 00318 } 00319 00334 mdd_t * 00335 Mvf_FunctionReadComponent( 00336 Mvf_Function_t *function, 00337 int i) 00338 { 00339 mdd_t *component = array_fetch(mdd_t *, (array_t *) function, i); 00340 return (component); 00341 } 00342 00343 00359 Mvf_Function_t * 00360 Mvf_FunctionCreateFromVariable( 00361 mdd_manager *mddManager, 00362 int mddId) 00363 { 00364 int i; 00365 array_t *mvar_list = mdd_ret_mvar_list(mddManager); 00366 mvar_type varInfo; 00367 array_t *result; 00368 00369 assert(mddId >= 0); 00370 00371 varInfo = array_fetch(mvar_type, mvar_list, mddId); 00372 result = array_alloc(mdd_t *, varInfo.values); 00373 00374 for(i = 0; i < varInfo.values; i++) { 00375 mdd_t *literal; 00376 00377 literal = mdd_eq_c(mddManager, mddId, i); 00378 array_insert(mdd_t *, result, i, literal); 00379 } 00380 00381 return ((Mvf_Function_t *) result); 00382 } 00383 00384 00401 Mvf_Function_t * 00402 Mvf_FunctionComposeWithFunctionArray( 00403 Mvf_Function_t *f, 00404 array_t *mddIdArray /* of int */, 00405 array_t *functionArray /* of Mvf_Function_t* */) 00406 { 00407 Mvf_Function_t *result; 00408 int i; 00409 00410 assert(array_n(mddIdArray) == array_n(functionArray)); 00411 00412 /* Make an initial copy of the function */ 00413 result = Mvf_FunctionDuplicate(f); 00414 00415 for(i = 0; i < array_n(mddIdArray); i++) { 00416 Mvf_Function_t *tmp; 00417 int mddId = array_fetch(int, mddIdArray, i); 00418 Mvf_Function_t *g = array_fetch(Mvf_Function_t *, functionArray, i); 00419 00420 tmp = Mvf_FunctionComposeWithFunction(result, mddId, g); 00421 00422 Mvf_FunctionFree(result); 00423 result = tmp; 00424 } 00425 00426 return result; 00427 } 00428 00429 00450 Mvf_Function_t * 00451 Mvf_FunctionComposeWithFunction( 00452 Mvf_Function_t *f, 00453 int mddId, 00454 Mvf_Function_t *g) 00455 { 00456 mdd_t *sumOfFactors; 00457 array_t *result; 00458 array_t *values; 00459 int i; 00460 mdd_manager *mddManager = Mvf_FunctionReadMddManager(f); 00461 00462 /* Allocate array to hold values for the literal and the result */ 00463 result = array_alloc(mdd_t *, array_n(f)); 00464 00465 /* 00466 * Create the sum of factors (x==i * gi). This function will verify that the 00467 * domain of x and the range of g have the same cardinality. 00468 */ 00469 sumOfFactors = Mvf_FunctionBuildRelationWithVariable(g, mddId); 00470 00471 /* 00472 * Result is an array of mdd_t * , result[i] = Exists(x) (f[i] * sumOfFactors) 00473 * The array values holds now the index of the variable to smooth out. 00474 */ 00475 values = array_alloc(int, 1); 00476 array_insert(int, values, 0, mddId); 00477 for(i = 0; i < array_n(f); i++) { 00478 mdd_t *functionUnit = array_fetch(mdd_t *, f, i); 00479 mdd_t *tmp = mdd_and_smooth(mddManager, functionUnit, sumOfFactors, values); 00480 00481 array_insert(mdd_t *, result, i, tmp); 00482 } 00483 00484 /* Clean up */ 00485 array_free(values); 00486 mdd_free(sumOfFactors); 00487 00488 return ((Mvf_Function_t *) result); 00489 } 00490 00491 00510 mdd_t * 00511 Mvf_MddComposeWithFunction( 00512 mdd_t *f, 00513 int mddId, 00514 Mvf_Function_t *g) 00515 { 00516 mdd_t *sumOfFactors; 00517 mdd_t *result; 00518 array_t *values; 00519 mdd_manager *mddManager = mdd_get_manager(f); 00520 00521 /* 00522 * Create the sum of factors (x==i * gi). This function will verify that the 00523 * domain of x and the range of g have the same cardinality. 00524 */ 00525 sumOfFactors = Mvf_FunctionBuildRelationWithVariable(g, mddId); 00526 00527 /* Result is an mdd_t * , result = Exists(x) (f * sumOfFactors) */ 00528 values = array_alloc(int, 1); 00529 array_insert(int, values, 0, mddId); 00530 result = mdd_and_smooth(mddManager, f, sumOfFactors, values); 00531 00532 /* Clean up */ 00533 array_free(values); 00534 mdd_free(sumOfFactors); 00535 00536 return result; 00537 } 00538 00539 00556 boolean 00557 Mvf_FunctionTestIsDeterministic( 00558 Mvf_Function_t *function) 00559 { 00560 int i; 00561 array_t *mddArray = (array_t *) function; 00562 int numComponents = array_n(mddArray); 00563 mdd_t *sum; 00564 00565 if (numComponents == 0) { 00566 return TRUE; 00567 } 00568 00569 sum = mdd_dup(array_fetch(mdd_t *, mddArray, 0)); 00570 00571 for (i = 1; i < numComponents; i++) { 00572 mdd_t *temp = sum; 00573 mdd_t *ithComponent = array_fetch(mdd_t *, mddArray, i); 00574 boolean intersectionIsEmpty = mdd_lequal(ithComponent, sum, 1, 0); 00575 00576 /* If the intersection is not empty, then return FALSE. */ 00577 if (!intersectionIsEmpty) { 00578 mdd_free(sum); 00579 return FALSE; 00580 } 00581 00582 sum = mdd_or(temp, ithComponent, 1, 1); 00583 mdd_free(temp); 00584 } 00585 mdd_free(sum); 00586 00587 /* The components are pairwise disjoint. */ 00588 return TRUE; 00589 } 00590 00591 00608 boolean 00609 Mvf_FunctionTestIsCompletelySpecified( 00610 Mvf_Function_t *function) 00611 { 00612 mdd_t *sum = Mvf_FunctionComputeDomain(function); 00613 boolean sumIsTautology = mdd_is_tautology(sum, 1); 00614 00615 mdd_free(sum); 00616 return sumIsTautology; 00617 } 00618 00619 00636 boolean 00637 Mvf_FunctionTestIsConstant( 00638 Mvf_Function_t *function, 00639 int *constantValue /* return value */ ) 00640 { 00641 int i; 00642 array_t *mddArray = (array_t *) function; 00643 int numComponents = array_n(mddArray); 00644 int numTautComps = 0; 00645 00646 for (i = 0; i < numComponents; i++) { 00647 mdd_t *ithComponent = array_fetch(mdd_t *, mddArray, i); 00648 00649 if (mdd_is_tautology(ithComponent, 1)) { 00650 *constantValue = i; 00651 numTautComps++; 00652 } 00653 else if (!mdd_is_tautology(ithComponent, 0)) { 00654 /* this component is not 1 nor 0, so function can't be a constant */ 00655 return FALSE; 00656 } 00657 /* else, must be the zero function */ 00658 } 00659 00660 return (numTautComps == 1); 00661 } 00662 00663 00680 boolean 00681 Mvf_FunctionTestIsNonDeterministicConstant( 00682 Mvf_Function_t *function) 00683 { 00684 int i; 00685 array_t *mddArray = (array_t *) function; 00686 int numComponents = array_n(mddArray); 00687 int numTautComps = 0; 00688 00689 for (i = 0; i < numComponents; i++) { 00690 mdd_t *ithComponent = array_fetch(mdd_t *, mddArray, i); 00691 00692 if (mdd_is_tautology(ithComponent, 1)) { 00693 numTautComps++; 00694 } 00695 else if (!mdd_is_tautology(ithComponent, 0)) { 00696 /* this component is not 1 nor 0, so function can't be a non-det constant */ 00697 return FALSE; 00698 } 00699 /* else, must be the zero function */ 00700 } 00701 00702 return (numTautComps > 1); 00703 } 00704 00705 00720 mdd_t * 00721 Mvf_FunctionComputeDomain( 00722 Mvf_Function_t *function) 00723 { 00724 array_t *mddArray = (array_t *) function; 00725 mdd_manager *mddManager = Mvf_FunctionReadMddManager(function); 00726 mdd_t *sum = mdd_multiway_or(mddManager, mddArray); 00727 00728 return sum; 00729 } 00730 00731 00743 boolean 00744 Mvf_FunctionTestIsWellFormed( 00745 Mvf_Function_t *function) 00746 { 00747 return (Mvf_FunctionTestIsDeterministic(function) 00748 && Mvf_FunctionTestIsCompletelySpecified(function)); 00749 } 00750 00751 00763 boolean 00764 Mvf_FunctionTestIsEqualToFunction( 00765 Mvf_Function_t *function1, 00766 Mvf_Function_t *function2) 00767 { 00768 int i; 00769 array_t *mddArray1 = (array_t *) function1; 00770 array_t *mddArray2 = (array_t *) function2; 00771 int numComponents = array_n(mddArray1); 00772 00773 if (numComponents != array_n(mddArray2)) { 00774 return FALSE; 00775 } 00776 00777 for (i = 0; i < numComponents; i++) { 00778 mdd_t *mdd1 = array_fetch(mdd_t *, mddArray1, i); 00779 mdd_t *mdd2 = array_fetch(mdd_t *, mddArray2, i); 00780 if (!mdd_equal(mdd1, mdd2)) { 00781 return FALSE; 00782 } 00783 } 00784 00785 return TRUE; 00786 } 00787 00788 00802 mdd_t * 00803 Mvf_FunctionsComputeEquivalentSet( 00804 Mvf_Function_t *function1, 00805 Mvf_Function_t *function2) 00806 { 00807 int i; 00808 array_t *mddArray1 = (array_t *) function1; 00809 array_t *mddArray2 = (array_t *) function2; 00810 int numComponents = array_n(mddArray1); 00811 mdd_manager *mddManager = Mvf_FunctionReadMddManager(function1); 00812 mdd_t *product = mdd_one(mddManager); 00813 00814 assert(numComponents == array_n(mddArray2)); 00815 00816 for (i = 0; i < numComponents; i++) { 00817 mdd_t *mdd1 = array_fetch(mdd_t *, mddArray1, i); 00818 mdd_t *mdd2 = array_fetch(mdd_t *, mddArray2, i); 00819 mdd_t *xnor = mdd_xnor(mdd1, mdd2); 00820 mdd_t *temp = product; 00821 00822 product = mdd_and(temp, xnor, 1, 1); 00823 mdd_free(temp); 00824 mdd_free(xnor); 00825 } 00826 00827 return product; 00828 } 00829 00830 00843 Mvf_Function_t * 00844 Mvf_FunctionCofactor( 00845 Mvf_Function_t * function, 00846 mdd_t * wrtMdd) 00847 { 00848 int i; 00849 array_t *mddArray = (array_t *) function; 00850 int numComponents = array_n(mddArray); 00851 array_t *newFunction = array_alloc(mdd_t *, numComponents); 00852 00853 for(i = 0; i < numComponents; i++) { 00854 mdd_t *component = array_fetch(mdd_t *, mddArray, i); 00855 mdd_t *cofactor = bdd_cofactor(component, wrtMdd); 00856 00857 array_insert(mdd_t *, newFunction, i, cofactor); 00858 } 00859 return((Mvf_Function_t *)newFunction); 00860 } 00861 00862 00876 Mvf_Function_t * 00877 Mvf_FunctionMinimize( 00878 Mvf_Function_t *f, 00879 mdd_t *c) 00880 { 00881 int i; 00882 array_t *mddArray = (array_t *) f; 00883 int numComponents = array_n(mddArray); 00884 array_t *newFunction = array_alloc(mdd_t *, numComponents); 00885 00886 for(i = 0; i < numComponents; i++) { 00887 mdd_t *component = array_fetch(mdd_t *, mddArray, i); 00888 mdd_t *minimize = bdd_minimize(component, c); 00889 00890 array_insert(mdd_t *, newFunction, i, minimize); 00891 } 00892 return((Mvf_Function_t *)newFunction); 00893 } 00894 00895 00907 long 00908 Mvf_FunctionArrayComputeNumBddNodes( 00909 array_t * functionArray) 00910 { 00911 int i; 00912 long numNodes; 00913 array_t *mddArray = array_alloc(mdd_t *, 0); 00914 00915 /* Build an array of all MDDs */ 00916 for(i = 0; i < array_n(functionArray); i++) { 00917 int j; 00918 array_t *function = (array_t *)array_fetch(Mvf_Function_t *, functionArray, i); 00919 00920 for(j = 0; j < array_n(function); j++) { 00921 mdd_t *component = array_fetch(mdd_t *, function, j); 00922 array_insert_last(mdd_t *, mddArray, component); 00923 } 00924 } 00925 00926 /* Compute the reduced number of bdd nodes */ 00927 numNodes = mdd_size_multiple(mddArray); 00928 array_free(mddArray); 00929 00930 return(numNodes); 00931 } 00932 00933 00941 long 00942 Mvf_FunctionComputeNumBddNodes( 00943 Mvf_Function_t * function) 00944 { 00945 return(mdd_size_multiple((array_t *)function)); 00946 } 00947 00948 00963 int 00964 Mvf_FunctionFindFirstTrueComponent( 00965 Mvf_Function_t * function) 00966 { 00967 int i; 00968 array_t *mddArray = (array_t *) function; 00969 00970 for(i = 0; i < array_n(mddArray); i++) { 00971 mdd_t *component = array_fetch(mdd_t *, mddArray, i); 00972 if (mdd_is_tautology(component, 1)) { 00973 return(i); 00974 } 00975 } 00976 return(-1); 00977 } 00978 00991 int 00992 Mvf_FunctionComputeHashValue( 00993 Mvf_Function_t * function) 00994 { 00995 int i; 00996 int result = 0; 00997 array_t *mddArray = (array_t *) function; 00998 00999 for(i = 0; i < array_n(mddArray); i++) { 01000 mdd_t *component = array_fetch(mdd_t *, mddArray, i); 01001 result += (mdd_top_var_id(component)) * (i + 1); 01002 } 01003 return(result); 01004 } 01005 01006 01007 01023 array_t * 01024 Mvf_FunctionComputeSupport( 01025 Mvf_Function_t *function, 01026 mdd_manager *mddMgr, 01027 int *value) 01028 { 01029 int i; 01030 mdd_t *component; 01031 array_t *totalSupportArray; 01032 var_set_t *totalSupportSet; 01033 int numMddVars = array_n(mdd_ret_mvar_list(mddMgr)); 01034 01035 /* 01036 * Handle the case where function is just a constant. 01037 */ 01038 if (Mvf_FunctionTestIsConstant(function, value)) { 01039 return NIL(array_t); 01040 } 01041 01042 /* 01043 * Accumulate the union of supports of the function components into a bit 01044 * array. 01045 */ 01046 totalSupportArray = array_alloc(int, 0); 01047 totalSupportSet = var_set_new(numMddVars); 01048 01049 Mvf_FunctionForEachComponent(function, i, component) { 01050 int j; 01051 int mddVarId; 01052 array_t *support = mdd_get_support(mddMgr, component); 01053 01054 arrayForEachItem(int, support, j, mddVarId) { 01055 var_set_set_elt(totalSupportSet, mddVarId); 01056 } 01057 array_free(support); 01058 } 01059 01060 /* Convert the bit array to an array of mdd ids. */ 01061 for (i = 0; i < numMddVars; i++) { 01062 if (var_set_get_elt(totalSupportSet, i)) { 01063 array_insert_last(int, totalSupportArray, i); 01064 } 01065 } 01066 var_set_free(totalSupportSet); 01067 01068 return totalSupportArray; 01069 } 01070 01071 /*---------------------------------------------------------------------------*/ 01072 /* Definition of internal functions */ 01073 /*---------------------------------------------------------------------------*/ 01074 01075 01076 /*---------------------------------------------------------------------------*/ 01077 /* Definition of static functions */ 01078 /*---------------------------------------------------------------------------*/ 01079