VIS

src/img/imgTfmUtil.c

Go to the documentation of this file.
00001 
00033 #include "imgInt.h"
00034 
00035 static char rcsid[] UNUSED = "$Id: imgTfmUtil.c,v 1.23 2005/04/23 14:30:55 jinh Exp $";
00036 
00037 /*---------------------------------------------------------------------------*/
00038 /* Constant declarations                                                     */
00039 /*---------------------------------------------------------------------------*/
00040 
00041 /*---------------------------------------------------------------------------*/
00042 /* Type declarations                                                         */
00043 /*---------------------------------------------------------------------------*/
00044 
00045 /*---------------------------------------------------------------------------*/
00046 /* Structure declarations                                                    */
00047 /*---------------------------------------------------------------------------*/
00048 
00049 /*---------------------------------------------------------------------------*/
00050 /* Variable declarations                                                     */
00051 /*---------------------------------------------------------------------------*/
00052 
00053 static  double  *signatures; /* used in finding dependent variables */
00054 
00055 /*---------------------------------------------------------------------------*/
00056 /* Macro declarations                                                        */
00057 /*---------------------------------------------------------------------------*/
00058 
00061 /*---------------------------------------------------------------------------*/
00062 /* Static function prototypes                                                */
00063 /*---------------------------------------------------------------------------*/
00064 
00065 static int SignatureCompare(int *ptrX, int *ptrY);
00066 static int CompareBddPointer(const void *e1, const void *e2);
00067 
00071 /*---------------------------------------------------------------------------*/
00072 /* Definition of exported functions                                          */
00073 /*---------------------------------------------------------------------------*/
00074 
00075 
00076 /*---------------------------------------------------------------------------*/
00077 /* Definition of internal functions                                          */
00078 /*---------------------------------------------------------------------------*/
00079 
00080 
00090 void
00091 ImgVectorConstrain(ImgTfmInfo_t *info, array_t *vector, mdd_t *constraint,
00092                    array_t *relationArray, array_t **newVector, mdd_t **cube,
00093                    array_t **newRelationArray, mdd_t **cofactorCube,
00094                    mdd_t **abstractCube, boolean singleVarFlag)
00095 {
00096   mdd_t                 *new_, *res, *old, *tmp;
00097   ImgComponent_t        *comp, *comp1;
00098   array_t               *vector1;
00099   int                   i, index;
00100   int                   dynStatus, dynOff;
00101   bdd_reorder_type_t    dynMethod;
00102   st_table              *equivTable;
00103   int                   *ptr, *regularPtr;
00104   int                   n, pos;
00105   mdd_t                 *cofactor, *abstract, *nsVar, *constIntermediate;
00106   array_t               *tmpRelationArray;
00107   int                   size;
00108 
00109   old = mdd_one(info->manager);
00110   vector1 = array_alloc(ImgComponent_t *, 0);
00111   dynStatus = 0;
00112 
00113   if (singleVarFlag)
00114     dynOff = 0;
00115   else
00116     dynOff = 1;
00117   if (dynOff) {
00118     dynStatus = bdd_reordering_status(info->manager, &dynMethod);
00119     if (dynStatus != 0)
00120       bdd_dynamic_reordering_disable(info->manager);
00121   }
00122 
00123   if (relationArray) {
00124     cofactor = mdd_one(info->manager);
00125     abstract = mdd_one(info->manager);
00126   } else {
00127     cofactor = NIL(mdd_t);
00128     abstract = NIL(mdd_t);
00129   }
00130 
00131   if (info->nIntermediateVars) {
00132     size = ImgVectorFunctionSize(vector);
00133     if (size == array_n(vector))
00134       constIntermediate = NIL(mdd_t);
00135     else
00136       constIntermediate = mdd_one(info->manager);
00137   } else
00138     constIntermediate = NIL(mdd_t);
00139 
00140   n = 0;
00141   equivTable = st_init_table(st_ptrcmp, st_ptrhash);
00142   index = (int)bdd_top_var_id(constraint);
00143   for (i = 0; i < array_n(vector); i++) {
00144     comp = array_fetch(ImgComponent_t *, vector, i);
00145     if (!bdd_is_tautology(constraint, 1)) {
00146       if (singleVarFlag) {
00147         if (comp->support[index])
00148           res = bdd_cofactor(comp->func, constraint);
00149         else
00150           res = mdd_dup(comp->func);
00151       } else
00152         res = bdd_cofactor(comp->func, constraint);
00153     } else
00154       res = mdd_dup(comp->func);
00155     if (bdd_is_tautology(res, 1)) {
00156       if (comp->intermediate) {
00157         tmp = constIntermediate;
00158         constIntermediate = mdd_and(tmp, comp->var, 1, 1);
00159         mdd_free(tmp);
00160         mdd_free(res);
00161         continue;
00162       }
00163       new_ = mdd_and(comp->var, old, 1, 1);
00164       mdd_free(old);
00165       mdd_free(res);
00166       old = new_;
00167       if (cofactor) {
00168         nsVar = ImgSubstitute(comp->var, info->functionData, Img_D2R_c);
00169         tmp = cofactor;
00170         cofactor = mdd_and(tmp, nsVar, 1, 1);
00171         mdd_free(tmp);
00172         mdd_free(nsVar);
00173       }
00174     } else if (bdd_is_tautology(res, 0)) {
00175       if (comp->intermediate) {
00176         tmp = constIntermediate;
00177         constIntermediate = mdd_and(tmp, comp->var, 1, 0);
00178         mdd_free(tmp);
00179         mdd_free(res);
00180         continue;
00181       }
00182       new_ = mdd_and(comp->var, old, 0, 1);
00183       mdd_free(old);
00184       mdd_free(res);
00185       old = new_;
00186       if (cofactor) {
00187         nsVar = ImgSubstitute(comp->var, info->functionData, Img_D2R_c);
00188         tmp = cofactor;
00189         cofactor = mdd_and(tmp, nsVar, 1, 0);
00190         mdd_free(tmp);
00191         mdd_free(nsVar);
00192       }
00193     } else {
00194       if (comp->intermediate) {
00195         comp1 = ImgComponentAlloc(info);
00196         comp1->var = mdd_dup(comp->var);
00197         comp1->func = res;
00198         comp1->intermediate = 1;
00199         if (mdd_equal(res, comp->func))
00200           ImgSupportCopy(info, comp1->support, comp->support);
00201         else
00202           ImgComponentGetSupport(comp1);
00203         array_insert_last(ImgComponent_t *, vector1, comp1);
00204         n++;
00205         continue;
00206       }
00207       ptr = (int *)bdd_pointer(res);
00208       regularPtr = (int *)((unsigned long)ptr & ~01);
00209       if (st_lookup_int(equivTable, (char *)regularPtr, &pos)) {
00210         comp1 = array_fetch(ImgComponent_t *, vector1, pos);
00211         if (mdd_equal(res, comp1->func))
00212           tmp = mdd_xnor(comp->var, comp1->var);
00213         else
00214           tmp = mdd_xor(comp->var, comp1->var);
00215         new_ = mdd_and(tmp, old, 1, 1);
00216         mdd_free(tmp);
00217         mdd_free(old);
00218         mdd_free(res);
00219         old = new_;
00220         if (abstract) {
00221           nsVar = ImgSubstitute(comp->var, info->functionData, Img_D2R_c);
00222           tmp = abstract;
00223           abstract = mdd_and(tmp, nsVar, 1, 1);
00224           mdd_free(tmp);
00225           mdd_free(nsVar);
00226         }
00227       } else {
00228         comp1 = ImgComponentAlloc(info);
00229         comp1->var = mdd_dup(comp->var);
00230         comp1->func = res;
00231         if (mdd_equal(res, comp->func))
00232           ImgSupportCopy(info, comp1->support, comp->support);
00233         else
00234           ImgComponentGetSupport(comp1);
00235         array_insert_last(ImgComponent_t *, vector1, comp1);
00236         st_insert(equivTable, (char *)regularPtr, (char *)(long)n);
00237         n++;
00238       }
00239     }
00240   }
00241   st_free_table(equivTable);
00242 
00243   if (dynOff && dynStatus != 0) {
00244     bdd_dynamic_reordering(info->manager, dynMethod,
00245                            BDD_REORDER_VERBOSITY_DEFAULT);
00246   }
00247 
00248   if (constIntermediate) {
00249     if (!bdd_is_tautology(constIntermediate, 1)) {
00250       mdd_t     *tmpCofactor, *tmpAbstract;
00251 
00252       if (relationArray) {
00253         vector1 = ImgComposeConstIntermediateVars(info, vector1,
00254                                                   constIntermediate,
00255                                                   &tmpCofactor, &tmpAbstract,
00256                                                   &old, NIL(mdd_t *));
00257         if (!bdd_is_tautology(tmpCofactor, 1)) {
00258           tmp = cofactor;
00259           cofactor = mdd_and(tmp, tmpCofactor, 1, 1);
00260           mdd_free(tmp);
00261         }
00262         mdd_free(tmpCofactor);
00263         if (!bdd_is_tautology(tmpAbstract, 1)) {
00264           tmp = abstract;
00265           abstract = mdd_and(tmp, tmpAbstract, 1, 1);
00266           mdd_free(tmp);
00267         }
00268         mdd_free(tmpAbstract);
00269         tmp = cofactor;
00270         cofactor = mdd_and(tmp, constIntermediate, 1, 1);
00271         mdd_free(tmp);
00272       } else {
00273         vector1 = ImgComposeConstIntermediateVars(info, vector1,
00274                                                   constIntermediate,
00275                                                   NIL(mdd_t *), NIL(mdd_t *),
00276                                                   &old, NIL(mdd_t *));
00277       }
00278     }
00279     mdd_free(constIntermediate);
00280   }
00281 
00282   if (info->option->sortVectorFlag)
00283     array_sort(vector1, CompareBddPointer);
00284 
00285   if (relationArray && newRelationArray) {
00286     if (singleVarFlag) {
00287       *newRelationArray = relationArray;
00288       tmp = cofactor;
00289       cofactor = mdd_and(tmp, constraint, 1, 1);
00290       mdd_free(tmp);
00291     } else
00292       *newRelationArray = ImgGetConstrainedRelationArray(info, relationArray,
00293                                                          constraint);
00294   }
00295   if (cofactorCube && abstractCube) {
00296     if (cofactor)
00297       *cofactorCube = cofactor;
00298     if (abstract)
00299       *abstractCube = abstract;
00300   } else {
00301     if (cofactor) {
00302       if (bdd_is_tautology(cofactor, 1))
00303         mdd_free(cofactor);
00304       else {
00305         tmpRelationArray = *newRelationArray;
00306         *newRelationArray = ImgGetCofactoredRelationArray(tmpRelationArray,
00307                                                           cofactor);
00308         mdd_free(cofactor);
00309         if (tmpRelationArray != relationArray)
00310           mdd_array_free(tmpRelationArray);
00311       }
00312     }
00313     if (abstract) {
00314       if (bdd_is_tautology(abstract, 1))
00315         mdd_free(abstract);
00316       else {
00317         tmpRelationArray = *newRelationArray;
00318         *newRelationArray = ImgGetAbstractedRelationArray(info->manager,
00319                                                           tmpRelationArray,
00320                                                         abstract);
00321         mdd_free(abstract);
00322         if (tmpRelationArray != relationArray)
00323           mdd_array_free(tmpRelationArray);
00324       }
00325     }
00326   }
00327 
00328   *newVector = vector1;
00329   *cube = old;
00330 }
00331 
00332 
00345 mdd_t *
00346 ImgVectorMinimize(ImgTfmInfo_t *info, array_t *vector, mdd_t *constraint,
00347                   mdd_t *from, array_t *relationArray, array_t **newVector,
00348                   mdd_t **cube, array_t **newRelationArray,
00349                   mdd_t **cofactorCube, mdd_t **abstractCube)
00350 {
00351   mdd_t                 *new_, *res, *old, *tmp, *newFrom;
00352   ImgComponent_t        *comp, *comp1;
00353   array_t               *vector1;
00354   int                   i;
00355   st_table              *equivTable;
00356   int                   *ptr, *regularPtr;
00357   int                   n, pos;
00358   mdd_t                 *cofactor, *abstract, *nsVar, *constIntermediate;
00359   array_t               *tmpRelationArray;
00360   int                   size;
00361 
00362   if (from)
00363     newFrom = mdd_dup(from);
00364   else
00365     newFrom = NIL(mdd_t);
00366   if (cube)
00367     old = mdd_one(info->manager);
00368   else
00369     old = NIL(mdd_t);
00370   assert(newVector)
00371   vector1 = array_alloc(ImgComponent_t *, 0);
00372 
00373   if (relationArray) {
00374     cofactor = mdd_one(info->manager);
00375     abstract = mdd_one(info->manager);
00376   } else {
00377     cofactor = NIL(mdd_t);
00378     abstract = NIL(mdd_t);
00379   }
00380 
00381   if (info->nIntermediateVars) {
00382     size = ImgVectorFunctionSize(vector);
00383     if (size == array_n(vector))
00384       constIntermediate = NIL(mdd_t);
00385     else
00386       constIntermediate = mdd_one(info->manager);
00387   } else
00388     constIntermediate = NIL(mdd_t);
00389 
00390   n = 0;
00391   equivTable = st_init_table(st_ptrcmp, st_ptrhash);
00392   for (i = 0; i < array_n(vector); i++) {
00393     comp = array_fetch(ImgComponent_t *, vector, i);
00394     res = bdd_minimize(comp->func, constraint);
00395     if (bdd_is_tautology(res, 1)) {
00396       if (comp->intermediate) {
00397         tmp = constIntermediate;
00398         constIntermediate = mdd_and(tmp, comp->var, 1, 1);
00399         mdd_free(tmp);
00400         mdd_free(res);
00401         continue;
00402       }
00403       if (newFrom) {
00404         tmp = newFrom;
00405         newFrom = bdd_cofactor(tmp, comp->var);
00406         mdd_free(tmp);
00407       }
00408       if (old) {
00409         new_ = mdd_and(comp->var, old, 1, 1);
00410         mdd_free(old);
00411         mdd_free(res);
00412         old = new_;
00413       }
00414       if (cofactor) {
00415         nsVar = ImgSubstitute(comp->var, info->functionData, Img_D2R_c);
00416         tmp = cofactor;
00417         cofactor = mdd_and(tmp, nsVar, 1, 1);
00418         mdd_free(tmp);
00419         mdd_free(nsVar);
00420       }
00421     } else if (bdd_is_tautology(res, 0)) {
00422       if (comp->intermediate) {
00423         tmp = constIntermediate;
00424         constIntermediate = mdd_and(tmp, comp->var, 1, 0);
00425         mdd_free(tmp);
00426         mdd_free(res);
00427         continue;
00428       }
00429       if (newFrom) {
00430         tmp = newFrom;
00431         new_ = mdd_not(comp->var);
00432         newFrom = bdd_cofactor(tmp, new_);
00433         mdd_free(tmp);
00434         mdd_free(new_);
00435       }
00436       if (old) {
00437         new_ = mdd_and(comp->var, old, 0, 1);
00438         mdd_free(old);
00439         mdd_free(res);
00440         old = new_;
00441       }
00442       if (cofactor) {
00443         nsVar = ImgSubstitute(comp->var, info->functionData, Img_D2R_c);
00444         tmp = cofactor;
00445         cofactor = mdd_and(tmp, nsVar, 1, 0);
00446         mdd_free(tmp);
00447         mdd_free(nsVar);
00448       }
00449     } else {
00450       if (comp->intermediate) {
00451         comp1 = ImgComponentAlloc(info);
00452         comp1->var = mdd_dup(comp->var);
00453         comp1->func = res;
00454         comp1->intermediate = 1;
00455         if (mdd_equal(res, comp->func))
00456           ImgSupportCopy(info, comp1->support, comp->support);
00457         else
00458           ImgComponentGetSupport(comp1);
00459         array_insert_last(ImgComponent_t *, vector1, comp1);
00460         n++;
00461         continue;
00462       }
00463       ptr = (int *)bdd_pointer(res);
00464       regularPtr = (int *)((unsigned long)ptr & ~01);
00465       if (st_lookup_int(equivTable, (char *)regularPtr, &pos)) {
00466         comp1 = array_fetch(ImgComponent_t *, vector1, pos);
00467         if (newFrom) {
00468           if (mdd_equal(res, comp1->func)) {
00469             tmp = newFrom;
00470             newFrom = bdd_compose(tmp, comp->var, comp1->var);
00471             mdd_free(tmp);
00472           } else {
00473             tmp = newFrom;
00474             new_ = mdd_not(comp1->var);
00475             newFrom = bdd_compose(tmp, comp->var, new_);
00476             mdd_free(tmp);
00477             mdd_free(new_);
00478           }
00479         }
00480         if (old) {
00481           if (mdd_equal(res, comp1->func))
00482             tmp = mdd_xnor(comp->var, comp1->var);
00483           else
00484             tmp = mdd_xor(comp->var, comp1->var);
00485           new_ = mdd_and(tmp, old, 1, 1);
00486           mdd_free(tmp);
00487           mdd_free(old);
00488           old = new_;
00489         }
00490         mdd_free(res);
00491         if (abstract) {
00492           nsVar = ImgSubstitute(comp->var, info->functionData, Img_D2R_c);
00493           tmp = abstract;
00494           abstract = mdd_and(tmp, nsVar, 1, 1);
00495           mdd_free(tmp);
00496           mdd_free(nsVar);
00497         }
00498       } else {
00499         comp1 = ImgComponentAlloc(info);
00500         comp1->var = mdd_dup(comp->var);
00501         comp1->func = res;
00502         if (mdd_equal(res, comp->func))
00503           ImgSupportCopy(info, comp1->support, comp->support);
00504         else
00505           ImgComponentGetSupport(comp1);
00506         array_insert_last(ImgComponent_t *, vector1, comp1);
00507         st_insert(equivTable, (char *)regularPtr, (char *)(long)n);
00508         n++;
00509       }
00510     }
00511   }
00512   st_free_table(equivTable);
00513 
00514   if (constIntermediate) {
00515     if (!bdd_is_tautology(constIntermediate, 1)) {
00516       mdd_t     *tmpCofactor, *tmpAbstract;
00517 
00518       if (relationArray) {
00519         vector1 = ImgComposeConstIntermediateVars(info, vector1,
00520                                                   constIntermediate,
00521                                                   &tmpCofactor, &tmpAbstract,
00522                                                   &old, NIL(mdd_t *));
00523         if (!bdd_is_tautology(tmpCofactor, 1)) {
00524           tmp = cofactor;
00525           cofactor = mdd_and(tmp, tmpCofactor, 1, 1);
00526           mdd_free(tmp);
00527         }
00528         mdd_free(tmpCofactor);
00529         if (!bdd_is_tautology(tmpAbstract, 1)) {
00530           tmp = abstract;
00531           abstract = mdd_and(tmp, tmpAbstract, 1, 1);
00532           mdd_free(tmp);
00533         }
00534         mdd_free(tmpAbstract);
00535         tmp = cofactor;
00536         cofactor = mdd_and(tmp, constIntermediate, 1, 1);
00537         mdd_free(tmp);
00538       } else {
00539         vector1 = ImgComposeConstIntermediateVars(info, vector1,
00540                                                   constIntermediate,
00541                                                   NIL(mdd_t *), NIL(mdd_t *),
00542                                                   &old, NIL(mdd_t *));
00543       }
00544     }
00545     mdd_free(constIntermediate);
00546   }
00547 
00548   if (info->option->sortVectorFlag)
00549     array_sort(vector1, CompareBddPointer);
00550 
00551   if (newRelationArray)
00552     *newRelationArray = relationArray;
00553   if (cofactorCube && abstractCube) {
00554     if (cofactor) {
00555       if (bdd_is_tautology(cofactor, 1)) {
00556         *cofactorCube = mdd_dup(constraint);
00557         mdd_free(cofactor);
00558       } else {
00559         tmp = cofactor;
00560         cofactor = mdd_and(tmp, constraint, 1, 1);
00561         mdd_free(tmp);
00562         *cofactorCube = cofactor;
00563       }
00564     }
00565     if (abstract)
00566       *abstractCube = abstract;
00567   } else {
00568     if (cofactor) {
00569       if (bdd_is_tautology(cofactor, 1))
00570         mdd_free(cofactor);
00571       else {
00572         tmp = cofactor;
00573         cofactor = mdd_and(tmp, constraint, 1, 1);
00574         mdd_free(tmp);
00575         if (newRelationArray) {
00576           *newRelationArray = ImgGetCofactoredRelationArray(relationArray,
00577                                                             cofactor);
00578         } else
00579           ImgCofactorRelationArray(relationArray, cofactor);
00580         mdd_free(cofactor);
00581       }
00582     }
00583     if (abstract) {
00584       if (bdd_is_tautology(abstract, 1))
00585         mdd_free(abstract);
00586       else {
00587         if (newRelationArray) {
00588           tmpRelationArray = *newRelationArray;
00589           *newRelationArray = ImgGetAbstractedRelationArray(info->manager,
00590                                                             tmpRelationArray,
00591                                                             abstract);
00592           if (tmpRelationArray != relationArray)
00593             mdd_array_free(tmpRelationArray);
00594         } else
00595           ImgAbstractRelationArray(info->manager, relationArray, abstract);
00596         mdd_free(abstract);
00597       }
00598     }
00599   }
00600 
00601   if (*newVector == vector)
00602     ImgVectorFree(vector);
00603   *newVector = vector1;
00604   if (cube)
00605     *cube = old;
00606 
00607   return(newFrom);
00608 }
00609 
00610 
00620 void
00621 ImgVectorFree(array_t *vector)
00622 {
00623   int                   i;
00624   ImgComponent_t        *comp;
00625 
00626   for (i = 0; i < array_n(vector); i++) {
00627     comp = array_fetch(ImgComponent_t *, vector, i);
00628     ImgComponentFree(comp);
00629   }
00630   array_free(vector);
00631 }
00632 
00633 
00644 int
00645 ImgVectorFunctionSize(array_t *vector)
00646 {
00647   ImgComponent_t        *comp;
00648   int                   i, size;
00649 
00650   size = 0;
00651   for (i = 0; i < array_n(vector); i++) {
00652     comp = array_fetch(ImgComponent_t *, vector, i);
00653     if (!comp->intermediate)
00654       size++;
00655   }
00656 
00657   return(size);
00658 }
00659 
00660 
00670 long
00671 ImgVectorBddSize(array_t *vector)
00672 {
00673   array_t               *nodeArray;
00674   ImgComponent_t        *comp;
00675   int                   i, size;
00676 
00677   nodeArray = array_alloc(mdd_t *, 0);
00678   for (i = 0; i < array_n(vector); i++) {
00679     comp = array_fetch(ImgComponent_t *, vector, i);
00680     array_insert_last(mdd_t *, nodeArray, comp->func);
00681   }
00682   size = bdd_size_multiple(nodeArray);
00683   array_free(nodeArray);
00684 
00685   return(size);
00686 }
00687 
00688 
00698 array_t *
00699 ImgVectorCopy(ImgTfmInfo_t *info, array_t *vector)
00700 {
00701   array_t               *newVector;
00702   ImgComponent_t        *comp, *newComp;
00703   int                   i;
00704 
00705   newVector = array_alloc(ImgComponent_t *, 0);
00706   for (i = 0; i < array_n(vector); i++) {
00707     comp = array_fetch(ImgComponent_t *, vector, i);
00708     newComp = ImgComponentCopy(info, comp);
00709     array_insert_last(ImgComponent_t *, newVector, newComp);
00710   }
00711   return(newVector);
00712 }
00713 
00714 
00724 ImgComponent_t *
00725 ImgComponentAlloc(ImgTfmInfo_t *info)
00726 {
00727   ImgComponent_t        *comp;
00728 
00729   comp = ALLOC(ImgComponent_t, 1);
00730   memset(comp, 0, sizeof(ImgComponent_t));
00731   comp->support = ALLOC(char, info->nVars);
00732   ImgSupportClear(info, comp->support);
00733   comp->id = info->nComponents++;
00734   return(comp);
00735 }
00736 
00737 
00747 ImgComponent_t *
00748 ImgComponentCopy(ImgTfmInfo_t *info, ImgComponent_t *comp)
00749 {
00750   ImgComponent_t        *newComp;
00751 
00752   newComp = ImgComponentAlloc(info);
00753   newComp->func = mdd_dup(comp->func);
00754   newComp->var = mdd_dup(comp->var);
00755   ImgSupportCopy(info, newComp->support, comp->support);
00756   newComp->intermediate = comp->intermediate;
00757   return(newComp);
00758 }
00759 
00760 
00770 void
00771 ImgComponentFree(ImgComponent_t *comp)
00772 {
00773   if (comp->func)
00774     mdd_free(comp->func);
00775   if (comp->var != NULL)
00776     mdd_free(comp->var);
00777   FREE(comp->support);
00778   FREE(comp);
00779 }
00780 
00781 
00791 void
00792 ImgComponentGetSupport(ImgComponent_t *comp)
00793 {
00794   int           index;
00795   var_set_t     *supportVarSet;
00796 
00797   supportVarSet = bdd_get_support(comp->func);
00798   for (index = 0; index < supportVarSet->n_elts; index++) {
00799     if (var_set_get_elt(supportVarSet, index) == 1)
00800       comp->support[index] = 1;
00801   }
00802   var_set_free(supportVarSet);
00803 }
00804 
00805 
00816 void
00817 ImgSupportCopy(ImgTfmInfo_t *info, char *dsupport, char *ssupport)
00818 {
00819   memcpy(dsupport, ssupport, sizeof(char) * info->nVars);
00820 }
00821 
00822 
00832 void
00833 ImgSupportClear(ImgTfmInfo_t *info, char *support)
00834 {
00835   memset(support, 0, sizeof(char) * info->nVars);
00836 }
00837 
00838 
00848 void
00849 ImgSupportPrint(ImgTfmInfo_t *info, char *support)
00850 {
00851   int   i;
00852 
00853   for (i = 0; i < info->nVars; i++) {
00854    if (support[i])
00855      printf("*");
00856    else
00857      printf(".");
00858   }
00859   printf("\n");
00860 }
00861 
00862 
00872 int
00873 ImgSupportCount(ImgTfmInfo_t *info, char *support)
00874 {
00875   int   i, nSupports;
00876 
00877   nSupports = 0;
00878   for (i = 0; i < info->nVars; i++) {
00879    if (support[i])
00880      nSupports++;
00881   }
00882   return(nSupports);
00883 }
00884 
00885 
00896 array_t *
00897 ImgGetConstrainedRelationArray(ImgTfmInfo_t *info, array_t *relationArray,
00898                                 mdd_t *constraint)
00899 {
00900   array_t               *constrainedRelationArray;
00901   int                   dynStatus;
00902   bdd_reorder_type_t    dynMethod;
00903 
00904   dynStatus = bdd_reordering_status(info->manager, &dynMethod);
00905   if (dynStatus != 0)
00906     bdd_dynamic_reordering_disable(info->manager);
00907 
00908   constrainedRelationArray = ImgGetCofactoredRelationArray(relationArray,
00909                                                            constraint);
00910 
00911   if (dynStatus != 0) {
00912     bdd_dynamic_reordering(info->manager, dynMethod,
00913                            BDD_REORDER_VERBOSITY_DEFAULT);
00914   }
00915 
00916   return(constrainedRelationArray);
00917 }
00918 
00919 
00930 array_t *
00931 ImgGetCofactoredRelationArray(array_t *relationArray, mdd_t *func)
00932 {
00933   int           i;
00934   array_t       *cofactoredRelationArray;
00935   mdd_t         *relation, *cofactoredRelation;
00936 
00937   if (bdd_is_tautology(func, 1))
00938     return(mdd_array_duplicate(relationArray));
00939 
00940   cofactoredRelationArray = array_alloc(mdd_t *, 0);
00941 
00942   for (i = 0; i < array_n(relationArray); i++) {
00943     relation = array_fetch(mdd_t *, relationArray, i);
00944     cofactoredRelation = bdd_cofactor(relation, func);
00945     if (bdd_is_tautology(cofactoredRelation, 1))
00946       mdd_free(cofactoredRelation);
00947     else
00948       array_insert_last(mdd_t *, cofactoredRelationArray, cofactoredRelation);
00949   }
00950 
00951   return(cofactoredRelationArray);
00952 }
00953 
00954 
00964 void
00965 ImgCofactorRelationArray(array_t *relationArray, mdd_t *func)
00966 {
00967   int           i;
00968   mdd_t         *relation, *cofactoredRelation;
00969 
00970   if (bdd_is_tautology(func, 1))
00971     return;
00972 
00973   for (i = 0; i < array_n(relationArray); i++) {
00974     relation = array_fetch(mdd_t *, relationArray, i);
00975     cofactoredRelation = bdd_cofactor(relation, func);
00976     if (mdd_equal(cofactoredRelation, relation))
00977       mdd_free(cofactoredRelation);
00978     else {
00979       mdd_free(relation);
00980       array_insert(mdd_t *, relationArray, i, cofactoredRelation);
00981     }
00982   }
00983 }
00984 
00985 
00995 array_t *
00996 ImgGetAbstractedRelationArray(mdd_manager *manager, array_t *relationArray,
00997                               mdd_t *cube)
00998 {
00999   int           i;
01000   array_t       *abstractedRelationArray;
01001   mdd_t         *relation, *abstractedRelation;
01002   array_t       *varsArray;
01003 
01004   if (bdd_is_tautology(cube, 1))
01005     return(mdd_array_duplicate(relationArray));
01006 
01007   abstractedRelationArray = array_alloc(mdd_t *, 0);
01008 
01009   if (bdd_get_package_name() != CUDD)
01010     varsArray = mdd_get_bdd_support_vars(manager, cube);
01011   else /* to remove uninitialized variable warning*/
01012     varsArray = NIL(array_t);
01013   for (i = 0; i < array_n(relationArray); i++) {
01014     relation = array_fetch(mdd_t *, relationArray, i);
01015     if (bdd_get_package_name() == CUDD)
01016       abstractedRelation = bdd_smooth_with_cube(relation, cube);
01017     else
01018       abstractedRelation = bdd_smooth(relation, varsArray);
01019     if (bdd_is_tautology(abstractedRelation, 1))
01020       mdd_free(abstractedRelation);
01021     else
01022       array_insert_last(mdd_t *, abstractedRelationArray, abstractedRelation);
01023   }
01024   if (bdd_get_package_name() != CUDD)
01025     mdd_array_free(varsArray);
01026 
01027   return(abstractedRelationArray);
01028 }
01029 
01030 
01040 void
01041 ImgAbstractRelationArray(mdd_manager *manager, array_t *relationArray,
01042                          mdd_t *cube)
01043 {
01044   int           i;
01045   mdd_t         *relation, *abstractedRelation;
01046   array_t       *varsArray;
01047 
01048   if (bdd_is_tautology(cube, 1))
01049     return;
01050 
01051   if (bdd_get_package_name() != CUDD)
01052     varsArray = mdd_get_bdd_support_vars(manager, cube);
01053   else /* to remove uninitialized variable warning*/
01054     varsArray = NIL(array_t);
01055   for (i = 0; i < array_n(relationArray); i++) {
01056     relation = array_fetch(mdd_t *, relationArray, i);
01057     if (bdd_get_package_name() == CUDD)
01058       abstractedRelation = bdd_smooth_with_cube(relation, cube);
01059     else
01060       abstractedRelation = bdd_smooth(relation, varsArray);
01061     if (mdd_equal(abstractedRelation, relation))
01062       mdd_free(abstractedRelation);
01063     else {
01064       mdd_free(relation);
01065       array_insert(mdd_t *, relationArray, i, abstractedRelation);
01066     }
01067   }
01068   if (bdd_get_package_name() != CUDD)
01069     mdd_array_free(varsArray);
01070 }
01071 
01072 
01083 array_t *
01084 ImgGetCofactoredAbstractedRelationArray(mdd_manager *manager,
01085                                         array_t *relationArray,
01086                                         mdd_t *cofactorCube,
01087                                         mdd_t *abstractCube)
01088 {
01089   int           i;
01090   array_t       *newRelationArray = array_alloc(mdd_t *, 0);
01091   mdd_t         *relation, *newRelation, *tmpRelation;
01092   array_t       *varsArray;
01093 
01094   if (bdd_get_package_name() != CUDD)
01095     varsArray = mdd_get_bdd_support_vars(manager, abstractCube);
01096   else /* to remove uninitialized variable warning*/
01097     varsArray = NIL(array_t);
01098   for (i = 0; i < array_n(relationArray); i++) {
01099     relation = array_fetch(mdd_t *, relationArray, i);
01100     tmpRelation = bdd_cofactor(relation, cofactorCube);
01101     if (bdd_get_package_name() == CUDD)
01102       newRelation = bdd_smooth_with_cube(tmpRelation, abstractCube);
01103     else
01104       newRelation = bdd_smooth(tmpRelation, varsArray);
01105     mdd_free(tmpRelation);
01106     if (bdd_is_tautology(newRelation, 1))
01107       mdd_free(newRelation);
01108     else
01109       array_insert_last(mdd_t *, newRelationArray, newRelation);
01110   }
01111   if (bdd_get_package_name() != CUDD)
01112     mdd_array_free(varsArray);
01113 
01114   return(newRelationArray);
01115 }
01116 
01117 
01128 array_t *
01129 ImgGetAbstractedCofactoredRelationArray(mdd_manager *manager,
01130                                         array_t *relationArray,
01131                                         mdd_t *cofactorCube,
01132                                         mdd_t *abstractCube)
01133 {
01134   int           i;
01135   array_t       *newRelationArray = array_alloc(mdd_t *, 0);
01136   mdd_t         *relation, *newRelation, *tmpRelation;
01137   array_t       *varsArray;
01138 
01139   if (bdd_get_package_name() != CUDD)
01140     varsArray = mdd_get_bdd_support_vars(manager, abstractCube);
01141   else /* to remove uninitialized variable warning*/
01142     varsArray = NIL(array_t);
01143   for (i = 0; i < array_n(relationArray); i++) {
01144     relation = array_fetch(mdd_t *, relationArray, i);
01145     if (bdd_get_package_name() == CUDD)
01146       tmpRelation = bdd_smooth_with_cube(relation, abstractCube);
01147     else
01148       tmpRelation = bdd_smooth(relation, varsArray);
01149     newRelation = bdd_cofactor(tmpRelation, cofactorCube);
01150     mdd_free(tmpRelation);
01151     if (bdd_is_tautology(newRelation, 1))
01152       mdd_free(newRelation);
01153     else
01154       array_insert_last(mdd_t *, newRelationArray, newRelation);
01155   }
01156   if (bdd_get_package_name() != CUDD)
01157     mdd_array_free(varsArray);
01158 
01159   return(newRelationArray);
01160 }
01161 
01162 
01173 array_t *
01174 ImgGetConstrainedVector(ImgTfmInfo_t *info, array_t *vector, mdd_t *constraint)
01175 {
01176   array_t               *constrainedVector;
01177   int                   dynStatus;
01178   bdd_reorder_type_t    dynMethod;
01179 
01180   dynStatus = bdd_reordering_status(info->manager, &dynMethod);
01181   if (dynStatus != 0)
01182     bdd_dynamic_reordering_disable(info->manager);
01183 
01184   constrainedVector = ImgGetCofactoredVector(info, vector, constraint);
01185 
01186   if (dynStatus != 0) {
01187     bdd_dynamic_reordering(info->manager, dynMethod,
01188                            BDD_REORDER_VERBOSITY_DEFAULT);
01189   }
01190 
01191   return(constrainedVector);
01192 }
01193 
01194 
01205 array_t *
01206 ImgGetCofactoredVector(ImgTfmInfo_t *info, array_t *vector, mdd_t *func)
01207 {
01208   int                   i;
01209   array_t               *cofactoredVector = array_alloc(ImgComponent_t *, 0);
01210   ImgComponent_t        *comp, *cofactoredComp;
01211   mdd_t                 *cofactoredFunc;
01212 
01213   if (bdd_is_tautology(func, 1))
01214     return(ImgVectorCopy(info, vector));
01215 
01216   for (i = 0; i < array_n(vector); i++) {
01217     comp = array_fetch(ImgComponent_t *, vector, i);
01218     cofactoredFunc = bdd_cofactor(comp->func, func);
01219     cofactoredComp = ImgComponentAlloc(info);
01220     cofactoredComp->var = mdd_dup(comp->var);
01221     cofactoredComp->func = cofactoredFunc;
01222     cofactoredComp->intermediate = comp->intermediate;
01223     if (mdd_equal(cofactoredFunc, comp->func))
01224       ImgSupportCopy(info, cofactoredComp->support, comp->support);
01225     else
01226       ImgComponentGetSupport(cofactoredComp);
01227     array_insert_last(ImgComponent_t *, cofactoredVector, cofactoredComp);
01228   }
01229 
01230   return(cofactoredVector);
01231 }
01232 
01233 
01243 void
01244 ImgCofactorVector(ImgTfmInfo_t *info, array_t *vector, mdd_t *func)
01245 {
01246   int                   i;
01247   ImgComponent_t        *comp;
01248   mdd_t                 *cofactoredFunc;
01249 
01250   if (bdd_is_tautology(func, 1))
01251     return;
01252 
01253   for (i = 0; i < array_n(vector); i++) {
01254     comp = array_fetch(ImgComponent_t *, vector, i);
01255     cofactoredFunc = bdd_cofactor(comp->func, func);
01256     if (mdd_equal(cofactoredFunc, comp->func))
01257       mdd_free(cofactoredFunc);
01258     else {
01259       mdd_free(comp->func);
01260       comp->func = cofactoredFunc;
01261       ImgSupportClear(info, comp->support);
01262       ImgComponentGetSupport(comp);
01263     }
01264   }
01265 }
01266 
01267 
01281 mdd_t *
01282 ImgTfmEliminateDependVars(ImgTfmInfo_t *info, array_t *vector,
01283                           array_t *relationArray, mdd_t *states,
01284                           array_t **newVector,
01285                           mdd_t **dependRelations)
01286 {
01287   int                   i, j;
01288   int                   howMany = 0;
01289                         /* number of latches that can be eliminated */
01290   mdd_t                 *var, *newStates, *abs, *positive, *phi;
01291   mdd_t                 *tmp, *relation;
01292   int                   nVars;
01293   int                   nSupports; /* vars in the support of the state set */
01294   int                   *candidates; /* vars to be considered for elimination */
01295   double                minStates;
01296   ImgComponent_t        *comp, *newComp;
01297 
01298   if (dependRelations) {
01299     *dependRelations = mdd_one(info->manager);
01300     *newVector = array_alloc(ImgComponent_t *, 0);
01301   }
01302   newStates = mdd_dup(states);
01303   nVars = info->nVars;
01304 
01305   candidates = ALLOC(int, nVars);
01306   if (candidates == NULL)
01307     return(NULL);
01308 
01309   comp = ImgComponentAlloc(info);
01310   comp->func = newStates;
01311   ImgComponentGetSupport(comp);
01312   nSupports = 0;
01313   for (i = 0 ; i < nVars; i++) {
01314     if (comp->support[i]) {
01315       candidates[nSupports] = i;
01316       nSupports++;
01317     }
01318   }
01319   comp->func = NIL(mdd_t);
01320   ImgComponentFree(comp);
01321 
01322   /* The signatures of the variables in a function are the number
01323   ** of minterms of the positive cofactors with respect to the
01324   ** variables themselves. */
01325   signatures = bdd_cof_minterm(newStates);
01326   if (signatures == NULL) {
01327     FREE(candidates);
01328     return(NULL);
01329   }
01330   /* We now extract a positive quantity which is higher for those
01331   ** variables that are closer to being essential. */
01332   minStates = signatures[nSupports];
01333   for (i = 0; i < nSupports; i++) {
01334     double z = signatures[i] / minStates - 1.0;
01335     signatures[i] = (z < 0.0) ? -z : z;    /* make positive */
01336   }
01337   qsort((void *)candidates, nSupports, sizeof(int),
01338       (int (*)(const void *, const void *))SignatureCompare);
01339   FREE(signatures);
01340 
01341   /* Now process the candidates in the given order. */
01342   for (i = 0; i < nSupports; i++) {
01343     var = bdd_var_with_index(info->manager, candidates[i]);
01344     if (bdd_var_is_dependent(newStates, var)) {
01345       abs = bdd_smooth_with_cube(newStates, var);
01346       if (abs == NULL)
01347         return(NULL);
01348       positive = bdd_cofactor(newStates, var);
01349       if (positive == NULL)
01350         return(NULL);
01351       phi = Img_MinimizeImage(positive, abs, Img_DefaultMinimizeMethod_c,
01352                               TRUE); 
01353       if (phi == NULL)
01354         return(NULL);
01355       mdd_free(positive);
01356       if (bdd_size(phi) < IMG_MAX_DEP_SIZE) {
01357         howMany++;
01358         if (dependRelations) {
01359           for (j = 0; j < array_n(vector); j++) {
01360             comp = array_fetch(ImgComponent_t *, vector, j);
01361             if (mdd_equal(comp->var, var))
01362               continue;
01363             newComp = ImgComponentCopy(info, comp);
01364             array_insert_last(ImgComponent_t *, *newVector, newComp);
01365           }
01366         } else {
01367           for (j = 0; j < array_n(vector); j++) {
01368             comp = array_fetch(ImgComponent_t *, vector, j);
01369             tmp = bdd_compose(comp->func, var, phi);
01370             if (tmp == NULL)
01371               return(NULL);
01372             mdd_free(comp->func);
01373             comp->func = tmp;
01374             ImgSupportClear(info, comp->support);
01375             ImgComponentGetSupport(comp);
01376           }
01377         }
01378         if (relationArray) {
01379           for (j = 0; j < array_n(relationArray); j++) {
01380             relation = array_fetch(mdd_t *, relationArray, j);
01381             if (dependRelations)
01382               tmp = bdd_smooth_with_cube(relation, var);
01383             else
01384               tmp = bdd_compose(relation, var, phi);
01385             mdd_free(relation);
01386             array_insert(mdd_t *, relationArray, j, tmp);
01387           }
01388         }
01389         mdd_free(newStates);
01390         newStates = abs;
01391         if (dependRelations) {
01392           relation = mdd_xnor(var, phi);
01393           tmp = mdd_and(*dependRelations, relation, 1, 1);
01394           mdd_free(*dependRelations);
01395           mdd_free(relation);
01396           *dependRelations = tmp;
01397         }
01398       } else {
01399         mdd_free(abs);
01400       }
01401       mdd_free(phi);
01402     }
01403   }
01404   FREE(candidates);
01405 
01406   if (howMany) {
01407     if (info->imageVerbosity > 0)
01408       (void)fprintf(vis_stdout, "Eliminated %d vars.\n", howMany);
01409     info->averageFoundDependVars = (info->averageFoundDependVars *
01410                         (float)info->nFoundDependVars + (float)howMany) /
01411                         (float)(info->nFoundDependVars + 1);
01412     info->nFoundDependVars++;
01413   }
01414 
01415   info->nPrevEliminatedFwd = howMany;
01416   return(newStates);
01417 } /* end of TfmEliminateDependVars */
01418 
01419 
01431 int
01432 ImgExistConstIntermediateVar(array_t *vector)
01433 {
01434   int                   i;
01435   ImgComponent_t        *comp;
01436 
01437   for (i = 0; i < array_n(vector); i++) {
01438     comp = array_fetch(ImgComponent_t *, vector, i);
01439     if (comp->intermediate) {
01440       if (mdd_is_tautology(comp->func, 1) || mdd_is_tautology(comp->func, 0))
01441         return(1);
01442     }
01443   }
01444   return(0);
01445 }
01446 
01447 
01457 mdd_t *
01458 ImgGetComposedFunction(array_t *vector)
01459 {
01460   ImgComponent_t        *comp;
01461   mdd_t                 *func, *newFunc;
01462   int                   i;
01463   array_t               *varArray, *funcArray;
01464 
01465   assert(ImgVectorFunctionSize(vector) == 1);
01466 
01467   /* no intermediate variables */
01468   if (array_n(vector) == 1) {
01469     comp = array_fetch(ImgComponent_t *, vector, 0);
01470     newFunc = mdd_dup(comp->func);
01471     return(newFunc);
01472   }
01473 
01474   func = NIL(mdd_t);
01475   varArray = array_alloc(mdd_t *, 0);
01476   funcArray = array_alloc(mdd_t *, 0);
01477 
01478   for (i = 0; i < array_n(vector); i++) {
01479     comp = array_fetch(ImgComponent_t *, vector, i);
01480     if (comp->intermediate) {
01481       array_insert_last(mdd_t *, varArray, comp->var);
01482       array_insert_last(mdd_t *, funcArray, comp->func);
01483       continue;
01484     }
01485     func = comp->func;
01486   }
01487 
01488   newFunc = bdd_vector_compose(func, varArray, funcArray);
01489   array_free(varArray);
01490   array_free(funcArray);
01491   return(newFunc);
01492 }
01493 
01494 
01504 ImgComponent_t *
01505 ImgGetLatchComponent(array_t *vector)
01506 {
01507   ImgComponent_t        *comp;
01508   int                   i;
01509 
01510   for (i = 0; i < array_n(vector); i++) {
01511     comp = array_fetch(ImgComponent_t *, vector, i);
01512     if (!comp->intermediate)
01513       return(comp);
01514   }
01515   return(NIL(ImgComponent_t));
01516 }
01517 
01518 
01528 array_t *
01529 ImgComposeConstIntermediateVars(ImgTfmInfo_t *info, array_t *vector,
01530                                 mdd_t *constIntermediate,
01531                                 mdd_t **cofactorCube, mdd_t **abstractCube,
01532                                 mdd_t **and_, mdd_t **from)
01533 {
01534   int                   i, n, pos;
01535   array_t               *tmpVector, *cofactoredVector;
01536   mdd_t                 *cofactor, *abstract;
01537   mdd_t                 *curConstIntermediate, *newConstIntermediate;
01538   mdd_t                 *tmp, *new_, *func, *varNot, *nsVar;
01539   ImgComponent_t        *comp, *comp1;
01540   st_table              *equivTable;
01541   int                   *ptr, *regularPtr;
01542 
01543   if (cofactorCube)
01544     cofactor = mdd_one(info->manager);
01545   else
01546     cofactor = NIL(mdd_t);
01547   if (abstractCube)
01548     abstract = mdd_one(info->manager);
01549   else
01550     abstract = NIL(mdd_t);
01551 
01552   cofactoredVector = vector;
01553   tmpVector = cofactoredVector;
01554   curConstIntermediate = constIntermediate;
01555 
01556   while (!bdd_is_tautology(curConstIntermediate, 1)) {
01557     newConstIntermediate = mdd_one(info->manager);
01558     n = 0;
01559     equivTable = st_init_table(st_ptrcmp, st_ptrhash);
01560     cofactoredVector = array_alloc(ImgComponent_t *, 0);
01561     for (i = 0; i < array_n(tmpVector); i++) {
01562       comp = array_fetch(ImgComponent_t *, tmpVector, i);
01563       func = bdd_cofactor(comp->func, curConstIntermediate);
01564 
01565       if (comp->intermediate) {
01566         if (mdd_is_tautology(func, 1)) {
01567           tmp = newConstIntermediate;
01568           newConstIntermediate = mdd_and(tmp, comp->var, 1, 1);
01569           mdd_free(tmp);
01570           mdd_free(func);
01571           continue;
01572         } else if (mdd_is_tautology(func, 0)) {
01573           tmp = newConstIntermediate;
01574           newConstIntermediate = mdd_and(tmp, comp->var, 1, 0);
01575           mdd_free(tmp);
01576           mdd_free(func);
01577           continue;
01578         }
01579 
01580         comp1 = ImgComponentAlloc(info);
01581         comp1->var = mdd_dup(comp->var);
01582         comp1->func = func;
01583         comp1->intermediate = 1;
01584         if (mdd_equal(func, comp->func))
01585           ImgSupportCopy(info, comp1->support, comp->support);
01586         else
01587           ImgComponentGetSupport(comp1);
01588         array_insert_last(ImgComponent_t *, cofactoredVector, comp1);
01589         n++;
01590         continue;
01591       }
01592 
01593       if (mdd_is_tautology(func, 1)) {
01594         if (cofactor) {
01595           nsVar = ImgSubstitute(comp->var, info->functionData, Img_D2R_c);
01596           tmp = cofactor;
01597           cofactor = mdd_and(tmp, nsVar, 1, 1);
01598           mdd_free(tmp);
01599           mdd_free(nsVar);
01600         }
01601         if (and_) {
01602           tmp = *and_;
01603           *and_ = mdd_and(tmp, comp->var, 1, 1);
01604           mdd_free(tmp);
01605         }
01606         if (from) {
01607           tmp = *from;
01608           *from = bdd_cofactor(tmp, comp->var);
01609           mdd_free(tmp);
01610         }
01611         mdd_free(func);
01612       } else if (mdd_is_tautology(func, 0)) {
01613         if (cofactor) {
01614           nsVar = ImgSubstitute(comp->var, info->functionData, Img_D2R_c);
01615           tmp = cofactor;
01616           cofactor = mdd_and(tmp, nsVar, 1, 0);
01617           mdd_free(tmp);
01618           mdd_free(nsVar);
01619         }
01620         if (and_) {
01621           tmp = *and_;
01622           *and_ = mdd_and(tmp, comp->var, 1, 0);
01623           mdd_free(tmp);
01624         }
01625         if (from) {
01626           tmp = *from;
01627           varNot = bdd_not(comp->var);
01628           *from = bdd_cofactor(tmp, varNot);
01629           mdd_free(tmp);
01630           mdd_free(varNot);
01631         }
01632         mdd_free(func);
01633       } else {
01634         ptr = (int *)bdd_pointer(func);
01635         regularPtr = (int *)((unsigned long)ptr & ~01);
01636         if (st_lookup_int(equivTable, (char *)regularPtr, &pos)) {
01637           comp1 = array_fetch(ImgComponent_t *, cofactoredVector, pos);
01638           if (and_) {
01639             if (mdd_equal(func, comp1->func))
01640               tmp = mdd_xnor(comp->var, comp1->var);
01641             else
01642               tmp = mdd_xor(comp->var, comp1->var);
01643             new_ = mdd_and(tmp, *and_, 1, 1);
01644             mdd_free(tmp);
01645             mdd_free(*and_);
01646             mdd_free(func);
01647             *and_ = new_;
01648           }
01649           if (abstract) {
01650             nsVar = ImgSubstitute(comp->var, info->functionData, Img_D2R_c);
01651             tmp = abstract;
01652             abstract = mdd_and(tmp, nsVar, 1, 1);
01653             mdd_free(tmp);
01654             mdd_free(nsVar);
01655           }
01656           if (from) {
01657             tmp = *from;
01658             *from = bdd_compose(tmp, comp->var, comp1->var);
01659             mdd_free(tmp);
01660           }
01661         } else {
01662           comp1 = ImgComponentAlloc(info);
01663           comp1->var = mdd_dup(comp->var);
01664           comp1->func = func;
01665           if (mdd_equal(func, comp->func))
01666             ImgSupportCopy(info, comp1->support, comp->support);
01667           else
01668             ImgComponentGetSupport(comp1);
01669           array_insert_last(ImgComponent_t *, cofactoredVector, comp1);
01670           st_insert(equivTable, (char *)regularPtr, (char *)(long)n);
01671           n++;
01672         }
01673       }
01674     }
01675 
01676     if (curConstIntermediate != constIntermediate)
01677       mdd_free(curConstIntermediate);
01678     curConstIntermediate = newConstIntermediate;
01679 
01680     if (cofactor) {
01681       tmp = cofactor;
01682       cofactor = mdd_and(tmp, curConstIntermediate, 1, 1);
01683       mdd_free(tmp);
01684     }
01685 
01686     st_free_table(equivTable);
01687     ImgVectorFree(tmpVector);
01688     tmpVector = cofactoredVector;
01689   }
01690 
01691   if (curConstIntermediate != constIntermediate)
01692     mdd_free(curConstIntermediate);
01693 
01694   if (cofactorCube)
01695     *cofactorCube = cofactor;
01696   if (abstractCube)
01697     *abstractCube = abstract;
01698 
01699   return(cofactoredVector);
01700 }
01701 
01702 
01712 int
01713 ImgCountBddSupports(mdd_t *func)
01714 {
01715   int           index, nSupports = 0;
01716   var_set_t     *supportVarSet;
01717 
01718   supportVarSet = bdd_get_support(func);
01719   for (index = 0; index < supportVarSet->n_elts; index++) {
01720     if (var_set_get_elt(supportVarSet, index) == 1)
01721       nSupports++;
01722   }
01723   var_set_free(supportVarSet);
01724   return(nSupports);
01725 }
01726 
01727 
01740 void
01741 ImgCheckConstConstrain(mdd_t *f1, mdd_t *f2, int *f21p, int *f21n)
01742 {
01743   if (mdd_lequal(f1, f2, 1, 1)) { /* f2 > f1 */
01744     *f21p = 1;
01745     *f21n = 2;
01746   } else if (mdd_lequal(f2, f1, 1, 0)) { /* f2&f1=0 -> f2 < f1' */
01747     *f21p = 0;
01748     *f21n = 2;
01749   } else if (mdd_lequal(f1, f2, 0, 1)) { /* f2 > f1' */
01750     *f21p = 2;
01751     *f21n = 1;
01752   } else if (mdd_lequal(f2, f1, 1, 1)) { /* f2&f1'=0 -> f2 < f1 */
01753     *f21p = 2;
01754     *f21n = 0;
01755   } else {
01756     *f21p = 2;
01757     *f21n = 2;
01758   }
01759 }
01760 
01761 
01771 int
01772 ImgConstConstrain(mdd_t *func, mdd_t *constraint)
01773 {
01774   if (mdd_lequal(constraint, func, 1, 1)) /* func | constraint = 1 */
01775     return(1);
01776   if (mdd_lequal(func, constraint, 1, 0)) /* func | constraint = 0 */
01777     return(0);
01778   return(2); /* non-constant */
01779 }
01780 
01781 
01791 void
01792 ImgPrintVectorDependency(ImgTfmInfo_t *info, array_t *vector, int verbosity)
01793 {
01794   int                   i, j, index, nFuncs, nSupports;
01795   int                   nLambdaLatches, nConstLatches, nIntermediateVars;
01796   int                   count, countStates, total;
01797   int                   start, end;
01798   char                  *support, line[80];
01799   ImgComponent_t        *comp;
01800 
01801   if (verbosity == 0 || (!vector))
01802     return;
01803 
01804   support = ALLOC(char, sizeof(char) * info->nVars);
01805   memset(support, 0, sizeof(char) * info->nVars);
01806 
01807   count = countStates = 0;
01808   nFuncs = array_n(vector);
01809   for (i = 0; i < nFuncs; i++) {
01810     comp = array_fetch(ImgComponent_t *, vector, i);
01811     for (j = 0; j < info->nVars; j++) {
01812       if (comp->support[j]) {
01813         support[j] = 1;
01814         count++;
01815         if (!st_lookup(info->quantifyVarsTable, (char *)(long)j, NIL(char *)))
01816           countStates++;
01817       }
01818     }
01819   }
01820   nSupports = 0;
01821   for (i = 0; i < info->nVars; i++) {
01822     if (support[i])
01823       nSupports++;
01824   }
01825   nLambdaLatches = 0;
01826   nConstLatches = 0;
01827   nIntermediateVars = 0;
01828   for (i = 0; i < nFuncs; i++) {
01829     comp = array_fetch(ImgComponent_t *, vector, i);
01830     index = bdd_top_var_id(comp->var);
01831     if (!support[index])
01832       nLambdaLatches++;
01833     if (ImgSupportCount(info, comp->support) == 0)
01834       nConstLatches++;
01835     if (comp->intermediate)
01836       nIntermediateVars++;
01837   }
01838   fprintf(vis_stdout, "** tfm info: #vars = %d(%d)\n",
01839           info->nVars - nFuncs + nIntermediateVars, info->nVars);
01840   fprintf(vis_stdout, "** tfm info: #input vars = %d\n",
01841           info->nVars - (nFuncs - nIntermediateVars) * 2 - nIntermediateVars);
01842   fprintf(vis_stdout, "** tfm info: #funcs = %d\n", nFuncs);
01843   fprintf(vis_stdout, "** tfm info: #lambda funcs = %d\n", nLambdaLatches);
01844   fprintf(vis_stdout, "** tfm info: #constant funcs = %d\n", nConstLatches);
01845   fprintf(vis_stdout, "** tfm info: #intermediate funcs = %d\n",
01846           nIntermediateVars);
01847   fprintf(vis_stdout,
01848           "Shared size of transition function vector is %10ld BDD nodes\n",
01849           ImgVectorBddSize(vector));
01850   total = nFuncs * nFuncs;
01851   fprintf(vis_stdout,
01852 "** tfm info: support distribution (state variables) = %.2f%%(%d out of %d)\n",
01853           (float)countStates / (float)total * 100.0, countStates, total);
01854   total = nFuncs * nSupports;
01855   fprintf(vis_stdout,
01856 "** tfm info: support distribution (all variables) = %.2f%% (%d out of %d)\n",
01857           (float)count / (float)total * 100.0, count, total);
01858 
01859   if (verbosity < 3) {
01860     FREE(support);
01861     return;
01862   }
01863 
01864   fprintf(vis_stdout, "*** function list ***\n");
01865   for (i = 0; i < nFuncs; i++) {
01866     comp = array_fetch(ImgComponent_t *, vector, i);
01867     index = bdd_top_var_id(comp->var);
01868     fprintf(vis_stdout, "[%d] index = %d\n", i, index);
01869   }
01870 
01871   start = 0;
01872   end = 74;
01873   if (end >= nFuncs)
01874     end = nFuncs - 1;
01875   while (1) {
01876     fprintf(vis_stdout, "========================================");
01877     fprintf(vis_stdout, "========================================\n");
01878     fprintf(vis_stdout, "     1234567890123456789012345678901234567890");
01879     fprintf(vis_stdout, "12345678901234567890123456789012345\n");
01880     fprintf(vis_stdout, "----------------------------------------");
01881     fprintf(vis_stdout, "----------------------------------------\n");
01882     for (i = 0; i < info->nVars; i++) {
01883       if (!support[i])
01884         continue;
01885       if (st_lookup(info->rangeVarsTable, (char *)(long)i, NIL(char *)))
01886         continue;
01887       for (j = start; j <= end; j++) {
01888         comp = array_fetch(ImgComponent_t *, vector, j);
01889         if (comp->support[i])
01890           line[j - start] = '1';
01891         else
01892           line[j - start] = '.';
01893       }
01894       line[j - start] = '\0';
01895       fprintf(vis_stdout, "%4d %s\n", i, line);
01896     }
01897     if (end >= nFuncs - 1)
01898       break;
01899     start += 75;
01900     end += 75;
01901     if (end >= nFuncs)
01902       end = nFuncs - 1;
01903   }
01904   FREE(support);
01905 }
01906 
01907 
01917 float
01918 ImgPercentVectorDependency(ImgTfmInfo_t *info, array_t *vector, int length,
01919                            int *nLongs)
01920 {
01921   int                   i, j, index, nFuncs, nSupports, nLambdaLatches;
01922   int                   count, total;
01923   char                  *support;
01924   ImgComponent_t        *comp;
01925   float                 percent;
01926   int                   *occurs;
01927 
01928   support = ALLOC(char, sizeof(char) * info->nVars);
01929   memset(support, 0, sizeof(char) * info->nVars);
01930   occurs = ALLOC(int, sizeof(int) * info->nVars);
01931   memset(occurs, 0, sizeof(int) * info->nVars);
01932 
01933   count = 0;
01934   nFuncs = array_n(vector);
01935   for (i = 0; i < nFuncs; i++) {
01936     comp = array_fetch(ImgComponent_t *, vector, i);
01937     for (j = 0; j < info->nVars; j++) {
01938       if (comp->support[j]) {
01939         support[j] = 1;
01940         count++;
01941         occurs[i]++;
01942       }
01943     }
01944   }
01945   nSupports = 0;
01946   for (i = 0; i < info->nVars; i++) {
01947     if (support[i])
01948       nSupports++;
01949   }
01950   nLambdaLatches = 0;
01951   for (i = 0; i < nFuncs; i++) {
01952     comp = array_fetch(ImgComponent_t *, vector, i);
01953     index = bdd_top_var_id(comp->var);
01954     if (!support[index])
01955       nLambdaLatches++;
01956   }
01957   FREE(support);
01958 
01959   *nLongs = 0;
01960   for (i = 0; i < info->nVars; i++) {
01961     if (occurs[i] >= length)
01962       (*nLongs)++;
01963   }
01964 
01965   total = (nFuncs - nLambdaLatches) * nSupports;
01966   percent = (float)count / (float)total * 100.0;
01967   return(percent);
01968 }
01969 
01970 
01980 void
01981 ImgWriteSupportMatrix(ImgTfmInfo_t *info, array_t *vector,
01982                       array_t *relationArray, char *string)
01983 {
01984   int                   i, j, id, nFuncs, nRelations, nRows, nSupports;
01985   int                   *row, col, varType;
01986   char                  *support, **relationSupport;
01987   ImgComponent_t        *comp;
01988   FILE                  *fout;
01989   mdd_t                 *relation, *var;
01990   char                  *filename;
01991 
01992   support = ALLOC(char, sizeof(char) * info->nVars);
01993   memset(support, 0, sizeof(char) * info->nVars);
01994   nRows = 0;
01995   if (vector)
01996     nRows += array_n(vector);
01997   if (relationArray)
01998     nRows += array_n(relationArray);
01999   row = ALLOC(int, sizeof(int) * nRows);
02000   if (string)
02001     filename = string;
02002   else
02003     filename = "support.mat";
02004   fout = fopen(filename, "w");
02005 
02006   nRows = 0;
02007   if (vector) {
02008     nFuncs = array_n(vector);
02009     for (i = 0; i < nFuncs; i++) {
02010       comp = array_fetch(ImgComponent_t *, vector, i);
02011       if (ImgSupportCount(info, comp->support) == 0) {
02012         row[i] = -1;
02013         continue;
02014       }
02015       row[i] = nRows;
02016       nRows++;
02017       if (info->option->writeSupportMatrixWithYvars) {
02018         var = ImgSubstitute(comp->var, info->functionData, Img_D2R_c);
02019         id = (int)bdd_top_var_id(var);
02020         support[id] = 1;
02021         mdd_free(var);
02022       }
02023       for (j = 0; j < info->nVars; j++) {
02024         if (comp->support[j])
02025           support[j] = 1;
02026       }
02027     }
02028   } else
02029     nFuncs = 0;
02030 
02031   relationSupport = 0;
02032   if (relationArray && array_n(relationArray) > 0) {
02033     comp = ImgComponentAlloc(info);
02034     nRelations = 0;
02035     relationSupport = ALLOC(char *, sizeof(char *) * array_n(relationArray));
02036     for (i = 0; i < array_n(relationArray); i++) {
02037       relation = array_fetch(mdd_t *, relationArray, i);
02038       comp->func = relation;
02039       ImgSupportClear(info, comp->support);
02040       ImgComponentGetSupport(comp);
02041       if (ImgSupportCount(info, comp->support) <= 1) {
02042         row[i + nFuncs] = -1;
02043         relationSupport[i] = NIL(char);
02044         continue;
02045       }
02046       row[i + nFuncs] = nRows;
02047       nRows++;
02048       for (j = 0; j < info->nVars; j++) {
02049         if (comp->support[j])
02050           support[j] = 1;
02051       }
02052       relationSupport[i] = ALLOC(char, sizeof(char) * info->nVars);
02053       memcpy(relationSupport[i], comp->support, sizeof(char) * info->nVars);
02054       nRelations++;
02055     }
02056     comp->func = NIL(mdd_t);
02057     ImgComponentFree(comp);
02058   } else
02059     nRelations = 0;
02060 
02061   nSupports = 0;
02062   for (i = 0; i < info->nVars; i++) {
02063     if (support[i]) {
02064       if (!info->option->writeSupportMatrixWithYvars &&
02065           st_lookup(info->rangeVarsTable, (char *)(long)i, NIL(char *))) {
02066         continue;
02067       }
02068       nSupports++;
02069     }
02070   }
02071 
02072   col = 0;
02073   for (i = 0; i < info->nVars; i++) {
02074     if (!support[i])
02075       continue;
02076     if (st_lookup(info->rangeVarsTable, (char *)(long)i, NIL(char *))) {
02077       if (info->option->writeSupportMatrixWithYvars)
02078         varType = 3;
02079       else
02080         continue;
02081     } else if (st_lookup(info->quantifyVarsTable, (char *)(long)i, NIL(char *)))
02082       varType = 2;
02083     else
02084       varType = 1;
02085     for (j = 0; j < nFuncs; j++) {
02086       comp = array_fetch(ImgComponent_t *, vector, j);
02087       if (comp->support[i]) {
02088         if (info->option->writeSupportMatrixReverseRow) {
02089           if (info->option->writeSupportMatrixReverseCol) {
02090             fprintf(fout, "%d %d %d\n", nSupports - col, nRows - row[j],
02091                     varType);
02092           } else
02093             fprintf(fout, "%d %d %d\n", col + 1, nRows - row[j], varType);
02094         } else {
02095           if (info->option->writeSupportMatrixReverseCol)
02096             fprintf(fout, "%d %d %d\n", nSupports - col, row[j] + 1, varType);
02097           else
02098             fprintf(fout, "%d %d %d\n", col + 1, row[j] + 1, varType);
02099         }
02100       } else if (varType == 3) {
02101         var = ImgSubstitute(comp->var, info->functionData, Img_D2R_c);
02102         id = (int)bdd_top_var_id(var);
02103         mdd_free(var);
02104         if (id == i) {
02105           if (info->option->writeSupportMatrixReverseRow) {
02106             if (info->option->writeSupportMatrixReverseCol)
02107               fprintf(fout, "%d %d 3\n", nSupports - col, nRows - row[j]);
02108             else
02109               fprintf(fout, "%d %d 3\n", col + 1, nRows - row[j]);
02110           } else {
02111             if (info->option->writeSupportMatrixReverseCol)
02112               fprintf(fout, "%d %d 3\n", nSupports - col, row[j] + 1);
02113             else
02114               fprintf(fout, "%d %d 3\n", col + 1, row[j] + 1);
02115           }
02116         }
02117       }
02118     }
02119     if (relationArray) {
02120       for (j = 0; j < array_n(relationArray); j++) {
02121         if (relationSupport[j] && relationSupport[j][i]) {
02122           if (info->option->writeSupportMatrixReverseRow) {
02123             if (info->option->writeSupportMatrixReverseCol) {
02124               fprintf(fout, "%d %d %d\n", nSupports - col,
02125                       nRows - row[j + nFuncs], varType);
02126             } else {
02127               fprintf(fout, "%d %d %d\n", col + 1, nRows - row[j + nFuncs],
02128                       varType);
02129             }
02130           } else {
02131             if (info->option->writeSupportMatrixReverseCol) {
02132               fprintf(fout, "%d %d %d\n", nSupports - col, row[j + nFuncs] + 1,
02133                       varType);
02134             } else {
02135               fprintf(fout, "%d %d %d\n", col + 1, row[j + nFuncs] + 1,
02136                       varType);
02137             }
02138           }
02139         }
02140       }
02141     }
02142     col++;
02143   }
02144   fclose(fout);
02145   FREE(support);
02146   FREE(row);
02147   if (nRelations) {
02148     for (i = 0; i < nRelations; i++)
02149       FREE(relationSupport[i]);
02150     FREE(relationSupport);
02151   }
02152 }
02153 
02154 
02155 /*---------------------------------------------------------------------------*/
02156 /* Definition of static functions                                            */
02157 /*---------------------------------------------------------------------------*/
02158 
02159 
02170 static int
02171 SignatureCompare(int *ptrX, int *ptrY)
02172 {
02173   if (signatures[*ptrY] > signatures[*ptrX])
02174     return(1);
02175   if (signatures[*ptrY] < signatures[*ptrX])
02176     return(-1);
02177   return(0);
02178 } /* end of SignatureCompare */
02179 
02180 
02190 static int
02191 CompareBddPointer(const void *e1, const void *e2)
02192 {
02193   ImgComponent_t        *c1, *c2;
02194   unsigned long         ptr1, ptr2;
02195 
02196   c1 = *((ImgComponent_t **)e1);
02197   c2 = *((ImgComponent_t **)e2);
02198 
02199   ptr1 = (unsigned long)bdd_pointer(c1->func);
02200   ptr2 = (unsigned long)bdd_pointer(c2->func);
02201 
02202   if (ptr1 > ptr2)
02203     return(1);
02204   else if (ptr1 < ptr2)
02205     return(-1);
02206   else
02207     return(0);
02208 }