VIS

src/mark/mark.c

Go to the documentation of this file.
00001 
00028 #include "markInt.h"
00029 
00030 static char rcsid[] UNUSED = "$Id: mark.c,v 1.29 2005/04/27 05:24:08 fabio Exp $";
00031 
00032 /*---------------------------------------------------------------------------*/
00033 /* Constant declarations                                                     */
00034 /*---------------------------------------------------------------------------*/
00035 
00036 
00037 /*---------------------------------------------------------------------------*/
00038 /* Stucture declarations                                                     */
00039 /*---------------------------------------------------------------------------*/
00040 
00041 
00042 /*---------------------------------------------------------------------------*/
00043 /* Type declarations                                                         */
00044 /*---------------------------------------------------------------------------*/
00045 
00046 
00047 /*---------------------------------------------------------------------------*/
00048 /* Variable declarations                                                     */
00049 /*---------------------------------------------------------------------------*/
00050 
00051 
00052 /*---------------------------------------------------------------------------*/
00053 /* Macro declarations                                                        */
00054 /*---------------------------------------------------------------------------*/
00055 
00056 
00059 /*---------------------------------------------------------------------------*/
00060 /* Static function prototypes                                                */
00061 /*---------------------------------------------------------------------------*/
00062 
00063 static void ckInterface(CK *ck);
00064 static bdd_node * recTC(CK *ck, bdd_node *tr);
00065 static bdd_node * transitiveClosureByIterSquaring(bdd_manager *ddManager, bdd_node *TR, bdd_node **xVars, bdd_node **yVars, bdd_node **zVars, int nVars);
00066 static bdd_node * bddCollapseTSCC(CK *ck);
00067 static int sccGetPeriod(CK *ck, bdd_node *reset);
00068 static array_t * markGetBddArray(array_t *mvfArray);
00069 static bdd_node ** BddNodeArrayFromIdArray(bdd_manager *ddManager, array_t *idArray);
00070 static bdd_node * computeTransitionRelationWithIds(bdd_manager *ddManager, array_t *nextBdds, bdd_node **yVars, int nVars);
00071 
00075 /*---------------------------------------------------------------------------*/
00076 /* Definition of exported functions                                          */
00077 /*---------------------------------------------------------------------------*/
00078 
00116 bdd_node **
00117 Mark_FsmComputeStateProbs(
00118   Fsm_Fsm_t *fsm,
00119   Mark_SolveMethod solveMethod,
00120   Mark_StartMethod startMethod,
00121   st_table *inputProb,
00122   int roundOff)
00123 {
00124     graph_t *partition;
00125     bdd_manager *ddManager;
00126 
00127     array_t *tranFunArray, *leaveIds;
00128     array_t *nextBdds, *nextMvfs;
00129 
00130     int i, phase;
00131     int nVars, nPi;
00132 
00133     bdd_node *tranRelation, **result;
00134     bdd_node **xVars,**yVars, **piVars;
00135     bdd_node *ddTemp, *reachable;
00136 
00137     mdd_t *reachStates;
00138     
00139     if (bdd_get_package_name() != CUDD) {
00140         (void) fprintf(vis_stderr,"Synthesis package can be used only with CUDD package\n");
00141         (void) fprintf(vis_stderr,"Please compile with CUDD package\n");
00142         return 0;
00143     }
00144 
00145     if (solveMethod == Solve_CKMethod_c ||
00146         solveMethod == Solve_GenMethod_c) {
00147         fprintf(vis_stdout,"Mark: Solve_CKMethod_c and Solve_GenMethod_c");
00148         fprintf(vis_stdout," not implemented yet\n");
00149         return NIL(bdd_node *);
00150     }
00151 
00152     ddManager = (bdd_manager *)Fsm_FsmReadMddManager(fsm);
00153 
00154     /*
00155      * tranFunArray is a list of next state funs.
00156      */
00157 
00158     tranFunArray = Fsm_FsmReadNextStateFunctionNames(fsm);
00159 
00160     leaveIds = array_join(Fsm_FsmReadInputVars(fsm),
00161                           Fsm_FsmReadPresentStateVars(fsm));
00162     /*
00163      * Get the BDDs for transition functions.Duplicate functions are returned.
00164      */
00165     partition = Fsm_FsmReadPartition(fsm);
00166     nextMvfs = Part_PartitionBuildFunctions(partition,tranFunArray,leaveIds,
00167                                             NIL(mdd_t));
00168     array_free(leaveIds);
00169     array_free(tranFunArray);
00170     nextBdds = markGetBddArray(nextMvfs);
00171 
00172     Mvf_FunctionArrayFree(nextMvfs);
00173 
00174     /* Get the DdNodes for all the variables.*/
00175 
00176     piVars = BddNodeArrayFromIdArray(ddManager, 
00177                                          Fsm_FsmReadInputVars(fsm));
00178     xVars = BddNodeArrayFromIdArray(ddManager, 
00179                                         Fsm_FsmReadPresentStateVars(fsm));
00180     yVars = BddNodeArrayFromIdArray(ddManager,
00181                                         Fsm_FsmReadNextStateVars(fsm));
00182 
00183     nVars = array_n(Fsm_FsmReadNextStateVars(fsm));
00184     nPi = array_n(Fsm_FsmReadInputVars(fsm));
00185 
00186     /* Compute the transition relation */
00187     tranRelation = computeTransitionRelationWithIds(ddManager, nextBdds,
00188                                                     yVars, nVars);
00189 
00190     arrayForEachItem(bdd_node *, nextBdds, i, ddTemp) {
00191         bdd_recursive_deref(ddManager,ddTemp);
00192     }
00193     array_free(nextBdds);
00194 
00195     /* Compute the reachable states. */
00196     reachStates = Fsm_FsmComputeReachableStates(fsm,0,0,0,0,0,0,1000,
00197                                                 Fsm_Rch_Default_c,0,0,
00198                                                 NIL(array_t),FALSE, NIL(array_t));
00199 
00200     ddTemp = (bdd_node *)bdd_get_node(reachStates,&phase);
00201     reachable = phase ?  bdd_not_bdd_node(ddTemp) : ddTemp;
00202     bdd_ref(reachable);
00203     mdd_free(reachStates);
00204 
00205     /* Restrict the STG to only the reachale states */
00206     bdd_ref(ddTemp = bdd_bdd_constrain(ddManager,tranRelation,reachable));
00207     bdd_recursive_deref(ddManager,tranRelation);
00208     tranRelation = ddTemp;
00209     
00210     /* Compute the state probabilities */
00211     /* result[0] = state probabilities, result[1] = transition prob. matrix */
00212     result = Mark_ComputeStateProbsWithTr(ddManager,tranRelation,
00213                                           reachable,piVars,
00214                                           xVars,yVars,NIL(bdd_node *),inputProb,
00215                                           nVars,nPi,roundOff,
00216                                           solveMethod,startMethod);
00217     
00218     bdd_recursive_deref(ddManager,tranRelation);
00219     bdd_recursive_deref(ddManager,reachable);
00220     
00221     for(i = 0; i < nVars; i++) {
00222         bdd_recursive_deref(ddManager,xVars[i]);
00223         bdd_recursive_deref(ddManager,yVars[i]);
00224     }
00225     for(i = 0 ; i < nPi; i++) {
00226         bdd_recursive_deref(ddManager,piVars[i]);
00227     }
00228     FREE(xVars);
00229     FREE(yVars);
00230     FREE(piVars);
00231         
00232     return (result);
00233 }
00234 
00267 bdd_node **
00268 Mark_ComputeStateProbsWithTr(
00269   bdd_manager *ddManager,
00270   bdd_node *TR,
00271   bdd_node *reachable,
00272   bdd_node **piVars,
00273   bdd_node **xVars,
00274   bdd_node **yVars,
00275   bdd_node **zVars,
00276   st_table *inputProb,
00277   int nVars,
00278   int nPi,
00279   int roundOff,
00280   Mark_SolveMethod method,
00281   Mark_StartMethod start)
00282 {
00283     CK *ck;
00284     bdd_node **piAddVars, **xAddVars, **yAddVars, **zAddVars;
00285     bdd_node *rep, *scc;
00286     bdd_node **result;
00287     st_generator *gen;
00288     int i, index;
00289     int createdPia, createdXa, createdYa, createdZa;
00290     int createdZ;
00291     int period;
00292 
00293     /* To suppress Alpha warnings */
00294     yAddVars = NIL(bdd_node *);
00295     zAddVars = NIL(bdd_node *);
00296 
00297     if (bdd_get_package_name() != CUDD) {
00298         (void) fprintf(vis_stderr,"Synthesis package can be used only with CUDD package\n");
00299         (void) fprintf(vis_stderr,"Please compile with CUDD package\n");
00300         return 0;
00301     }
00302     
00303     createdPia = createdXa = createdYa = createdZa = 0;
00304     createdZ = 0;
00305 
00306     piAddVars = ALLOC(bdd_node *, nPi);
00307     if (piAddVars == NULL)
00308         return NULL;
00309     createdPia = 1;
00310 
00311     xAddVars = ALLOC(bdd_node *, nVars);
00312     if (xAddVars == NULL)
00313         goto endgame;
00314     createdXa = 1;
00315 
00316     yAddVars = ALLOC(bdd_node *, nVars);
00317     if (yAddVars == NULL)
00318         goto endgame;
00319     createdYa = 1;
00320 
00321     zAddVars = ALLOC(bdd_node *, nVars);
00322     if (zAddVars == NULL)
00323         goto endgame;
00324     createdZa = 1;
00325   
00326     if (zVars == NULL) {
00327         zVars = ALLOC(bdd_node *, nVars);
00328         if (zVars == NULL) 
00329             goto endgame;
00330         createdZ = 1;
00331         for (i = 0; i < nVars; i++)
00332             bdd_ref(zVars[i] = bdd_bdd_new_var(ddManager));
00333     }
00334 
00335     for(i = 0;i < nPi; i++) {
00336         index = bdd_node_read_index(piVars[i]);
00337         bdd_ref(piAddVars[i] = bdd_add_ith_var(ddManager,index));
00338     }
00339 
00340     for(i = 0; i < nVars; i++) {
00341         index = bdd_node_read_index(xVars[i]);
00342         bdd_ref(xAddVars[i] = bdd_add_ith_var(ddManager,index));
00343         index = bdd_node_read_index(yVars[i]);
00344         bdd_ref(yAddVars[i] = bdd_add_ith_var(ddManager,index));
00345         index = bdd_node_read_index(zVars[i]);
00346         bdd_ref(zAddVars[i] = bdd_add_ith_var(ddManager,index));
00347     }
00348 
00349     /* Allocate the structure for internal use */
00350     ck = ALLOC(CK,1);
00351   
00352     ck->manager = ddManager;
00353     ck->piVars = piVars;
00354     ck->xVars = xVars;
00355     ck->yVars = yVars;
00356     ck->zVars = zVars;
00357     ck->piAddVars = piAddVars;
00358     ck->xAddVars = xAddVars;
00359     ck->yAddVars = yAddVars;
00360     ck->zAddVars = zAddVars;
00361     ck->coeff = NULL; /* assigned in ckInterface - ADD */
00362     ck->nVars = nVars;
00363     ck->nPi = nPi;
00364     ck->abstol = bdd_read_epsilon(ddManager);
00365     ck->scale = 1.0;
00366     ck->reltol = 1.0e-4;
00367     ck->start = start;
00368     ck->roundOff = roundOff;
00369     ck->inputProb = inputProb;
00370     ck->transition = TR;
00371     ck->reached = reachable;
00372     ck->indexSCC = NULL;       /* assigned in MarkGetSCC called by recTC */
00373     ck->collapsedcoeff = NULL; /* assigned in ckInterface */
00374     ck->term_SCC_states = 0;
00375     ck->periods = NULL;        /* assigned in bddCollapseTSCC */
00376     ck->term_scc = NULL;       /* assigned in ckInterface - ADD */
00377     ck->init_guess = NULL;     /* assigned and derefed in all the methods.*/
00378 
00379     ckInterface(ck);
00380 
00381     /* select resolution method */
00382     if (method == Solve_CKMethod_c) {
00383         fprintf(stdout,"Mark<->Equations' Solver uses CK Method\n");
00384         result = MarkAddCKSolve(ck); 
00385     } 
00386     else if (method == Solve_GenMethod_c) {
00387         fprintf(stdout,"Mark<->Equations' Solver uses General Method\n");
00388         result = MarkAddGenSolve(ck); 
00389     }
00390     else {
00391         fprintf(stdout,"Mark<->Equations's Solver uses FP Method\n");
00392         result = MarkAddFPSolve(ck);
00393     }
00394 
00395     /* Clean up */
00396     bdd_recursive_deref(ddManager,ck->coeff);
00397     st_foreach_item(ck->indexSCC,gen,&rep,&scc) {
00398         bdd_recursive_deref(ddManager,rep);
00399         bdd_recursive_deref(ddManager,scc);
00400     }
00401     st_free_table(ck->indexSCC);
00402     bdd_recursive_deref(ddManager,ck->collapsedcoeff);
00403     st_foreach_item_int(ck->periods,gen,&rep, &period) {
00404         bdd_recursive_deref(ddManager,rep);
00405     }
00406     st_free_table(ck->periods);
00407 
00408     bdd_recursive_deref(ddManager,ck->term_scc);
00409 
00410     for(i = 0; i < nPi; i++) {
00411         bdd_recursive_deref(ddManager,piAddVars[i]);
00412     }
00413 
00414     for(i = 0; i < nVars; i++) {
00415         bdd_recursive_deref(ddManager,xAddVars[i]);
00416         bdd_recursive_deref(ddManager,yAddVars[i]);
00417         bdd_recursive_deref(ddManager,zAddVars[i]);
00418     }
00419 
00420     if (createdZ) {
00421         for(i = 0; i < nVars; i++) {
00422             bdd_recursive_deref(ddManager,zVars[i]);
00423         }
00424         FREE(zVars);
00425     }
00426     FREE(xAddVars);
00427     FREE(yAddVars);
00428     FREE(zAddVars);
00429     FREE(piAddVars);
00430     FREE(ck);
00431 
00432     return result;
00433 
00434 endgame:
00435     if (createdPia)
00436         FREE(piAddVars);
00437     if (createdXa)
00438         FREE(xAddVars);
00439     if (createdYa)
00440         FREE(yAddVars);
00441     if (createdZa)
00442         FREE(zAddVars);
00443     if (createdZ)
00444         FREE(zVars);
00445 
00446     return NULL;
00447 }
00448 
00449 
00450 /*---------------------------------------------------------------------------*/
00451 /* Definition of internal functions                                          */
00452 /*---------------------------------------------------------------------------*/
00453 
00465 bdd_node **
00466 MarkAddCKSolve(
00467   CK *ck)
00468 {
00469     (void) fprintf(vis_stdout,"Not implemented yet. \n");
00470     return NIL(bdd_node *);
00471 }
00472 
00473 
00485 bdd_node **
00486 MarkAddGenSolve(
00487   CK *ck)
00488 {
00489     (void) fprintf(vis_stdout,"Not implemented yet. \n");
00490     return NIL(bdd_node *);
00491 }
00492 
00493 
00518 double 
00519 MarkAverageBitChange(
00520   bdd_manager *manager,
00521   bdd_node *probTR,
00522   bdd_node **xVars,
00523   bdd_node **yVars,
00524   int nVars)
00525 {
00526     bdd_node *diff, *cube, *PA, *QA;
00527     bdd_node **vars;
00528     double Mean;
00529     int i;
00530 
00531     vars = ALLOC(bdd_node *,2*nVars);
00532     for (i = 0; i < nVars; i++) {
00533         vars[i] = bdd_add_ith_var(manager,bdd_node_read_index(xVars[i]));
00534         bdd_ref(vars[i]);
00535     }
00536     for (i = nVars; i < 2*nVars; i++) {
00537         vars[i] = bdd_add_ith_var(manager,bdd_node_read_index(yVars[i-nVars]));
00538         bdd_ref(vars[i]);
00539     }
00540 
00541     cube = bdd_add_compute_cube(manager,vars,NULL,2*nVars);
00542     bdd_ref(cube);
00543 
00544     /* Calculate the Hamming distance ADD. This ADD represents the hamming
00545      * distance between two vectors represented by xVars and yVars.
00546      */
00547     bdd_ref(diff = bdd_add_hamming(manager,xVars,yVars,nVars));
00548     bdd_ref(PA = bdd_add_apply(manager,bdd_add_times,probTR,diff));
00549     bdd_recursive_deref(manager,diff);
00550   
00551     /* And now add and abstract all the variables.*/
00552     bdd_ref(QA = bdd_add_exist_abstract(manager,PA,cube));
00553     bdd_recursive_deref(manager,PA);
00554     bdd_recursive_deref(manager,cube);
00555     Mean = (double)bdd_add_value(QA);
00556     bdd_recursive_deref(manager,QA); 
00557 
00558     for (i = 0; i < 2*nVars; i++) {
00559         bdd_recursive_deref(manager,vars[i]);
00560     }
00561     FREE(vars);
00562     return Mean;
00563 }
00564 
00565 /*---------------------------------------------------------------------------*/
00566 /* Definition of static functions                                            */
00567 /*---------------------------------------------------------------------------*/
00568 
00580 static void
00581 ckInterface(
00582   CK *ck)
00583 {
00584     bdd_manager *ddManager;
00585     bdd_node *piCube;
00586     bdd_node *new_;
00587     bdd_node *tmp1,*tmp2;
00588     bdd_node *p, *t;
00589     bdd_node *reachable, *TR;
00590     bdd_node *q, *r;
00591     st_table *newSCC;
00592     st_table *newperiods;
00593     st_generator *gen;
00594     int len, nVars;
00595 
00596     ddManager = ck->manager;
00597     reachable = ck->reached;
00598     TR = ck->transition;
00599     nVars = ck->nVars;
00600 
00601     bdd_ref(piCube = bdd_bdd_compute_cube(ddManager,ck->piVars,NULL,ck->nPi));
00602     /* abstract the PI variables for the SCC computation */
00603     bdd_ref(new_ = bdd_bdd_exist_abstract(ddManager,TR,piCube));
00604     bdd_recursive_deref(ddManager,piCube);
00605 
00606     /* now find the set of nodes in terminal SCC's */
00607     p = recTC(ck,new_);
00608     bdd_recursive_deref(ddManager,new_);
00609 
00610     /* Collapse the TSCC in the graph */
00611     ck->collapsedcoeff = bddCollapseTSCC(ck);
00612     bdd_ref(ck->collapsedcoeff);
00613 
00614     /* retain only reachable terminal SCC's */
00615     bdd_ref(t = bdd_bdd_and(ddManager,p,reachable));
00616     bdd_recursive_deref(ddManager,p);
00617 
00618     /* count the number of states in the terminal SCC's */
00619     ck->term_SCC_states = bdd_count_minterm(ddManager,t,nVars);
00620     (void) fprintf(vis_stdout,"# of states in TSCCs = %f\n",
00621                    ck->term_SCC_states);
00622 
00623     /* Translate the data in ck->collapsedcoeff and 
00624      * ck->indexSCC from BDDs to ADDs.
00625      */
00626 
00627     newSCC = st_init_table(st_ptrcmp,st_ptrhash);
00628     newperiods = st_init_table(st_ptrcmp,st_ptrhash);
00629     st_foreach_item(ck->indexSCC,gen,&tmp1,&tmp2) {
00630         bdd_ref(q = bdd_bdd_to_add(ddManager,tmp1));
00631         bdd_ref(r = bdd_bdd_to_add(ddManager,tmp2));
00632         st_lookup_int(ck->periods,(char *)tmp1, &len);
00633         st_insert(newSCC,(char *)q,(char *)r);
00634         st_insert(newperiods,(char *)q,(char *)(long)len);
00635         bdd_recursive_deref(ddManager,tmp1);
00636         bdd_recursive_deref(ddManager,tmp2);
00637     }
00638     st_free_table(ck->indexSCC);
00639     st_free_table(ck->periods);
00640     bdd_ref(q = bdd_bdd_to_add(ddManager,ck->collapsedcoeff));
00641     bdd_recursive_deref(ddManager,ck->collapsedcoeff);
00642     ck->collapsedcoeff = q;
00643     ck->indexSCC = newSCC;
00644     ck->periods = newperiods;
00645 
00646     /* Print the number of TSCCs */
00647     (void) fprintf(vis_stdout,"# of TSCCs = %d\n",st_count(newSCC));
00648 
00649     /* convert the transition relation BDD into an ADD */
00650     bdd_ref(q = bdd_bdd_to_add(ddManager,TR));
00651     ck->coeff = q;
00652 
00653     /* convert the term_scc set BDD into an ADD */
00654     bdd_ref(q = bdd_bdd_to_add(ddManager,t));
00655     ck->term_scc = q;
00656     bdd_recursive_deref(ddManager,t);
00657 
00658 } /* End of ckInterface */
00659 
00671 static bdd_node * 
00672 recTC(
00673   CK *ck,
00674   bdd_node *tr)
00675 {
00676 
00677     bdd_manager *manager = ck->manager;
00678     bdd_node **xVars, **yVars, **zVars;
00679     bdd_node *closure;
00680     bdd_node *lastScc;
00681     int nVars;
00682 
00683     xVars = ck->xVars;
00684     yVars = ck->yVars;
00685     zVars = ck->zVars;
00686     nVars = ck->nVars;
00687 
00688     /* Matsunaga's procedure could also be used. Will have to implement it
00689      * later.
00690      */ 
00691     
00692     closure = transitiveClosureByIterSquaring(manager,tr,xVars,yVars,zVars, 
00693                                               nVars);
00694     bdd_ref(closure);
00695     lastScc = MarkGetSCC(manager,tr,closure,ck->reached,
00696                      xVars, yVars, nVars, &(ck->indexSCC));
00697 
00698     bdd_recursive_deref(manager,closure);
00699 
00700     return(lastScc);
00701 }
00702 
00703 
00715 static bdd_node *
00716 transitiveClosureByIterSquaring(
00717   bdd_manager *ddManager,
00718   bdd_node *TR,
00719   bdd_node **xVars,
00720   bdd_node **yVars,
00721   bdd_node **zVars,
00722   int nVars)
00723 {
00724     bdd_node *prev, *next, *TRxz, *TRzy;
00725     bdd_node *inter;
00726     bdd_node *zCube;
00727   
00728     bdd_ref(zCube = bdd_bdd_compute_cube(ddManager,zVars,NULL,nVars));
00729 
00730     bdd_ref(prev = TR);
00731     while(1) {
00732         TRxz = bdd_bdd_swap_variables(ddManager,prev,yVars,zVars,nVars);
00733         bdd_ref(TRxz);
00734         TRzy = bdd_bdd_swap_variables(ddManager,prev,xVars,zVars,nVars);
00735         bdd_ref(TRzy);
00736         inter = bdd_bdd_and_abstract(ddManager,TRxz,TRzy,zCube);
00737         bdd_ref(inter);
00738         bdd_recursive_deref(ddManager,TRxz);
00739         bdd_recursive_deref(ddManager,TRzy);
00740         next = bdd_bdd_or(ddManager,TR,inter);
00741         bdd_ref(next);
00742         bdd_recursive_deref(ddManager,inter);
00743         if(prev == next)
00744             break;
00745         bdd_recursive_deref(ddManager,prev);
00746         prev = next;
00747     }
00748     bdd_recursive_deref(ddManager,zCube);
00749     bdd_recursive_deref(ddManager,prev);
00750     bdd_deref(next);
00751     return next;
00752 }
00753 
00765 static bdd_node *
00766 bddCollapseTSCC(
00767   CK *ck)
00768 {
00769     bdd_manager *manager = ck->manager;
00770     bdd_node *tmp1,*tmp2;
00771     bdd_node *repr,*scc,*restscc;
00772     bdd_node *newtr;
00773     bdd_node *xCube,*yCube;
00774     bdd_node *sccfanout,*sccfanin;
00775     st_generator *gen;
00776     int i;
00777 
00778     bdd_ref(xCube = bdd_bdd_compute_cube(manager,ck->xVars,NULL,ck->nVars));
00779     bdd_ref(yCube = bdd_bdd_compute_cube(manager,ck->yVars,NULL,ck->nVars));
00780 
00781     ck->periods = st_init_table(st_ptrcmp,st_ptrhash);
00782   
00783     bdd_ref(newtr = ck->transition);
00784     i = 0;
00785     st_foreach_item(ck->indexSCC,gen,&repr,&scc) {
00786         /* Traverse the SCC to obtain the period */
00787         st_insert(ck->periods,(char *)repr,(char *)(long)sccGetPeriod(ck,repr));
00788       
00789         /* Add edges from scc to the representatives in the fanout */
00790         bdd_ref(sccfanout = bdd_bdd_and_abstract(manager,newtr,scc,xCube));
00791       
00792         bdd_ref(tmp1 = bdd_bdd_and(manager,scc,sccfanout));
00793         bdd_recursive_deref(manager,sccfanout);
00794         bdd_ref(tmp2 = bdd_bdd_or(manager,newtr,tmp1));
00795         bdd_recursive_deref(manager,tmp1);
00796         bdd_recursive_deref(manager,newtr);
00797         newtr = tmp2;
00798       
00799         /* Add edges from fanin to representative */
00800         bdd_ref(tmp2 = bdd_bdd_swap_variables(manager,scc,ck->xVars,ck->yVars,
00801                                               ck->nVars));
00802         bdd_ref(sccfanin = bdd_bdd_and_abstract(manager,newtr,tmp2,yCube));
00803         bdd_recursive_deref(manager,tmp2);
00804       
00805         /* Add edges (fanin,representative) to the TR */
00806         bdd_ref(tmp1 = bdd_bdd_swap_variables(manager,repr,ck->xVars,
00807                                               ck->yVars,ck->nVars));
00808         bdd_ref(tmp2 = bdd_bdd_and(manager,sccfanin,tmp1));
00809         bdd_recursive_deref(manager,tmp1);
00810         bdd_recursive_deref(manager,sccfanin);
00811         bdd_ref(tmp1 = bdd_bdd_or(manager,newtr,tmp2));
00812         bdd_recursive_deref(manager,tmp2);
00813         bdd_recursive_deref(manager,newtr);
00814         newtr = tmp1;
00815       
00816         /*Delete the edges that go to the non-representative nodes */
00817         bdd_ref(restscc = bdd_bdd_and(manager,scc,bdd_not_bdd_node(repr)));
00818       
00819         bdd_ref(tmp1 = bdd_bdd_and(manager,newtr,bdd_not_bdd_node(restscc)));
00820         bdd_ref(tmp2 = bdd_bdd_swap_variables(manager,restscc,ck->xVars,
00821                                             ck->yVars,ck->nVars));
00822         bdd_recursive_deref(manager,restscc);
00823         bdd_recursive_deref(manager,newtr);
00824         bdd_ref(newtr = bdd_bdd_and(manager,tmp1,bdd_not_bdd_node(tmp2)));
00825         bdd_recursive_deref(manager,tmp1);
00826         bdd_recursive_deref(manager,tmp2);
00827       
00828         i++;
00829     }
00830   
00831     bdd_recursive_deref(manager,xCube);
00832     bdd_recursive_deref(manager,yCube);
00833   
00834     bdd_deref(newtr);
00835     return(newtr);
00836 }
00837 
00849 static int
00850 sccGetPeriod(
00851   CK *ck,
00852   bdd_node *reset)
00853 {
00854 
00855     bdd_manager *manager = ck->manager;
00856     bdd_node *new_,*from;
00857     bdd_node *tmp1;
00858     bdd_node *xCube, *inputCube;
00859     bdd_node *transition;
00860     int pos,result = 0;
00861     int depth;
00862     int stop = 0; 
00863     st_table *tos;
00864     st_generator *gen;
00865   
00866     /* Calculate the cube for abstraction */
00867 
00868     bdd_ref(xCube = bdd_bdd_compute_cube(manager,ck->xVars,NULL,ck->nVars));
00869     bdd_ref(inputCube = bdd_bdd_compute_cube(manager,ck->piVars,NULL,ck->nPi));
00870     bdd_ref(transition = bdd_bdd_exist_abstract(manager,ck->transition,
00871                                                 inputCube));
00872     bdd_recursive_deref(manager,inputCube);
00873   
00874     depth = 0;
00875     bdd_ref(from = reset);
00876     bdd_ref(tmp1 = reset);
00877     tos = st_init_table(st_ptrcmp,st_ptrhash);
00878     depth++;
00879     st_insert(tos,(char *)tmp1,(char *)(long)depth);
00880 
00881     while(!stop) {
00882         bdd_ref(tmp1 = bdd_bdd_and_abstract(manager,from,transition,xCube));
00883         bdd_ref(new_ = bdd_bdd_swap_variables(manager,tmp1,ck->yVars,ck->xVars,
00884                                              ck->nVars));
00885         bdd_recursive_deref(manager,tmp1);
00886       
00887         if((stop = st_lookup_int(tos,(char *)new_, &pos)))
00888             result = depth - pos;
00889         else
00890             st_insert(tos,(char *)new_,(char *)(long)depth);
00891         
00892         bdd_recursive_deref(manager,from);
00893         bdd_ref(from = new_);
00894         depth++;
00895     }
00896 
00897     bdd_recursive_deref(manager,new_);
00898     bdd_recursive_deref(manager,xCube);
00899     bdd_recursive_deref(manager,from);
00900 
00901     st_foreach_item_int(tos,gen,&new_, &pos) {
00902         bdd_recursive_deref(manager,new_);
00903     }
00904     st_free_table(tos);
00905 
00906     return result;
00907 }
00908 
00909 
00919 static array_t *
00920 markGetBddArray(array_t *mvfArray)
00921 {
00922     int           i,phase;
00923     array_t *bddArray;
00924     Mvf_Function_t *mvf;
00925 
00926     bddArray = array_alloc(bdd_node *,0);
00927 
00928     arrayForEachItem(Mvf_Function_t *, mvfArray,i,mvf) {
00929         mdd_t     *mddTemp;
00930         bdd_node    *ddNode;
00931 
00932         mddTemp = array_fetch(mdd_t *, mvf, 1);
00933         ddNode = (bdd_node *) bdd_get_node(mddTemp,&phase);
00934         bdd_ref(ddNode);
00935 
00936         ddNode = phase ? bdd_not_bdd_node(ddNode) : ddNode;
00937         array_insert_last(bdd_node *, bddArray, ddNode);
00938     }
00939     return bddArray;
00940 }
00941 
00951 static bdd_node **
00952 BddNodeArrayFromIdArray(
00953   bdd_manager   *ddManager,
00954   array_t       *idArray)
00955 {
00956     bdd_node **xvars;
00957     int i,id;
00958     int nvars = array_n(idArray);
00959 
00960     xvars = ALLOC(bdd_node *, nvars);
00961     if (xvars == NULL)
00962         return NULL;
00963 
00964     for(i = 0; i < nvars; i++) {
00965         id = array_fetch(int,idArray,i);
00966         xvars[i] = bdd_bdd_ith_var(ddManager,id);
00967         bdd_ref(xvars[i]);
00968     }
00969     return xvars;
00970 }
00971 
00983 static bdd_node *
00984 computeTransitionRelationWithIds(
00985   bdd_manager   *ddManager,
00986   array_t       *nextBdds,
00987   bdd_node      **yVars,
00988   int           nVars)
00989 {
00990     bdd_node    *ddtemp1, *ddtemp2;
00991     bdd_node    *oldTR, *fn;
00992     int                  i;
00993 
00994 
00995     oldTR = bdd_read_one(ddManager);
00996 
00997     for(i = 0; i < nVars; i++) {
00998         ddtemp2  = array_fetch(bdd_node *, nextBdds, i);
00999 
01000         fn = bdd_bdd_xnor(ddManager,ddtemp2,yVars[i]);
01001         bdd_ref(fn);
01002         ddtemp1 = bdd_bdd_and(ddManager,oldTR,fn);
01003         bdd_ref(ddtemp1);
01004         bdd_recursive_deref(ddManager,fn);
01005         bdd_recursive_deref(ddManager,oldTR);
01006         oldTR = ddtemp1;
01007     }
01008 
01009     return oldTR;
01010 }
01011