VIS
|
00001 00075 #include "imgInt.h" 00076 00077 static char rcsid[] UNUSED = "$Id: imgTfm.c,v 1.93 2005/04/23 14:30:54 jinh Exp $"; 00078 00079 /*---------------------------------------------------------------------------*/ 00080 /* Constant declarations */ 00081 /*---------------------------------------------------------------------------*/ 00082 00083 /*---------------------------------------------------------------------------*/ 00084 /* Type declarations */ 00085 /*---------------------------------------------------------------------------*/ 00086 00087 /*---------------------------------------------------------------------------*/ 00088 /* Structure declarations */ 00089 /*---------------------------------------------------------------------------*/ 00090 00091 /*---------------------------------------------------------------------------*/ 00092 /* Variable declarations */ 00093 /*---------------------------------------------------------------------------*/ 00094 00095 static st_table *HookInfoList; /* adds a hook function to flush image 00096 cache before veriable reordering */ 00097 static int nHookInfoList; /* the number of hook functions */ 00098 00099 /*---------------------------------------------------------------------------*/ 00100 /* Macro declarations */ 00101 /*---------------------------------------------------------------------------*/ 00102 00103 00106 /*---------------------------------------------------------------------------*/ 00107 /* Static function prototypes */ 00108 /*---------------------------------------------------------------------------*/ 00109 00110 static ImgTfmInfo_t * TfmInfoStructAlloc(Img_MethodType method); 00111 static int CompareIndex(const void *e1, const void *e2); 00112 static int HookInfoFunction(bdd_manager *mgr, char *str, void *method); 00113 static array_t * ChoosePartialVars(ImgTfmInfo_t *info, array_t *vector, int nPartialVars, int partialMethod); 00114 static void PrintRecursionStatistics(ImgTfmInfo_t *info, int preFlag); 00115 static void PrintFoundVariableStatistics(ImgTfmInfo_t *info, int preFlag); 00116 static void GetRecursionStatistics(ImgTfmInfo_t *info, int preFlag, int *nRecurs, int *nLeaves, int *nTurns, float *averageDepth, int *maxDepth, int *nDecomps, int *topDecomp, int *maxDecomp, float *averageDecomp); 00117 static int ReadSetIntValue(char *string, int l, int u, int defaultValue); 00118 static boolean ReadSetBooleanValue(char *string, boolean defaultValue); 00119 static void FindIntermediateVarsRecursively(ImgTfmInfo_t *info, mdd_manager *mddManager, vertex_t *vertex, int mddId, st_table *vertexTable, array_t *vector, st_table *domainQuantifyVarMddIdTable, array_t *intermediateVarMddIdArray); 00120 static void GetIntermediateRelationsRecursively(mdd_manager *mddManager, vertex_t *vertex, int mddId, st_table *vertexTable, array_t *relationArray, st_table *domainQuantifyVarMddIdTable, array_t *intermediateVarMddIdArray); 00121 static int CheckNondeterminism(Ntk_Network_t *network); 00122 static array_t * TfmCreateBitVector(ImgTfmInfo_t *info, int composeIntermediateVars, int findIntermediateVars); 00123 static array_t * TfmCreateBitRelationArray(ImgTfmInfo_t *info, int composeIntermediateVars, int findIntermediateVars); 00124 static void TfmSetupPartialTransitionRelation(ImgTfmInfo_t *info, array_t **partialRelationArray); 00125 static void TfmBuildRelationArray(ImgTfmInfo_t *info, ImgFunctionData_t *functionData, array_t *bitRelationArray, Img_DirectionType directionType, int writeMatrix); 00126 static void RebuildTransitionRelation(ImgTfmInfo_t *info, Img_DirectionType directionType); 00127 static void MinimizeTransitionFunction(array_t *vector, array_t *relationArray, mdd_t *constrain, Img_MinimizeType minimizeMethod, int printStatus); 00128 static void AddDontCareToTransitionFunction(array_t *vector, array_t *relationArray, mdd_t *constrain, Img_MinimizeType minimizeMethod, int printStatus); 00129 00133 /*---------------------------------------------------------------------------*/ 00134 /* Definition of exported functions */ 00135 /*---------------------------------------------------------------------------*/ 00136 00137 00151 int 00152 Img_TfmGetRecursionStatistics(Img_ImageInfo_t *imageInfo, int preFlag, 00153 int *nRecurs, int *nLeaves, int *nTurns, 00154 float *averageDepth, int *maxDepth, int *nDecomps, 00155 int *topDecomp, int *maxDecomp, 00156 float *averageDecomp) 00157 { 00158 ImgTfmInfo_t *info; 00159 00160 if (imageInfo->methodType != Img_Tfm_c && 00161 imageInfo->methodType != Img_Hybrid_c) { 00162 return(0); 00163 } 00164 00165 info = (ImgTfmInfo_t *)imageInfo->methodData; 00166 if (preFlag) { 00167 *nRecurs = info->nRecursionB; 00168 *nLeaves = info->nLeavesB; 00169 *nTurns = info->nTurnsB; 00170 *averageDepth = info->averageDepthB; 00171 *maxDepth = info->maxDepthB; 00172 *nDecomps = 0; 00173 *topDecomp = 0; 00174 *maxDecomp = 0; 00175 *averageDecomp = 0.0; 00176 } else { 00177 *nRecurs = info->nRecursion; 00178 *nLeaves = info->nLeaves; 00179 *nTurns = info->nTurns; 00180 *averageDepth = info->averageDepth; 00181 *maxDepth = info->maxDepth; 00182 *nDecomps = info->nDecomps; 00183 *topDecomp = info->topDecomp; 00184 *maxDecomp = info->maxDecomp; 00185 *averageDecomp = info->averageDecomp; 00186 } 00187 return(1); 00188 } 00189 00190 00204 void 00205 Img_TfmPrintStatistics(Img_ImageInfo_t *imageInfo, Img_DirectionType dir) 00206 { 00207 if (dir == Img_Forward_c || dir == Img_Both_c) { 00208 Img_TfmPrintCacheStatistics(imageInfo, 0); 00209 Img_TfmPrintRecursionStatistics(imageInfo, 0); 00210 } 00211 if (dir == Img_Backward_c || dir == Img_Both_c) { 00212 Img_TfmPrintCacheStatistics(imageInfo, 1); 00213 Img_TfmPrintRecursionStatistics(imageInfo, 1); 00214 } 00215 } 00216 00217 00231 void 00232 Img_TfmPrintRecursionStatistics(Img_ImageInfo_t *imageInfo, int preFlag) 00233 { 00234 float avgDepth, avgDecomp; 00235 int nRecurs, nLeaves, nTurns, nDecomps, topDecomp, maxDecomp; 00236 int maxDepth; 00237 00238 (void) Img_TfmGetRecursionStatistics(imageInfo, preFlag, &nRecurs, &nLeaves, 00239 &nTurns, &avgDepth, &maxDepth, &nDecomps, 00240 &topDecomp, &maxDecomp, &avgDecomp); 00241 if (preFlag) 00242 fprintf(vis_stdout, "** recursion statistics of splitting (preImg) **\n"); 00243 else 00244 fprintf(vis_stdout, "** recursion statistics of splitting (img) **\n"); 00245 fprintf(vis_stdout, "# recursions = %d\n", nRecurs); 00246 fprintf(vis_stdout, "# leaves = %d\n", nLeaves); 00247 fprintf(vis_stdout, "# turns = %d\n", nTurns); 00248 fprintf(vis_stdout, "# average recursion depth = %g (max = %d)\n", 00249 avgDepth, maxDepth); 00250 if (!preFlag) { 00251 fprintf(vis_stdout, 00252 "# decompositions = %d (top = %d, max = %d, average = %g)\n", 00253 nDecomps, topDecomp, maxDecomp, avgDecomp); 00254 } 00255 } 00256 00257 00271 void 00272 Img_PrintTfmOptions(void) 00273 { 00274 ImgTfmOption_t *options; 00275 Img_MethodType method; 00276 char *flagValue, dummy[40]; 00277 00278 flagValue = Cmd_FlagReadByName("image_method"); 00279 if (flagValue) { 00280 if (strcmp(flagValue, "hybrid") == 0) 00281 method = Img_Hybrid_c; 00282 else 00283 method = Img_Tfm_c; 00284 } else 00285 method = Img_Tfm_c; 00286 00287 options = ImgTfmGetOptions(method); 00288 00289 switch (options->splitMethod) { 00290 case 0 : 00291 sprintf(dummy, "input split"); 00292 break; 00293 case 1 : 00294 sprintf(dummy, "output split"); 00295 break; 00296 case 2 : 00297 sprintf(dummy, "mixed"); 00298 break; 00299 case 3 : 00300 sprintf(dummy, "hybrid"); 00301 break; 00302 default : 00303 sprintf(dummy, "invalid"); 00304 break; 00305 } 00306 fprintf(vis_stdout, "TFM: tfm_split_method = %d (%s)\n", 00307 options->splitMethod, dummy); 00308 00309 switch (options->inputSplit) { 00310 case 0 : 00311 sprintf(dummy, "support before splitting"); 00312 break; 00313 case 1 : 00314 sprintf(dummy, "support after splitting"); 00315 break; 00316 case 2 : 00317 sprintf(dummy, "estimate BDD size after splitting"); 00318 break; 00319 case 3 : 00320 sprintf(dummy, "top variable"); 00321 break; 00322 default : 00323 sprintf(dummy, "invalid"); 00324 break; 00325 } 00326 fprintf(vis_stdout, "TFM: tfm_input_split = %d (%s)\n", 00327 options->inputSplit, dummy); 00328 00329 if (options->piSplitFlag) 00330 sprintf(dummy, "yes"); 00331 else 00332 sprintf(dummy, "no"); 00333 fprintf(vis_stdout, "TFM: tfm_pi_split_flag = %s\n", dummy); 00334 00335 /* whether to convert image computation to range computation */ 00336 switch (options->rangeComp) { 00337 case 0 : 00338 sprintf(dummy, "do not convert"); 00339 break; 00340 case 1 : 00341 sprintf(dummy, "convert to range computation"); 00342 break; 00343 case 2 : 00344 sprintf(dummy, "convert with threshold"); 00345 break; 00346 default : 00347 sprintf(dummy, "invalid"); 00348 break; 00349 } 00350 fprintf(vis_stdout, "TFM: tfm_range_comp = %d (%s)\n", 00351 options->rangeComp, dummy); 00352 00353 fprintf(vis_stdout, "TFM: tfm_range_threshold = %d\n", 00354 options->rangeThreshold); 00355 00356 fprintf(vis_stdout, "TFM: tfm_range_try_threshold = %d\n", 00357 options->rangeTryThreshold); 00358 00359 if (options->rangeCheckReorder) 00360 sprintf(dummy, "yes"); 00361 else 00362 sprintf(dummy, "no"); 00363 fprintf(vis_stdout, "TFM: tfm_range_check_reorder = %s\n", dummy); 00364 00365 switch (options->tieBreakMode) { 00366 case 0 : 00367 sprintf(dummy, "closest variable to top"); 00368 break; 00369 case 1 : 00370 sprintf(dummy, "smallest BDD size after splitting"); 00371 break; 00372 default : 00373 sprintf(dummy, "invalid"); 00374 break; 00375 } 00376 fprintf(vis_stdout, "TFM: tfm_tie_break_mode = %d (%s)\n", 00377 options->tieBreakMode, dummy); 00378 00379 switch (options->outputSplit) { 00380 case 0 : 00381 sprintf(dummy, "smallest BDD size"); 00382 break; 00383 case 1 : 00384 sprintf(dummy, "largest BDD size"); 00385 break; 00386 case 2 : 00387 sprintf(dummy, "top variable"); 00388 break; 00389 default : 00390 sprintf(dummy, "invalid"); 00391 break; 00392 } 00393 fprintf(vis_stdout, "TFM: tfm_output_split = %d (%s)\n", 00394 options->outputSplit, dummy); 00395 00396 fprintf(vis_stdout, "TFM: tfm_turn_depth = %d\n", 00397 options->turnDepth); 00398 00399 if (options->findDecompVar) 00400 sprintf(dummy, "yes"); 00401 else 00402 sprintf(dummy, "no"); 00403 fprintf(vis_stdout, "TFM: tfm_find_decomp_var = %s\n", dummy); 00404 00405 if (options->sortVectorFlag) 00406 sprintf(dummy, "yes"); 00407 else 00408 sprintf(dummy, "no"); 00409 fprintf(vis_stdout, "TFM: tfm_sort_vector_flag = %s\n", dummy); 00410 00411 if (options->printStatistics) 00412 sprintf(dummy, "yes"); 00413 else 00414 sprintf(dummy, "no"); 00415 fprintf(vis_stdout, "TFM: tfm_print_stats = %s\n", dummy); 00416 00417 if (options->printBddSize) 00418 sprintf(dummy, "yes"); 00419 else 00420 sprintf(dummy, "no"); 00421 fprintf(vis_stdout, "TFM: tfm_print_bdd_size = %s\n", dummy); 00422 00423 if (options->splitCubeFunc) 00424 sprintf(dummy, "yes"); 00425 else 00426 sprintf(dummy, "no"); 00427 fprintf(vis_stdout, "TFM: tfm_split_cube_func = %s\n", dummy); 00428 00429 switch (options->findEssential) { 00430 case 0 : 00431 sprintf(dummy, "off"); 00432 break; 00433 case 1 : 00434 sprintf(dummy, "on"); 00435 break; 00436 case 2 : 00437 sprintf(dummy, "dynamic"); 00438 break; 00439 default : 00440 sprintf(dummy, "invalid"); 00441 break; 00442 } 00443 fprintf(vis_stdout, "TFM: tfm_find_essential = %d (%s)\n", 00444 options->findEssential, dummy); 00445 00446 switch (options->printEssential) { 00447 case 0 : 00448 sprintf(dummy, "off"); 00449 break; 00450 case 1 : 00451 sprintf(dummy, "at the end"); 00452 break; 00453 case 2 : 00454 sprintf(dummy, "at every image computation"); 00455 break; 00456 default : 00457 sprintf(dummy, "invalid"); 00458 break; 00459 } 00460 fprintf(vis_stdout, "TFM: tfm_print_essential = %d (%s)\n", 00461 options->printEssential, dummy); 00462 00463 switch (options->useCache) { 00464 case 0 : 00465 sprintf(dummy, "off"); 00466 break; 00467 case 1 : 00468 sprintf(dummy, "on"); 00469 break; 00470 case 2 : 00471 sprintf(dummy, "store all intermediate"); 00472 break; 00473 default : 00474 sprintf(dummy, "invalid"); 00475 break; 00476 } 00477 fprintf(vis_stdout, "TFM: tfm_use_cache = %d (%s)\n", 00478 options->useCache, dummy); 00479 00480 if (options->globalCache) 00481 sprintf(dummy, "yes"); 00482 else 00483 sprintf(dummy, "no"); 00484 fprintf(vis_stdout, "TFM: tfm_global_cache = %s\n", dummy); 00485 00486 fprintf(vis_stdout, "TFM: tfm_max_chain_length = %d\n", 00487 options->maxChainLength); 00488 00489 fprintf(vis_stdout, "TFM: tfm_init_cache_size = %d\n", 00490 options->initCacheSize); 00491 00492 switch (options->autoFlushCache) { 00493 case 0 : 00494 sprintf(dummy, "when requested"); 00495 break; 00496 case 1 : 00497 sprintf(dummy, "at the end of image computation"); 00498 break; 00499 case 2 : 00500 sprintf(dummy, "before reordering"); 00501 break; 00502 default : 00503 sprintf(dummy, "invalid"); 00504 break; 00505 } 00506 fprintf(vis_stdout, "TFM: tfm_auto_flush_cache = %d (%s)\n", 00507 options->autoFlushCache, dummy); 00508 00509 if (options->composeIntermediateVars) 00510 sprintf(dummy, "yes"); 00511 else 00512 sprintf(dummy, "no"); 00513 fprintf(vis_stdout, "TFM: tfm_compose_intermediate_vars = %s\n", dummy); 00514 00515 switch (options->preSplitMethod) { 00516 case 0 : 00517 sprintf(dummy, "input split"); 00518 break; 00519 case 1 : 00520 sprintf(dummy, "output split"); 00521 break; 00522 case 2 : 00523 sprintf(dummy, "mixed"); 00524 break; 00525 case 3 : 00526 sprintf(dummy, "substitution"); 00527 break; 00528 case 4 : 00529 sprintf(dummy, "hybrid"); 00530 break; 00531 default : 00532 sprintf(dummy, "invalid"); 00533 break; 00534 } 00535 fprintf(vis_stdout, "TFM: tfm_pre_split_method = %d (%s)\n", 00536 options->preSplitMethod, dummy); 00537 00538 switch (options->preInputSplit) { 00539 case 0 : 00540 sprintf(dummy, "support before splitting"); 00541 break; 00542 case 1 : 00543 sprintf(dummy, "support after splitting"); 00544 break; 00545 case 2 : 00546 sprintf(dummy, "estimate BDD size after splitting"); 00547 break; 00548 case 3 : 00549 sprintf(dummy, "top variable"); 00550 break; 00551 default : 00552 sprintf(dummy, "invalid"); 00553 break; 00554 } 00555 fprintf(vis_stdout, "TFM: tfm_pre_input_split = %d (%s)\n", 00556 options->preInputSplit, dummy); 00557 00558 switch (options->preOutputSplit) { 00559 case 0 : 00560 sprintf(dummy, "smallest BDD size"); 00561 break; 00562 case 1 : 00563 sprintf(dummy, "largest BDD size"); 00564 break; 00565 case 2 : 00566 sprintf(dummy, "top variable"); 00567 break; 00568 default : 00569 sprintf(dummy, "invalid"); 00570 break; 00571 } 00572 fprintf(vis_stdout, "TFM: tfm_pre_output_split = %d (%s)\n", 00573 options->preOutputSplit, dummy); 00574 00575 switch (options->preDcLeafMethod) { 00576 case 0 : 00577 sprintf(dummy, "substitution"); 00578 break; 00579 case 1 : 00580 sprintf(dummy, "constraint cofactoring"); 00581 break; 00582 case 2 : 00583 sprintf(dummy, "hybrid"); 00584 break; 00585 default : 00586 sprintf(dummy, "invalid"); 00587 break; 00588 } 00589 fprintf(vis_stdout, "TFM: tfm_pre_dc_leaf_method = %d (%s)\n", 00590 options->preDcLeafMethod, dummy); 00591 00592 if (options->preMinimize) 00593 sprintf(dummy, "yes"); 00594 else 00595 sprintf(dummy, "no"); 00596 fprintf(vis_stdout, "TFM: tfm_pre_minimize = %s\n", dummy); 00597 00598 fprintf(vis_stdout, "TFM: tfm_verbosity = %d\n", 00599 options->verbosity); 00600 00601 FREE(options); 00602 } 00603 00604 00605 /*---------------------------------------------------------------------------*/ 00606 /* Definition of internal functions */ 00607 /*---------------------------------------------------------------------------*/ 00608 00609 00621 void * 00622 ImgImageInfoInitializeTfm(void *methodData, ImgFunctionData_t * functionData, 00623 Img_DirectionType directionType, 00624 Img_MethodType method) 00625 { 00626 int i; 00627 int latches; 00628 int variables, nVars; 00629 array_t *vector; 00630 graph_t *mddNetwork; 00631 mdd_manager *mddManager; 00632 array_t *rangeVarMddIdArray; 00633 ImgTfmInfo_t *info = (ImgTfmInfo_t *)methodData; 00634 int index; 00635 mdd_t *var; 00636 char *flagValue; 00637 char filename[20]; 00638 int composeIntermediateVars, findIntermediateVars; 00639 int nonDeterministic; 00640 00641 if (info) { 00642 if (info->option->useCache) { 00643 if (directionType == Img_Forward_c || directionType == Img_Both_c) { 00644 if (!info->imgCache) 00645 ImgCacheInitTable(info, info->option->initCacheSize, 00646 info->option->globalCache, FALSE); 00647 } 00648 if (directionType == Img_Backward_c || directionType == Img_Both_c) { 00649 if (!info->preCache) 00650 ImgCacheInitTable(info, info->option->initCacheSize, 00651 info->option->globalCache, TRUE); 00652 } 00653 } 00654 if (info->buildTR && 00655 (((directionType == Img_Forward_c || directionType == Img_Both_c) && 00656 !info->fwdClusteredRelationArray) || 00657 ((directionType == Img_Backward_c || directionType == Img_Both_c) && 00658 !info->bwdClusteredRelationArray))) { 00659 TfmBuildRelationArray(info, functionData, NIL(array_t), directionType, 0); 00660 } 00661 return((void *)info); 00662 } 00663 00664 mddNetwork = functionData->mddNetwork; 00665 mddManager = Part_PartitionReadMddManager(mddNetwork); 00666 rangeVarMddIdArray = functionData->rangeVars; 00667 00668 nonDeterministic = CheckNondeterminism(functionData->network); 00669 if (nonDeterministic) 00670 info = TfmInfoStructAlloc(Img_Hybrid_c); 00671 else 00672 info = TfmInfoStructAlloc(method); 00673 info->nonDeterministic = nonDeterministic; 00674 info->functionData = functionData; 00675 info->quantifyVarsTable = st_init_table(st_numcmp, st_numhash); 00676 for (i = 0; i < array_n(functionData->quantifyBddVars); i++) { 00677 var = array_fetch(mdd_t *, functionData->quantifyBddVars, i); 00678 index = (int)bdd_top_var_id(var); 00679 st_insert(info->quantifyVarsTable, (char *)(long)index, NIL(char)); 00680 } 00681 info->rangeVarsTable = st_init_table(st_numcmp, st_numhash); 00682 for (i = 0; i < array_n(functionData->rangeBddVars); i++) { 00683 var = array_fetch(mdd_t *, functionData->rangeBddVars, i); 00684 index = (int)bdd_top_var_id(var); 00685 st_insert(info->rangeVarsTable, (char *)(long)index, NIL(char)); 00686 } 00687 00688 latches = 2 * mdd_get_number_of_bdd_vars(mddManager, rangeVarMddIdArray); 00689 nVars = latches + mdd_get_number_of_bdd_vars(mddManager, 00690 functionData->quantifyVars); 00691 variables = bdd_num_vars(mddManager); /* real number of variables */ 00692 info->nRealVars = nVars; 00693 info->nVars = variables; 00694 00695 if (info->nonDeterministic) { 00696 if (method == Img_Tfm_c) { 00697 fprintf(vis_stdout, 00698 "** tfm warning: The circuit may have nondeterminism.\n"); 00699 fprintf(vis_stdout, "\tautomatically switched to hybrid mode = 2.\n"); 00700 info->method = Img_Hybrid_c; 00701 } else { 00702 if (info->option->hybridMode == 2) { 00703 if (info->option->buildPartialTR) { 00704 fprintf(vis_stdout, 00705 "** hyb warning: The circuit may have nondeterminism.\n"); 00706 fprintf(vis_stdout, 00707 "\tdid not use partial transition relation.\n"); 00708 } else { 00709 fprintf(vis_stdout, 00710 "** hyb info: The circuit may have nondeterminism.\n"); 00711 } 00712 } else { 00713 fprintf(vis_stdout, 00714 "** hyb warning: The circuit may have nondeterminism.\n"); 00715 fprintf(vis_stdout, "\tautomatically switched to hybrid mode = 2.\n"); 00716 } 00717 } 00718 } 00719 if (info->nonDeterministic || 00720 (info->option->hybridMode > 0 && 00721 (info->option->splitMethod == 3 || info->option->preSplitMethod == 4))) { 00722 if (info->option->hybridMode == 2 || info->nonDeterministic) 00723 info->buildTR = 2; 00724 else 00725 info->buildTR = 1; 00726 } 00727 if (info->buildTR == 2 && 00728 info->option->buildPartialTR && 00729 info->nonDeterministic == 0 && 00730 info->option->useCache == 0) { 00731 info->buildPartialTR = TRUE; 00732 } 00733 00734 info->imgKeepPiInTr = info->option->imgKeepPiInTr; 00735 if (info->option->useCache) 00736 info->preKeepPiInTr = TRUE; 00737 else 00738 info->preKeepPiInTr = info->option->preKeepPiInTr; 00739 00740 if (Part_PartitionReadMethod(mddNetwork) == Part_Frontier_c && 00741 nVars != variables) { 00742 if (info->option->composeIntermediateVars) { 00743 composeIntermediateVars = 1; 00744 findIntermediateVars = 0; 00745 } else { 00746 composeIntermediateVars = 0; 00747 findIntermediateVars = 1; 00748 } 00749 } else { 00750 composeIntermediateVars = 0; 00751 findIntermediateVars = 0; 00752 } 00753 00754 if (info->buildTR != 2 || info->buildPartialTR) { /* deterministic */ 00755 vector = TfmCreateBitVector(info, composeIntermediateVars, 00756 findIntermediateVars); 00757 } else 00758 vector = NIL(array_t); 00759 00760 info->manager = mddManager; 00761 if (info->buildPartialTR) 00762 info->fullVector = vector; 00763 else 00764 info->vector = vector; 00765 if (info->buildTR == 2) 00766 info->useConstraint = 1; 00767 else if (info->option->splitMethod == 1) 00768 info->useConstraint = 0; 00769 else { 00770 if (info->option->rangeComp == 2) 00771 info->useConstraint = 2; 00772 else if (info->option->rangeComp == 0) 00773 info->useConstraint = 1; 00774 else 00775 info->useConstraint = 0; 00776 } 00777 if (info->option->useCache) { 00778 if (directionType == Img_Forward_c || directionType == Img_Both_c) { 00779 ImgCacheInitTable(info, info->option->initCacheSize, 00780 info->option->globalCache, FALSE); 00781 } 00782 if (directionType == Img_Backward_c || directionType == Img_Both_c) { 00783 ImgCacheInitTable(info, info->option->initCacheSize, 00784 info->option->globalCache, TRUE); 00785 } 00786 if (info->option->autoFlushCache == 2) { 00787 if (nHookInfoList == 0) { 00788 HookInfoList = st_init_table(st_ptrcmp, st_ptrhash); 00789 bdd_add_hook(info->manager, HookInfoFunction, BDD_PRE_REORDERING_HOOK); 00790 st_insert(HookInfoList, (char *)info, NIL(char)); 00791 } else { 00792 if (info->option->globalCache == 0) 00793 st_insert(HookInfoList, (char *)info, NIL(char)); 00794 } 00795 nHookInfoList++; 00796 } 00797 } 00798 00799 info->trmOption = ImgGetTrmOptions(); 00800 info->domainVarBddArray = functionData->domainBddVars; 00801 info->quantifyVarBddArray = functionData->quantifyBddVars; 00802 info->rangeVarBddArray = functionData->rangeBddVars; 00803 00804 if (info->vector && info->option->sortVectorFlag && info->option->useCache) 00805 array_sort(info->vector, CompareIndex); 00806 if (info->buildPartialTR) 00807 TfmSetupPartialTransitionRelation(info, NIL(array_t *)); 00808 if (info->buildTR) 00809 TfmBuildRelationArray(info, functionData, NIL(array_t), directionType, 1); 00810 if (info->buildTR == 1) { 00811 ImgPrintVectorDependency(info, info->vector, info->option->verbosity); 00812 if (info->option->writeSupportMatrix == 1) { 00813 sprintf(filename, "support%d.mat", info->option->supportFileCount++); 00814 ImgWriteSupportMatrix(info, info->vector, NIL(array_t), filename); 00815 } 00816 } 00817 if (info->option->writeSupportMatrixAndStop) 00818 exit(0); 00819 00820 flagValue = Cmd_FlagReadByName("image_eliminate_depend_vars"); 00821 if (flagValue == NIL(char)) 00822 info->eliminateDepend = 0; /* the default value */ 00823 else 00824 info->eliminateDepend = atoi(flagValue); 00825 if (info->eliminateDepend && bdd_get_package_name() != CUDD) { 00826 fprintf(vis_stderr, 00827 "** tfm error : image_eliminate_depend_vars is available for only CUDD.\n"); 00828 info->eliminateDepend = 0; 00829 } 00830 info->nPrevEliminatedFwd = -1; 00831 00832 flagValue = Cmd_FlagReadByName("image_verbosity"); 00833 if (flagValue) 00834 info->imageVerbosity = atoi(flagValue); 00835 00836 if (info->option->printEssential) { 00837 info->foundEssentials = ALLOC(int, IMG_TF_MAX_PRINT_DEPTH); 00838 memset(info->foundEssentials, 0, sizeof(int) * IMG_TF_MAX_PRINT_DEPTH); 00839 } 00840 if (info->option->debug) 00841 info->debugCareSet = bdd_one(mddManager); 00842 else 00843 info->debugCareSet = NIL(mdd_t); 00844 return((void *)info); 00845 } 00846 00847 00859 mdd_t * 00860 ImgImageInfoComputeFwdTfm(ImgFunctionData_t *functionData, 00861 Img_ImageInfo_t *imageInfo, 00862 mdd_t *fromLowerBound, 00863 mdd_t *fromUpperBound, 00864 array_t *toCareSetArray) 00865 { 00866 ImgTfmInfo_t *info = (ImgTfmInfo_t *)imageInfo->methodData; 00867 mdd_t *image, *domainSubset; 00868 00869 if (info->vector == NIL(array_t) && 00870 !(info->buildTR == 2 && info->fwdClusteredRelationArray)) { 00871 fprintf(vis_stderr, "** img error: The data structure has not been "); 00872 fprintf(vis_stderr, "initialized for image computation\n"); 00873 return(NIL(mdd_t)); 00874 } 00875 00876 info->updatedFlag = FALSE; 00877 domainSubset = bdd_between(fromLowerBound, fromUpperBound); 00878 00879 image = ImgTfmImage(info, domainSubset); 00880 00881 mdd_free(domainSubset); 00882 return(image); 00883 } 00884 00885 00898 mdd_t * 00899 ImgImageInfoComputeFwdWithDomainVarsTfm(ImgFunctionData_t *functionData, 00900 Img_ImageInfo_t *imageInfo, 00901 mdd_t *fromLowerBound, 00902 mdd_t *fromUpperBound, 00903 array_t *toCareSetArray) 00904 { 00905 mdd_t *image; 00906 00907 image = ImgImageInfoComputeFwdTfm(functionData, 00908 imageInfo , fromLowerBound, fromUpperBound, toCareSetArray); 00909 return(image); 00910 } 00911 00912 00924 mdd_t * 00925 ImgImageInfoComputeBwdTfm(ImgFunctionData_t *functionData, 00926 Img_ImageInfo_t *imageInfo, 00927 mdd_t *fromLowerBound, 00928 mdd_t *fromUpperBound, 00929 array_t *toCareSetArray) 00930 { 00931 ImgTfmInfo_t *info = (ImgTfmInfo_t *)imageInfo->methodData; 00932 mdd_t *image, *domainSubset, *simplifiedImage; 00933 array_t *replace; 00934 00935 if (info->vector == NIL(array_t) && 00936 !(info->buildTR == 2 && info->bwdClusteredRelationArray)) { 00937 fprintf(vis_stderr, "** img error: The data structure has not been "); 00938 fprintf(vis_stderr, "initialized for backward image computation\n"); 00939 return(NIL(mdd_t)); 00940 } 00941 00942 info->updatedFlag = FALSE; 00943 domainSubset = bdd_between(fromLowerBound, fromUpperBound); 00944 00945 if (info->toCareSetArray) 00946 replace = info->toCareSetArray; 00947 else { 00948 replace = NIL(array_t); 00949 info->toCareSetArray = toCareSetArray; 00950 } 00951 image = ImgTfmPreImage(info, domainSubset); 00952 info->toCareSetArray = replace; 00953 00954 mdd_free(domainSubset); 00955 simplifiedImage = bdd_minimize_array(image, toCareSetArray); 00956 bdd_free(image); 00957 return(simplifiedImage); 00958 } 00959 00960 00972 mdd_t * 00973 ImgImageInfoComputeBwdWithDomainVarsTfm(ImgFunctionData_t *functionData, 00974 Img_ImageInfo_t *imageInfo, 00975 mdd_t *fromLowerBound, 00976 mdd_t *fromUpperBound, 00977 array_t *toCareSetArray) 00978 { 00979 mdd_t *image; 00980 00981 image = ImgImageInfoComputeBwdTfm(functionData, 00982 imageInfo, fromLowerBound, fromUpperBound, toCareSetArray); 00983 return(image); 00984 } 00985 00986 00996 void 00997 ImgImageInfoFreeTfm(void *methodData) 00998 { 00999 ImgTfmInfo_t *info = (ImgTfmInfo_t *)methodData; 01000 01001 if (info == NIL(ImgTfmInfo_t)) { 01002 fprintf(vis_stderr, "** img error: Trying to free the NULL image info\n"); 01003 return; 01004 } 01005 if (info->option->printStatistics) { 01006 if (info->nRecursion) { 01007 if (info->imgCache) 01008 ImgPrintCacheStatistics(info->imgCache); 01009 PrintRecursionStatistics(info, 0); 01010 PrintFoundVariableStatistics(info, 0); 01011 } 01012 if (info->nRecursionB) { 01013 if (info->preCache) 01014 ImgPrintCacheStatistics(info->preCache); 01015 PrintRecursionStatistics(info, 1); 01016 PrintFoundVariableStatistics(info, 1); 01017 } 01018 } 01019 if (info->vector != NIL(array_t)) 01020 ImgVectorFree(info->vector); 01021 if (info->toCareSetArray != NIL(array_t)) 01022 mdd_array_free(info->toCareSetArray); 01023 if (info->imgCache) 01024 ImgCacheDestroyTable(info->imgCache, info->option->globalCache); 01025 if (info->preCache) 01026 ImgCacheDestroyTable(info->preCache, info->option->globalCache); 01027 st_free_table(info->quantifyVarsTable); 01028 st_free_table(info->rangeVarsTable); 01029 if (info->intermediateVarsTable) { 01030 st_free_table(info->intermediateVarsTable); 01031 info->intermediateVarsTable = NIL(st_table); 01032 } 01033 if (info->intermediateBddVars) { 01034 mdd_array_free(info->intermediateBddVars); 01035 info->intermediateBddVars= NIL(array_t); 01036 } 01037 if (info->newQuantifyBddVars) { 01038 mdd_array_free(info->newQuantifyBddVars); 01039 info->newQuantifyBddVars = NIL(array_t); 01040 } 01041 01042 if (info->option->useCache) { 01043 if (info->option->autoFlushCache == 2) { 01044 nHookInfoList--; 01045 st_delete(HookInfoList, &info, NULL); 01046 if (nHookInfoList == 0) { 01047 st_free_table(HookInfoList); 01048 bdd_remove_hook(info->manager, HookInfoFunction, 01049 BDD_PRE_REORDERING_HOOK); 01050 } 01051 } 01052 } 01053 if (info->option != NULL) 01054 FREE(info->option); 01055 01056 if (info->fwdClusteredRelationArray) 01057 mdd_array_free(info->fwdClusteredRelationArray); 01058 if (info->bwdClusteredRelationArray) 01059 mdd_array_free(info->bwdClusteredRelationArray); 01060 if (info->fwdArraySmoothVarBddArray) 01061 mdd_array_array_free(info->fwdArraySmoothVarBddArray); 01062 if (info->bwdArraySmoothVarBddArray) 01063 mdd_array_array_free(info->bwdArraySmoothVarBddArray); 01064 if (info->fwdSmoothVarCubeArray) 01065 mdd_array_free(info->fwdSmoothVarCubeArray); 01066 if (info->bwdSmoothVarCubeArray) 01067 mdd_array_free(info->bwdSmoothVarCubeArray); 01068 if (info->trmOption) 01069 ImgFreeTrmOptions(info->trmOption); 01070 if (info->partialBddVars) 01071 mdd_array_free(info->partialBddVars); 01072 if (info->partialVarFlag) 01073 FREE(info->partialVarFlag); 01074 if (info->fullVector != NIL(array_t)) 01075 ImgVectorFree(info->fullVector); 01076 01077 if (info->foundEssentials) 01078 FREE(info->foundEssentials); 01079 if (info->debugCareSet) 01080 mdd_free(info->debugCareSet); 01081 01082 if (info->savedArraySmoothVarBddArray != NIL(array_t)) 01083 mdd_array_array_free(info->savedArraySmoothVarBddArray); 01084 if (info->savedSmoothVarCubeArray != NIL(array_t)) 01085 mdd_array_free(info->savedSmoothVarCubeArray); 01086 FREE(info); 01087 } 01088 01089 01100 void 01101 ImgImageInfoPrintMethodParamsTfm(void *methodData, FILE *fp) 01102 { 01103 ImgTfmInfo_t *info = (ImgTfmInfo_t *)methodData; 01104 01105 if (fp == NULL) 01106 return; 01107 if (info->vector) 01108 ImgPrintVectorDependency(info, info->vector, 1); 01109 if (info->method == Img_Tfm_c) { 01110 fprintf(vis_stdout, 01111 "For the options in tfm method, try print_tfm_options.\n"); 01112 return; 01113 } 01114 if (info->fwdClusteredRelationArray != NIL(array_t)) { 01115 fprintf(fp, "Shared size of transition relation for forward image"); 01116 fprintf(fp, " computation is %10ld BDD nodes (%-4d components)\n", 01117 bdd_size_multiple(info->fwdClusteredRelationArray), 01118 array_n(info->fwdClusteredRelationArray)); 01119 } 01120 if (info->bwdClusteredRelationArray != NIL(array_t)) { 01121 fprintf(fp, "Shared size of transition relation for backward image"); 01122 fprintf(fp, " computation is %10ld BDD nodes (%-4d components)\n", 01123 bdd_size_multiple(info->bwdClusteredRelationArray), 01124 array_n(info->bwdClusteredRelationArray)); 01125 } 01126 fprintf(vis_stdout, "For the options in hybrid method,"); 01127 fprintf(vis_stdout, " try print_hybrid_options and print_tfm_options.\n"); 01128 } 01129 01130 01140 void 01141 ImgRestoreTransitionFunction(Img_ImageInfo_t *imageInfo, 01142 Img_DirectionType directionType) 01143 { 01144 ImgTfmInfo_t *tfmInfo = (ImgTfmInfo_t *)imageInfo->methodData; 01145 01146 if (tfmInfo->vector) { 01147 ImgVectorFree(tfmInfo->vector); 01148 tfmInfo->vector = (array_t *)imageInfo->savedRelation; 01149 imageInfo->savedRelation = NIL(void); 01150 } 01151 if (tfmInfo->fwdClusteredRelationArray) { 01152 if (directionType == Img_Forward_c || directionType == Img_Both_c) { 01153 mdd_array_free(tfmInfo->fwdClusteredRelationArray); 01154 tfmInfo->fwdClusteredRelationArray = tfmInfo->fwdSavedRelation; 01155 tfmInfo->fwdSavedRelation = NIL(array_t); 01156 } 01157 } 01158 if (tfmInfo->bwdClusteredRelationArray) { 01159 if (directionType == Img_Backward_c || directionType == Img_Both_c) { 01160 mdd_array_free(tfmInfo->bwdClusteredRelationArray); 01161 tfmInfo->bwdClusteredRelationArray = tfmInfo->bwdSavedRelation; 01162 tfmInfo->bwdSavedRelation = NIL(array_t); 01163 } 01164 } 01165 } 01166 01167 01177 void 01178 ImgDuplicateTransitionFunction(Img_ImageInfo_t *imageInfo, 01179 Img_DirectionType directionType) 01180 { 01181 array_t *copiedVector; 01182 array_t *copiedRelation; 01183 ImgTfmInfo_t *tfmInfo = (ImgTfmInfo_t *)imageInfo->methodData; 01184 01185 if (tfmInfo->vector) { 01186 copiedVector = ImgVectorCopy(tfmInfo, tfmInfo->vector); 01187 assert(!imageInfo->savedRelation); 01188 imageInfo->savedRelation = (void *)tfmInfo->vector; 01189 tfmInfo->vector = copiedVector; 01190 } 01191 if (tfmInfo->fwdClusteredRelationArray) { 01192 if (directionType == Img_Forward_c || directionType == Img_Both_c) { 01193 copiedRelation = mdd_array_duplicate(tfmInfo->fwdClusteredRelationArray); 01194 tfmInfo->fwdSavedRelation = tfmInfo->fwdClusteredRelationArray; 01195 tfmInfo->fwdClusteredRelationArray = copiedRelation; 01196 } 01197 } 01198 if (tfmInfo->bwdClusteredRelationArray) { 01199 if (directionType == Img_Backward_c || directionType == Img_Both_c) { 01200 copiedRelation = mdd_array_duplicate(tfmInfo->bwdClusteredRelationArray); 01201 tfmInfo->bwdSavedRelation = tfmInfo->bwdClusteredRelationArray; 01202 tfmInfo->bwdClusteredRelationArray = copiedRelation; 01203 } 01204 } 01205 } 01206 01207 01217 void 01218 ImgMinimizeTransitionFunction(void *methodData, 01219 array_t *constrainArray, Img_MinimizeType minimizeMethod, 01220 Img_DirectionType directionType, int printStatus) 01221 { 01222 ImgTfmInfo_t *info = (ImgTfmInfo_t *)methodData; 01223 int i, j; 01224 bdd_t *function, *simplifiedFunction; 01225 bdd_t *constrain; 01226 bdd_t *relation, *simplifiedRelation; 01227 int size = 0; 01228 long sizeConstrain; 01229 ImgComponent_t *comp; 01230 01231 if (printStatus) 01232 sizeConstrain = bdd_size_multiple(constrainArray); 01233 else 01234 sizeConstrain = 0; 01235 01236 if (info->vector) { 01237 if (printStatus) 01238 size = ImgVectorBddSize(info->vector); 01239 01240 arrayForEachItem(ImgComponent_t *, info->vector, i, comp) { 01241 function = mdd_dup(comp->func); 01242 arrayForEachItem(bdd_t *, constrainArray, j, constrain) { 01243 if (bdd_is_tautology(constrain, 1)) 01244 continue; 01245 simplifiedFunction = Img_MinimizeImage(function, constrain, 01246 minimizeMethod, TRUE); 01247 if (printStatus == 2) { 01248 (void) fprintf(vis_stdout, 01249 "IMG Info: minimized function %d | %d => %d in component %d\n", 01250 bdd_size(function), bdd_size(constrain), 01251 bdd_size(simplifiedFunction), i); 01252 } 01253 mdd_free(function); 01254 function = simplifiedFunction; 01255 } 01256 if (mdd_equal(function, comp->func)) 01257 mdd_free(function); 01258 else { 01259 mdd_free(comp->func); 01260 comp->func = function; 01261 ImgSupportClear(info, comp->support); 01262 ImgComponentGetSupport(comp); 01263 } 01264 } 01265 01266 if (printStatus) { 01267 (void) fprintf(vis_stdout, 01268 "IMG Info: minimized function [%d | %ld => %ld] with %d components\n", 01269 size, sizeConstrain, 01270 ImgVectorBddSize(info->vector), array_n(info->vector)); 01271 } 01272 } 01273 01274 if (info->buildTR == 0) 01275 return; 01276 else if (info->buildTR == 1 && info->option->synchronizeTr) { 01277 if (info->fwdClusteredRelationArray && 01278 (directionType == Img_Forward_c || directionType == Img_Both_c)) { 01279 RebuildTransitionRelation(info, Img_Forward_c); 01280 } 01281 if (info->bwdClusteredRelationArray && 01282 (directionType == Img_Backward_c || directionType == Img_Both_c)) { 01283 RebuildTransitionRelation(info, Img_Backward_c); 01284 } 01285 return; 01286 } 01287 01288 if (info->fwdClusteredRelationArray && 01289 (directionType == Img_Forward_c || directionType == Img_Both_c)) { 01290 if (printStatus) 01291 size = bdd_size_multiple(info->fwdClusteredRelationArray); 01292 arrayForEachItem(bdd_t *, constrainArray, i, constrain) { 01293 if (bdd_is_tautology(constrain, 1)) 01294 continue; 01295 01296 arrayForEachItem(bdd_t*, info->fwdClusteredRelationArray, j, relation) { 01297 simplifiedRelation = Img_MinimizeImage(relation, constrain, 01298 minimizeMethod, TRUE); 01299 if (printStatus == 2) { 01300 (void) fprintf(vis_stdout, 01301 "IMG Info: minimized fwd relation %d | %d => %d in component %d\n", 01302 bdd_size(relation), bdd_size(constrain), 01303 bdd_size(simplifiedRelation), j); 01304 } 01305 mdd_free(relation); 01306 array_insert(bdd_t*, info->fwdClusteredRelationArray, j, 01307 simplifiedRelation); 01308 } 01309 } 01310 if (printStatus) { 01311 (void) fprintf(vis_stdout, 01312 "IMG Info: minimized fwd relation [%d | %ld => %ld] with %d components\n", 01313 size, sizeConstrain, 01314 bdd_size_multiple(info->fwdClusteredRelationArray), 01315 array_n(info->fwdClusteredRelationArray)); 01316 } 01317 } 01318 if (info->bwdClusteredRelationArray && 01319 (directionType == Img_Backward_c || directionType == Img_Both_c)) { 01320 if (printStatus) 01321 size = bdd_size_multiple(info->bwdClusteredRelationArray); 01322 arrayForEachItem(bdd_t *, constrainArray, i, constrain) { 01323 if (bdd_is_tautology(constrain, 1)) 01324 continue; 01325 01326 arrayForEachItem(bdd_t*, info->bwdClusteredRelationArray, j, relation) { 01327 simplifiedRelation = Img_MinimizeImage(relation, constrain, 01328 minimizeMethod, TRUE); 01329 if (printStatus == 2) { 01330 (void) fprintf(vis_stdout, 01331 "IMG Info: minimized bwd relation %d | %d => %d in component %d\n", 01332 bdd_size(relation), bdd_size(constrain), 01333 bdd_size(simplifiedRelation), j); 01334 } 01335 mdd_free(relation); 01336 array_insert(bdd_t*, info->bwdClusteredRelationArray, j, 01337 simplifiedRelation); 01338 } 01339 } 01340 if (printStatus) { 01341 (void) fprintf(vis_stdout, 01342 "IMG Info: minimized bwd relation [%d | %ld => %ld] with %d components\n", 01343 size, sizeConstrain, 01344 bdd_size_multiple(info->bwdClusteredRelationArray), 01345 array_n(info->bwdClusteredRelationArray)); 01346 } 01347 } 01348 } 01349 01350 01361 void 01362 ImgAddDontCareToTransitionFunction(void *methodData, 01363 array_t *constrainArray, 01364 Img_MinimizeType minimizeMethod, 01365 Img_DirectionType directionType, 01366 int printStatus) 01367 { 01368 ImgTfmInfo_t *info = (ImgTfmInfo_t *)methodData; 01369 int i, j; 01370 bdd_t *function, *simplifiedFunction; 01371 bdd_t *constrain; 01372 bdd_t *relation, *simplifiedRelation; 01373 int size = 0; 01374 long sizeConstrain; 01375 ImgComponent_t *comp; 01376 01377 if (printStatus) 01378 sizeConstrain = bdd_size_multiple(constrainArray); 01379 else 01380 sizeConstrain = 0; 01381 01382 if (info->vector) { 01383 if (printStatus) 01384 size = ImgVectorBddSize(info->vector); 01385 01386 arrayForEachItem(ImgComponent_t *, info->vector, i, comp) { 01387 function = mdd_dup(comp->func); 01388 arrayForEachItem(bdd_t *, constrainArray, j, constrain) { 01389 if (bdd_is_tautology(constrain, 1)) 01390 continue; 01391 simplifiedFunction = Img_AddDontCareToImage(function, constrain, 01392 minimizeMethod); 01393 if (printStatus == 2) { 01394 (void) fprintf(vis_stdout, 01395 "IMG Info: minimized function %d | %d => %d in component %d\n", 01396 bdd_size(function), bdd_size(constrain), 01397 bdd_size(simplifiedFunction), i); 01398 } 01399 mdd_free(function); 01400 function = simplifiedFunction; 01401 } 01402 if (mdd_equal(function, comp->func)) 01403 mdd_free(function); 01404 else { 01405 mdd_free(comp->func); 01406 comp->func = function; 01407 ImgSupportClear(info, comp->support); 01408 ImgComponentGetSupport(comp); 01409 } 01410 } 01411 01412 if (printStatus) { 01413 (void) fprintf(vis_stdout, 01414 "IMG Info: minimized function [%d | %ld => %ld] with %d components\n", 01415 size, sizeConstrain, 01416 ImgVectorBddSize(info->vector), array_n(info->vector)); 01417 } 01418 } 01419 01420 if (info->buildTR == 0) 01421 return; 01422 else if (info->buildTR == 1 && info->option->synchronizeTr) { 01423 if (info->fwdClusteredRelationArray && 01424 (directionType == Img_Forward_c || directionType == Img_Both_c)) { 01425 RebuildTransitionRelation(info, Img_Forward_c); 01426 } 01427 if (info->bwdClusteredRelationArray && 01428 (directionType == Img_Backward_c || directionType == Img_Both_c)) { 01429 RebuildTransitionRelation(info, Img_Backward_c); 01430 } 01431 return; 01432 } 01433 01434 if (info->fwdClusteredRelationArray && 01435 (directionType == Img_Forward_c || directionType == Img_Both_c)) { 01436 if (printStatus) 01437 size = bdd_size_multiple(info->fwdClusteredRelationArray); 01438 arrayForEachItem(bdd_t *, constrainArray, i, constrain) { 01439 if (bdd_is_tautology(constrain, 1)) 01440 continue; 01441 01442 arrayForEachItem(bdd_t*, info->fwdClusteredRelationArray, j, relation) { 01443 simplifiedRelation = Img_AddDontCareToImage(relation, constrain, 01444 minimizeMethod); 01445 if (printStatus == 2) { 01446 (void) fprintf(vis_stdout, 01447 "IMG Info: minimized fwd relation %d | %d => %d in component %d\n", 01448 bdd_size(relation), bdd_size(constrain), 01449 bdd_size(simplifiedRelation), j); 01450 } 01451 mdd_free(relation); 01452 array_insert(bdd_t*, info->fwdClusteredRelationArray, j, 01453 simplifiedRelation); 01454 } 01455 } 01456 if (printStatus) { 01457 (void) fprintf(vis_stdout, 01458 "IMG Info: minimized fwd relation [%d | %ld => %ld] with %d components\n", 01459 size, sizeConstrain, 01460 bdd_size_multiple(info->fwdClusteredRelationArray), 01461 array_n(info->fwdClusteredRelationArray)); 01462 } 01463 } 01464 if (info->bwdClusteredRelationArray && 01465 (directionType == Img_Backward_c || directionType == Img_Both_c)) { 01466 if (printStatus) 01467 size = bdd_size_multiple(info->bwdClusteredRelationArray); 01468 arrayForEachItem(bdd_t *, constrainArray, i, constrain) { 01469 if (bdd_is_tautology(constrain, 1)) 01470 continue; 01471 01472 arrayForEachItem(bdd_t*, info->bwdClusteredRelationArray, j, relation) { 01473 simplifiedRelation = Img_AddDontCareToImage(relation, constrain, 01474 minimizeMethod); 01475 if (printStatus == 2) { 01476 (void) fprintf(vis_stdout, 01477 "IMG Info: minimized bwd relation %d | %d => %d in component %d\n", 01478 bdd_size(relation), bdd_size(constrain), 01479 bdd_size(simplifiedRelation), j); 01480 } 01481 mdd_free(relation); 01482 array_insert(bdd_t*, info->bwdClusteredRelationArray, j, 01483 simplifiedRelation); 01484 } 01485 } 01486 if (printStatus) { 01487 (void) fprintf(vis_stdout, 01488 "IMG Info: minimized bwd relation [%d | %ld => %ld] with %d components\n", 01489 size, sizeConstrain, 01490 bdd_size_multiple(info->bwdClusteredRelationArray), 01491 array_n(info->bwdClusteredRelationArray)); 01492 } 01493 } 01494 } 01495 01496 01507 void 01508 ImgAbstractTransitionFunction(Img_ImageInfo_t *imageInfo, 01509 array_t *abstractVars, mdd_t *abstractCube, 01510 Img_DirectionType directionType, int printStatus) 01511 { 01512 ImgTfmInfo_t *info = (ImgTfmInfo_t *)imageInfo->methodData; 01513 int i, size = 0; 01514 bdd_t *abstractedFunction; 01515 ImgComponent_t *comp; 01516 array_t *vector; 01517 int flag = 0; 01518 int fwd_size = 0, bwd_size = 0; 01519 bdd_t *relation, *abstractedRelation; 01520 01521 if (!abstractVars || array_n(abstractVars) == 0) 01522 return; 01523 01524 if (info->vector) { 01525 if (printStatus) 01526 size = ImgVectorBddSize(info->vector); 01527 01528 arrayForEachItem(ImgComponent_t *, info->vector, i, comp) { 01529 if (bdd_is_tautology(comp->func, 1)) 01530 continue; 01531 if (abstractCube) 01532 abstractedFunction = bdd_smooth_with_cube(comp->func, abstractCube); 01533 else 01534 abstractedFunction = bdd_smooth(comp->func, abstractVars); 01535 if (bdd_is_tautology(abstractedFunction, 1)) { 01536 comp->flag = 1; 01537 flag = 1; 01538 continue; 01539 } 01540 if (mdd_equal(abstractedFunction, comp->func)) 01541 mdd_free(abstractedFunction); 01542 else { 01543 if (printStatus == 2) { 01544 (void) fprintf(vis_stdout, 01545 "IMG Info: abstracted function %d => %d in component %d\n", 01546 bdd_size(comp->func), bdd_size(abstractedFunction), i); 01547 } 01548 mdd_free(comp->func); 01549 comp->func = abstractedFunction; 01550 ImgSupportClear(info, comp->support); 01551 ImgComponentGetSupport(comp); 01552 } 01553 } 01554 01555 if (flag) { 01556 vector = info->vector; 01557 info->vector = array_alloc(ImgComponent_t *, 0); 01558 arrayForEachItem(ImgComponent_t *, vector, i, comp) { 01559 if (comp->flag) { 01560 ImgComponentFree(comp); 01561 continue; 01562 } 01563 array_insert_last(ImgComponent_t *, info->vector, comp); 01564 } 01565 array_free(vector); 01566 } 01567 01568 if (printStatus) { 01569 (void) fprintf(vis_stdout, 01570 "IMG Info: abstracted function [%d => %ld] with %d components\n", 01571 size, ImgVectorBddSize(info->vector), 01572 array_n(info->vector)); 01573 } 01574 } 01575 01576 if (info->buildTR == 0) 01577 return; 01578 else if (info->buildTR == 1 && info->option->synchronizeTr) { 01579 if (info->fwdClusteredRelationArray && 01580 (directionType == Img_Forward_c || directionType == Img_Both_c)) { 01581 RebuildTransitionRelation(info, Img_Forward_c); 01582 } 01583 if (info->bwdClusteredRelationArray && 01584 (directionType == Img_Backward_c || directionType == Img_Both_c)) { 01585 RebuildTransitionRelation(info, Img_Backward_c); 01586 } 01587 return; 01588 } 01589 01590 if (printStatus) { 01591 if (directionType == Img_Forward_c || directionType == Img_Both_c) 01592 fwd_size = bdd_size_multiple(info->fwdClusteredRelationArray); 01593 if (directionType == Img_Backward_c || directionType == Img_Both_c) 01594 bwd_size = bdd_size_multiple(info->bwdClusteredRelationArray); 01595 } 01596 if (info->fwdClusteredRelationArray && 01597 (directionType == Img_Forward_c || directionType == Img_Both_c)) { 01598 arrayForEachItem(bdd_t*, info->fwdClusteredRelationArray, i, relation) { 01599 if (abstractCube) 01600 abstractedRelation = bdd_smooth_with_cube(relation, abstractCube); 01601 else 01602 abstractedRelation = bdd_smooth(relation, abstractVars); 01603 if (printStatus == 2) { 01604 (void) fprintf(vis_stdout, 01605 "IMG Info: abstracted fwd relation %d => %d in component %d\n", 01606 bdd_size(relation), bdd_size(abstractedRelation), i); 01607 } 01608 mdd_free(relation); 01609 array_insert(bdd_t*, info->fwdClusteredRelationArray, i, 01610 abstractedRelation); 01611 } 01612 } 01613 if (info->bwdClusteredRelationArray && 01614 (directionType == Img_Backward_c || directionType == Img_Both_c)) { 01615 arrayForEachItem(bdd_t*, info->bwdClusteredRelationArray, i, relation) { 01616 if (abstractCube) 01617 abstractedRelation = bdd_smooth_with_cube(relation, abstractCube); 01618 else 01619 abstractedRelation = bdd_smooth(relation, abstractVars); 01620 if (printStatus == 2) { 01621 (void) fprintf(vis_stdout, 01622 "IMG Info: abstracted bwd relation %d => %d in component %d\n", 01623 bdd_size(relation), bdd_size(abstractedRelation), i); 01624 } 01625 mdd_free(relation); 01626 array_insert(bdd_t*, info->bwdClusteredRelationArray, i, 01627 abstractedRelation); 01628 } 01629 } 01630 if (printStatus) { 01631 if (directionType == Img_Forward_c || directionType == Img_Both_c) { 01632 (void) fprintf(vis_stdout, 01633 "IMG Info: abstracted fwd relation [%d => %ld] with %d components\n", 01634 fwd_size, 01635 bdd_size_multiple(info->fwdClusteredRelationArray), 01636 array_n(info->fwdClusteredRelationArray)); 01637 } 01638 if (directionType == Img_Backward_c || directionType == Img_Both_c) { 01639 (void) fprintf(vis_stdout, 01640 "IMG Info: abstracted bwd relation [%d => %ld] with %d components\n", 01641 bwd_size, 01642 bdd_size_multiple(info->bwdClusteredRelationArray), 01643 array_n(info->bwdClusteredRelationArray)); 01644 } 01645 } 01646 } 01647 01648 01658 int 01659 ImgApproximateTransitionFunction(mdd_manager *mgr, 01660 void *methodData, bdd_approx_dir_t approxDir, 01661 bdd_approx_type_t approxMethod, int approxThreshold, 01662 double approxQuality, double approxQualityBias, 01663 Img_DirectionType directionType, mdd_t *bias) 01664 { 01665 ImgTfmInfo_t *info = (ImgTfmInfo_t *)methodData; 01666 int i; 01667 bdd_t *approxFunction; 01668 int unchanged = 0; 01669 ImgComponent_t *comp; 01670 bdd_t *relation, *approxRelation; 01671 01672 if (info->vector) { 01673 arrayForEachItem(ImgComponent_t *, info->vector, i, comp) { 01674 approxFunction = Img_ApproximateImage(mgr, comp->func, 01675 approxDir, approxMethod, 01676 approxThreshold, approxQuality, 01677 approxQualityBias, bias); 01678 if (bdd_is_tautology(approxFunction, 1)) { 01679 fprintf(vis_stdout, 01680 "** img warning : bdd_one from subsetting in [%d].\n", i); 01681 mdd_free(approxFunction); 01682 unchanged++; 01683 } else if (bdd_is_tautology(approxFunction, 0)) { 01684 fprintf(vis_stdout, 01685 "** img warning : bdd_zero from subsetting in [%d].\n", i); 01686 mdd_free(approxFunction); 01687 unchanged++; 01688 } else if (mdd_equal(approxFunction, comp->func)) { 01689 mdd_free(approxFunction); 01690 unchanged++; 01691 } else { 01692 mdd_free(comp->func); 01693 comp->func = approxFunction; 01694 ImgSupportClear(info, comp->support); 01695 ImgComponentGetSupport(comp); 01696 } 01697 } 01698 } 01699 01700 if (info->buildTR == 0) 01701 return(unchanged); 01702 else if (info->buildTR == 1 && info->option->synchronizeTr) { 01703 if (info->fwdClusteredRelationArray && 01704 (directionType == Img_Forward_c || directionType == Img_Both_c)) { 01705 RebuildTransitionRelation(info, Img_Forward_c); 01706 } 01707 if (info->bwdClusteredRelationArray && 01708 (directionType == Img_Backward_c || directionType == Img_Both_c)) { 01709 RebuildTransitionRelation(info, Img_Backward_c); 01710 } 01711 return(unchanged); 01712 } 01713 01714 if (info->fwdClusteredRelationArray && 01715 (directionType == Img_Forward_c || directionType == Img_Both_c)) { 01716 arrayForEachItem(bdd_t*, info->fwdClusteredRelationArray, i, relation) { 01717 approxRelation = Img_ApproximateImage(mgr, relation, 01718 approxDir, approxMethod, 01719 approxThreshold, approxQuality, 01720 approxQualityBias, bias); 01721 if (bdd_is_tautology(approxRelation, 1)) { 01722 fprintf(vis_stdout, 01723 "** img warning : bdd_one from subsetting in fwd[%d].\n", i); 01724 mdd_free(approxRelation); 01725 unchanged++; 01726 } else if (bdd_is_tautology(approxRelation, 0)) { 01727 fprintf(vis_stdout, 01728 "** img warning : bdd_zero from subsetting in fwd[%d].\n", i); 01729 mdd_free(approxRelation); 01730 unchanged++; 01731 } else if (mdd_equal(approxRelation, relation)) { 01732 mdd_free(approxRelation); 01733 unchanged++; 01734 } else { 01735 mdd_free(relation); 01736 array_insert(bdd_t*, info->fwdClusteredRelationArray, i, 01737 approxRelation); 01738 } 01739 } 01740 } 01741 if (info->bwdClusteredRelationArray && 01742 (directionType == Img_Backward_c || directionType == Img_Both_c)) { 01743 arrayForEachItem(bdd_t*, info->bwdClusteredRelationArray, i, relation) { 01744 approxRelation = Img_ApproximateImage(mgr, relation, 01745 approxDir, approxMethod, 01746 approxThreshold, approxQuality, 01747 approxQualityBias, bias); 01748 if (bdd_is_tautology(approxRelation, 1)) { 01749 fprintf(vis_stdout, 01750 "** img warning : bdd_one from subsetting in bwd[%d].\n", i); 01751 mdd_free(approxRelation); 01752 unchanged++; 01753 } else if (bdd_is_tautology(approxRelation, 0)) { 01754 fprintf(vis_stdout, 01755 "** img warning : bdd_zero from subsetting in bwd[%d].\n", i); 01756 mdd_free(approxRelation); 01757 unchanged++; 01758 } else if (mdd_equal(approxRelation, relation)) { 01759 mdd_free(approxRelation); 01760 unchanged++; 01761 } else { 01762 mdd_free(relation); 01763 array_insert(bdd_t*, info->bwdClusteredRelationArray, i, 01764 approxRelation); 01765 } 01766 } 01767 } 01768 return(unchanged); 01769 } 01770 01771 01781 array_t * 01782 ImgGetTransitionFunction(void *methodData, Img_DirectionType directionType) 01783 { 01784 ImgTfmInfo_t *tfmInfo = (ImgTfmInfo_t *)methodData; 01785 if (tfmInfo->vector) 01786 return(tfmInfo->vector); 01787 if (directionType == Img_Forward_c) 01788 return(tfmInfo->fwdClusteredRelationArray); 01789 return(tfmInfo->bwdClusteredRelationArray); 01790 } 01791 01792 01802 void 01803 ImgUpdateTransitionFunction(void *methodData, array_t *vector, 01804 Img_DirectionType directionType) 01805 { 01806 ImgTfmInfo_t *tfmInfo = (ImgTfmInfo_t *)methodData; 01807 if (tfmInfo->vector) 01808 tfmInfo->vector = vector; 01809 else if (directionType == Img_Forward_c) 01810 tfmInfo->fwdClusteredRelationArray = vector; 01811 else 01812 tfmInfo->bwdClusteredRelationArray = vector; 01813 } 01814 01815 01825 void 01826 ImgReplaceIthTransitionFunction(void *methodData, int i, mdd_t *function, 01827 Img_DirectionType directionType) 01828 { 01829 ImgTfmInfo_t *info = (ImgTfmInfo_t *)methodData; 01830 array_t *relationArray; 01831 ImgComponent_t *comp; 01832 mdd_t *old; 01833 01834 if (info->vector) { 01835 comp = array_fetch(ImgComponent_t *, info->vector, i); 01836 mdd_free(comp->func); 01837 comp->func = function; 01838 ImgSupportClear(info, comp->support); 01839 ImgComponentGetSupport(comp); 01840 return; 01841 } 01842 01843 if (directionType == Img_Forward_c) 01844 relationArray = info->fwdClusteredRelationArray; 01845 else 01846 relationArray = info->bwdClusteredRelationArray; 01847 01848 old = array_fetch(mdd_t *, relationArray, i); 01849 mdd_free(old); 01850 array_insert(mdd_t *, relationArray, i, function); 01851 } 01852 01853 01865 ImgTfmOption_t * 01866 ImgTfmGetOptions(Img_MethodType method) 01867 { 01868 char *flagValue; 01869 ImgTfmOption_t *option; 01870 01871 option = ALLOC(ImgTfmOption_t, 1); 01872 memset(option, 0, sizeof(ImgTfmOption_t)); 01873 01874 option->debug = ReadSetBooleanValue("tfm_debug", FALSE); 01875 option->checkEquivalence = ReadSetBooleanValue("tfm_check_equivalence", 01876 FALSE); 01877 option->writeSupportMatrix = ReadSetIntValue("tfm_write_support_matrix", 01878 0, 2, 0); 01879 option->writeSupportMatrixWithYvars = 01880 ReadSetBooleanValue("tfm_write_support_matrix_with_y", FALSE); 01881 option->writeSupportMatrixAndStop = 01882 ReadSetBooleanValue("tfm_write_support_matrix_and_stop", FALSE); 01883 option->writeSupportMatrixReverseRow = 01884 ReadSetBooleanValue("tfm_write_support_matrix_reverse_row", TRUE); 01885 option->writeSupportMatrixReverseCol = 01886 ReadSetBooleanValue("tfm_write_support_matrix_reverse_col", TRUE); 01887 01888 option->verbosity = ReadSetIntValue("tfm_verbosity", 0, 2, 0); 01889 if (method == Img_Tfm_c) 01890 option->splitMethod = ReadSetIntValue("tfm_split_method", 0, 3, 0); 01891 else 01892 option->splitMethod = 3; /* the default value */ 01893 option->inputSplit = ReadSetIntValue("tfm_input_split", 0, 3, 0); 01894 option->piSplitFlag = ReadSetBooleanValue("tfm_pi_split_flag", TRUE); 01895 if (method == Img_Tfm_c) 01896 option->rangeComp = ReadSetIntValue("tfm_range_comp", 0, 2, 1); 01897 else 01898 option->rangeComp = ReadSetIntValue("tfm_range_comp", 0, 2, 2); 01899 01900 flagValue = Cmd_FlagReadByName("tfm_range_threshold"); 01901 if (flagValue == NIL(char)) 01902 option->rangeThreshold = 10; /* the default value */ 01903 else 01904 option->rangeThreshold = atoi(flagValue); 01905 01906 flagValue = Cmd_FlagReadByName("tfm_range_try_threshold"); 01907 if (flagValue == NIL(char)) 01908 option->rangeTryThreshold = 2; /* the default value */ 01909 else 01910 option->rangeTryThreshold = atoi(flagValue); 01911 01912 option->rangeCheckReorder = 01913 ReadSetBooleanValue("tfm_range_check_reorder", FALSE); 01914 option->tieBreakMode = ReadSetIntValue("tfm_tie_break", 0, 1, 0); 01915 01916 option->outputSplit = ReadSetIntValue("tfm_output_split", 0, 2, 0); 01917 01918 flagValue = Cmd_FlagReadByName("tfm_turn_depth"); 01919 if (flagValue == NIL(char)) { 01920 if (method == Img_Tfm_c) 01921 option->turnDepth = 5; /* the default for tfm */ 01922 else 01923 option->turnDepth = -1; /* the default for hybrid */ 01924 } else 01925 option->turnDepth = atoi(flagValue); 01926 01927 option->findDecompVar = ReadSetBooleanValue("tfm_find_decomp_var", FALSE); 01928 option->globalCache = ReadSetBooleanValue("tfm_global_cache", TRUE); 01929 01930 flagValue = Cmd_FlagReadByName("tfm_use_cache"); 01931 if (flagValue == NIL(char)) { 01932 if (method == Img_Tfm_c) 01933 option->useCache = 1; 01934 else 01935 option->useCache = 0; 01936 } else 01937 option->useCache = atoi(flagValue); 01938 01939 flagValue = Cmd_FlagReadByName("tfm_max_chain_length"); 01940 if (flagValue == NIL(char)) 01941 option->maxChainLength = 2; /* the default value */ 01942 else 01943 option->maxChainLength = atoi(flagValue); 01944 01945 flagValue = Cmd_FlagReadByName("tfm_init_cache_size"); 01946 if (flagValue == NIL(char)) 01947 option->initCacheSize = 1001; /* the default value */ 01948 else 01949 option->initCacheSize = atoi(flagValue); 01950 01951 option->autoFlushCache = ReadSetIntValue("tfm_auto_flush_cache", 0, 2, 1); 01952 if (method == Img_Tfm_c) 01953 option->sortVectorFlag = ReadSetBooleanValue("tfm_sort_vector", TRUE); 01954 else 01955 option->sortVectorFlag = ReadSetBooleanValue("tfm_sort_vector", FALSE); 01956 option->printStatistics = ReadSetBooleanValue("tfm_print_stats", FALSE); 01957 option->printBddSize = ReadSetBooleanValue("tfm_print_bdd_size", FALSE); 01958 01959 flagValue = Cmd_FlagReadByName("tfm_max_essential_depth"); 01960 if (flagValue == NIL(char)) 01961 option->maxEssentialDepth = 5; /* the default value */ 01962 else 01963 option->maxEssentialDepth = atoi(flagValue); 01964 01965 option->findEssential = ReadSetIntValue("tfm_find_essential", 0, 2, 0); 01966 if (option->findEssential && bdd_get_package_name() != CUDD) { 01967 fprintf(vis_stderr, 01968 "** tfm error: tfm_find_essential is available for only CUDD.\n"); 01969 option->findEssential = 0; 01970 } 01971 option->printEssential = ReadSetIntValue("tfm_print_essential", 0, 2, 0); 01972 option->splitCubeFunc = ReadSetBooleanValue("tfm_split_cube_func", FALSE); 01973 option->composeIntermediateVars = 01974 ReadSetBooleanValue("tfm_compose_intermediate_vars", FALSE); 01975 01976 if (method == Img_Tfm_c) 01977 option->preSplitMethod = ReadSetIntValue("tfm_pre_split_method", 0, 4, 0); 01978 else 01979 option->preSplitMethod = 4; 01980 option->preInputSplit = ReadSetIntValue("tfm_pre_input_split", 0, 3, 0); 01981 option->preOutputSplit = ReadSetIntValue("tfm_pre_output_split", 0, 2, 0); 01982 option->preDcLeafMethod = ReadSetIntValue("tfm_pre_dc_leaf_method", 0, 2, 0); 01983 option->preMinimize = ReadSetBooleanValue("tfm_pre_minimize", FALSE); 01984 01985 option->trSplitMethod = ReadSetIntValue("hybrid_tr_split_method", 0, 1, 0); 01986 01987 option->hybridMode = ReadSetIntValue("hybrid_mode", 0, 2, 1); 01988 option->buildPartialTR = 01989 ReadSetBooleanValue("hybrid_build_partial_tr", FALSE); 01990 01991 flagValue = Cmd_FlagReadByName("hybrid_partial_num_vars"); 01992 if (flagValue == NIL(char)) 01993 option->nPartialVars = 8; /* the default value */ 01994 else 01995 option->nPartialVars = atoi(flagValue); 01996 01997 option->partialMethod = ReadSetIntValue("hybrid_partial_method", 0, 1, 0); 01998 01999 option->delayedSplit = ReadSetBooleanValue("hybrid_delayed_split", FALSE); 02000 02001 flagValue = Cmd_FlagReadByName("hybrid_split_min_depth"); 02002 if (flagValue == NIL(char)) 02003 option->splitMinDepth = 1; /* the default value */ 02004 else 02005 option->splitMinDepth = atoi(flagValue); 02006 02007 flagValue = Cmd_FlagReadByName("hybrid_split_max_depth"); 02008 if (flagValue == NIL(char)) 02009 option->splitMaxDepth = 5; /* the default value */ 02010 else 02011 option->splitMaxDepth = atoi(flagValue); 02012 02013 flagValue = Cmd_FlagReadByName("hybrid_pre_split_min_depth"); 02014 if (flagValue == NIL(char)) 02015 option->preSplitMinDepth = 0; /* the default value */ 02016 else 02017 option->preSplitMinDepth = atoi(flagValue); 02018 02019 flagValue = Cmd_FlagReadByName("hybrid_pre_split_max_depth"); 02020 if (flagValue == NIL(char)) 02021 option->preSplitMaxDepth = 4; /* the default value */ 02022 else 02023 option->preSplitMaxDepth = atoi(flagValue); 02024 02025 flagValue = Cmd_FlagReadByName("hybrid_lambda_threshold"); 02026 if (flagValue == NIL(char)) 02027 option->lambdaThreshold = 0.6; /* the default value */ 02028 else 02029 sscanf(flagValue, "%f", &option->lambdaThreshold); 02030 02031 flagValue = Cmd_FlagReadByName("hybrid_pre_lambda_threshold"); 02032 if (flagValue == NIL(char)) 02033 option->preLambdaThreshold = 0.65; /* the default value */ 02034 else 02035 sscanf(flagValue, "%f", &option->preLambdaThreshold); 02036 02037 flagValue = Cmd_FlagReadByName("hybrid_conjoin_vector_size"); 02038 if (flagValue == NIL(char)) 02039 option->conjoinVectorSize = 10; /* the default value */ 02040 else 02041 option->conjoinVectorSize = atoi(flagValue); 02042 02043 flagValue = Cmd_FlagReadByName("hybrid_conjoin_relation_size"); 02044 if (flagValue == NIL(char)) 02045 option->conjoinRelationSize = 1; /* the default value */ 02046 else 02047 option->conjoinRelationSize = atoi(flagValue); 02048 02049 flagValue = Cmd_FlagReadByName("hybrid_conjoin_relation_bdd_size"); 02050 if (flagValue == NIL(char)) 02051 option->conjoinRelationBddSize = 200; /* the default value */ 02052 else 02053 option->conjoinRelationBddSize = atoi(flagValue); 02054 02055 flagValue = Cmd_FlagReadByName("hybrid_improve_lambda"); 02056 if (flagValue == NIL(char)) 02057 option->improveLambda = 0.1; /* the default value */ 02058 else 02059 sscanf(flagValue, "%f", &option->improveLambda); 02060 02061 flagValue = Cmd_FlagReadByName("hybrid_improve_vector_size"); 02062 if (flagValue == NIL(char)) 02063 option->improveVectorSize = 3; /* the default value */ 02064 else 02065 option->improveVectorSize = atoi(flagValue); 02066 02067 flagValue = Cmd_FlagReadByName("hybrid_improve_vector_bdd_size"); 02068 if (flagValue == NIL(char)) 02069 option->improveVectorBddSize = 30.0; /* the default value */ 02070 else 02071 sscanf(flagValue, "%f", &option->improveVectorBddSize); 02072 02073 option->decideMode = ReadSetIntValue("hybrid_decide_mode", 0, 3, 3); 02074 02075 option->reorderWithFrom = 02076 ReadSetBooleanValue("hybrid_reorder_with_from", TRUE); 02077 option->preReorderWithFrom = 02078 ReadSetBooleanValue("hybrid_pre_reorder_with_from", FALSE); 02079 02080 option->lambdaMode = ReadSetIntValue("hybrid_lambda_mode", 0, 2, 0); 02081 option->preLambdaMode = ReadSetIntValue("hybrid_pre_lambda_mode", 0, 3, 2); 02082 option->lambdaWithFrom = ReadSetBooleanValue("hybrid_lambda_with_from", TRUE); 02083 option->lambdaWithTr = ReadSetBooleanValue("hybrid_lambda_with_tr", TRUE); 02084 option->lambdaWithClustering = 02085 ReadSetBooleanValue("hybrid_lambda_with_clustering", FALSE); 02086 02087 option->synchronizeTr = ReadSetBooleanValue("hybrid_synchronize_tr", FALSE); 02088 option->imgKeepPiInTr = ReadSetBooleanValue("hybrid_img_keep_pi", FALSE); 02089 option->preKeepPiInTr = ReadSetBooleanValue("hybrid_pre_keep_pi", FALSE); 02090 02091 flagValue = Cmd_FlagReadByName("hybrid_tr_method"); 02092 if (flagValue == NIL(char)) 02093 option->trMethod = Img_Iwls95_c; /* the default value */ 02094 else { 02095 if (strcmp(flagValue, "iwls95") == 0) 02096 option->trMethod = Img_Iwls95_c; 02097 else if (strcmp(flagValue, "mlp") == 0) 02098 option->trMethod = Img_Mlp_c; 02099 else { 02100 fprintf(vis_stderr, 02101 "** tfm error : invalid value %s for hybrid_tr_method\n", 02102 flagValue); 02103 option->trMethod = Img_Iwls95_c; 02104 } 02105 } 02106 option->preCanonical = ReadSetBooleanValue("hybrid_pre_canonical", FALSE); 02107 02108 option->printLambda = ReadSetBooleanValue("hybrid_print_lambda", FALSE); 02109 02110 return(option); 02111 } 02112 02113 02125 void 02126 ImgImageFreeClusteredTransitionRelationTfm(void *methodData, 02127 Img_DirectionType directionType) 02128 { 02129 ImgTfmInfo_t *info = (ImgTfmInfo_t *)methodData; 02130 02131 if (info->vector) { 02132 ImgVectorFree(info->vector); 02133 info->vector = NIL(array_t); 02134 } 02135 if (info->fullVector) { 02136 ImgVectorFree(info->fullVector); 02137 info->fullVector = NIL(array_t); 02138 } 02139 if (info->partialBddVars) 02140 mdd_array_free(info->partialBddVars); 02141 if (info->partialVarFlag) 02142 FREE(info->partialVarFlag); 02143 if (info->fwdClusteredRelationArray != NIL(array_t)) { 02144 mdd_array_free(info->fwdClusteredRelationArray); 02145 info->fwdClusteredRelationArray = NIL(array_t); 02146 } 02147 if (info->bwdClusteredRelationArray != NIL(array_t)) { 02148 mdd_array_free(info->bwdClusteredRelationArray); 02149 info->bwdClusteredRelationArray = NIL(array_t); 02150 } 02151 } 02152 02153 02171 void 02172 ImgImageConstrainAndClusterTransitionRelationTfm(Img_ImageInfo_t *imageInfo, 02173 Img_DirectionType direction, 02174 mdd_t *constrain, 02175 Img_MinimizeType minimizeMethod, 02176 boolean underApprox, 02177 boolean cleanUp, 02178 boolean forceReorder, 02179 int printStatus) 02180 { 02181 ImgFunctionData_t *functionData = &(imageInfo->functionData); 02182 ImgTfmInfo_t *info = (ImgTfmInfo_t *)imageInfo->methodData; 02183 graph_t *mddNetwork; 02184 mdd_manager *mddManager = Part_PartitionReadMddManager( 02185 functionData->mddNetwork); 02186 int composeIntermediateVars, findIntermediateVars; 02187 array_t *relationArray; 02188 02189 /* free existing function vector and/or relation */ 02190 ImgImageFreeClusteredTransitionRelationTfm(imageInfo->methodData, direction); 02191 if (forceReorder) 02192 bdd_reorder(mddManager); 02193 02194 mddNetwork = functionData->mddNetwork; 02195 02196 /* create function vector or bit relation */ 02197 if (Part_PartitionReadMethod(mddNetwork) == Part_Frontier_c && 02198 info->nVars != info->nRealVars) { 02199 if (info->option->composeIntermediateVars) { 02200 composeIntermediateVars = 1; 02201 findIntermediateVars = 0; 02202 } else { 02203 composeIntermediateVars = 0; 02204 findIntermediateVars = 1; 02205 } 02206 } else { 02207 composeIntermediateVars = 0; 02208 findIntermediateVars = 0; 02209 } 02210 02211 if (info->buildTR == 2) { /* non-deterministic */ 02212 if (info->buildPartialTR) { 02213 info->fullVector = TfmCreateBitVector(info, composeIntermediateVars, 02214 findIntermediateVars); 02215 TfmSetupPartialTransitionRelation(info, &relationArray); 02216 } else { 02217 info->vector = NIL(array_t); 02218 relationArray = TfmCreateBitRelationArray(info, composeIntermediateVars, 02219 findIntermediateVars); 02220 } 02221 } else { 02222 info->vector = TfmCreateBitVector(info, composeIntermediateVars, 02223 findIntermediateVars); 02224 if (info->buildTR == 0 || info->option->synchronizeTr) 02225 relationArray = NIL(array_t); 02226 else { 02227 relationArray = TfmCreateBitRelationArray(info, composeIntermediateVars, 02228 findIntermediateVars); 02229 } 02230 } 02231 02232 /* apply the constrain to the bit relation */ 02233 if (constrain) { 02234 if (underApprox) { 02235 MinimizeTransitionFunction(info->vector, relationArray, 02236 constrain, minimizeMethod, printStatus); 02237 } else { 02238 AddDontCareToTransitionFunction(info->vector, relationArray, 02239 constrain, minimizeMethod, printStatus); 02240 } 02241 } 02242 02243 if (info->vector && info->option->sortVectorFlag && info->option->useCache) 02244 array_sort(info->vector, CompareIndex); 02245 if (info->buildTR) { 02246 TfmBuildRelationArray(info, functionData, relationArray, direction, 0); 02247 if (relationArray) 02248 mdd_array_free(relationArray); 02249 } 02250 02251 /* Print information */ 02252 if (info->option->verbosity > 0){ 02253 if (info->method == Img_Tfm_c) 02254 fprintf(vis_stdout,"Computing Image Using tfm technique.\n"); 02255 else 02256 fprintf(vis_stdout,"Computing Image Using hybrid technique.\n"); 02257 fprintf(vis_stdout,"Total # of domain binary variables = %3d\n", 02258 array_n(functionData->domainBddVars)); 02259 fprintf(vis_stdout,"Total # of range binary variables = %3d\n", 02260 array_n(functionData->rangeBddVars)); 02261 fprintf(vis_stdout,"Total # of quantify binary variables = %3d\n", 02262 array_n(functionData->quantifyBddVars)); 02263 if (info->vector) { 02264 (void) fprintf(vis_stdout, 02265 "Shared size of transition function vector for image "); 02266 (void) fprintf(vis_stdout, 02267 "computation is %10ld BDD nodes (%-4d components)\n", 02268 ImgVectorBddSize(info->vector), array_n(info->vector)); 02269 } 02270 if (((direction == Img_Forward_c) || (direction == Img_Both_c)) && 02271 (info->fwdClusteredRelationArray != NIL(array_t))) { 02272 (void) fprintf(vis_stdout, 02273 "Shared size of transition relation for forward image "); 02274 (void) fprintf(vis_stdout, 02275 "computation is %10ld BDD nodes (%-4d components)\n", 02276 bdd_size_multiple(info->fwdClusteredRelationArray), 02277 array_n(info->fwdClusteredRelationArray)); 02278 } 02279 if (((direction == Img_Backward_c) || (direction == Img_Both_c)) && 02280 (info->bwdClusteredRelationArray != NIL(array_t))) { 02281 (void) fprintf(vis_stdout, 02282 "Shared size of transition relation for backward image "); 02283 (void) fprintf(vis_stdout, 02284 "computation is %10ld BDD nodes (%-4d components)\n", 02285 bdd_size_multiple(info->bwdClusteredRelationArray), 02286 array_n(info->bwdClusteredRelationArray)); 02287 } 02288 } 02289 } 02290 02291 02301 int 02302 ImgIsPartitionedTransitionRelationTfm(Img_ImageInfo_t *imageInfo) 02303 { 02304 ImgTfmInfo_t *info = (ImgTfmInfo_t *)imageInfo->methodData; 02305 02306 if (info->buildTR) 02307 return(1); 02308 else 02309 return(0); 02310 } 02311 02312 02313 /*---------------------------------------------------------------------------*/ 02314 /* Definition of static functions */ 02315 /*---------------------------------------------------------------------------*/ 02316 02317 02329 static ImgTfmInfo_t * 02330 TfmInfoStructAlloc(Img_MethodType method) 02331 { 02332 ImgTfmInfo_t *info; 02333 02334 info = ALLOC(ImgTfmInfo_t, 1); 02335 memset(info, 0, sizeof(ImgTfmInfo_t)); 02336 info->method = method; 02337 info->option = ImgTfmGetOptions(method); 02338 return(info); 02339 } 02340 02341 02351 static int 02352 CompareIndex(const void *e1, const void *e2) 02353 { 02354 ImgComponent_t *c1, *c2; 02355 int id1, id2; 02356 02357 c1 = *((ImgComponent_t **)e1); 02358 c2 = *((ImgComponent_t **)e2); 02359 02360 id1 = (int)bdd_top_var_id(c1->var); 02361 id2 = (int)bdd_top_var_id(c2->var); 02362 02363 if (id1 > id2) 02364 return(1); 02365 else if (id1 < id2) 02366 return(-1); 02367 else 02368 return(0); 02369 } 02370 02371 02381 static int 02382 HookInfoFunction(bdd_manager *mgr, char *str, void *method) 02383 { 02384 ImgTfmInfo_t *info; 02385 st_generator *stGen; 02386 02387 if (HookInfoList) { 02388 st_foreach_item(HookInfoList, stGen, &info, NULL) { 02389 if (info->imgCache) 02390 ImgFlushCache(info->imgCache); 02391 if (info->preCache) 02392 ImgFlushCache(info->preCache); 02393 } 02394 } 02395 return(0); 02396 } 02397 02398 02409 static array_t * 02410 ChoosePartialVars(ImgTfmInfo_t *info, array_t *vector, int nPartialVars, 02411 int partialMethod) 02412 { 02413 int i, j, nVars; 02414 ImgComponent_t *comp; 02415 char *support; 02416 int *varCost; 02417 int big, small, nChosen, insert, id; 02418 mdd_t *var; 02419 int *partialVars = ALLOC(int, nPartialVars); 02420 array_t *partialBddVars = array_alloc(mdd_t *, 0); 02421 02422 nVars = info->nVars; 02423 varCost = ALLOC(int, nVars); 02424 memset(varCost, 0, sizeof(int) * nVars); 02425 02426 if (partialMethod == 0) { 02427 /* chooses the variable whose function has the largest bdd size */ 02428 for (i = 0; i < array_n(vector); i++) { 02429 comp = array_fetch(ImgComponent_t *, vector, i); 02430 id = (int)bdd_top_var_id(comp->var); 02431 varCost[id] = bdd_size(comp->func); 02432 } 02433 } else { 02434 /* chooses the variable that appears the most frequently */ 02435 for (i = 0; i < array_n(vector); i++) { 02436 comp = array_fetch(ImgComponent_t *, vector, i); 02437 support = comp->support; 02438 for (j = 0; j < nVars; j++) { 02439 if (support[j]) 02440 varCost[j]++; 02441 } 02442 } 02443 } 02444 02445 nChosen = 0; 02446 big = small = -1; 02447 for (i = 0; i < nVars; i++) { 02448 if (varCost[i] == 0) 02449 continue; 02450 if (st_lookup(info->quantifyVarsTable, (char *)(long)i, NIL(char *))) 02451 continue; 02452 if (info->intermediateVarsTable && 02453 st_lookup(info->intermediateVarsTable, (char *)(long)i, NIL(char *))) { 02454 continue; 02455 } 02456 if (nChosen == 0) { 02457 partialVars[0] = i; 02458 nChosen = 1; 02459 big = small = varCost[i]; 02460 } else if (varCost[i] < small) { 02461 if (nChosen < nPartialVars) { 02462 partialVars[nChosen] = i; 02463 nChosen++; 02464 small = varCost[i]; 02465 } else 02466 continue; 02467 } else if (varCost[i] > big) { 02468 if (nChosen < nPartialVars) { 02469 for (j = nChosen; j > 0; j--) 02470 partialVars[j] = partialVars[j - 1]; 02471 partialVars[0] = i; 02472 nChosen++; 02473 big = varCost[i]; 02474 } else { 02475 for (j = nPartialVars - 1; j > 0; j--) 02476 partialVars[j] = partialVars[j - 1]; 02477 partialVars[0] = i; 02478 big = varCost[i]; 02479 small = varCost[partialVars[nPartialVars - 1]]; 02480 } 02481 } else { 02482 insert = nChosen; 02483 for (j = 0; j < nChosen; j++) { 02484 if (varCost[i] > varCost[partialVars[j]]) { 02485 insert = j; 02486 break; 02487 } 02488 } 02489 if (nChosen < nPartialVars) { 02490 for (j = nChosen; j > insert; j--) 02491 partialVars[j] = partialVars[j - 1]; 02492 partialVars[insert] = i; 02493 nChosen++; 02494 } else if (insert < nChosen) { 02495 for (j = nPartialVars - 1; j > insert; j--) 02496 partialVars[j] = partialVars[j - 1]; 02497 partialVars[insert] = i; 02498 small = varCost[partialVars[nPartialVars - 1]]; 02499 } 02500 } 02501 } 02502 FREE(varCost); 02503 02504 for (i = 0; i < nChosen; i++) { 02505 var = bdd_var_with_index(info->manager, partialVars[i]); 02506 array_insert_last(mdd_t *, partialBddVars, var); 02507 } 02508 02509 FREE(partialVars); 02510 return(partialBddVars); 02511 } 02512 02513 02525 static void 02526 PrintRecursionStatistics(ImgTfmInfo_t *info, int preFlag) 02527 { 02528 float avgDepth, avgDecomp; 02529 int nRecurs, nLeaves, nTurns, nDecomps, topDecomp, maxDecomp, maxDepth; 02530 02531 GetRecursionStatistics(info, preFlag, &nRecurs, &nLeaves, &nTurns, &avgDepth, 02532 &maxDepth, &nDecomps, &topDecomp, &maxDecomp, &avgDecomp); 02533 if (preFlag) 02534 fprintf(vis_stdout, "** recursion statistics of splitting (preImg) **\n"); 02535 else 02536 fprintf(vis_stdout, "** recursion statistics of splitting (img) **\n"); 02537 fprintf(vis_stdout, "# recursions = %d\n", nRecurs); 02538 fprintf(vis_stdout, "# leaves = %d\n", nLeaves); 02539 fprintf(vis_stdout, "# turns = %d\n", nTurns); 02540 fprintf(vis_stdout, "# average recursion depth = %g (max = %d)\n", 02541 avgDepth, maxDepth); 02542 if (!preFlag) { 02543 fprintf(vis_stdout, 02544 "# decompositions = %d (top = %d, max = %d, average = %g)\n", 02545 nDecomps, topDecomp, maxDecomp, avgDecomp); 02546 } 02547 } 02548 02549 02561 static void 02562 PrintFoundVariableStatistics(ImgTfmInfo_t *info, int preFlag) 02563 { 02564 int i, maxDepth; 02565 02566 if (preFlag) { 02567 fprintf(vis_stdout, "# split = %d, conjoin = %d\n", 02568 info->nSplitsB, info->nConjoinsB); 02569 return; 02570 } 02571 02572 fprintf(vis_stdout, 02573 "# found essential vars = %d (top = %d, average = %g, averageDepth = %g)\n", 02574 info->nFoundEssentials, info->topFoundEssentialDepth, 02575 info->averageFoundEssential, info->averageFoundEssentialDepth); 02576 if (info->option->printEssential == 1) { 02577 maxDepth = info->maxDepth < IMG_TF_MAX_PRINT_DEPTH ? 02578 info->maxDepth : IMG_TF_MAX_PRINT_DEPTH; 02579 fprintf(vis_stdout, "foundEssential:"); 02580 for (i = 0; i < maxDepth; i++) 02581 fprintf(vis_stdout, " [%d]%d", i, info->foundEssentials[i]); 02582 fprintf(vis_stdout, "\n"); 02583 } 02584 if (info->useConstraint == 2) 02585 fprintf(vis_stdout, "# range computations = %d\n", info->nRangeComps); 02586 fprintf(vis_stdout, 02587 "# found dependent vars = %d (average = %g)\n", 02588 info->nFoundDependVars, info->averageFoundDependVars); 02589 fprintf(vis_stdout, "# tautologous subimage = %d\n", info->nEmptySubImage); 02590 fprintf(vis_stdout, "# split = %d, conjoin = %d, cubeSplit = %d\n", 02591 info->nSplits, info->nConjoins, info->nCubeSplits); 02592 } 02593 02594 02608 static void 02609 GetRecursionStatistics(ImgTfmInfo_t *info, int preFlag, int *nRecurs, 02610 int *nLeaves, int *nTurns, float *averageDepth, 02611 int *maxDepth, int *nDecomps, int *topDecomp, 02612 int *maxDecomp, float *averageDecomp) 02613 { 02614 if (preFlag) { 02615 *nRecurs = info->nRecursionB; 02616 *nLeaves = info->nLeavesB; 02617 *nTurns = info->nTurnsB; 02618 *averageDepth = info->averageDepthB; 02619 *maxDepth = info->maxDepthB; 02620 *nDecomps = 0; 02621 *topDecomp = 0; 02622 *maxDecomp = 0; 02623 *averageDecomp = 0.0; 02624 } else { 02625 *nRecurs = info->nRecursion; 02626 *nLeaves = info->nLeaves; 02627 *nTurns = info->nTurns; 02628 *averageDepth = info->averageDepth; 02629 *maxDepth = info->maxDepth; 02630 *nDecomps = info->nDecomps; 02631 *topDecomp = info->topDecomp; 02632 *maxDecomp = info->maxDecomp; 02633 *averageDecomp = info->averageDecomp; 02634 } 02635 } 02636 02637 02649 static int 02650 ReadSetIntValue(char *string, int l, int u, int defaultValue) 02651 { 02652 char *flagValue; 02653 int tmp; 02654 int value = defaultValue; 02655 02656 flagValue = Cmd_FlagReadByName(string); 02657 if (flagValue != NIL(char)) { 02658 sscanf(flagValue, "%d", &tmp); 02659 if (tmp >= l && (tmp <= u || u == 0)) 02660 value = tmp; 02661 else { 02662 fprintf(vis_stderr, 02663 "** tfm error: invalid value %d for %s[%d-%d]. **\n", tmp, string, 02664 l, u); 02665 } 02666 } 02667 02668 return(value); 02669 } 02670 02671 02683 static boolean 02684 ReadSetBooleanValue(char *string, boolean defaultValue) 02685 { 02686 char *flagValue; 02687 boolean value = defaultValue; 02688 02689 flagValue = Cmd_FlagReadByName(string); 02690 if (flagValue != NIL(char)) { 02691 if (strcmp(flagValue, "yes") == 0) 02692 value = TRUE; 02693 else if (strcmp(flagValue, "no") == 0) 02694 value = FALSE; 02695 else { 02696 fprintf(vis_stderr, 02697 "** tfm error: invalid value %s for %s[yes/no]. **\n", 02698 flagValue, string); 02699 } 02700 } 02701 02702 return(value); 02703 } 02704 02705 02718 static void 02719 FindIntermediateVarsRecursively(ImgTfmInfo_t *info, mdd_manager *mddManager, 02720 vertex_t *vertex, int mddId, 02721 st_table *vertexTable, array_t *vector, 02722 st_table *domainQuantifyVarMddIdTable, 02723 array_t *intermediateVarMddIdArray) 02724 { 02725 Mvf_Function_t *mvf; 02726 lsList faninEdges; 02727 lsGen gen; 02728 vertex_t *faninVertex; 02729 edge_t *faninEdge; 02730 array_t *varBddFunctionArray, *bddArray; 02731 int i; 02732 mdd_t *var, *func; 02733 ImgComponent_t *comp; 02734 02735 if (st_is_member(vertexTable, (char *)vertex)) 02736 return; 02737 st_insert(vertexTable, (char *)vertex, NIL(char)); 02738 if (mddId != -1) { /* This is not the next state function node */ 02739 /* There is an mdd variable associated with this vertex */ 02740 array_insert_last(int, intermediateVarMddIdArray, mddId); 02741 mvf = Part_VertexReadFunction(vertex); 02742 varBddFunctionArray = mdd_fn_array_to_bdd_fn_array(mddManager, mddId, mvf); 02743 bddArray = mdd_id_to_bdd_array(mddManager, mddId); 02744 assert(array_n(varBddFunctionArray) == array_n(bddArray)); 02745 for (i = 0; i < array_n(bddArray); i++) { 02746 var = array_fetch(mdd_t *, bddArray, i); 02747 func = array_fetch(mdd_t *, varBddFunctionArray, i); 02748 comp = ImgComponentAlloc(info); 02749 comp->var = var; 02750 comp->func = func; 02751 comp->intermediate = 1; 02752 ImgComponentGetSupport(comp); 02753 array_insert_last(ImgComponent_t *, vector, comp); 02754 } 02755 array_free(varBddFunctionArray); 02756 array_free(bddArray); 02757 } 02758 faninEdges = g_get_in_edges(vertex); 02759 if (lsLength(faninEdges) == 0) 02760 return; 02761 lsForEachItem(faninEdges, gen, faninEdge) { 02762 faninVertex = g_e_source(faninEdge); 02763 mddId = Part_VertexReadMddId(faninVertex); 02764 if (st_is_member(domainQuantifyVarMddIdTable, (char *)(long)mddId)) { 02765 /* This is either domain var or quantify var */ 02766 continue; 02767 } 02768 FindIntermediateVarsRecursively(info, mddManager, faninVertex, mddId, 02769 vertexTable, vector, 02770 domainQuantifyVarMddIdTable, 02771 intermediateVarMddIdArray); 02772 } 02773 } 02774 02775 02788 static void 02789 GetIntermediateRelationsRecursively(mdd_manager *mddManager, vertex_t *vertex, 02790 int mddId, st_table *vertexTable, 02791 array_t *relationArray, 02792 st_table *domainQuantifyVarMddIdTable, 02793 array_t *intermediateVarMddIdArray) 02794 { 02795 Mvf_Function_t *mvf; 02796 lsList faninEdges; 02797 lsGen gen; 02798 vertex_t *faninVertex; 02799 edge_t *faninEdge; 02800 array_t *varBddRelationArray; 02801 02802 if (st_is_member(vertexTable, (char *)vertex)) 02803 return; 02804 st_insert(vertexTable, (char *)vertex, NIL(char)); 02805 if (mddId != -1) { /* This is not the next state function node */ 02806 /* There is an mdd variable associated with this vertex */ 02807 array_insert_last(int, intermediateVarMddIdArray, mddId); 02808 mvf = Part_VertexReadFunction(vertex); 02809 varBddRelationArray = mdd_fn_array_to_bdd_rel_array(mddManager, mddId, mvf); 02810 array_append(relationArray, varBddRelationArray); 02811 array_free(varBddRelationArray); 02812 } 02813 faninEdges = g_get_in_edges(vertex); 02814 if (lsLength(faninEdges) == 0) 02815 return; 02816 lsForEachItem(faninEdges, gen, faninEdge) { 02817 faninVertex = g_e_source(faninEdge); 02818 mddId = Part_VertexReadMddId(faninVertex); 02819 if (st_is_member(domainQuantifyVarMddIdTable, (char *)(long)mddId)) { 02820 /* This is either domain var or quantify var */ 02821 continue; 02822 } 02823 GetIntermediateRelationsRecursively(mddManager, faninVertex, mddId, 02824 vertexTable, relationArray, 02825 domainQuantifyVarMddIdTable, 02826 intermediateVarMddIdArray); 02827 } 02828 } 02829 02830 02844 static int 02845 CheckNondeterminism(Ntk_Network_t *network) 02846 { 02847 Ntk_Node_t *node; 02848 lsGen gen; 02849 Var_Variable_t *var; 02850 int numValues; 02851 02852 Ntk_NetworkForEachNode(network, gen, node) { 02853 var = Ntk_NodeReadVariable(node); 02854 numValues = Var_VariableReadNumValues(var); 02855 if (numValues > 2) { 02856 lsFinish(gen); 02857 return 1; 02858 } 02859 } 02860 return 0; 02861 } 02862 02863 02875 static array_t * 02876 TfmCreateBitVector(ImgTfmInfo_t *info, 02877 int composeIntermediateVars, int findIntermediateVars) 02878 { 02879 int i, j; 02880 array_t *vector; 02881 graph_t *mddNetwork; 02882 mdd_manager *mddManager; 02883 array_t *roots; 02884 array_t *rangeVarMddIdArray; 02885 int index; 02886 mdd_t *var; 02887 ImgComponent_t *comp; 02888 st_table *vertexTable; 02889 st_table *domainQuantifyVarMddIdTable; 02890 array_t *intermediateVarMddIdArray, *intermediateBddVars; 02891 int mddId; 02892 ImgFunctionData_t *functionData = info->functionData; 02893 02894 mddNetwork = functionData->mddNetwork; 02895 mddManager = Part_PartitionReadMddManager(mddNetwork); 02896 roots = functionData->roots; 02897 rangeVarMddIdArray = functionData->rangeVars; 02898 02899 if (findIntermediateVars) { 02900 vertexTable = st_init_table(st_ptrcmp, st_ptrhash); 02901 domainQuantifyVarMddIdTable = st_init_table(st_numcmp, st_numhash); 02902 intermediateVarMddIdArray = array_alloc(int, 0); 02903 arrayForEachItem(int, functionData->domainVars, i, mddId) { 02904 st_insert(domainQuantifyVarMddIdTable, (char *)(long)mddId, NIL(char)); 02905 } 02906 arrayForEachItem(int, functionData->quantifyVars, i, mddId) { 02907 st_insert(domainQuantifyVarMddIdTable, (char *)(long)mddId, NIL(char)); 02908 } 02909 } else { 02910 vertexTable = NIL(st_table); 02911 domainQuantifyVarMddIdTable = NIL(st_table); 02912 intermediateVarMddIdArray = NIL(array_t); 02913 } 02914 02915 vector = array_alloc(ImgComponent_t *, 0); 02916 /* 02917 * Iterate over the function of all the root nodes. 02918 */ 02919 for (i = 0; i < array_n(roots); i++) { 02920 mdd_t *func; 02921 char *nodeName = array_fetch(char*, roots, i); 02922 vertex_t *vertex = Part_PartitionFindVertexByName(mddNetwork, nodeName); 02923 Mvf_Function_t *mvf = Part_VertexReadFunction(vertex); 02924 int mddId = array_fetch(int, rangeVarMddIdArray, i); 02925 array_t *varBddFunctionArray = mdd_fn_array_to_bdd_fn_array(mddManager, 02926 mddId, mvf); 02927 array_t *bddArray = mdd_id_to_bdd_array(mddManager, mddId); 02928 02929 assert(array_n(varBddFunctionArray) == array_n(bddArray)); 02930 if (info->option->debug) { 02931 mdd_t *rel1, *rel2; 02932 array_t *varBddRelationArray = mdd_fn_array_to_bdd_rel_array(mddManager, 02933 mddId, 02934 mvf); 02935 for (j = 0; j < array_n(bddArray); j++) { 02936 var = array_fetch(mdd_t *, bddArray, j); 02937 func = array_fetch(mdd_t *, varBddFunctionArray, j); 02938 rel1 = array_fetch(mdd_t *, varBddRelationArray, j); 02939 rel2 = mdd_xnor(var, func); 02940 if (!mdd_equal(rel1, rel2)) { 02941 if (mdd_lequal(rel1, rel2, 1, 1)) 02942 fprintf(vis_stdout, "** %d(%d): rel < funcRel\n", i, j); 02943 else if (mdd_lequal(rel2, rel1, 1, 1)) 02944 fprintf(vis_stdout, "** %d(%d): rel > funcRel\n", i, j); 02945 else 02946 fprintf(vis_stdout, "** %d(%d): rel != funcRel\n", i, j); 02947 } 02948 mdd_free(rel1); 02949 mdd_free(rel2); 02950 } 02951 02952 array_free(varBddRelationArray); 02953 } 02954 for (j = 0; j < array_n(bddArray); j++) { 02955 var = array_fetch(mdd_t *, bddArray, j); 02956 func = array_fetch(mdd_t *, varBddFunctionArray, j); 02957 if (array_n(bddArray) == 1 && bdd_is_tautology(func, 1)) { 02958 array_t *varBddRelationArray = mdd_fn_array_to_bdd_rel_array(mddManager, 02959 mddId, mvf); 02960 mdd_t *relation = array_fetch(mdd_t *, varBddRelationArray, 0); 02961 /* non-deterministic constant */ 02962 if (bdd_is_tautology(relation, 1)) { 02963 mdd_array_free(varBddRelationArray); 02964 mdd_free(func); 02965 break; 02966 } 02967 mdd_array_free(varBddRelationArray); 02968 } 02969 comp = ImgComponentAlloc(info); 02970 comp->var = ImgSubstitute(var, functionData, Img_R2D_c); 02971 if (composeIntermediateVars) { 02972 comp->func = Img_ComposeIntermediateNodes(functionData->mddNetwork, 02973 func, functionData->domainVars, functionData->rangeVars, 02974 functionData->quantifyVars); 02975 mdd_free(func); 02976 } else 02977 comp->func = func; 02978 ImgComponentGetSupport(comp); 02979 array_insert_last(ImgComponent_t *, vector, comp); 02980 } 02981 if (findIntermediateVars) { 02982 int n1, n2; 02983 02984 n1 = array_n(vector); 02985 FindIntermediateVarsRecursively(info, mddManager, vertex, -1, 02986 vertexTable, vector, 02987 domainQuantifyVarMddIdTable, 02988 intermediateVarMddIdArray); 02989 n2 = array_n(vector); 02990 info->nIntermediateVars += n2 - n1; 02991 } 02992 array_free(varBddFunctionArray); 02993 mdd_array_free(bddArray); 02994 } 02995 if (findIntermediateVars) { 02996 int nonExistFlag; 02997 02998 /* checks whether intermediate variables are already found */ 02999 if (info->intermediateVarsTable && info->intermediateBddVars && 03000 info->newQuantifyBddVars) { 03001 nonExistFlag = 0; 03002 } else { 03003 assert(!info->intermediateVarsTable); 03004 assert(!info->intermediateBddVars); 03005 assert(!info->newQuantifyBddVars); 03006 nonExistFlag = 1; 03007 } 03008 03009 if (info->option->verbosity) { 03010 (void)fprintf(vis_stdout, "** img info: %d intermediate variables\n", 03011 info->nIntermediateVars); 03012 } 03013 st_free_table(vertexTable); 03014 st_free_table(domainQuantifyVarMddIdTable); 03015 if (nonExistFlag) { 03016 intermediateBddVars = mdd_id_array_to_bdd_array(mddManager, 03017 intermediateVarMddIdArray); 03018 } else 03019 intermediateBddVars = NIL(array_t); 03020 array_free(intermediateVarMddIdArray); 03021 if (nonExistFlag) { 03022 info->intermediateVarsTable = st_init_table(st_numcmp, st_numhash); 03023 for (i = 0; i < array_n(intermediateBddVars); i++) { 03024 var = array_fetch(mdd_t *, intermediateBddVars, i); 03025 index = (int)bdd_top_var_id(var); 03026 st_insert(info->intermediateVarsTable, (char *)(long)index, NIL(char)); 03027 } 03028 info->newQuantifyBddVars = mdd_array_duplicate( 03029 functionData->quantifyBddVars); 03030 for (i = 0; i < array_n(intermediateBddVars); i++) { 03031 var = array_fetch(mdd_t *, intermediateBddVars, i); 03032 array_insert_last(mdd_t *, info->newQuantifyBddVars, mdd_dup(var)); 03033 } 03034 info->intermediateBddVars = intermediateBddVars; 03035 } 03036 } 03037 03038 return(vector); 03039 } 03040 03041 03053 static array_t * 03054 TfmCreateBitRelationArray(ImgTfmInfo_t *info, 03055 int composeIntermediateVars, int findIntermediateVars) 03056 { 03057 array_t *bddRelationArray = array_alloc(mdd_t*, 0); 03058 ImgFunctionData_t *functionData = info->functionData; 03059 array_t *domainVarMddIdArray = functionData->domainVars; 03060 array_t *rangeVarMddIdArray = functionData->rangeVars; 03061 array_t *quantifyVarMddIdArray = functionData->quantifyVars; 03062 graph_t *mddNetwork = functionData->mddNetwork; 03063 array_t *roots = functionData->roots; 03064 int i, j, n1, n2, mddId, nIntermediateVars = 0; 03065 mdd_manager *mddManager = Part_PartitionReadMddManager(mddNetwork); 03066 st_table *vertexTable = st_init_table(st_ptrcmp, st_ptrhash); 03067 st_table *domainQuantifyVarMddIdTable = 03068 st_init_table(st_numcmp, st_numhash); 03069 char *nodeName; 03070 mdd_t *relation, *composedRelation; 03071 array_t *intermediateVarMddIdArray, *intermediateBddVars; 03072 int index; 03073 mdd_t *var; 03074 03075 if (findIntermediateVars) 03076 intermediateVarMddIdArray = array_alloc(int, 0); 03077 else 03078 intermediateVarMddIdArray = NIL(array_t); 03079 03080 arrayForEachItem(int, domainVarMddIdArray, i, mddId) { 03081 st_insert(domainQuantifyVarMddIdTable, (char *)(long)mddId, NIL(char)); 03082 } 03083 arrayForEachItem(int, quantifyVarMddIdArray, i, mddId) { 03084 st_insert(domainQuantifyVarMddIdTable, (char *)(long)mddId, NIL(char)); 03085 } 03086 03087 arrayForEachItem(char *, roots, i, nodeName) { 03088 vertex_t *vertex = Part_PartitionFindVertexByName(mddNetwork, nodeName); 03089 Mvf_Function_t *mvf = Part_VertexReadFunction(vertex); 03090 int mddId = array_fetch(int, rangeVarMddIdArray, i); 03091 03092 array_t *varBddRelationArray = mdd_fn_array_to_bdd_rel_array(mddManager, 03093 mddId, mvf); 03094 if (composeIntermediateVars) { 03095 for (j = 0; j < array_n(varBddRelationArray); j++) { 03096 relation = array_fetch(mdd_t *, varBddRelationArray, j); 03097 composedRelation = Img_ComposeIntermediateNodes( 03098 functionData->mddNetwork, relation, functionData->domainVars, 03099 functionData->rangeVars, functionData->quantifyVars); 03100 mdd_free(relation); 03101 array_insert(mdd_t *, varBddRelationArray, j, composedRelation); 03102 } 03103 03104 array_append(bddRelationArray, varBddRelationArray); 03105 array_free(varBddRelationArray); 03106 } else { 03107 array_append(bddRelationArray, varBddRelationArray); 03108 array_free(varBddRelationArray); 03109 03110 if (findIntermediateVars) { 03111 if (info->option->verbosity) 03112 n1 = array_n(bddRelationArray); 03113 GetIntermediateRelationsRecursively(mddManager, vertex, -1, vertexTable, 03114 bddRelationArray, 03115 domainQuantifyVarMddIdTable, 03116 intermediateVarMddIdArray); 03117 if (info->option->verbosity) { 03118 n2 = array_n(bddRelationArray); 03119 nIntermediateVars += n2 - n1; 03120 } 03121 } 03122 } 03123 } 03124 03125 st_free_table(vertexTable); 03126 st_free_table(domainQuantifyVarMddIdTable); 03127 if (findIntermediateVars) { 03128 int nonExistFlag; 03129 03130 /* checks whether intermediate variables are already found */ 03131 if (info->intermediateVarsTable && info->intermediateBddVars && 03132 info->newQuantifyBddVars) { 03133 nonExistFlag = 0; 03134 } else { 03135 assert(!info->intermediateVarsTable); 03136 assert(!info->intermediateBddVars); 03137 assert(!info->newQuantifyBddVars); 03138 nonExistFlag = 1; 03139 } 03140 03141 if (info->option->verbosity) { 03142 (void)fprintf(vis_stdout, "** img info: %d intermediate variables\n", 03143 info->nIntermediateVars); 03144 } 03145 if (nonExistFlag) { 03146 intermediateBddVars = mdd_id_array_to_bdd_array(mddManager, 03147 intermediateVarMddIdArray); 03148 } else 03149 intermediateBddVars = NIL(array_t); 03150 array_free(intermediateVarMddIdArray); 03151 if (nonExistFlag) { 03152 info->intermediateVarsTable = st_init_table(st_numcmp, st_numhash); 03153 for (i = 0; i < array_n(intermediateBddVars); i++) { 03154 var = array_fetch(mdd_t *, intermediateBddVars, i); 03155 index = (int)bdd_top_var_id(var); 03156 st_insert(info->intermediateVarsTable, (char *)(long)index, NIL(char)); 03157 } 03158 info->newQuantifyBddVars = mdd_array_duplicate( 03159 functionData->quantifyBddVars); 03160 for (i = 0; i < array_n(intermediateBddVars); i++) { 03161 var = array_fetch(mdd_t *, intermediateBddVars, i); 03162 array_insert_last(mdd_t *, info->newQuantifyBddVars, mdd_dup(var)); 03163 } 03164 info->intermediateBddVars = intermediateBddVars; 03165 } 03166 } 03167 return(bddRelationArray); 03168 } 03169 03170 03182 static void 03183 TfmSetupPartialTransitionRelation(ImgTfmInfo_t *info, 03184 array_t **partialRelationArray) 03185 { 03186 int i, id; 03187 mdd_t *var, *relation; 03188 ImgComponent_t *comp, *newComp; 03189 array_t *partialVector; 03190 ImgFunctionData_t *functionData = info->functionData; 03191 03192 if (!info->buildPartialTR) 03193 return; 03194 03195 info->partialBddVars = ChoosePartialVars(info, info->fullVector, 03196 info->option->nPartialVars, 03197 info->option->partialMethod); 03198 info->partialVarFlag = ALLOC(char, info->nVars); 03199 memset(info->partialVarFlag, 0, sizeof(char) * info->nVars); 03200 for (i = 0; i < array_n(info->partialBddVars); i++) { 03201 var = array_fetch(mdd_t *, info->partialBddVars, i); 03202 id = (int)bdd_top_var_id(var); 03203 info->partialVarFlag[id] = 1; 03204 } 03205 03206 partialVector = array_alloc(ImgComponent_t *, 0); 03207 if (partialRelationArray) 03208 *partialRelationArray = array_alloc(mdd_t *, 0); 03209 03210 for (i = 0; i < array_n(info->fullVector); i++) { 03211 comp = array_fetch(ImgComponent_t *, info->fullVector, i); 03212 id = (int)bdd_top_var_id(comp->var); 03213 if (info->partialVarFlag[id]) { 03214 newComp = ImgComponentCopy(info, comp); 03215 array_insert_last(ImgComponent_t *, partialVector, newComp); 03216 03217 if (newComp->intermediate) 03218 relation = mdd_xnor(newComp->var, newComp->func); 03219 else { 03220 var = ImgSubstitute(newComp->var, functionData, Img_D2R_c); 03221 relation = mdd_xnor(var, newComp->func); 03222 mdd_free(var); 03223 } 03224 array_insert_last(mdd_t *, *partialRelationArray, relation); 03225 } 03226 } 03227 03228 info->vector = partialVector; 03229 } 03230 03231 03243 static void 03244 TfmBuildRelationArray(ImgTfmInfo_t *info, ImgFunctionData_t *functionData, 03245 array_t *bitRelationArray, 03246 Img_DirectionType directionType, int writeMatrix) 03247 { 03248 int i; 03249 mdd_t *var, *relation; 03250 array_t *relationArray; 03251 ImgComponent_t *comp; 03252 int id; 03253 array_t *domainVarBddArray, *quantifyVarBddArray; 03254 mdd_t *one, *res1, *res2; 03255 char filename[20]; 03256 int composeIntermediateVars, findIntermediateVars; 03257 03258 if ((info->buildTR == 1 && info->option->synchronizeTr) || 03259 info->buildPartialTR) { 03260 relationArray = array_alloc(mdd_t *, 0); 03261 if (info->fullVector) { 03262 for (i = 0; i < array_n(info->fullVector); i++) { 03263 comp = array_fetch(ImgComponent_t *, info->fullVector, i); 03264 id = (int)bdd_top_var_id(comp->var); 03265 if (!info->partialVarFlag[id]) { 03266 if (comp->intermediate) 03267 relation = mdd_xnor(comp->var, comp->func); 03268 else { 03269 var = ImgSubstitute(comp->var, functionData, Img_D2R_c); 03270 relation = mdd_xnor(var, comp->func); 03271 mdd_free(var); 03272 } 03273 array_insert_last(mdd_t *, relationArray, relation); 03274 } 03275 } 03276 } else { 03277 for (i = 0; i < array_n(info->vector); i++) { 03278 comp = array_fetch(ImgComponent_t *, info->vector, i); 03279 if (comp->intermediate) 03280 relation = mdd_xnor(comp->var, comp->func); 03281 else { 03282 var = ImgSubstitute(comp->var, functionData, Img_D2R_c); 03283 relation = mdd_xnor(var, comp->func); 03284 mdd_free(var); 03285 } 03286 array_insert_last(mdd_t *, relationArray, relation); 03287 } 03288 } 03289 03290 if (directionType == Img_Forward_c || directionType == Img_Both_c) { 03291 if (info->imgKeepPiInTr) { 03292 if (info->intermediateBddVars) 03293 quantifyVarBddArray = info->intermediateBddVars; 03294 else 03295 quantifyVarBddArray = array_alloc(mdd_t *, 0); 03296 domainVarBddArray = array_join(info->domainVarBddArray, 03297 info->quantifyVarBddArray); 03298 } else { 03299 if (info->newQuantifyBddVars) 03300 quantifyVarBddArray = info->newQuantifyBddVars; 03301 else 03302 quantifyVarBddArray = info->quantifyVarBddArray; 03303 domainVarBddArray = info->domainVarBddArray; 03304 } 03305 info->fwdClusteredRelationArray = ImgClusterRelationArray( 03306 info->manager, info->functionData, 03307 info->option->trMethod, Img_Forward_c, info->trmOption, 03308 relationArray, domainVarBddArray, quantifyVarBddArray, 03309 info->rangeVarBddArray, &info->fwdArraySmoothVarBddArray, 03310 &info->fwdSmoothVarCubeArray, 0); 03311 if (writeMatrix && info->option->writeSupportMatrix == 3) { 03312 sprintf(filename, "support%d.mat", info->option->supportFileCount++); 03313 ImgWriteSupportMatrix(info, info->vector, 03314 info->fwdClusteredRelationArray, filename); 03315 } else if (writeMatrix && info->option->writeSupportMatrix == 2) { 03316 sprintf(filename, "support%d.mat", info->option->supportFileCount++); 03317 ImgWriteSupportMatrix(info, NIL(array_t), 03318 info->fwdClusteredRelationArray, filename); 03319 } 03320 if (info->imgKeepPiInTr) { 03321 if (!info->intermediateBddVars) 03322 array_free(quantifyVarBddArray); 03323 array_free(domainVarBddArray); 03324 } 03325 if (info->option->checkEquivalence && (!info->fullVector)) { 03326 assert(ImgCheckEquivalence(info, info->vector, 03327 info->fwdClusteredRelationArray, 03328 NIL(mdd_t), NIL(mdd_t), 0)); 03329 } 03330 if (info->option->debug) { 03331 one = mdd_one(info->manager); 03332 if (info->fullVector) { 03333 res1 = ImgImageByHybrid(info, info->fullVector, one); 03334 res2 = ImgImageByHybridWithStaticSplit(info, info->vector, one, 03335 info->fwdClusteredRelationArray, 03336 NIL(mdd_t), NIL(mdd_t)); 03337 } else { 03338 res1 = ImgImageByHybrid(info, info->vector, one); 03339 res2 = ImgImageByHybridWithStaticSplit(info, NIL(array_t), one, 03340 info->fwdClusteredRelationArray, 03341 NIL(mdd_t), NIL(mdd_t)); 03342 } 03343 assert(mdd_equal(res1, res2)); 03344 mdd_free(one); 03345 mdd_free(res1); 03346 mdd_free(res2); 03347 } 03348 } 03349 if (directionType == Img_Backward_c || directionType == Img_Both_c) { 03350 if (info->preKeepPiInTr) { 03351 if (info->intermediateBddVars) 03352 quantifyVarBddArray = info->intermediateBddVars; 03353 else 03354 quantifyVarBddArray = array_alloc(mdd_t *, 0); 03355 domainVarBddArray = array_join(info->domainVarBddArray, 03356 info->quantifyVarBddArray); 03357 } else { 03358 if (info->newQuantifyBddVars) 03359 quantifyVarBddArray = info->newQuantifyBddVars; 03360 else 03361 quantifyVarBddArray = info->quantifyVarBddArray; 03362 domainVarBddArray = info->domainVarBddArray; 03363 } 03364 info->bwdClusteredRelationArray = ImgClusterRelationArray( 03365 info->manager, info->functionData, 03366 info->option->trMethod, Img_Backward_c, info->trmOption, 03367 relationArray, domainVarBddArray, quantifyVarBddArray, 03368 info->rangeVarBddArray, &info->bwdArraySmoothVarBddArray, 03369 &info->bwdSmoothVarCubeArray, 0); 03370 if (writeMatrix && info->option->writeSupportMatrix == 3) { 03371 sprintf(filename, "support%d.mat", info->option->supportFileCount++); 03372 ImgWriteSupportMatrix(info, info->vector, 03373 info->bwdClusteredRelationArray, filename); 03374 } else if (writeMatrix && info->option->writeSupportMatrix == 2) { 03375 sprintf(filename, "support%d.mat", info->option->supportFileCount++); 03376 ImgWriteSupportMatrix(info, NIL(array_t), 03377 info->bwdClusteredRelationArray, filename); 03378 } 03379 if (info->preKeepPiInTr) { 03380 if (!info->intermediateBddVars) 03381 array_free(quantifyVarBddArray); 03382 array_free(domainVarBddArray); 03383 } 03384 if (info->option->checkEquivalence && (!info->fullVector)) { 03385 assert(ImgCheckEquivalence(info, info->vector, 03386 info->bwdClusteredRelationArray, 03387 NIL(mdd_t), NIL(mdd_t), 1)); 03388 } 03389 if (info->option->debug) { 03390 one = mdd_one(info->manager); 03391 if (info->fullVector) { 03392 res1 = ImgImageByHybrid(info, info->fullVector, one); 03393 res2 = ImgImageByHybridWithStaticSplit(info, info->vector, one, 03394 info->bwdClusteredRelationArray, 03395 NIL(mdd_t), NIL(mdd_t)); 03396 } else { 03397 res1 = ImgImageByHybrid(info, info->vector, one); 03398 res2 = ImgImageByHybridWithStaticSplit(info, NIL(array_t), one, 03399 info->bwdClusteredRelationArray, 03400 NIL(mdd_t), NIL(mdd_t)); 03401 } 03402 assert(mdd_equal(res1, res2)); 03403 mdd_free(one); 03404 mdd_free(res1); 03405 mdd_free(res2); 03406 } 03407 } 03408 03409 mdd_array_free(relationArray); 03410 } else { 03411 graph_t *mddNetwork = functionData->mddNetwork; 03412 03413 if (bitRelationArray) 03414 relationArray = bitRelationArray; 03415 else { 03416 if (Part_PartitionReadMethod(mddNetwork) == Part_Frontier_c && 03417 info->nVars != info->nRealVars) { 03418 if (info->option->composeIntermediateVars) { 03419 composeIntermediateVars = 1; 03420 findIntermediateVars = 0; 03421 } else { 03422 composeIntermediateVars = 0; 03423 findIntermediateVars = 1; 03424 } 03425 } else { 03426 composeIntermediateVars = 0; 03427 findIntermediateVars = 0; 03428 } 03429 03430 relationArray = TfmCreateBitRelationArray(info, composeIntermediateVars, 03431 findIntermediateVars); 03432 } 03433 03434 if (directionType == Img_Forward_c || directionType == Img_Both_c) { 03435 if (info->imgKeepPiInTr) { 03436 if (info->intermediateBddVars) 03437 quantifyVarBddArray = info->intermediateBddVars; 03438 else 03439 quantifyVarBddArray = array_alloc(mdd_t *, 0); 03440 domainVarBddArray = array_join(info->domainVarBddArray, 03441 info->quantifyVarBddArray); 03442 } else { 03443 if (info->newQuantifyBddVars) 03444 quantifyVarBddArray = info->newQuantifyBddVars; 03445 else 03446 quantifyVarBddArray = info->quantifyVarBddArray; 03447 domainVarBddArray = info->domainVarBddArray; 03448 } 03449 info->fwdClusteredRelationArray = ImgClusterRelationArray( 03450 info->manager, info->functionData, info->option->trMethod, 03451 Img_Forward_c, info->trmOption, relationArray, 03452 domainVarBddArray, quantifyVarBddArray, 03453 info->rangeVarBddArray, &info->fwdArraySmoothVarBddArray, 03454 &info->fwdSmoothVarCubeArray, 0); 03455 if (writeMatrix && info->option->writeSupportMatrix >= 2) { 03456 sprintf(filename, "support%d.mat", info->option->supportFileCount++); 03457 ImgWriteSupportMatrix(info, NIL(array_t), 03458 info->fwdClusteredRelationArray, filename); 03459 } 03460 if (info->imgKeepPiInTr) { 03461 if (!info->intermediateBddVars) 03462 array_free(quantifyVarBddArray); 03463 array_free(domainVarBddArray); 03464 } 03465 } 03466 if (directionType == Img_Backward_c || directionType == Img_Both_c) { 03467 if (info->preKeepPiInTr) { 03468 if (info->intermediateBddVars) 03469 quantifyVarBddArray = info->intermediateBddVars; 03470 else 03471 quantifyVarBddArray = array_alloc(mdd_t *, 0); 03472 domainVarBddArray = array_join(info->domainVarBddArray, 03473 info->quantifyVarBddArray); 03474 } else { 03475 if (info->newQuantifyBddVars) 03476 quantifyVarBddArray = info->newQuantifyBddVars; 03477 else 03478 quantifyVarBddArray = info->quantifyVarBddArray; 03479 domainVarBddArray = info->domainVarBddArray; 03480 } 03481 info->bwdClusteredRelationArray = ImgClusterRelationArray( 03482 info->manager, info->functionData, 03483 info->option->trMethod, Img_Backward_c, info->trmOption, 03484 relationArray, domainVarBddArray, quantifyVarBddArray, 03485 info->rangeVarBddArray, &info->bwdArraySmoothVarBddArray, 03486 &info->bwdSmoothVarCubeArray, 0); 03487 if (writeMatrix && info->option->writeSupportMatrix >= 2) { 03488 sprintf(filename, "support%d.mat", info->option->supportFileCount++); 03489 ImgWriteSupportMatrix(info, NIL(array_t), 03490 info->bwdClusteredRelationArray, filename); 03491 } 03492 if (info->preKeepPiInTr) { 03493 if (!info->intermediateBddVars) 03494 array_free(quantifyVarBddArray); 03495 array_free(domainVarBddArray); 03496 } 03497 } 03498 03499 if (!bitRelationArray) 03500 mdd_array_free(relationArray); 03501 } 03502 } 03503 03504 03516 static void 03517 RebuildTransitionRelation(ImgTfmInfo_t *info, Img_DirectionType directionType) 03518 { 03519 int i; 03520 mdd_t *var, *relation; 03521 ImgComponent_t *comp; 03522 array_t *relationArray; 03523 array_t *quantifyVarBddArray, *domainVarBddArray; 03524 03525 relationArray = array_alloc(mdd_t *, 0); 03526 03527 for (i = 0; i < array_n(info->vector); i++) { 03528 comp = array_fetch(ImgComponent_t *, info->vector, i); 03529 var = ImgSubstitute(comp->var, info->functionData, Img_D2R_c); 03530 relation = mdd_xnor(var, comp->func); 03531 array_insert_last(mdd_t *, relationArray, relation); 03532 mdd_free(var); 03533 } 03534 03535 if (directionType == Img_Forward_c || directionType == Img_Both_c) { 03536 mdd_array_free(info->fwdClusteredRelationArray); 03537 if (info->imgKeepPiInTr) { 03538 if (info->intermediateBddVars) 03539 quantifyVarBddArray = info->intermediateBddVars; 03540 else 03541 quantifyVarBddArray = array_alloc(mdd_t *, 0); 03542 domainVarBddArray = array_join(info->domainVarBddArray, 03543 info->quantifyVarBddArray); 03544 } else { 03545 if (info->newQuantifyBddVars) 03546 quantifyVarBddArray = info->newQuantifyBddVars; 03547 else 03548 quantifyVarBddArray = info->quantifyVarBddArray; 03549 domainVarBddArray = info->domainVarBddArray; 03550 } 03551 info->fwdClusteredRelationArray = ImgClusterRelationArray( 03552 info->manager, info->functionData, info->option->trMethod, 03553 Img_Forward_c, info->trmOption, relationArray, 03554 domainVarBddArray, quantifyVarBddArray, 03555 info->rangeVarBddArray, &info->fwdArraySmoothVarBddArray, 03556 &info->fwdSmoothVarCubeArray, 0); 03557 if (info->imgKeepPiInTr) { 03558 if (!info->intermediateBddVars) 03559 array_free(quantifyVarBddArray); 03560 array_free(domainVarBddArray); 03561 } 03562 } 03563 if (directionType == Img_Backward_c || directionType == Img_Both_c) { 03564 mdd_array_free(info->bwdClusteredRelationArray); 03565 if (info->preKeepPiInTr) { 03566 if (info->intermediateBddVars) 03567 quantifyVarBddArray = info->intermediateBddVars; 03568 else 03569 quantifyVarBddArray = array_alloc(mdd_t *, 0); 03570 domainVarBddArray = array_join(info->domainVarBddArray, 03571 info->quantifyVarBddArray); 03572 } else { 03573 if (info->newQuantifyBddVars) 03574 quantifyVarBddArray = info->newQuantifyBddVars; 03575 else 03576 quantifyVarBddArray = info->quantifyVarBddArray; 03577 domainVarBddArray = info->domainVarBddArray; 03578 } 03579 info->bwdClusteredRelationArray = ImgClusterRelationArray( 03580 info->manager, info->functionData, 03581 info->option->trMethod, Img_Backward_c, info->trmOption, 03582 relationArray, domainVarBddArray, quantifyVarBddArray, 03583 info->rangeVarBddArray, &info->fwdArraySmoothVarBddArray, 03584 &info->fwdSmoothVarCubeArray, 0); 03585 if (info->preKeepPiInTr) { 03586 if (!info->intermediateBddVars) 03587 array_free(quantifyVarBddArray); 03588 array_free(domainVarBddArray); 03589 } 03590 } 03591 03592 mdd_array_free(relationArray); 03593 } 03594 03595 03605 static void 03606 MinimizeTransitionFunction(array_t *vector, array_t *relationArray, 03607 mdd_t *constrain, Img_MinimizeType minimizeMethod, 03608 int printStatus) 03609 { 03610 int i; 03611 bdd_t *relation, *simplifiedRelation, *simplifiedFunc; 03612 long sizeConstrain = 0, size = 0; 03613 ImgComponent_t *comp; 03614 03615 if (bdd_is_tautology(constrain, 1)) 03616 return; 03617 03618 if (vector) { 03619 if (printStatus) { 03620 size = ImgVectorBddSize(vector); 03621 sizeConstrain = bdd_size(constrain); 03622 } 03623 03624 arrayForEachItem(ImgComponent_t *, vector, i, comp) { 03625 simplifiedFunc = Img_MinimizeImage(comp->func, constrain, minimizeMethod, 03626 TRUE); 03627 if (printStatus == 2) { 03628 (void)fprintf(vis_stdout, 03629 "IMG Info: minimized function %d | %ld => %d in component %d\n", 03630 bdd_size(comp->func), sizeConstrain, 03631 bdd_size(simplifiedFunc), i); 03632 } 03633 mdd_free(comp->func); 03634 comp->func = simplifiedFunc; 03635 } 03636 03637 if (printStatus) { 03638 (void) fprintf(vis_stdout, 03639 "IMG Info: minimized function [%ld | %ld => %ld] with %d components\n", 03640 size, sizeConstrain, 03641 ImgVectorBddSize(vector), array_n(vector)); 03642 } 03643 } 03644 03645 if (relationArray) { 03646 if (printStatus) { 03647 size = bdd_size_multiple(relationArray); 03648 sizeConstrain = bdd_size(constrain); 03649 } 03650 03651 arrayForEachItem(bdd_t*, relationArray, i, relation) { 03652 simplifiedRelation = Img_MinimizeImage(relation, constrain, 03653 minimizeMethod, TRUE); 03654 if (printStatus == 2) { 03655 (void)fprintf(vis_stdout, 03656 "IMG Info: minimized relation %d | %ld => %d in component %d\n", 03657 bdd_size(relation), sizeConstrain, 03658 bdd_size(simplifiedRelation), i); 03659 } 03660 mdd_free(relation); 03661 array_insert(bdd_t *, relationArray, i, simplifiedRelation); 03662 } 03663 03664 if (printStatus) { 03665 (void) fprintf(vis_stdout, 03666 "IMG Info: minimized relation [%ld | %ld => %ld] with %d components\n", 03667 size, sizeConstrain, 03668 bdd_size_multiple(relationArray), array_n(relationArray)); 03669 } 03670 } 03671 } 03672 03673 03683 static void 03684 AddDontCareToTransitionFunction(array_t *vector, array_t *relationArray, 03685 mdd_t *constrain, 03686 Img_MinimizeType minimizeMethod, 03687 int printStatus) 03688 { 03689 int i; 03690 bdd_t *relation, *simplifiedRelation, *simplifiedFunc; 03691 long sizeConstrain = 0, size = 0; 03692 ImgComponent_t *comp; 03693 03694 if (bdd_is_tautology(constrain, 1)) 03695 return; 03696 03697 if (vector) { 03698 if (printStatus) { 03699 size = ImgVectorBddSize(vector); 03700 sizeConstrain = bdd_size(constrain); 03701 } 03702 03703 arrayForEachItem(ImgComponent_t *, vector, i, comp) { 03704 simplifiedFunc = Img_AddDontCareToImage(comp->func, constrain, 03705 minimizeMethod); 03706 if (printStatus == 2) { 03707 (void)fprintf(vis_stdout, 03708 "IMG Info: minimized function %d | %ld => %d in component %d\n", 03709 bdd_size(comp->func), sizeConstrain, 03710 bdd_size(simplifiedFunc), i); 03711 } 03712 mdd_free(comp->func); 03713 comp->func = simplifiedFunc; 03714 } 03715 03716 if (printStatus) { 03717 (void) fprintf(vis_stdout, 03718 "IMG Info: minimized function [%ld | %ld => %ld] with %d components\n", 03719 size, sizeConstrain, 03720 ImgVectorBddSize(vector), array_n(vector)); 03721 } 03722 } 03723 03724 if (relationArray) { 03725 if (printStatus) { 03726 size = bdd_size_multiple(relationArray); 03727 sizeConstrain = bdd_size(constrain); 03728 } 03729 03730 arrayForEachItem(bdd_t*, relationArray, i, relation) { 03731 simplifiedRelation = Img_AddDontCareToImage(relation, constrain, 03732 minimizeMethod); 03733 if (printStatus == 2) { 03734 (void)fprintf(vis_stdout, 03735 "IMG Info: minimized relation %d | %ld => %d in component %d\n", 03736 bdd_size(relation), sizeConstrain, 03737 bdd_size(simplifiedRelation), i); 03738 } 03739 mdd_free(relation); 03740 array_insert(bdd_t *, relationArray, i, simplifiedRelation); 03741 } 03742 03743 if (printStatus) { 03744 (void) fprintf(vis_stdout, 03745 "IMG Info: minimized relation [%ld | %ld => %ld] with %d components\n", 03746 size, sizeConstrain, 03747 bdd_size_multiple(relationArray), array_n(relationArray)); 03748 } 03749 } 03750 }