VIS
|
00001 00025 #include "restrInt.h" 00026 00027 /*---------------------------------------------------------------------------*/ 00028 /* Constant declarations */ 00029 /*---------------------------------------------------------------------------*/ 00030 00031 00032 /*---------------------------------------------------------------------------*/ 00033 /* Type declarations */ 00034 /*---------------------------------------------------------------------------*/ 00035 00036 00037 /*---------------------------------------------------------------------------*/ 00038 /* Structure declarations */ 00039 /*---------------------------------------------------------------------------*/ 00040 00041 /*---------------------------------------------------------------------------*/ 00042 /* Variable declarations */ 00043 /*---------------------------------------------------------------------------*/ 00044 00045 00046 /*---------------------------------------------------------------------------*/ 00047 /* Macro declarations */ 00048 /*---------------------------------------------------------------------------*/ 00049 00050 00053 /*---------------------------------------------------------------------------*/ 00054 /* Static function prototypes */ 00055 /*---------------------------------------------------------------------------*/ 00056 00057 static bdd_node * restrHxygthxz(bdd_manager *dd, int N, bdd_node **x, bdd_node **y, bdd_node **z); 00058 00062 /*---------------------------------------------------------------------------*/ 00063 /* Definition of exported functions */ 00064 /*---------------------------------------------------------------------------*/ 00065 00066 /*---------------------------------------------------------------------------*/ 00067 /* Definition of internal functions */ 00068 /*---------------------------------------------------------------------------*/ 00069 00104 bdd_node * 00105 RestrSelectLeastHammingDStates( 00106 bdd_manager *dd, 00107 bdd_node *oldTR, 00108 bdd_node *pTR, 00109 bdd_node **xVars, 00110 bdd_node **yVars, 00111 bdd_node **vVars, 00112 int nVars, 00113 int nPi) 00114 { 00115 bdd_node *result; 00116 bdd_node *temp1,*Pi; 00117 double oldSize,newSize; 00118 int twice = 0; 00119 00120 /* restrHxygthxz is a function that returns 1 if HD(x,y) > HD(x,z) */ 00121 bdd_ref(Pi = restrHxygthxz(dd,nVars,xVars,yVars,vVars)); 00122 result = bdd_priority_select(dd,pTR,xVars,yVars,vVars, 00123 Pi,nVars,NULL); 00124 bdd_recursive_deref(dd,Pi); 00125 if(! result) { 00126 return NIL(bdd_node); 00127 } 00128 bdd_ref(result); 00129 00130 oldSize = bdd_count_minterm(dd,oldTR,2*nVars+nPi); 00131 newSize = bdd_count_minterm(dd,result,2*nVars+nPi); 00132 00133 /* As restrHxygthxz is not a priority function, result might still be 00134 non-deterministic. Hence use the tie breaker bdd_dxygtdxz to make the 00135 "result" deterministic */ 00136 00137 if(newSize > oldSize) { 00138 temp1 = bdd_priority_select(dd,result,xVars,yVars,vVars, 00139 NIL(bdd_node),nVars,bdd_dxygtdxz); 00140 if(! temp1) { 00141 return NIL(bdd_node); 00142 } 00143 bdd_ref(temp1); 00144 bdd_recursive_deref(dd,result); 00145 result = temp1; 00146 twice = 1; 00147 } 00148 if (twice) { 00149 newSize = bdd_count_minterm(dd,result,2*nVars+nPi); 00150 assert(oldSize == newSize); 00151 } 00152 00153 if(result == oldTR) { 00154 fprintf(vis_stdout,"** restr info: HammingD heuristic produces no restructuring.\n"); 00155 } 00156 00157 return result; 00158 00159 #if 0 00160 /* Compute a priority function that looks like: 00161 * \Pi_H(x,y,z) = H(x,y,z) \vee (\neg H(x,z,y) \wedge \Pi_{RP}(x,y,z)) 00162 * 00163 * where H(x,y,z) = 1 if HD(x,y) < HD(x,z) and 0 otherwise; 00164 * Here z variables are vVars. 00165 */ 00166 00167 /* Observe that below I am computing H(x,z,y) */ 00168 bdd_ref(Hxyz = restrHxygthxz(dd,nVars,xVars,vVars,yVars)); 00169 bdd_ref(Hxzy = bdd_bdd_swap_variables(dd,Hxyz,yVars,vVars,nVars)); 00170 bdd_ref(piRP = bdd_dxygtdxz(dd,nVars,xVars,yVars,vVars)); 00171 00172 bdd_ref(Pi = bdd_bdd_ite(dd,Hxyz,bdd_not_bdd_node(Hxzy),piRP)); 00173 bdd_recursive_deref(dd,Hxzy); 00174 bdd_recursive_deref(dd,piRP); 00175 bdd_recursive_deref(dd,Hxyz); 00176 00177 /* Compute \Pi_H(x,z,y) and use priority select formulation */ 00178 bdd_ref(temp = bdd_bdd_swap_variables(dd,Pi,yVars,vVars,nVars)); 00179 bdd_recursive_deref(dd,Pi); 00180 Pi = temp; 00181 result = bdd_priority_select(dd,pTR,xVars,yVars,vVars, 00182 Pi,nVars,NULL); 00183 if(! result) { 00184 return NIL(bdd_node); 00185 } 00186 bdd_ref(result); 00187 #endif 00188 } 00189 00190 /*---------------------------------------------------------------------------*/ 00191 /* Definition of static functions */ 00192 /*---------------------------------------------------------------------------*/ 00193 00210 static bdd_node * 00211 restrHxygthxz( 00212 bdd_manager *dd, 00213 int N, 00214 bdd_node **x, 00215 bdd_node **y, 00216 bdd_node **z) 00217 { 00218 bdd_node **dEqualToINodes, **tempDEqualToINodes; 00219 bdd_node *z1, *z2, *z3, *z4, *y1, *y2; 00220 bdd_node *one, *zero; 00221 bdd_node *temp; 00222 bdd_node *result; 00223 int i, j, m; 00224 int fromIndex, toIndex; 00225 00226 dEqualToINodes = ALLOC(bdd_node *, 2*N+1); 00227 tempDEqualToINodes = ALLOC(bdd_node *, 2*N+1); 00228 00229 one = bdd_read_one(dd); 00230 zero = bdd_not_bdd_node(one); 00231 00232 for(i = 0; i <= N; i++) { 00233 dEqualToINodes[i] = zero; 00234 bdd_ref(dEqualToINodes[i]); 00235 tempDEqualToINodes[i] = zero; 00236 bdd_ref(tempDEqualToINodes[i]); 00237 } 00238 for(i = N+1; i < 2*N+1; i++) { 00239 dEqualToINodes[i] = one; 00240 bdd_ref(dEqualToINodes[i]); 00241 tempDEqualToINodes[i] = one; 00242 bdd_ref(tempDEqualToINodes[i]); 00243 } 00244 00245 /* Loop to build the rest of the BDD */ 00246 for(i = N-1; i >= 0; i--) { 00247 fromIndex = N - restrMin(N-i-1,i); 00248 toIndex = restrMin(N-i,i) + N; 00249 00250 for(j = fromIndex;j <= toIndex; j++) { 00251 z1 = bdd_bdd_ite(dd,z[i],tempDEqualToINodes[j], 00252 tempDEqualToINodes[j-1]); 00253 if(! z1){ 00254 goto endgame; 00255 } 00256 bdd_ref(z1); 00257 00258 z2 = bdd_bdd_ite(dd,z[i],tempDEqualToINodes[j+1], 00259 tempDEqualToINodes[j]); 00260 if(! z2){ 00261 bdd_recursive_deref(dd,z1); 00262 goto endgame; 00263 } 00264 bdd_ref(z2); 00265 00266 z3 = bdd_bdd_ite(dd,z[i],tempDEqualToINodes[j], 00267 tempDEqualToINodes[j+1]); 00268 if(! z3){ 00269 bdd_recursive_deref(dd,z1); 00270 bdd_recursive_deref(dd,z2); 00271 goto endgame; 00272 } 00273 bdd_ref(z3); 00274 00275 z4 = bdd_bdd_ite(dd,z[i],tempDEqualToINodes[j-1], 00276 tempDEqualToINodes[j]); 00277 if(! z4){ 00278 bdd_recursive_deref(dd,z1); 00279 bdd_recursive_deref(dd,z2); 00280 bdd_recursive_deref(dd,z3); 00281 goto endgame; 00282 } 00283 bdd_ref(z4); 00284 00285 y1 = bdd_bdd_ite(dd,y[i],z1,z2); 00286 if(! y1){ 00287 bdd_recursive_deref(dd,z1); 00288 bdd_recursive_deref(dd,z2); 00289 bdd_recursive_deref(dd,z3); 00290 bdd_recursive_deref(dd,z4); 00291 goto endgame; 00292 } 00293 bdd_ref(y1); 00294 00295 y2 = bdd_bdd_ite(dd,y[i],z3,z4); 00296 if(! y2){ 00297 bdd_recursive_deref(dd,z1); 00298 bdd_recursive_deref(dd,z2); 00299 bdd_recursive_deref(dd,z3); 00300 bdd_recursive_deref(dd,z4); 00301 bdd_recursive_deref(dd,y1); 00302 goto endgame; 00303 } 00304 bdd_ref(y2); 00305 00306 bdd_recursive_deref(dd,z1); 00307 bdd_recursive_deref(dd,z2); 00308 bdd_recursive_deref(dd,z3); 00309 bdd_recursive_deref(dd,z4); 00310 00311 temp = bdd_bdd_ite(dd,x[i],y1,y2); 00312 if(! temp){ 00313 bdd_recursive_deref(dd,y1); 00314 bdd_recursive_deref(dd,y2); 00315 goto endgame; 00316 } 00317 bdd_ref(temp); 00318 dEqualToINodes[j] = temp; 00319 bdd_recursive_deref(dd,y1); 00320 bdd_recursive_deref(dd,y2); 00321 } 00322 00323 for(j = 0; j < 2*N+1; j++) { 00324 if(tempDEqualToINodes[j]) { 00325 bdd_recursive_deref(dd,tempDEqualToINodes[j]); 00326 } 00327 tempDEqualToINodes[j] = dEqualToINodes[j]; 00328 if(tempDEqualToINodes[j]) { 00329 bdd_ref(tempDEqualToINodes[j]); 00330 } 00331 if(dEqualToINodes[j] && 00332 j >= fromIndex && j <= toIndex) { 00333 bdd_recursive_deref(dd,dEqualToINodes[j]); 00334 /* To be safe */ 00335 dEqualToINodes[j] = NIL(bdd_node); 00336 } 00337 } 00338 } 00339 /* Clean up */ 00340 for(j = 0; j < N; j++) { 00341 if(tempDEqualToINodes[j]) { 00342 bdd_recursive_deref(dd,tempDEqualToINodes[j]); 00343 } 00344 } 00345 for(j = N+1; j < 2*N+1; j++) { 00346 if(tempDEqualToINodes[j]) { 00347 bdd_recursive_deref(dd,tempDEqualToINodes[j]); 00348 } 00349 } 00350 00351 result = tempDEqualToINodes[N]; 00352 bdd_deref(result); 00353 00354 FREE(dEqualToINodes); 00355 FREE(tempDEqualToINodes); 00356 00357 return result; 00358 00359 endgame: 00360 for(m = 0; m < 2*N+1; m++) { 00361 if(tempDEqualToINodes[m]) { 00362 bdd_recursive_deref(dd,tempDEqualToINodes[m]); 00363 } 00364 } 00365 for(m = fromIndex; m < j; m++) { 00366 bdd_recursive_deref(dd,dEqualToINodes[m]); 00367 } 00368 FREE(dEqualToINodes); 00369 FREE(tempDEqualToINodes); 00370 00371 return NULL; 00372 } 00373