VIS
|
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