VIS

src/mark/markGetScc.c

Go to the documentation of this file.
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