VIS
|
00001 00060 #include "imgInt.h" 00061 #include "fsm.h" 00062 00063 static char rcsid[] UNUSED = "$Id: imgIwls95.c,v 1.127 2005/05/18 18:11:57 jinh Exp $"; 00064 00065 /*---------------------------------------------------------------------------*/ 00066 /* Constant declarations */ 00067 /*---------------------------------------------------------------------------*/ 00068 #define domainVar_c 0 00069 #define rangeVar_c 1 00070 #define quantifyVar_c 2 00071 #define IMG_IWLS95_DEBUG 00072 00073 /*---------------------------------------------------------------------------*/ 00074 /* Type declarations */ 00075 /*---------------------------------------------------------------------------*/ 00076 00077 typedef struct Iwls95InfoStruct Iwls95Info_t; 00078 typedef struct CtrInfoStruct CtrInfo_t; 00079 typedef struct VarInfoStruct VarInfo_t; 00080 typedef struct CtrItemStruct CtrItem_t; 00081 typedef struct VarItemStruct VarItem_t; 00082 00083 /*---------------------------------------------------------------------------*/ 00084 /* Structure declarations */ 00085 /*---------------------------------------------------------------------------*/ 00127 struct Iwls95InfoStruct { 00128 array_t *bitRelationArray; 00129 00130 array_t *quantifyVarMddIdArray; 00131 00132 array_t *fwdOptClusteredRelationArray; 00133 array_t *fwdClusteredRelationArray; 00134 array_t *fwdOriClusteredRelationArray; 00135 array_t *bwdClusteredRelationArray; 00136 array_t *bwdOriClusteredRelationArray; 00137 array_t *bwdClusteredCofactoredRelationArray; 00138 array_t *careSetArray; 00139 00140 array_t *fwdOptArraySmoothVarBddArray; 00141 array_t *fwdArraySmoothVarBddArray; 00142 array_t *bwdArraySmoothVarBddArray; 00143 array_t *fwdOptSmoothVarCubeArray; 00144 array_t *fwdSmoothVarCubeArray; 00145 array_t *bwdSmoothVarCubeArray; 00146 00147 boolean allowPartialImage; 00148 boolean wasPartialImage; 00149 ImgPartialImageOption_t *PIoption; 00150 00151 array_t *savedArraySmoothVarBddArray; 00152 array_t *savedSmoothVarCubeArray; 00153 00154 Img_MethodType method; 00155 ImgTrmOption_t *option; 00156 00157 int eliminateDepend; 00158 /* 0 : do not perform this 00159 1 : eliminates dependent variables from 00160 constraint and modifies function vector by 00161 composition at every image computation. 00162 2 : once the number of eliminated variables 00163 becomes zero, do not perform. 00164 */ 00165 int nFoundDependVars; 00166 float averageFoundDependVars; 00167 00168 int nPrevEliminatedFwd; 00169 int linearComputeRange; 00170 00171 boolean lazySiftFlag; 00172 }; 00173 00174 00187 struct CtrInfoStruct { 00188 int ctrId; /* Unique id of the cluster */ 00189 int numLocalSmoothVars; /* 00190 * Number of smooth variables in the support of the 00191 * cluster which can be quantified out if the cluster 00192 * is multiplied in the current product. 00193 */ 00194 int numSmoothVars; /* Number of smooth variables in the support */ 00195 int numIntroducedVars; /* 00196 * Number of range variables introduced if the cluster 00197 * is multiplied in the current product. 00198 */ 00199 int maxSmoothVarIndex; /* Max. index of a smooth variable in the support */ 00200 int rankMaxSmoothVarIndex; /* Rank of maximum index amongst all ctr's */ 00201 lsList varItemList; /* List of varItemStruct of the support variables */ 00202 lsHandle ctrInfoListHandle; /* 00203 * Handle to the list of info struct of ctr's 00204 * which are yet to be ordered. 00205 */ 00206 }; 00207 00208 00209 00222 struct VarInfoStruct { 00223 int bddId; /* BDD id of the variable */ 00224 int numCtr; /* Number of components which depend on this variable. */ 00225 int varType; /* Domain, range or quantify variable ?*/ 00226 lsList ctrItemList; /* List of ctrItemStruct corresponding to the clusters 00227 that depend on it */ 00228 }; 00229 00230 00231 00244 struct VarItemStruct { 00245 VarInfo_t *varInfo; /* The pointer to the corresponding variable info 00246 * structure */ 00247 lsHandle ctrItemHandle; /* 00248 * The list handle to the ctrItemStruct 00249 * corresponding to the ctrInfo (the one which 00250 * contains this varItem in the varItemList) in the 00251 * ctrItemList field of the varInfo. 00252 */ 00253 }; 00254 00255 00268 struct CtrItemStruct { 00269 CtrInfo_t *ctrInfo; /* Pointer to the corresponding cluster 00270 * info structure. */ 00271 lsHandle varItemHandle; /* 00272 * The list handle to the varItemStruct 00273 * corresponding to the varInfo (the one which 00274 * contains this ctrItem in the ctrItemList) in the 00275 * varItemList field of the ctrInfo. 00276 */ 00277 }; 00278 00279 00280 00281 /*---------------------------------------------------------------------------*/ 00282 /* Variable declarations */ 00283 /*---------------------------------------------------------------------------*/ 00284 00285 static double *signatures; 00286 00287 /*---------------------------------------------------------------------------*/ 00288 /* Macro declarations */ 00289 /*---------------------------------------------------------------------------*/ 00290 00291 00294 /*---------------------------------------------------------------------------*/ 00295 /* Static function prototypes */ 00296 /*---------------------------------------------------------------------------*/ 00297 00298 static void ResetClusteredCofactoredRelationArray(mdd_manager *mddManager, Iwls95Info_t *info); 00299 static void FreeClusteredCofactoredRelationArray(Iwls95Info_t *info); 00300 static ImgTrmOption_t * TrmGetOptions(void); 00301 static void CreateBitRelationArray(Iwls95Info_t *info, ImgFunctionData_t *functionData); 00302 static void FreeBitRelationArray(Iwls95Info_t *info); 00303 static void OrderClusterOrder(mdd_manager *mddManager, array_t *relationArray, array_t *fromVarBddArray, array_t *toVarBddArray, array_t *quantifyVarBddArray, array_t **orderedClusteredRelationArrayPtr, array_t **smoothVarBddArrayPtr, ImgTrmOption_t *option, boolean freeRelationArray); 00304 static array_t * CreateClusters(bdd_manager *bddManager, array_t *relationArray, ImgTrmOption_t *option); 00305 static void OrderRelationArray(mdd_manager *mddManager, array_t *relationArray, array_t *domainVarBddArray, array_t *quantifyVarBddArray, array_t *rangeVarBddArray, ImgTrmOption_t *option, array_t **orderedRelationArrayPtr, array_t **arraySmoothVarBddArrayPtr); 00306 static array_t * RelationArraySmoothLocalVars(array_t *relationArray, array_t *ctrInfoArray, array_t *varInfoArray, st_table *bddIdToBddTable); 00307 static void OrderRelationArrayAux(array_t *relationArray, lsList remainingCtrInfoList, array_t *ctrInfoArray, array_t *varInfoArray, int *sortedMaxIndexVector, int numSmoothVarsRemaining, int numIntroducedVarsRemaining, st_table *bddIdToBddTable, ImgTrmOption_t *option, array_t *domainAndQuantifyVarBddArray, array_t **orderedRelationArrayPtr, array_t **arraySmoothVarBddArrayPtr, array_t *arrayDomainQuantifyVarsWithZeroNumCtr); 00308 static array_t * UpdateInfoArrays(CtrInfo_t *ctrInfo, st_table *bddIdToBddTable, int *numSmoothVarsRemainingPtr, int *numIntroducedVarsRemainingPtr); 00309 static float CalculateBenefit(CtrInfo_t *ctrInfo, int maxNumLocalSmoothVars, int maxNumSmoothVars, int maxIndex, int maxNumIntroducedVars, ImgTrmOption_t *option); 00310 static void PrintOption(Img_MethodType method, ImgTrmOption_t *option, FILE *fp); 00311 static Iwls95Info_t * Iwls95InfoStructAlloc(Img_MethodType method); 00312 static CtrInfo_t * CtrInfoStructAlloc(void); 00313 static void CtrInfoStructFree(CtrInfo_t *ctrInfo); 00314 static VarInfo_t * VarInfoStructAlloc(void); 00315 static void VarInfoStructFree(VarInfo_t *varInfo); 00316 static void CtrItemStructFree(CtrItem_t *ctrItem); 00317 static void VarItemStructFree(VarItem_t *varItem); 00318 static int CtrInfoMaxIndexCompare(const void * p1, const void * p2); 00319 static void PrintCtrInfoStruct(CtrInfo_t *ctrInfo); 00320 static void PrintVarInfoStruct(VarInfo_t *varInfo); 00321 static int CheckQuantificationSchedule(array_t *relationArray, array_t *arraySmoothVarBddArray); 00322 static int CheckCtrInfoArray(array_t *ctrInfoArray, int numDomainVars, int numQuantifyVars, int numRangeVars); 00323 static int CheckCtrInfo(CtrInfo_t *ctrInfo, int numDomainVars, int numQuantifyVars, int numRangeVars); 00324 static int CheckVarInfoArray(array_t *varInfoArray, int numRelation); 00325 static array_t * BddArrayDup(array_t *bddArray); 00326 static array_t * BddArrayArrayDup(array_t *bddArray); 00327 static mdd_t * BddLinearAndSmooth(mdd_manager *mddManager, bdd_t *fromSet, array_t *relationArray, array_t *arraySmoothVarBddArray, array_t *smoothVarCubeArray, int verbosity, ImgPartialImageOption_t *PIoption, boolean *partial, boolean lazySiftFlag); 00328 static void HashIdToBddTable(st_table *table, array_t *idArray, array_t *bddArray); 00329 static void PrintSmoothIntroducedCount(array_t *clusterArray, array_t **arraySmoothVarBddArrayPtr, array_t *psBddIdArray, array_t *nsBddIdArray); 00330 static void PrintBddIdFromBddArray(array_t *bddArray); 00331 static void PrintBddIdTable(st_table *idTable); 00332 static void PartitionTraverseRecursively(mdd_manager *mddManager, vertex_t *vertex, int mddId, st_table *vertexTable, array_t *relationArray, st_table *domainQuantifyVarMddIdTable, array_t *quantifyVarMddIdArray); 00333 static void PrintPartitionRecursively(vertex_t *vertex, st_table *vertexTable, int indent); 00334 static bdd_t * RecomputeImageIfNecessary(ImgFunctionData_t *functionData, mdd_manager *mddManager, bdd_t *domainSubset, array_t *relationArray, array_t *arraySmoothVarBddArray, array_t *smoothVarCubeArray, int verbosity, ImgPartialImageOption_t *PIoption, array_t *toCareSetArray, boolean *partial, boolean lazySiftFlag); 00335 static bdd_t * ComputeSubsetOfIntermediateProduct(bdd_t *product, ImgPartialImageOption_t *PIoption); 00336 static bdd_t * ComputeClippedAndAbstract(bdd_t *product, bdd_t *relation, array_t *smoothVarBddArray, int nvars, int clippingDepth, boolean *partial, int verbosity); 00337 static array_t * CopyArrayBddArray(array_t *arrayBddArray); 00338 static void PrintPartitionedTransitionRelation(mdd_manager *mddManager, Iwls95Info_t *info, Img_DirectionType directionType); 00339 static void ReorderPartitionedTransitionRelation(Iwls95Info_t *info, ImgFunctionData_t *functionData, Img_DirectionType directionType); 00340 static void UpdateQuantificationSchedule(Iwls95Info_t *info, ImgFunctionData_t *functionData, Img_DirectionType directionType); 00341 static array_t * MakeSmoothVarCubeArray(mdd_manager *mddManager, array_t *arraySmoothVarBddArray); 00342 static mdd_t * TrmEliminateDependVars(Img_ImageInfo_t *imageInfo, array_t *relationArray, mdd_t *states, mdd_t **dependRelations); 00343 static int TrmSignatureCompare(int *ptrX, int *ptrY); 00344 static void SetupLazySifting(mdd_manager *mddManager, array_t *bddRelationArray, array_t *domainVarBddArray, array_t *quantifyVarBddArray, array_t *rangeVarBddArray, int verbosity); 00345 static int MddSizeCompare(const void *ptr1, const void *ptr2); 00349 /*---------------------------------------------------------------------------*/ 00350 /* Definition of exported functions */ 00351 /*---------------------------------------------------------------------------*/ 00352 00353 00376 mdd_t* 00377 Img_MultiwayLinearAndSmooth(mdd_manager *mddManager, array_t *relationArray, 00378 array_t *smoothVarMddIdArray, 00379 array_t *introducedVarMddIdArray, 00380 Img_MethodType method, 00381 Img_DirectionType direction) 00382 { 00383 mdd_t *product; 00384 array_t *smoothVarBddArray = mdd_id_array_to_bdd_array(mddManager, 00385 smoothVarMddIdArray); 00386 array_t *introducedVarBddArray = mdd_id_array_to_bdd_array(mddManager, 00387 introducedVarMddIdArray); 00388 00389 product = ImgMultiwayLinearAndSmooth(mddManager, relationArray, 00390 smoothVarBddArray, introducedVarBddArray, 00391 method, direction, NIL(ImgTrmOption_t)); 00392 00393 mdd_array_free(introducedVarBddArray); 00394 mdd_array_free(smoothVarBddArray); 00395 return product; 00396 } 00397 00398 00408 void 00409 Img_PrintPartitionedTransitionRelation(mdd_manager *mddManager, 00410 Img_ImageInfo_t *imageInfo, 00411 Img_DirectionType directionType) 00412 { 00413 Iwls95Info_t *info = (Iwls95Info_t *) imageInfo->methodData; 00414 00415 if (imageInfo->methodType != Img_Iwls95_c && 00416 imageInfo->methodType != Img_Mlp_c && 00417 imageInfo->methodType != Img_Linear_c) 00418 return; 00419 00420 PrintPartitionedTransitionRelation(mddManager, info, directionType); 00421 } 00422 00423 00433 void 00434 Img_ReorderPartitionedTransitionRelation(Img_ImageInfo_t *imageInfo, 00435 Img_DirectionType directionType) 00436 { 00437 if (imageInfo->methodType != Img_Iwls95_c && 00438 imageInfo->methodType != Img_Mlp_c && 00439 imageInfo->methodType != Img_Linear_c) 00440 return; 00441 00442 ReorderPartitionedTransitionRelation((Iwls95Info_t *)imageInfo->methodData, 00443 &(imageInfo->functionData), 00444 directionType); 00445 } 00446 00447 00457 void 00458 Img_UpdateQuantificationSchedule(Img_ImageInfo_t *imageInfo, 00459 Img_DirectionType directionType) 00460 { 00461 if (imageInfo->methodType != Img_Iwls95_c) 00462 return; 00463 00464 UpdateQuantificationSchedule((Iwls95Info_t *)imageInfo->methodData, 00465 &(imageInfo->functionData), directionType); 00466 } 00467 00468 00478 void 00479 Img_ClusterRelationArray(mdd_manager *mddManager, 00480 Img_MethodType method, 00481 Img_DirectionType direction, 00482 array_t *relationArray, 00483 array_t *domainVarMddIdArray, 00484 array_t *rangeVarMddIdArray, 00485 array_t *quantifyVarMddIdArray, 00486 array_t **clusteredRelationArray, 00487 array_t **arraySmoothVarBddArray, 00488 array_t **smoothVarCubeArray, 00489 boolean freeRelationArray) 00490 { 00491 array_t *domainVarBddArray; 00492 array_t *quantifyVarBddArray; 00493 array_t *rangeVarBddArray; 00494 ImgTrmOption_t *option; 00495 00496 option = TrmGetOptions(); 00497 domainVarBddArray = mdd_id_array_to_bdd_array(mddManager, 00498 domainVarMddIdArray); 00499 rangeVarBddArray = mdd_id_array_to_bdd_array(mddManager, 00500 rangeVarMddIdArray); 00501 quantifyVarBddArray = mdd_id_array_to_bdd_array(mddManager, 00502 quantifyVarMddIdArray); 00503 00504 *clusteredRelationArray = ImgClusterRelationArray(mddManager, 00505 NIL(ImgFunctionData_t), 00506 method, 00507 direction, 00508 option, 00509 relationArray, 00510 domainVarBddArray, 00511 quantifyVarBddArray, 00512 rangeVarBddArray, 00513 arraySmoothVarBddArray, 00514 smoothVarCubeArray, 00515 freeRelationArray); 00516 00517 ImgFreeTrmOptions(option); 00518 mdd_array_free(domainVarBddArray); 00519 mdd_array_free(rangeVarBddArray); 00520 mdd_array_free(quantifyVarBddArray); 00521 } 00522 00523 00524 /*---------------------------------------------------------------------------*/ 00525 /* Definition of internal functions */ 00526 /*---------------------------------------------------------------------------*/ 00527 00528 00551 mdd_t* 00552 ImgMultiwayLinearAndSmooth(mdd_manager *mddManager, 00553 array_t *relationArray, 00554 array_t *smoothVarBddArray, 00555 array_t *introducedVarBddArray, 00556 Img_MethodType method, 00557 Img_DirectionType direction, 00558 ImgTrmOption_t *option) 00559 { 00560 mdd_t *product; 00561 array_t *domainVarBddArray = array_alloc(bdd_t*, 0); 00562 00563 product = ImgMultiwayLinearAndSmoothWithFrom(mddManager, relationArray, 00564 NIL(mdd_t), 00565 smoothVarBddArray, 00566 domainVarBddArray, 00567 introducedVarBddArray, 00568 method, direction, option); 00569 00570 array_free(domainVarBddArray); 00571 return product; 00572 } 00573 00574 00601 mdd_t* 00602 ImgMultiwayLinearAndSmoothWithFrom(mdd_manager *mddManager, 00603 array_t *relationArray, 00604 mdd_t *from, 00605 array_t *smoothVarBddArray, 00606 array_t *domainVarBddArray, 00607 array_t *introducedVarBddArray, 00608 Img_MethodType method, 00609 Img_DirectionType direction, 00610 ImgTrmOption_t *option) 00611 { 00612 mdd_t *product; 00613 boolean partial = FALSE; 00614 array_t *orderedRelationArray = NIL(array_t); 00615 array_t *arraySmoothVarBddArray = NIL(array_t); 00616 int freeOptionFlag; 00617 int lazySiftFlag = bdd_is_lazy_sift(mddManager); 00618 00619 if (!option) { 00620 option = TrmGetOptions(); 00621 freeOptionFlag = 1; 00622 } else 00623 freeOptionFlag = 0; 00624 00625 if (method == Img_Iwls95_c) { 00626 OrderRelationArray(mddManager, relationArray, domainVarBddArray, 00627 smoothVarBddArray, introducedVarBddArray, option, 00628 &orderedRelationArray, &arraySmoothVarBddArray); 00629 } else if (method == Img_Mlp_c) { 00630 if (direction == Img_Forward_c) { 00631 /* 00632 * domainVarBddArray : PS 00633 * introducedVarBddArray : NS 00634 */ 00635 if (option->mlpMultiway && from == NIL(mdd_t)) { 00636 product = ImgMlpMultiwayAndSmooth(mddManager, NIL(ImgFunctionData_t), 00637 relationArray, domainVarBddArray, 00638 smoothVarBddArray, 00639 introducedVarBddArray, direction, 00640 option); 00641 array_free(domainVarBddArray); 00642 if (freeOptionFlag) 00643 ImgFreeTrmOptions(option); 00644 return product; 00645 } else { 00646 ImgMlpOrderRelationArray(mddManager, relationArray, domainVarBddArray, 00647 smoothVarBddArray, introducedVarBddArray, 00648 direction, &orderedRelationArray, 00649 &arraySmoothVarBddArray, option); 00650 } 00651 } else { /* direction == Img_Backward_c */ 00652 /* 00653 * domainVarBddArray : NS 00654 * introducedVarBddArray : PS 00655 */ 00656 if (option->mlpPreSwapStateVars) { 00657 if (option->mlpMultiway && from == NIL(mdd_t)) { 00658 product = ImgMlpMultiwayAndSmooth(mddManager, NIL(ImgFunctionData_t), 00659 relationArray, 00660 domainVarBddArray, 00661 smoothVarBddArray, 00662 introducedVarBddArray, 00663 Img_Forward_c, option); 00664 array_free(domainVarBddArray); 00665 if (freeOptionFlag) 00666 ImgFreeTrmOptions(option); 00667 return product; 00668 } else { 00669 ImgMlpOrderRelationArray(mddManager, relationArray, 00670 domainVarBddArray, smoothVarBddArray, 00671 introducedVarBddArray, 00672 Img_Forward_c, &orderedRelationArray, 00673 &arraySmoothVarBddArray, option); 00674 } 00675 } else { 00676 if (option->mlpMultiway && from == NIL(mdd_t)) { 00677 product = ImgMlpMultiwayAndSmooth(mddManager, NIL(ImgFunctionData_t), 00678 relationArray, domainVarBddArray, 00679 smoothVarBddArray, 00680 introducedVarBddArray, 00681 Img_Backward_c, option); 00682 array_free(domainVarBddArray); 00683 if (freeOptionFlag) 00684 ImgFreeTrmOptions(option); 00685 return product; 00686 } else { 00687 ImgMlpOrderRelationArray(mddManager, relationArray, 00688 domainVarBddArray, smoothVarBddArray, 00689 introducedVarBddArray, 00690 Img_Backward_c, &orderedRelationArray, 00691 &arraySmoothVarBddArray, option); 00692 } 00693 } 00694 } 00695 } else 00696 assert(0); 00697 00698 product = BddLinearAndSmooth(mddManager, from, 00699 orderedRelationArray, 00700 arraySmoothVarBddArray, 00701 NIL(array_t), 00702 option->verbosity, 00703 NULL, &partial, lazySiftFlag); 00704 00705 if (freeOptionFlag) 00706 ImgFreeTrmOptions(option); 00707 mdd_array_free(orderedRelationArray); 00708 mdd_array_array_free(arraySmoothVarBddArray); 00709 return product; 00710 } 00711 00712 00727 mdd_t* 00728 ImgBddLinearAndSmooth(mdd_manager *mddManager, 00729 mdd_t *from, 00730 array_t *relationArray, 00731 array_t *arraySmoothVarBddArray, 00732 array_t *smoothVarCubeArray, 00733 int verbosity) 00734 { 00735 mdd_t *product; 00736 boolean partial = FALSE; 00737 int lazySiftFlag = bdd_is_lazy_sift(mddManager); 00738 00739 product = BddLinearAndSmooth(mddManager, from, 00740 relationArray, 00741 arraySmoothVarBddArray, 00742 smoothVarCubeArray, 00743 verbosity, 00744 NULL, &partial, lazySiftFlag); 00745 00746 return product; 00747 } 00748 00749 00760 array_t * 00761 ImgClusterRelationArray(mdd_manager *mddManager, 00762 ImgFunctionData_t *functionData, 00763 Img_MethodType method, 00764 Img_DirectionType direction, 00765 ImgTrmOption_t *option, 00766 array_t *relationArray, 00767 array_t *domainVarBddArray, 00768 array_t *quantifyVarBddArray, 00769 array_t *rangeVarBddArray, 00770 array_t **arraySmoothVarBddArray, 00771 array_t **smoothVarCubeArray, 00772 boolean freeRelationArray) 00773 { 00774 array_t *orderedRelationArray; 00775 array_t *clusteredRelationArray; 00776 int freeOptionFlag; 00777 long initialTime, finalTime; 00778 00779 if (!option) { 00780 option = TrmGetOptions(); 00781 freeOptionFlag = 1; 00782 } else 00783 freeOptionFlag = 0; 00784 00785 if (option->verbosity >= 2) 00786 initialTime = util_cpu_time(); 00787 else /* to remove uninitialized variables warning */ 00788 initialTime = 0; 00789 00790 if (method == Img_Iwls95_c) { 00791 assert(direction != Img_Both_c); 00792 if (direction == Img_Forward_c) { 00793 OrderClusterOrder(mddManager, relationArray, domainVarBddArray, 00794 rangeVarBddArray, quantifyVarBddArray, 00795 &orderedRelationArray, arraySmoothVarBddArray, 00796 option, freeRelationArray); 00797 } else { 00798 assert(direction == Img_Backward_c); 00799 OrderClusterOrder(mddManager, relationArray, rangeVarBddArray, 00800 domainVarBddArray, quantifyVarBddArray, 00801 &orderedRelationArray, arraySmoothVarBddArray, 00802 option, freeRelationArray); 00803 00804 } 00805 if (freeOptionFlag) 00806 ImgFreeTrmOptions(option); 00807 00808 if (smoothVarCubeArray) { 00809 if (functionData->createVarCubesFlag) { 00810 *smoothVarCubeArray = MakeSmoothVarCubeArray(mddManager, 00811 *arraySmoothVarBddArray); 00812 } else 00813 *smoothVarCubeArray = NIL(array_t); 00814 } 00815 if (option->verbosity >= 2) { 00816 finalTime = util_cpu_time(); 00817 fprintf(vis_stdout, "time for clustering with IWLS95 = %10g\n", 00818 (double)(finalTime - initialTime) / 1000.0); 00819 } 00820 return(orderedRelationArray); 00821 } else if (method == Img_Mlp_c) { 00822 if ((direction == Img_Forward_c && option->mlpReorder == 2) || 00823 (direction == Img_Backward_c && option->mlpPreReorder == 2)) { 00824 if (direction == Img_Forward_c) 00825 option->mlpReorder = 0; 00826 else 00827 option->mlpPreReorder = 0; 00828 ImgMlpClusterRelationArray(mddManager, functionData, relationArray, 00829 domainVarBddArray, quantifyVarBddArray, rangeVarBddArray, 00830 direction, &clusteredRelationArray, NIL(array_t *), option); 00831 if (direction == Img_Forward_c) 00832 option->mlpReorder = 2; 00833 else 00834 option->mlpPreReorder = 2; 00835 ImgMlpOrderRelationArray(mddManager, clusteredRelationArray, 00836 domainVarBddArray, quantifyVarBddArray, rangeVarBddArray, 00837 direction, &orderedRelationArray, arraySmoothVarBddArray, 00838 option); 00839 mdd_array_free(clusteredRelationArray); 00840 } else if ((direction == Img_Forward_c && option->mlpReorder == 3) || 00841 (direction == Img_Backward_c && option->mlpPreReorder == 3)) { 00842 if (direction == Img_Forward_c) 00843 option->mlpReorder = 0; 00844 else 00845 option->mlpPreReorder = 0; 00846 ImgMlpClusterRelationArray(mddManager, functionData, relationArray, 00847 domainVarBddArray, quantifyVarBddArray, rangeVarBddArray, 00848 direction, &clusteredRelationArray, NIL(array_t *), option); 00849 if (direction == Img_Forward_c) 00850 option->mlpReorder = 3; 00851 else 00852 option->mlpPreReorder = 3; 00853 OrderRelationArray(mddManager, clusteredRelationArray, 00854 domainVarBddArray, quantifyVarBddArray, 00855 rangeVarBddArray, option, 00856 &orderedRelationArray, arraySmoothVarBddArray); 00857 mdd_array_free(clusteredRelationArray); 00858 } else { 00859 ImgMlpClusterRelationArray(mddManager, functionData, relationArray, 00860 domainVarBddArray, quantifyVarBddArray, rangeVarBddArray, 00861 direction, &orderedRelationArray, arraySmoothVarBddArray, 00862 option); 00863 } 00864 if (freeOptionFlag) 00865 ImgFreeTrmOptions(option); 00866 if (smoothVarCubeArray) { 00867 if (functionData->createVarCubesFlag) { 00868 *smoothVarCubeArray = MakeSmoothVarCubeArray(mddManager, 00869 *arraySmoothVarBddArray); 00870 } else 00871 *smoothVarCubeArray = NIL(array_t); 00872 } 00873 if (option->verbosity >= 2) { 00874 finalTime = util_cpu_time(); 00875 fprintf(vis_stdout, "time for clustering with MLP = %10g\n", 00876 (double)(finalTime - initialTime) / 1000.0); 00877 } 00878 return(orderedRelationArray); 00879 } else 00880 assert(0); 00881 return NIL(array_t); /* we should never get here */ 00882 } 00883 00884 00894 array_t * 00895 ImgGetQuantificationSchedule(mdd_manager *mddManager, 00896 ImgFunctionData_t *functionData, 00897 Img_MethodType method, 00898 Img_DirectionType direction, 00899 ImgTrmOption_t *option, 00900 array_t *relationArray, 00901 array_t *smoothVarBddArray, 00902 array_t *domainVarBddArray, 00903 array_t *introducedVarBddArray, 00904 boolean withClustering, 00905 array_t **orderedRelationArrayPtr) 00906 { 00907 array_t *orderedRelationArray = NIL(array_t); 00908 array_t *clusteredRelationArray; 00909 array_t *arraySmoothVarBddArray = NIL(array_t); 00910 int freeOptionFlag; 00911 00912 if (!option) { 00913 option = TrmGetOptions(); 00914 freeOptionFlag = 1; 00915 } else 00916 freeOptionFlag = 0; 00917 00918 if (method == Img_Iwls95_c) { 00919 if (withClustering) { 00920 OrderRelationArray(mddManager, relationArray, domainVarBddArray, 00921 smoothVarBddArray, introducedVarBddArray, option, 00922 &orderedRelationArray, NIL(array_t *)); 00923 00924 clusteredRelationArray = CreateClusters(mddManager, orderedRelationArray, 00925 option); 00926 mdd_array_free(orderedRelationArray); 00927 00928 OrderRelationArray(mddManager, clusteredRelationArray, domainVarBddArray, 00929 smoothVarBddArray, introducedVarBddArray, option, 00930 &orderedRelationArray, &arraySmoothVarBddArray); 00931 mdd_array_free(clusteredRelationArray); 00932 } else { 00933 OrderRelationArray(mddManager, relationArray, domainVarBddArray, 00934 smoothVarBddArray, introducedVarBddArray, option, 00935 &orderedRelationArray, &arraySmoothVarBddArray); 00936 } 00937 } else if (method == Img_Mlp_c) { 00938 if (withClustering) { 00939 ImgMlpClusterRelationArray(mddManager, functionData, relationArray, 00940 domainVarBddArray, smoothVarBddArray, introducedVarBddArray, 00941 direction, &orderedRelationArray, &arraySmoothVarBddArray, 00942 option); 00943 } else { 00944 ImgMlpOrderRelationArray(mddManager, relationArray, domainVarBddArray, 00945 smoothVarBddArray, introducedVarBddArray, direction, 00946 &orderedRelationArray, &arraySmoothVarBddArray, 00947 option); 00948 } 00949 } else 00950 assert(0); 00951 00952 if (freeOptionFlag) 00953 ImgFreeTrmOptions(option); 00954 if (orderedRelationArrayPtr) 00955 *orderedRelationArrayPtr = orderedRelationArray; 00956 else 00957 mdd_array_free(orderedRelationArray); 00958 return(arraySmoothVarBddArray); 00959 } 00960 00961 00971 ImgTrmOption_t * 00972 ImgGetTrmOptions(void) 00973 { 00974 ImgTrmOption_t *option; 00975 00976 option = TrmGetOptions(); 00977 return(option); 00978 } 00979 00980 00990 void 00991 ImgFreeTrmOptions(ImgTrmOption_t *option) 00992 { 00993 if (option->readCluster) 00994 FREE(option->readCluster); 00995 if (option->writeCluster) 00996 FREE(option->writeCluster); 00997 if (option->writeDepMatrix) 00998 FREE(option->writeDepMatrix); 00999 FREE(option); 01000 } 01001 01002 01014 void 01015 ImgResetMethodDataLinearComputeRange(void *methodData) 01016 { 01017 Iwls95Info_t *info = (Iwls95Info_t *) methodData; 01018 info->linearComputeRange = 0; 01019 } 01020 01031 void 01032 ImgSetMethodDataLinearComputeRange(void *methodData) 01033 { 01034 Iwls95Info_t *info = (Iwls95Info_t *) methodData; 01035 info->linearComputeRange = 1; 01036 } 01037 01048 mdd_t * 01049 Img_ImageGetUnreachableStates(Img_ImageInfo_t * imageInfo) 01050 { 01051 array_t *relationArray; 01052 mdd_t *states; 01053 Iwls95Info_t *info = (Iwls95Info_t *) imageInfo->methodData; 01054 01055 relationArray = info->fwdOptClusteredRelationArray; 01056 states = array_fetch(mdd_t *, relationArray, 0); 01057 states = ImgSubstitute(states, &(imageInfo->functionData), Img_R2D_c); 01058 return(states); 01059 } 01060 01061 01080 void * 01081 ImgImageInfoInitializeIwls95(void *methodData, 01082 ImgFunctionData_t *functionData, 01083 Img_DirectionType directionType, 01084 Img_MethodType method) 01085 { 01086 array_t *fwdClusteredRelationArray; 01087 array_t *bwdClusteredRelationArray; 01088 Iwls95Info_t *info = (Iwls95Info_t *) methodData; 01089 Ntk_Network_t *network; 01090 Ntk_Node_t *node; 01091 char *flagValue; 01092 int i, mddId ; 01093 01094 if (info && 01095 (((info->fwdClusteredRelationArray) && 01096 (info->bwdClusteredRelationArray)) || 01097 ((directionType == Img_Forward_c) && 01098 (info->fwdClusteredRelationArray)) || 01099 ((directionType == Img_Backward_c) && 01100 (info->bwdClusteredRelationArray)))) { 01101 /* Nothing needs to be done. Return */ 01102 return (void *) info; 01103 } 01104 else{ 01105 array_t *rangeVarBddArray, *domainVarBddArray, *quantifyVarBddArray; 01106 array_t *newQuantifyVarMddIdArray; 01107 array_t *clusteredRelationArray; 01108 FILE *fin, *fout; 01109 array_t *bddRelationArray, *quantifyVarMddIdArray; 01110 mdd_manager *mddManager = Part_PartitionReadMddManager(functionData->mddNetwork); 01111 01112 if (info == NIL(Iwls95Info_t)) { 01113 info = Iwls95InfoStructAlloc(method); 01114 } 01115 CreateBitRelationArray(info, functionData); 01116 01118 bddRelationArray = info->bitRelationArray; 01119 quantifyVarMddIdArray = info->quantifyVarMddIdArray; 01120 if(functionData->FAFWFlag) { 01121 network = functionData->network; 01122 newQuantifyVarMddIdArray = array_alloc(int, 0); 01123 for(i=0; i<array_n(quantifyVarMddIdArray); i++) { 01124 mddId = array_fetch(int, quantifyVarMddIdArray, i); 01125 node = Ntk_NetworkFindNodeByMddId(network, mddId); 01126 if(!Ntk_NodeTestIsInput(node)) { 01127 array_insert_last(int, newQuantifyVarMddIdArray, mddId); 01128 } 01129 } 01130 array_free(quantifyVarMddIdArray); 01131 quantifyVarMddIdArray = newQuantifyVarMddIdArray; 01132 info->quantifyVarMddIdArray = newQuantifyVarMddIdArray; 01133 } 01134 01135 info->bitRelationArray = NIL(array_t); 01136 info->quantifyVarMddIdArray = NIL(array_t); 01137 01138 rangeVarBddArray = functionData->rangeBddVars; 01139 domainVarBddArray = functionData->domainBddVars; 01140 quantifyVarBddArray = mdd_id_array_to_bdd_array(mddManager, 01141 quantifyVarMddIdArray); 01142 01143 array_free(quantifyVarMddIdArray); 01144 01145 if (((directionType == Img_Forward_c) || 01146 (directionType == Img_Both_c)) && 01147 (info->fwdClusteredRelationArray == NIL(array_t))) { 01148 if (info->option->readCluster) { 01149 if (info->option->readReorderCluster) { 01150 fin = fopen(info->option->readCluster, "r"); 01151 ImgMlpReadClusterFile(fin, mddManager, 01152 functionData, bddRelationArray, 01153 domainVarBddArray, rangeVarBddArray, 01154 quantifyVarBddArray, Img_Forward_c, 01155 &clusteredRelationArray, NIL(array_t *), 01156 info->option); 01157 fclose(fin); 01158 if (method == Img_Iwls95_c) { 01159 OrderRelationArray(mddManager, clusteredRelationArray, 01160 domainVarBddArray, quantifyVarBddArray, 01161 rangeVarBddArray, info->option, 01162 &info->fwdClusteredRelationArray, 01163 &info->fwdArraySmoothVarBddArray); 01164 } else if (method == Img_Mlp_c) { 01165 ImgMlpOrderRelationArray(mddManager, clusteredRelationArray, 01166 domainVarBddArray, quantifyVarBddArray, 01167 rangeVarBddArray, Img_Forward_c, 01168 &info->fwdClusteredRelationArray, 01169 &info->fwdArraySmoothVarBddArray, 01170 info->option); 01171 } else 01172 assert(0); 01173 mdd_array_free(clusteredRelationArray); 01174 } else { 01175 fin = fopen(info->option->readCluster, "r"); 01176 ImgMlpReadClusterFile(fin, mddManager, 01177 functionData, bddRelationArray, 01178 domainVarBddArray, rangeVarBddArray, 01179 quantifyVarBddArray, Img_Forward_c, 01180 &info->fwdClusteredRelationArray, 01181 &info->fwdArraySmoothVarBddArray, 01182 info->option); 01183 fclose(fin); 01184 } 01185 } else if (method == Img_Iwls95_c) { 01186 /* 01187 * Since clusters are formed by multiplying the latches starting 01188 * from one end we need to order the latches using some heuristics 01189 * first. Right now, we order the latches using the same heuristic 01190 * as the one used for ordering the clusters for early quantifiction. 01191 * However, since we are not interested in the quantification 01192 * schedule at this stage, we will pass a NIL(array_t*) as the last 01193 * argument. 01194 */ 01195 OrderClusterOrder(mddManager, bddRelationArray, domainVarBddArray, 01196 rangeVarBddArray, quantifyVarBddArray, 01197 &info->fwdClusteredRelationArray, 01198 &info->fwdArraySmoothVarBddArray, 01199 info->option, 0); 01200 } else if (method == Img_Mlp_c) { 01201 if (info->option->mlpReorder == 2) { 01202 info->option->mlpReorder = 0; 01203 ImgMlpClusterRelationArray(mddManager, functionData, 01204 bddRelationArray, domainVarBddArray, 01205 quantifyVarBddArray, rangeVarBddArray, 01206 Img_Forward_c, &clusteredRelationArray, 01207 NIL(array_t *), info->option); 01208 info->option->mlpReorder = 2; 01209 ImgMlpOrderRelationArray(mddManager, clusteredRelationArray, 01210 domainVarBddArray, quantifyVarBddArray, 01211 rangeVarBddArray, Img_Forward_c, 01212 &info->fwdClusteredRelationArray, 01213 &info->fwdArraySmoothVarBddArray, info->option); 01214 mdd_array_free(clusteredRelationArray); 01215 } else if (info->option->mlpReorder == 3) { 01216 info->option->mlpReorder = 0; 01217 ImgMlpClusterRelationArray(mddManager, functionData, 01218 bddRelationArray, domainVarBddArray, 01219 quantifyVarBddArray, rangeVarBddArray, 01220 Img_Forward_c, &clusteredRelationArray, 01221 NIL(array_t *), info->option); 01222 info->option->mlpReorder = 3; 01223 OrderRelationArray(mddManager, clusteredRelationArray, 01224 domainVarBddArray, quantifyVarBddArray, 01225 rangeVarBddArray, info->option, 01226 &info->fwdClusteredRelationArray, 01227 &info->fwdArraySmoothVarBddArray); 01228 mdd_array_free(clusteredRelationArray); 01229 } else { 01230 ImgMlpClusterRelationArray(mddManager, functionData, 01231 bddRelationArray, domainVarBddArray, 01232 quantifyVarBddArray, rangeVarBddArray, 01233 Img_Forward_c, &info->fwdClusteredRelationArray, 01234 &info->fwdArraySmoothVarBddArray, info->option); 01235 } 01236 } else if (method == Img_Linear_c || method == Img_Linear_Range_c) { 01237 if(method == Img_Linear_Range_c) { 01238 info->option->linearComputeRange = 1; 01239 method = Img_Linear_c; 01240 } 01241 ImgLinearClusterRelationArray(mddManager, functionData, 01242 bddRelationArray, 01243 Img_Forward_c, 01244 &info->fwdClusteredRelationArray, 01245 &info->fwdArraySmoothVarBddArray, 01246 &info->fwdOptClusteredRelationArray, 01247 &info->fwdOptArraySmoothVarBddArray, 01248 info->option); 01249 } else 01250 assert(0); 01251 01252 if (info->option->verbosity > 2) 01253 PrintPartitionedTransitionRelation(mddManager, info, Img_Forward_c); 01254 if(method == Img_Linear_c) 01255 ImgPrintPartitionedTransitionRelation(mddManager, 01256 info->fwdOptClusteredRelationArray , 01257 info->fwdOptArraySmoothVarBddArray); 01258 01259 if (info->option->printDepMatrix || info->option->writeDepMatrix) { 01260 if (info->option->writeDepMatrix) { 01261 fout = fopen(info->option->writeDepMatrix, "w"); 01262 if (!fout) { 01263 fprintf(vis_stderr, "** img error: can't open file [%s]\n", 01264 info->option->writeDepMatrix); 01265 } 01266 } else 01267 fout = NIL(FILE); 01268 ImgMlpPrintDependenceMatrix(mddManager, 01269 info->fwdClusteredRelationArray, 01270 domainVarBddArray, quantifyVarBddArray, rangeVarBddArray, 01271 Img_Forward_c, info->option->printDepMatrix, fout, 01272 info->option); 01273 if (fout) 01274 fclose(fout); 01275 } 01276 if (info->option->writeCluster) { 01277 fout = fopen(info->option->writeCluster, "w"); 01278 ImgMlpWriteClusterFile(fout, mddManager, 01279 info->fwdClusteredRelationArray, 01280 domainVarBddArray, rangeVarBddArray); 01281 fclose(fout); 01282 } 01283 01284 if (functionData->createVarCubesFlag && info->fwdArraySmoothVarBddArray) 01285 info->fwdSmoothVarCubeArray = MakeSmoothVarCubeArray(mddManager, 01286 info->fwdArraySmoothVarBddArray); 01287 else 01288 info->fwdSmoothVarCubeArray = NIL(array_t); 01289 01290 if (functionData->createVarCubesFlag && info->fwdOptArraySmoothVarBddArray) 01291 info->fwdOptSmoothVarCubeArray = MakeSmoothVarCubeArray(mddManager, 01292 info->fwdOptArraySmoothVarBddArray); 01293 else 01294 info->fwdOptSmoothVarCubeArray = NIL(array_t); 01295 01296 #ifndef NDEBUG 01297 if(info->fwdClusteredRelationArray) 01298 assert(CheckQuantificationSchedule(info->fwdClusteredRelationArray, 01299 info->fwdArraySmoothVarBddArray)); 01300 if(info->fwdOptClusteredRelationArray) 01301 assert(CheckQuantificationSchedule(info->fwdOptClusteredRelationArray, 01302 info->fwdOptArraySmoothVarBddArray)); 01303 #endif 01304 } 01305 01306 if (((directionType == Img_Backward_c) || 01307 (directionType == Img_Both_c)) && 01308 (info->bwdClusteredRelationArray == NIL(array_t))) { 01309 if (info->option->readCluster) { 01310 if (info->option->readReorderCluster) { 01311 fin = fopen(info->option->readCluster, "r"); 01312 ImgMlpReadClusterFile(fin, mddManager, 01313 functionData, bddRelationArray, 01314 domainVarBddArray, rangeVarBddArray, 01315 quantifyVarBddArray, Img_Backward_c, 01316 &clusteredRelationArray, NIL(array_t *), 01317 info->option); 01318 fclose(fin); 01319 if (method == Img_Iwls95_c) { 01320 OrderRelationArray(mddManager, clusteredRelationArray, 01321 rangeVarBddArray, quantifyVarBddArray, 01322 domainVarBddArray, info->option, 01323 &info->bwdClusteredRelationArray, 01324 &info->bwdArraySmoothVarBddArray); 01325 } else if (method == Img_Mlp_c) { 01326 ImgMlpOrderRelationArray(mddManager, clusteredRelationArray, 01327 domainVarBddArray, quantifyVarBddArray, 01328 rangeVarBddArray, Img_Backward_c, 01329 &info->bwdClusteredRelationArray, 01330 &info->bwdArraySmoothVarBddArray, 01331 info->option); 01332 } else 01333 assert(0); 01334 mdd_array_free(clusteredRelationArray); 01335 } else { 01336 fin = fopen(info->option->readCluster, "r"); 01337 ImgMlpReadClusterFile(fin, mddManager, 01338 functionData, bddRelationArray, 01339 domainVarBddArray, rangeVarBddArray, 01340 quantifyVarBddArray, Img_Backward_c, 01341 &info->bwdClusteredRelationArray, 01342 &info->bwdArraySmoothVarBddArray, 01343 info->option); 01344 fclose(fin); 01345 } 01346 } else if (method == Img_Iwls95_c) { 01347 /* 01348 * Since clusters are formed by multiplying the latches starting 01349 * from one end we need to order the latches using some heuristics 01350 * first. Right now, we order the latches using the same heuristic 01351 * as the one used for ordering the clusters for early quantifiction. 01352 * However, since we are not interested in the quantification 01353 * schedule at this stage, we will pass a NIL(array_t*) as the last 01354 * argument. 01355 */ 01356 OrderClusterOrder(mddManager, bddRelationArray, rangeVarBddArray, 01357 domainVarBddArray, quantifyVarBddArray, 01358 &info->bwdClusteredRelationArray, 01359 &info->bwdArraySmoothVarBddArray, 01360 info->option, 0); 01361 } else if (method == Img_Mlp_c) { 01362 if (info->option->mlpPreReorder == 2) { 01363 info->option->mlpPreReorder = 0; 01364 ImgMlpClusterRelationArray(mddManager, functionData, 01365 bddRelationArray, domainVarBddArray, 01366 quantifyVarBddArray, rangeVarBddArray, 01367 Img_Backward_c, &clusteredRelationArray, 01368 NIL(array_t *), info->option); 01369 info->option->mlpPreReorder = 2; 01370 ImgMlpOrderRelationArray(mddManager, clusteredRelationArray, 01371 domainVarBddArray, quantifyVarBddArray, 01372 rangeVarBddArray, Img_Backward_c, 01373 &info->bwdClusteredRelationArray, 01374 &info->bwdArraySmoothVarBddArray, info->option); 01375 mdd_array_free(clusteredRelationArray); 01376 } else if (info->option->mlpPreReorder == 3) { 01377 info->option->mlpPreReorder = 0; 01378 ImgMlpClusterRelationArray(mddManager, functionData, 01379 bddRelationArray, domainVarBddArray, 01380 quantifyVarBddArray, rangeVarBddArray, 01381 Img_Backward_c, &clusteredRelationArray, 01382 NIL(array_t *), info->option); 01383 info->option->mlpPreReorder = 3; 01384 OrderRelationArray(mddManager, clusteredRelationArray, 01385 domainVarBddArray, quantifyVarBddArray, 01386 rangeVarBddArray, info->option, 01387 &info->bwdClusteredRelationArray, 01388 &info->bwdArraySmoothVarBddArray); 01389 mdd_array_free(clusteredRelationArray); 01390 } else { 01391 ImgMlpClusterRelationArray(mddManager, functionData, 01392 bddRelationArray, domainVarBddArray, 01393 quantifyVarBddArray, rangeVarBddArray, 01394 Img_Backward_c, &info->bwdClusteredRelationArray, 01395 &info->bwdArraySmoothVarBddArray, info->option); 01396 } 01397 } else 01398 assert(0); 01399 01400 info->careSetArray = NIL(array_t); 01401 info->bwdClusteredCofactoredRelationArray = NIL(array_t); 01402 01403 if (info->option->verbosity > 2) 01404 PrintPartitionedTransitionRelation(mddManager, info, Img_Backward_c); 01405 01406 if (info->option->printDepMatrix || info->option->writeDepMatrix) { 01407 if (info->option->writeDepMatrix) { 01408 fout = fopen(info->option->writeDepMatrix, "w"); 01409 if (!fout) { 01410 fprintf(vis_stderr, "** img error: can't open file [%s]\n", 01411 info->option->writeDepMatrix); 01412 } 01413 } else 01414 fout = NIL(FILE); 01415 ImgMlpPrintDependenceMatrix(mddManager, 01416 info->bwdClusteredRelationArray, 01417 domainVarBddArray, quantifyVarBddArray, rangeVarBddArray, 01418 Img_Backward_c, info->option->printDepMatrix, fout, 01419 info->option); 01420 01421 if (fout) 01422 fclose(fout); 01423 } 01424 if (info->option->writeCluster) { 01425 fout = fopen(info->option->writeCluster, "w"); 01426 ImgMlpWriteClusterFile(fout, mddManager, 01427 info->bwdClusteredRelationArray, 01428 domainVarBddArray, rangeVarBddArray); 01429 fclose(fout); 01430 } 01431 01432 if (functionData->createVarCubesFlag) 01433 info->bwdSmoothVarCubeArray = MakeSmoothVarCubeArray(mddManager, 01434 info->bwdArraySmoothVarBddArray); 01435 else 01436 info->bwdSmoothVarCubeArray = NIL(array_t); 01437 01438 #ifndef NDEBUG 01439 assert(CheckQuantificationSchedule(info->bwdClusteredRelationArray, 01440 info->bwdArraySmoothVarBddArray)); 01441 #endif 01442 } 01443 01444 01445 info->lazySiftFlag = bdd_is_lazy_sift(mddManager); 01446 if (info->lazySiftFlag) { 01447 SetupLazySifting(mddManager, bddRelationArray, domainVarBddArray, 01448 quantifyVarBddArray, rangeVarBddArray, 01449 info->option->verbosity); 01450 } 01451 01452 /* Free the bddRelationArray */ 01453 mdd_array_free(bddRelationArray); 01454 01455 if ((info->option)->verbosity > 0) { 01456 fwdClusteredRelationArray = info->fwdClusteredRelationArray; 01457 bwdClusteredRelationArray = info->bwdClusteredRelationArray; 01458 if (method == Img_Iwls95_c) 01459 fprintf(vis_stdout,"Computing Image Using IWLS95 technique.\n"); 01460 else if (method == Img_Mlp_c) 01461 fprintf(vis_stdout,"Computing Image Using MLP technique.\n"); 01462 else if (method == Img_Linear_c) { 01463 fprintf(vis_stdout,"Computing Image Using LINEAR technique.\n"); 01464 fwdClusteredRelationArray = info->fwdOptClusteredRelationArray; 01465 /*bwdClusteredRelationArray = info->bwdOptClusteredRelationArray;*/ 01466 } 01467 else 01468 assert(0); 01469 fprintf(vis_stdout,"Total # of domain binary variables = %3d\n", 01470 array_n(domainVarBddArray)); 01471 fprintf(vis_stdout,"Total # of range binary variables = %3d\n", 01472 array_n(rangeVarBddArray)); 01473 fprintf(vis_stdout,"Total # of quantify binary variables = %3d\n", 01474 array_n(quantifyVarBddArray)); 01475 if ((directionType == Img_Forward_c) || (directionType == 01476 Img_Both_c)) { 01477 fprintf(vis_stdout, "Shared size of transition relation for forward image computation is %10ld BDD nodes (%-4d components)\n", 01478 bdd_size_multiple(fwdClusteredRelationArray), 01479 array_n(fwdClusteredRelationArray)); 01480 } 01481 if ((directionType == Img_Backward_c) || (directionType == Img_Both_c)) { 01482 fprintf(vis_stdout, "Shared size of transition relation for backward image computation is %10ld BDD nodes (%-4d components)\n", 01483 bdd_size_multiple(bwdClusteredRelationArray), 01484 array_n(bwdClusteredRelationArray)); 01485 } 01486 } 01487 01488 /* Update nvars field in partial image options structure with 01489 total number of variables. */ 01490 if (info->PIoption != NULL) { 01491 (info->PIoption)->nvars = array_n(domainVarBddArray) + 01492 array_n(quantifyVarBddArray) + 01493 array_n(rangeVarBddArray); 01494 } 01495 /* Free the Bdd arrays */ 01496 mdd_array_free(quantifyVarBddArray); 01497 01498 flagValue = Cmd_FlagReadByName("image_eliminate_depend_vars"); 01499 if (flagValue == NIL(char)) 01500 info->eliminateDepend = 0; /* the default value */ 01501 else 01502 info->eliminateDepend = atoi(flagValue); 01503 if (info->eliminateDepend && bdd_get_package_name() != CUDD) { 01504 fprintf(vis_stderr, 01505 "** trm error : image_eliminate_depend_vars is available for only CUDD.\n"); 01506 info->eliminateDepend = 0; 01507 } 01508 info->nPrevEliminatedFwd = -1; 01509 01510 return (void *)info; 01511 } 01512 } 01513 01514 01532 mdd_t * 01533 ImgImageInfoComputeFwdIwls95(ImgFunctionData_t *functionData, 01534 Img_ImageInfo_t *imageInfo, 01535 mdd_t *fromLowerBound, 01536 mdd_t *fromUpperBound, 01537 array_t *toCareSetArray) 01538 { 01539 mdd_t *image, *domainSubset, *newFrom; 01540 mdd_manager *mddManager; 01541 boolean partial; 01542 Iwls95Info_t *info = (Iwls95Info_t *)imageInfo->methodData; 01543 int eliminateDepend; 01544 Img_OptimizeType optDir; 01545 array_t *fwdOriClusteredRelationArray; 01546 array_t *fwdOriArraySmoothVarBddArray; 01547 array_t *fwdOriSmoothVarCubeArray; 01548 array_t *fwdClusteredRelationArray; 01549 Relation_t *head; 01550 int bOptimize; 01551 boolean farSideImageIsEnabled; 01552 char *userSpecifiedMethod; 01553 01554 mddManager = Part_PartitionReadMddManager(functionData->mddNetwork); 01555 01556 if(imageInfo->methodType == Img_Linear_c) { 01557 if(info->fwdClusteredRelationArray == 0 || 01558 imageInfo->useOptimizedRelationFlag) { 01559 fwdOriClusteredRelationArray = info->fwdOptClusteredRelationArray; 01560 fwdOriArraySmoothVarBddArray = info->fwdOptArraySmoothVarBddArray; 01561 fwdOriSmoothVarCubeArray = info->fwdOptSmoothVarCubeArray; 01562 } 01563 else { 01564 fwdOriClusteredRelationArray = info->fwdClusteredRelationArray; 01565 fwdOriArraySmoothVarBddArray = info->fwdArraySmoothVarBddArray; 01566 fwdOriSmoothVarCubeArray = info->fwdSmoothVarCubeArray; 01567 } 01568 } 01569 else { 01570 fwdOriClusteredRelationArray = info->fwdClusteredRelationArray; 01571 fwdOriArraySmoothVarBddArray = info->fwdArraySmoothVarBddArray; 01572 fwdOriSmoothVarCubeArray = info->fwdSmoothVarCubeArray; 01573 } 01574 01575 if (fwdOriClusteredRelationArray == NIL(array_t)) { 01576 fprintf(vis_stderr, "** img error: The data structure has not been "); 01577 fprintf(vis_stderr, "initialized for forward image computation\n"); 01578 return NIL(mdd_t); 01579 } 01580 01581 if (info->eliminateDepend == 1 || 01582 (info->eliminateDepend == 2 && info->nPrevEliminatedFwd > 0)) { 01583 eliminateDepend = 1; 01584 } else 01585 eliminateDepend = 0; 01586 01587 domainSubset = bdd_between(fromLowerBound, fromUpperBound); 01588 01589 if (eliminateDepend) { 01590 fwdClusteredRelationArray = mdd_array_duplicate(fwdOriClusteredRelationArray); 01591 newFrom = TrmEliminateDependVars(imageInfo, fwdClusteredRelationArray, 01592 domainSubset, NIL(mdd_t *)); 01593 mdd_free(domainSubset); 01594 domainSubset = newFrom; 01595 } else 01596 fwdClusteredRelationArray = fwdOriClusteredRelationArray; 01597 01598 /* Record if partial images are allowed. */ 01599 partial = info->allowPartialImage; 01600 info->wasPartialImage = FALSE; 01601 01602 /* bias field is used to bias the intermediate results towards care states */ 01603 if ((info->PIoption)->partialImageApproxMethod == BDD_APPROX_BIASED_RUA) { 01604 /* assume that this array has only one mdd */ 01605 mdd_t *toCareSet = array_fetch(mdd_t *, toCareSetArray, 0); 01606 (info->PIoption)->bias = mdd_dup(toCareSet); 01607 } 01608 01609 /* when the "compositional far side image approach" is selected, and 01610 * there are more than one transition relation clusters, 01611 * over-approximate images (w.r.t individual TR clusters) will be 01612 * used to minimize the transition relation. 01613 */ 01614 farSideImageIsEnabled = FALSE; 01615 userSpecifiedMethod = Cmd_FlagReadByName("image_farside_method"); 01616 if (userSpecifiedMethod != NIL(char)) { 01617 if (!strcmp(userSpecifiedMethod, "1")) 01618 farSideImageIsEnabled = TRUE; 01619 } 01620 01621 if (!farSideImageIsEnabled || array_n(fwdClusteredRelationArray) < 2) { 01622 01623 image = BddLinearAndSmooth(mddManager, domainSubset, 01624 fwdClusteredRelationArray, 01625 fwdOriArraySmoothVarBddArray, 01626 fwdOriSmoothVarCubeArray, 01627 (info->option)->verbosity, 01628 info->PIoption, &partial, info->lazySiftFlag); 01629 01630 }else { 01631 01632 array_t *fwdFarArraySmoothVarBddArray = fwdOriArraySmoothVarBddArray; 01633 array_t *fwdFarSmoothVarCubeArray = fwdOriSmoothVarCubeArray; 01634 array_t *fwdFarClusteredRelationArray = mdd_array_duplicate(fwdClusteredRelationArray); 01635 array_t *upperBoundImages = array_alloc(mdd_t *, 0); 01636 st_table *domainSupportVarTable, *trClusterSupportVarTable; 01637 mdd_t *trCluster, *newDomainset, *newTRcluster, *upperBoundImage; 01638 mdd_t *holdMdd, *tmpMdd; 01639 array_t *tempArray; 01640 int beforeSize, afterSize, middleSize; 01641 int size1, size2, size3; 01642 boolean flag1, flag2; 01643 int i,j, k; 01644 long bddId; 01645 01646 /* compute a series of over-approximate images based on individual 01647 * TR clusters 01648 */ 01649 domainSupportVarTable = st_init_table(st_ptrcmp, st_ptrhash); 01650 tempArray = mdd_get_bdd_support_ids(mddManager, domainSubset); 01651 arrayForEachItem(int, tempArray, j, bddId) { 01652 st_insert(domainSupportVarTable, (char *)bddId, (char *)0); 01653 } 01654 array_free(tempArray); 01655 01656 beforeSize = afterSize = middleSize =0; 01657 arrayForEachItem(mdd_t *, fwdFarClusteredRelationArray, i, trCluster) { 01658 array_t *preQuantifiedVarsInDomainset = array_alloc(mdd_t *, 0); 01659 array_t *preQuantifiedVarsInTRcluster = array_alloc(mdd_t *, 0); 01660 array_t *quantifiedVarsInProduct = array_alloc(mdd_t *, 0); 01661 01662 /* some variables can be quantified before taking the conjunction */ 01663 trClusterSupportVarTable = st_init_table(st_ptrcmp, st_ptrhash); 01664 tempArray = mdd_get_bdd_support_ids(mddManager, trCluster); 01665 arrayForEachItem(int, tempArray, j, bddId) { 01666 st_insert(trClusterSupportVarTable, (char *)bddId, (char *)0); 01667 } 01668 array_free(tempArray); 01669 arrayForEachItem(array_t *, fwdFarArraySmoothVarBddArray, j, tempArray) { 01670 arrayForEachItem(mdd_t *, tempArray, k, holdMdd) { 01671 bddId = (int)bdd_top_var_id(holdMdd); 01672 flag1 = st_is_member(domainSupportVarTable, (char *)bddId); 01673 flag2 = st_is_member(trClusterSupportVarTable, (char *)bddId); 01674 if (flag1 && flag2) 01675 array_insert_last(mdd_t *, quantifiedVarsInProduct, holdMdd); 01676 else if (flag1) 01677 array_insert_last(mdd_t *, preQuantifiedVarsInDomainset, holdMdd); 01678 else if (flag2) 01679 array_insert_last(mdd_t *, preQuantifiedVarsInTRcluster, holdMdd); 01680 else 01681 ; 01682 } 01683 } 01684 st_free_table(trClusterSupportVarTable); 01685 01686 if (array_n(preQuantifiedVarsInDomainset) == 0) 01687 newDomainset = bdd_dup(domainSubset); 01688 else 01689 newDomainset = bdd_smooth(domainSubset, preQuantifiedVarsInDomainset); 01690 array_free(preQuantifiedVarsInDomainset); 01691 01692 if (array_n(preQuantifiedVarsInTRcluster) == 0) 01693 newTRcluster = bdd_dup(trCluster); 01694 else 01695 newTRcluster = bdd_smooth(trCluster, preQuantifiedVarsInTRcluster); 01696 array_free(preQuantifiedVarsInTRcluster); 01697 01698 /* compute the over-approximated image */ 01699 if (array_n(quantifiedVarsInProduct) == 0) 01700 upperBoundImage = bdd_and(newTRcluster, newDomainset, 1, 1); 01701 else 01702 upperBoundImage = bdd_and_smooth(newTRcluster, newDomainset, quantifiedVarsInProduct); 01703 array_free(quantifiedVarsInProduct); 01704 mdd_free(newTRcluster); 01705 mdd_free(newDomainset); 01706 01707 /* minimize the TR cluster with the new upper bound image */ 01708 newTRcluster = Img_MinimizeImage(trCluster, upperBoundImage, 01709 Img_DefaultMinimizeMethod_c, TRUE); 01710 01711 size1 = mdd_size(trCluster); 01712 beforeSize += size1; 01713 size2 = mdd_size(upperBoundImage); 01714 middleSize += size2; 01715 size3 = mdd_size(newTRcluster); 01716 afterSize += size3; 01717 if (info->option->verbosity >= 3) { 01718 fprintf(vis_stdout, "farSideImg: minimize TR cluster[%d] %d |%d => %d\n", i, 01719 size1, size2, size3); 01720 } 01721 01722 if (mdd_equal(newTRcluster, trCluster)) { 01723 mdd_free(newTRcluster); 01724 mdd_free(upperBoundImage); 01725 }else { 01726 mdd_free(trCluster); 01727 array_insert(mdd_t *, fwdFarClusteredRelationArray, i, newTRcluster); 01728 array_insert_last(mdd_t *, upperBoundImages, upperBoundImage); 01729 } 01730 } 01731 st_free_table(domainSupportVarTable); 01732 01733 if (info->option->verbosity >= 2) { 01734 fprintf(vis_stdout, "farSideImg: minimize TR total %d |%d => %d\n", 01735 beforeSize, middleSize, afterSize); 01736 } 01737 01738 /* compute the image with the simplified transition relation */ 01739 image = BddLinearAndSmooth(mddManager, domainSubset, 01740 fwdFarClusteredRelationArray, 01741 fwdFarArraySmoothVarBddArray, 01742 fwdFarSmoothVarCubeArray, 01743 (info->option)->verbosity, 01744 info->PIoption, &partial, info->lazySiftFlag); 01745 mdd_array_free(fwdFarClusteredRelationArray); 01746 01747 /* for performance concerns, the following operations are carried 01748 * out in the domain space 01749 */ 01750 arrayForEachItem(mdd_t *, upperBoundImages, i, holdMdd) { 01751 tmpMdd = ImgSubstitute(holdMdd, functionData, Img_R2D_c); 01752 mdd_free(holdMdd); 01753 array_insert(mdd_t *, upperBoundImages, i, tmpMdd); 01754 } 01755 holdMdd = image; 01756 image = ImgSubstitute(image, functionData,Img_R2D_c); 01757 mdd_free(holdMdd); 01758 01759 /* remove the "bad states" introduced by the TR cluster minimization */ 01760 beforeSize = mdd_size(image); 01761 array_sort(upperBoundImages, MddSizeCompare); 01762 arrayForEachItem(mdd_t *, upperBoundImages, i, tmpMdd) { 01763 size1 = mdd_size(image); 01764 size2 = mdd_size(tmpMdd); 01765 holdMdd = image; 01766 image = mdd_and(image, tmpMdd, 1, 1); 01767 mdd_free(tmpMdd); 01768 mdd_free(holdMdd); 01769 size3 = mdd_size(image); 01770 01771 if (info->option->verbosity >= 3) { 01772 fprintf(vis_stdout, "farSideImg: clip image %d | %d => %d\n", 01773 size1, size2, size3); 01774 } 01775 } 01776 array_free(upperBoundImages); 01777 01778 if (info->option->verbosity >= 2) { 01779 afterSize = mdd_size(image); 01780 fprintf(vis_stdout, "farSideImg: clip image total %d => %d \n", 01781 beforeSize, afterSize); 01782 } 01783 01784 } 01785 01786 01787 /* check that no partial image was computed if not allowed */ 01788 assert(!((!info->allowPartialImage) && partial)); 01789 01790 /* if partial image computed, and if no new states, recompute 01791 * image with relaxed parameters. 01792 */ 01793 if (partial) { 01794 if (bdd_leq_array(image, toCareSetArray, 1, 0)) { 01795 mdd_free(image); 01796 partial = info->allowPartialImage; 01797 image = RecomputeImageIfNecessary(functionData, 01798 mddManager, 01799 domainSubset, 01800 fwdClusteredRelationArray, 01801 fwdOriArraySmoothVarBddArray, 01802 fwdOriSmoothVarCubeArray, 01803 (info->option)->verbosity, 01804 info->PIoption, 01805 toCareSetArray, 01806 &partial, info->lazySiftFlag); 01807 } 01808 } 01809 01810 if(imageInfo->methodType == Img_Linear_c) { 01811 if(imageInfo->useOptimizedRelationFlag) { 01812 if(info->option->linearOptimize == Opt_NS || 01813 info->option->linearOptimize == Opt_Both) 01814 optDir = Opt_Both; 01815 else 01816 optDir = Opt_CS; 01817 01818 head = ImgLinearRelationInit(mddManager, fwdOriClusteredRelationArray, 01819 functionData->domainBddVars, functionData->rangeBddVars, 01820 functionData->quantifyBddVars, info->option); 01821 bOptimize = ImgLinearOptimizeAll(head, optDir, 0); 01822 if(bOptimize) { 01823 ImgLinearRefineRelation(head); 01824 if(info->fwdClusteredRelationArray == 0 && optDir == Opt_Both) { 01825 info->fwdClusteredRelationArray = fwdOriClusteredRelationArray; 01826 info->fwdArraySmoothVarBddArray = 01827 BddArrayArrayDup(fwdOriArraySmoothVarBddArray); 01828 info->fwdSmoothVarCubeArray = MakeSmoothVarCubeArray(mddManager, 01829 info->fwdArraySmoothVarBddArray); 01830 } 01831 else { 01832 mdd_array_free(fwdOriClusteredRelationArray); 01833 } 01834 fwdOriClusteredRelationArray = ImgLinearExtractRelationArrayT(head); 01835 info->fwdOptClusteredRelationArray = fwdOriClusteredRelationArray; 01836 } 01837 ImgLinearRelationQuit(head); 01838 } 01839 } 01840 01841 /* free the bias function created. */ 01842 if ((info->PIoption)->partialImageApproxMethod == BDD_APPROX_BIASED_RUA) { 01843 mdd_free((info->PIoption)->bias); 01844 (info->PIoption)->bias = NIL(mdd_t); 01845 } 01846 /* indicate whether this image computation was partial or exact. */ 01847 info->wasPartialImage = partial; 01848 info->allowPartialImage = FALSE; 01849 01850 if (eliminateDepend) 01851 mdd_array_free(fwdClusteredRelationArray); 01852 mdd_free(domainSubset); 01853 01854 return image; 01855 } 01856 01871 mdd_t * 01872 ImgImageInfoComputeFwdWithDomainVarsIwls95(ImgFunctionData_t *functionData, 01873 Img_ImageInfo_t *imageInfo, 01874 mdd_t *fromLowerBound, 01875 mdd_t *fromUpperBound, 01876 array_t *toCareSetArray) 01877 { 01878 int i; 01879 array_t *toCareSetArrayRV = NIL(array_t); 01880 mdd_t *toCareSet, *toCareSetRV; 01881 mdd_t *imageRV, *imageDV; 01882 int useToCareSetFlag; 01883 Iwls95Info_t *info = (Iwls95Info_t *)imageInfo->methodData; 01884 01885 if (toCareSetArray && info->allowPartialImage) 01886 useToCareSetFlag = 1; 01887 else 01888 useToCareSetFlag = 0; 01889 01890 if (useToCareSetFlag) { 01891 toCareSetArrayRV = array_alloc(mdd_t *, 0); 01892 arrayForEachItem(bdd_t *, toCareSetArray, i, toCareSet) { 01893 toCareSetRV = ImgSubstitute(toCareSet, functionData, Img_D2R_c); 01894 array_insert(bdd_t *, toCareSetArrayRV, i, toCareSetRV); 01895 } 01896 } 01897 01898 imageRV = ImgImageInfoComputeFwdIwls95(functionData, 01899 imageInfo, 01900 fromLowerBound, 01901 fromUpperBound, 01902 toCareSetArrayRV); 01903 01904 imageDV = ImgSubstitute(imageRV, functionData, Img_R2D_c); 01905 mdd_free(imageRV); 01906 if (useToCareSetFlag) 01907 mdd_array_free(toCareSetArrayRV); 01908 return imageDV; 01909 } 01910 01911 01927 mdd_t * 01928 ImgImageInfoComputeBwdIwls95(ImgFunctionData_t *functionData, 01929 Img_ImageInfo_t *imageInfo, 01930 mdd_t *fromLowerBound, 01931 mdd_t *fromUpperBound, 01932 array_t *toCareSetArray) 01933 { 01934 mdd_t *image, *domainSubset, *simplifiedImage; 01935 mdd_manager *mddManager; 01936 Iwls95Info_t *info = (Iwls95Info_t *)imageInfo->methodData; 01937 boolean partial; 01938 01939 if (info->bwdClusteredRelationArray == NIL(array_t)) { 01940 fprintf(vis_stderr, "** img error: The data structure has not been "); 01941 fprintf(vis_stderr, "initialized for backward image computation\n"); 01942 return NIL(mdd_t); 01943 } 01944 mddManager = Part_PartitionReadMddManager(functionData->mddNetwork); 01945 domainSubset = bdd_between(fromLowerBound, fromUpperBound); 01946 01947 assert(mddManager != NIL(mdd_manager)); 01948 01949 /* Check if we can use the stored simplified relations */ 01950 if (info->careSetArray == NIL(array_t) || 01951 !mdd_array_equal(info->careSetArray, toCareSetArray)){ 01952 FreeClusteredCofactoredRelationArray(info); 01953 info->careSetArray = mdd_array_duplicate(toCareSetArray); 01954 info->bwdClusteredCofactoredRelationArray = 01955 ImgMinimizeImageArrayWithCareSetArray(info->bwdClusteredRelationArray, 01956 toCareSetArray, 01957 Img_DefaultMinimizeMethod_c, TRUE, 01958 (info->option->verbosity > 0), 01959 Img_Backward_c); 01960 } 01961 01962 /* if the partial images are allowed, compute the care set (or its superset) 01963 * so that partial products can be minimized with respect to it. 01964 */ 01965 partial = info->allowPartialImage; 01966 info->wasPartialImage = FALSE; 01967 01968 /* bias is used to bias the intermediate results towards care states */ 01969 if ((info->PIoption)->partialImageApproxMethod == BDD_APPROX_BIASED_RUA) { 01970 /* assume that this array has only one mdd */ 01971 mdd_t *toCareSet = array_fetch(mdd_t *, toCareSetArray, 0); 01972 (info->PIoption)->bias = mdd_dup(toCareSet); 01973 } 01974 01975 01976 image = BddLinearAndSmooth(mddManager, domainSubset, 01977 info->bwdClusteredCofactoredRelationArray, 01978 info->bwdArraySmoothVarBddArray, 01979 info->bwdSmoothVarCubeArray, 01980 (info->option)->verbosity, 01981 info->PIoption, &partial, info->lazySiftFlag); 01982 01983 01984 /* check that no partial image was computed if not allowed */ 01985 assert(!((!info->allowPartialImage) && partial)); 01986 01987 /* if partial image computed, and if no new states, recompute 01988 * image with relaxed parameters. 01989 */ 01990 if (partial && bdd_leq_array(image, toCareSetArray, 1, 0)) { 01991 bdd_free(image); 01992 partial = info->allowPartialImage; 01993 image = RecomputeImageIfNecessary(functionData, 01994 mddManager, 01995 domainSubset, 01996 info->bwdClusteredRelationArray, 01997 info->bwdArraySmoothVarBddArray, 01998 info->bwdSmoothVarCubeArray, 01999 (info->option)->verbosity, 02000 info->PIoption, 02001 toCareSetArray, 02002 &partial, info->lazySiftFlag); 02003 } 02004 02005 /* free the bias function created. */ 02006 if ((info->PIoption)->partialImageApproxMethod == BDD_APPROX_BIASED_RUA) { 02007 mdd_free((info->PIoption)->bias); 02008 (info->PIoption)->bias = NIL(mdd_t); 02009 } 02010 /* indicate whether this image computation was partial or exact. */ 02011 info->wasPartialImage = partial; 02012 info->allowPartialImage = FALSE; 02013 02014 mdd_free(domainSubset); 02015 simplifiedImage = bdd_minimize_array(image, toCareSetArray); 02016 bdd_free(image); 02017 return simplifiedImage; 02018 } 02019 02033 mdd_t * 02034 ImgImageInfoComputeBwdWithDomainVarsIwls95(ImgFunctionData_t *functionData, 02035 Img_ImageInfo_t *imageInfo, 02036 mdd_t *fromLowerBound, 02037 mdd_t *fromUpperBound, 02038 array_t *toCareSetArray) 02039 { 02040 mdd_t *fromLowerBoundRV; 02041 mdd_t *fromUpperBoundRV; 02042 mdd_t *image; 02043 02044 fromLowerBoundRV = ImgSubstitute(fromLowerBound, functionData, Img_D2R_c); 02045 if (mdd_equal(fromLowerBound, fromUpperBound)) 02046 fromUpperBoundRV = fromLowerBoundRV; 02047 else 02048 fromUpperBoundRV = ImgSubstitute(fromUpperBound, functionData, Img_D2R_c); 02049 02050 image = ImgImageInfoComputeBwdIwls95(functionData, 02051 imageInfo, 02052 fromLowerBoundRV, 02053 fromUpperBoundRV, 02054 toCareSetArray); 02055 02056 mdd_free(fromLowerBoundRV); 02057 if (!mdd_equal(fromLowerBound, fromUpperBound)) 02058 mdd_free(fromUpperBoundRV); 02059 return image; 02060 } 02061 02073 void 02074 ImgImageInfoFreeIwls95(void *methodData) 02075 { 02076 Iwls95Info_t *info = (Iwls95Info_t *)methodData; 02077 02078 if (info == NIL(Iwls95Info_t)) { 02079 fprintf(vis_stderr, "** img error: Trying to free the NULL image info\n"); 02080 return; 02081 } 02082 if (info->bitRelationArray != NIL(array_t)) { 02083 mdd_array_free(info->bitRelationArray); 02084 } 02085 if (info->quantifyVarMddIdArray != NIL(array_t)) { 02086 array_free(info->quantifyVarMddIdArray); 02087 } 02088 if (info->fwdOptClusteredRelationArray != NIL(array_t)) { 02089 mdd_array_free(info->fwdOptClusteredRelationArray); 02090 mdd_array_array_free(info->fwdOptArraySmoothVarBddArray); 02091 } 02092 if (info->fwdOptSmoothVarCubeArray) 02093 mdd_array_free(info->fwdOptSmoothVarCubeArray); 02094 if (info->fwdClusteredRelationArray != NIL(array_t)) { 02095 mdd_array_free(info->fwdClusteredRelationArray); 02096 mdd_array_array_free(info->fwdArraySmoothVarBddArray); 02097 } 02098 if (info->fwdSmoothVarCubeArray) 02099 mdd_array_free(info->fwdSmoothVarCubeArray); 02100 if (info->bwdClusteredRelationArray != NIL(array_t)) { 02101 mdd_array_free(info->bwdClusteredRelationArray); 02102 mdd_array_array_free(info->bwdArraySmoothVarBddArray); 02103 } 02104 if (info->bwdSmoothVarCubeArray) 02105 mdd_array_free(info->bwdSmoothVarCubeArray); 02106 FreeClusteredCofactoredRelationArray(info); 02107 02108 if (info->option != NULL) ImgFreeTrmOptions(info->option); 02109 if (info->PIoption != NULL) FREE(info->PIoption); 02110 02111 if (info->savedArraySmoothVarBddArray != NIL(array_t)) 02112 mdd_array_array_free(info->savedArraySmoothVarBddArray); 02113 if (info->savedSmoothVarCubeArray != NIL(array_t)) 02114 mdd_array_free(info->savedSmoothVarCubeArray); 02115 02116 FREE(info); 02117 } 02118 02131 void 02132 ImgImageInfoPrintMethodParamsIwls95(void *methodData, FILE *fp) 02133 { 02134 Iwls95Info_t *info = (Iwls95Info_t *)methodData; 02135 if (fp == NULL) return; 02136 PrintOption(info->method, info->option, fp); 02137 if (info->fwdClusteredRelationArray != NIL(array_t)) { 02138 (void) fprintf(fp, "Shared size of transition relation for forward image computation is %10ld BDD nodes (%-4d components)\n", 02139 bdd_size_multiple(info->fwdClusteredRelationArray), 02140 array_n(info->fwdClusteredRelationArray)); 02141 } 02142 if (info->bwdClusteredRelationArray != NIL(array_t)) { 02143 (void) fprintf(fp, "Shared size of transition relation for backward image computation is %10ld BDD nodes (%-4d components)\n", 02144 bdd_size_multiple(info->bwdClusteredRelationArray), 02145 array_n(info->bwdClusteredRelationArray)); 02146 } 02147 } 02148 02160 st_table * 02161 ImgBddGetSupportIdTable(bdd_t *function) 02162 { 02163 st_table *supportTable; 02164 var_set_t *supportVarSet; 02165 int i; 02166 02167 supportTable = st_init_table(st_numcmp, st_numhash); 02168 supportVarSet = bdd_get_support(function); 02169 for(i=0; i<supportVarSet->n_elts; i++) { 02170 if (var_set_get_elt(supportVarSet, i) == 1) { 02171 st_insert(supportTable, (char *)(long) i, NIL(char)); 02172 } 02173 } 02174 var_set_free(supportVarSet); 02175 return supportTable; 02176 } 02177 02191 boolean 02192 ImgImageWasPartialIwls95(void *methodData) 02193 { 02194 Iwls95Info_t *info = (Iwls95Info_t *) methodData; 02195 return (info->wasPartialImage); 02196 } 02197 02213 void 02214 ImgImageAllowPartialImageIwls95(void *methodData, boolean value) 02215 { 02216 Iwls95Info_t *info = (Iwls95Info_t *) methodData; 02217 info->allowPartialImage = value; 02218 } 02219 02230 void 02231 ImgRestoreTransitionRelationIwls95(Img_ImageInfo_t *imageInfo, 02232 Img_DirectionType directionType) 02233 { 02234 array_t *relationArray; 02235 Iwls95Info_t *iwlsInfo = (Iwls95Info_t *) imageInfo->methodData; 02236 ImgFunctionData_t *functionData = &(imageInfo->functionData); 02237 mdd_manager *mgr = NIL(mdd_manager); 02238 02239 mgr = Part_PartitionReadMddManager(imageInfo->functionData.mddNetwork); 02240 02241 if (directionType == Img_Both_c) { 02242 fprintf(vis_stderr, 02243 "** img error : can't restore fwd and bwd at the same time.\n"); 02244 return; 02245 } 02246 02247 relationArray = ImgGetTransitionRelationIwls95(iwlsInfo, directionType); 02248 mdd_array_free(relationArray); 02249 ImgUpdateTransitionRelationIwls95(iwlsInfo, 02250 (array_t *)imageInfo->savedRelation, 02251 directionType); 02252 imageInfo->savedRelation = NIL(void); 02253 02254 assert(iwlsInfo->savedArraySmoothVarBddArray); 02255 if (directionType == Img_Forward_c) { 02256 mdd_array_array_free(iwlsInfo->fwdArraySmoothVarBddArray); 02257 iwlsInfo->fwdArraySmoothVarBddArray = iwlsInfo->savedArraySmoothVarBddArray; 02258 if (functionData->createVarCubesFlag) { 02259 mdd_array_free(iwlsInfo->fwdSmoothVarCubeArray); 02260 iwlsInfo->fwdSmoothVarCubeArray = iwlsInfo->savedSmoothVarCubeArray; 02261 } 02262 } else { 02263 mdd_array_array_free(iwlsInfo->bwdArraySmoothVarBddArray); 02264 iwlsInfo->bwdArraySmoothVarBddArray = iwlsInfo->savedArraySmoothVarBddArray; 02265 if (functionData->createVarCubesFlag) { 02266 mdd_array_free(iwlsInfo->bwdSmoothVarCubeArray); 02267 iwlsInfo->bwdSmoothVarCubeArray = iwlsInfo->savedSmoothVarCubeArray; 02268 } 02269 } 02270 iwlsInfo->savedArraySmoothVarBddArray = NIL(array_t); 02271 iwlsInfo->savedSmoothVarCubeArray = NIL(array_t); 02272 02273 if(directionType == Img_Backward_c || directionType == Img_Both_c) 02274 ResetClusteredCofactoredRelationArray(mgr, iwlsInfo); 02275 } 02276 02288 void 02289 ImgDuplicateTransitionRelationIwls95(Img_ImageInfo_t *imageInfo, 02290 Img_DirectionType directionType) 02291 { 02292 array_t *relationArray, *copiedRelationArray; 02293 Iwls95Info_t *iwlsInfo = (Iwls95Info_t *) imageInfo->methodData; 02294 ImgFunctionData_t *functionData = &(imageInfo->functionData); 02295 02296 if (directionType == Img_Both_c) { 02297 fprintf(vis_stderr, 02298 "** img error : can't duplicate fwd and bwd at the same time.\n"); 02299 return; 02300 } 02301 02302 relationArray = ImgGetTransitionRelationIwls95(iwlsInfo, directionType); 02303 copiedRelationArray = BddArrayDup(relationArray); 02304 assert(!imageInfo->savedRelation); 02305 imageInfo->savedRelation = (void *)relationArray; 02306 ImgUpdateTransitionRelationIwls95(iwlsInfo, 02307 copiedRelationArray, directionType); 02308 02309 assert(!iwlsInfo->savedArraySmoothVarBddArray); 02310 if (directionType == Img_Forward_c) { 02311 iwlsInfo->savedArraySmoothVarBddArray = iwlsInfo->fwdArraySmoothVarBddArray; 02312 iwlsInfo->fwdArraySmoothVarBddArray = 02313 CopyArrayBddArray(iwlsInfo->savedArraySmoothVarBddArray); 02314 if (functionData->createVarCubesFlag) { 02315 iwlsInfo->savedSmoothVarCubeArray = iwlsInfo->fwdSmoothVarCubeArray; 02316 iwlsInfo->fwdSmoothVarCubeArray = 02317 BddArrayDup(iwlsInfo->savedSmoothVarCubeArray); 02318 } 02319 } else { 02320 iwlsInfo->savedArraySmoothVarBddArray = iwlsInfo->bwdArraySmoothVarBddArray; 02321 iwlsInfo->bwdArraySmoothVarBddArray = 02322 CopyArrayBddArray(iwlsInfo->savedArraySmoothVarBddArray); 02323 if (functionData->createVarCubesFlag) { 02324 iwlsInfo->savedSmoothVarCubeArray = iwlsInfo->bwdSmoothVarCubeArray; 02325 iwlsInfo->bwdSmoothVarCubeArray = 02326 BddArrayDup(iwlsInfo->savedSmoothVarCubeArray); 02327 } 02328 } 02329 } 02330 02331 02355 void 02356 ImgMinimizeTransitionRelationIwls95( 02357 void *methodData, 02358 ImgFunctionData_t *functionData, 02359 array_t *constrainArray, 02360 Img_MinimizeType minimizeMethod, 02361 Img_DirectionType directionType, 02362 boolean reorderClusters, 02363 int printStatus) 02364 { 02365 Iwls95Info_t *info = (Iwls95Info_t *)methodData; 02366 02367 if (minimizeMethod == Img_DefaultMinimizeMethod_c) 02368 minimizeMethod = Img_ReadMinimizeMethod(); 02369 02370 if (directionType == Img_Forward_c || directionType == Img_Both_c) { 02371 ImgMinimizeImageArrayWithCareSetArrayInSitu( 02372 info->fwdClusteredRelationArray, constrainArray, minimizeMethod, TRUE, 02373 (printStatus == 2), Img_Forward_c); 02374 02375 if(reorderClusters) 02376 ReorderPartitionedTransitionRelation(info, functionData, 02377 Img_Forward_c); 02378 else{ 02379 /* any minimization method other than restrict may introduce new 02380 variables, which invalidates the quantification schedule */ 02381 assert(minimizeMethod != Img_DefaultMinimizeMethod_c); 02382 if(minimizeMethod != Img_Restrict_c) 02383 UpdateQuantificationSchedule(info, functionData, Img_Forward_c); 02384 } 02385 assert(CheckQuantificationSchedule(info->fwdClusteredRelationArray, 02386 info->fwdArraySmoothVarBddArray)); 02387 } 02388 02389 if (directionType == Img_Backward_c || directionType == Img_Both_c) { 02390 ImgMinimizeImageArrayWithCareSetArrayInSitu( 02391 info->bwdClusteredRelationArray, constrainArray, minimizeMethod, TRUE, 02392 (printStatus == 2), Img_Backward_c); 02393 02394 if(reorderClusters) 02395 ReorderPartitionedTransitionRelation(info, functionData, 02396 Img_Backward_c); 02397 /* Minimization can only introduce PS variables, which need not be 02398 quantified out, hence no need to recompute quantification schedule 02399 in backward case. */ 02400 assert(CheckQuantificationSchedule(info->bwdClusteredRelationArray, 02401 info->bwdArraySmoothVarBddArray)) 02402 } 02403 02404 if(directionType == Img_Backward_c || directionType == Img_Both_c) 02405 FreeClusteredCofactoredRelationArray(info); 02406 02407 return; 02408 } 02409 02410 02425 void 02426 ImgAbstractTransitionRelationIwls95(Img_ImageInfo_t *imageInfo, 02427 array_t *abstractVars, mdd_t *abstractCube, 02428 Img_DirectionType directionType, int printStatus) 02429 { 02430 Iwls95Info_t *info = (Iwls95Info_t *)imageInfo->methodData; 02431 int i, fwd_size, bwd_size; 02432 bdd_t *relation, *abstractedRelation; 02433 02434 if (!abstractVars || array_n(abstractVars) == 0) 02435 return; 02436 02437 fwd_size = bwd_size = 0; 02438 if (printStatus) { 02439 if (directionType == Img_Forward_c || directionType == Img_Both_c) 02440 fwd_size = bdd_size_multiple(info->fwdClusteredRelationArray); 02441 if (directionType == Img_Backward_c || directionType == Img_Both_c) 02442 bwd_size = bdd_size_multiple(info->bwdClusteredRelationArray); 02443 } 02444 if (directionType == Img_Forward_c || directionType == Img_Both_c) { 02445 arrayForEachItem(bdd_t*, info->fwdClusteredRelationArray, i, relation) { 02446 if (abstractCube) 02447 abstractedRelation = bdd_smooth_with_cube(relation, abstractCube); 02448 else 02449 abstractedRelation = bdd_smooth(relation, abstractVars); 02450 if (printStatus == 2) { 02451 (void) fprintf(vis_stdout, 02452 "IMG Info: abstracted fwd relation %d => %d in component %d\n", 02453 bdd_size(relation), bdd_size(abstractedRelation), i); 02454 } 02455 mdd_free(relation); 02456 array_insert(bdd_t*, info->fwdClusteredRelationArray, i, 02457 abstractedRelation); 02458 } 02459 } 02460 if (directionType == Img_Backward_c || directionType == Img_Both_c) { 02461 arrayForEachItem(bdd_t*, info->bwdClusteredRelationArray, i, relation) { 02462 if (abstractCube) 02463 abstractedRelation = bdd_smooth_with_cube(relation, abstractCube); 02464 else 02465 abstractedRelation = bdd_smooth(relation, abstractVars); 02466 if (printStatus == 2) { 02467 (void) fprintf(vis_stdout, 02468 "IMG Info: abstracted bwd relation %d => %d in component %d\n", 02469 bdd_size(relation), bdd_size(abstractedRelation), i); 02470 } 02471 mdd_free(relation); 02472 array_insert(bdd_t*, info->bwdClusteredRelationArray, i, 02473 abstractedRelation); 02474 } 02475 } 02476 if (printStatus) { 02477 if (directionType == Img_Forward_c || directionType == Img_Both_c) { 02478 (void) fprintf(vis_stdout, 02479 "IMG Info: abstracted fwd relation [%d => %ld] with %d components\n", 02480 fwd_size, 02481 bdd_size_multiple(info->fwdClusteredRelationArray), 02482 array_n(info->fwdClusteredRelationArray)); 02483 } 02484 if (directionType == Img_Backward_c || directionType == Img_Both_c) { 02485 (void) fprintf(vis_stdout, 02486 "IMG Info: abstracted bwd relation [%d => %ld] with %d components\n", 02487 bwd_size, 02488 bdd_size_multiple(info->bwdClusteredRelationArray), 02489 array_n(info->bwdClusteredRelationArray)); 02490 } 02491 } 02492 02493 if(directionType == Img_Backward_c || directionType == Img_Both_c) 02494 FreeClusteredCofactoredRelationArray(info); 02495 } 02496 02497 02510 int 02511 ImgApproximateTransitionRelationIwls95(mdd_manager *mgr, void *methodData, 02512 bdd_approx_dir_t approxDir, bdd_approx_type_t approxMethod, 02513 int approxThreshold, double approxQuality, 02514 double approxQualityBias, 02515 Img_DirectionType directionType, mdd_t *bias) 02516 { 02517 Iwls95Info_t *info = (Iwls95Info_t *)methodData; 02518 int i; 02519 bdd_t *relation, *approxRelation; 02520 int unchanged = 0; 02521 02522 if (directionType == Img_Forward_c || directionType == Img_Both_c) { 02523 arrayForEachItem(bdd_t*, info->fwdClusteredRelationArray, i, relation) { 02524 approxRelation = Img_ApproximateImage(mgr, relation, 02525 approxDir, approxMethod, 02526 approxThreshold, approxQuality, 02527 approxQualityBias, bias); 02528 if (bdd_is_tautology(approxRelation, 1)) { 02529 fprintf(vis_stdout, 02530 "** img warning : bdd_one from subsetting in fwd[%d].\n", i); 02531 mdd_free(approxRelation); 02532 unchanged++; 02533 } else if (bdd_is_tautology(approxRelation, 0)) { 02534 fprintf(vis_stdout, 02535 "** img warning : bdd_zero from subsetting in fwd[%d].\n", i); 02536 mdd_free(approxRelation); 02537 unchanged++; 02538 } else if (mdd_equal(approxRelation, relation)) { 02539 mdd_free(approxRelation); 02540 unchanged++; 02541 } else { 02542 mdd_free(relation); 02543 array_insert(bdd_t*, info->fwdClusteredRelationArray, i, 02544 approxRelation); 02545 } 02546 } 02547 } 02548 if (directionType == Img_Backward_c || directionType == Img_Both_c) { 02549 arrayForEachItem(bdd_t*, info->bwdClusteredRelationArray, i, relation) { 02550 approxRelation = Img_ApproximateImage(mgr, relation, 02551 approxDir, approxMethod, 02552 approxThreshold, approxQuality, 02553 approxQualityBias, bias); 02554 if (bdd_is_tautology(approxRelation, 1)) { 02555 fprintf(vis_stdout, 02556 "** img warning : bdd_one from subsetting in bwd[%d].\n", i); 02557 mdd_free(approxRelation); 02558 unchanged++; 02559 } else if (bdd_is_tautology(approxRelation, 0)) { 02560 fprintf(vis_stdout, 02561 "** img warning : bdd_zero from subsetting in bwd[%d].\n", i); 02562 mdd_free(approxRelation); 02563 unchanged++; 02564 } else if (mdd_equal(approxRelation, relation)) { 02565 mdd_free(approxRelation); 02566 unchanged++; 02567 } else { 02568 mdd_free(relation); 02569 array_insert(bdd_t*, info->bwdClusteredRelationArray, i, 02570 approxRelation); 02571 } 02572 } 02573 } 02574 02575 if(directionType == Img_Backward_c || directionType == Img_Both_c) 02576 FreeClusteredCofactoredRelationArray(info); 02577 02578 return(unchanged); 02579 } 02580 02581 02591 array_t * 02592 ImgGetTransitionRelationIwls95(void *methodData, 02593 Img_DirectionType directionType) 02594 { 02595 Iwls95Info_t *info = (Iwls95Info_t *)methodData; 02596 02597 if (directionType == Img_Forward_c) 02598 return(info->fwdClusteredRelationArray); 02599 else if (directionType == Img_Backward_c) 02600 return(info->bwdClusteredRelationArray); 02601 return(NIL(array_t)); 02602 } 02603 02604 02614 void 02615 ImgUpdateTransitionRelationIwls95(void *methodData, array_t *relationArray, 02616 Img_DirectionType directionType) 02617 { 02618 Iwls95Info_t *info = (Iwls95Info_t *)methodData; 02619 02620 if (directionType == Img_Forward_c) 02621 info->fwdClusteredRelationArray = relationArray; 02622 else if (directionType == Img_Backward_c) 02623 info->bwdClusteredRelationArray = relationArray; 02624 } 02625 02626 02636 void 02637 ImgReplaceIthPartitionedTransitionRelationIwls95(void *methodData, 02638 int i, mdd_t *relation, Img_DirectionType directionType) 02639 { 02640 array_t *relationArray; 02641 mdd_t *old; 02642 02643 relationArray = ImgGetTransitionRelationIwls95(methodData, directionType); 02644 if (!relationArray) 02645 return; 02646 old = array_fetch(mdd_t *, relationArray, i); 02647 mdd_free(old); 02648 array_insert(mdd_t *, relationArray, i, relation); 02649 } 02650 02651 02663 void 02664 ImgImageFreeClusteredTransitionRelationIwls95(void *methodData, 02665 Img_DirectionType directionType) 02666 { 02667 Iwls95Info_t *info = (Iwls95Info_t *)methodData; 02668 02669 if (directionType == Img_Forward_c || directionType == Img_Both_c) { 02670 if (info->fwdClusteredRelationArray != NIL(array_t)) { 02671 mdd_array_free(info->fwdClusteredRelationArray); 02672 info->fwdClusteredRelationArray = NIL(array_t); 02673 } 02674 if (info->fwdArraySmoothVarBddArray != NIL(array_t)) { 02675 mdd_array_array_free(info->fwdArraySmoothVarBddArray); 02676 info->fwdArraySmoothVarBddArray = NIL(array_t); 02677 } 02678 if (info->fwdSmoothVarCubeArray != NIL(array_t)) { 02679 mdd_array_free(info->fwdSmoothVarCubeArray); 02680 info->fwdSmoothVarCubeArray = NIL(array_t); 02681 } 02682 } 02683 if (directionType == Img_Backward_c || directionType == Img_Both_c) { 02684 if (info->bwdClusteredRelationArray != NIL(array_t)) { 02685 mdd_array_free(info->bwdClusteredRelationArray); 02686 info->bwdClusteredRelationArray = NIL(array_t); 02687 } 02688 if (info->bwdArraySmoothVarBddArray != NIL(array_t)) { 02689 mdd_array_array_free(info->bwdArraySmoothVarBddArray); 02690 info->bwdArraySmoothVarBddArray = NIL(array_t); 02691 } 02692 if (info->bwdSmoothVarCubeArray != NIL(array_t)) { 02693 mdd_array_free(info->bwdSmoothVarCubeArray); 02694 info->bwdSmoothVarCubeArray = NIL(array_t); 02695 } 02696 } 02697 } 02698 02699 02700 02728 void 02729 ImgImageConstrainAndClusterTransitionRelationIwls95OrMlp( 02730 Img_ImageInfo_t *imageInfo, 02731 Img_DirectionType direction, 02732 mdd_t *constrain, 02733 Img_MinimizeType minimizeMethod, 02734 boolean underApprox, 02735 boolean cleanUp, 02736 boolean forceReorder, 02737 int printStatus) 02738 { 02739 ImgFunctionData_t *functionData = &(imageInfo->functionData); 02740 Iwls95Info_t *info = (Iwls95Info_t *)imageInfo->methodData; 02741 array_t *constrainArray; 02742 mdd_manager *mddManager = Part_PartitionReadMddManager(functionData->mddNetwork); 02743 array_t *relationArray = NIL(array_t); 02744 array_t *relationArrayFwd = NIL(array_t); 02745 array_t *relationArrayBwd = NIL(array_t); 02746 02747 assert(imageInfo->methodType == Img_Iwls95_c || 02748 imageInfo->methodType == Img_Mlp_c); 02749 02750 /* free existing relation */ 02751 ImgImageFreeClusteredTransitionRelationIwls95(imageInfo->methodData, 02752 direction); 02753 if (forceReorder) bdd_reorder(mddManager); 02754 /* create a bit relation and quantifiable variables (PIs and 02755 intermediate variables) if necessary */ 02756 CreateBitRelationArray(info, functionData); 02757 02758 /* make a work copy of the bit array */ 02759 relationArray = BddArrayDup(info->bitRelationArray); 02760 02761 if (cleanUp) FreeBitRelationArray(info); 02762 02763 /* apply the constraint to the bit relation */ 02764 if (constrain) { 02765 constrainArray = array_alloc(mdd_t *, 1); 02766 array_insert(mdd_t *, constrainArray, 0, constrain); 02767 ImgMinimizeImageArrayWithCareSetArrayInSitu(relationArray, 02768 constrainArray, 02769 minimizeMethod, underApprox, 02770 printStatus, direction); 02771 array_free(constrainArray); 02772 } 02773 02774 if (direction == Img_Forward_c) { 02775 relationArrayFwd = relationArray; 02776 } else if (direction == Img_Backward_c) { 02777 relationArrayBwd = relationArray; 02778 } else if (direction == Img_Both_c) { 02779 relationArrayFwd = relationArray; 02780 relationArrayBwd = BddArrayDup(relationArray); 02781 } else { 02782 assert(0); 02783 } 02784 relationArray = NIL(array_t); 02785 02786 /* return order and recluster the relation */ 02787 if (direction == Img_Forward_c || direction == Img_Both_c) { 02788 Img_ClusterRelationArray(mddManager, 02789 imageInfo->methodType, 02790 direction, 02791 relationArrayFwd, 02792 functionData->domainVars, 02793 functionData->rangeVars, 02794 info->quantifyVarMddIdArray, 02795 &info->fwdClusteredRelationArray, 02796 &info->fwdArraySmoothVarBddArray, 02797 NULL, 02798 1); 02799 if (functionData->createVarCubesFlag) { 02800 info->fwdSmoothVarCubeArray = MakeSmoothVarCubeArray(mddManager, 02801 info->fwdArraySmoothVarBddArray); 02802 } 02803 } 02804 02805 if (direction == Img_Backward_c || direction == Img_Both_c) { 02806 Img_ClusterRelationArray(mddManager, 02807 imageInfo->methodType, 02808 direction, 02809 relationArrayBwd, 02810 functionData->domainVars, 02811 functionData->rangeVars, 02812 info->quantifyVarMddIdArray, 02813 &info->bwdClusteredRelationArray, 02814 &info->bwdArraySmoothVarBddArray, 02815 NULL, 02816 1); 02817 if (functionData->createVarCubesFlag) { 02818 info->bwdSmoothVarCubeArray = MakeSmoothVarCubeArray(mddManager, 02819 info->bwdArraySmoothVarBddArray); 02820 } 02821 } 02822 02823 if (cleanUp) { 02824 array_free(info->quantifyVarMddIdArray); 02825 info->quantifyVarMddIdArray = NIL(array_t); 02826 } 02827 02828 /* Print information */ 02829 if (info->option->verbosity > 0){ 02830 fprintf(vis_stdout,"Computing Image Using %s technique.\n", 02831 imageInfo->methodType == Img_Mlp_c ? "MLP" : "IWLS95"); 02832 fprintf(vis_stdout,"Total # of domain binary variables = %3d\n", 02833 array_n(functionData->domainBddVars)); 02834 fprintf(vis_stdout,"Total # of range binary variables = %3d\n", 02835 array_n(functionData->rangeBddVars)); 02836 if (info->quantifyVarMddIdArray) { 02837 array_t *bddArray; 02838 02839 bddArray = mdd_id_array_to_bdd_array(mddManager, 02840 info->quantifyVarMddIdArray); 02841 fprintf(vis_stdout,"Total # of quantify binary variables = %3d\n", 02842 array_n(bddArray)); 02843 mdd_array_free(bddArray); 02844 } else { 02845 fprintf(vis_stdout,"Total # of quantify binary variables = %3d\n", 02846 array_n(functionData->quantifyBddVars)); 02847 } 02848 if (((direction == Img_Forward_c) || (direction == Img_Both_c)) && 02849 (info->fwdClusteredRelationArray != NIL(array_t))) { 02850 (void) fprintf(vis_stdout, 02851 "Shared size of transition relation for forward image "); 02852 (void) fprintf(vis_stdout, 02853 "computation is %10ld BDD nodes (%-4d components)\n", 02854 bdd_size_multiple(info->fwdClusteredRelationArray), 02855 array_n(info->fwdClusteredRelationArray)); 02856 } 02857 if (((direction == Img_Backward_c) || (direction == Img_Both_c)) && 02858 (info->bwdClusteredRelationArray != NIL(array_t))) { 02859 (void) fprintf(vis_stdout, 02860 "Shared size of transition relation for backward image "); 02861 (void) fprintf(vis_stdout, 02862 "computation is %10ld BDD nodes (%-4d components)\n", 02863 bdd_size_multiple(info->bwdClusteredRelationArray), 02864 array_n(info->bwdClusteredRelationArray)); 02865 } 02866 }/* if verbosity > 0 */ 02867 02868 if(direction == Img_Backward_c || direction == Img_Both_c) 02869 ResetClusteredCofactoredRelationArray(mddManager, info); 02870 } 02871 02872 02873 02883 void 02884 ImgPrintIntegerArray(array_t *idArray) 02885 { 02886 int i; 02887 fprintf(vis_stdout, 02888 "**************** printing bdd ids from the bdd array ***********\n"); 02889 fprintf(vis_stdout,"%d::\t", array_n(idArray)); 02890 for (i=0;i<array_n(idArray); i++) { 02891 fprintf(vis_stdout," %d ", array_fetch(int, idArray, i)); 02892 } 02893 } 02894 02895 02905 void 02906 ImgPrintPartition(graph_t *partition) 02907 { 02908 vertex_t *vertex; 02909 lsList vertexList = g_get_vertices(partition); 02910 lsGen gen; 02911 st_table *vertexTable = st_init_table(st_ptrcmp, st_ptrhash); 02912 fprintf(vis_stdout,"\n"); 02913 lsForEachItem(vertexList, gen, vertex) { 02914 if (lsLength(g_get_out_edges(vertex)) == 0) 02915 PrintPartitionRecursively(vertex,vertexTable,0); 02916 } 02917 st_free_table(vertexTable); 02918 } 02919 02920 02930 void 02931 ImgPrintPartitionedTransitionRelation(mdd_manager *mddManager, 02932 array_t *relationArray, 02933 array_t *arraySmoothVarBddArray) 02934 { 02935 int i, j, n; 02936 mdd_t *relation; 02937 mdd_t *bdd; 02938 array_t *smoothVarBddArray; 02939 array_t *bvar_list = mdd_ret_bvar_list(mddManager); 02940 var_set_t *vset; 02941 bvar_type bv; 02942 02943 n = array_n(relationArray); 02944 02945 fprintf(vis_stdout, "# of relations = %d\n", n); 02946 if (arraySmoothVarBddArray) { 02947 smoothVarBddArray = array_fetch(array_t *, arraySmoothVarBddArray, 0); 02948 fprintf(vis_stdout, "Early smooth(%d) = ", array_n(smoothVarBddArray)); 02949 for (j = 0; j < array_n(smoothVarBddArray); j++) { 02950 bdd = array_fetch(mdd_t *, smoothVarBddArray, j); 02951 mdd_print_support_to_file(vis_stdout, " %s", bdd); 02952 } 02953 fprintf(vis_stdout, "\n"); 02954 } 02955 for (i = 0; i < n; i++) { 02956 relation = array_fetch(mdd_t *, relationArray, i); 02957 fprintf(vis_stdout, "T[%d] : bdd_size = %d\n", i, bdd_size(relation)); 02958 fprintf(vis_stdout, " support(%d) = ", 02959 mdd_get_number_of_bdd_support(mddManager, relation)); 02960 vset = bdd_get_support(relation); 02961 for (j = 0; j < array_n(bvar_list); j++) { 02962 if (var_set_get_elt(vset, j) == 1) { 02963 bv = array_fetch(bvar_type, bvar_list, j); 02964 mdd_print_support_to_file(vis_stdout, " %s", bv.node); 02965 } 02966 } 02967 var_set_free(vset); 02968 fprintf(vis_stdout, "\n"); 02969 if (arraySmoothVarBddArray) { 02970 smoothVarBddArray = array_fetch(array_t *, arraySmoothVarBddArray, i + 1); 02971 fprintf(vis_stdout, " smooth(%d) = ", array_n(smoothVarBddArray)); 02972 for (j = 0; j < array_n(smoothVarBddArray); j++) { 02973 bdd = array_fetch(mdd_t *, smoothVarBddArray, j); 02974 mdd_print_support_to_file(vis_stdout, " %s", bdd); 02975 } 02976 fprintf(vis_stdout, "\n"); 02977 } 02978 } 02979 } 02980 02981 02995 mdd_t * 02996 ImgTrmEliminateDependVars(ImgFunctionData_t *functionData, 02997 array_t *relationArray, 02998 mdd_t *states, mdd_t **dependRelations, 02999 int *nDependVars) 03000 { 03001 int i, j; 03002 int howMany = 0; /* number of latches that can be eliminated */ 03003 mdd_t *var, *newStates, *abs, *positive, *phi, *tmp, *relation; 03004 int nSupports; /* vars in the support of the state set */ 03005 int *candidates; /* vars to be considered for elimination */ 03006 double minStates; 03007 var_set_t *supportVarSet; 03008 graph_t *mddNetwork; 03009 mdd_manager *mddManager; 03010 03011 mddNetwork = functionData->mddNetwork; 03012 mddManager = Part_PartitionReadMddManager(mddNetwork); 03013 03014 if (dependRelations) 03015 *dependRelations = mdd_one(mddManager); 03016 newStates = mdd_dup(states); 03017 03018 nSupports = 0; 03019 supportVarSet = bdd_get_support(newStates); 03020 for (i = 0; i < supportVarSet->n_elts; i++) { 03021 if (var_set_get_elt(supportVarSet, i) == 1) 03022 nSupports++; 03023 } 03024 candidates = ALLOC(int, nSupports); 03025 if (candidates == NULL) { 03026 var_set_free(supportVarSet); 03027 return(NULL); 03028 } 03029 nSupports = 0; 03030 for (i = 0; i < supportVarSet->n_elts; i++) { 03031 if (var_set_get_elt(supportVarSet, i) == 1) { 03032 candidates[nSupports] = i; 03033 nSupports++; 03034 } 03035 } 03036 var_set_free(supportVarSet); 03037 03038 /* The signatures of the variables in a function are the number 03039 ** of minterms of the positive cofactors with respect to the 03040 ** variables themselves. */ 03041 signatures = bdd_cof_minterm(newStates); 03042 if (signatures == NULL) { 03043 FREE(candidates); 03044 return(NULL); 03045 } 03046 /* We now extract a positive quantity which is higher for those 03047 ** variables that are closer to being essential. */ 03048 minStates = signatures[nSupports]; 03049 for (i = 0; i < nSupports; i++) { 03050 double z = signatures[i] / minStates - 1.0; 03051 signatures[i] = (z < 0.0) ? -z : z; /* make positive */ 03052 } 03053 qsort((void *)candidates, nSupports, sizeof(int), 03054 (int (*)(const void *, const void *))TrmSignatureCompare); 03055 FREE(signatures); 03056 03057 /* Now process the candidates in the given order. */ 03058 for (i = 0; i < nSupports; i++) { 03059 var = bdd_var_with_index(mddManager, candidates[i]); 03060 if (bdd_var_is_dependent(newStates, var)) { 03061 abs = bdd_smooth_with_cube(newStates, var); 03062 if (abs == NULL) 03063 return(NULL); 03064 positive = bdd_cofactor(newStates, var); 03065 if (positive == NULL) 03066 return(NULL); 03067 phi = Img_MinimizeImage(positive, abs, Img_DefaultMinimizeMethod_c, 1); 03068 if (phi == NULL) 03069 return(NULL); 03070 mdd_free(positive); 03071 if (bdd_size(phi) < IMG_MAX_DEP_SIZE) { 03072 howMany++; 03073 for (j = 0; j < array_n(relationArray); j++) { 03074 relation = array_fetch(mdd_t *, relationArray, j); 03075 if (dependRelations) 03076 tmp = bdd_smooth_with_cube(relation, var); 03077 else 03078 tmp = bdd_compose(relation, var, phi); 03079 mdd_free(relation); 03080 array_insert(mdd_t *, relationArray, j, tmp); 03081 } 03082 mdd_free(newStates); 03083 newStates = abs; 03084 if (dependRelations) { 03085 relation = mdd_xnor(var, phi); 03086 tmp = ImgSubstitute(relation, functionData, Img_R2D_c); 03087 mdd_free(relation); 03088 relation = mdd_and(*dependRelations, tmp, 1, 1); 03089 mdd_free(*dependRelations); 03090 *dependRelations = relation; 03091 } 03092 } else { 03093 mdd_free(abs); 03094 } 03095 mdd_free(phi); 03096 } 03097 } 03098 FREE(candidates); 03099 03100 *nDependVars = howMany; 03101 return(newStates); 03102 } /* end of ImgTrmEliminateDependVars */ 03103 03104 03105 /*---------------------------------------------------------------------------*/ 03106 /* Definition of static functions */ 03107 /*---------------------------------------------------------------------------*/ 03108 03121 static void 03122 ResetClusteredCofactoredRelationArray( 03123 mdd_manager *mddManager, 03124 Iwls95Info_t *info) 03125 { 03126 int i; 03127 mdd_t *cluster; 03128 03129 assert(info->bwdClusteredRelationArray != NIL(array_t)); 03130 03131 FreeClusteredCofactoredRelationArray(info); 03132 03133 info->careSetArray = array_alloc(mdd_t *, 1); 03134 array_insert_last(mdd_t *, info->careSetArray, mdd_one(mddManager)); 03135 info->bwdClusteredCofactoredRelationArray = array_alloc(mdd_t *, 0); 03136 03137 arrayForEachItem(mdd_t *, info->bwdClusteredRelationArray, i, cluster){ 03138 array_insert_last(mdd_t *, info->bwdClusteredCofactoredRelationArray, 03139 mdd_dup(cluster)); 03140 } 03141 } 03142 03143 03155 static void 03156 FreeClusteredCofactoredRelationArray( 03157 Iwls95Info_t *info) 03158 { 03159 /* one should only be NIL if the other is, too */ 03160 assert((info->bwdClusteredCofactoredRelationArray != NIL(array_t)) == 03161 (info->careSetArray != NIL(array_t))); 03162 03163 if(info->bwdClusteredCofactoredRelationArray == NIL(array_t)) 03164 return; 03165 03166 mdd_array_free(info->bwdClusteredCofactoredRelationArray); 03167 info->bwdClusteredCofactoredRelationArray = NIL(array_t); 03168 mdd_array_free(info->careSetArray); 03169 info->careSetArray = NIL(array_t); 03170 } 03171 03172 03185 static ImgTrmOption_t * 03186 TrmGetOptions(void) 03187 { 03188 char *flagValue; 03189 ImgTrmOption_t *option; 03190 03191 option = ALLOC(ImgTrmOption_t, 1); 03192 03193 flagValue = Cmd_FlagReadByName("image_cluster_size"); 03194 if (flagValue == NIL(char)) { 03195 option->clusterSize = 5000; /* the default value */ 03196 } 03197 else { 03198 option->clusterSize = atoi(flagValue); 03199 } 03200 03201 flagValue = Cmd_FlagReadByName("image_verbosity"); 03202 if (flagValue == NIL(char)) { 03203 option->verbosity = 0; /* the default value */ 03204 } 03205 else { 03206 option->verbosity = atoi(flagValue); 03207 } 03208 03209 flagValue = Cmd_FlagReadByName("image_W1"); 03210 if (flagValue == NIL(char)) { 03211 option->W1 = 6; /* the default value */ 03212 } 03213 else { 03214 option->W1 = atoi(flagValue); 03215 } 03216 03217 flagValue = Cmd_FlagReadByName("image_W2"); 03218 if (flagValue == NIL(char)) { 03219 option->W2 = 1; /* the default value */ 03220 } 03221 else { 03222 option->W2 = atoi(flagValue); 03223 } 03224 03225 flagValue = Cmd_FlagReadByName("image_W3"); 03226 if (flagValue == NIL(char)) { 03227 option->W3 = 1; /* the default value */ 03228 } 03229 else { 03230 option->W3 = atoi(flagValue); 03231 } 03232 03233 flagValue = Cmd_FlagReadByName("image_W4"); 03234 if (flagValue == NIL(char)) { 03235 option->W4 = 2; /* the default value */ 03236 } 03237 else { 03238 option->W4 = atoi(flagValue); 03239 } 03240 03241 flagValue = Cmd_FlagReadByName("image_print_depend_matrix"); 03242 if (flagValue == NIL(char)) { 03243 option->printDepMatrix = 0; /* the default value */ 03244 } 03245 else { 03246 option->printDepMatrix = atoi(flagValue); 03247 } 03248 03249 03250 flagValue = Cmd_FlagReadByName("mlp_method"); 03251 if (flagValue == NIL(char)) { 03252 option->mlpMethod = 0; /* the default value */ 03253 } 03254 else { 03255 option->mlpMethod = atoi(flagValue); 03256 } 03257 03258 flagValue = Cmd_FlagReadByName("mlp_cluster"); 03259 if (flagValue == NIL(char)) { 03260 option->mlpCluster = 1; /* the default value */ 03261 } 03262 else { 03263 option->mlpCluster = atoi(flagValue); 03264 } 03265 03266 flagValue = Cmd_FlagReadByName("mlp_cluster_dynamic"); 03267 if (flagValue == NIL(char)) { 03268 option->mlpClusterDynamic = 1; /* the default value */ 03269 } 03270 else { 03271 option->mlpClusterDynamic = atoi(flagValue); 03272 } 03273 03274 flagValue = Cmd_FlagReadByName("mlp_affinity_threshold"); 03275 if (flagValue == NIL(char)) { 03276 option->mlpAffinityThreshold = 0.0; /* the default value */ 03277 } 03278 else { 03279 sscanf(flagValue, "%f", &option->mlpAffinityThreshold); 03280 } 03281 03282 flagValue = Cmd_FlagReadByName("mlp_cluster_quantify_vars"); 03283 if (flagValue == NIL(char)) { 03284 option->mlpClusterQuantifyVars = 0; /* the default value */ 03285 } 03286 else { 03287 option->mlpClusterQuantifyVars = atoi(flagValue); 03288 } 03289 03290 flagValue = Cmd_FlagReadByName("mlp_cluster_sorted_list"); 03291 if (flagValue == NIL(char)) { 03292 option->mlpClusterSortedList = 1; /* the default value */ 03293 } 03294 else { 03295 option->mlpClusterSortedList = atoi(flagValue); 03296 } 03297 03298 flagValue = Cmd_FlagReadByName("mlp_initial_cluster"); 03299 if (flagValue == NIL(char)) { 03300 option->mlpInitialCluster = 0; /* the default value */ 03301 } 03302 else { 03303 option->mlpInitialCluster = atoi(flagValue); 03304 } 03305 03306 flagValue = Cmd_FlagReadByName("mlp_cs_first"); 03307 if (flagValue == NIL(char)) { 03308 option->mlpCsFirst = 0; /* the default value */ 03309 } 03310 else { 03311 option->mlpCsFirst = atoi(flagValue); 03312 } 03313 03314 flagValue = Cmd_FlagReadByName("mlp_skip_rs"); 03315 if (flagValue == NIL(char)) { 03316 option->mlpSkipRs = 0; /* the default value */ 03317 } 03318 else { 03319 option->mlpSkipRs = atoi(flagValue); 03320 } 03321 03322 flagValue = Cmd_FlagReadByName("mlp_skip_cs"); 03323 if (flagValue == NIL(char)) { 03324 option->mlpSkipCs = 1; /* the default value */ 03325 } 03326 else { 03327 option->mlpSkipCs = atoi(flagValue); 03328 } 03329 03330 flagValue = Cmd_FlagReadByName("mlp_row_based"); 03331 if (flagValue == NIL(char)) { 03332 option->mlpRowBased = 0; /* the default value */ 03333 } 03334 else { 03335 option->mlpRowBased = atoi(flagValue); 03336 } 03337 03338 flagValue = Cmd_FlagReadByName("mlp_reorder"); 03339 if (flagValue == NIL(char)) { 03340 option->mlpReorder = 0; /* the default value */ 03341 } 03342 else { 03343 option->mlpReorder = atoi(flagValue); 03344 } 03345 03346 flagValue = Cmd_FlagReadByName("mlp_pre_reorder"); 03347 if (flagValue == NIL(char)) { 03348 option->mlpPreReorder = 0; /* the default value */ 03349 } 03350 else { 03351 option->mlpPreReorder = atoi(flagValue); 03352 } 03353 03354 flagValue = Cmd_FlagReadByName("mlp_postprocess"); 03355 if (flagValue == NIL(char)) { 03356 option->mlpPostProcess = 0; /* the default value */ 03357 } 03358 else { 03359 option->mlpPostProcess = atoi(flagValue); 03360 } 03361 03362 flagValue = Cmd_FlagReadByName("mlp_decompose_scc"); 03363 if (flagValue == NIL(char)) { 03364 option->mlpDecomposeScc = 1; /* the default value */ 03365 } 03366 else { 03367 option->mlpDecomposeScc = atoi(flagValue); 03368 } 03369 03370 flagValue = Cmd_FlagReadByName("mlp_cluster_scc"); 03371 if (flagValue == NIL(char)) { 03372 option->mlpClusterScc = 1; /* the default value */ 03373 } 03374 else { 03375 option->mlpClusterScc = atoi(flagValue); 03376 } 03377 03378 flagValue = Cmd_FlagReadByName("mlp_sort_scc"); 03379 if (flagValue == NIL(char)) { 03380 option->mlpSortScc = 1; /* the default value */ 03381 } 03382 else { 03383 option->mlpSortScc = atoi(flagValue); 03384 } 03385 03386 flagValue = Cmd_FlagReadByName("mlp_sort_scc_mode"); 03387 if (flagValue == NIL(char)) { 03388 option->mlpSortSccMode = 2; /* the default value */ 03389 } 03390 else { 03391 option->mlpSortSccMode = atoi(flagValue); 03392 } 03393 03394 flagValue = Cmd_FlagReadByName("mlp_cluster_merge"); 03395 if (flagValue == NIL(char)) { 03396 option->mlpClusterMerge = 0; /* the default value */ 03397 } 03398 else { 03399 option->mlpClusterMerge = atoi(flagValue); 03400 } 03401 03402 flagValue = Cmd_FlagReadByName("mlp_multiway"); 03403 if (flagValue == NIL(char)) { 03404 option->mlpMultiway = 0; /* the default value */ 03405 } 03406 else { 03407 option->mlpMultiway = atoi(flagValue); 03408 } 03409 03410 flagValue = Cmd_FlagReadByName("mlp_lambda_mode"); 03411 if (flagValue == NIL(char)) { 03412 option->mlpLambdaMode = 0; /* the default value */ 03413 } 03414 else { 03415 option->mlpLambdaMode = atoi(flagValue); 03416 } 03417 03418 flagValue = Cmd_FlagReadByName("mlp_sorted_rows"); 03419 if (flagValue == NIL(char)) { 03420 option->mlpSortedRows = 1; /* the default value */ 03421 } 03422 else { 03423 option->mlpSortedRows = atoi(flagValue); 03424 } 03425 03426 flagValue = Cmd_FlagReadByName("mlp_sorted_cols"); 03427 if (flagValue == NIL(char)) { 03428 option->mlpSortedCols = 1; /* the default value */ 03429 } 03430 else { 03431 option->mlpSortedCols = atoi(flagValue); 03432 } 03433 03434 flagValue = Cmd_FlagReadByName("mlp_pre_swap_state_vars"); 03435 if (flagValue == NIL(char)) { 03436 option->mlpPreSwapStateVars = 0; /* the default value */ 03437 } 03438 else { 03439 option->mlpPreSwapStateVars = atoi(flagValue); 03440 } 03441 03442 flagValue = Cmd_FlagReadByName("mlp_print_matrix"); 03443 if (flagValue == NIL(char)) { 03444 option->mlpPrintMatrix = 0; /* the default value */ 03445 } 03446 else { 03447 option->mlpPrintMatrix = atoi(flagValue); 03448 } 03449 03450 flagValue = Cmd_FlagReadByName("mlp_write_order"); 03451 if (flagValue == NIL(char)) { 03452 option->mlpWriteOrder = NIL(char); /* the default value */ 03453 } 03454 else { 03455 option->mlpWriteOrder = util_strsav(flagValue); 03456 } 03457 03458 flagValue = Cmd_FlagReadByName("mlp_verbosity"); 03459 if (flagValue == NIL(char)) { 03460 option->mlpVerbosity = 0; /* the default value */ 03461 } 03462 else { 03463 option->mlpVerbosity = atoi(flagValue); 03464 } 03465 03466 flagValue = Cmd_FlagReadByName("mlp_debug"); 03467 if (flagValue == NIL(char)) { 03468 option->mlpDebug = 0; /* the default value */ 03469 } 03470 else { 03471 option->mlpDebug = atoi(flagValue); 03472 } 03473 03474 flagValue = Cmd_FlagReadByName("image_read_reorder_cluster"); 03475 if (flagValue == NIL(char)) { 03476 option->readReorderCluster = 0; /* the default value */ 03477 } 03478 else { 03479 option->readReorderCluster = atoi(flagValue); 03480 } 03481 03482 flagValue = Cmd_FlagReadByName("image_read_cluster"); 03483 if (flagValue == NIL(char)) { 03484 option->readCluster = NIL(char); /* the default value */ 03485 } 03486 else { 03487 option->readCluster = util_strsav(flagValue); 03488 } 03489 03490 flagValue = Cmd_FlagReadByName("image_write_cluster"); 03491 if (flagValue == NIL(char)) { 03492 option->writeCluster = NIL(char); /* the default value */ 03493 } 03494 else { 03495 option->writeCluster = util_strsav(flagValue); 03496 } 03497 03498 flagValue = Cmd_FlagReadByName("image_write_depend_matrix"); 03499 if (flagValue == NIL(char)) { 03500 option->writeDepMatrix = NIL(char); /* the default value */ 03501 } 03502 else { 03503 option->writeDepMatrix = util_strsav(flagValue); 03504 } 03505 03506 flagValue = Cmd_FlagReadByName("linear_grain_type"); 03507 if (flagValue == NIL(char)) { 03508 option->linearFineGrainFlag = 0; /* the default value */ 03509 } 03510 else { 03511 option->linearFineGrainFlag = 1; 03512 } 03513 03514 flagValue = Cmd_FlagReadByName("linear_optimize"); 03515 if (flagValue == NIL(char)) { 03516 option->linearOptimize = Opt_None; /* the default value */ 03517 } 03518 else { 03519 option->linearOptimize = Opt_NS; 03520 } 03521 03522 option->linearOrderVariable = 0; 03523 flagValue = Cmd_FlagReadByName("linear_order_variable"); 03524 if (flagValue == NIL(char)) { 03525 option->linearOrderVariable = 0; /* the default value */ 03526 } 03527 else { 03528 option->linearOrderVariable = 1; 03529 } 03530 03531 option->linearGroupStateVariable = 0; 03532 flagValue = Cmd_FlagReadByName("linear_group_state_variable"); 03533 if (flagValue == NIL(char)) { 03534 option->linearGroupStateVariable = 0; /* the default value */ 03535 } 03536 else { 03537 option->linearGroupStateVariable = 1; 03538 } 03539 03540 option->linearIncludeCS = 1; 03541 option->linearIncludeNS = 1; 03542 option->linearQuantifyCS = 0; 03543 option->linearComputeRange = 0; 03544 flagValue = Cmd_FlagReadByName("linear_exclude_cs"); 03545 if (flagValue) option->linearIncludeCS = 0; 03546 flagValue = Cmd_FlagReadByName("linear_exclude_ns"); 03547 if (flagValue) option->linearIncludeNS = 0; 03548 03549 return option; 03550 } 03551 03572 static void 03573 CreateBitRelationArray(Iwls95Info_t *info, ImgFunctionData_t *functionData) 03574 { 03575 array_t *bddRelationArray = NIL(array_t); 03576 array_t *domainVarMddIdArray = functionData->domainVars; 03577 array_t *rangeVarMddIdArray = functionData->rangeVars; 03578 array_t *quantifyVarMddIdArray = NIL(array_t); 03579 graph_t *mddNetwork = functionData->mddNetwork; 03580 array_t *roots = functionData->roots; 03581 int i; 03582 int n1, n2, nIntermediateVars = 0; 03583 mdd_manager *mddManager = NIL(mdd_manager); 03584 st_table *vertexTable = NIL(st_table); 03585 st_table *domainQuantifyVarMddIdTable = NIL(st_table); 03586 int mddId; 03587 char *nodeName; 03588 03589 if (info->bitRelationArray != NIL(array_t)) { 03590 assert(info->quantifyVarMddIdArray != NIL(array_t)); 03591 return; 03592 } 03593 03594 bddRelationArray = array_alloc(mdd_t*, 0); 03595 quantifyVarMddIdArray = array_dup(functionData->quantifyVars); 03596 mddManager = Part_PartitionReadMddManager(mddNetwork); 03597 vertexTable = st_init_table(st_ptrcmp, st_ptrhash); 03598 domainQuantifyVarMddIdTable = st_init_table(st_numcmp, st_numhash); 03599 03600 arrayForEachItem(int, domainVarMddIdArray, i, mddId) { 03601 st_insert(domainQuantifyVarMddIdTable, (char *)(long)mddId, NIL(char)); 03602 } 03603 arrayForEachItem(int, quantifyVarMddIdArray, i, mddId) { 03604 st_insert(domainQuantifyVarMddIdTable, (char *)(long)mddId, NIL(char)); 03605 } 03606 03607 arrayForEachItem(char *, roots, i, nodeName) { 03608 vertex_t *vertex = Part_PartitionFindVertexByName(mddNetwork, nodeName); 03609 Mvf_Function_t *mvf = Part_VertexReadFunction(vertex); 03610 int mddId = array_fetch(int, rangeVarMddIdArray, i); 03611 03612 /*mdd_t *relation = Mvf_FunctionBuildRelationWithVariable(mvf, mddId);*/ 03613 array_t *varBddRelationArray = mdd_fn_array_to_bdd_rel_array(mddManager, 03614 mddId, mvf); 03615 array_append(bddRelationArray, varBddRelationArray); 03616 array_free(varBddRelationArray); 03617 /*array_insert_last(mdd_t *, bddRelationArray, relation);*/ 03618 if (info->option->verbosity) 03619 n1 = array_n(bddRelationArray); 03620 else /* to remove uninitialized variable warning */ 03621 n1 = 0; 03622 PartitionTraverseRecursively(mddManager, vertex, -1, vertexTable, 03623 bddRelationArray, 03624 domainQuantifyVarMddIdTable, 03625 quantifyVarMddIdArray); 03626 if (info->option->verbosity) { 03627 n2 = array_n(bddRelationArray); 03628 nIntermediateVars += n2 - n1; 03629 } 03630 } 03631 if (info->option->verbosity) { 03632 (void)fprintf(vis_stdout, "** img info: %d intermediate variables\n", 03633 nIntermediateVars); 03634 } 03635 st_free_table(vertexTable); 03636 st_free_table(domainQuantifyVarMddIdTable); 03637 info->bitRelationArray = bddRelationArray; 03638 info->quantifyVarMddIdArray = quantifyVarMddIdArray; 03639 return; 03640 03641 } 03642 03653 static void 03654 FreeBitRelationArray (Iwls95Info_t *info) 03655 { 03656 mdd_array_free(info->bitRelationArray); 03657 info->bitRelationArray = NIL(array_t); 03658 return; 03659 } 03660 03661 03662 03691 static void 03692 OrderClusterOrder(mdd_manager *mddManager, 03693 array_t *relationArray, 03694 array_t *fromVarBddArray, 03695 array_t *toVarBddArray, 03696 array_t *quantifyVarBddArray, 03697 array_t **orderedClusteredRelationArrayPtr, 03698 array_t **smoothVarBddArrayPtr, 03699 ImgTrmOption_t *option, 03700 boolean freeRelationArray) 03701 { 03702 array_t *clusteredRelationArray; /*clustered version of orderedRelationArray*/ 03703 03704 /* 03705 * Since clusters are formed by multiplying the latches starting 03706 * from one end we need to order the latches using some heuristics 03707 * first. Right now, we order the latches using the same heuristic 03708 * as the one used for ordering the clusters for early quantifiction. 03709 * However, since we are not interested in the quantification 03710 * schedule at this stage, we will pass a NIL(array_t*) as the last 03711 * argument. 03712 */ 03713 *orderedClusteredRelationArrayPtr = NIL(array_t); 03714 OrderRelationArray(mddManager, relationArray, fromVarBddArray, 03715 quantifyVarBddArray, toVarBddArray, option, 03716 orderedClusteredRelationArrayPtr, NIL(array_t *)); 03717 03718 /* free relationArray if told to */ 03719 if (freeRelationArray) mdd_array_free(relationArray); 03720 03721 03722 /* Create the clusters */ 03723 clusteredRelationArray = CreateClusters(mddManager, 03724 *orderedClusteredRelationArrayPtr, 03725 option); 03726 03727 /* Free the orderedRelationArray */ 03728 mdd_array_free(*orderedClusteredRelationArrayPtr); 03729 03730 /* Order the clusters for image and pre-image computation. */ 03731 OrderRelationArray(mddManager, clusteredRelationArray, fromVarBddArray, 03732 quantifyVarBddArray, toVarBddArray, option, 03733 orderedClusteredRelationArrayPtr, smoothVarBddArrayPtr); 03734 /* Free the clusteredRelationArray. */ 03735 mdd_array_free(clusteredRelationArray); 03736 } 03737 03738 03750 static array_t * 03751 CreateClusters(bdd_manager *bddManager, array_t *relationArray, 03752 ImgTrmOption_t *option) 03753 { 03754 array_t *clusterArray; 03755 int i; 03756 bdd_t *cluster, *relation, *tempCluster; 03757 int flag; 03758 int size; 03759 03760 clusterArray = array_alloc(bdd_t *, 0); 03761 03762 for (i=0; i<array_n(relationArray);) { 03763 cluster = bdd_one(bddManager); 03764 flag = 0; 03765 do{ 03766 relation = array_fetch(bdd_t *,relationArray, i); 03767 i++; 03768 tempCluster = bdd_and_with_limit(cluster, relation, 1, 1, 03769 option->clusterSize); 03770 assert(flag || tempCluster != NIL(mdd_t)); 03771 if (tempCluster != NIL(mdd_t)) { 03772 size = bdd_size(tempCluster); 03773 if (size <= option->clusterSize || flag == 0) { 03774 bdd_free(cluster); 03775 cluster = tempCluster; 03776 if (flag == 0 && size >= option->clusterSize) 03777 break; 03778 flag = 1; 03779 } 03780 else{ 03781 bdd_free(tempCluster); 03782 i--; 03783 break; 03784 } 03785 } 03786 else { 03787 i--; 03788 break; 03789 } 03790 } while (i < array_n(relationArray)); 03791 array_insert_last(bdd_t *, clusterArray, cluster); 03792 } 03793 return clusterArray; 03794 } 03795 03814 static void 03815 OrderRelationArray(mdd_manager *mddManager, 03816 array_t *relationArray, 03817 array_t *domainVarBddArray, 03818 array_t *quantifyVarBddArray, 03819 array_t *rangeVarBddArray, 03820 ImgTrmOption_t *option, 03821 array_t **orderedRelationArrayPtr, 03822 array_t **arraySmoothVarBddArrayPtr) 03823 { 03824 array_t *quantifyVarBddIdArray, *domainVarBddIdArray, *rangeVarBddIdArray; 03825 array_t *domainAndQuantifyVarBddArray; 03826 array_t *ctrInfoArray, *varInfoArray, *simplifiedRelationArray; 03827 array_t *sortedMaxIndexArray; 03828 array_t *arrayDomainQuantifyVarsWithZeroNumCtr = NIL(array_t); 03829 int numRelation, numDomainVars, numQuantifyVars, numRangeVars; 03830 int numSmoothVars, numVars; 03831 int bddId; 03832 int i; 03833 int *sortedMaxIndexVector; 03834 int numSmoothVarsRemaining, numIntroducedVarsRemaining; 03835 st_table *bddIdToVarInfoTable, *bddIdToBddTable; 03836 bdd_t *relation, *bdd; 03837 CtrInfo_t *ctrInfo; 03838 VarInfo_t *varInfo; 03839 lsList remainingCtrInfoList; 03840 03841 numRelation = array_n(relationArray); 03842 numDomainVars = array_n(domainVarBddArray); 03843 numRangeVars = array_n(rangeVarBddArray); 03844 numQuantifyVars = array_n(quantifyVarBddArray); 03845 numSmoothVars = numDomainVars + numQuantifyVars; 03846 numVars = numSmoothVars + numRangeVars; 03847 03848 domainVarBddIdArray = bdd_get_varids(domainVarBddArray); 03849 rangeVarBddIdArray = bdd_get_varids(rangeVarBddArray); 03850 quantifyVarBddIdArray = bdd_get_varids(quantifyVarBddArray); 03851 domainAndQuantifyVarBddArray = array_join(domainVarBddArray, 03852 quantifyVarBddArray); 03853 03854 bddIdToBddTable = st_init_table(st_numcmp, st_numhash); 03855 HashIdToBddTable(bddIdToBddTable, domainVarBddIdArray, domainVarBddArray); 03856 HashIdToBddTable(bddIdToBddTable, quantifyVarBddIdArray, quantifyVarBddArray); 03857 HashIdToBddTable(bddIdToBddTable, rangeVarBddIdArray, rangeVarBddArray); 03858 03859 bddIdToVarInfoTable = st_init_table(st_numcmp, st_numhash); 03860 03861 /* 03862 * Create the array of ctrInfo's for each component 03863 */ 03864 ctrInfoArray = array_alloc(CtrInfo_t*, 0); 03865 varInfoArray = array_alloc(VarInfo_t*, 0); 03866 03867 /* 03868 * Create the array of varInfo for each variable 03869 */ 03870 for (i=0; i<numVars; i++) { 03871 varInfo = VarInfoStructAlloc(); 03872 if (i<numDomainVars) { 03873 bddId = array_fetch(int, domainVarBddIdArray, i); 03874 varInfo->varType = domainVar_c; 03875 } 03876 else if (i < (numDomainVars+numQuantifyVars)) { 03877 bddId = array_fetch(int, quantifyVarBddIdArray, i-numDomainVars); 03878 varInfo->varType = quantifyVar_c; 03879 } 03880 else{ 03881 bddId = array_fetch(int, rangeVarBddIdArray, 03882 (i-(numDomainVars+numQuantifyVars))); 03883 varInfo->varType = rangeVar_c; 03884 } 03885 array_insert_last(VarInfo_t*, varInfoArray, varInfo); 03886 varInfo->bddId = bddId; 03887 st_insert(bddIdToVarInfoTable, (char *)(long) bddId, (char *)varInfo); 03888 } 03889 03890 /* 03891 * Fill in the data structure of the ctrInfo and varInfo 03892 */ 03893 for (i=0; i<numRelation; i++) { 03894 st_table *supportTable; 03895 st_generator *stGen; 03896 VarItem_t *varItem; 03897 CtrItem_t *ctrItem; 03898 lsHandle varItemHandle, ctrItemHandle; 03899 long varId; 03900 03901 ctrInfo = CtrInfoStructAlloc(); 03902 array_insert_last(CtrInfo_t*, ctrInfoArray, ctrInfo); 03903 ctrInfo->ctrId = i; 03904 relation = array_fetch(bdd_t*, relationArray, i); 03905 supportTable = ImgBddGetSupportIdTable(relation); 03906 st_foreach_item(supportTable, stGen, &varId, NULL) { 03907 varInfo = NIL(VarInfo_t); 03908 if (st_lookup(bddIdToVarInfoTable, (char *) varId, &varInfo) == 0) { 03909 /* This variable is of no interest, because it is not present 03910 * in the bddIdToVarInfoTable. 03911 */ 03912 continue; 03913 } 03914 varItem = ALLOC(VarItem_t,1); 03915 varItem->varInfo = varInfo; 03916 (void) lsNewBegin(ctrInfo->varItemList, (lsGeneric)varItem, 03917 (lsHandle *)&varItemHandle); 03918 ctrItem = ALLOC(CtrItem_t,1); 03919 ctrItem->ctrInfo = ctrInfo; 03920 (void) lsNewBegin(varInfo->ctrItemList, (lsGeneric)ctrItem, 03921 (lsHandle *)&ctrItemHandle); 03922 varItem->ctrItemHandle = ctrItemHandle; 03923 ctrItem->varItemHandle = varItemHandle; 03924 varInfo->numCtr++; 03925 } 03926 st_free_table(supportTable); 03927 } /* Initialization of ctrInfoArray and varInfoArray complete */ 03928 03929 /* 03930 * Smooth out the quantify variables which are local to a particular cluster. 03931 */ 03932 simplifiedRelationArray = RelationArraySmoothLocalVars(relationArray, 03933 ctrInfoArray, 03934 varInfoArray, 03935 bddIdToBddTable); 03936 03937 assert(CheckCtrInfoArray(ctrInfoArray, numDomainVars, numQuantifyVars, 03938 numRangeVars)); 03939 assert(CheckVarInfoArray(varInfoArray, numRelation)); 03940 03941 /* 03942 * In the ordering scheme of clusters, the number of variables yet to be 03943 * quantified out and number of variables which are yet to be introduced is 03944 * taken into account. The number of smooth variables which are yet to be 03945 * quantified out could have changed. Also some of the range variables may 03946 * not be in the support of any of the clusters. This can happen while doing 03947 * the ordering for clusters for backward image (when a present state 03948 * variable does not appear in the support of any of the next state 03949 * functions. Recalculate these numbers. */ 03950 03951 numSmoothVarsRemaining = numSmoothVars; 03952 numIntroducedVarsRemaining = numRangeVars; 03953 03954 /* 03955 * Find out which variables do not appear in the support of any cluster. 03956 * Update the numSmoothVarsRemaining and numIntroducedVarsRemaining 03957 * accordingly. 03958 * Also, these domainVars and quantifyVars can be quantified out as soon as 03959 * possible. 03960 */ 03961 if (arraySmoothVarBddArrayPtr != NIL(array_t *)) 03962 arrayDomainQuantifyVarsWithZeroNumCtr = array_alloc(bdd_t*, 0); 03963 for (i=0; i<numVars; i++) { 03964 varInfo = array_fetch(VarInfo_t*, varInfoArray, i); 03965 if (varInfo->numCtr == 0) { 03966 if ((varInfo->varType == domainVar_c) || 03967 (varInfo->varType == quantifyVar_c)) { 03968 numSmoothVarsRemaining--; 03969 if (arraySmoothVarBddArrayPtr != NIL(array_t *)) { 03970 st_lookup(bddIdToBddTable, (char *)(long)varInfo->bddId, &bdd); 03971 array_insert_last(bdd_t*, arrayDomainQuantifyVarsWithZeroNumCtr, 03972 bdd_dup(bdd)); 03973 } 03974 } 03975 else numIntroducedVarsRemaining--; 03976 } 03977 } 03978 03979 /* 03980 * The ordering scheme also depends on the value of the maximum index of a 03981 * smooth variable which is yet to be quantified. For efficiency reasons, we 03982 * maintain a vector indicating the maximum index of the clusters. This 03983 * vector is sorted in the decreasing order of index. The rank of a cluster 03984 * is stored in its "rankMaxSmoothVarIndex" field. 03985 */ 03986 sortedMaxIndexArray = array_dup(ctrInfoArray); 03987 array_sort(sortedMaxIndexArray, CtrInfoMaxIndexCompare); 03988 sortedMaxIndexVector = ALLOC(int, numRelation); 03989 for (i=0; i<numRelation; i++) { 03990 ctrInfo = array_fetch(CtrInfo_t*, sortedMaxIndexArray, i); 03991 ctrInfo->rankMaxSmoothVarIndex = i; 03992 sortedMaxIndexVector[i] = ctrInfo->maxSmoothVarIndex; 03993 } 03994 array_free(sortedMaxIndexArray); 03995 03996 /* 03997 * Create a list of clusters which are yet to be ordered. Right now 03998 * put all the clusters. Later on the list will contain only those 03999 * clusters which have not yet been ordered. 04000 */ 04001 remainingCtrInfoList = lsCreate(); 04002 for(i=0; i<numRelation; i++) { 04003 lsHandle ctrHandle; 04004 ctrInfo = array_fetch(CtrInfo_t*, ctrInfoArray, i); 04005 lsNewBegin(remainingCtrInfoList, (lsGeneric)ctrInfo, &ctrHandle); 04006 ctrInfo->ctrInfoListHandle = ctrHandle; 04007 } 04008 04009 /* Call the auxiliary routine to do the ordering. */ 04010 OrderRelationArrayAux(simplifiedRelationArray, remainingCtrInfoList, 04011 ctrInfoArray, varInfoArray, sortedMaxIndexVector, 04012 numSmoothVarsRemaining, numIntroducedVarsRemaining, 04013 bddIdToBddTable, option, domainAndQuantifyVarBddArray, 04014 orderedRelationArrayPtr, arraySmoothVarBddArrayPtr, 04015 arrayDomainQuantifyVarsWithZeroNumCtr); 04016 04017 lsDestroy(remainingCtrInfoList,0); 04018 04019 /* Free the info arrays */ 04020 04021 for (i=0; i<numRelation; i++) { 04022 ctrInfo = array_fetch(CtrInfo_t*, ctrInfoArray, i); 04023 CtrInfoStructFree(ctrInfo); 04024 } 04025 array_free(ctrInfoArray); 04026 04027 for (i=0; i<numVars; i++) { 04028 varInfo = array_fetch(VarInfo_t*, varInfoArray, i); 04029 assert(varInfo->numCtr == 0); 04030 VarInfoStructFree(varInfo); 04031 } 04032 array_free(varInfoArray); 04033 04034 if (option->verbosity >= 3) { 04035 int numRelation = array_n(*orderedRelationArrayPtr); 04036 04037 if (arraySmoothVarBddArrayPtr != NIL(array_t*)) { 04038 PrintSmoothIntroducedCount(*orderedRelationArrayPtr, 04039 arraySmoothVarBddArrayPtr, 04040 domainVarBddIdArray, 04041 rangeVarBddIdArray); 04042 } 04043 if (option->verbosity >= 4) { 04044 for (i= 0; i <numRelation; i++) { 04045 st_table *supportTable; 04046 (void) fprintf(vis_stdout, "Cluster # %d\n",i); 04047 supportTable = ImgBddGetSupportIdTable( 04048 array_fetch(bdd_t*, *orderedRelationArrayPtr, i)); 04049 PrintBddIdTable(supportTable); 04050 if (arraySmoothVarBddArrayPtr != NIL(array_t*)) { 04051 (void) fprintf(vis_stdout, "Exist cube # %d\n",i); 04052 PrintBddIdFromBddArray(array_fetch(array_t*, 04053 *arraySmoothVarBddArrayPtr, i)); 04054 } 04055 } 04056 } 04057 } 04058 FREE(sortedMaxIndexVector); 04059 array_free(simplifiedRelationArray); 04060 04061 /* Free BDD Id arrays */ 04062 array_free(domainVarBddIdArray); 04063 array_free(quantifyVarBddIdArray); 04064 array_free(rangeVarBddIdArray); 04065 array_free(domainAndQuantifyVarBddArray); 04066 /* Free the st_tables */ 04067 st_free_table(bddIdToBddTable); 04068 st_free_table(bddIdToVarInfoTable); 04069 } 04070 04087 static array_t * 04088 RelationArraySmoothLocalVars(array_t *relationArray, array_t *ctrInfoArray, 04089 array_t *varInfoArray, 04090 st_table *bddIdToBddTable) 04091 { 04092 array_t *arraySmoothVarBddArray, *smoothVarBddArray; 04093 array_t *simplifiedRelationArray; 04094 bdd_t *simplifiedRelation, *relation, *varBdd; 04095 int maxSmoothVarIndexForAllCtr, i, numRelation; 04096 04097 numRelation = array_n(relationArray); 04098 04099 /* 04100 * Initialize the array of cubes (of quantified variables which occur in 04101 * only one relation), to be smoothed out. 04102 */ 04103 arraySmoothVarBddArray = array_alloc(array_t*, 0); 04104 for (i=0; i<numRelation; i++) { 04105 smoothVarBddArray = array_alloc(bdd_t*, 0); 04106 array_insert_last(array_t*, arraySmoothVarBddArray, smoothVarBddArray); 04107 } 04108 04109 maxSmoothVarIndexForAllCtr = -1; 04110 for (i=0; i<numRelation; i++) { 04111 VarItem_t *varItem; 04112 lsHandle varItemHandle; 04113 CtrInfo_t *ctrInfo = array_fetch(CtrInfo_t*, ctrInfoArray, i); 04114 int maxSmoothVarIndex = -1; 04115 lsGen varItemListGen = lsStart(ctrInfo->varItemList); 04116 04117 smoothVarBddArray = array_fetch(array_t *, arraySmoothVarBddArray, i); 04118 while (lsNext(varItemListGen, &varItem, &varItemHandle) == 04119 LS_OK) { 04120 int varBddId; 04121 VarInfo_t *varInfo = varItem->varInfo; 04122 if (varInfo->varType == rangeVar_c) { 04123 ctrInfo->numIntroducedVars++; 04124 } 04125 else if (varInfo->numCtr == 1) { 04126 assert(lsLength(varInfo->ctrItemList) == 1); 04127 if (varInfo->varType == quantifyVar_c) { 04128 /* 04129 * The variable can be smoothed out. 04130 * Put it in an array of variables to be 04131 * smoothed out from the relation. 04132 */ 04133 CtrItem_t *ctrItem; 04134 varBddId = varInfo->bddId; 04135 st_lookup(bddIdToBddTable, (char *)(long)varBddId,&varBdd); 04136 array_insert_last(bdd_t*, smoothVarBddArray, bdd_dup(varBdd)); 04137 varInfo->numCtr = 0; 04138 /* Remove the cluster from the ctrItemList of varInfo */ 04139 lsRemoveItem(varItem->ctrItemHandle, &ctrItem); 04140 CtrItemStructFree(ctrItem); 04141 /* Remove the variable from the varItemList of ctrInfo.*/ 04142 lsRemoveItem(varItemHandle, &varItem); 04143 VarItemStructFree(varItem); 04144 continue; 04145 } 04146 else { 04147 /* Increase the numLocalSmoothVars count of the corresponding ctr. */ 04148 ctrInfo->numLocalSmoothVars++; 04149 ctrInfo->numSmoothVars++; 04150 if (maxSmoothVarIndex < varInfo->bddId) { 04151 maxSmoothVarIndex = varInfo->bddId; 04152 } 04153 } 04154 } 04155 else{ /* varInfo->numCtr > 1 */ 04156 assert(varInfo->numCtr > 1); 04157 ctrInfo->numSmoothVars++; 04158 if (maxSmoothVarIndex < varInfo->bddId) { 04159 maxSmoothVarIndex = varInfo->bddId; 04160 } 04161 } 04162 } 04163 lsFinish(varItemListGen); 04164 if (maxSmoothVarIndex >= 0) { 04165 ctrInfo->maxSmoothVarIndex = maxSmoothVarIndex; 04166 } 04167 else{ 04168 ctrInfo->maxSmoothVarIndex = 0; 04169 } 04170 if (maxSmoothVarIndexForAllCtr < maxSmoothVarIndex) { 04171 maxSmoothVarIndexForAllCtr = maxSmoothVarIndex; 04172 } 04173 } 04174 04175 /* 04176 * Initialization Finished. We need to smooth out those quantify 04177 * variables which appear in only one ctr. 04178 */ 04179 simplifiedRelationArray = array_alloc(bdd_t*, 0); 04180 for (i=0; i<numRelation; i++) { 04181 relation = array_fetch(bdd_t*, relationArray, i); 04182 smoothVarBddArray = array_fetch(array_t*, arraySmoothVarBddArray, i); 04183 if (array_n(smoothVarBddArray) != 0) 04184 simplifiedRelation = bdd_smooth(relation, smoothVarBddArray); 04185 else 04186 simplifiedRelation = bdd_dup(relation); 04187 array_insert_last(bdd_t*, simplifiedRelationArray, simplifiedRelation); 04188 } 04189 mdd_array_array_free(arraySmoothVarBddArray); 04190 return simplifiedRelationArray; 04191 } 04192 04211 static void 04212 OrderRelationArrayAux(array_t *relationArray, 04213 lsList remainingCtrInfoList, 04214 array_t *ctrInfoArray, 04215 array_t *varInfoArray, 04216 int *sortedMaxIndexVector, 04217 int numSmoothVarsRemaining, 04218 int numIntroducedVarsRemaining, 04219 st_table *bddIdToBddTable, 04220 ImgTrmOption_t *option, 04221 array_t *domainAndQuantifyVarBddArray, 04222 array_t **orderedRelationArrayPtr, 04223 array_t **arraySmoothVarBddArrayPtr, 04224 array_t *arrayDomainQuantifyVarsWithZeroNumCtr) 04225 { 04226 int numRelation, ctrCount, currentRankMaxSmoothVarIndex; 04227 int maxIndex = 0; 04228 array_t *orderedRelationArray, *arraySmoothVarBddArray; 04229 array_t *smoothVarBddArray; 04230 int *bestCtrIdVector; 04231 int maxNumLocalSmoothVars, maxNumSmoothVars, maxNumIntroducedVars; 04232 lsGen lsgen; 04233 04234 ctrCount = 0; 04235 currentRankMaxSmoothVarIndex = 0; 04236 04237 numRelation = array_n(relationArray); 04238 04239 arraySmoothVarBddArray = NIL(array_t); 04240 orderedRelationArray = array_alloc(bdd_t*, 0); 04241 *orderedRelationArrayPtr = orderedRelationArray; 04242 if (arraySmoothVarBddArrayPtr != NIL(array_t *)) { 04243 arraySmoothVarBddArray = array_alloc(array_t*, 0); 04244 *arraySmoothVarBddArrayPtr = arraySmoothVarBddArray; 04245 array_insert_last(array_t*, arraySmoothVarBddArray, 04246 arrayDomainQuantifyVarsWithZeroNumCtr); 04247 } 04248 bestCtrIdVector = ALLOC(int, numRelation); 04249 04250 while (ctrCount < numRelation) { 04251 float bestBenefit, benefit; 04252 int bestCtrId; 04253 bdd_t *bestRelation; 04254 lsGen ctrInfoListGen; 04255 CtrInfo_t *ctrInfo, *ctrInfoAux; 04256 04257 bestBenefit = -1.0e20; /* a safely small number */ 04258 bestCtrId = -1; 04259 /* Find the maximum index of the remaining clusters */ 04260 while (currentRankMaxSmoothVarIndex < numRelation && 04261 (maxIndex = sortedMaxIndexVector[currentRankMaxSmoothVarIndex++]) == -1); 04262 04263 /* Calculate the maximum values of local smooth variables etc. */ 04264 maxNumLocalSmoothVars = 0; 04265 maxNumSmoothVars = 0; 04266 maxNumIntroducedVars = 0; 04267 lsForEachItem(remainingCtrInfoList, lsgen, ctrInfo) { 04268 if (ctrInfo->numLocalSmoothVars > maxNumLocalSmoothVars) { 04269 maxNumLocalSmoothVars = ctrInfo->numLocalSmoothVars; 04270 } 04271 if (ctrInfo->numSmoothVars > maxNumSmoothVars) { 04272 maxNumSmoothVars = ctrInfo->numSmoothVars; 04273 } 04274 if (ctrInfo->numIntroducedVars > maxNumIntroducedVars) { 04275 maxNumIntroducedVars = ctrInfo->numIntroducedVars; 04276 } 04277 } 04278 04279 if (option->verbosity >= 4) { 04280 fprintf(vis_stdout, "maxNumLocalSmoothVars = %3d maxNumSmoothVars = %3d ", 04281 maxNumLocalSmoothVars, maxNumSmoothVars); 04282 fprintf(vis_stdout, "maxNumIntroducedVars = %3d\n", maxNumIntroducedVars); 04283 } 04284 /* Calculate the cost function of each of the cluster */ 04285 ctrInfoListGen = lsStart(remainingCtrInfoList); 04286 while (lsNext(ctrInfoListGen, &ctrInfo, NIL(lsHandle)) == 04287 LS_OK) { 04288 benefit = CalculateBenefit(ctrInfo, maxNumLocalSmoothVars, 04289 maxNumSmoothVars, maxIndex, 04290 maxNumIntroducedVars, option); 04291 04292 if (option->verbosity >= 4) { 04293 fprintf(vis_stdout, 04294 "id = %d: numLocalSmoothVars = %d numSmoothVars = %d benefit = %f\n", 04295 ctrInfo->ctrId, ctrInfo->numLocalSmoothVars, 04296 ctrInfo->numSmoothVars, benefit); 04297 } 04298 if (benefit > bestBenefit) { 04299 bestBenefit = benefit; 04300 bestCtrId = ctrInfo->ctrId; 04301 } 04302 } 04303 lsFinish(ctrInfoListGen); 04304 /* 04305 * Insert the relation in the ordered array of relations and put in the 04306 * appropriate cubes. 04307 */ 04308 04309 bestCtrIdVector[ctrCount] = bestCtrId; 04310 ctrInfo = array_fetch(CtrInfo_t*, ctrInfoArray, bestCtrId); 04311 lsRemoveItem(ctrInfo->ctrInfoListHandle, &ctrInfoAux); 04312 assert(ctrInfo == ctrInfoAux); 04313 bestRelation = array_fetch(bdd_t*, relationArray, bestCtrId); 04314 array_insert_last(bdd_t*, orderedRelationArray, bestRelation); 04315 if (option->verbosity >= 4) { 04316 fprintf(vis_stdout, 04317 "Best id = %d benefit = %f numLocalSmoothVars = %d numSmoothVars = %d\n", 04318 bestCtrId, bestBenefit, ctrInfo->numLocalSmoothVars, 04319 ctrInfo->numSmoothVars); 04320 } 04321 /* 04322 * Update the remaining ctrInfo's and the varInfo's affected by choosing 04323 * this cluster. Also get the array of smooth variables which can be 04324 * quantified once this cluster is multiplied in the product. 04325 */ 04326 smoothVarBddArray = UpdateInfoArrays(ctrInfo, bddIdToBddTable, 04327 &numSmoothVarsRemaining, 04328 &numIntroducedVarsRemaining); 04329 assert(CheckCtrInfo(ctrInfo, numSmoothVarsRemaining, 0, 04330 numIntroducedVarsRemaining)); 04331 04332 if (arraySmoothVarBddArrayPtr != NIL(array_t *)) { 04333 if (ctrCount == numRelation-1) { 04334 /* 04335 * In the last element of arraySmoothVarBddArray, put all the domain 04336 * and quantify variables (in case some of them were not in the support 04337 * of any cluster). 04338 */ 04339 int i, j; 04340 st_table *varsTable = st_init_table((ST_PFICPCP)bdd_ptrcmp, 04341 (ST_PFICPI)bdd_ptrhash); 04342 array_t *tmpVarBddArray; 04343 mdd_t *tmpVar; 04344 04345 arrayForEachItem(array_t *, arraySmoothVarBddArray, i, tmpVarBddArray) { 04346 arrayForEachItem(mdd_t *, tmpVarBddArray, j, tmpVar) { 04347 st_insert(varsTable, (char *)tmpVar, NIL(char)); 04348 } 04349 } 04350 arrayForEachItem(mdd_t *, smoothVarBddArray, i, tmpVar) { 04351 st_insert(varsTable, (char *)tmpVar, NIL(char)); 04352 } 04353 arrayForEachItem(mdd_t *, domainAndQuantifyVarBddArray, i, tmpVar) { 04354 if (st_lookup(varsTable, (char *)tmpVar, NIL(char *)) == 0) 04355 array_insert_last(mdd_t *, smoothVarBddArray, mdd_dup(tmpVar)); 04356 } 04357 st_free_table(varsTable); 04358 } 04359 array_insert_last(array_t*, arraySmoothVarBddArray, smoothVarBddArray); 04360 } 04361 else{ 04362 mdd_array_free(smoothVarBddArray); 04363 } 04364 sortedMaxIndexVector[ctrInfo->rankMaxSmoothVarIndex] = -1; 04365 ctrCount++; 04366 } 04367 assert(numIntroducedVarsRemaining == 0); 04368 assert(numSmoothVarsRemaining == 0); 04369 if (option->verbosity >= 3) { 04370 int i; 04371 (void) fprintf(vis_stdout,"Cluster Sequence = "); 04372 for (i=0; i<numRelation; i++) { 04373 (void) fprintf(vis_stdout, "%d ", bestCtrIdVector[i]); 04374 } 04375 (void) fprintf(vis_stdout,"\n"); 04376 } 04377 04378 FREE(bestCtrIdVector); 04379 } 04380 04381 04425 static array_t * 04426 UpdateInfoArrays(CtrInfo_t *ctrInfo, st_table *bddIdToBddTable, 04427 int *numSmoothVarsRemainingPtr, 04428 int *numIntroducedVarsRemainingPtr) 04429 { 04430 array_t *smoothVarBddArray; 04431 lsGen varItemListGen; 04432 int numSmoothVarsRemaining = *numSmoothVarsRemainingPtr; 04433 int numIntroducedVarsRemaining = *numIntroducedVarsRemainingPtr; 04434 VarItem_t *varItem; 04435 lsHandle varItemHandle; 04436 04437 smoothVarBddArray = array_alloc(bdd_t*, 0); 04438 varItemListGen = lsStart(ctrInfo->varItemList); 04439 while (lsNext(varItemListGen, &varItem, &varItemHandle) == 04440 LS_OK) { 04441 VarInfo_t *varInfo = varItem->varInfo; 04442 CtrItem_t *ctrItem; 04443 assert(varInfo->numCtr == lsLength(varInfo->ctrItemList)); 04444 lsRemoveItem(varItem->ctrItemHandle, &ctrItem); 04445 CtrItemStructFree(ctrItem); 04446 varInfo->numCtr--; 04447 lsRemoveItem(varItemHandle, &varItem); 04448 VarItemStructFree(varItem); 04449 04450 /* 04451 * If this variable is to be smoothed (domain or quantify type) and 04452 * the numCtr is 1, then it should be added to the smoothVarBddArray, 04453 * otherwise, the numCtr should be decreased by 1. 04454 * If the variable is of the range type then the number of introduced 04455 * vars remaining and the number of introduced vars should be 04456 * appropriately modified. 04457 */ 04458 if ((varInfo->varType == domainVar_c) || 04459 (varInfo->varType == quantifyVar_c)) { 04460 if (varInfo->numCtr == 0) { 04461 bdd_t *varBdd; 04462 st_lookup(bddIdToBddTable, (char *)(long)(varInfo->bddId), &varBdd); 04463 array_insert_last(bdd_t*, smoothVarBddArray, bdd_dup(varBdd)); 04464 numSmoothVarsRemaining--; 04465 ctrInfo->numLocalSmoothVars--; 04466 ctrInfo->numSmoothVars--; 04467 } 04468 else{ 04469 if (varInfo->numCtr == 1) { 04470 /* 04471 * We need to update the numLocalSmoothVars of the ctr 04472 * which depends on it. 04473 */ 04474 lsFirstItem(varInfo->ctrItemList, &ctrItem, LS_NH); 04475 ctrItem->ctrInfo->numLocalSmoothVars++; 04476 } 04477 /* 04478 * else varInfo->numCtr > 1 : Nothing to be done because neither it 04479 * can be quantified out, nor it is effecting any cost function. 04480 */ 04481 ctrInfo->numSmoothVars--; 04482 } 04483 } 04484 else{/* The variable is of range type, so need to appropriately modify the 04485 * numIntroducedVars of those clusters which contain this range 04486 * variable in their support. 04487 */ 04488 lsHandle ctrItemHandle; 04489 lsGen ctrItemListGen = lsStart(varInfo->ctrItemList); 04490 ctrInfo->numIntroducedVars--; 04491 while (lsNext(ctrItemListGen, &ctrItem, &ctrItemHandle) == LS_OK) { 04492 ctrItem->ctrInfo->numIntroducedVars--; 04493 lsRemoveItem(ctrItem->varItemHandle,&varItem); 04494 lsRemoveItem(ctrItemHandle,&ctrItem); 04495 VarItemStructFree(varItem); 04496 CtrItemStructFree(ctrItem); 04497 } 04498 lsFinish(ctrItemListGen); 04499 numIntroducedVarsRemaining--; 04500 varInfo->numCtr = 0; 04501 } 04502 assert(varInfo->numCtr == lsLength(varInfo->ctrItemList)); 04503 } 04504 lsFinish(varItemListGen); 04505 *numIntroducedVarsRemainingPtr = numIntroducedVarsRemaining; 04506 *numSmoothVarsRemainingPtr = numSmoothVarsRemaining; 04507 return smoothVarBddArray; 04508 } 04509 04510 04544 static float 04545 CalculateBenefit(CtrInfo_t *ctrInfo, int maxNumLocalSmoothVars, int 04546 maxNumSmoothVars, int maxIndex, int 04547 maxNumIntroducedVars, ImgTrmOption_t *option) 04548 { 04549 int W1, W2, W3, W4; 04550 float benefit; 04551 04552 W1 = option->W1; 04553 W2 = option->W2; 04554 W3 = option->W3; 04555 W4 = option->W4; 04556 04557 benefit = 0.0; 04558 benefit += (maxNumLocalSmoothVars ? 04559 ((float)W1 * ((float)ctrInfo->numLocalSmoothVars / 04560 (float)maxNumLocalSmoothVars)) : 0.0); 04561 04562 benefit += (maxNumSmoothVars ? 04563 ((float)W2 * ((float)ctrInfo->numSmoothVars / 04564 (float)maxNumSmoothVars)) : 0.0); 04565 04566 benefit += (maxIndex ? 04567 ((float)W3 * ((float)ctrInfo->maxSmoothVarIndex / 04568 (float)maxIndex)) : 0.0); 04569 04570 benefit -= (maxNumIntroducedVars ? 04571 ((float)W4 * ((float)ctrInfo->numIntroducedVars / 04572 (float)maxNumIntroducedVars)) : 0.0); 04573 04574 return benefit; 04575 } 04576 04588 static void 04589 PrintOption(Img_MethodType method, ImgTrmOption_t *option, FILE *fp) 04590 { 04591 if (method == Img_Iwls95_c) 04592 (void)fprintf(fp, "Printing Information about Image method: IWLS95\n"); 04593 else if (method == Img_Mlp_c) 04594 (void)fprintf(fp, "Printing Information about Image method: MLP\n"); 04595 else if (method == Img_Linear_c) 04596 (void)fprintf(fp, "Printing Information about Image method: LINEAR\n"); 04597 else 04598 assert(0); 04599 (void)fprintf(fp, 04600 "\tThreshold Value of Bdd Size For Creating Clusters = %d\n", 04601 option->clusterSize); 04602 (void)fprintf(fp, 04603 "\t\t(Use \"set image_cluster_size value\" to set this to desired value)\n"); 04604 (void)fprintf(fp, "\tVerbosity = %d\n", option->verbosity); 04605 (void)fprintf(fp, 04606 "\t\t(Use \"set image_verbosity value\" to set this to desired value)\n"); 04607 if (method == Img_Iwls95_c) { 04608 (void)fprintf(fp, "\tW1 =%3d W2 =%2d W3 =%2d W4 =%2d\n", 04609 option->W1, option->W2, option->W3, option->W4); 04610 (void)fprintf(fp, 04611 "\t\t(Use \"set image_W? value\" to set these to desired values)\n"); 04612 } 04613 } 04614 04626 static Iwls95Info_t * 04627 Iwls95InfoStructAlloc(Img_MethodType method) 04628 { 04629 Iwls95Info_t *info; 04630 info = ALLOC(Iwls95Info_t, 1); 04631 memset(info, 0, sizeof(Iwls95Info_t)); 04632 info->method = method; 04633 info->option = TrmGetOptions(); 04634 info->PIoption = ImgGetPartialImageOptions(); 04635 return info; 04636 } 04637 04647 static CtrInfo_t * 04648 CtrInfoStructAlloc(void) 04649 { 04650 CtrInfo_t *ctrInfo; 04651 ctrInfo = ALLOC(CtrInfo_t, 1); 04652 ctrInfo->ctrId = -1; 04653 ctrInfo->numLocalSmoothVars = 0; 04654 ctrInfo->numSmoothVars = 0; 04655 ctrInfo->maxSmoothVarIndex = -1; 04656 ctrInfo->numIntroducedVars = 0; 04657 ctrInfo->varItemList = lsCreate(); 04658 ctrInfo->ctrInfoListHandle = NULL; 04659 return ctrInfo; 04660 } 04661 04662 04672 static void 04673 CtrInfoStructFree(CtrInfo_t *ctrInfo) 04674 { 04675 lsDestroy(ctrInfo->varItemList, 0); 04676 FREE(ctrInfo); 04677 } 04678 04688 static VarInfo_t * 04689 VarInfoStructAlloc(void) 04690 { 04691 VarInfo_t *varInfo; 04692 varInfo = ALLOC(VarInfo_t, 1); 04693 varInfo->bddId = -1; 04694 varInfo->numCtr = 0; 04695 varInfo->varType = -1; 04696 varInfo->ctrItemList = lsCreate(); 04697 return varInfo; 04698 } 04699 04709 static void 04710 VarInfoStructFree(VarInfo_t *varInfo) 04711 { 04712 lsDestroy(varInfo->ctrItemList,0); 04713 FREE(varInfo); 04714 } 04715 04725 static void 04726 CtrItemStructFree(CtrItem_t *ctrItem) 04727 { 04728 FREE(ctrItem); 04729 } 04730 04740 static void 04741 VarItemStructFree(VarItem_t *varItem) 04742 { 04743 FREE(varItem); 04744 } 04745 04757 static int 04758 CtrInfoMaxIndexCompare(const void * p1, const void * p2) 04759 { 04760 CtrInfo_t **infoCtr1 = (CtrInfo_t **) p1; 04761 CtrInfo_t **infoCtr2 = (CtrInfo_t **) p2; 04762 return ((*infoCtr1)->maxSmoothVarIndex > (*infoCtr2)->maxSmoothVarIndex); 04763 } 04764 04765 /* ************************************************************************** 04766 * Debugging Related Routines. 04767 ***************************************************************************/ 04768 04769 04779 static void 04780 PrintCtrInfoStruct(CtrInfo_t *ctrInfo) 04781 { 04782 lsGen lsgen; 04783 VarItem_t *varItem; 04784 04785 (void) fprintf(vis_stdout,"Ctr ID = %d\tNumLocal = %d\tNumSmooth=%d\tNumIntro=%d\tmaxSmooth=%d\trank=%d\n", 04786 ctrInfo->ctrId, ctrInfo->numLocalSmoothVars, 04787 ctrInfo->numSmoothVars, ctrInfo->numIntroducedVars, 04788 ctrInfo->maxSmoothVarIndex, ctrInfo->rankMaxSmoothVarIndex); 04789 lsgen = lsStart(ctrInfo->varItemList); 04790 while (lsNext(lsgen, &varItem, NIL(lsHandle)) == LS_OK) { 04791 (void) fprintf(vis_stdout,"%d\t", varItem->varInfo->bddId); 04792 } 04793 lsFinish(lsgen); 04794 fprintf(vis_stdout,"\n"); 04795 } 04805 static void 04806 PrintVarInfoStruct(VarInfo_t *varInfo) 04807 { 04808 lsGen lsgen; 04809 CtrItem_t *ctrItem; 04810 04811 (void) fprintf(vis_stdout,"Var ID = %d\tNumCtr = %d\tVarType=%d\n", 04812 varInfo->bddId, varInfo->numCtr, varInfo->varType); 04813 lsgen = lsStart(varInfo->ctrItemList); 04814 while (lsNext(lsgen, &ctrItem, NIL(lsHandle)) == LS_OK) { 04815 (void) fprintf(vis_stdout,"%d\t", ctrItem->ctrInfo->ctrId); 04816 } 04817 lsFinish(lsgen); 04818 fprintf(vis_stdout,"\n"); 04819 } 04820 04840 static int 04841 CheckQuantificationSchedule(array_t *relationArray, 04842 array_t *arraySmoothVarBddArray) 04843 { 04844 int i, j; 04845 long varId; 04846 st_table *smoothVarTable, *supportTable; 04847 bdd_t *relation; 04848 array_t *smoothVarBddArray, *smoothVarBddIdArray; 04849 st_generator *stgen; 04850 04851 assert(array_n(relationArray) + 1 == array_n(arraySmoothVarBddArray)); 04852 04853 smoothVarTable = st_init_table(st_numcmp, st_numhash); 04854 04855 smoothVarBddArray = array_fetch(array_t*, arraySmoothVarBddArray, 0); 04856 smoothVarBddIdArray = bdd_get_varids(smoothVarBddArray); 04857 for (j=0; j<array_n(smoothVarBddIdArray); j++) { 04858 varId = (long) array_fetch(int, smoothVarBddIdArray, j); 04859 assert(st_insert(smoothVarTable, (char *) varId, NIL(char))==0); 04860 } 04861 array_free(smoothVarBddIdArray); 04862 04863 for (i=0; i<array_n(relationArray); i++) { 04864 relation = array_fetch(bdd_t*, relationArray, i); 04865 supportTable = ImgBddGetSupportIdTable(relation); 04866 /* 04867 * Check that none of the variables in the support have already been 04868 * quantified. 04869 */ 04870 st_foreach_item(supportTable, stgen, &varId, NULL) { 04871 assert(st_is_member(smoothVarTable, (char *) varId) == 0); 04872 04873 } 04874 st_free_table(supportTable); 04875 if (i == (array_n(relationArray)-1)) { 04876 /* Since last element of arraySmoothVarBddArray has all the 04877 * smooth variables, it will not satisfy the condition. 04878 */ 04879 continue; 04880 } 04881 04882 /* 04883 * Put each of the variables quantified at this step in the 04884 * smoothVarTable. And check that none of these smooth variables 04885 * have been introduced before. 04886 */ 04887 smoothVarBddArray = array_fetch(array_t*, arraySmoothVarBddArray, i + 1); 04888 smoothVarBddIdArray = bdd_get_varids(smoothVarBddArray); 04889 for (j=0; j<array_n(smoothVarBddIdArray); j++) { 04890 varId = (long) array_fetch(int, smoothVarBddIdArray, j); 04891 assert(st_insert(smoothVarTable, (char *) varId, NIL(char))==0); 04892 } 04893 array_free(smoothVarBddIdArray); 04894 } 04895 st_free_table(smoothVarTable); 04896 return 1; 04897 } 04898 04908 static int 04909 CheckCtrInfoArray(array_t *ctrInfoArray, int numDomainVars, int 04910 numQuantifyVars, int numRangeVars) 04911 { 04912 int i; 04913 for (i=0; i<array_n(ctrInfoArray); i++) { 04914 CheckCtrInfo(array_fetch(CtrInfo_t *, ctrInfoArray, i), 04915 numDomainVars, numQuantifyVars, numRangeVars); 04916 } 04917 return 1; 04918 } 04919 04929 static int 04930 CheckCtrInfo(CtrInfo_t *ctrInfo, int numDomainVars, 04931 int numQuantifyVars, int numRangeVars) 04932 { 04933 assert(ctrInfo->numLocalSmoothVars <= (numDomainVars + 04934 numQuantifyVars)); 04935 assert(ctrInfo->numSmoothVars <= (numDomainVars + 04936 numQuantifyVars)); 04937 assert(ctrInfo->numIntroducedVars <= numRangeVars); 04938 assert(lsLength(ctrInfo->varItemList) == 04939 (ctrInfo->numSmoothVars+ctrInfo->numIntroducedVars)); 04940 return 1; 04941 } 04942 04952 static int 04953 CheckVarInfoArray(array_t *varInfoArray, int numRelation) 04954 { 04955 int i; 04956 for (i=0; i<array_n(varInfoArray); i++) { 04957 VarInfo_t *varInfo; 04958 varInfo = array_fetch(VarInfo_t *, varInfoArray, i); 04959 assert(varInfo->numCtr <= numRelation); 04960 assert(varInfo->varType >= 0); 04961 assert(varInfo->varType <= 2); 04962 assert(lsLength(varInfo->ctrItemList) == varInfo->numCtr); 04963 } 04964 return 1; 04965 } 04966 04967 /* **************************************************************** 04968 * Utility Routines. 04969 ****************************************************************/ 04970 04980 static array_t * 04981 BddArrayDup(array_t *bddArray) 04982 { 04983 int i; 04984 array_t *resultArray; 04985 bdd_t *bdd; 04986 resultArray = array_alloc(bdd_t*, 0); 04987 arrayForEachItem(bdd_t *, bddArray, i, bdd) { 04988 array_insert_last(bdd_t*, resultArray, bdd_dup(bdd)); 04989 } 04990 return resultArray; 04991 } 04992 04993 static array_t * 04994 BddArrayArrayDup(array_t *bddArray) 04995 { 04996 int i; 04997 array_t *resultArray; 04998 array_t *arr, *tarr; 04999 05000 resultArray = array_alloc(bdd_t*, 0); 05001 arrayForEachItem(array_t *, bddArray, i, arr) { 05002 tarr = BddArrayDup(arr); 05003 array_insert_last(array_t*, resultArray, tarr); 05004 } 05005 return resultArray; 05006 } 05007 05008 05032 static mdd_t * 05033 BddLinearAndSmooth(mdd_manager *mddManager, 05034 bdd_t *fromSet, 05035 array_t *relationArray, 05036 array_t *arraySmoothVarBddArray, 05037 array_t *smoothVarCubeArray, 05038 int verbosity, 05039 ImgPartialImageOption_t *PIoption, 05040 boolean *partial, boolean lazySiftFlag) 05041 { 05042 int i; 05043 int intermediateSize = 0; 05044 int maxSize = 0; 05045 mdd_t *newProduct; 05046 boolean partialImageAllowed; 05047 bdd_t *product = fromSet; 05048 int clippingDepth = -1; 05049 int partialImageThreshold = 0; 05050 int partialImageMethod = Img_PIApprox_c; 05051 array_t *smoothVarBddArray = NIL(array_t); 05052 mdd_t *smoothVarCube = NIL(mdd_t); 05053 int nvars = -2; 05054 05055 assert(CheckQuantificationSchedule(relationArray, arraySmoothVarBddArray)); 05056 05057 /* Copy (*partial) which indicates whether partial image is allowed. */ 05058 /* (*partial) is set to TRUE later if partial image was performed. */ 05059 partialImageAllowed = *partial; 05060 *partial = FALSE; 05061 05062 /* partial image options */ 05063 if (PIoption != NULL) { 05064 nvars = PIoption->nvars; 05065 clippingDepth = (int) (PIoption->clippingDepthFrac*nvars); 05066 partialImageThreshold = PIoption->partialImageThreshold; 05067 partialImageMethod = PIoption->partialImageMethod; 05068 } 05069 05070 if (fromSet) { 05071 if (smoothVarCubeArray) { 05072 smoothVarCube = array_fetch(mdd_t*, smoothVarCubeArray, 0); 05073 if (bdd_is_tautology(smoothVarCube, 1)) 05074 product = bdd_dup(fromSet); 05075 else 05076 product = bdd_smooth_with_cube(fromSet, smoothVarCube); 05077 } else { 05078 smoothVarBddArray = array_fetch(array_t*, arraySmoothVarBddArray, 0); 05079 if (array_n(smoothVarBddArray) == 0) 05080 product = bdd_dup(fromSet); 05081 else 05082 product = bdd_smooth(fromSet, smoothVarBddArray); 05083 } 05084 } else 05085 product = bdd_one(mddManager); 05086 05087 for (i=0; i<array_n(relationArray); i++) { 05088 bdd_t *relation, *tmpProduct; 05089 boolean allowClipping = FALSE; 05090 05091 /* fetch relation to intersect with the next product. */ 05092 relation = array_fetch(bdd_t*, relationArray, i); 05093 if (smoothVarCubeArray) 05094 smoothVarCube = array_fetch(mdd_t*, smoothVarCubeArray, i + 1); 05095 else 05096 smoothVarBddArray = array_fetch(array_t*, arraySmoothVarBddArray, i + 1); 05097 05098 /* Clipping allowed only if clipping option is specified, partial 05099 * image is allowed, clipping depth is meaningful and sizes are not 05100 * under control. 05101 */ 05102 if ((PIoption != NULL) && 05103 (partialImageAllowed) && 05104 (partialImageMethod == Img_PIClipping_c) && 05105 (nvars >= clippingDepth)) { 05106 /* if conjuncts too small, dont clip. */ 05107 if ((bdd_size(product) > partialImageThreshold) || 05108 (bdd_size(relation) > partialImageThreshold)) { 05109 allowClipping = TRUE; 05110 } 05111 } 05112 05113 if (lazySiftFlag) { 05114 int j; 05115 int nVars = bdd_num_vars(mddManager); 05116 var_set_t *sup_ids = bdd_get_support(relation); 05117 05118 for (j = 0; j < nVars; j++) { 05119 if (var_set_get_elt(sup_ids, j) == 1) { 05120 if (bdd_is_ns_var(mddManager, j)) 05121 bdd_reset_var_to_be_grouped(mddManager, j); 05122 else if (!bdd_is_ps_var(mddManager, j)) 05123 bdd_reset_var_to_be_grouped(mddManager, j); 05124 } 05125 } 05126 var_set_free(sup_ids); 05127 } 05128 05129 /* if clipping not allowed, do regular and-abstract */ 05130 if (!allowClipping) { 05131 if (smoothVarCubeArray) { 05132 if (bdd_is_tautology(smoothVarCube, 1)) 05133 tmpProduct = bdd_and(product, relation, 1, 1); 05134 else { 05135 tmpProduct = bdd_and_smooth_with_cube(product, relation, 05136 smoothVarCube); 05137 } 05138 } else { 05139 if (array_n(smoothVarBddArray) == 0) 05140 tmpProduct = bdd_and(product, relation, 1, 1); 05141 else 05142 tmpProduct = bdd_and_smooth(product, relation, smoothVarBddArray); 05143 } 05144 } else { 05145 /* the conditions to clip are that partial image is allowed, 05146 * partial image method is set to clipping, clipping depth 05147 * is meaningful and either the product or the relation is 05148 * larger than the partial image threshold. 05149 */ 05150 if (smoothVarCubeArray) 05151 smoothVarBddArray = array_fetch(array_t*, arraySmoothVarBddArray, i+1); 05152 tmpProduct = ComputeClippedAndAbstract(product, relation, 05153 smoothVarBddArray, nvars, 05154 clippingDepth, partial, verbosity); 05155 } 05156 05157 if (lazySiftFlag) { 05158 int k, index; 05159 bdd_t *svar; 05160 05161 if (smoothVarCubeArray) 05162 smoothVarBddArray = array_fetch(array_t*, arraySmoothVarBddArray, i+1); 05163 for (k = 0; k < array_n(smoothVarBddArray); k++) { 05164 svar = array_fetch(bdd_t *, smoothVarBddArray, k); 05165 index = bdd_top_var_id(svar); 05166 bdd_set_var_to_be_grouped(mddManager, index); 05167 } 05168 } 05169 05170 bdd_free(product); 05171 product = tmpProduct; 05172 05173 /* subset if necessary */ 05174 if ((i != array_n(relationArray)) && 05175 (partialImageAllowed) && 05176 (partialImageMethod == Img_PIApprox_c)) { 05177 intermediateSize = bdd_size(product); 05178 /* approximate if the intermediate product is too large. */ 05179 if (intermediateSize > partialImageThreshold) { 05180 if (verbosity >= 2) { 05181 (void) fprintf(vis_stdout, "Intermediate Block %d Size = %10d\n", i, 05182 intermediateSize); 05183 } 05184 newProduct = ComputeSubsetOfIntermediateProduct(product, PIoption); 05185 if (verbosity >= 2) { 05186 if (!bdd_equal(newProduct, product)) { 05187 (void)fprintf(vis_stdout, 05188 "Intermediate Block Subset Size = %10d\n", 05189 bdd_size(newProduct)); 05190 } else { 05191 (void)fprintf(vis_stdout, "Intermediate Block unchanged\n"); 05192 } 05193 } 05194 /* record if partial image occurred */ 05195 if (!bdd_equal(newProduct, product)) { 05196 *partial = TRUE; 05197 intermediateSize = bdd_size(product); 05198 } 05199 bdd_free(product); 05200 product = newProduct; 05201 } 05202 } 05203 05204 /* keep track of intermediate product size */ 05205 if (verbosity >= 2) { 05206 if ((partialImageMethod != Img_PIApprox_c) || 05207 (!partialImageAllowed) || 05208 ( i == array_n(relationArray))) { 05209 intermediateSize = bdd_size(product); 05210 } 05211 if (maxSize < intermediateSize) { 05212 maxSize = intermediateSize; 05213 } 05214 } 05215 } 05216 if (lazySiftFlag) { 05217 int nVars = bdd_num_vars(mddManager); 05218 for (i = 0; i < nVars; i++) { 05219 if (bdd_is_ps_var(mddManager, i)) 05220 bdd_reset_var_to_be_grouped(mddManager, i); 05221 else 05222 bdd_set_var_to_be_grouped(mddManager, i); 05223 } 05224 } 05225 if (verbosity >= 2) { 05226 (void)fprintf(vis_stdout, 05227 "Max. BDD size for intermediate product = %10d\n", maxSize); 05228 }/* for all clusters */ 05229 05230 return product; 05231 } /* end of BddLinearAndSmooth */ 05232 05246 static void 05247 HashIdToBddTable(st_table *table, array_t *idArray, 05248 array_t *bddArray) 05249 { 05250 int i; 05251 for (i=0; i<array_n(idArray); i++) { 05252 int id; 05253 bdd_t *bdd; 05254 id = array_fetch(int, idArray, i); 05255 bdd = array_fetch(bdd_t*, bddArray, i); 05256 st_insert(table, (char*)(long)id, (char *)bdd); 05257 } 05258 } 05259 05260 05274 static void 05275 PrintSmoothIntroducedCount(array_t *clusterArray, array_t 05276 **arraySmoothVarBddArrayPtr, 05277 array_t *psBddIdArray, array_t 05278 *nsBddIdArray) 05279 { 05280 int i,j; 05281 st_table *nsBddIdTable, *supportTable, *psBddIdTable; 05282 bdd_t *trans; 05283 int introducedCount; 05284 bdd_t *tmp; 05285 st_generator *stgen; 05286 long varId; 05287 array_t *smoothVarBddArray, *arraySmoothVarBddArray; 05288 array_t *smoothVarBddIdArray = NIL(array_t); 05289 int psCount, piNdCount; 05290 05291 if (arraySmoothVarBddArrayPtr == NIL(array_t*)) 05292 arraySmoothVarBddArray = NIL(array_t); 05293 else 05294 arraySmoothVarBddArray = *arraySmoothVarBddArrayPtr; 05295 05296 (void) fprintf(vis_stdout, "**********************************************\n"); 05297 nsBddIdTable = st_init_table(st_numcmp, st_numhash); 05298 for (i=0; i<array_n(nsBddIdArray); i++) 05299 st_insert(nsBddIdTable, (char *)(long) array_fetch(int, nsBddIdArray, i), 05300 (char *) NULL); 05301 psBddIdTable = st_init_table(st_numcmp, st_numhash); 05302 for (i=0; i<array_n(psBddIdArray); i++) 05303 st_insert(psBddIdTable, (char *)(long) array_fetch(int, psBddIdArray, i), 05304 (char *) NULL); 05305 05306 for (i=0; i<=array_n(clusterArray)-1; i++) { 05307 trans = array_fetch(bdd_t*, clusterArray, i); 05308 supportTable = ImgBddGetSupportIdTable(trans); 05309 psCount = 0; 05310 piNdCount = 0; 05311 if (arraySmoothVarBddArray != NIL(array_t)) { 05312 smoothVarBddArray = array_fetch(array_t*, arraySmoothVarBddArray, i); 05313 smoothVarBddIdArray = bdd_get_varids(smoothVarBddArray); 05314 for (j=0; j<array_n(smoothVarBddIdArray);j++) { 05315 if (st_is_member(psBddIdTable, (char *)(long) 05316 array_fetch(int, smoothVarBddIdArray, j))) 05317 psCount++; 05318 else 05319 piNdCount++; 05320 } 05321 } 05322 introducedCount = 0; 05323 st_foreach_item(nsBddIdTable, stgen, &varId, &tmp) { 05324 if (st_is_member(supportTable, (char *)varId)) { 05325 introducedCount++; 05326 st_delete(nsBddIdTable,&varId, NULL); 05327 } 05328 } 05329 (void)fprintf(vis_stdout, 05330 "Tr no = %3d\tSmooth PS # = %3d\tSmooth PI # = %3d\tIntroduced # = %d\n", i, 05331 psCount, piNdCount, introducedCount); 05332 st_free_table(supportTable); 05333 array_free(smoothVarBddIdArray); 05334 } 05335 st_free_table(nsBddIdTable); 05336 st_free_table(psBddIdTable); 05337 } 05338 05348 static void 05349 PrintBddIdFromBddArray(array_t *bddArray) 05350 { 05351 int i; 05352 array_t *idArray = bdd_get_varids(bddArray); 05353 fprintf(vis_stdout, 05354 "**************** printing bdd ids from the bdd array ***********\n"); 05355 fprintf(vis_stdout,"%d::\t", array_n(idArray)); 05356 for (i=0;i<array_n(idArray); i++) { 05357 fprintf(vis_stdout," %d ", (int)array_fetch(int, idArray, i)); 05358 } 05359 fprintf(vis_stdout,"\n******************\n"); 05360 array_free(idArray); 05361 return; 05362 } 05363 05373 static void 05374 PrintBddIdTable(st_table *idTable) 05375 { 05376 st_generator *stgen; 05377 long varId; 05378 fprintf(vis_stdout, 05379 "**************** printing bdd ids from the id table ***********\n"); 05380 fprintf(vis_stdout,"%d::\t", st_count(idTable)); 05381 st_foreach_item(idTable, stgen, &varId, NIL(char *)) { 05382 fprintf(vis_stdout," %d ", (int) varId); 05383 } 05384 fprintf(vis_stdout,"\n******************\n"); 05385 return; 05386 } 05387 05399 static void 05400 PartitionTraverseRecursively(mdd_manager *mddManager, vertex_t *vertex, 05401 int mddId, st_table *vertexTable, 05402 array_t *relationArray, 05403 st_table *domainQuantifyVarMddIdTable, 05404 array_t *quantifyVarMddIdArray) 05405 { 05406 Mvf_Function_t *mvf; 05407 lsList faninEdges; 05408 lsGen gen; 05409 vertex_t *faninVertex; 05410 edge_t *faninEdge; 05411 array_t *varBddRelationArray; 05412 05413 if (st_is_member(vertexTable, (char *)vertex)) return; 05414 st_insert(vertexTable, (char *)vertex, NIL(char)); 05415 if (mddId != -1) { /* This is not the next state function node */ 05416 /* There is an mdd variable associated with this vertex */ 05417 array_insert_last(int, quantifyVarMddIdArray, mddId); 05418 mvf = Part_VertexReadFunction(vertex); 05419 /*relation = Mvf_FunctionBuildRelationWithVariable(mvf, mddId);*/ 05420 varBddRelationArray = mdd_fn_array_to_bdd_rel_array(mddManager, mddId, mvf); 05421 array_append(relationArray, varBddRelationArray); 05422 array_free(varBddRelationArray); 05423 /*array_insert_last(mdd_t *, relationArray, relation);*/ 05424 } 05425 faninEdges = g_get_in_edges(vertex); 05426 if (lsLength(faninEdges) == 0) return; 05427 lsForEachItem(faninEdges, gen, faninEdge) { 05428 faninVertex = g_e_source(faninEdge); 05429 mddId = Part_VertexReadMddId(faninVertex); 05430 if (st_is_member(domainQuantifyVarMddIdTable, (char *)(long)mddId)) { 05431 /* This is either domain var or quantify var */ 05432 /* continue */ 05433 continue; 05434 } 05435 PartitionTraverseRecursively(mddManager, faninVertex, mddId, vertexTable, 05436 relationArray, 05437 domainQuantifyVarMddIdTable, 05438 quantifyVarMddIdArray); 05439 } 05440 } 05441 05442 05452 static void 05453 PrintPartitionRecursively(vertex_t *vertex, st_table *vertexTable, int indent) 05454 { 05455 int i; 05456 lsList faninEdges; 05457 lsGen gen; 05458 vertex_t *faninVertex; 05459 edge_t *faninEdge; 05460 05461 if (st_is_member(vertexTable, (char *)vertex)) return; 05462 st_insert(vertexTable, (char *)vertex, NIL(char)); 05463 for(i=0; i<= indent; i++) fprintf(vis_stdout," "); 05464 fprintf(vis_stdout,"%s %d\n", Part_VertexReadName(vertex), 05465 Part_VertexReadMddId(vertex)); 05466 faninEdges = g_get_in_edges(vertex); 05467 if (lsLength(faninEdges) == 0) return; 05468 lsForEachItem(faninEdges, gen, faninEdge) { 05469 faninVertex = g_e_source(faninEdge); 05470 PrintPartitionRecursively(faninVertex, vertexTable,indent+2); 05471 } 05472 } 05473 05492 static bdd_t * 05493 RecomputeImageIfNecessary(ImgFunctionData_t *functionData, 05494 mdd_manager *mddManager, 05495 bdd_t *domainSubset, 05496 array_t *relationArray, 05497 array_t *arraySmoothVarBddArray, 05498 array_t *smoothVarCubeArray, 05499 int verbosity, 05500 ImgPartialImageOption_t *PIoption, 05501 array_t *toCareSetArray, 05502 boolean *partial, boolean lazySiftFlag) 05503 { 05504 int oldPIThreshold = 0, oldPISize; 05505 double oldClippingFrac = IMG_PI_CLIP_DEPTH; 05506 boolean realRequired = FALSE; 05507 mdd_t *image = NIL(mdd_t); 05508 05509 /* relax values to compute a non-trivial partial image */ 05510 if (PIoption->partialImageMethod == Img_PIApprox_c) { 05511 oldPIThreshold = PIoption->partialImageThreshold; 05512 PIoption->partialImageThreshold *= 2; 05513 if (!PIoption->partialImageThreshold) 05514 PIoption->partialImageThreshold = IMG_PI_SP_THRESHOLD; 05515 } else if (PIoption->partialImageMethod == Img_PIClipping_c) { 05516 oldClippingFrac = PIoption->clippingDepthFrac; 05517 PIoption->clippingDepthFrac = 05518 (PIoption->clippingDepthFrac < IMG_PI_CLIP_DEPTH_FINAL) ? 05519 IMG_PI_CLIP_DEPTH_FINAL : PIoption->clippingDepthFrac; 05520 } 05521 if (((PIoption->partialImageMethod == Img_PIClipping_c) && 05522 (oldClippingFrac != PIoption->clippingDepthFrac)) || 05523 (PIoption->partialImageMethod == Img_PIApprox_c)) { 05524 if (verbosity >= 2) { 05525 fprintf(vis_stdout, 05526 "IMG: No new states, computing image again with relaxed thresholds.\n"); 05527 if (PIoption->partialImageMethod == Img_PIApprox_c) { 05528 fprintf(vis_stdout, "IMG: Relaxed hd_partial_image_threshold to %d\n", 05529 PIoption->partialImageThreshold); 05530 } else if (PIoption->partialImageMethod == Img_PIClipping_c) { 05531 fprintf(vis_stdout, 05532 "IMG: Relaxed hd_partial_image_clipping_depth to %g\n", 05533 PIoption->clippingDepthFrac); 05534 } 05535 } 05536 05537 *partial = TRUE; 05538 /* if values were relaxed, compute image again. */ 05539 image = BddLinearAndSmooth(mddManager, domainSubset, relationArray, 05540 arraySmoothVarBddArray, smoothVarCubeArray, 05541 verbosity, PIoption, partial, lazySiftFlag); 05542 05543 /* check if new states were produced. */ 05544 if (*partial) { 05545 if (bdd_leq_array(image, toCareSetArray, 1, 0)) { 05546 bdd_free(image); 05547 if (PIoption->partialImageMethod == Img_PIApprox_c) { 05548 /* relax approximation values some more. */ 05549 oldPISize = PIoption->partialImageSize; 05550 PIoption->partialImageSize *= 2; 05551 if (!PIoption->partialImageSize) 05552 PIoption->partialImageSize = IMG_PI_SP_THRESHOLD; 05553 05554 if (verbosity >= 2) { 05555 fprintf(vis_stdout, 05556 "IMG: No new states, computing image again with relaxed thresholds.\n"); 05557 fprintf(vis_stdout, "IMG: Relaxed hd_partial_image_size to %d\n", 05558 PIoption->partialImageSize); 05559 } 05560 05561 *partial = TRUE; 05562 image = BddLinearAndSmooth(mddManager, domainSubset, relationArray, 05563 arraySmoothVarBddArray, smoothVarCubeArray, 05564 verbosity, PIoption, partial, 05565 lazySiftFlag); 05566 PIoption->partialImageSize = oldPISize; 05567 05568 /* check if new states were produced. */ 05569 if (*partial) { 05570 if (bdd_leq_array(image, toCareSetArray, 1, 0)) { 05571 bdd_free(image); 05572 realRequired = TRUE; 05573 } 05574 } 05575 } else if (PIoption->partialImageMethod == Img_PIClipping_c) { 05576 /* compute real image since clipping depth cannot be increased. */ 05577 realRequired = TRUE; 05578 } 05579 } 05580 } /* require recomputation */ 05581 } else { /* clipping depth could not be increased. */ 05582 /* compute real image since clipping depth cannot be increased. */ 05583 realRequired = TRUE; 05584 } 05585 05586 /* reset the values to the orginal values. */ 05587 if (PIoption->partialImageMethod == Img_PIClipping_c) { 05588 PIoption->clippingDepthFrac = oldClippingFrac; 05589 } else if (PIoption->partialImageMethod == Img_PIApprox_c) { 05590 PIoption->partialImageThreshold = oldPIThreshold; 05591 } 05592 /* if the actual image is required compute it. */ 05593 if (realRequired) { 05594 if (verbosity >= 2) { 05595 fprintf(vis_stdout, "IMG: No new states, computing exact image.\n"); 05596 } 05597 *partial = FALSE; 05598 image = BddLinearAndSmooth(mddManager, domainSubset, relationArray, 05599 arraySmoothVarBddArray, smoothVarCubeArray, 05600 verbosity, PIoption, partial, lazySiftFlag); 05601 assert(!(*partial)); 05602 } 05603 05604 return (image); 05605 } /* end of RecomputeImageIfNecessary */ 05606 05607 05617 static bdd_t * 05618 ComputeSubsetOfIntermediateProduct(bdd_t *product, 05619 ImgPartialImageOption_t *PIoption) 05620 { 05621 int partialImageSize = PIoption->partialImageSize; 05622 int nvars = PIoption->nvars; 05623 bdd_t *newProduct; 05624 05625 switch (PIoption->partialImageApproxMethod) { 05626 case BDD_APPROX_HB: 05627 { 05628 int tempSize; 05629 tempSize = (partialImageSize < IMG_PI_SP_THRESHOLD) ? 05630 IMG_PI_SP_THRESHOLD : partialImageSize; 05631 newProduct = bdd_approx_hb(product, 05632 (bdd_approx_dir_t)BDD_UNDER_APPROX, 05633 nvars, tempSize); 05634 break; 05635 } 05636 case BDD_APPROX_SP: 05637 { 05638 int tempSize; 05639 tempSize = (partialImageSize < IMG_PI_SP_THRESHOLD) ? 05640 IMG_PI_SP_THRESHOLD : partialImageSize; 05641 newProduct = bdd_approx_sp(product, 05642 (bdd_approx_dir_t)BDD_UNDER_APPROX, 05643 nvars, tempSize, 0); 05644 break; 05645 } 05646 case BDD_APPROX_UA: 05647 newProduct = bdd_approx_ua(product, 05648 (bdd_approx_dir_t)BDD_UNDER_APPROX, 05649 nvars, partialImageSize, 05650 0, PIoption->quality); 05651 break; 05652 case BDD_APPROX_RUA: 05653 newProduct = bdd_approx_remap_ua(product, 05654 (bdd_approx_dir_t)BDD_UNDER_APPROX, 05655 0, partialImageSize, 05656 PIoption->quality); 05657 break; 05658 case BDD_APPROX_COMP: 05659 { 05660 newProduct = bdd_approx_compress(product, 05661 (bdd_approx_dir_t)BDD_UNDER_APPROX, 05662 nvars, partialImageSize); 05663 } 05664 break; 05665 case BDD_APPROX_BIASED_RUA: 05666 newProduct = bdd_approx_biased_rua(product, 05667 (bdd_approx_dir_t)BDD_UNDER_APPROX, 05668 PIoption->bias, 05669 0, partialImageSize, 05670 PIoption->quality, 05671 PIoption->qualityBias); 05672 break; 05673 default : 05674 newProduct = bdd_approx_remap_ua(product, 05675 (bdd_approx_dir_t)BDD_UNDER_APPROX, 05676 0, partialImageSize, 05677 PIoption->quality); 05678 break; 05679 } 05680 return newProduct; 05681 } /* end of ComputeSubsetOfIntermediateProduct */ 05682 05693 static bdd_t * 05694 ComputeClippedAndAbstract(bdd_t *product, 05695 bdd_t *relation, 05696 array_t *smoothVarBddArray, 05697 int nvars, 05698 int clippingDepth, 05699 boolean *partial, 05700 int verbosity) 05701 { 05702 bdd_t *tmpProduct; 05703 05704 /* compute clipped image */ 05705 tmpProduct = bdd_clipping_and_smooth(product, relation, 05706 smoothVarBddArray, clippingDepth, 0); 05707 /* if product is zero, compute clipped image with increased 05708 * clipping depth 05709 */ 05710 if (bdd_is_tautology(tmpProduct, 0)) { 05711 bdd_free(tmpProduct); 05712 tmpProduct = bdd_clipping_and_smooth(product, relation, 05713 smoothVarBddArray, 05714 (int) (nvars*IMG_PI_CLIP_DEPTH_FINAL), 05715 0); 05716 05717 /* if clipped image is zero, compute unclipped image */ 05718 if (bdd_is_tautology(tmpProduct, 0)) { 05719 if (verbosity >= 2) { 05720 fprintf(vis_stdout, 05721 "IMG: Clipping failed, computing exact and-abstract\n"); 05722 } 05723 bdd_free(tmpProduct); 05724 tmpProduct = bdd_and_smooth(product, relation, 05725 smoothVarBddArray); 05726 } else *partial = TRUE; 05727 05728 } else *partial = TRUE; 05729 05730 return tmpProduct; 05731 } /* end of ComputeClippedAndAbstract */ 05732 05733 05743 static array_t * 05744 CopyArrayBddArray(array_t *arrayBddArray) 05745 { 05746 int i, j; 05747 array_t *newArrayBddArray = array_alloc(array_t *, 0); 05748 array_t *bddArray, *newBddArray; 05749 mdd_t *bdd; 05750 05751 for (i = 0; i < array_n(arrayBddArray); i++) { 05752 bddArray = array_fetch(array_t *, arrayBddArray, i); 05753 newBddArray = array_alloc(mdd_t *, 0); 05754 for (j = 0; j < array_n(bddArray); j++) { 05755 bdd = array_fetch(mdd_t *, bddArray, j); 05756 array_insert(mdd_t *, newBddArray, j, bdd_dup(bdd)); 05757 } 05758 array_insert(array_t *, newArrayBddArray, i, newBddArray); 05759 } 05760 05761 return(newArrayBddArray); 05762 } 05763 05764 05774 static void 05775 PrintPartitionedTransitionRelation(mdd_manager *mddManager, 05776 Iwls95Info_t *info, 05777 Img_DirectionType directionType) 05778 { 05779 array_t *relationArray; 05780 array_t *arraySmoothVarBddArray; 05781 05782 if (directionType == Img_Forward_c) { 05783 relationArray = info->fwdClusteredRelationArray; 05784 arraySmoothVarBddArray = info->fwdArraySmoothVarBddArray; 05785 } else if (directionType == Img_Backward_c) { 05786 relationArray = info->bwdClusteredRelationArray; 05787 arraySmoothVarBddArray = info->bwdArraySmoothVarBddArray; 05788 } else { 05789 return; 05790 } 05791 05792 ImgPrintPartitionedTransitionRelation(mddManager, relationArray, 05793 arraySmoothVarBddArray); 05794 } 05795 05796 05806 static void 05807 ReorderPartitionedTransitionRelation(Iwls95Info_t *info, 05808 ImgFunctionData_t *functionData, 05809 Img_DirectionType directionType) 05810 { 05811 array_t *domainVarMddIdArray = functionData->domainVars; 05812 array_t *rangeVarMddIdArray = functionData->rangeVars; 05813 array_t *quantifyVarMddIdArray = array_dup(functionData->quantifyVars); 05814 graph_t *mddNetwork = functionData->mddNetwork; 05815 mdd_manager *mddManager = Part_PartitionReadMddManager(mddNetwork); 05816 array_t *rangeVarBddArray, *domainVarBddArray, *quantifyVarBddArray; 05817 array_t *clusteredRelationArray; 05818 st_table *varsTable = st_init_table(st_numcmp, st_numhash); 05819 int i, j, k, mddId; 05820 array_t *smoothVarBddArray, *arraySmoothVarBddArray; 05821 mdd_t *mdd; 05822 array_t *supportIdArray; 05823 05824 /* Finds the variables which are neither state variable nor primary input 05825 * from previous smooth variable array, and put those variable into 05826 * quantify variable array. 05827 */ 05828 for (i =0 ; i< array_n(domainVarMddIdArray); i++) { 05829 mddId = array_fetch(int, domainVarMddIdArray, i); 05830 st_insert(varsTable, (char *)(long)mddId, NIL(char)); 05831 } 05832 for (i = 0; i < array_n(rangeVarMddIdArray); i++) { 05833 mddId = array_fetch(int, rangeVarMddIdArray, i); 05834 st_insert(varsTable, (char *)(long)mddId, NIL(char)); 05835 } 05836 for (i = 0; i < array_n(quantifyVarMddIdArray); i++) { 05837 mddId = array_fetch(int, quantifyVarMddIdArray, i); 05838 st_insert(varsTable, (char *)(long)mddId, NIL(char)); 05839 } 05840 if (directionType == Img_Forward_c || directionType == Img_Both_c) 05841 arraySmoothVarBddArray = info->fwdArraySmoothVarBddArray; 05842 else 05843 arraySmoothVarBddArray = info->bwdArraySmoothVarBddArray; 05844 for (i = 0; i < array_n(arraySmoothVarBddArray); i++) { 05845 smoothVarBddArray = array_fetch(array_t *, arraySmoothVarBddArray, i); 05846 for (j = 0; j < array_n(smoothVarBddArray); j++) { 05847 mdd = array_fetch(mdd_t *, smoothVarBddArray, j); 05848 supportIdArray = mdd_get_support(mddManager, mdd); 05849 for (k = 0; k < array_n(supportIdArray); k++) { 05850 mddId = array_fetch(int, supportIdArray, k); 05851 if (!st_lookup(varsTable, (char *)(long)mddId, NIL(char *))) { 05852 array_insert_last(int, quantifyVarMddIdArray, mddId); 05853 st_insert(varsTable, (char *)(long)mddId, NIL(char)); 05854 } 05855 } 05856 array_free(supportIdArray); 05857 } 05858 } 05859 st_free_table(varsTable); 05860 05861 /* Get the Bdds from Mdd Ids */ 05862 rangeVarBddArray = functionData->rangeBddVars; 05863 domainVarBddArray = functionData->domainBddVars; 05864 quantifyVarBddArray = mdd_id_array_to_bdd_array(mddManager, 05865 quantifyVarMddIdArray); 05866 array_free(quantifyVarMddIdArray); 05867 05868 if (directionType == Img_Forward_c || directionType == Img_Both_c) { 05869 clusteredRelationArray = info->fwdClusteredRelationArray; 05870 mdd_array_array_free(info->fwdArraySmoothVarBddArray); 05871 info->fwdClusteredRelationArray = NIL(array_t); 05872 info->fwdArraySmoothVarBddArray = NIL(array_t); 05873 if (info->method == Img_Iwls95_c) { 05874 OrderRelationArray(mddManager, clusteredRelationArray, 05875 domainVarBddArray, quantifyVarBddArray, 05876 rangeVarBddArray, info->option, 05877 &info->fwdClusteredRelationArray, 05878 &info->fwdArraySmoothVarBddArray); 05879 } else if (info->method == Img_Mlp_c) { 05880 ImgMlpOrderRelationArray(mddManager, clusteredRelationArray, 05881 domainVarBddArray, quantifyVarBddArray, 05882 rangeVarBddArray, Img_Forward_c, 05883 &info->fwdClusteredRelationArray, 05884 &info->fwdArraySmoothVarBddArray, 05885 info->option); 05886 } else 05887 assert(0); 05888 mdd_array_free(clusteredRelationArray); 05889 05890 if (functionData->createVarCubesFlag) { 05891 if (info->fwdSmoothVarCubeArray) 05892 mdd_array_free(info->fwdSmoothVarCubeArray); 05893 info->fwdSmoothVarCubeArray = MakeSmoothVarCubeArray(mddManager, 05894 info->fwdArraySmoothVarBddArray); 05895 } 05896 05897 if (info->option->verbosity > 2) { 05898 PrintPartitionedTransitionRelation(mddManager, info, Img_Forward_c); 05899 } 05900 } 05901 05902 if (directionType == Img_Backward_c || directionType == Img_Both_c) { 05903 clusteredRelationArray = info->bwdClusteredRelationArray; 05904 mdd_array_array_free(info->bwdArraySmoothVarBddArray); 05905 info->bwdClusteredRelationArray = NIL(array_t); 05906 info->bwdArraySmoothVarBddArray = NIL(array_t); 05907 if (info->method == Img_Iwls95_c) { 05908 OrderRelationArray(mddManager, clusteredRelationArray, 05909 rangeVarBddArray, quantifyVarBddArray, 05910 domainVarBddArray, info->option, 05911 &info->bwdClusteredRelationArray, 05912 &info->bwdArraySmoothVarBddArray); 05913 } else if (info->method == Img_Mlp_c) { 05914 ImgMlpOrderRelationArray(mddManager, clusteredRelationArray, 05915 domainVarBddArray, quantifyVarBddArray, 05916 rangeVarBddArray, Img_Backward_c, 05917 &info->bwdClusteredRelationArray, 05918 &info->bwdArraySmoothVarBddArray, info->option); 05919 } else 05920 assert(0); 05921 mdd_array_free(clusteredRelationArray); 05922 05923 if (functionData->createVarCubesFlag) { 05924 if (info->bwdSmoothVarCubeArray) 05925 mdd_array_free(info->bwdSmoothVarCubeArray); 05926 info->bwdSmoothVarCubeArray = MakeSmoothVarCubeArray(mddManager, 05927 info->bwdArraySmoothVarBddArray); 05928 } 05929 05930 if (info->option->verbosity > 2) { 05931 PrintPartitionedTransitionRelation(mddManager, info, Img_Backward_c); 05932 } 05933 } 05934 05935 /* Free the Bdd arrays */ 05936 mdd_array_free(quantifyVarBddArray); 05937 } 05938 05939 05949 static void 05950 UpdateQuantificationSchedule(Iwls95Info_t *info, 05951 ImgFunctionData_t *functionData, 05952 Img_DirectionType directionType) 05953 { 05954 graph_t *mddNetwork = functionData->mddNetwork; 05955 mdd_manager *mddManager = Part_PartitionReadMddManager(mddNetwork); 05956 array_t *clusteredRelationArray; 05957 st_table *quantifyVarsTable; 05958 var_set_t *supportVarSet; 05959 int i, j, id, nRelations; 05960 int pos; 05961 long longid; 05962 array_t *smoothVarBddArray, **smoothVarBddArrayPtr; 05963 bdd_t *bdd, *relation; 05964 st_generator *gen; 05965 05966 if (directionType == Img_Forward_c || directionType == Img_Both_c) { 05967 nRelations = array_n(info->fwdClusteredRelationArray); 05968 quantifyVarsTable = st_init_table(st_numcmp, st_numhash); 05969 for (i = 0; i <= nRelations; i++) { 05970 smoothVarBddArray = array_fetch(array_t *, 05971 info->fwdArraySmoothVarBddArray, i); 05972 for (j = 0; j < array_n(smoothVarBddArray); j++) { 05973 bdd = array_fetch(mdd_t *, smoothVarBddArray, j); 05974 id = (int)bdd_top_var_id(bdd); 05975 st_insert(quantifyVarsTable, (char *)(long)id, NIL(char)); 05976 } 05977 } 05978 05979 clusteredRelationArray = info->fwdClusteredRelationArray; 05980 for (i = 0; i < nRelations; i++) { 05981 relation = array_fetch(bdd_t *, clusteredRelationArray, i); 05982 supportVarSet = bdd_get_support(relation); 05983 for (j = 0; j < supportVarSet->n_elts; j++) { 05984 if (var_set_get_elt(supportVarSet, j) == 1) { 05985 if (st_is_member(quantifyVarsTable, (char *)(long)j)) 05986 st_insert(quantifyVarsTable, (char *)(long)j, (char *)(long)(i+1)); 05987 } 05988 } 05989 var_set_free(supportVarSet); 05990 } 05991 05992 mdd_array_array_free(info->fwdArraySmoothVarBddArray); 05993 info->fwdArraySmoothVarBddArray = array_alloc(array_t *, nRelations + 1); 05994 smoothVarBddArrayPtr = ALLOC(array_t *, sizeof(array_t *) * (nRelations+1)); 05995 for (i = 0; i <= nRelations; i++) { 05996 smoothVarBddArray = array_alloc(bdd_t *, 0); 05997 smoothVarBddArrayPtr[i] = smoothVarBddArray; 05998 array_insert(array_t *, info->fwdArraySmoothVarBddArray, i, 05999 smoothVarBddArray); 06000 } 06001 06002 st_foreach_item_int(quantifyVarsTable, gen, &longid, &pos) { 06003 id = (int) longid; 06004 smoothVarBddArray = array_fetch(array_t *, 06005 info->fwdArraySmoothVarBddArray, pos); 06006 bdd = bdd_var_with_index(mddManager, id); 06007 array_insert_last(bdd_t *, smoothVarBddArray, bdd); 06008 } 06009 06010 FREE(smoothVarBddArrayPtr); 06011 st_free_table(quantifyVarsTable); 06012 06013 if (functionData->createVarCubesFlag) { 06014 if (info->fwdSmoothVarCubeArray) 06015 mdd_array_free(info->fwdSmoothVarCubeArray); 06016 info->fwdSmoothVarCubeArray = MakeSmoothVarCubeArray(mddManager, 06017 info->fwdArraySmoothVarBddArray); 06018 } 06019 06020 if (info->option->verbosity > 2) { 06021 PrintPartitionedTransitionRelation(mddManager, info, Img_Forward_c); 06022 } 06023 } 06024 06025 if (directionType == Img_Backward_c || directionType == Img_Both_c) { 06026 nRelations = array_n(info->bwdClusteredRelationArray); 06027 quantifyVarsTable = st_init_table(st_numcmp, st_numhash); 06028 for (i = 0; i <= nRelations; i++) { 06029 smoothVarBddArray = array_fetch(array_t *, 06030 info->bwdArraySmoothVarBddArray, i); 06031 for (j = 0; j < array_n(smoothVarBddArray); j++) { 06032 bdd = array_fetch(mdd_t *, smoothVarBddArray, j); 06033 id = (int)bdd_top_var_id(bdd); 06034 st_insert(quantifyVarsTable, (char *)(long)id, (char *)(long)0); 06035 } 06036 } 06037 06038 clusteredRelationArray = info->bwdClusteredRelationArray; 06039 for (i = 0; i < nRelations; i++) { 06040 relation = array_fetch(bdd_t *, clusteredRelationArray, i); 06041 supportVarSet = bdd_get_support(relation); 06042 for (j = 0; j < supportVarSet->n_elts; j++) { 06043 if (var_set_get_elt(supportVarSet, j) == 1) { 06044 if (st_is_member(quantifyVarsTable, (char *)(long)j)) 06045 st_insert(quantifyVarsTable, (char *)(long)j, (char *)(long)(i+1)); 06046 } 06047 } 06048 var_set_free(supportVarSet); 06049 } 06050 06051 mdd_array_array_free(info->bwdArraySmoothVarBddArray); 06052 info->bwdArraySmoothVarBddArray = array_alloc(array_t *, nRelations + 1); 06053 smoothVarBddArrayPtr = ALLOC(array_t *, sizeof(array_t *) * (nRelations+1)); 06054 for (i = 0; i <= nRelations; i++) { 06055 smoothVarBddArray = array_alloc(bdd_t *, 0); 06056 smoothVarBddArrayPtr[i] = smoothVarBddArray; 06057 array_insert(array_t *, info->bwdArraySmoothVarBddArray, i, 06058 smoothVarBddArray); 06059 } 06060 06061 st_foreach_item_int(quantifyVarsTable, gen, &longid, &pos) { 06062 id = (int) longid; 06063 smoothVarBddArray = array_fetch(array_t *, 06064 info->bwdArraySmoothVarBddArray, pos); 06065 bdd = bdd_var_with_index(mddManager, id); 06066 array_insert_last(bdd_t *, smoothVarBddArray, bdd); 06067 } 06068 06069 FREE(smoothVarBddArrayPtr); 06070 st_free_table(quantifyVarsTable); 06071 06072 if (functionData->createVarCubesFlag) { 06073 if (info->bwdSmoothVarCubeArray) 06074 mdd_array_free(info->bwdSmoothVarCubeArray); 06075 info->bwdSmoothVarCubeArray = MakeSmoothVarCubeArray(mddManager, 06076 info->bwdArraySmoothVarBddArray); 06077 } 06078 06079 if (info->option->verbosity > 2) { 06080 PrintPartitionedTransitionRelation(mddManager, info, Img_Backward_c); 06081 } 06082 } 06083 } 06084 06085 06095 static array_t * 06096 MakeSmoothVarCubeArray(mdd_manager *mddManager, array_t *arraySmoothVarBddArray) 06097 { 06098 int i, j; 06099 array_t *smoothVarBddArray; 06100 array_t *cubeArray = array_alloc(mdd_t *, 0); 06101 mdd_t *cube, *var, *tmp; 06102 06103 arrayForEachItem(array_t *, arraySmoothVarBddArray, i, smoothVarBddArray) { 06104 cube = mdd_one(mddManager); 06105 arrayForEachItem(mdd_t *, smoothVarBddArray, j, var) { 06106 tmp = mdd_and(cube, var, 1, 1); 06107 mdd_free(cube); 06108 cube = tmp; 06109 } 06110 array_insert_last(mdd_t *, cubeArray, cube); 06111 } 06112 return(cubeArray); 06113 } 06114 06115 06129 static mdd_t * 06130 TrmEliminateDependVars(Img_ImageInfo_t *imageInfo, array_t *relationArray, 06131 mdd_t *states, mdd_t **dependRelations) 06132 { 06133 int nDependVars; 06134 mdd_t *newStates; 06135 Iwls95Info_t *info = (Iwls95Info_t *) imageInfo->methodData; 06136 06137 newStates = ImgTrmEliminateDependVars(&imageInfo->functionData, relationArray, 06138 states, dependRelations, &nDependVars); 06139 if (nDependVars) { 06140 if (imageInfo->verbosity > 0) 06141 (void)fprintf(vis_stdout, "Eliminated %d vars.\n", nDependVars); 06142 info->averageFoundDependVars = (info->averageFoundDependVars * 06143 (float)info->nFoundDependVars + (float)nDependVars) / 06144 (float)(info->nFoundDependVars + 1); 06145 info->nFoundDependVars++; 06146 } 06147 06148 info->nPrevEliminatedFwd = nDependVars; 06149 return(newStates); 06150 } /* end of TfmEliminateDependVars */ 06151 06152 06163 static int 06164 TrmSignatureCompare(int *ptrX, int *ptrY) 06165 { 06166 if (signatures[*ptrY] > signatures[*ptrX]) 06167 return(1); 06168 if (signatures[*ptrY] < signatures[*ptrX]) 06169 return(-1); 06170 return(0); 06171 } /* end of TrmSignatureCompare */ 06172 06173 06183 static void 06184 SetupLazySifting(mdd_manager *mddManager, array_t *bddRelationArray, 06185 array_t *domainVarBddArray, array_t *quantifyVarBddArray, 06186 array_t *rangeVarBddArray, int verbosity) 06187 { 06188 int i, id, psId, nsId, psLevel, nsLevel; 06189 int nVars = bdd_num_vars(mddManager); 06190 int nUngroup = 0; 06191 int nGroup = 0; 06192 int nConst = 0; 06193 int *nonLambda = ALLOC(int, nVars); 06194 int nLambda = 0; 06195 int nDepend1to1 = 0; 06196 int nIndepend1to1 = 0; 06197 int nPairPsOnce = 0; 06198 int pairPsId; 06199 int constFlag; 06200 int dependFlag; 06201 int nDependPs; 06202 int nDependPi; 06203 bdd_t* relation; 06204 var_set_t* supIds; 06205 bdd_t *bdd, *psVar, *nsVar; 06206 06207 bdd_discard_all_var_groups(mddManager); 06208 for (i = 0; i < array_n(quantifyVarBddArray); i++) { 06209 bdd = array_fetch(bdd_t *, quantifyVarBddArray, i); 06210 id = bdd_top_var_id(bdd); 06211 bdd_set_pair_index(mddManager, id, id); 06212 bdd_set_pi_var(mddManager, id); 06213 bdd_reset_var_to_be_grouped(mddManager, id); 06214 } 06215 06216 for (i = 0; i < array_n(rangeVarBddArray); i++) { 06217 psVar = array_fetch(bdd_t *, domainVarBddArray, i); 06218 nsVar = array_fetch(bdd_t *, rangeVarBddArray, i); 06219 psId = bdd_top_var_id(psVar); 06220 nsId = bdd_top_var_id(nsVar); 06221 bdd_set_pair_index(mddManager, psId, nsId); 06222 bdd_set_pair_index(mddManager, nsId, psId); 06223 bdd_set_ps_var(mddManager, psId); 06224 bdd_set_ns_var(mddManager, nsId); 06225 bdd_reset_var_to_be_grouped(mddManager, psId); 06226 bdd_set_var_to_be_grouped(mddManager, nsId); 06227 } 06228 06229 if (array_n(domainVarBddArray) > array_n(rangeVarBddArray)) { 06230 for (i = array_n(rangeVarBddArray); i < array_n(domainVarBddArray); i++) { 06231 bdd = array_fetch(bdd_t *, domainVarBddArray, i); 06232 id = bdd_top_var_id(bdd); 06233 bdd_set_pair_index(mddManager, id, id); 06234 bdd_set_pi_var(mddManager, id); 06235 bdd_reset_var_to_be_grouped(mddManager, id); 06236 } 06237 } 06238 06239 memset(nonLambda, 0, sizeof(int) * nVars); 06240 for (i = 0; i < array_n(bddRelationArray); i++) { 06241 nsId = -1; 06242 pairPsId = -1; 06243 constFlag = 1; 06244 dependFlag = 0; 06245 nDependPs = 0; 06246 nDependPi = 0; 06247 relation = array_fetch(bdd_t *, bddRelationArray, i); 06248 supIds = bdd_get_support(relation); 06249 06250 for (id = 0; id < nVars; id++) { 06251 if (var_set_get_elt(supIds, id) == 1) { 06252 if (bdd_is_ns_var(mddManager, id)) { 06253 pairPsId = bdd_read_pair_index(mddManager, id); 06254 nsId = id; 06255 } else if (bdd_is_ps_var(mddManager, id)) { 06256 constFlag = 0; /* nonconst next sate function */ 06257 nonLambda[id]++; 06258 psId = id; 06259 /* At least one next state function depends on psvar id */ 06260 nDependPs++; 06261 } else { 06262 constFlag = 0; /* nonconst next state function */ 06263 nDependPi++; 06264 } 06265 } 06266 } 06267 if (nsId >= 0) { 06268 /* bitwise transition relation depends on some nsvar */ 06269 for (id = 0; id < nVars; id++) { 06270 if (var_set_get_elt(supIds, id) == 1) { 06271 if (pairPsId == id) { 06272 /* dependendent state pair */ 06273 nGroup++; 06274 dependFlag = 1; 06275 } 06276 } 06277 } 06278 if (dependFlag != 1) { 06279 /* independent state pair */ 06280 nUngroup++; 06281 if (constFlag == 1) { 06282 /* next state function is constant */ 06283 psLevel = bdd_get_level_from_id(mddManager, pairPsId); 06284 nsLevel = bdd_get_level_from_id(mddManager, nsId); 06285 if (psLevel == nsLevel - 1) { 06286 bdd = bdd_var_with_index(mddManager, pairPsId); 06287 bdd_new_var_block(bdd, 2); 06288 bdd_free(bdd); 06289 nConst++; 06290 } else if (psLevel == nsLevel + 1) { 06291 bdd = bdd_var_with_index(mddManager, nsId); 06292 bdd_new_var_block(bdd, 2); 06293 bdd_free(bdd); 06294 nConst++; 06295 } 06296 } else { 06297 bdd_set_var_to_be_ungrouped(mddManager, pairPsId); 06298 bdd_set_var_to_be_ungrouped(mddManager, nsId); 06299 } 06300 } else if (nDependPs == 1) { 06301 psLevel = bdd_get_level_from_id(mddManager, pairPsId); 06302 nsLevel = bdd_get_level_from_id(mddManager, nsId); 06303 if (psLevel == nsLevel - 1) { 06304 bdd = bdd_var_with_index(mddManager, pairPsId); 06305 bdd_new_var_block(bdd, 2); 06306 bdd_free(bdd); 06307 nDepend1to1++; 06308 } else if (psLevel == nsLevel + 1) { 06309 bdd = bdd_var_with_index(mddManager, nsId); 06310 bdd_new_var_block(bdd, 2); 06311 bdd_free(bdd); 06312 nDepend1to1++; 06313 } 06314 } else if (nonLambda[pairPsId] == 1) { 06315 psLevel = bdd_get_level_from_id(mddManager, pairPsId); 06316 nsLevel = bdd_get_level_from_id(mddManager, nsId); 06317 if (psLevel == nsLevel - 1) { 06318 bdd = bdd_var_with_index(mddManager, pairPsId); 06319 bdd_new_var_block(bdd, 2); 06320 bdd_free(bdd); 06321 nPairPsOnce++; 06322 } else if (psLevel == nsLevel + 1) { 06323 bdd = bdd_var_with_index(mddManager, nsId); 06324 bdd_new_var_block(bdd, 2); 06325 bdd_free(bdd); 06326 nPairPsOnce++; 06327 } 06328 } 06329 } else { 06330 /* bitwise transition relation does not depend on any nsvar */ 06331 nUngroup++; 06332 } 06333 var_set_free(supIds); 06334 } 06335 for (i = 0; i < nVars; i++) { 06336 if (bdd_is_ps_var(mddManager, i)) { 06337 if (nonLambda[i] == 0) { 06338 /* no next state function depends on psvar i */ 06339 psId = i; 06340 nsId = bdd_read_pair_index(mddManager, psId); 06341 psLevel = bdd_get_level_from_id(mddManager, psId); 06342 nsLevel = bdd_get_level_from_id(mddManager, nsId); 06343 nLambda++; 06344 if (psLevel == nsLevel - 1) { 06345 bdd = bdd_var_with_index(mddManager, psId); 06346 bdd_new_var_block(bdd, 2); 06347 bdd_free(bdd); 06348 } else if (psLevel == nsLevel + 1) { 06349 bdd = bdd_var_with_index(mddManager, nsId); 06350 bdd_new_var_block(bdd, 2); 06351 bdd_free(bdd); 06352 } 06353 } 06354 } else if (bdd_is_pi_var(mddManager, i)) { 06355 bdd_set_var_to_be_ungrouped(mddManager, i); 06356 } 06357 } 06358 if (verbosity) { 06359 fprintf(vis_stdout, "#grp=%d(#depend1to1=%d,#pairpsonce=%d)", 06360 nGroup, nDepend1to1, nPairPsOnce); 06361 fprintf(vis_stdout, 06362 " #ungrp=%d(#const=%d,#lambda=%d, independ1to1=%d)\n", 06363 nUngroup, nConst, nLambda, nIndepend1to1); 06364 } 06365 FREE(nonLambda); 06366 } 06367 06377 int 06378 Img_IsTransitionRelationOptimized(Img_ImageInfo_t * imageInfo) 06379 { 06380 Iwls95Info_t *info = (Iwls95Info_t *)imageInfo->methodData; 06381 if(info->fwdOptClusteredRelationArray && 06382 info->fwdClusteredRelationArray) return(1); 06383 return(0); 06384 } 06385 06395 static int 06396 MddSizeCompare(const void *ptr1, const void *ptr2) 06397 { 06398 mdd_t *mdd1 = *(mdd_t **)ptr1; 06399 mdd_t *mdd2 = *(mdd_t **)ptr2; 06400 int size1 = mdd_size(mdd1); 06401 int size2 = mdd_size(mdd2); 06402 06403 if (size1 > size2) 06404 return 1; 06405 else if (size1 < size2) 06406 return -1; 06407 else 06408 return 0; 06409 } 06410 06421 void 06422 Img_ForwardImageInfoRecoverFromWinningStrategy( 06423 Img_ImageInfo_t * imageInfo 06424 ) 06425 { 06426 Iwls95Info_t *info; 06427 array_t *new_; 06428 06429 info = (Iwls95Info_t *)imageInfo->methodData; 06430 06431 if(info->fwdOriClusteredRelationArray) { 06432 new_ = info->fwdClusteredRelationArray; 06433 info->fwdClusteredRelationArray = info->fwdOriClusteredRelationArray; 06434 info->fwdOriClusteredRelationArray = 0; 06435 mdd_array_free(new_); 06436 } 06437 } 06438 06449 void 06450 Img_ForwardImageInfoConjoinWithWinningStrategy( 06451 Img_ImageInfo_t * imageInfo, 06452 mdd_t *winningStrategy) 06453 { 06454 Iwls95Info_t *info; 06455 array_t *old, *new_; 06456 int i; 06457 mdd_t *tr, *ntr, *winning; 06458 06459 06460 old = 0; 06461 winning = 0; 06462 new_ = array_alloc(mdd_t *, 0); 06463 info = (Iwls95Info_t *)imageInfo->methodData; 06464 old = info->fwdClusteredRelationArray; 06465 info->fwdClusteredRelationArray = new_; 06466 info->fwdOriClusteredRelationArray = old; 06467 winning = mdd_dup(winningStrategy); 06468 /* winning = ImgSubstitute(winningStrategy, &(imageInfo->functionData), Img_D2R_c);*/ 06469 for(i=0; i<array_n(old); i++) { 06470 tr = array_fetch(mdd_t *, old, i); 06471 ntr = mdd_and(tr, winning, 1, 1); 06472 array_insert_last(mdd_t *, new_, ntr); 06473 } 06474 mdd_free(winning); 06475 } 06476