VIS

src/img/imgLinear.c

Go to the documentation of this file.
00001 
00036 #include "imgInt.h"
00037 #include "fsm.h"
00038 #include "heap.h"
00039 
00040 static char rcsid[] UNUSED = "$Id: imgLinear.c,v 1.18 2010/04/10 00:37:06 fabio Exp $";
00041 static char linearVarString[] = "TCNI";
00042 
00043 
00044 /*---------------------------------------------------------------------------*/
00045 /* Constant declarations                                                     */
00046 /*---------------------------------------------------------------------------*/
00047 
00048 /*---------------------------------------------------------------------------*/
00049 /* Type declarations                                                         */
00050 /*---------------------------------------------------------------------------*/
00051 
00052 
00053 /*---------------------------------------------------------------------------*/
00054 /* Structure declarations                                                    */
00055 /*---------------------------------------------------------------------------*/
00056 
00057 
00058 /*---------------------------------------------------------------------------*/
00059 /* Variable declarations                                                     */
00060 /*---------------------------------------------------------------------------*/
00061 
00062 Cluster_t *__clu;
00063 
00064 /*---------------------------------------------------------------------------*/
00065 /* Macro declarations                                                        */
00066 /*---------------------------------------------------------------------------*/
00067 
00068 #define BACKWARD_REDUCTION_RATE 0.5
00069 #define FORWARD_REDUCTION_RATE 0.5
00070 
00073 /*---------------------------------------------------------------------------*/
00074 /* Static function prototypes                                                */
00075 /*---------------------------------------------------------------------------*/
00076 
00077 static void ImgLinearUpdateVariableArrayWithId(Relation_t *head, int cindex, int id);
00078 static int ImgLinearQuantifyVariablesFromConjunct(Relation_t *head, Conjunct_t *conjunct, array_t *smoothVarBddArray, int *bModified);
00079 static void ImgLinearConjunctRefine(Relation_t *head, Conjunct_t *conjunct);
00080 static void ImgLinearVariableArrayQuit(Relation_t *head);
00081 static void ImgLinearConjunctQuit(Conjunct_t *conjunct);
00082 static Conjunct_t ** ImgLinearAddConjunctIntoArray(Conjunct_t **array, int *nArray, Conjunct_t *con);
00083 static void ImgLinearFindSameSupportConjuncts(Relation_t *head, int from, int to);
00084 static void ImgLinearClusterSameSupportSet(Relation_t *head);
00085 static void ImgLinearExpandSameSupportSet(Relation_t *head);
00086 static int ImgLinearIsSameConjunct(Relation_t *head, Conjunct_t *con1, Conjunct_t *con2);
00087 static bdd_t * ImgLinearClusteringSmooth(Relation_t *head, Cluster_t *clu, int **failureHistory, int andExistLimit, int bddLimit);
00088 static int ImgLinearClusterUsingHeap(Relation_t *head, double affinityLimit, int andExistLimit, int varLimit, Img_OptimizeType optDir, int rangeFlag, int (*compare_func)(const void *, const void *));
00089 static void ImgLinearPrintTransitionInfo(Relation_t *head);
00090 static void ImgLinearComputeLifeTime(Relation_t *head, double *paal, double *patl);
00091 static void ImgLinearFreeSmoothArray(array_t *smoothVarBddArray);
00092 static void ImgLinearPrintMatrixFull(Relation_t *head, int matrixIndex);
00093 static void ImgLinearPrintMatrix(Relation_t *head);
00094 static void ImgLinearCAPOReadVariableOrder(Relation_t *head, char *baseName, int includeNS);
00095 static void ImgLinearCAPOInterfaceVariablePl(Relation_t *head, char *baseName, int includeNS);
00096 static void ImgLinearCAPOInterfaceVariableScl(Relation_t *head, char *baseName);
00097 static void ImgLinearCAPOInterfaceVariableNet(Relation_t *head, char *baseName, int includeNS);
00098 static void ImgLinearCAPOInterfaceVariableNodes(Relation_t *head, char *baseName, int includeNS);
00099 static void ImgLinearVariableOrder(Relation_t *head, char *baseName, int includeNS);
00100 static void ImgLinearCAPOReadConjunctOrder(Relation_t *head, char *baseName);
00101 static int ImgLinearCAPORun(char *capoExe, char *baseName, int brief);
00102 static void ImgLinearCAPOInterfaceAux(Relation_t *head, char *baseName);
00103 static void ImgLinearCAPOInterfaceConjunctPl(Relation_t *head, char *baseName);
00104 static void ImgLinearCAPOInterfaceConjunctScl(Relation_t *head, char *baseName);
00105 static void ImgLinearCAPOInterfaceConjunctNet(Relation_t *head, char *baseName);
00106 static void ImgLinearCAPOInterfaceConjunctNodes(Relation_t *head, char *baseName);
00107 static void ImgLinearConjunctionOrder(Relation_t *head, char *baseName, int refineFlag);
00108 static void ImgLinearConjunctOrderMain(Relation_t *head, int bRefineConjunctOrder);
00109 static void ImgLinearPrintDebugInfo(Relation_t *head);
00110 static void ImgLinearPrintVariableProfile(Relation_t *head, char *baseName);
00111 static void ImgLinearInsertClusterCandidate(Relation_t *head, int from, int to, int nDead, int nVar, double affinityLimit);
00112 static void ImgLinearInsertPairClusterCandidate(Relation_t *head, int from, double affinityLimit, int varLimit, int rangeFlag);
00113 static void ImgLinearBuildInitialCandidate(Relation_t *head, double affinityLimit, int varLimit, int rangeFlag, int (*compare_func)(const void *, const void *));
00114 static bdd_t * ImgLinearClusteringPairSmooth(Relation_t *head, Cluster_t *clu, int **failureHistory, int andExistLimit, int bddLimit);
00115 static void ImgLinearVariableArrayInit(Relation_t *head);
00116 static void ImgLinearSetEffectiveNumberOfStateVariable(Relation_t *head, int *rangeId, int *domainId, int *existStateVariable) ;
00117 static void ImgLinearVariableLifeQuit(VarLife_t *var);
00118 static void ImgLinearAddNextStateCase(Relation_t *head);
00119 static void ImgLinearAddSingletonCase(Relation_t *head);
00120 
00121 static int ImgLinearCompareDeadAffinityLive(const void *c1, const void *c2);
00122 static int ImgLinearCompareDeadLiveAffinity(const void *c1, const void *c2);
00123 static int ImgLinearCompareAffinityDeadLive(const void *c1, const void *c2);
00124 static int ImgLinearCompareLiveAffinityDead(const void *c1, const void *c2);
00125 static int ImgLinearHeapCompareDeadAffinityLive(const void *c1, const void *c2);
00126 static int ImgLinearHeapCompareDeadLiveAffinity(const void *c1, const void *c2);
00127 static int ImgLinearHeapCompareAffinityDeadLive(const void *c1, const void *c2);
00128 static int ImgLinearHeapCompareLiveAffinityDead(const void *c1, const void *c2);
00129 
00130 static int ImgLinearCompareVarIndex(const void *c1, const void *c2);
00131 static int ImgLinearCompareVarSize(const void *c1, const void *c2);
00132 static int ImgLinearCompareVarEffFromSmall(const void *c1, const void *c2);
00133 static int ImgLinearCompareVarEffFromLarge(const void *c1, const void *c2);
00134 static int ImgLinearCompareConjunctDummy(const void *c1, const void *c2);
00135 static int ImgLinearCompareConjunctIndex(const void *c1, const void *c2);
00136 static int ImgLinearCompareConjunctSize(const void *c1, const void *c2);
00137 static int ImgLinearCompareConjunctRangeMinusDomain(const void *c1, const void *c2);
00138 static int ImgLinearCompareVarId(const void *c1, const void *c2);
00139 static int ImgCheckRangeTestAndOverapproximate(Relation_t *head);
00140 static void ImgCountOnsetDisjunctiveArray(Relation_t *head);
00141 static int linearCheckRange(const void *tc);
00142 
00143 static void ImgLinearConjunctArrayRefine(Relation_t *head);
00147 /*---------------------------------------------------------------------------*/
00148 /* Definition of exported functions                                          */
00149 /*---------------------------------------------------------------------------*/
00150 void ImgLinearConjunctOrderMainCC(Relation_t *head, int refineFlag);
00151 int ImgLinearClustering(Relation_t *head, Img_OptimizeType optDir);
00152 int ImgLinearPropagateConstant(Relation_t *head, int nextStateFlag);
00153 int ImgLinearOptimizeStateVariables(Relation_t *head, Img_OptimizeType optDir);
00154 void ImgLinearExtractNextStateCase(Relation_t *head);
00155 void ImgLinearExtractSingletonCase(Relation_t *head);
00156 /*void ImgLinearClusterRelationArray(mdd_manager *mgr, ImgFunctionData_t *functionData, array_t *relationArray, Img_DirectionType direction, array_t **clusteredRelationArrayPtr, array_t **arraySmoothVarBddArrayPtr, array_t **optClusteredRelationArrayPtr, array_t **optArraySmoothVarBddArrayPtr, ImgTrmOption_t *option);
00157 */
00158 void ImgLinearConnectedComponent(Relation_t *head);
00159 void ImgLinearBuildConjunctArrayWithQuotientCC(Relation_t *head);
00160 void ImgLinearFindConnectedComponent(Relation_t *head, Conjunct_t *conjunct, int cc_index);
00161 void ImgLinearAddConjunctIntoClusterArray(Conjunct_t *base, Conjunct_t *con);
00162 
00163 
00175 void
00176 ImgLinearClusterRelationArray(mdd_manager *mgr, 
00177                              ImgFunctionData_t *functionData, 
00178                              array_t *relationArray, 
00179                              Img_DirectionType direction, 
00180                              array_t **clusteredRelationArrayPtr, 
00181                              array_t **arraySmoothVarBddArrayPtr, 
00182                              array_t **optClusteredRelationArrayPtr, 
00183                              array_t **optArraySmoothVarBddArrayPtr, 
00184                              ImgTrmOption_t *option)
00185 {
00186 Img_OptimizeType optDir;
00187 int bGroupStateVariable;
00188 int bOrderVariable;
00189 
00190 int includeCS;
00191 int includeNS;
00192 int quantifyCS;
00193 array_t *initRelationArray;
00194 int bOptimize;
00195 Relation_t *head;
00196 bdd_t **smoothCubeArr, **optSmoothCubeArr;
00197 array_t *optRelationArr, *optSmoothVarBddArr;
00198 array_t *relationArr, *smoothVarBddArr;
00199 
00200   if(option->linearComputeRange) {
00201     option->linearIncludeCS = 0;
00202     option->linearIncludeNS = 0;
00203     option->linearQuantifyCS = 1;
00204   }
00205   
00206   optRelationArr = relationArr = 0;
00207   optSmoothVarBddArr = smoothVarBddArr = 0;
00208 
00209   includeCS = option->linearIncludeCS;
00210   includeNS = option->linearIncludeNS;
00211   quantifyCS = option->linearQuantifyCS;
00212   if(option->linearFineGrainFlag)       includeNS = 1;
00213   optDir = option->linearOptimize;
00214   bOrderVariable = option->linearOrderVariable;
00215   bGroupStateVariable = option->linearGroupStateVariable;
00216 
00217   head = ImgLinearRelationInit(mgr, relationArray, 
00218           functionData->domainBddVars, functionData->rangeBddVars, 
00219           functionData->quantifyBddVars, option);
00220 
00221   if(head->verbosity >= 5) ImgLinearPrintDebugInfo(head);
00222 
00223   ImgLinearOptimizeAll(head, Opt_None, 0);
00224   ImgLinearRefineRelation(head);
00225   initRelationArray = ImgLinearExtractRelationArrayT(head);
00226 
00227   bOptimize = 0;
00228 
00229   ImgLinearPrintMatrix(head);
00230 
00231   if(bOrderVariable)
00232     ImgLinearVariableOrder(head, "VarOrder", !bGroupStateVariable);
00233 
00234   if((direction==0) || (direction==2))  {
00235     ImgLinearPrintMatrix(head);
00236 
00237     bOptimize |= ImgLinearOptimizeAll(head, optDir, 0);
00238     ImgLinearRefineRelation(head);
00239     ImgLinearSetEffectiveNumberOfStateVariable(head, 0, 0, 0);
00240 
00241     ImgLinearConjunctOrderMainCC(head, 0);
00242 
00243     ImgLinearPrintMatrix(head);
00244 
00245     bOptimize |= ImgLinearClustering(head, optDir);
00246 
00247     ImgLinearRefineRelation(head);
00248     ImgLinearSetEffectiveNumberOfStateVariable(head, 0, 0, 0);
00249     ImgLinearPrintTransitionInfo(head);
00250 
00251     ImgLinearPrintMatrix(head);
00252 
00253     ImgLinearPrintMatrixFull(head, 2);
00254 
00255     if(bOptimize) {
00256       optRelationArr = ImgLinearExtractRelationArrayT(head);
00257       optSmoothCubeArr = ALLOC(bdd_t *, head->nSize+1);
00258       optSmoothVarBddArr = ImgLinearMakeSmoothVarBdd(head, optSmoothCubeArr);
00259     }
00260     else {
00261       optRelationArr = ImgLinearExtractRelationArrayT(head);
00262       optSmoothCubeArr = ALLOC(bdd_t *, head->nSize+1);
00263       optSmoothVarBddArr = ImgLinearMakeSmoothVarBdd(head, optSmoothCubeArr);
00264       relationArr = 0;
00265       smoothVarBddArr = 0;
00266     }
00267     ImgLinearPrintDebugInfo(head);
00268     ImgLinearRelationQuit(head);
00269 
00270     if(bOptimize) {
00271       fprintf(vis_stdout, "Get Schedules without optimization\n");
00272       head = ImgLinearRelationInit(mgr, initRelationArray, 
00273           functionData->domainBddVars, functionData->rangeBddVars, 
00274           functionData->quantifyBddVars, option);
00275       ImgLinearSetEffectiveNumberOfStateVariable(head, 0, 0, 0);
00276       ImgLinearConjunctOrderMainCC(head, 0);
00277       if(head->verbosity >= 5)
00278         ImgLinearPrintMatrix(head);
00279       ImgLinearClustering(head, Opt_None);
00280        
00281       relationArr = ImgLinearExtractRelationArrayT(head);
00282       smoothCubeArr = ALLOC(bdd_t *, head->nSize+1);
00283       smoothVarBddArr = ImgLinearMakeSmoothVarBdd(head, smoothCubeArr);
00284 
00285       ImgLinearSetEffectiveNumberOfStateVariable(head, 0, 0, 0);
00286       ImgLinearPrintDebugInfo(head);
00287       ImgLinearPrintTransitionInfo(head);
00288 
00289       ImgLinearRelationQuit(head);
00290     }
00291 
00292     if(optClusteredRelationArrayPtr)
00293       *optClusteredRelationArrayPtr = optRelationArr;
00294     else
00295       mdd_array_free(optRelationArr);
00296 
00297     if(optArraySmoothVarBddArrayPtr)
00298       *optArraySmoothVarBddArrayPtr = optSmoothVarBddArr;
00299     else if(optSmoothVarBddArr)
00300       ImgLinearFreeSmoothArray(optSmoothVarBddArr);
00301 
00302     if(clusteredRelationArrayPtr)
00303       *clusteredRelationArrayPtr = relationArr;
00304     else
00305       mdd_array_free(relationArr);
00306 
00307     if(arraySmoothVarBddArrayPtr)
00308       *arraySmoothVarBddArrayPtr = smoothVarBddArr;
00309     else if(smoothVarBddArr)
00310       ImgLinearFreeSmoothArray(smoothVarBddArr);
00311   }
00312 
00313   if((direction==1) || (direction==2)) {
00314   }
00315 }
00316 
00317 
00329 Relation_t *
00330 ImgLinearRelationInit(mdd_manager *mgr,
00331                         array_t *relationArray,
00332                         array_t *domainBddVars,
00333                         array_t *rangeBddVars,
00334                         array_t *quantifyBddVars,
00335                         ImgTrmOption_t *option)
00336 {
00337 Relation_t *head;
00338 Conjunct_t *conjunct, **conjunctArray;
00339 bdd_t *varBdd;
00340 int *domain2range, *range2domain;
00341 int *varArrayMap, *varType;
00342 bdd_t **constantCase, *relation;
00343 int i, j, id, tid, nSize;
00344 int *supList, listSize;
00345 char *flagValue;
00346 int *quantifyVars, nQuantify, *visited;
00347 
00348   head = ALLOC(Relation_t, 1);
00349   memset(head, 0, sizeof(Relation_t));
00350   head->mgr = mgr;
00351   head->nVar = bdd_num_vars(head->mgr);
00352   head->bddLimit = option->clusterSize;
00353 
00354   head->verbosity = option->verbosity;
00355   flagValue = Cmd_FlagReadByName("linear_verbosity");
00356   if(flagValue) {
00357     head->verbosity += atoi(flagValue);
00358   }
00359 
00360 
00361   head->includeCS = option->linearIncludeCS;
00362   head->includeNS = option->linearIncludeNS;
00363   head->quantifyCS = option->linearQuantifyCS;
00364   head->computeRange = option->linearComputeRange;
00365 
00366   head->nInitRange = 0;
00367   head->nInitDomain = 0;
00368   head->nInitQuantify = 0;
00369   head->nEffRange = 0;
00370   head->nEffDomain = 0;
00371   head->nEffQuantify = 0;
00372 
00373   head->clusterArray = 0;
00374   head->nClusterArray = 0;
00375 
00376   head->nVarArray = 0;
00377   head->varArray = 0;
00378 
00379   head->nSingletonArray = 0;
00380   head->singletonArray = 0;
00381   head->nNextStateArray = 0;
00382   head->nextStateArray = 0;
00383 
00384   domain2range = ALLOC(int, head->nVar);
00385   head->domain2range = domain2range;
00386   memset(domain2range, -1, sizeof(int)*head->nVar);
00387 
00388   range2domain = ALLOC(int, head->nVar);
00389   head->range2domain = range2domain;
00390   memset(range2domain, -1, sizeof(int)*head->nVar);
00391 
00392   varType = ALLOC(int, head->nVar);
00393   head->varType = varType;
00394   memset(varType, 0, sizeof(int)*head->nVar);
00395 
00396   head->nRange = array_n(rangeBddVars);
00397   head->nDomain = array_n(domainBddVars);
00398 
00399   head->domainVars = ALLOC(int, head->nDomain);
00400   head->rangeVars = ALLOC(int, head->nRange);
00401   for(i=0; i<head->nDomain; i++) {
00402     varBdd = array_fetch(bdd_t *, domainBddVars, i);
00403     id = (int)bdd_top_var_id(varBdd);
00404     head->domainVars[i] = id;
00405     varType[id] = 1;
00406 
00407     varBdd = array_fetch(bdd_t *, rangeBddVars, i);
00408     tid = (int)bdd_top_var_id(varBdd);
00409     head->rangeVars[i] = tid;
00410     varType[tid] = 2;
00411 
00412     domain2range[id] = tid;
00413     range2domain[tid] = id;
00414   }
00415 
00416   head->quantifyVars = quantifyVars = ALLOC(int, head->nVar);
00417   memset(quantifyVars, 0, sizeof(int)*head->nVar);
00418   for(nQuantify=0, i=0; i<array_n(quantifyBddVars); i++) {
00419     varBdd = array_fetch(bdd_t *, quantifyBddVars, i);
00420     id = (int)bdd_top_var_id(varBdd);
00421     quantifyVars[nQuantify++] = id;
00422     varType[id] = 3;
00423   }
00424 
00425   varArrayMap = ALLOC(int, head->nVar);
00426   head->varArrayMap = varArrayMap;
00427   memset(varArrayMap, -1, sizeof(int)*head->nVar);
00428 
00429   constantCase = ALLOC(bdd_t *, head->nVar);
00430   head->constantCase = constantCase;
00431   memset(constantCase, 0, sizeof(bdd_t *)*head->nVar);
00432 
00433 
00434   nSize = array_n(relationArray);
00435   conjunctArray = ALLOC(Conjunct_t *, nSize+1);
00436   head->nSize = nSize;
00437   head->conjunctArray = conjunctArray;
00438 
00439   visited = ALLOC(int, head->nVar);
00440   memset(visited, 0, sizeof(int)*head->nVar);
00441   for(i=0; i<nSize; i++) {
00442     conjunct = ALLOC(Conjunct_t, 1);
00443     memset(conjunct, 0, sizeof(Conjunct_t));
00444     conjunct->index = i;
00445     relation = array_fetch(bdd_t *, relationArray, i);
00446 
00447     conjunct->relation = mdd_dup(relation);
00448 
00449     supList = ImgLinearGetSupportBddId(head->mgr, relation, &listSize);
00450     conjunct->supList = supList;
00451     conjunct->nSize = listSize;
00452     for(j=0; j<listSize; j++) {
00453       id = supList[j];
00454       if(varType[id] == 1)      conjunct->nDomain++;
00455       else if(varType[id] == 2) conjunct->nRange++;
00456       else if(varType[id] == 3) conjunct->nQuantify++;
00457       else if(visited[id] == 0) {
00458         quantifyVars[nQuantify++] = id;
00459         visited[id] = 1;
00460       }
00461     }
00462 
00463     conjunctArray[i] = conjunct;
00464   }
00465   conjunctArray[i] = 0;
00466 
00467   head->nQuantify= nQuantify;
00468   free(visited);
00469 
00470   ImgLinearVariableArrayInit(head);
00471   return(head);
00472 }
00473 
00474 
00486 int *
00487 ImgLinearGetSupportBddId(mdd_manager *mgr, bdd_t *f, int *nSize)
00488 {
00489 var_set_t *vset;
00490 array_t *bvar_list;
00491 int *supList, i, size;
00492 
00493   bvar_list = mdd_ret_bvar_list(mgr);
00494   vset = bdd_get_support(f);
00495   size = 0;
00496   supList = ALLOC(int, size+1);
00497   supList[0] = -1;
00498   for(i=0; i<array_n(bvar_list); i++) {
00499     if(var_set_get_elt(vset, i) == 1) {
00500       supList = REALLOC(int, supList, size+2); 
00501       supList[size++] = i;
00502       supList[size] = -1;
00503     }
00504   }
00505   var_set_free(vset);
00506   *nSize = size;
00507   if(size == 0) {
00508     free(supList);
00509     supList = 0;
00510   }
00511   return(supList);
00512 }
00513 
00525 bdd_t **
00526 ImgLinearExtractRelationArray(Relation_t *head)
00527 {
00528 int i;
00529 bdd_t **relationArray;
00530 Conjunct_t *conjunct;
00531 
00532   relationArray = ALLOC(bdd_t *, head->nSize+1);
00533   for(i=0; i<head->nSize; i++) {
00534     conjunct = head->conjunctArray[i];
00535     relationArray[i] = bdd_dup(conjunct->relation);
00536   }
00537   relationArray[i] = 0;
00538   return(relationArray);
00539 }
00551 array_t *
00552 ImgLinearExtractRelationArrayT(Relation_t *head)
00553 {
00554 int i;
00555 array_t *relationArray;
00556 Conjunct_t *conjunct;
00557 
00558   relationArray = array_alloc(bdd_t *, head->nSize);
00559   for(i=0; i<head->nSize; i++) {
00560     conjunct = head->conjunctArray[i];
00561     array_insert_last(bdd_t *, relationArray, bdd_dup(conjunct->relation));
00562   }
00563   return(relationArray);
00564 }
00565 
00566 
00580 int
00581 ImgLinearOptimizeAll(Relation_t *head, Img_OptimizeType optDir, int constantNSOpt)
00582 {
00583 int bOptimize;
00584 
00585   bOptimize = 0;
00586   bOptimize |= ImgLinearPropagateConstant(head, constantNSOpt);
00587   bOptimize |= ImgLinearOptimizeStateVariables(head, optDir);
00588   ImgLinearOptimizeInternalVariables(head);
00589   return(bOptimize);
00590 }
00602 int
00603 ImgLinearPropagateConstant(Relation_t *head, int nextStateFlag)
00604 {
00605 int nSize, i, j;
00606 int *supList;
00607 Conjunct_t **conjunctArray;
00608 Conjunct_t *conjunct;
00609 mdd_manager *mgr;
00610 bdd_t **constantCase;
00611 bdd_t *relation, *simpleRelation;
00612 int nConstantCase;
00613 int bOptimize;
00614 int id, cid, index;
00615 int *varType;
00616 int size;
00617 
00618   bOptimize = 0;
00619   mgr = head->mgr;
00620   constantCase = head->constantCase;
00621   varType = head->varType;
00622 
00623   conjunctArray = head->conjunctArray;
00624   nSize = head->nSize;
00625   nConstantCase = 0;
00626   for(index=0, i=0; i<nSize; i++) {
00627     conjunct = conjunctArray[i];
00628     if(conjunct == 0)   continue;
00629     if(conjunct->relation == 0) continue;
00630     
00631     if(conjunct->nSize == 1) {
00632       id = conjunct->supList[0];
00633       if(varType[id] == 2) {
00634         if(nextStateFlag) {
00635           cid = head->range2domain[id]; 
00636           if(constantCase[cid] == 0) {
00637             constantCase[cid] = bdd_dup(conjunct->relation);
00638             if(head->verbosity >= 4)
00639               fprintf(vis_stdout, "Detect Constant Case %3d(%c)\n", cid, linearVarString[varType[cid]]);
00640             nConstantCase++;
00641           }
00642         }
00643         continue;
00644       }
00645       else {
00646         if(constantCase[id] == 0) {
00647           constantCase[id] = bdd_dup(conjunct->relation);
00648           if(head->verbosity >= 4)
00649             fprintf(vis_stdout, "Detect Constant Case %3d(%c)\n", id, linearVarString[varType[id]]);
00650           nConstantCase++;
00651         }
00652         continue;
00653       }
00654     }
00655   }
00656 
00657   if(nConstantCase > 0) {
00658     for(i=0; i<head->nSize; i++) {
00659       conjunct = conjunctArray[i]; 
00660       if(conjunct == 0) continue;
00661       if(conjunct->relation == 0)       continue;
00662       relation = conjunct->relation;
00663       size = conjunct->nSize;
00664       supList = conjunct->supList;
00665 
00666       for(j=0; j<size; j++) {
00667         id = supList[j];
00668         if(constantCase[id] == 0)       continue;
00669 
00670         simpleRelation = bdd_cofactor(relation, constantCase[id]); 
00671         if(bdd_equal(relation, simpleRelation)) {
00672           bdd_free(simpleRelation);
00673           continue;
00674         }
00675         if(varType[id] == 1) bOptimize++;
00676         bdd_free(conjunct->relation);
00677         conjunct->relation = simpleRelation;
00678         relation = conjunct->relation;
00679         conjunct->bModified = 1;
00680         head->bModified = 1;
00681         head->bRefineVarArray = 1;
00682 
00683 
00684         if(head->verbosity >= 2)
00685           fprintf(vis_stdout, "Constant propagation is applied %3d(%c) to %3d'th relation\n", id, linearVarString[varType[id]],  i);
00686       }
00687       ImgLinearConjunctRefine(head, conjunct);
00688     }
00689   }
00690 
00691   return(bOptimize);
00692 }
00693 
00705 int
00706 ImgLinearOptimizeStateVariables(Relation_t *head, Img_OptimizeType optDir)
00707 {
00708 int *rangeId, *domainId, *existStateVar;
00709 int *domain2range;
00710 int *range2domain;
00711 bdd_t *oneBdd, *varBdd;
00712 VarLife_t **varArray, *var;
00713 array_t *smoothVarBddArray;
00714 Conjunct_t *conjunct;
00715 int i, id;
00716 int bOptimize;
00717 int rangeBound, domainBound;
00718 int nRangeReduced, nDomainReduced;
00719 
00720   if(optDir == Opt_None)        return(0);
00721 
00722   id = 0;
00723   ImgLinearVariableArrayInit(head);
00724 
00725   bOptimize = 0;
00726   rangeId = ALLOC(int, head->nRange+1);
00727   memset(rangeId, 0, sizeof(int)*(head->nRange+1));
00728   domainId = ALLOC(int, head->nDomain+1);
00729   memset(domainId, 0, sizeof(int)*(head->nDomain+1));
00730   existStateVar = ALLOC(int, head->nVar);
00731   memset(existStateVar, 0, sizeof(int)*head->nVar);
00732   ImgLinearSetEffectiveNumberOfStateVariable(head, rangeId, domainId, existStateVar);
00733 
00734   rangeBound = (int)((double)head->nInitRange * BACKWARD_REDUCTION_RATE);
00735   domainBound = (int)((double)head->nInitDomain * FORWARD_REDUCTION_RATE);
00736   if(head->nEffDomain < domainBound) {
00737     if(optDir == Opt_Both)      optDir = Opt_NS;
00738     else if(optDir == Opt_CS)   optDir = Opt_None;
00739   }
00740   if(head->nEffRange < rangeBound) {
00741     if(optDir == Opt_Both)      optDir = Opt_CS;
00742     else if(optDir == Opt_NS)   optDir = Opt_None;
00743   }
00744   if(optDir == Opt_None)        return(0);
00745 
00746   oneBdd = bdd_one(head->mgr);
00747   domain2range = head->domain2range;
00748   range2domain = head->range2domain;
00749   varArray = head->varArray;
00750 
00751   if(optDir == Opt_Both || optDir == Opt_CS) {
00752     smoothVarBddArray = array_alloc(bdd_t *, 0);
00753     nDomainReduced = 0;
00754     for(i=0; i<head->nEffDomain; i++) {
00755       id = domainId[i];
00756       if(existStateVar[domain2range[id]])       continue;
00757 
00758       var = head->varArrayMap[id] >=0 ? head->varArray[head->varArrayMap[id]] : 0;
00759       if(var) {
00760         if(head->nEffDomain-nDomainReduced < domainBound)       break;
00761         if(var->nSize-head->includeCS == 1) {
00762           varBdd = bdd_get_variable(head->mgr, id);
00763           array_insert_last(bdd_t *, smoothVarBddArray, varBdd);
00764           nDomainReduced++;
00765         }           
00766       } 
00767     }
00768 
00769     if(array_n(smoothVarBddArray)) {
00770       for(i=0; i<head->nSize; i++) {
00771         conjunct = head->conjunctArray[i];
00772         if(conjunct->nDomain == 0)      continue;
00773         if(ImgLinearQuantifyVariablesFromConjunct(
00774                       head, conjunct, smoothVarBddArray, &bOptimize)) {
00775           fprintf(vis_stdout, "NOTICE : CS %3d quantified from %d'th relation\n", id, i);
00776         }
00777       }
00778     }
00779     mdd_array_free(smoothVarBddArray);
00780   }
00781 
00782   if(optDir == Opt_Both || optDir == Opt_NS) {
00783     smoothVarBddArray = array_alloc(bdd_t *, 0);
00784     nRangeReduced = 0;
00785     for(i=0; i<head->nEffRange; i++) {
00786       id = rangeId[i];
00787       if(existStateVar[range2domain[id]])       continue;
00788 
00789       var = head->varArrayMap[id] >=0 ? head->varArray[head->varArrayMap[id]] :
00790 0;
00791       if(var) {
00792         if(head->nEffRange-nRangeReduced < rangeBound)  break;
00793         if(var->nSize-head->includeNS == 1) {
00794           varBdd = bdd_get_variable(head->mgr, id);
00795           array_insert_last(bdd_t *, smoothVarBddArray, varBdd);
00796           nRangeReduced++;
00797         }           
00798       } 
00799     }
00800 
00801     if(array_n(smoothVarBddArray)) {
00802       for(i=0; i<head->nSize; i++) {
00803         conjunct = head->conjunctArray[i];
00804         if(conjunct->nRange == 0)       continue;
00805         if(ImgLinearQuantifyVariablesFromConjunct(
00806                   head, conjunct, smoothVarBddArray, &bOptimize)) {
00807           fprintf(vis_stdout, "NOTICE : NS %3d quantified from %d'th relation\n", id, i);
00808         }
00809       }
00810     }
00811     mdd_array_free(smoothVarBddArray);
00812   }
00813 
00814   bdd_free(oneBdd);
00815   free(rangeId);
00816   free(domainId);
00817   free(existStateVar);
00818 
00819   ImgLinearVariableArrayInit(head);
00820 
00821   return(bOptimize);
00822 }
00823 
00835 void
00836 ImgLinearOptimizeInternalVariables(Relation_t *head)
00837 {
00838 bdd_t *oneBdd, *varBdd;
00839 VarLife_t **varArray, *var;
00840 Conjunct_t **conjunctArray;
00841 array_t *smoothVarBddArray;
00842 int *varType;
00843 int i, bModified;
00844 
00845   oneBdd = bdd_one(head->mgr);
00846   while(1) {
00847     bModified = 0;
00848     varArray = head->varArray;
00849     varType = head->varType;
00850     conjunctArray = head->conjunctArray;
00851     for(i=0; i<head->nVarArray; i++) {
00852       var = head->varArray[i];
00853       if(varType[var->id] == 2)
00854         continue;
00855       if(varType[var->id] == 1 && head->quantifyCS == 0)
00856         continue;
00857       if(var->from == var->to) {
00858         if(conjunctArray[var->from] == 0)       continue;
00859         varBdd = bdd_get_variable(head->mgr, var->id);
00860         smoothVarBddArray = array_alloc(bdd_t *, 0);
00861         array_insert_last(bdd_t *, smoothVarBddArray, varBdd);
00862         ImgLinearQuantifyVariablesFromConjunct(
00863                 head, head->conjunctArray[var->from], smoothVarBddArray, &bModified);
00864         mdd_array_free(smoothVarBddArray);
00865       }
00866     }
00867     if(bModified == 0)  break;
00868     ImgLinearVariableArrayInit(head);
00869   }
00870   bdd_free(oneBdd);
00871   return;
00872 }
00873 
00874 
00875 
00876 
00888 void
00889 ImgLinearRefineRelation(Relation_t *head)
00890 {
00891   ImgLinearConjunctArrayRefine(head);
00892   ImgLinearVariableArrayInit(head);
00893 }
00894 
00906 void
00907 ImgLinearConjunctOrderMainCC(Relation_t *head, int refineFlag)
00908 {
00909 Conjunct_t **connectedArray;
00910 int i, index;
00911 char baseName[1024];
00912 
00913   ImgLinearPrintMatrix(head);
00914   ImgLinearExtractNextStateCase(head);
00915   ImgLinearClusterSameSupportSet(head);
00916   ImgLinearRefineRelation(head);
00917 
00918   ImgLinearExtractSingletonCase(head);
00919   ImgLinearRefineRelation(head);
00920 
00921   ImgLinearConnectedComponent(head);
00922 
00923   for(i=0; i<head->nConnectedComponent; i++) {
00924     connectedArray = head->connectedComponent[i];
00925     for(index=0; (long)(connectedArray[index])>0; index++);
00926     head->conjunctArray = connectedArray;
00927     head->nSize = index;
00928     head->bModified = 1;
00929     head->bRefineVarArray = 1;
00930     qsort(head->conjunctArray, head->nSize, sizeof(Conjunct_t *), 
00931           ImgLinearCompareConjunctSize);
00932     ImgLinearVariableArrayInit(head);
00933 
00934     ImgLinearConjunctOrderMain(head, 0);
00935     fprintf(stdout, "NOTICE : %d'th connected component\n", i);
00936     head->connectedComponent[i] = head->conjunctArray;
00937     head->conjunctArray = 0;
00938   }
00939 
00940   ImgLinearBuildConjunctArrayWithQuotientCC(head);
00941   
00942   ImgLinearAddSingletonCase(head);
00943   ImgLinearAddNextStateCase(head);
00944   ImgLinearExpandSameSupportSet(head);
00945   ImgLinearRefineRelation(head);
00946 
00947   ImgLinearRefineRelation(head);
00948   ImgLinearPrintMatrix(head);
00949 
00950   sprintf(baseName, "profile");
00951   ImgLinearPrintVariableProfile(head, baseName);
00952   ImgLinearPrintMatrixFull(head, 2);
00953 }
00965 void
00966 ImgLinearBuildConjunctArrayWithQuotientCC(Relation_t *head)
00967 {
00968 Conjunct_t *conjunct, *tConjunct;
00969 Conjunct_t **connectedArray;
00970 Conjunct_t **conjunctArray;
00971 Conjunct_t **newConjunctArray;
00972 st_table *table;
00973 int i, j, k, l;
00974 int index, id, size;
00975 int *varType, *supList;
00976 st_generator *gen;
00977 char baseName[1024];
00978 
00979   if(head->nConnectedComponent == 1) {
00980     size = 0;
00981     newConjunctArray = ALLOC(Conjunct_t *, size+1);
00982     connectedArray = head->connectedComponent[0];
00983     for(j=0; (long)(connectedArray[j])>0; j++) {
00984       tConjunct = connectedArray[j];
00985       newConjunctArray[size++] = tConjunct;
00986       newConjunctArray = REALLOC(Conjunct_t *, newConjunctArray, size+1);
00987     }
00988     free(head->conjunctArray);
00989     head->nSize = size;
00990     head->conjunctArray = newConjunctArray;
00991     head->bModified = 1;
00992     head->bRefineVarArray = 1;
00993     ImgLinearRefineRelation(head);
00994     return;
00995   }
00996 
00997   head->includeCS = 1;
00998   head->includeNS = 1;
00999   varType = head->varType;
01000   conjunctArray = ALLOC(Conjunct_t *, head->nConnectedComponent);
01001   for(i=0; i<head->nConnectedComponent; i++) {
01002     connectedArray = head->connectedComponent[i];
01003 
01004     table = st_init_table(st_ptrcmp, st_ptrhash);
01005     for(j=0; (long)(connectedArray[j])>0; j++) {
01006       conjunct = connectedArray[j];
01007       size = conjunct->nSize;
01008       supList = conjunct->supList;
01009       for(k=0; k<size; k++) {
01010         id = supList[k];
01011         st_insert(table, (char *)(long)id, (char *)(long)id);
01012       }
01013       for(l=0; l<conjunct->nCluster; l++) {
01014         tConjunct = conjunct->clusterArray[l];
01015         size = tConjunct->nSize;
01016         supList = tConjunct->supList;
01017         for(k=0; k<size; k++) {
01018           id = supList[k];
01019           st_insert(table, (char *)(long)id, (char *)(long)id);
01020         }
01021       }
01022     }
01023 
01024     conjunct = ALLOC(Conjunct_t, 1);
01025     memset(conjunct, 0, sizeof(Conjunct_t));
01026     conjunct->index = i;
01027     conjunct->dummy = (long)connectedArray;
01028     supList = ALLOC(int, table->num_entries);
01029     index = 0;
01030     st_foreach_item(table, gen, &id, &id) {
01031       if(varType[id] == 1)      conjunct->nDomain++;
01032       else if(varType[id] == 2) conjunct->nRange++;
01033       else if(varType[id] == 3) conjunct->nQuantify++;
01034       supList[index++] = id;
01035     }
01036     conjunct->supList = supList;
01037     conjunct->nSize = index;
01038 
01039     conjunctArray[i] = conjunct;
01040     conjunct->index = i;
01041     conjunct->relation = bdd_zero(head->mgr);
01042   }
01043 
01044   head->nSize = head->nConnectedComponent;
01045   head->conjunctArray = conjunctArray;
01046   head->bRefineVarArray = 1;
01047   ImgLinearVariableArrayInit(head);
01048 
01049   sprintf(baseName, "TopCon");
01050   ImgLinearCAPOInterfaceConjunctNodes(head, baseName);
01051   ImgLinearCAPOInterfaceConjunctNet(head, baseName);
01052   ImgLinearCAPOInterfaceConjunctScl(head, baseName);
01053   ImgLinearCAPOInterfaceConjunctPl(head, baseName);
01054   ImgLinearCAPOInterfaceAux(head, baseName);
01055   ImgLinearCAPORun("MetaPlacer", baseName, 0);
01056   ImgLinearCAPOReadConjunctOrder(head, baseName);
01057 
01058   size = 0;
01059   newConjunctArray = ALLOC(Conjunct_t *, size+1);
01060   conjunctArray = head->conjunctArray;
01061   for(i=0; i<head->nSize; i++) {
01062     conjunct = head->conjunctArray[i];
01063     connectedArray = (Conjunct_t **)conjunct->dummy;
01064     for(j=0; (long)(connectedArray[j])>0; j++) {
01065       tConjunct = connectedArray[j];
01066       newConjunctArray[size++] = tConjunct;
01067       newConjunctArray = REALLOC(Conjunct_t *, newConjunctArray, size+1);
01068     }
01069     ImgLinearConjunctQuit(conjunct);
01070   }
01071   free(conjunctArray);
01072   head->conjunctArray = newConjunctArray;
01073   head->nSize = size;
01074   head->bModified = 1;
01075   head->bRefineVarArray = 1;
01076   ImgLinearRefineRelation(head);
01077 
01078 }
01079 
01080 
01092 void
01093 ImgLinearConnectedComponent(Relation_t *head)
01094 {
01095 Conjunct_t *conjunct;
01096 Conjunct_t **connectedArray;
01097 int i, j, index, cc_index;
01098 int pre_index, pre_cc_index;
01099 
01100   ImgLinearVariableArrayInit(head);
01101 
01102   for(i=0; i<head->nSize; i++) {
01103     conjunct = head->conjunctArray[i];
01104     conjunct->dummy = 0;
01105   }
01106 
01107   cc_index = 0;
01108   for(i=0; i<head->nSize; i++) {
01109     conjunct = head->conjunctArray[i];
01110     if(conjunct->dummy) continue;
01111     cc_index++;
01112     ImgLinearFindConnectedComponent(head, conjunct, cc_index);
01113   }
01114   qsort(head->conjunctArray, head->nSize, sizeof(Conjunct_t *), 
01115                      ImgLinearCompareConjunctDummy);
01116 
01117   head->nConnectedComponent = 0;
01118   pre_index = 0;
01119   pre_cc_index = 1;
01120   for(i=0; i<head->nSize; i++) {
01121     conjunct = head->conjunctArray[i];
01122     if(conjunct->dummy != pre_cc_index) {
01123       if((i-pre_index) == 1) { 
01124         head->singletonArray = ImgLinearAddConjunctIntoArray(
01125                 head->singletonArray, &(head->nSingletonArray), 
01126                 head->conjunctArray[i-1]);
01127       }
01128       else { 
01129         if(head->nConnectedComponent)
01130           head->connectedComponent = REALLOC(Conjunct_t **, head->connectedComponent, head->nConnectedComponent+1);
01131         else
01132           head->connectedComponent = ALLOC(Conjunct_t **, head->nConnectedComponent+1);
01133 
01134         connectedArray = ALLOC(Conjunct_t *, (i-pre_index+2));
01135         head->connectedComponent[head->nConnectedComponent++] = connectedArray;
01136         for(index=0, j=pre_index; j<i; j++)
01137           connectedArray[index++] = head->conjunctArray[j];
01138         connectedArray[index] = 0;
01139       }
01140 
01141       pre_cc_index = conjunct->dummy;
01142       pre_index = i;
01143     }
01144   }
01145 
01146   if((i-pre_index) == 1) { 
01147     head->singletonArray = ImgLinearAddConjunctIntoArray(
01148                 head->singletonArray, &(head->nSingletonArray), 
01149                 head->conjunctArray[i-1]);
01150   }
01151   else { 
01152     if(head->nConnectedComponent)
01153       head->connectedComponent = REALLOC(Conjunct_t **,
01154 head->connectedComponent, head->nConnectedComponent+1);
01155 
01156     else
01157       head->connectedComponent = ALLOC(Conjunct_t **,
01158 head->nConnectedComponent+1);
01159 
01160     connectedArray = ALLOC(Conjunct_t *, (i-pre_index+2));
01161     head->connectedComponent[head->nConnectedComponent++] = connectedArray;
01162     for(index=0, j=pre_index; j<i; j++)
01163       connectedArray[index++] = head->conjunctArray[j];
01164     connectedArray[index] = 0;
01165   }
01166   free(head->conjunctArray);
01167 }
01168 
01180 void
01181 ImgLinearFindConnectedComponent(Relation_t *head, 
01182                                  Conjunct_t *conjunct, 
01183                                  int cc_index)
01184 {
01185 VarLife_t *var;
01186 int *supList;
01187 int id, size;
01188 int index, i, j;
01189 int *relArr;
01190 Conjunct_t *tConjunct;
01191   
01192   if(conjunct->dummy)   return;
01193   supList = conjunct->supList;
01194   size = conjunct->nSize;
01195   conjunct->dummy = cc_index;
01196   for(i=0; i<size; i++) {
01197     id = supList[i];
01198     var = head->varArrayMap[id] >=0 ? head->varArray[head->varArrayMap[id]] : 0;
01199    if(!var)     continue;
01200     relArr = var->relArr;
01201     for(j=0; j<var->nSize; j++) {
01202       index = relArr[j];
01203       if(index == MAXINT)       continue;
01204       if(index == MAXINT-1)     continue;
01205       tConjunct = head->conjunctArray[index];
01206       if(tConjunct->dummy)      continue;
01207       ImgLinearFindConnectedComponent(head, tConjunct, cc_index);
01208     }
01209   }
01210 }
01211 
01212 
01224 void
01225 ImgLinearExtractSingletonCase(Relation_t *head) 
01226 {
01227 int i, j, k, id, index;
01228 VarLife_t **varArray, *var;
01229 int nSingleton;
01230 int *supList, *varType;
01231 Conjunct_t *conjunct, **newSingletonArray;
01232 int *singletonArray;
01233 
01234   varType = head->varType;
01235   varArray = head->varArray;
01236   nSingleton = 0;
01237   singletonArray = ALLOC(int , nSingleton+1);
01238   for(i=0; i<head->nVarArray; i++) {
01239     var = varArray[i];
01240     if(var->stateVar == 2)      continue;
01241     if(var->stateVar == 1) {
01242       if(var->nSize - head->includeCS > 1)      continue;
01243     }
01244     else {
01245       if(var->nSize > 1)        continue;
01246     }
01247 
01248     for(j=0; j<var->nSize; j++) {
01249       if(var->relArr[j] == MAXINT)      continue;
01250       if(var->relArr[j] == MAXINT-1)    continue;
01251       singletonArray[nSingleton++] = var->relArr[j];
01252       singletonArray = REALLOC(int , singletonArray, nSingleton+1);
01253     }
01254   }
01255 
01256   for(i=0; i<nSingleton; i++) {
01257     conjunct = head->conjunctArray[singletonArray[i]];
01258     conjunct->bSingleton = 1;
01259   }
01260 
01261   for(i=0; i<nSingleton; i++) {
01262     conjunct = head->conjunctArray[singletonArray[i]];
01263     if(conjunct->nRange == conjunct->nSize-conjunct->nRange &&
01264        conjunct->nSize-conjunct->nRange != 1) {
01265       conjunct->bSingleton = 0;
01266       continue;
01267     }
01268 
01269     supList = conjunct->supList;
01270     for(j=0; j<conjunct->nSize; j++) {
01271       id = supList[j];
01272       if(varType[id] == 2)  continue;
01273       var = head->varArrayMap[id] >=0 ? head->varArray[head->varArrayMap[id]] : 0;
01274       if(!var)  continue;
01275 
01276       if(var->stateVar == 1) {
01277         if(var->nSize - head->includeCS == 1) continue;
01278       }
01279       else {
01280         if(var->nSize == 1)     continue;
01281       }
01282       for(k=0; k<var->nSize; k++) {
01283         index = var->relArr[k];
01284         if(index == MAXINT)     continue;
01285         if(index == MAXINT-1)   continue;
01286         (head->conjunctArray[index])->bSingleton = 0;
01287       }
01288     }
01289   }
01290   
01291   newSingletonArray = ALLOC(Conjunct_t *, nSingleton);
01292   for(index=0, i=0; i<nSingleton; i++) {
01293     conjunct = head->conjunctArray[singletonArray[i]];
01294     if(conjunct == 0)   continue;
01295     if(conjunct->bSingleton) {
01296       newSingletonArray[index++] = conjunct;
01297       head->conjunctArray[singletonArray[i]] = 0;
01298     }
01299   }
01300   head->nSingletonArray = index;
01301   free(singletonArray);
01302   qsort(newSingletonArray, head->nSingletonArray, 
01303           sizeof(Conjunct_t *), ImgLinearCompareConjunctRangeMinusDomain);
01304   head->singletonArray = newSingletonArray;
01305 
01306   if(head->nSingletonArray)     {
01307     head->bModified = 1;
01308     head->bRefineVarArray = 1;
01309   }
01310 }
01311 
01323 void
01324 ImgLinearAddConjunctIntoClusterArray(Conjunct_t *base, Conjunct_t *con)
01325 {
01326   if(base->clusterArray == 0) {
01327     base->clusterArray = ALLOC(Conjunct_t *, base->nCluster+1);
01328     base->clusterArray[base->nCluster++] = con;
01329   }
01330   else {
01331     base->clusterArray = REALLOC(Conjunct_t *, base->clusterArray, base->nCluster+1);
01332     base->clusterArray[base->nCluster++] = con;
01333   }
01334   base->bClustered = 1;
01335 }
01336 
01337 
01338 
01350 void
01351 ImgLinearExtractNextStateCase(Relation_t *head) 
01352 {
01353 int i, index, flag;
01354 Conjunct_t *conjunct;
01355 Conjunct_t **nextStateArray;
01356 
01357   index = 0;
01358   flag = 1;
01359   nextStateArray = ALLOC(Conjunct_t *, index+1);
01360   for(index=0, i=head->nSize-1; i>=0; i--) {
01361     conjunct = head->conjunctArray[i];
01362     if(conjunct == 0)   continue;
01363     if(conjunct->nSize == conjunct->nRange && flag == 0) {
01364       nextStateArray[index++] = conjunct;
01365       nextStateArray = REALLOC(Conjunct_t *, nextStateArray, index+1);
01366       head->conjunctArray[i] = 0;
01367       head->bModified = 1;
01368     }
01369     if(conjunct->nSize != conjunct->nRange) flag = 0;
01370   }
01371   head->nextStateArray = nextStateArray;
01372   head->nNextStateArray = index;
01373 
01374   ImgLinearRefineRelation(head);
01375 }
01376 
01388 void
01389 ImgLinearRelationQuit(Relation_t *head)
01390 {
01391 int i;
01392 Conjunct_t *conjunct;
01393 
01394   if(head->varArray)            ImgLinearVariableArrayQuit(head);
01395   if(head->rangeVars)           free(head->rangeVars);
01396   if(head->domainVars)          free(head->domainVars);
01397   if(head->quantifyVars)        free(head->quantifyVars);
01398   if(head->varType)             free(head->varType);
01399   if(head->varArrayMap)         free(head->varArrayMap);
01400 
01401   if(head->singletonArray)      free(head->singletonArray);
01402   if(head->nextStateArray)      free(head->nextStateArray);
01403 
01404   if(head->constantCase) {
01405     for(i=0; i<head->nVar; i++)
01406       if(head->constantCase[i]) bdd_free(head->constantCase[i]);
01407   }
01408 
01409   for(i=0; i<head->nSize; i++) {
01410     conjunct = head->conjunctArray[i];
01411     ImgLinearConjunctQuit(conjunct);
01412   }
01413   free(head);
01414 }
01415 
01416 
01428 int
01429 ImgLinearClusteringIteratively(Relation_t *head,
01430                                 double affinityLimit,
01431                                 int andExistLimit,
01432                                 int varLimit,
01433                                 int includeZeroGain,
01434                                 int useFailureHistory,
01435                                 Img_OptimizeType optDir,
01436                                 int (*compare_func)(const void *, const void *))
01437 {
01438 int bddLimit, gainLimit;
01439 int clusterLimit;
01440 int bOptimize;
01441 
01442   if(head->nSize < 2)   return(0);
01443 
01444   bOptimize = 0;
01445   bddLimit = head->bddLimit;
01446   gainLimit = 50;
01447 
01448   while(1) {
01449     if(head->nSize < 50)clusterLimit = head->nSize/2;
01450     else                clusterLimit = head->nSize/3+1;
01451     if(clusterLimit > 50)       clusterLimit = 50;
01457     ImgLinearClusteringByConstraints(head, includeZeroGain, varLimit, clusterLimit, 
01458                                       gainLimit, affinityLimit, andExistLimit,
01459                                       bddLimit,  useFailureHistory, compare_func);
01460     if(head->bModified) {
01461       ImgLinearRefineRelation(head);
01462       bOptimize |= ImgLinearOptimizeAll(head, optDir, 0);
01463     }
01464     else break;
01465   }
01466   return(bOptimize);
01467 }
01479 void
01480 ImgLinearClusteringByConstraints(Relation_t *head, 
01481                                    int includeZeroGain,
01482                                    int varLimit,
01483                                    int clusterLimit,
01484                                    int gainLimit,
01485                                    double affinityLimit,
01486                                    int andExistLimit,
01487                                    int bddLimit, 
01488                                    int useFailureHistory,
01489                                    int (*compare_func)(const void *, const void *))
01490 {
01491 int size, begin, end;
01492 int **nDead, **nVar, **nFailure;
01493 int *dirtyBit;
01494 int i, j, k, l, index;
01495 int start, preGain;
01496 int nClusterArray;
01497 VarLife_t **varArray, *var;
01498 Cluster_t **clusterArray, *clu;
01499 Conjunct_t *conjunct;
01500 bdd_t *clusteredRelation;
01501 int fail_flag;
01502 int from, to, splitable;
01503 
01504   varArray = head->varArray;
01505   size = head->nSize;
01506 
01507   nDead = ALLOC(int *, size);
01508   nVar = ALLOC(int *, size);
01509   nFailure = 0;
01510   if(useFailureHistory)
01511     nFailure = ALLOC(int *, size);
01512   for(i=0; i<size; i++) {
01513     nDead[i] = ALLOC(int, size);
01514     nVar[i] = ALLOC(int, size);
01515     if(useFailureHistory)
01516       nFailure[i] = ALLOC(int, size);
01517     memset(nDead[i], 0, sizeof(int)*size);
01518     memset(nVar[i], 0, sizeof(int)*size);
01519     if(useFailureHistory)
01520       memset(nFailure[i], 0, sizeof(int)*size);
01521   }
01522 
01523   index = 0;
01524   for(l=0; l<head->nVarArray; l++) {
01525     var = varArray[l];
01526     begin = var->from;
01527     end = var->to;
01528     if(var->stateVar == 1)      begin = -1;
01529     else if(var->stateVar == 2) end = size;
01530 
01531     for(i=0; i<=begin; i++)
01532       for(j=end; j<size; j++)
01533         nDead[i][j]++;
01534 
01535     for(i=0; i<=var->effTo; i++) {
01536       if(i > var->effFrom) {
01537         for(k=0; k<var->nSize; k++) {
01538           index = var->relArr[k];
01539           if(index == MAXINT)   continue;
01540           if(index == MAXINT-1) continue;
01541           if(index >= i)        break;
01542         }
01543         if(index < i)   start = var->effTo;
01544         else            start = index;
01545       }
01546       else {
01547         start = var->effFrom;
01548       }
01549 
01550       for(j=start; j<size; j++)
01551         nVar[i][j]++;
01552     }
01553   }
01554 
01555   for(i=0; i<size; i++) {
01556     end = (size-1) < i+clusterLimit ? size-1 : i+clusterLimit;
01557     if(i==end)  continue;
01558     if(nDead[i][end] == 0 && !includeZeroGain)  continue;
01559 
01560     preGain = -1;
01561     for(j=end; j>=i; j--) {
01562       if(varLimit < nVar[i][j]-nDead[i][j])     continue;
01563       if(gainLimit < nDead[i][j])               continue; 
01564 
01565 
01566       if(preGain != -1) {
01567         if(nDead[i][j] < preGain && nDead[i][j] >= 0) {
01568           to = j+1;
01569           for(from=i; from < to; from++) {
01570             if(nDead[from+1][to] != nDead[from][to])    break;
01571           }
01572           if(from != i) continue;
01573 
01574           splitable = 0;
01575           for(k=from; k<to; k++) {
01576             if(nDead[from][to] == (nDead[from][k] + nDead[k+1][to])) {
01577               splitable = 1;
01578               break;
01579             }
01580           }
01581           if(!splitable)
01582             ImgLinearInsertClusterCandidate(head, from, to, 
01583                              nDead[from][to], nVar[from][to], affinityLimit);
01584         }
01585       }
01586 
01587       if(nDead[i][j] == 0)      {
01588         if(includeZeroGain)
01589           ImgLinearInsertClusterCandidate(head, i, i+1, 
01590                              nDead[i][i+1], nVar[i][i+1], affinityLimit);
01591         break;
01592       }
01593 
01594       preGain = nDead[i][j];
01595 
01596     }
01597   }
01598   
01599   if(head->nClusterArray == 0)  return;
01600   qsort(head->clusterArray, head->nClusterArray, sizeof(Cluster_t *),
01601 compare_func);
01602 
01603   dirtyBit = ALLOC(int, size);
01604   memset(dirtyBit, 0, sizeof(int)*size);
01605 
01606   clusterArray = head->clusterArray;
01607   nClusterArray = head->nClusterArray;
01608   for(i=0; i<nClusterArray; i++) {
01609     clu = clusterArray[i];
01610     if(useFailureHistory) {
01611       if(nFailure[clu->from][clu->to] == 1)     continue;
01612     }
01613     fail_flag = 0;
01614     for(j=clu->from; j<=clu->to; j++) {
01615       if(dirtyBit[j] == 1)      {
01616           fail_flag = 1;
01617         continue;
01618       }
01619     }
01620     if(fail_flag)       continue;
01621 
01622     clusteredRelation = ImgLinearClusteringSmooth(head, clu, 
01623                            nFailure, andExistLimit, bddLimit);
01624 
01625     conjunct = 0;
01626     if(clusteredRelation) {
01627       for(j=clu->from; j<=clu->to; j++) {
01628         conjunct = head->conjunctArray[j];
01629         if(conjunct->relation)  bdd_free(conjunct->relation);
01630         conjunct->relation = 0;
01631       }
01632       conjunct->relation = clusteredRelation;
01633       conjunct->bModified = 1;
01634       head->bModified = 1;
01635       for(j=clu->from; j<=clu->to; j++) dirtyBit[j] = 1;
01636 
01637       if(head->verbosity >= 5)
01638         fprintf(stdout, "\tClustering Success : %4d -%4d G(%3d) V(%3d) A(%3d)\n",
01639               clu->from, clu->to, clu->nDead, clu->nVar, clu->nAffinity);
01640     }
01641     fflush(stdout);
01642   }
01643 
01644   for(i=0; i<nClusterArray; i++)
01645     free(clusterArray[i]);
01646   free(clusterArray);
01647   head->clusterArray = 0;
01648   head->nClusterArray = 0;
01649 
01650   for(i=0; i<head->nSize; i++) {
01651     free(nDead[i]);
01652     free(nVar[i]);
01653     if(useFailureHistory)
01654       free(nFailure[i]);
01655   }
01656   free(nDead);
01657   free(nVar);
01658   if(useFailureHistory)
01659     free(nFailure);
01660 
01661   return;
01662 }
01674 static void
01675 ImgLinearInsertClusterCandidate(Relation_t *head, 
01676                                  int from, int to, 
01677                                  int nDead, int nVar,
01678                                  double affinityLimit)
01679 {
01680 Conjunct_t *conjunct;
01681 Cluster_t *clu;
01682 int *varType, *supList;
01683 int i, j, id, size;
01684 st_table *table;
01685 double affinity, tAffinity;
01686 int preSize, postSize, curSize, overlap;
01687 
01688   varType = head->varType;
01689 
01690   conjunct = head->conjunctArray[from];
01691   if(conjunct->relation == 0)   {
01692     return;
01693   }
01694 
01695   supList = conjunct->supList;
01696   size = conjunct->nSize;
01697   table = st_init_table(st_numcmp, st_numhash);
01698   for(i=0; i<size; i++) {
01699     id = supList[i];
01700     if(varType[id] == 2)        continue;
01701     st_insert(table, (char *)(long)id, (char *)(long)id);
01702   }
01703 
01704   tAffinity = 0.0;
01705   for(i=from+1; i<=to; i++) {
01706     preSize = table->num_entries;
01707 
01708     conjunct = head->conjunctArray[i];
01709     if(conjunct->relation == 0) continue;
01710     supList = conjunct->supList;
01711     size = conjunct->nSize;
01712     curSize = 0;
01713     for(j=0; j<size; j++) {
01714       id = supList[j];
01715 
01716       if(varType[id] == 2)      continue;
01717       curSize++;
01718       st_insert(table, (char *)(long)id, (char *)(long)id);
01719     }
01720 
01721     postSize = table->num_entries;
01722 
01723     overlap = curSize - (postSize-preSize);
01724 
01725     if(curSize > preSize)       affinity = (double)overlap/(double)preSize;
01726     else                        affinity = (double)overlap/(double)curSize;
01727 
01734     tAffinity += affinity;
01735   }
01736   st_free_table(table);
01737 
01738   tAffinity /= (double)(to-from);
01739   clu = ALLOC(Cluster_t, 1);
01740   clu->from = from;
01741   clu->to = to;
01742   clu->nVar = nVar;
01743   clu->nDead = nDead;
01744   clu->nAffinity = (int)(tAffinity * 100.0);
01745 
01746   head->clusterArray = REALLOC(Cluster_t *, head->clusterArray, head->nClusterArray+1);
01747   head->clusterArray[head->nClusterArray++] = clu;
01748   if(head->verbosity >= 5) {
01749     fprintf(stdout, "Candidate Cluster : %4d-%4d G(%3d) V(%3d) A(%3d)\n",
01750               clu->from, clu->to, clu->nDead, clu->nVar, clu->nAffinity);
01751     fflush(stdout);
01752   }
01753 
01754 }
01755 
01767 static bdd_t *
01768 ImgLinearClusteringSmooth(Relation_t *head, 
01769                            Cluster_t *clu, 
01770                            int **failureHistory, 
01771                            int andExistLimit,
01772                            int bddLimit)
01773 {
01774 int *varType, *supList;
01775 array_t *smoothVarBddArray, *smoothArray;
01776 Conjunct_t *conjunct;
01777 bdd_t *relation, *totalRelation;
01778 bdd_t *varBdd, *tempRelation;
01779 int i, j, k, tempSize, failFlag;
01780 int id, tid;
01781 st_table *deadTable;
01782 VarLife_t *var;
01783 
01784   varType = head->varType;
01785 
01786   smoothVarBddArray = array_alloc(array_t *, 0);
01787   for(i=clu->from; i<=clu->to; i++) {
01788     smoothArray = array_alloc(bdd_t *, 0);
01789     array_insert_last(array_t *, smoothVarBddArray, smoothArray);
01790   }
01791 
01792   deadTable = st_init_table(st_numcmp, st_numhash);
01793   for(i=clu->from; i<=clu->to; i++) {
01794     conjunct = head->conjunctArray[i];
01795     if(conjunct == 0)           continue;
01796     if(conjunct->relation == 0) continue;
01797     supList = conjunct->supList;
01798     for(j=0; j<conjunct->nSize; j++) {
01799       id = supList[j];
01800       if(varType[id] == 1 || varType[id] == 2)  continue;
01801 
01802       if(st_lookup(deadTable, (char *)(long)id, &tid))  continue;
01803 
01804       var = head->varArray[head->varArrayMap[id]];
01805 
01806       if(clu->from <= var->from && var->to <= clu->to) {
01807         st_insert(deadTable, (char *)(long)id, (char *)(long)id);
01808         smoothArray = array_fetch(array_t *, smoothVarBddArray,
01809 var->to-clu->from);
01810         varBdd = bdd_get_variable(head->mgr, var->id);
01811         array_insert_last(bdd_t *, smoothArray, varBdd);
01812       }
01813     }
01814   }
01815   st_free_table(deadTable);
01816 
01817 
01818   totalRelation = bdd_one(head->mgr);
01819   failFlag = 0;
01820   for(i=clu->from; i<=clu->to; i++) {
01821     conjunct = head->conjunctArray[i];
01822     if(conjunct == 0)           continue;
01823     if(conjunct->relation == 0) continue;
01824     relation = conjunct->relation;
01825     smoothArray = array_fetch(array_t *, smoothVarBddArray, i-clu->from);
01826 
01827     tempRelation = bdd_and_smooth_with_limit(totalRelation, relation, 
01828                                         smoothArray, andExistLimit);
01829     if(tempRelation)    tempSize = bdd_size(tempRelation);
01830     else                tempSize = MAXINT;
01831 
01832     if(tempSize > bddLimit) {
01833       bdd_free(totalRelation);
01834       if(tempRelation)  bdd_free(tempRelation);
01835       totalRelation = 0;
01836       
01837       if(failureHistory) {
01838         for(j=0; j<=clu->from; j++) 
01839           for(k=i; k<head->nSize; k++)
01840             failureHistory[j][k] = 1;
01841       }
01842 
01843       if(head->verbosity >= 3)
01844         fprintf(stdout, "Clustering Failure : %4d-%4d G(%3d) V(%3d) A(%3d) At %3d S(%d)\n",
01845               clu->from, clu->to, clu->nDead, clu->nVar, clu->nAffinity, i, tempSize);
01846       break;
01847     }
01848 
01849     bdd_free(totalRelation);
01850     totalRelation = tempRelation;
01851   }
01852   ImgLinearFreeSmoothArray(smoothVarBddArray);
01853 
01854   if(failFlag)  return(0);
01855   else          return(totalRelation);
01856 }
01857 
01858 
01870 static int
01871 ImgLinearClusterUsingHeap(Relation_t *head,
01872                            double affinityLimit,
01873                            int andExistLimit,
01874                            int varLimit,
01875                            Img_OptimizeType optDir,
01876                            int rangeFlag,
01877                            int (*compare_func)(const void *, const void *))
01878 {
01879 Cluster_t *clu;
01880 int j;
01881 Conjunct_t *conjunct;
01882 bdd_t *clusteredRelation;
01883 Heap_t *heap;
01884 int bOptimize;
01885 long dummy;
01886 
01887   bOptimize = 0;
01888   ImgLinearBuildInitialCandidate(head, affinityLimit, varLimit, rangeFlag, compare_func);
01890   heap = head->clusterHeap;
01891   while(Heap_HeapExtractMin(heap, &clu, &dummy)) {
01892     if(clu->flag) {
01893       free(clu);
01894       continue;
01895     }
01896     if(clu->to >= head->nSize) {
01897       free(clu);
01898       continue;
01899     }
01900 
01901     clusteredRelation = ImgLinearClusteringPairSmooth(head, clu, 
01902                            0, andExistLimit, head->bddLimit);
01903     if(clusteredRelation) {
01904       if(head->verbosity >= 5)
01905         fprintf(stdout, "\tClustering Success : %4d -%4d G(%3d) V(%3d) A(%3d)\n",
01906               clu->from, clu->to, clu->nDead, clu->nVar, clu->nAffinity);
01907       fflush(stdout);
01908 
01909       for(j=clu->from+1; j<=clu->to; j++) {
01910         conjunct = head->conjunctArray[j];
01911         if(conjunct == 0)       continue;
01912         if(conjunct->relation == 0)     continue;
01913         bdd_free(conjunct->relation);
01914         conjunct->relation = 0;
01915       }
01916       conjunct = head->conjunctArray[clu->from];
01917       if(conjunct->relation)
01918         bdd_free(conjunct->relation);
01919       conjunct->relation = clusteredRelation;
01920       conjunct->bModified = 1;
01921       ImgLinearConjunctRefine(head, conjunct);
01922       head->bModified = 1;
01923       head->bRefineVarArray = 1;
01924 
01925       Heap_HeapApplyForEachElement(heap, linearCheckRange);
01936       ImgLinearInsertPairClusterCandidate(head, clu->from, affinityLimit, varLimit, rangeFlag);
01937       ImgLinearInsertPairClusterCandidate(head, clu->from-1, affinityLimit, varLimit, rangeFlag);
01938     }
01939     if(clu->nDead && clusteredRelation) {
01940       ImgLinearVariableArrayInit(head);
01941       bOptimize |= ImgLinearOptimizeAll(head, optDir, 0);
01942     }
01943     free(clu);
01944   }
01945   Heap_HeapFree(heap);
01946   head->clusterHeap = 0;
01947 
01948   if(head->bModified) {
01949     if(head->verbosity >= 5)
01950       ImgLinearPrintMatrix(head);
01951 
01952     bOptimize |= ImgLinearOptimizeAll(head, optDir, 0);
01953     ImgLinearRefineRelation(head);
01954 
01955     if(head->verbosity >= 5)
01956       ImgLinearPrintMatrix(head);
01957   }
01958   return(bOptimize);
01959 }
01960 
01972 static int
01973 linearCheckRange(const void *tc)
01974 {
01975 Cluster_t *tclu;
01976 
01977   tclu = (Cluster_t *)tc;
01978   if(tclu->from <= __clu->from && __clu->from <= tclu->to)
01979     tclu->flag = 1;
01980   if(tclu->from <= __clu->to && __clu->to <= tclu->to)
01981     tclu->flag = 1;
01982 
01983   return(1);
01984 }
01985 
01997 static bdd_t *
01998 ImgLinearClusteringPairSmooth(Relation_t *head, 
01999                            Cluster_t *clu, 
02000                            int **failureHistory, 
02001                            int andExistLimit,
02002                            int bddLimit)
02003 {
02004 int *varType, *supList;
02005 array_t *smoothArray;
02006 Conjunct_t *conjunct;
02007 bdd_t *totalRelation;
02008 bdd_t *fromRelation, *toRelation;
02009 bdd_t *varBdd;
02010 int i, j, k, tempSize;
02011 int id, tid, effTo;
02012 st_table *deadTable;
02013 VarLife_t *var;
02014 
02015   varType = head->varType;
02016 
02017   smoothArray = array_alloc(bdd_t *, 0);
02018 
02019   for(effTo = clu->to+1; effTo<head->nSize; effTo++) {
02020     conjunct = head->conjunctArray[effTo];
02021     if(conjunct && conjunct->relation)  break;
02022   }
02023   effTo--;
02024 
02025   deadTable = st_init_table(st_numcmp, st_numhash);
02026   for(i=clu->from; i<=clu->to; i++) {
02027     conjunct = head->conjunctArray[i];
02028     if(conjunct == 0)           continue;
02029     if(conjunct->relation == 0) continue;
02030     supList = conjunct->supList;
02031     for(j=0; j<conjunct->nSize; j++) {
02032       id = supList[j];
02033       if(varType[id] == 1 || varType[id] == 2)  continue;
02034 
02035       if(st_lookup(deadTable, (char *)(long)id, &tid))  continue;
02036 
02037       var = head->varArray[head->varArrayMap[id]];
02038 
02039       if(clu->from <= var->from && var->to <= effTo) {
02040         st_insert(deadTable, (char *)(long)id, (char *)(long)id);
02041         varBdd = bdd_get_variable(head->mgr, var->id);
02042         array_insert_last(bdd_t *, smoothArray, varBdd);
02043       }
02044     }
02045   }
02046   st_free_table(deadTable);
02047 
02048   conjunct = head->conjunctArray[clu->from];
02049   fromRelation = conjunct->relation;
02050   toRelation = 0;
02051   for(i=clu->from+1; i<=clu->to; i++) {
02052     conjunct = head->conjunctArray[i];
02053     if(conjunct == 0)           continue;
02054     if(conjunct->relation == 0) continue;
02055     toRelation = conjunct->relation;
02056     break;
02057   }
02058   if(toRelation == 0) {
02059     mdd_array_free(smoothArray);
02060     return(0);
02061   }
02062   if(fromRelation == 0 && toRelation == 0)      return(0);
02063   if(fromRelation == 0) {
02064     totalRelation = bdd_dup(toRelation);
02065   }
02066   else if(toRelation == 0) {
02067     totalRelation = bdd_dup(fromRelation);
02068   }
02069   else {
02070     totalRelation = bdd_and_smooth_with_limit(fromRelation, toRelation, 
02071                                                 smoothArray, andExistLimit);
02072   }
02073   if(totalRelation)     tempSize = bdd_size(totalRelation);
02074   else                  tempSize = MAXINT;
02075 
02076   if(tempSize > bddLimit) {
02077     if(totalRelation)   bdd_free(totalRelation);
02078     totalRelation = 0;
02079     if(failureHistory) {
02080       for(j=0; j<=clu->from; j++) 
02081         for(k=i; k<head->nSize; k++)
02082           failureHistory[j][k] = 1;
02083     }
02084     if(head->verbosity >= 3)
02085       fprintf(stdout, "Clustering Failure : %4d-%4d G(%3d) V(%3d) A(%3d) At %3d S(%d)\n",
02086               clu->from, clu->to, clu->nDead, clu->nVar, clu->nAffinity, i, tempSize);
02087   }
02088   mdd_array_free(smoothArray);
02089 
02090   return(totalRelation);
02091 }
02092 
02093 
02094 
02107 static void 
02108 ImgLinearBuildInitialCandidate(Relation_t *head, 
02109                                 double affinityLimit,
02110                                 int varLimit, 
02111                                 int rangeFlag,
02112                                 int (*compare_func)(const void *, const void *))
02113 {
02114 int size, i;
02115 
02116   head->clusterHeap = Heap_HeapInitCompare(head->nSize, compare_func);
02117   size = head->nSize;
02118   for(i=0; i<size; i++) {
02119     ImgLinearInsertPairClusterCandidate(head, i, affinityLimit, varLimit, rangeFlag);
02120   }
02121   
02122   return;
02123 }
02135 static void
02136 ImgLinearInsertPairClusterCandidate(Relation_t *head, 
02137                                      int from, 
02138                                      double affinityLimit,
02139                                      int varLimit,
02140                                      int rangeFlag)
02141 {
02142 Conjunct_t *conjunct, *fromC, *toC;
02143 Cluster_t *clu;
02144 int *varType, *supList;
02145 st_table *table;
02146 double affinity;
02147 int preSize, postSize, curSize, overlap;
02148 int i, j, id, tid, size, nDead;
02149 int to, effTo;
02150 VarLife_t *var;
02151 
02152   if(from < 0)  return;
02153   if(from == head->nSize-1)     return;
02154  
02155   conjunct = head->conjunctArray[from];
02156   if(conjunct == 0 || conjunct->relation == 0) {
02157     for(; from>=0; from--) {
02158       conjunct = head->conjunctArray[from];
02159       if(conjunct == 0) continue;
02160       if(conjunct->relation == 0)       continue;
02161       break;
02162     }
02163   }
02164   if(from < 0)  return;
02165 
02166   to = -1;
02167   for(i=from+1; i<head->nSize; i++) {
02168     conjunct = head->conjunctArray[i];
02169     if(!conjunct)       continue;
02170     if(conjunct->relation == 0) continue;
02171     to = i;
02172     break;
02173   }
02174   if(to == -1)  return;
02175   for(effTo = to+1; effTo<head->nSize; effTo++) {
02176     conjunct = head->conjunctArray[effTo];
02177     if(conjunct && conjunct->relation)  break;
02178   }
02179   effTo--;
02180 
02181 
02182   varType = head->varType;
02183 
02184   fromC = head->conjunctArray[from];
02185   toC = head->conjunctArray[to];
02186 
02187   if(rangeFlag && 
02188      (fromC->nSize == fromC->nRange || toC->nSize == toC->nRange))
02189       return;
02190 
02191   if(fromC->nSize == fromC->nRange && toC->nSize != toC->nRange)
02192     return;
02193   if(fromC->nSize != fromC->nRange && toC->nSize == toC->nRange)
02194     return;
02195 
02196   nDead = 0;
02197   supList = fromC->supList;
02198   size = fromC->nSize;
02199   table = st_init_table(st_numcmp, st_numhash);
02200   for(i=0; i<size; i++) {
02201     id = supList[i];
02202     if(varType[id] == 2)        continue;
02203     preSize++;
02204     st_insert(table, (char *)(long)id, (char *)(long)id);
02205     var = head->varArray[head->varArrayMap[id]];
02206     if(from <= var->from && var->to <= effTo)   nDead++;
02207   }
02208 
02209   preSize = table->num_entries;
02210   supList = toC->supList;
02211   size = toC->nSize;
02212   curSize = 0;
02213   for(j=0; j<size; j++) {
02214     id = supList[j];
02215     if(varType[id] == 2)        continue;
02216     curSize++;
02217     if(st_lookup(table, (char *)(long)id, &tid))        continue;
02218     st_insert(table, (char *)(long)id, (char *)(long)id);
02219     var = head->varArray[head->varArrayMap[id]];
02220     if(from <= var->from && var->to <= effTo)   nDead++;
02221   }
02222 
02223   postSize = table->num_entries;
02224   overlap = curSize - (postSize-preSize);
02225   if(overlap == 0)      affinity = 0.0;
02226   else {
02227     if(curSize > preSize)affinity = (double)overlap/(double)preSize;
02228     else                 affinity = (double)overlap/(double)curSize;
02229   }
02230   st_free_table(table);
02231 
02232   if(affinity < affinityLimit)  return;
02233 
02234   if(affinity == 0.0 && postSize > 10 && 
02235           (fromC->bSingleton || toC->bSingleton))       return;
02236   if(postSize-nDead > varLimit) return;
02237 
02238   clu = ALLOC(Cluster_t, 1);
02239   memset(clu, 0, sizeof(Cluster_t));
02240   clu->from = from;
02241   clu->to = to;
02242   clu->nVar = postSize;
02243   clu->nDead = nDead;
02244   clu->nAffinity = (int)(affinity * 100.0);
02245 
02246   Heap_HeapInsertCompare(head->clusterHeap, (void *)clu, (long)clu);
02247   if(head->verbosity >= 5) {
02248     fprintf(stdout, "Candidate Cluster : %4d -%4d G(%3d) V(%3d) A(%3d)\n",
02249               clu->from, clu->to, clu->nDead, clu->nVar, clu->nAffinity);
02250     fflush(stdout);
02251   }
02252 }
02253 
02265 static void
02266 ImgLinearPrintDebugInfo(Relation_t *head)
02267 {
02268 int i, j, id;
02269 Conjunct_t *conjunct;
02270 int *supList;
02271 array_t *smoothVarBddArray;
02272 array_t *smoothArray;
02273 bdd_t *varBdd;
02274 int idPerLine;
02275 
02276   idPerLine = 12;
02277 
02278   fprintf(vis_stdout, "-----------------------------------------------------\n");
02279   fprintf(vis_stdout, "     Debug Information for Transition Relations\n");
02280   fprintf(vis_stdout, "-----------------------------------------------------\n");
02281   fprintf(vis_stdout, "List of Quantify Variables---------------------------\n");
02282   for(i=0; i<head->nQuantify; i++) {
02283     if(i!=0 && i%idPerLine == 0) fprintf(vis_stdout, "\n");
02284     fprintf(vis_stdout, "%3d ", head->quantifyVars[i]);
02285   }
02286   fprintf(vis_stdout, "\n");
02287 
02288   fprintf(vis_stdout, "List of Domain Variables-----------------------------\n");
02289   for(i=0; i<head->nDomain; i++) {
02290     if(i!=0 && i%idPerLine == 0) fprintf(vis_stdout, "\n");
02291     fprintf(vis_stdout, "%3d ", head->domainVars[i]);
02292   }
02293   fprintf(vis_stdout, "\n");
02294 
02295   fprintf(vis_stdout, "List of Range Variables------------------------------\n");
02296   for(i=0; i<head->nRange; i++) {
02297     if(i!=0 && i%idPerLine == 0) fprintf(vis_stdout, "\n");
02298     fprintf(vis_stdout, "%3d ", head->rangeVars[i]);
02299   }
02300   fprintf(vis_stdout, "\n");
02301 
02302   fprintf(vis_stdout, "Varibles in Each Transition Relation-----------------\n");
02303   for(i=0; i<head->nSize; i++) {
02304     conjunct = head->conjunctArray[i];
02305     supList = conjunct->supList;
02306     fprintf(vis_stdout, "%3d'th : ", i);
02307     for(j=0; j<conjunct->nSize; j++) {
02308       if(j!=0 && j%idPerLine == 0) fprintf(vis_stdout, "\n         ");
02309       fprintf(vis_stdout, "%3d ", supList[j]);
02310     }
02311     fprintf(vis_stdout, "\n");
02312   }
02313 
02314   smoothVarBddArray = ImgLinearMakeSmoothVarBdd(head, 0);
02315   fprintf(vis_stdout, "Quantified Schedule----------------------------------\n");
02316   for(i=0; i<=head->nSize; i++) {
02317     fprintf(vis_stdout, "%3d'th : ", i);
02318     smoothArray = array_fetch(array_t *, smoothVarBddArray, i);
02319     for(j=0; j<array_n(smoothArray); j++) {
02320       varBdd = array_fetch(bdd_t *, smoothArray, j);
02321       id = bdd_top_var_id(varBdd);
02322       if(j!=0 && j%idPerLine == 0) fprintf(vis_stdout, "\n         ");
02323       fprintf(vis_stdout, "%3d ", id);
02324     }
02325     fprintf(vis_stdout, "\n");
02326   }
02327   ImgLinearFreeSmoothArray(smoothVarBddArray);
02328 }
02329 
02341 static void
02342 ImgLinearConjunctOrderMain(Relation_t *head, int bRefineConjunctOrder)
02343 {
02344 double aal, atl;
02345 
02362   ImgLinearConjunctionOrder(head, "SecondCon", bRefineConjunctOrder);
02363   ImgLinearComputeLifeTime(head, &aal, &atl);
02364   ImgLinearPrintMatrixFull(head, 1);
02365   fprintf(stdout, "NOTICE : aal %.3f atl %.3f\n", aal, atl);
02366   ImgLinearPrintMatrix(head);
02367 
02386 }
02387 
02399 static void
02400 ImgLinearConjunctionOrder(Relation_t *head, char *baseName, int refineFlag)
02401 {
02402 Conjunct_t *conjunct;
02403 int i, j;
02404 
02405 
02406   if(head->nSize < 2)   return;
02407   for(i=0; i<head->nSize; i++) {
02408     conjunct = head->conjunctArray[i];
02409     conjunct->dummy = 0;
02410     for(j=0; j<conjunct->nSize; j++)
02411       conjunct->dummy += conjunct->supList[j];
02412   }
02413   qsort(head->conjunctArray, head->nSize, sizeof(Conjunct_t *), 
02414           ImgLinearCompareConjunctSize);
02415   head->bRefineVarArray = 1;
02416   ImgLinearRefineRelation(head);
02417 
02418   ImgLinearCAPOInterfaceConjunctNodes(head, baseName);
02419   ImgLinearCAPOInterfaceConjunctNet(head, baseName);
02420   ImgLinearCAPOInterfaceConjunctScl(head, baseName);
02421   ImgLinearCAPOInterfaceConjunctPl(head, baseName);
02422   ImgLinearCAPOInterfaceAux(head, baseName);
02423   ImgLinearCAPORun("MetaPlacer", baseName, 0);
02424   ImgLinearCAPOReadConjunctOrder(head, baseName);
02425 }
02426 
02427 
02439 static void
02440 ImgLinearCAPOInterfaceConjunctNodes(Relation_t *head, char *baseName)
02441 {
02442 char filename[1024];
02443 FILE *fout;
02444 int i;
02445 
02446   sprintf(filename, "%s.nodes", baseName);
02447   fout = fopen(filename, "w");
02448   fprintf(fout, "UCLA nodes 1.0\n");
02449   if(head->includeNS) {
02450     if(head->includeCS) {
02451       fprintf(fout, "NumNodes : %d\n", head->nSize+2);
02452       fprintf(fout, "NumTerminals : 2\n");
02453     }
02454     else {
02455       fprintf(fout, "NumNodes : %d\n", head->nSize+1);
02456       fprintf(fout, "NumTerminals : 1\n");
02457     }
02458   }
02459   else if(head->includeCS) {
02460     fprintf(fout, "NumNodes : %d\n", head->nSize+1);
02461     fprintf(fout, "NumTerminals : 1\n");
02462   }
02463   else {
02464     fprintf(fout, "NumNodes : %d\n", head->nSize);
02465     fprintf(fout, "NumTerminals : 0\n");
02466   }
02467   
02468   for(i=0; i<head->nSize; i++)
02469     fprintf(fout, "C%d 1 1\n", i);
02470 
02471   if(head->includeCS) 
02472     fprintf(fout, "C%d 1 1 terminal\n", MAXINT-1);
02473 
02474   if(head->includeNS)
02475     fprintf(fout, "C%d 1 1 terminal\n", MAXINT);
02476 
02477   fclose(fout);
02478 }
02479 
02491 static void
02492 ImgLinearCAPOInterfaceConjunctNet(Relation_t *head, char *baseName)
02493 {
02494 char filename[1024];
02495 FILE *fout;
02496 VarLife_t **varArray, *var;
02497 int i, j, nPin;
02498 
02499   varArray = head->varArray;
02500   sprintf(filename, "%s.nets", baseName);
02501   fout = fopen(filename, "w");
02502   fprintf(fout, "UCLA nets 1.0\n");
02503   fprintf(fout, "#NumNets : %d\n", head->nVarArray);
02504 
02505   qsort(head->varArray, head->nVarArray, sizeof(VarLife_t *), ImgLinearCompareVarId);
02506   nPin = 0;
02507   for(i=0; i<head->nVarArray; i++) {
02508     var = varArray[i];
02509     if(var->nSize == 1) nPin += 2;
02510     else                nPin += var->nSize;
02511   }
02512   fprintf(fout, "NumPins : %d\n", nPin);
02513 
02514   for(i=0; i<head->nVarArray; i++) {
02515     var = varArray[i];
02516     if(var->nSize == 1)
02517       fprintf(fout, "NetDegree : %d S%d\n", var->nSize+1, var->id);
02518     else
02519       fprintf(fout, "NetDegree : %d S%d\n", var->nSize, var->id);
02520 
02521     for(j=0; j<var->nSize; j++)
02522       fprintf(fout, "C%d B\n", var->relArr[j]);
02523 
02524     if(var->nSize == 1) 
02525       fprintf(fout, "C%d B\n", var->relArr[0]);
02526   }
02527   fclose(fout);
02528 }
02529 
02530 
02542 static void
02543 ImgLinearCAPOInterfaceConjunctScl(Relation_t *head, char *baseName)
02544 {
02545 char filename[1024];
02546 FILE *fout;
02547 
02548   sprintf(filename, "%s.scl", baseName);
02549   fout = fopen(filename, "w");
02550   fprintf(fout, "UCLA scl 1.0\n");
02551   fprintf(fout, "Numrows : 1\n");
02552   fprintf(fout, "CoreRow Horizontal\n");
02553   fprintf(fout, " Coordinate   : 1\n");
02554   fprintf(fout, " Height       : 1\n");
02555   fprintf(fout, " Sitewidth    : 1\n");
02556   fprintf(fout, " Sitespacing  : 1\n");
02557   fprintf(fout, " Siteorient   : N\n");
02558   fprintf(fout, " Sitesymmetry : Y\n");
02559   fprintf(fout, " SubrowOrigin : 0\n");
02560   fprintf(fout, " Numsites     : %d\n", head->nSize*2+2);
02561   fprintf(fout, "End\n");
02562   fclose(fout);
02563 }
02564 
02576 static void
02577 ImgLinearCAPOInterfaceConjunctPl(Relation_t *head, char *baseName)
02578 {
02579 char filename[1024];
02580 FILE *fout;
02581 int i;
02582 
02583   sprintf(filename, "%s.pl", baseName);
02584   fout = fopen(filename, "w");
02585 
02586   fprintf(fout, "UCLA pl 1.0\n");
02587   for(i=0; i<head->nSize; i++)
02588     fprintf(fout, "C%d %d 1\n", i, (i+2)*2+1);
02589 
02590   if(head->includeCS)
02591     fprintf(fout, "C%d 0 1 / N / FIXED\n", MAXINT-1);
02592 
02593   if(head->includeNS)
02594     fprintf(fout, "C%d %d 1 / N / FIXED\n", MAXINT, (head->nSize+2)*2+1);
02595 
02596   fclose(fout);
02597 }
02598 
02610 static void
02611 ImgLinearCAPOInterfaceAux(Relation_t *head, char *baseName)
02612 {
02613 char filename[1024];
02614 FILE *fout;
02615 
02616   sprintf(filename, "%s.aux", baseName);
02617   fout = fopen(filename, "w");
02618   fprintf(fout, "RowBasedPlacement : ");
02619   fprintf(fout, "%s.nodes %s.nets %s.pl %s.scl\n", 
02620                 baseName, baseName, baseName, baseName);
02621   fclose(fout);
02622 }
02623 
02635 static int
02636 ImgLinearCAPORun(char *capoExe, char *baseName, int brief)
02637 {
02638 char logFile[1024];
02639 char capoOption[1024];
02640 char command[1024];
02641 char cpCommand[1024];
02642 FILE *fout;
02643 int cmdStatus;
02644 
02645   fout = fopen("seeds.in", "w");
02646   fprintf(fout, "0\n");
02647   fprintf(fout, "460427264\n");
02648   fclose(fout);
02649 
02650 
02651   if(brief)     
02652     sprintf(capoOption, "-replaceSmallBlocks Never -noRowIroning -save -saveXorder");
02653   else          
02654     sprintf(capoOption, "-save -saveXorder -clust CutOpt");
02655 
02656   sprintf(logFile, "%s.log", baseName);
02657   sprintf(command, "%s -f %s.aux %s > %s", 
02658             capoExe, baseName, capoOption, logFile);
02659   cmdStatus = system(command);
02660   sprintf(cpCommand, "cp left2right.ord %s.ord", baseName);
02661   cmdStatus |= system(cpCommand);
02662 
02663   unlink("seeds.out");
02664   unlink("left2right.ord");
02665   return (cmdStatus == 0);
02666 }
02667 
02668 
02680 static void
02681 ImgLinearCAPOReadConjunctOrder(Relation_t *head, char *baseName)
02682 {
02683 char ordFile[1024];
02684 char line[1024];
02685 int index, id;
02686 char *next;
02687 FILE *fin;
02688 Conjunct_t *conjunct;
02689 
02690   sprintf(ordFile, "%s.ord", baseName);
02691   if(!(fin = fopen(ordFile, "r"))) {
02692     fprintf(stdout, "Can't open order file %s\n", ordFile);
02693     exit(0);
02694   }
02695   index = 0;
02696   while(fgets(line, 1024, fin)){
02697     next = strchr(line, 'C');
02698     next++;
02699     sscanf(next, "%d", &id);
02700     if(id == MAXINT) continue;
02701     if(id == MAXINT-1) continue;
02702     conjunct = head->conjunctArray[id];
02703     conjunct->index = index;
02704     index++;
02705   }
02706   fclose(fin);
02707 
02708   qsort(head->conjunctArray, head->nSize, sizeof(Conjunct_t *), ImgLinearCompareConjunctIndex);
02709 
02710   head->bModified = 1;
02711   head->bRefineVarArray = 1;
02712   ImgLinearRefineRelation(head);
02713 }
02714 
02726 static void
02727 ImgLinearVariableOrder(Relation_t *head, char *baseName, int includeNS)
02728 {
02729   ImgLinearCAPOInterfaceVariableNodes(head, baseName, includeNS);
02730   ImgLinearCAPOInterfaceVariableNet(head, baseName, includeNS);
02731   ImgLinearCAPOInterfaceVariableScl(head, baseName);
02732   ImgLinearCAPOInterfaceVariablePl(head, baseName, includeNS);
02733   ImgLinearCAPOInterfaceAux(head, baseName);
02734   ImgLinearCAPORun("MetaPlacer", baseName, 0);
02735   ImgLinearCAPOReadVariableOrder(head, baseName, includeNS);
02736 }
02737 
02749 void
02750 ImgLinearCAPOInterfaceVariableNodes(Relation_t *head, char *baseName, int includeNS)
02751 {
02752 int i, size;
02753 VarLife_t **varArray, *var;
02754 int *varType;
02755 char filename[1024];
02756 FILE *fout;
02757 int numUnused;
02758 
02759   varArray = head->varArray;
02760   varType = head->varType;
02761   sprintf(filename, "%s.nodes", baseName);
02762   fout = fopen(filename, "w");
02763 
02764   fprintf(fout, "UCLA nodes 1.0\n");
02765 
02766   size = 0;
02767   if(includeNS) size = head->nVarArray;
02768   else {
02769     for(i=0; i<head->nVarArray; i++) {
02770       if(varType[varArray[i]->id] == 2) continue;
02771       size++;
02772     }
02773   }
02774 
02775   numUnused = 0;
02776   for(i=0; i<head->nVar; i++) {
02777     if(varType[i] != 1) continue; /* if it is not domain variable **/
02778     var = head->varArrayMap[i] >=0 ? head->varArray[head->varArrayMap[i]] : 0;
02779     if(var)     continue;
02780     numUnused++;
02781   }
02782   if(includeNS) {
02783     for(i=0; i<head->nVar; i++) {
02784       if(varType[i] != 2)       continue; /* if it is not range variable **/
02785       var = head->varArrayMap[i] >=0 ? head->varArray[head->varArrayMap[i]] : 0;
02786      if(var)    continue;
02787       numUnused++;
02788     }
02789   }
02790   
02791   fprintf(fout, "NumNodes : %d\n", size+numUnused);
02792   fprintf(fout, "NumTerminals : 0\n");
02793   for(i=0; i<head->nVarArray; i++) {
02794     var = varArray[i];
02795     if(includeNS == 0 && varType[var->id] == 2) continue;
02796     fprintf(fout, "C%d 1 1\n", var->id);
02797   }
02798 
02799   for(i=0; i<head->nVar; i++) {
02800     if(varType[i] != 1) continue; /* if it is not domain variable **/
02801     var = head->varArrayMap[i] >=0 ? head->varArray[head->varArrayMap[i]] : 0;
02802     if(var)     continue;
02803     fprintf(fout, "C%d 1 1\n", i);
02804   }
02805   if(includeNS) {
02806     for(i=0; i<head->nVar; i++) {
02807       if(varType[i] != 2)       continue; /* if it is not range variable **/
02808       var = head->varArrayMap[i] >=0 ? head->varArray[head->varArrayMap[i]] : 0;
02809      if(var)    continue;
02810       fprintf(fout, "C%d 1 1\n", i);
02811     }
02812   }
02813   fclose(fout);
02814 }
02815 
02827 static void
02828 ImgLinearCAPOInterfaceVariableNet(Relation_t *head, 
02829                                   char *baseName, 
02830                                   int includeNS)
02831 {
02832 int nPin, i, j;
02833 int id, size;
02834 Conjunct_t *conjunct;
02835 bdd_t *relation;
02836 int *supList, *varType;
02837 char filename[1024];
02838 FILE *fout;
02839 
02840   nPin = 0;
02841   for(i=0; i<head->nSize; i++) {
02842     conjunct = head->conjunctArray[i];
02843     relation = conjunct->relation;
02844     if(relation == (mdd_t *)(MAXINT-1)) continue;
02845     supList = conjunct->supList;
02846     if(includeNS) {
02847       if(conjunct->nSize == 1)  nPin += 2; 
02848       else                      nPin += conjunct->nSize-conjunct->nRange;
02849     }
02850     else {
02851       if(conjunct->nSize-conjunct->nRange == 1) nPin += 2;
02852       else                                      nPin += conjunct->nSize-conjunct->nRange;
02853     }
02854   }
02855   nPin += head->nDomain;
02856   if(includeNS)
02857     nPin += head->nRange;
02858 
02859   varType = head->varType;
02860   sprintf(filename, "%s.nets", baseName);
02861   fout = fopen(filename, "w");
02862   fprintf(fout, "UCLA nets 1.0\n");
02863   fprintf(fout, "#NumNets : %d\n", head->nSize);
02864   fprintf(fout, "NumPins : %d\n", nPin);
02865   for(i=0; i<head->nSize; i++) {
02866     conjunct = head->conjunctArray[i];
02867     relation = conjunct->relation;
02868     if(relation == (mdd_t *)(MAXINT-1)) continue;
02869 
02870     supList = conjunct->supList;
02871     if(includeNS)       size = conjunct->nSize;
02872     else                size = conjunct->nSize - conjunct->nRange;
02873 
02874     if(size == 1)       fprintf(fout, "NetDegree : %d \n", 2);
02875     else                fprintf(fout, "NetDegree : %d \n", size);
02876 
02877     id = 0;
02878     if(includeNS) {
02879       for(j=0; j<conjunct->nSize; j++) {
02880         id = supList[j];
02881         fprintf(fout, "C%d B\n", id);
02882       }
02883     }
02884     else {
02885       for(j=0; j<conjunct->nSize; j++) {
02886         id = supList[j];
02887         if(varType[id] == 2)    continue;
02888         fprintf(fout, "C%d B\n", id);
02889       }
02890     }
02891     if(size == 1)
02892       fprintf(fout, "C%d B\n", id);
02893   }
02894   fprintf(fout, "NetDegree : %d \n", head->nDomain);
02895   for(i=0; i<head->nVar; i++) {
02896     if(varType[i] == 1) 
02897       fprintf(fout, "C%d B\n", i);
02898   }
02899   if(includeNS) {
02900     fprintf(fout, "NetDegree : %d \n", head->nRange);
02901     for(i=0; i<head->nVar; i++) {
02902       if(varType[i] == 2) 
02903         fprintf(fout, "C%d B\n", i);
02904     }
02905   }
02906   fclose(fout);
02907 }
02908 
02920 static void
02921 ImgLinearCAPOInterfaceVariableScl(Relation_t *head, char *baseName)
02922 {
02923 char filename[1024];
02924 FILE *fout;
02925 
02926   sprintf(filename, "%s.scl", baseName);
02927   fout = fopen(filename, "w");
02928   fprintf(fout, "UCLA scl 1.0\n");
02929   fprintf(fout, "Numrows : 1\n");
02930   fprintf(fout, "CoreRow Horizontal\n");
02931   fprintf(fout, " Coordinate   : 1\n");
02932   fprintf(fout, " Height       : 1\n");
02933   fprintf(fout, " Sitewidth    : 1\n");
02934   fprintf(fout, " Sitespacing  : 1\n");
02935   fprintf(fout, " Siteorient   : N\n");
02936   fprintf(fout, " Sitesymmetry : Y\n");
02937   fprintf(fout, " SubrowOrigin : 0\n");
02938   fprintf(fout, " Numsites     : %d\n", head->nVarArray*2+2);
02939   fprintf(fout, "End\n");
02940   fclose(fout);
02941 }
02942 
02943 
02955 static void
02956 ImgLinearCAPOInterfaceVariablePl(Relation_t *head, char *baseName, int includeNS)
02957 {
02958 char filename[1024];
02959 FILE *fout;
02960 VarLife_t *var, **varArray;
02961 int i, index, *varType;
02962 
02963   varType = head->varType;
02964   sprintf(filename, "%s.pl", baseName);
02965   fout = fopen(filename, "w");
02966   fprintf(fout, "UCLA pl 1.0\n");
02967   varArray = head->varArray;
02968   for(index=0, i=0; i<head->nVarArray; i++) {
02969     var = varArray[i];
02970     if(includeNS == 0 && varType[var->id] == 2) continue;
02971     fprintf(fout, "C%d %d 1\n", var->id, (index+1)*2+1);
02972     index++;
02973   }
02974   fclose(fout);
02975 }
02976 
02977 
02978 
02990 static void
02991 ImgLinearCAPOReadVariableOrder(Relation_t *head, char *baseName, int includeNS)
02992 {
02993 char ordFile[1024], line[1024];
02994 FILE *fin;
02995 char *next;
02996 int i, id, index, *permutation, *exist;
02997 
02998   sprintf(ordFile, "%s.ord", baseName);
02999   if(!(fin = fopen(ordFile, "r"))) {
03000     fprintf(stdout, "Can't open order file %s\n", ordFile);
03001     exit(0);
03002   }
03003 
03004   permutation = ALLOC(int, head->nVar);
03005   exist = ALLOC(int, head->nVar);
03006   memset(exist, 0, sizeof(int)*head->nVar);
03007 
03008   index = 0;
03009   while(fgets(line, 1024, fin)){
03010     next = strchr(line, 'C');
03011     next++;
03012     sscanf(next, "%d", &id);
03013     permutation[index++] = id;
03014     exist[id] = 1;
03015     if(includeNS == 0 && head->varType[id] == 1) {
03016       permutation[index++] = head->domain2range[id];
03017       exist[head->domain2range[id]] = 1;
03018     }
03019   }
03020   fclose(fin);
03021 
03022   for(i=0; i<head->nVar; i++)
03023     if(exist[i] == 0)
03024       permutation[index++] = i;
03025 
03026   free(exist);
03027 
03028   bdd_shuffle_heap(head->mgr, permutation);
03029 
03030   free(permutation);
03031 }
03032 
03044 static void
03045 ImgLinearPrintVariableProfile(Relation_t *head, char *baseName)
03046 {
03047 double aal, atl;
03048 char filename[1024];
03049 FILE *fout;
03050 st_table *cutSet;
03051 int i, j, nDead, id;
03052 int *varType;
03053 int *supList;
03054 Conjunct_t *conjunct;
03055 VarLife_t *var;
03056 st_generator *gen;
03057 
03058   ImgLinearVariableArrayInit(head);
03059   varType = head->varType;
03060 
03061   sprintf(filename, "%s.data", baseName);
03062   fout = fopen(filename, "w");
03063 
03064   cutSet = st_init_table(st_numcmp, st_numhash);
03065   for(i=0; i<head->nVar; i++) {
03066     if(varType[i] == 1) 
03067       st_insert(cutSet, (char *)(long)i, (char *)(long)i);
03068   }
03069 
03070   for(i=0; i<head->nSize; i++) {
03071     conjunct = head->conjunctArray[i];
03072     supList = conjunct->supList;
03073     for(j=0; j<conjunct->nSize; j++)
03074       st_insert(cutSet, (char *)(long)supList[j], (char *)(long)supList[j]);
03075 
03076     nDead = 0;
03077     st_foreach_item(cutSet, gen, &id, &id) {
03078       if(varType[id] == 2) continue;
03079 
03080       var = head->varArrayMap[id] >=0 ? head->varArray[head->varArrayMap[id]] :
03081 0;
03082       if(!var) continue;
03083       
03084       if(var->to <= i)  {
03085         nDead++;
03086         st_delete(cutSet, (&id), NULL);
03087       }
03088     }
03089     fprintf(fout, "%d %d %d\n", i, cutSet->num_entries, cutSet->num_entries+nDead);
03090   }
03091   fclose(fout);
03092 
03093   ImgLinearComputeLifeTime(head, &aal, &atl);
03094 
03095   sprintf(filename, "%s.gnu", baseName);
03096   fout = fopen(filename, "w");
03097   fprintf(fout, "set terminal postscript \n");
03098   fprintf(fout, "set output \"%s.ps\"\n", baseName);
03099   fprintf(fout, "set title \"profile of live variable aal %.3f atl %.3f\"\n",
03100           aal, atl);
03101   fprintf(fout, "plot \"%s.data\" using 1:2 title \"%s\" with lines, \\\n", baseName, "cut");
03102   fprintf(fout, "     \"%s.data\" using 1:3 title \"%s\" with lines\n", baseName, "cut+dead");
03103   fclose(fout);
03104 }
03105 
03117 void
03118 ImgLinearPrintMatrix(Relation_t *head)
03119 {
03120 int i, j, id, index;
03121 int *mapArray;
03122 VarLife_t **varArray, *var;
03123 VarLife_t **auxArr, **sortArr;
03124 int nAuxArr, nSortArr;
03125 array_t *smoothVarBddArr, *smoothArray;
03126 bdd_t *varBdd;
03127 Conjunct_t *conjunct;
03128 bdd_t *relation;
03129 int *supList, *varType;
03130 char *buffer;
03131 int maxIndex;
03132 
03133   if(head->verbosity < 5)       return;
03134 
03135   ImgLinearVariableArrayInit(head);
03136 
03137   mapArray = ALLOC(int, head->nVar);
03138   memset(mapArray, -1, sizeof(int)*head->nVar);
03139 
03140   varArray = head->varArray;
03141 
03142   smoothVarBddArr = ImgLinearMakeSmoothVarBdd(head, 0);
03143   for(index=0, i=0; i<array_n(smoothVarBddArr); i++) {
03144     smoothArray = array_fetch(array_t *, smoothVarBddArr, i);
03145     nAuxArr = 0;
03146     auxArr = ALLOC(VarLife_t *, nAuxArr+1);
03147     for(j=0; j<array_n(smoothArray); j++) {
03148       varBdd = array_fetch(bdd_t *, smoothArray, j);
03149       id = (int)bdd_top_var_id(varBdd);
03150 
03151       var = head->varArrayMap[id] >=0 ? head->varArray[head->varArrayMap[id]] :
03152 0;
03153       if(var) {
03154         auxArr[nAuxArr++] = var;
03155         auxArr = REALLOC(VarLife_t *, auxArr, nAuxArr+1);
03156       }
03157     }
03158     qsort(auxArr, nAuxArr, sizeof(VarLife_t *), ImgLinearCompareVarIndex);
03159     for(j=0; j<nAuxArr; j++)
03160       mapArray[auxArr[j]->id] = index++;
03161     free(auxArr);
03162   }
03163 
03164   varArray = head->varArray;
03165   nSortArr = 0;
03166   sortArr = ALLOC(VarLife_t *, nSortArr+1);
03167   for(i=0; i<head->nVarArray; i++) {
03168     var = varArray[i];
03169     if(var->stateVar == 2)      continue;
03170     if(mapArray[var->id] >= 0) {
03171       var->index = mapArray[var->id];
03172       sortArr[nSortArr++] = var;
03173       sortArr = REALLOC(VarLife_t *, sortArr, nSortArr+1);
03174     }
03175     else {
03176       var->index = (double)MAXINT;
03177     }
03178   }
03179   qsort(sortArr, nSortArr, sizeof(VarLife_t *), ImgLinearCompareVarIndex);
03180 
03181   fprintf(stdout, "     ");
03182   for(i=0; i<nSortArr; i++) fprintf(stdout, "%d", (i/10)%10);
03183   fprintf(stdout, "\n");
03184 
03185   fprintf(stdout, "     ");
03186   for(i=0; i<nSortArr; i++) fprintf(stdout, "%d", i%10);
03187   fprintf(stdout, "\n");
03188 
03189   buffer = ALLOC(char , nSortArr+1);
03190   for(i=0; i<nSortArr; i++) {
03191     var = sortArr[i];
03192     var->index = (double)i;
03193     if(var->stateVar == 1)      buffer[i] = 'C';
03194     else                        buffer[i] = 'T';
03195   }
03196   buffer[i] = '\0';
03197   free(sortArr);
03198   fprintf(stdout, "     %s\n", buffer);
03199 
03200   maxIndex = i;
03201   for(i=0; i<maxIndex; i++)     buffer[i] = '.';
03202   buffer[i] = '\0';
03203 
03204   varType = head->varType;
03205   for(index=0,i=head->nSize-1;i>=0; i--) {
03206     conjunct = head->conjunctArray[i];
03207     if(conjunct == 0)   continue;
03208     if(conjunct->relation == 0) continue;
03209     relation = conjunct->relation;
03210     if(relation == (mdd_t *)(MAXINT-1)) continue;
03211     if(relation == 0)                   continue;
03212     supList = conjunct->supList;
03213     for(j=0; j<conjunct->nSize; j++) {
03214       id = supList[j];
03215       if(varType[id] == 2)              continue;
03216       var = head->varArrayMap[id] >=0 ? head->varArray[head->varArrayMap[id]] :
03217 0;
03218       if(!var)  continue;
03219       if((int)var->index == MAXINT)     continue;
03220       buffer[(int)var->index] = '1';
03221     }
03222     index++;
03223     fprintf(stdout, "%4d %s %d %d\n", i, buffer, conjunct->nRange, bdd_size(relation));
03224     fflush(stdout);
03225     for(j=0; j<maxIndex; j++)   buffer[j] = '.';
03226     buffer[j] = '\0';
03227   }
03228   free(buffer);
03229 }
03241 void
03242 ImgLinearPrintMatrixFull(Relation_t *head, int matrixIndex)
03243 {
03244 int i, j, id, index;
03245 int *mapArray;
03246 VarLife_t **varArray, *var;
03247 VarLife_t **auxArr, **sortArr;
03248 int nAuxArr, nSortArr;
03249 array_t *smoothVarBddArr, *smoothArray;
03250 FILE *fout;
03251 int min, max;
03252 bdd_t *varBdd;
03253 char filename[1024];
03254 Conjunct_t *conjunct;
03255 bdd_t *relation;
03256 int *supList;
03257 
03258   ImgLinearVariableArrayInit(head);
03259 
03260   mapArray = ALLOC(int, head->nVar);
03261   memset(mapArray, -1, sizeof(int)*head->nVar);
03262   varArray = head->varArray;
03263 
03264   smoothVarBddArr = ImgLinearMakeSmoothVarBdd(head, 0);
03265   for(index=0, i=0; i<array_n(smoothVarBddArr); i++) {
03266     smoothArray = array_fetch(array_t *, smoothVarBddArr, i);
03267     nAuxArr = 0;
03268     auxArr = ALLOC(VarLife_t *, nAuxArr+1);
03269     for(j=0; j<array_n(smoothArray); j++) {
03270       varBdd = array_fetch(bdd_t *, smoothArray, j);
03271       id = (int)bdd_top_var_id(varBdd);
03272 
03273       var = head->varArrayMap[id] >=0 ? varArray[head->varArrayMap[id]] : 0;
03274       if(var) {
03275         auxArr[nAuxArr++] = var;
03276         auxArr = REALLOC(VarLife_t *, auxArr, nAuxArr+1);
03277       }
03278     }
03279     qsort(auxArr, nAuxArr, sizeof(VarLife_t *), ImgLinearCompareVarIndex);
03280     for(j=0; j<nAuxArr; j++)
03281       mapArray[auxArr[j]->id] = index++;
03282     free(auxArr);
03283   }
03284 
03285   nSortArr = 0;
03286   sortArr = ALLOC(VarLife_t *, nSortArr+1);
03287   for(i=0; i<head->nVarArray; i++) {
03288     var = varArray[i];
03289     if(var->stateVar == 2)      continue;
03290     if(mapArray[var->id] >= 0) {
03291       var->index = mapArray[var->id];
03292       sortArr[nSortArr++] = var;
03293       sortArr = REALLOC(VarLife_t *, sortArr, nSortArr+1);
03294     }
03295     else {
03296       var->index = (double)MAXINT;
03297     }
03298   }
03299 
03300   qsort(sortArr, nSortArr, sizeof(VarLife_t *), ImgLinearCompareVarIndex);
03301   free(mapArray);
03302 
03303   sprintf(filename, "fullmatrix%d.data", matrixIndex);
03304   fout = fopen(filename, "w");
03305   min = 0;
03306   max = head->nSize+1;
03307   for(i=0; i<nSortArr; i++) {
03308     var = sortArr[i];
03309     if(var->stateVar == 1)
03310       fprintf(fout, "%d %d\n", (int)var->index, min);
03311   }
03312   free(sortArr);
03313 
03314   for(index=0, i=0; i<head->nSize; i++) {
03315     conjunct = head->conjunctArray[i];
03316     relation = conjunct->relation;
03317     if(relation == (mdd_t *)(MAXINT-1)) continue;
03318     if(relation == 0)                   continue;
03319     supList = conjunct->supList;
03320     for(j=0; j<conjunct->nSize; j++) {
03321       id = supList[j];
03322       var = head->varArrayMap[id] >=0 ? head->varArray[head->varArrayMap[id]] : 0;
03323       if(!var)  continue; 
03324       if(var->stateVar == 2)
03325       if((int)var->index == MAXINT) continue;
03326       fprintf(fout, "%d %d\n", (int)var->index, index+1);
03327     }
03328     index++;
03329   }
03330   fclose(fout);
03331 
03332   sprintf(filename, "fullmatrix%d.gnu", matrixIndex);
03333   fout = fopen(filename, "w");
03334   fprintf(fout, "set terminal postscript \n");
03335   fprintf(fout, "set output \"fullmatrix%d.ps\"\n", matrixIndex);
03336   fprintf(fout, "set title \"profile of live variable\"\n");
03337   fprintf(fout, "set yrange [-1:%d]\n", head->nSize+2);
03338   fprintf(fout, "plot \"fullmatrix%d.data\" using 1:2 title \"%d\" with point\n",
03339                   matrixIndex, matrixIndex);
03340   fclose(fout);
03341 
03342   ImgLinearFreeSmoothArray(smoothVarBddArr);
03343 }
03344 
03356 void
03357 ImgLinearFreeSmoothArray(array_t *smoothVarBddArray)
03358 {
03359 int i;
03360 array_t *smoothArray;
03361 
03362   for(i=0; i<array_n(smoothVarBddArray); i++) {
03363     smoothArray = array_fetch(array_t *, smoothVarBddArray, i);
03364     mdd_array_free(smoothArray);
03365   }
03366   array_free(smoothVarBddArray);
03367 }
03368 
03380 void
03381 ImgLinearComputeLifeTime(Relation_t *head, double *paal, double *patl)
03382 {
03383 double aal, atl;
03384 int i;
03385 VarLife_t **varArray, *var;
03386 
03387   aal = atl = 0.0;
03388   varArray = head->varArray;
03389   for(i=0; i<head->nVarArray; i++) {
03390     var = varArray[i];
03391     aal += var->effTo - var->effFrom;
03392     if(var->stateVar == 1)      atl += var->to+1;
03393     else if(var->stateVar == 2) atl += head->nSize+1 - var->from;
03394     else                        atl += var->to - var->from;
03395   }
03396   atl = atl / (double)(head->nVarArray * head->nSize);
03397   aal = aal / (double)(head->nVarArray * head->nSize);
03398 
03399   *paal = aal;
03400   *patl = atl;
03401 }
03402 
03414 static void
03415 ImgLinearPrintTransitionInfo(Relation_t *head)
03416 {
03417 double aal, atl;
03418 
03419   fprintf(stdout, "SUMMARY : domain   variables %d -> %d -> %d\n", 
03420           head->nDomain, head->nInitDomain, head->nEffDomain);
03421   fprintf(stdout, "SUMMARY : range    variables %d -> %d -> %d\n", 
03422           head->nRange, head->nInitRange, head->nEffRange);
03423   fprintf(stdout, "SUMMARY : quantify variables %d -> %d -> %d\n", 
03424           head->nQuantify, head->nInitQuantify, head->nEffQuantify);
03425   fprintf(stdout, "SUMMARY : number of transition relation %d\n", 
03426           head->nSize);
03427   ImgLinearComputeLifeTime(head, &aal, &atl);
03428   fprintf(stdout, "Active  Life Time : %g\n", aal);
03429   fprintf(stdout, "Average Life Time : %g\n", atl);
03430 }
03431 
03432 
03433 
03445 array_t *
03446 ImgLinearMakeSmoothVarBdd(Relation_t *head, bdd_t **smoothCubeArr)
03447 {
03448 array_t *smoothVarBddArray;
03449 array_t *smoothArray;
03450 VarLife_t **varArray;
03451 int i, j, id;
03452 VarLife_t *var;
03453 bdd_t *varBdd, *cube, *newCube;
03454 
03455   smoothVarBddArray = array_alloc(array_t *, 0);
03456   for(i=0; i<=head->nSize; i++) {
03457     smoothArray = array_alloc(bdd_t *, 0);
03458     array_insert_last(array_t *, smoothVarBddArray, smoothArray);
03459   } 
03460 
03461   varArray = head->varArray;
03462   for(i=0; i<head->nVarArray; i++) {
03463     var = varArray[i];
03464     if(var->stateVar == 2)      continue;
03465     smoothArray = array_fetch(array_t *, smoothVarBddArray, var->to+1);
03466     varBdd = bdd_get_variable(head->mgr, var->id);
03467     array_insert_last(bdd_t *, smoothArray, varBdd);
03468   }
03469 
03470   smoothArray = array_fetch(array_t *, smoothVarBddArray, 0);
03471   for(i=0; i<head->nDomain; i++) {
03472     id = head->domainVars[i];
03473     var = head->varArrayMap[id] >=0 ? head->varArray[head->varArrayMap[id]] : 0;
03474    if(var)      continue;
03475     varBdd = bdd_get_variable(head->mgr, id);
03476     array_insert_last(bdd_t *, smoothArray, varBdd);
03477   }
03478 
03479   if(smoothCubeArr) {
03480     for(i=0; i<=head->nSize; i++) {
03481       smoothArray = array_fetch(array_t *, smoothVarBddArray, i);
03482       cube = bdd_one(head->mgr);
03483       for(j=0; j<array_n(smoothArray); j++) {
03484         varBdd = array_fetch(bdd_t *, smoothArray, j);
03485         newCube = bdd_and(varBdd, cube, 1, 1);
03486         bdd_free(cube);
03487         cube = newCube;
03488       }
03489       smoothCubeArr[i] = cube;
03490     }
03491   }
03492 
03493   return(smoothVarBddArray);
03494 }
03495 
03507 static int
03508 ImgLinearCompareVarEffFromSmall(const void *c1, const void *c2)
03509 {
03510 VarLife_t *con1, *con2;
03511 
03512   con1 = *(VarLife_t **)c1;
03513   con2 = *(VarLife_t **)c2;
03514   return(con1->effFrom > con2->effFrom);
03515 }
03516 
03528 static int
03529 ImgLinearCompareVarDummyLarge(const void *c1, const void *c2)
03530 {
03531 VarLife_t *con1, *con2;
03532 
03533   con1 = *(VarLife_t **)c1;
03534   con2 = *(VarLife_t **)c2;
03535   return(con1->dummy < con2->dummy);
03536 }
03537 
03549 static int
03550 ImgLinearCompareVarEffFromLarge(const void *c1, const void *c2)
03551 {
03552 VarLife_t *con1, *con2;
03553 
03554   con1 = *(VarLife_t **)c1;
03555   con2 = *(VarLife_t **)c2;
03556   return(con1->effFrom < con2->effFrom);
03557 }
03558 
03570 static int
03571 ImgLinearCompareVarId(const void *c1, const void *c2)
03572 {
03573 VarLife_t *con1, *con2;
03574 
03575   con1 = *(VarLife_t **)c1;
03576   con2 = *(VarLife_t **)c2;
03577   return(con1->id < con2->id);
03578 }
03579 
03591 static int
03592 ImgLinearCompareVarSize(const void *c1, const void *c2)
03593 {
03594 VarLife_t *con1, *con2;
03595 
03596   con1 = *(VarLife_t **)c1;
03597   con2 = *(VarLife_t **)c2;
03598   return(con1->nSize > con2->nSize);
03599 }
03600 
03612 static int
03613 ImgLinearCompareConjunctRangeMinusDomain(const void *c1, const void *c2)
03614 {
03615 Conjunct_t *con1, *con2;
03616 
03617   con1 = *(Conjunct_t **)c1;
03618   con2 = *(Conjunct_t **)c2;
03619   return(con1->nRange-con1->nDomain > con2->nRange-con2->nDomain);
03620 }
03621 
03633 static int
03634 ImgLinearCompareConjunctDummy(const void *c1, const void *c2)
03635 {
03636 Conjunct_t *con1, *con2;
03637 
03638   con1 = *(Conjunct_t **)c1;
03639   con2 = *(Conjunct_t **)c2;
03640   return(con1->dummy > con2->dummy); 
03641 }
03642 
03654 static int
03655 ImgLinearCompareConjunctIndex(const void *c1, const void *c2)
03656 {
03657 Conjunct_t *con1, *con2;
03658 
03659   con1 = *(Conjunct_t **)c1;
03660   con2 = *(Conjunct_t **)c2;
03661 
03662   return(con1->index > con2->index); 
03663 }
03664 
03676 static int
03677 ImgLinearCompareConjunctSize(const void *c1, const void *c2)
03678 {
03679 Conjunct_t *con1, *con2;
03680 
03681   con1 = *(Conjunct_t **)c1;
03682   con2 = *(Conjunct_t **)c2;
03683 
03684   if(con1->nSize == con2->nSize)
03685     return(con1->dummy < con2->dummy);
03686   return(con1->nSize < con2->nSize); 
03687 }
03688 
03700 static int
03701 ImgLinearCompareVarIndex(const void *c1, const void *c2)
03702 {
03703 VarLife_t *v1, *v2;
03704 
03705   v1 = *(VarLife_t **)c1;
03706   v2 = *(VarLife_t **)c2;
03707 
03708   return(v1->index < v2->index); 
03709 }
03710 
03722 static int
03723 ImgLinearCompareDeadAffinityLive(const void *c1, const void *c2)
03724 {
03725 Cluster_t *clu1, *clu2;
03726 
03727   clu1 = *(Cluster_t **)c1;
03728   clu2 = *(Cluster_t **)c2;
03729   if(clu1->nDead == clu2->nDead) {
03730     if(clu1->nAffinity == clu2->nAffinity) {
03731       return(clu1->nVar-clu1->nDead > clu2->nVar-clu2->nDead); 
03732     }
03733     return(clu1->nAffinity < clu2->nAffinity); 
03734   }
03735   return(clu1->nDead < clu2->nDead); 
03736 }
03737 
03749 static int
03750 ImgLinearCompareDeadLiveAffinity(const void *c1, const void *c2)
03751 {
03752 Cluster_t *clu1, *clu2;
03753 
03754   clu1 = *(Cluster_t **)c1;
03755   clu2 = *(Cluster_t **)c2;
03756   if(clu1->nDead == clu2->nDead) {
03757     if(clu1->nVar-clu1->nDead == clu2->nVar-clu2->nDead) {
03758       return(clu1->nAffinity < clu2->nAffinity); 
03759     }
03760     return(clu1->nVar-clu1->nDead > clu2->nVar-clu2->nDead); 
03761   }
03762   return(clu1->nDead < clu2->nDead); 
03763 }
03764 
03776 static int
03777 ImgLinearCompareAffinityDeadLive(const void *c1, const void *c2)
03778 {
03779 Cluster_t *clu1, *clu2;
03780 
03781   clu1 = *(Cluster_t **)c1;
03782   clu2 = *(Cluster_t **)c2;
03783   if(clu1->nAffinity == clu2->nAffinity) {
03784     if(clu1->nDead == clu2->nDead) {
03785       return(clu1->nVar-clu1->nDead > clu2->nVar-clu2->nDead); 
03786     }
03787     return(clu1->nDead < clu2->nDead); 
03788   }
03789   return(clu1->nAffinity < clu2->nAffinity); 
03790 }
03791 
03803 static int
03804 ImgLinearCompareLiveAffinityDead(const void *c1, const void *c2)
03805 {
03806 Cluster_t *clu1, *clu2;
03807 
03808   clu1 = *(Cluster_t **)c1;
03809   clu2 = *(Cluster_t **)c2;
03810   if(clu1->nVar-clu1->nDead == clu2->nVar-clu2->nDead) {
03811     if(clu1->nAffinity == clu2->nAffinity) {
03812       return(clu1->nDead < clu2->nDead);
03813     }
03814     return(clu1->nAffinity < clu2->nAffinity);
03815   }
03816   return(clu1->nVar-clu1->nDead > clu2->nVar-clu2->nDead);
03817 }
03818 
03830 static int
03831 ImgLinearHeapCompareDeadAffinityLive(const void *c1, const void *c2)
03832 {
03833 Cluster_t *clu1, *clu2;
03834 
03835   clu1 = (Cluster_t *)c1;
03836   clu2 = (Cluster_t *)c2;
03837   if(clu1->nDead == clu2->nDead) {
03838     if(clu1->nAffinity == clu2->nAffinity) {
03839       return((clu1->nVar-clu1->nDead) > (clu2->nVar-clu2->nDead)); 
03840     }
03841     return(clu1->nAffinity < clu2->nAffinity); 
03842   }
03843   return(clu1->nDead < clu2->nDead); 
03844 }
03845 
03857 static int
03858 ImgLinearHeapCompareDeadLiveAffinity(const void *c1, const void *c2)
03859 {
03860 Cluster_t *clu1, *clu2;
03861 
03862   clu1 = (Cluster_t *)c1;
03863   clu2 = (Cluster_t *)c2;
03864   if(clu1->nDead == clu2->nDead) {
03865     if((clu1->nVar-clu1->nDead) == (clu2->nVar-clu2->nDead)) {
03866       return(clu1->nAffinity < clu2->nAffinity); 
03867     }
03868     return((clu1->nVar-clu1->nDead) > (clu2->nVar-clu2->nDead)); 
03869   }
03870   return(clu1->nDead < clu2->nDead); 
03871 }
03872 
03884 static int
03885 ImgLinearHeapCompareAffinityDeadLive(const void *c1, const void *c2)
03886 {
03887 Cluster_t *clu1, *clu2;
03888 
03889   clu1 = (Cluster_t *)c1;
03890   clu2 = (Cluster_t *)c2;
03891   if(clu1->nAffinity == clu2->nAffinity) {
03892     if(clu1->nDead == clu2->nDead) {
03893       return(clu1->nVar-clu1->nDead > clu2->nVar-clu2->nDead); 
03894     }
03895     return(clu1->nDead < clu2->nDead); 
03896   }
03897   return(clu1->nAffinity < clu2->nAffinity); 
03898 }
03899 
03911 static int
03912 ImgLinearHeapCompareLiveAffinityDead(const void *c1, const void *c2)
03913 {
03914 Cluster_t *clu1, *clu2;
03915 
03916   clu1 = (Cluster_t *)c1;
03917   clu2 = (Cluster_t *)c2;
03918   if(clu1->nVar-clu1->nDead == clu2->nVar-clu2->nDead) {
03919     if(clu1->nAffinity == clu2->nAffinity) {
03920       return(clu1->nDead < clu2->nDead);
03921     }
03922     return(clu1->nAffinity < clu2->nAffinity);
03923   }
03924   return(clu1->nVar-clu1->nDead > clu2->nVar-clu2->nDead);
03925 }
03926 
03938 static void
03939 ImgLinearVariableArrayInit(Relation_t *head)
03940 {
03941 mdd_manager *mgr;
03942 Conjunct_t **conjunctArray, *conjunct;
03943 Conjunct_t *tConjunct;
03944 bdd_t *relation, *bddOne;
03945 VarLife_t **varArray;
03946 int *supList, listSize;
03947 int *varType, *varArrayMap;
03948 int i, j, k, id, nVarArray;
03949 int nSize, newNum;
03950 
03951 
03952   if(head->bRefineVarArray) {
03953     ImgLinearVariableArrayQuit(head);
03954   }
03955 
03956   if(head->varArray)    return;
03957 
03958   mgr = head->mgr;
03959 
03960   if(head->nVar != (int)(bdd_num_vars(mgr))) {
03961     newNum = bdd_num_vars(head->mgr);
03962     head->domain2range = REALLOC(int, head->domain2range, newNum);
03963     head->range2domain = REALLOC(int, head->range2domain, newNum);
03964     head->varType = REALLOC(int, head->varType, newNum);
03965     head->varArrayMap = REALLOC(int, head->varArrayMap, newNum);
03966     head->constantCase = REALLOC(bdd_t *, head->constantCase, newNum);
03967     head->quantifyVars = REALLOC(int, head->quantifyVars, newNum);
03968 
03969     for(i=head->nVar; i<newNum; i++) {
03970       head->domain2range[i] = -1;
03971       head->range2domain[i] = -1;
03972       head->varType[i] = 0;
03973       head->varArrayMap[i] = -1;
03974       head->constantCase[i] = 0;
03975       head->quantifyVars[i] = 0;
03976     }
03977     head->nVar = bdd_num_vars(head->mgr);
03978   }
03979 
03980   nSize = head->nSize;
03981   conjunctArray = head->conjunctArray;
03982   varArrayMap = head->varArrayMap;
03983 
03984   id = 0;
03985   nVarArray = 0;
03986   varArray = ALLOC(VarLife_t *, nVarArray+1);
03987   head->varArray = varArray;
03988   head->nVarArray = nVarArray;
03989   bddOne = bdd_one(head->mgr);
03990 
03991   varType = head->varType;
03992   for(i=0; i<nSize; i++) {
03993     conjunct = conjunctArray[i];
03994     if(conjunct == 0)   continue;
03995     relation = conjunct->relation;
03996     if(relation == 0)   continue;
03997     if(bdd_equal(bddOne, relation))     continue;
03998     supList = conjunct->supList;
03999     listSize = conjunct->nSize;
04000     for(j=0; j<listSize; j++) {
04001       id = supList[j]; 
04002       ImgLinearUpdateVariableArrayWithId(head, i, id);
04003     }
04004 
04005     for(k=0; k<conjunct->nCluster; k++) {
04006       tConjunct = conjunct->clusterArray[k];
04007       supList = tConjunct->supList;
04008       listSize = tConjunct->nSize;
04009       for(j=0; j<listSize; j++) {
04010         ImgLinearUpdateVariableArrayWithId(head, i, id);
04011       }
04012     }
04013   }
04014   bdd_free(bddOne);
04015   head->bRefineVarArray = 0;
04016 }
04017 
04029 static void
04030 ImgLinearUpdateVariableArrayWithId(Relation_t *head, 
04031                                    int cindex, 
04032                                    int id)
04033 {
04034 VarLife_t *var;
04035 int *varType;
04036 int *varArrayMap;
04037 int nVarArray;
04038 VarLife_t **varArray;
04039 
04040   varType = head->varType;
04041   varArrayMap = head->varArrayMap;
04042   varArray = head->varArray;
04043   nVarArray = head->nVarArray;
04044 
04045   if(varArrayMap[id] == -1) {
04046     var = ALLOC(VarLife_t, 1);
04047     var->id = id;
04048     var->from = cindex;
04049     var->to = cindex;
04050     var->effFrom = cindex;
04051     var->effTo = cindex;
04052     var->stateVar = 0;
04053     var->relArr = ALLOC(int, 1);
04054     var->nSize = 0;
04055     var->index = 0.0;
04056     varArrayMap[id] = nVarArray;
04057     varArray[nVarArray++] = var;
04058     varArray = REALLOC(VarLife_t *, varArray, nVarArray+1);
04059 
04060     if(varType[id] == 1) {
04061       var->stateVar = 1;
04062       if(head->includeCS && !head->quantifyCS) { 
04063         var->relArr = REALLOC(int, var->relArr, var->nSize+1);
04064         var->relArr[var->nSize++] = MAXINT-1;
04065         var->from = -1;
04066       }
04067     }
04068     else if(varType[id] == 2) {
04069       var->stateVar = 2;
04070       if(head->includeNS) { 
04071         var->relArr = REALLOC(int, var->relArr, var->nSize+1);
04072         var->relArr[var->nSize++] = MAXINT;
04073         var->to = head->nSize;
04074       }
04075     }
04076   }
04077   else {
04078     var = varArray[varArrayMap[id]];
04079   }
04080   
04081   if(var->to < cindex)          var->to = cindex;
04082   if(var->from > cindex)        var->from = cindex;
04083 
04084   if(var->effTo < cindex)       var->effTo = cindex;
04085   if(var->effFrom > cindex)     var->effFrom = cindex;
04086 
04087   var->relArr = REALLOC(int, var->relArr, var->nSize+1);
04088   var->relArr[var->nSize++] = cindex;
04089   head->varArray = varArray;
04090   head->nVarArray = nVarArray;
04091 }
04103 static int
04104 ImgLinearQuantifyVariablesFromConjunct(Relation_t *head,
04105                                        Conjunct_t *conjunct, 
04106                                        array_t *smoothVarBddArray,
04107                                        int *bModified)
04108 {
04109 bdd_t *relation, *simpleRelation;
04110 
04111   if(conjunct == 0)     return 1;
04112   relation = conjunct->relation;
04113   if(relation == 0)     return 1;
04114 
04115   simpleRelation = bdd_smooth(relation, smoothVarBddArray);
04116   if(bdd_equal(relation, simpleRelation)) {
04117     bdd_free(simpleRelation);
04118     return 0;
04119   }
04120   bdd_free(relation);
04121 
04122   (*bModified)++;
04123   conjunct->relation = simpleRelation;
04124   conjunct->bModified = 1;
04125   head->bModified = 1;
04126   head->bRefineVarArray = 1;
04127   ImgLinearConjunctRefine(head, conjunct);
04128   return 1;
04129 }
04130 
04142 static void
04143 ImgLinearConjunctRefine(Relation_t *head, Conjunct_t *conjunct)
04144 {
04145 int i, id, listSize, *supList;
04146 int *varType;
04147 
04148   if(conjunct->relation == 0)   {
04149     if(conjunct->supList)       free(conjunct->supList);
04150     conjunct->supList = 0;
04151     return;
04152   }
04153   if(!conjunct->bModified)      return; 
04154 
04155   if(conjunct->supList) {
04156     free(conjunct->supList);
04157     conjunct->supList = 0;
04158   }
04159 
04160   supList = ImgLinearGetSupportBddId(head->mgr, conjunct->relation, &listSize);
04161   if(listSize == 0) {
04162     conjunct->relation = 0;
04163     if(conjunct->supList) {
04164       free(conjunct->supList);
04165       conjunct->supList = 0;
04166     }
04167     return;
04168   }
04169   else {
04170     varType = head->varType;
04171     conjunct->supList = supList;
04172     conjunct->nSize = listSize;
04173     conjunct->bModified = 0;
04174     conjunct->nDomain = 0;
04175     conjunct->nRange = 0;
04176     conjunct->nQuantify = 0;
04177     conjunct->from = 0;
04178     conjunct->to = 0;
04179     conjunct->dummy = 0;
04180     for(i=0; i<listSize; i++) {
04181       id = supList[i];
04182       if(varType[id] == 1)      conjunct->nDomain++;
04183       else if(varType[id] == 2) conjunct->nRange++;
04184       else if(varType[id] == 3) conjunct->nQuantify++;
04185     }
04186     head->bModified = 1;
04187   }
04188   return;
04189 }
04201 static void
04202 ImgLinearConjunctArrayRefine(Relation_t *head)
04203 {
04204 int nSize, i;
04205 int index;
04206 Conjunct_t **conjunctArray, **newConjunctArray;
04207 Conjunct_t *conjunct;
04208 
04209   if(head->bModified == 0)      return;
04210 
04211   conjunctArray = head->conjunctArray;
04212   newConjunctArray = ALLOC(Conjunct_t *, head->nSize+1);
04213   nSize = head->nSize;
04214   for(index=0, i=0; i<nSize; i++) {
04215     conjunct = conjunctArray[i];
04216     if(conjunct == 0)   {
04217       head->bRefineVarArray = 1;
04218       continue;
04219     }
04220     if(conjunct->relation == 0) {
04221       ImgLinearConjunctQuit(conjunct);
04222       head->bRefineVarArray = 1;
04223       continue;
04224     }
04225 
04226     if(conjunct->bModified) {
04227       ImgLinearConjunctRefine(head, conjunct);
04228       head->bRefineVarArray = 1;
04229     }
04230 
04231     if(conjunct == 0)   continue;
04232     if(conjunct->relation == 0) {
04233       ImgLinearConjunctQuit(conjunct);
04234       continue;
04235     }
04236 
04237     newConjunctArray[index] = conjunct;
04238     conjunct->index = index++;
04239   }
04240   newConjunctArray[index] = 0;
04241   free(conjunctArray);
04242   head->conjunctArray = newConjunctArray;
04243   head->nSize = index;
04244   head->bModified = 0;
04245   return; 
04246 }
04247 
04259 static void
04260 ImgLinearSetEffectiveNumberOfStateVariable(Relation_t *head, 
04261                                             int *rangeId, 
04262                                             int *domainId,
04263                                             int *existStateVariable) 
04264 {
04265 VarLife_t **varArray, *var;
04266 int *varType;
04267 int nRange, nDomain, nQuantify;
04268 int i;
04269 
04270   varArray = head->varArray;
04271   varType = head->varType;
04272   nRange = nDomain = nQuantify = 0;
04273 
04274   for(i=0; i<head->nVarArray; i++) {
04275     var = varArray[i];
04276     if(varType[var->id] == 1)   {
04277       if(domainId) domainId[nDomain] = var->id;
04278       nDomain++;
04279       if(existStateVariable) existStateVariable[var->id] = 1;
04280     }
04281     else if(varType[var->id] == 2)      {
04282       if(rangeId) rangeId[nRange] = var->id;
04283       nRange++;
04284       if(existStateVariable) existStateVariable[var->id] = 1;
04285     }
04286     else if(varType[var->id] == 3)      {
04287       nQuantify++;
04288     }
04289     else
04290       nQuantify++;
04291 
04292   } 
04293   if(domainId)  domainId[nDomain] = -1;
04294   if(rangeId)   rangeId[nRange] = -1;
04295 
04296   head->nEffRange = nRange;
04297   head->nEffDomain = nDomain;
04298   head->nEffQuantify = nQuantify;
04299 
04300   if(head->nInitRange == 0 && head->nInitDomain == 0 && head->nInitQuantify == 0) {
04301     head->nInitRange = nRange;
04302     head->nInitDomain = nDomain;
04303     head->nInitQuantify = nQuantify;
04304   }
04305 }
04306 
04318 static void
04319 ImgLinearAddSingletonCase(Relation_t *head)
04320 {
04321 Conjunct_t **newConjunctArray;
04322 Conjunct_t **singletonArray;
04323 Conjunct_t *conjunct;
04324 int i, j, index;
04325 int nSingletonArray;
04326 int putFlag;
04327 
04328   nSingletonArray = head->nSingletonArray;
04329   singletonArray = head->singletonArray;
04330 
04331   if(nSingletonArray == 0)      return;
04332   fprintf(stdout, "NOTICE : %d singleton case will be added\n", nSingletonArray);
04333 
04334   qsort(singletonArray, nSingletonArray, sizeof(Conjunct_t *), ImgLinearCompareConjunctRangeMinusDomain);
04335 
04336   index = 0;
04337   newConjunctArray = ALLOC(Conjunct_t *, head->nSize + nSingletonArray);
04338   putFlag = 0;
04339   for(i=0; i<nSingletonArray; i++) {
04340     conjunct = singletonArray[i];
04341     if(putFlag == 0 && conjunct->nRange > conjunct->nSize-conjunct->nRange) {
04342       putFlag = 1;
04343       for(j=0; j<head->nSize; j++) 
04344         newConjunctArray[index++] = head->conjunctArray[j];
04345     }
04346     newConjunctArray[index++] = singletonArray[i];
04347   }
04348   if(putFlag == 0) {
04349     for(j=0; j<head->nSize; j++) 
04350       newConjunctArray[index++] = head->conjunctArray[j];
04351   }
04352 
04353   head->nSize = index;
04354   head->bModified = 1;
04355   head->bRefineVarArray = 1;
04356   free(head->conjunctArray);
04357   head->conjunctArray = newConjunctArray;
04358   free(singletonArray);
04359   head->singletonArray = 0;
04360   head->nSingletonArray = 0;
04361 }
04362 
04363 
04375 static void
04376 ImgLinearExpandSameSupportSet(Relation_t *head)
04377 {
04378 int index, i, j;
04379 Conjunct_t **newConjunctArray;
04380 Conjunct_t *conjunct;
04381 
04382   newConjunctArray = ALLOC(Conjunct_t *, head->nSize);
04383   for(index=0, i=0; i<head->nSize; i++) {
04384     if(index >= head->nSize)
04385       newConjunctArray = REALLOC(Conjunct_t *, newConjunctArray, index+1);
04386     conjunct = head->conjunctArray[i];
04387     newConjunctArray[index++] = conjunct;
04388     if(conjunct->nCluster) {
04389       for(j=0; j<conjunct->nCluster; j++) {
04390         if(index >= head->nSize)
04391           newConjunctArray = REALLOC(Conjunct_t *, newConjunctArray, index+1);
04392         newConjunctArray[index++] = conjunct->clusterArray[j];
04393       }
04394       head->bModified = 1;
04395       head->bRefineVarArray = 1;
04396       conjunct->nCluster = 0;
04397       if(conjunct->clusterArray) {
04398         free(conjunct->clusterArray);
04399         conjunct->clusterArray = 0;
04400       }
04401     }
04402   }
04403   free(head->conjunctArray);
04404   head->conjunctArray = newConjunctArray;
04405   head->nSize = index;
04406 }
04407 
04408 
04420 static void
04421 ImgLinearClusterSameSupportSet(Relation_t *head) 
04422 {
04423 int i, j, index, id;
04424 int *supList;
04425 Conjunct_t *conjunct, *base;
04426 int *varType;
04427 Conjunct_t **conjunctArray, **newConjunctArray;
04428 
04429   head->nTotalCluster = 0;
04430   varType = head->varType;
04431   conjunctArray = head->conjunctArray; 
04432 
04433   for(i=0; i<head->nSize; i++) {
04434     conjunct = head->conjunctArray[i];
04435     supList = conjunct->supList;
04436     conjunct->dummy = 0;
04437     for(j=0; j<conjunct->nSize; j++) {
04438       id = supList[j];
04439       if(varType[id] == 2)      continue;
04440       conjunct->dummy += id;
04441     }
04442     conjunct->dummy *= (conjunct->nSize-conjunct->nRange);
04443     conjunct->dummy -= conjunct->nDomain;
04444   }
04445   qsort(conjunctArray, head->nSize, sizeof(Conjunct_t *), 
04446                         ImgLinearCompareConjunctDummy);
04447 
04448   for(i=0; i<head->nSize; i++) {
04449     base = head->conjunctArray[i];
04450     for(j=i+1; j<head->nSize; j++) {
04451       conjunct = head->conjunctArray[j];
04452       if(base->dummy != conjunct->dummy) {
04453         if(j == i+1)    break;
04454         ImgLinearFindSameSupportConjuncts(head, i, j-1);
04455         i = j-1;
04456         break;
04457       }
04458     }
04459   }
04460 
04461   if(head->bModified)   {
04462     conjunctArray = head->conjunctArray;
04463     newConjunctArray = ALLOC(Conjunct_t *, head->nSize);
04464     for(index=0, i=0; i<head->nSize; i++) {
04465       conjunct = conjunctArray[i];
04466       if(conjunct == 0) continue;
04467       newConjunctArray[index++] = conjunct;
04468     }
04469     free(conjunctArray);
04470     head->conjunctArray = newConjunctArray;
04471     head->nSize = index;
04472     head->bModified = 1;
04473     head->bRefineVarArray = 1;
04474   }
04475 
04476   conjunctArray = head->conjunctArray;
04477   qsort(conjunctArray, head->nSize, sizeof(Conjunct_t *), ImgLinearCompareConjunctIndex);
04478   if(head->bModified)   {
04479     conjunctArray = head->conjunctArray;
04480     for(i=0; i<head->nSize; i++) {
04481       conjunct = conjunctArray[i];
04482       if(conjunct == 0) continue;
04483       conjunct->index = i;
04484     }
04485   }
04486   fprintf(stdout, "NOTICE : %d conjunct clustered\n", head->nTotalCluster);
04487   head->nTotalCluster = 0;
04488 
04489 }
04501 static void
04502 ImgLinearFindSameSupportConjuncts(Relation_t *head, int from, int to)
04503 {
04504 Conjunct_t *con1, *con2;
04505 int i, j;
04506 
04507   for(i=from; i<=to; i++) {
04508     con1 = head->conjunctArray[i];
04509     if(con1 == 0)       continue;
04510 
04511     for(j=from; j<=to; j++) {
04512       if(i == j)        continue;
04513       con2 = head->conjunctArray[j];
04514       if(con2 == 0)     continue;
04515       if(ImgLinearIsSameConjunct(head, con1, con2)) {
04516         ImgLinearAddConjunctIntoClusterArray(con1, con2);
04517         head->conjunctArray[j] = 0;
04518 
04519         head->bModified = 1;
04520         head->bRefineVarArray = 1;
04521         head->nTotalCluster++;
04522       }
04523     }
04524   }
04525 }
04526 
04538 static int
04539 ImgLinearIsSameConjunct(Relation_t *head, Conjunct_t *con1, Conjunct_t *con2)
04540 {
04541 int i, j;
04542 int *sup1, *sup2;
04543 int id1, id2;
04544 int *varType;
04545 
04546   if(con1->nDomain != con2->nDomain)    return(0);
04547   if(con1->nSize-con1->nRange != con2->nSize-con2->nRange)      return(0);
04548   sup1 = con1->supList;
04549   sup2 = con2->supList;
04550 
04551   varType = head->varType;
04552 
04553   for(j=0, i=0; i<con1->nSize; i++) {
04554     id1 = sup1[i];
04555     if(varType[id1] == 2)continue;
04556     while(1) {
04557       id2 = sup2[j];
04558       if(varType[id2] == 2) {
04559         j++;
04560         continue;
04561       }
04562       if(id1 != id2)    return(0);
04563       j++;
04564       break;
04565     }
04566   }
04567   return(1);
04568 }
04569 
04581 static Conjunct_t **
04582 ImgLinearAddConjunctIntoArray(Conjunct_t **array, int *nArray, Conjunct_t *con)
04583 {
04584   if(array)
04585     array = REALLOC(Conjunct_t *, array, (*nArray)+1);
04586   else 
04587     array = ALLOC(Conjunct_t *, (*nArray)+1);
04588   array[(*nArray)++] = con;
04589   return(array);
04590 
04591 }
04592 
04604 static void
04605 ImgLinearConjunctQuit(Conjunct_t *conjunct)
04606 {
04607   if(conjunct->supList) {
04608     free(conjunct->supList);
04609     conjunct->supList = 0;
04610   }
04611   if(conjunct->relation) {
04612     bdd_free(conjunct->relation);
04613     conjunct->relation = 0;
04614   }
04615   free(conjunct);
04616 }
04617 
04618 
04630 static void
04631 ImgLinearVariableArrayQuit(Relation_t *head)
04632 {
04633 int i;
04634 VarLife_t **varArray;
04635 
04636 
04637   varArray = head->varArray;
04638   for(i=0; i<head->nVarArray; i++)
04639     ImgLinearVariableLifeQuit(varArray[i]);
04640 
04641   free(varArray);
04642   head->varArray = 0;
04643   head->nVarArray = 0;
04644   memset(head->varArrayMap, -1, sizeof(int)*head->nVar);
04645 }
04646 
04647 
04659 static void
04660 ImgLinearVariableLifeQuit(VarLife_t *var) 
04661 {
04662    if(var->relArr)      free(var->relArr);
04663    free(var);
04664 }
04665 
04677 int
04678 ImgLinearClustering(Relation_t *head, Img_OptimizeType optDir)
04679 {
04680 int andExistLimit;
04681 int useFailureHistory;
04682 int includeZeroGain;
04683 double affinityLimit;
04684 int bOptimize;
04685 int varLimit;
04686 
04687   bOptimize = 0;
04688 
04689   affinityLimit = 0.99;
04690   andExistLimit = 10;
04691   varLimit = 200;
04692   fprintf(stdout, "Heap DAL affinity %3f, andExist %d\n", 
04693           affinityLimit, andExistLimit);
04694   bOptimize |= ImgLinearClusterUsingHeap(head, affinityLimit, andExistLimit,
04695                                 varLimit, optDir, 0,
04696                                 ImgLinearHeapCompareDeadAffinityLive);
04697   ImgLinearRefineRelation(head);
04698   if(head->verbosity >= 5)
04699     ImgLinearPrintMatrix(head);
04700   ImgLinearSetEffectiveNumberOfStateVariable(head, 0, 0, 0);
04701   ImgLinearPrintTransitionInfo(head);
04702 
04703   includeZeroGain = 0;
04704   affinityLimit = 0.3;
04705   andExistLimit = 5000;
04706   varLimit = 50;
04707   useFailureHistory = 0;
04708   if(head->computeRange) {
04709     varLimit = 50;
04710     affinityLimit = 0.8;
04711     andExistLimit = 5000;
04712     fprintf(stdout, "Heap DAL affinity %3f, andExist %d\n", 
04713             affinityLimit, andExistLimit);
04714     bOptimize |= ImgLinearClusterUsingHeap(head, affinityLimit, andExistLimit,
04715                                   varLimit, optDir, 0,
04716                                 ImgLinearHeapCompareDeadAffinityLive);
04717 
04718     ImgLinearRefineRelation(head);
04719     ImgLinearExtractNextStateCase(head);
04720     ImgLinearExtractSingletonCase(head);
04721     ImgLinearRefineRelation(head);
04722     ImgLinearAddSingletonCase(head);
04723     ImgLinearRefineRelation(head);
04724     ImgLinearAddNextStateCase(head);
04725     ImgLinearRefineRelation(head);
04726   }
04727   else 
04728   {
04729     fprintf(stdout, "Gain DAL affinity %3f, andExist %d\n", 
04730           affinityLimit, andExistLimit);
04731     bOptimize |= ImgLinearClusteringIteratively(head, affinityLimit,
04732                                 andExistLimit, varLimit, 
04733                                 includeZeroGain, useFailureHistory, optDir,
04734                                 ImgLinearCompareDeadAffinityLive);
04735     ImgLinearRefineRelation(head);
04736     ImgLinearExtractNextStateCase(head);
04737     ImgLinearExtractSingletonCase(head);
04738     ImgLinearRefineRelation(head);
04739     ImgLinearAddSingletonCase(head);
04740     ImgLinearRefineRelation(head);
04741     ImgLinearAddNextStateCase(head);
04742     ImgLinearRefineRelation(head);
04743   }
04744 
04745   includeZeroGain = 1;
04746   varLimit = 200;
04747   affinityLimit = 0.7;
04748   andExistLimit = 5000;
04749   fprintf(stdout, "Heap DAL affinity %3f, andExist %d\n", 
04750           affinityLimit, andExistLimit);
04751   bOptimize |= ImgLinearClusterUsingHeap(head, affinityLimit, andExistLimit,
04752                                 varLimit, optDir, 0,
04753                                 ImgLinearHeapCompareDeadAffinityLive);
04754 
04755   ImgLinearRefineRelation(head);
04756   ImgLinearExtractNextStateCase(head);
04757   ImgLinearExtractSingletonCase(head);
04758   ImgLinearRefineRelation(head);
04759   ImgLinearAddSingletonCase(head);
04760   ImgLinearRefineRelation(head);
04761   ImgLinearAddNextStateCase(head);
04762   ImgLinearRefineRelation(head);
04763 
04764   if(head->verbosity >= 5)
04765     ImgLinearPrintMatrix(head);
04766   ImgLinearSetEffectiveNumberOfStateVariable(head, 0, 0, 0);
04767   ImgLinearPrintTransitionInfo(head);
04768 
04769   includeZeroGain = 1;
04770   affinityLimit = 0.4;
04771   andExistLimit = 5000;
04772   fprintf(stdout, "Heap DAL affinity %3f, andExist %d\n", 
04773           affinityLimit, andExistLimit);
04774   bOptimize |= ImgLinearClusterUsingHeap(head, affinityLimit, andExistLimit,
04775                                 varLimit, optDir, 0,
04776                                 ImgLinearHeapCompareDeadAffinityLive);
04777   ImgLinearRefineRelation(head);
04778   ImgLinearExtractNextStateCase(head);
04779   ImgLinearExtractSingletonCase(head);
04780   ImgLinearRefineRelation(head);
04781   ImgLinearAddSingletonCase(head);
04782   ImgLinearRefineRelation(head);
04783   ImgLinearAddNextStateCase(head);
04784   ImgLinearRefineRelation(head);
04785 
04786   if(head->verbosity >= 5)
04787     ImgLinearPrintMatrix(head);
04788   ImgLinearSetEffectiveNumberOfStateVariable(head, 0, 0, 0);
04789   ImgLinearPrintTransitionInfo(head);
04790 
04791   affinityLimit = 0.0;
04792   andExistLimit = 5000;
04793   fprintf(stdout, "Heap DLA affinity %3f, andExist %d\n", 
04794           affinityLimit, andExistLimit);
04795   bOptimize |= ImgLinearClusterUsingHeap(head, affinityLimit, andExistLimit,
04796                                 varLimit, optDir, 0,
04797                                 ImgLinearHeapCompareDeadLiveAffinity);
04798   ImgLinearRefineRelation(head);
04799   ImgLinearExtractNextStateCase(head);
04800   ImgLinearRefineRelation(head);
04801   ImgLinearAddNextStateCase(head);
04802   ImgLinearRefineRelation(head);
04803   if(head->verbosity >= 5)
04804     ImgLinearPrintMatrix(head);
04805   ImgLinearSetEffectiveNumberOfStateVariable(head, 0, 0, 0);
04806   ImgLinearPrintTransitionInfo(head);
04807 
04808   if(head->computeRange) {
04809     includeZeroGain = 0;
04810     affinityLimit = 0.0;
04811     andExistLimit = andExistLimit;
04812     varLimit = MAXINT;
04813     head->bddLimit = head->bddLimit * 2;
04814     fprintf(stdout, "Heap DLA affinity %3f, andExist %d\n", 
04815           affinityLimit, andExistLimit);
04816     while(1) {
04817       bOptimize |= ImgLinearClusterUsingHeap(head, affinityLimit, andExistLimit,
04818                                 varLimit, optDir, 1,
04819                                 ImgLinearHeapCompareDeadLiveAffinity);
04820       ImgLinearRefineRelation(head);
04821 
04822       if(ImgCheckRangeTestAndOverapproximate(head))     break;
04823     }
04824 
04825     ImgCountOnsetDisjunctiveArray(head);
04826     ImgLinearSetEffectiveNumberOfStateVariable(head, 0, 0, 0);
04827     ImgLinearPrintTransitionInfo(head);
04828 
04829   }
04830 
04831   return(bOptimize);
04832 }
04833 
04845 static void 
04846 ImgCountOnsetDisjunctiveArray(Relation_t *head)
04847 {
04848 EpDouble tepd;
04849 char strValue[1024];
04850 bdd_t *varBdd;
04851 mdd_manager *mgr;
04852 array_t *bddVarArray;
04853 Conjunct_t *conjunct;
04854 int count, i, j, id;
04855 double onSet;
04856 
04857   mgr = head->mgr;
04858   count = 0;
04859   EpdConvert((double)1.0, &tepd);
04860   for(i=0; i<head->nSize; i++) {
04861     conjunct = head->conjunctArray[i];
04862     bddVarArray = array_alloc(bdd_t *, 0);
04863     for(j=0; j<conjunct->nSize; j++) {
04864       id = conjunct->supList[j];
04865       varBdd = bdd_get_variable(mgr, id);
04866       array_insert_last(bdd_t *, bddVarArray, varBdd);
04867     }
04872     onSet = bdd_count_onset(conjunct->relation, bddVarArray);
04873     EpdMultiply(&tepd, onSet);
04874     count += conjunct->nSize;
04875     mdd_array_free(bddVarArray);
04876   }
04877 
04878   if(count < head->nRange) {
04879     EpdMultiply(&tepd, pow(2, (double)(head->nRange-count)));
04880   }
04881   EpdGetString(&tepd, strValue);
04882   (void) fprintf(vis_stdout, "%-20s%10s\n", "range =", strValue);
04883 
04884 }
04885 
04897 static int
04898 ImgCheckRangeTestAndOverapproximate(Relation_t *head)
04899 {
04900 Conjunct_t *conjunct;
04901 VarLife_t **varArray, *var;
04902 int nVarArray, i, k, count;
04903 int index;
04904 int *varType;
04905 int allRangeFlag;
04906 bdd_t *relation, *simpleRelation, *varBdd;
04907 
04908 
04909   allRangeFlag = 1;
04910   for(i=0; i<head->nSize; i++) {
04911     conjunct = head->conjunctArray[i];
04912     if(conjunct->nRange != conjunct->nSize) {
04913       allRangeFlag = 0;
04914       break;
04915     }
04916   }
04917 
04918   if(allRangeFlag == 1) return(1);
04919 
04920   varArray = head->varArray;
04921   varType = head->varType;
04922   nVarArray = head->nVarArray;
04937   count = head->nEffDomain + head->nEffQuantify;
04938   if(count == 0)        return(1);
04939 
04940   varArray = ALLOC(VarLife_t *, head->nVarArray);
04941   memcpy(varArray, head->varArray, sizeof(VarLife_t *)*head->nVarArray);
04942   qsort(varArray, head->nVarArray, sizeof(VarLife_t *), ImgLinearCompareVarSize);
04943 
04944   if(count != 0) {
04945     count = (count / 10);
04946     if(count == 0) count = 1;
04947   }
04948   k=0;
04949   index = 0;
04950   while(1) {
04951     if(index >= count)  break;
04952     var = varArray[k++];
04953     if(var->stateVar == 2)      continue;
04954     index++;
04955     varBdd = bdd_get_variable(head->mgr, var->id);
04956     for(i=0; i<var->nSize; i++) {
04957       conjunct = head->conjunctArray[var->relArr[i]];
04958       relation = conjunct->relation;
04959       simpleRelation = bdd_smooth_with_cube(relation, varBdd);
04960       if(bdd_equal(relation, simpleRelation)) {
04961         bdd_free(simpleRelation);
04962         continue;
04963       }
04964       bdd_free(relation);
04965   
04966       conjunct->relation = simpleRelation;
04967       conjunct->bModified = 1;
04968       head->bModified = 1;
04969       head->bRefineVarArray = 1;
04970       ImgLinearConjunctRefine(head, conjunct);
04971     }
04972   }
04973   free(varArray);
04974 
04975   ImgLinearRefineRelation(head);
04976   ImgLinearConjunctOrderMainCC(head, 0);
04977   ImgLinearRefineRelation(head);
04978 
04979   ImgLinearSetEffectiveNumberOfStateVariable(head, 0, 0, 0);
04980   ImgLinearPrintTransitionInfo(head);
04981   
04982   return(0);
04983 }
04984 
04996 static void
04997 ImgLinearAddNextStateCase(Relation_t *head)
04998 {
04999 Conjunct_t **newConjunctArray;
05000 int i, j, index;
05001 
05002   index = 0;
05003   if(head->nNextStateArray) {
05004     newConjunctArray = ALLOC(Conjunct_t *, head->nSize + head->nNextStateArray);
05005    for(j=0; j<head->nSize; j++) 
05006       newConjunctArray[index++] = head->conjunctArray[j];
05007 
05008     for(i=0; i<head->nNextStateArray; i++) 
05009       newConjunctArray[index++] = head->nextStateArray[i];
05010 
05011     head->nSize = index;
05012     head->bModified = 1;
05013     head->bRefineVarArray = 1;
05014     free(head->conjunctArray);
05015     head->conjunctArray = newConjunctArray;
05016 
05017     if(head->nextStateArray)    free(head->nextStateArray);
05018     head->nextStateArray = 0;
05019   }
05020 }
05021