VIS
|
00001 00022 #include "markInt.h" 00023 00024 /*---------------------------------------------------------------------------*/ 00025 /* Constant declarations */ 00026 /*---------------------------------------------------------------------------*/ 00027 00028 00029 /*---------------------------------------------------------------------------*/ 00030 /* Stucture declarations */ 00031 /*---------------------------------------------------------------------------*/ 00032 00033 00034 /*---------------------------------------------------------------------------*/ 00035 /* Type declarations */ 00036 /*---------------------------------------------------------------------------*/ 00037 00038 00039 /*---------------------------------------------------------------------------*/ 00040 /* Variable declarations */ 00041 /*---------------------------------------------------------------------------*/ 00042 00043 00044 /*---------------------------------------------------------------------------*/ 00045 /* Macro declarations */ 00046 /*---------------------------------------------------------------------------*/ 00047 00048 00051 /*---------------------------------------------------------------------------*/ 00052 /* Static function prototypes */ 00053 /*---------------------------------------------------------------------------*/ 00054 00055 static bdd_node * pickOneCube(bdd_manager *manager, bdd_node *node, bdd_node **xVars, int nVars); 00056 00060 /*---------------------------------------------------------------------------*/ 00061 /* Definition of exported functions */ 00062 /*---------------------------------------------------------------------------*/ 00063 00064 00065 /*---------------------------------------------------------------------------*/ 00066 /* Definition of internal functions */ 00067 /*---------------------------------------------------------------------------*/ 00068 00084 bdd_node * 00085 MarkGetSCC( 00086 bdd_manager *manager, 00087 bdd_node *tr, 00088 bdd_node *tc, 00089 bdd_node *reached, 00090 bdd_node **xVars, 00091 bdd_node **yVars, 00092 int nVars, 00093 st_table **scc_table) 00094 00095 { 00096 bdd_node *zero = bdd_read_logic_zero(manager); 00097 bdd_node *cr, /* Cycle relation */ 00098 *ee, /* Exterior edges relation, edges between SCCs */ 00099 *nofanout, /* Nodes without fanout outside the SCC */ 00100 *nocycle, /* Nodes that are not in any cycle */ 00101 *tnofanout, /* Temporary nodes without fanout when 00102 * decomposing into SCCs. 00103 */ 00104 *cub, /* Arbitrary cube picked inside the SCC */ 00105 *scc, /* States in the current SCC */ 00106 *tmp1,*tmp2; 00107 bdd_node *yCube; 00108 bdd_node **permutArray; 00109 int i, size; 00110 00111 00112 /* Build the cycle relation CR(x,y) = TC(x,y)*TC(y,x) */ 00113 /* tmp1 = tc(y,x) -- retain it to use later in edge relation */ 00114 bdd_ref(tmp1 = bdd_bdd_swap_variables(manager,tc,xVars,yVars,nVars)); 00115 bdd_ref(cr = bdd_bdd_and(manager,tc,tmp1)); 00116 00117 /* Break into SCCs */ 00118 *scc_table = st_init_table(st_ptrcmp,st_ptrhash); 00119 00120 /* Build the exterior edge relation EE(x,y) = tTC(x,y)*tTC'(y,x) */ 00121 bdd_ref(ee = bdd_bdd_and(manager,tc,bdd_not_bdd_node(tmp1))); 00122 bdd_recursive_deref(manager,tmp1); 00123 00124 /* Calculate nodes without outgoing edges out the SCCS */ 00125 bdd_ref(yCube = bdd_bdd_compute_cube(manager,yVars,NULL,nVars)); 00126 bdd_ref(tmp2 = bdd_bdd_exist_abstract(manager,ee,yCube)); 00127 bdd_ref(tmp1 = bdd_bdd_and(manager,bdd_not_bdd_node(tmp2),reached)); 00128 bdd_recursive_deref(manager,tmp2); 00129 bdd_recursive_deref(manager,ee); 00130 nofanout = tmp1; 00131 00132 /* Detect the Single SCCs ( SSCCs ) */ 00133 bdd_ref(tmp2 = bdd_bdd_and(manager,nofanout,cr)); 00134 bdd_ref(tmp1 = bdd_bdd_exist_abstract(manager,tmp2,yCube)); 00135 bdd_recursive_deref(manager,tmp2); 00136 bdd_ref(nocycle = bdd_bdd_and(manager,nofanout,bdd_not_bdd_node(tmp1))); 00137 bdd_recursive_deref(manager,tmp1); 00138 00139 bdd_recursive_deref(manager,yCube); 00140 00141 /* Given the nofanout nodes, expand the SCCs that are inside */ 00142 bdd_ref(tnofanout = bdd_bdd_and(manager,nofanout,bdd_not_bdd_node(nocycle))); 00143 bdd_recursive_deref(manager,nocycle); 00144 00145 size = bdd_num_vars(manager); 00146 permutArray = ALLOC(bdd_node *, size); 00147 for(i = 0; i < size; i++) { 00148 permutArray[i] = bdd_bdd_ith_var(manager,i); 00149 bdd_ref(permutArray[i]); 00150 } 00151 for(i = 0; i < nVars; i++) { 00152 int yindex; 00153 00154 yindex = bdd_node_read_index(yVars[i]); 00155 bdd_recursive_deref(manager,permutArray[yindex]); 00156 bdd_ref(permutArray[yindex] = xVars[i]); 00157 } 00158 00159 /* While there are still nodes in the set tnofanout */ 00160 while(tnofanout != zero) { 00161 00162 /* Pick a point inside the nofanout set */ 00163 bdd_ref(cub = pickOneCube(manager,tnofanout,xVars,nVars)); 00164 00165 /* Obtain the points connected to "cube" by a cycle and 00166 * rename variables. 00167 */ 00168 00169 bdd_ref(tmp1 = bdd_bdd_constrain(manager,cr,cub)); 00170 00171 bdd_ref(tmp2 = bdd_bdd_vector_compose(manager,tmp1,permutArray)); 00172 bdd_recursive_deref(manager,tmp1); 00173 00174 /* Add the cube to the set, because may be it is not in it */ 00175 bdd_ref(scc = bdd_bdd_or(manager,tmp2,cub)); 00176 bdd_recursive_deref(manager,tmp2); 00177 st_insert(*scc_table,(char *)cub,(char *)scc); 00178 00179 /* Delete the SCC from the points without fanout */ 00180 bdd_ref(tmp2 = bdd_bdd_and(manager,tnofanout,bdd_not_bdd_node(scc))); 00181 bdd_recursive_deref(manager,tnofanout); 00182 tnofanout = tmp2; 00183 } 00184 00185 for(i = 0; i < size; i++) { 00186 bdd_recursive_deref(manager,permutArray[i]); 00187 } 00188 FREE(permutArray); 00189 bdd_recursive_deref(manager,tnofanout); 00190 bdd_recursive_deref(manager,cr); 00191 00192 return(nofanout); 00193 } 00194 00195 /*---------------------------------------------------------------------------*/ 00196 /* Definition of static functions */ 00197 /*---------------------------------------------------------------------------*/ 00198 00210 static bdd_node * 00211 pickOneCube( 00212 bdd_manager *manager, 00213 bdd_node *node, 00214 bdd_node **xVars, 00215 int nVars) 00216 { 00217 char *string; 00218 int i, size; 00219 int *indices; 00220 bdd_node *old, *new_; 00221 00222 size = bdd_num_vars(manager); 00223 indices = ALLOC(int,nVars); 00224 string = ALLOC(char,size); 00225 if(! bdd_bdd_pick_one_cube(manager,node,string)) { 00226 fprintf(stdout,"mark<->MarkPickOneCube: could not pick a cube\n"); 00227 exit(-1); 00228 } 00229 for (i = 0; i < nVars; i++) { 00230 indices[i] = bdd_node_read_index(xVars[i]); 00231 } 00232 00233 bdd_ref(old = bdd_read_one(manager)); 00234 00235 for (i = 0; i < nVars; i++) { 00236 switch(string[indices[i]]) { 00237 case 0: 00238 bdd_ref(new_ = bdd_bdd_and(manager,old,bdd_not_bdd_node(xVars[i]))); 00239 bdd_recursive_deref(manager,old); 00240 old = new_; 00241 break; 00242 case 1: 00243 bdd_ref(new_ = bdd_bdd_and(manager,old,xVars[i])); 00244 bdd_recursive_deref(manager,old); 00245 old = new_; 00246 break; 00247 } 00248 } 00249 FREE(string); 00250 FREE(indices); 00251 bdd_deref(old); 00252 return old; 00253 } 00254 00255