VIS

src/mvf/mvfMvf.c

Go to the documentation of this file.
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