VIS

src/bmc/bmcAutUtil.c

Go to the documentation of this file.
00001 
00017 #include "bmc.h"
00018 #include "bmcInt.h"
00019 
00020 static char rcsid[] UNUSED = "$Id: bmcAutUtil.c,v 1.18 2005/05/18 18:11:52 jinh Exp $";
00021 
00022 /*---------------------------------------------------------------------------*/
00023 /* Constant declarations                                                     */
00024 /*---------------------------------------------------------------------------*/
00025 
00026 /*---------------------------------------------------------------------------*/
00027 /* Type declarations                                                         */
00028 /*---------------------------------------------------------------------------*/
00029 
00030 
00031 /*---------------------------------------------------------------------------*/
00032 /* Structure declarations                                                    */
00033 /*---------------------------------------------------------------------------*/
00034 
00035 
00036 /*---------------------------------------------------------------------------*/
00037 /* Variable declarations                                                     */
00038 /*---------------------------------------------------------------------------*/
00039 
00040 
00043 /*---------------------------------------------------------------------------*/
00044 /* Static function prototypes                                                */
00045 /*---------------------------------------------------------------------------*/
00046 
00047 static st_table * AutomatonVertexGetImg(graph_t *G, vertex_t *vtx);
00048 static st_table * AutomatonVertexGetPreImg(graph_t *G, vertex_t *vtx);
00049 static int stIntersect(st_table *tbl1, st_table *tbl2);
00050 static int NoOfBitEncode(int n);
00051 static bdd_t * encodeOfInteger(mdd_manager *manager, array_t *varArray, int val);
00052 
00056 /*---------------------------------------------------------------------------*/
00057 /* Definition of exported functions                                          */
00058 /*---------------------------------------------------------------------------*/
00059 
00060 
00061 /*---------------------------------------------------------------------------*/
00062 /* Definition of internal functions                                          */
00063 /*---------------------------------------------------------------------------*/
00064 
00076 void
00077 BmcAutEncodeAutomatonStates(
00078   Ntk_Network_t   *network,
00079   Ltl_Automaton_t *automaton)
00080 {
00081   mdd_manager         *manager = Ntk_NetworkReadMddManager(network);
00082   lsGen               lsGen, lsGen1;
00083   vertex_t            *vtx;
00084   Ltl_AutomatonNode_t *node, *node1;
00085   Ctlsp_Formula_t     *F;
00086   mdd_t               *label;
00087   
00088   int                 i;
00089 
00090   /*
00091     Build the mdd of the labels of each automaton node
00092    */
00093   foreach_vertex(automaton->G, lsGen, vtx) {
00094     node = (Ltl_AutomatonNode_t *) vtx->user_data;
00095     if (node->Labels) {
00096       label =  mdd_one(manager);
00097       for (i=0; i<array_n(automaton->labelTable); i++) {
00098         if (LtlSetGetElt(node->Labels, i)) {
00099           F = array_fetch(Ctlsp_Formula_t *, automaton->labelTable, i);
00100           label = mdd_and(label, BmcAutBuildMddForPropositionalFormula(network, automaton, F), 1, 1);
00101         }
00102       }
00103       node->Encode = label;
00104     }
00105   }
00106   /*
00107     Encode automaton labels
00108    */
00109   foreach_vertex(automaton->G, lsGen, vtx) {
00110     bdd_t *newVar = NULL;
00111     
00112     node = (Ltl_AutomatonNode_t *) vtx->user_data;
00113     foreach_vertex(automaton->G, lsGen1, vtx) {
00114       node1 = (Ltl_AutomatonNode_t *) vtx->user_data;
00115       if(node != node1){
00116         if(newVar == NULL){
00117           newVar = bdd_create_variable(manager);
00118           node->Encode = bdd_and(node->Encode, newVar, 1, 1);
00119         }
00120         node1->Encode = bdd_and(node1->Encode, bdd_not(newVar), 1, 1);
00121       }
00122     }
00123   }
00124 } /* BmcAutEncodeAutomatonStates() */
00125 
00126 
00142 void
00143 BmcAutEncodeAutomatonStates2(
00144   Ntk_Network_t   *network,
00145   Ltl_Automaton_t *automaton)
00146 {
00147   mdd_manager         *manager = Ntk_NetworkReadMddManager(network);
00148   lsGen               lsGen, lsGen1;
00149   vertex_t            *vtx;
00150   Ltl_AutomatonNode_t *node, *node1;
00151   Ctlsp_Formula_t     *F;
00152   mdd_t               *label;
00153   
00154   int                 i;
00155  
00156   /*
00157     Build the mdd for the labels of each automaton node.
00158    */
00159   foreach_vertex(automaton->G, lsGen, vtx) {
00160     node = (Ltl_AutomatonNode_t *) vtx->user_data;
00161     if (node->Labels) {
00162       label =  mdd_one(manager);
00163       for (i=0; i<array_n(automaton->labelTable); i++) {
00164         if (LtlSetGetElt(node->Labels, i)) {
00165           F = array_fetch(Ctlsp_Formula_t *, automaton->labelTable, i); 
00166           label = mdd_and(label, BmcAutBuildMddForPropositionalFormula(network, automaton, F), 1, 1);
00167         }
00168       }
00169       node->Encode = label;
00170     }
00171   }
00172   /*
00173     Three cases:
00174       1- node and node1 are both = 1
00175       2- node1 = 1
00176       3- neither node nor nod1 equal to 1
00177    */
00178   foreach_vertex(automaton->G, lsGen, vtx) {
00179     bdd_t *newVar = NULL;
00180     st_table        *preState, *preState1;
00181    
00182     node = (Ltl_AutomatonNode_t *) vtx->user_data;
00183     preState  = AutomatonVertexGetPreImg(automaton->G, vtx);
00184 
00185     foreach_vertex(automaton->G, lsGen1, vtx) {  
00186       node1 = (Ltl_AutomatonNode_t *) vtx->user_data;
00187       if(node != node1){
00188         if (!mdd_is_tautology(mdd_and(node->Encode, node1->Encode, 1,1),0)){
00189           preState1 = AutomatonVertexGetPreImg(automaton->G, vtx);
00190           if (stIntersect(preState, preState1)){
00191             if(mdd_equal(node->Encode, mdd_one(manager)) && !mdd_equal(node1->Encode, mdd_one(manager))){
00192               node->Encode = bdd_not(node1->Encode);
00193             } else
00194               if(mdd_equal(node1->Encode, mdd_one(manager)) && !mdd_equal(node->Encode, mdd_one(manager))){
00195                 node1->Encode = bdd_not(node->Encode);
00196               } else {
00197                 if(newVar == NULL){
00198                   newVar = bdd_create_variable(manager);
00199                 }
00200                 node1->Encode = bdd_and(node1->Encode, bdd_not(newVar), 1, 1);
00201                 node->Encode = bdd_and(node->Encode, bdd_not(node1->Encode), 1, 1);
00202               }
00203           } else {
00204             if(newVar == NULL){
00205               newVar = bdd_create_variable(manager);
00206               node->Encode = bdd_and(node->Encode, newVar, 1, 1);
00207             }
00208             node1->Encode = bdd_and(node1->Encode,  bdd_not(newVar), 1, 1);
00209           }
00210         }
00211       }
00212     }
00213   }
00214 
00215 #if 0  
00216   /*
00217     Encode the automaton labels
00218    */
00219   foreach_vertex(automaton->G, lsGen, vtx) {
00220     bdd_t               *newVar = NULL;
00221     st_table            *nextStates;
00222     Ltl_AutomatonNode_t *nextState;
00223     st_generator        *stGen;
00224     
00225     node       = (Ltl_AutomatonNode_t *) vtx->user_data;
00226     nextStates = AutomatonVertexGetImg(automaton->G, vtx);
00227     
00228     st_foreach_item(nextStates, stGen, (char **)&vtx, NIL(char *)) {
00229       nextState = (Ltl_AutomatonNode_t *) vtx->user_data;
00230 
00231       if(node != nextState){
00232         if (!mdd_is_tautology(mdd_and(node->Encode, nextState->Encode, 1,1),0)){
00233           printf("n%d intersects n%d\n", node->index, nextState->index);
00234           if(newVar == NULL){
00235             newVar = bdd_create_variable(manager);
00236             /*node->Encode = bdd_and(node->Encode, newVar, 1, 1);*/
00237           }
00238           nextState->Encode = bdd_and(nextState->Encode, bdd_not(newVar), 1, 1);
00239           node->Encode = bdd_and(node->Encode, bdd_not(nextState->Encode), 1, 1);
00240         }
00241       }
00242     }
00243   }
00244 #endif
00245   
00246 } /* BmcAutEncodeAutomatonStates2() */
00247 
00263 void
00264 BmcAutEncodeAutomatonStates3(
00265   Ntk_Network_t   *network,
00266   Ltl_Automaton_t *automaton)
00267 {
00268   mdd_manager         *manager = Ntk_NetworkReadMddManager(network);
00269   lsGen               lsGen;
00270   st_generator        *stGen, *stGen1;
00271   vertex_t            *vtx, *vtx1;
00272   Ltl_AutomatonNode_t *node, *node1;
00273   Ctlsp_Formula_t     *F;
00274   bdd_t               *label;
00275   
00276   int                 i;
00277   int                 noOfStates=0;
00278   int                 noOfBits;
00279   array_t             *varArray = array_alloc(bdd_t*,0);
00280 
00281   /*
00282     Build the bdd for the labels of each automaton node.
00283    */
00284   foreach_vertex(automaton->G, lsGen, vtx) {
00285     node = (Ltl_AutomatonNode_t *) vtx->user_data;
00286     if (node->Labels) {
00287       noOfStates++;
00288       label =  bdd_one(manager);
00289       for (i=0; i<array_n(automaton->labelTable); i++) {
00290         if (LtlSetGetElt(node->Labels, i)) {
00291           F = array_fetch(Ctlsp_Formula_t *, automaton->labelTable, i); 
00292           label = bdd_and(label, BmcAutBuildMddForPropositionalFormula(network, automaton, F), 1, 1);
00293         }
00294       }
00295       node->Encode = label;
00296     }
00297   }
00298 
00299   st_foreach_item(automaton->Init, stGen, &vtx, NULL) {
00300     node = (Ltl_AutomatonNode_t *) vtx->user_data;
00301     st_foreach_item(automaton->Init, stGen1, &vtx1, NULL) {
00302       node1 = (Ltl_AutomatonNode_t *) vtx1->user_data;
00303       if(node != node1){
00304         if(mdd_equal(node->Encode, mdd_one(manager)) && !mdd_equal(node1->Encode, mdd_one(manager))){
00305               node->Encode = bdd_not(node1->Encode);
00306         } else
00307           if(mdd_equal(node1->Encode, mdd_one(manager)) && !mdd_equal(node->Encode, mdd_one(manager))){
00308             node1->Encode = bdd_not(node->Encode);
00309           }
00310       }
00311     }
00312   }
00313 
00314   noOfBits = NoOfBitEncode(noOfStates);
00315   for(i=0; i< noOfBits; i++){ 
00316     array_insert_last(bdd_t*, varArray, bdd_create_variable(manager));
00317   }
00318   i=0;
00319   foreach_vertex(automaton->G, lsGen, vtx) {
00320     node = (Ltl_AutomatonNode_t *) vtx->user_data;
00321     if (node->Labels) {
00322       node->Encode = bdd_and(node->Encode, encodeOfInteger(manager, varArray, i), 1, 1);
00323       i++;
00324     }
00325   }
00326 } /* BmcAutEncodeAutomatonStates3() */
00327 
00328 
00340 void
00341 BmcAutBuildTransitionRelation(
00342   Ntk_Network_t   *network,
00343   Ltl_Automaton_t *automaton)
00344 {
00345   mdd_manager         *manager = Ntk_NetworkReadMddManager(network);
00346   lsGen               lsGen;
00347   st_generator        *stGen;
00348   vertex_t            *vtx, *vtx1;
00349   Ltl_AutomatonNode_t *state, *nextState;
00350  
00351   
00352   
00353   bdd_t               *nextStateBdd, *transitionRelation;
00354   bdd_t               *initialState, *fairSet, *fairState;
00355   int                 i;
00356   bdd_t               *bddVar;
00357   st_table            *nextStates;
00358   var_set_t           *psSupport, *nsSupport;
00359   st_table            *FairSet = 0;
00360   array_t             *fairSetArray;
00361 
00362   /*
00363     psNsTable  (Bdd Id, bdd_t*)
00364    */
00365   st_table            *psNsTable = st_init_table(st_numcmp, st_numhash);
00366   /*
00367     nsPsTable  (BDD Id, BDD Id)
00368    */
00369   st_table            *nsPsTable = st_init_table(st_numcmp, st_numhash);
00370 
00371   boolean             isComplemented;
00372   int                 nodeIndex;
00373   
00374   /*
00375     Initialization
00376    */
00377   transitionRelation = bdd_zero(manager);
00378 
00379   /*
00380     Build the transition relation 
00381    */
00382   foreach_vertex(automaton->G, lsGen, vtx) {
00383     state = (Ltl_AutomatonNode_t *) vtx->user_data;
00384     /*
00385       support is the set of the bddId of the bdd node in the support of the bdd function. 
00386     */
00387     psSupport = bdd_get_support(state->Encode);
00388     for(i=0; i<psSupport->n_elts; i++) {
00389       if (var_set_get_elt(psSupport, i) == 1) {
00390         /*
00391           i is the bdd Id of the variable in the support of the function.
00392         */
00393         if (!st_lookup(psNsTable, (char *)(long) i, NULL)){
00394           bddVar =  bdd_create_variable(manager);
00395           nodeIndex = bdd_node_read_index(bdd_get_node(bddVar, &isComplemented));
00396           st_insert(psNsTable, (char *) (long) i,         (char *) bddVar);
00397           st_insert(nsPsTable, (char *) (long) nodeIndex, (char *) (long)i);
00398         }
00399       }
00400     }
00401     /*
00402       Get the next states.
00403      */
00404     nextStates = AutomatonVertexGetImg(automaton->G, vtx);
00405     st_foreach_item(nextStates, stGen, &vtx1, NULL) {
00406       nextState = (Ltl_AutomatonNode_t *) vtx1->user_data;
00407 
00408       nextStateBdd = bdd_dup(nextState->Encode);
00409       nsSupport = bdd_get_support(nextStateBdd);
00410       for(i=0; i<nsSupport->n_elts; i++) {
00411         if (var_set_get_elt(nsSupport, i) == 1) {
00412           bdd_t *tmp;
00413 
00414           if (!st_lookup(psNsTable, (char *)(long)i, &bddVar)){
00415             bddVar =  bdd_create_variable(manager);
00416             nodeIndex = bdd_node_read_index(bdd_get_node(bddVar, &isComplemented));
00417             st_insert(psNsTable, (char *) (long) i,         (char *) bddVar);
00418             st_insert(nsPsTable, (char *) (long) nodeIndex, (char *) (long)i);
00419           }       
00420           tmp = nextStateBdd;
00421           nextStateBdd = bdd_compose(nextStateBdd, bdd_get_variable(manager, i), bddVar);
00422           bdd_free(tmp);
00423         }
00424       }
00425       transitionRelation = bdd_or(transitionRelation, bdd_and(state->Encode, nextStateBdd,1 ,1) ,1 ,1);
00426       
00427     } /* for each next states*/
00428   } /* for each present state */
00429 
00430   fairSetArray = array_alloc(bdd_t*, 0);
00431   fairSet = 0;
00432   if (lsLength(automaton->Fair) != 0) {
00433     fairSet = bdd_zero(manager);
00434     lsForEachItem(automaton->Fair, lsGen, FairSet) {
00435       fairState = bdd_zero(manager);
00436       st_foreach_item(FairSet, stGen, &vtx, NULL) {
00437         state = (Ltl_AutomatonNode_t *) vtx->user_data;
00438         fairState = bdd_or(fairState, state->Encode,1,1);
00439       }
00440       array_insert_last(bdd_t*, fairSetArray, fairState); 
00441       fairSet = bdd_or(fairSet, fairState,1,1);
00442     }
00443   }
00444   initialState = bdd_zero(manager);
00445   st_foreach_item(automaton->Init, stGen, &vtx, NULL) {
00446     state = (Ltl_AutomatonNode_t *) vtx->user_data;
00447     initialState = bdd_or(initialState, state->Encode, 1, 1);
00448   }
00449   automaton->transitionRelation  = transitionRelation;
00450   automaton->initialStates       = initialState;
00451   automaton->fairSets            = fairSet;
00452   automaton->psNsTable           = psNsTable;
00453   automaton->nsPsTable           = nsPsTable;
00454   automaton->fairSetArray        = fairSetArray;
00455   
00456 } /* BmcAutBuildTransitionRelation() */
00457 
00458 
00471 mdd_t *
00472 BmcAutBuildMddForPropositionalFormula(
00473    Ntk_Network_t   *network,
00474    Ltl_Automaton_t *automaton,
00475    Ctlsp_Formula_t *formula)
00476 {
00477   mdd_manager     *manager = Ntk_NetworkReadMddManager(network);
00478   mdd_t           *left, *right, *result;
00479   
00480 
00481   if (formula == NIL(Ctlsp_Formula_t)) {
00482     return NIL(mdd_t);
00483   }
00484   if (formula->type == Ctlsp_TRUE_c){
00485     return bdd_one(manager);
00486   }
00487   if (formula->type == Ctlsp_FALSE_c){
00488     return  mdd_zero(manager);
00489   }
00490   
00491   if (!Ctlsp_isPropositionalFormula(formula)) {
00492     (void) fprintf(vis_stderr, "bmc error: Only propositional formula can be converted to bdd \n");
00493     fprintf(vis_stdout, "\nFormula: ");
00494     Ctlsp_FormulaPrint(vis_stdout, formula);
00495     fprintf(vis_stdout, "\n");
00496     return NIL(mdd_t);
00497   }
00498   /*
00499     Atomic proposition.
00500    */
00501   if (formula->type == Ctlsp_ID_c){
00502     int       is_complemented;
00503     bdd_node  *funcNode;
00504     
00505     result   =  BmcModelCheckAtomicFormula(Fsm_NetworkReadOrCreateFsm(network), formula);
00506     funcNode = bdd_get_node(result, &is_complemented);
00507     if(is_complemented){
00508       funcNode = bdd_not_bdd_node(funcNode);
00509     }
00510     return result;
00511   }
00512   /*
00513     right can be NIL(mdd_t) for unery operators, but left can't be  NIL(mdd_t)
00514    */
00515   left  = BmcAutBuildMddForPropositionalFormula(network, automaton, formula->left);
00516   if (left == NIL(mdd_t)){
00517     return NIL(mdd_t);
00518   }  
00519   right = BmcAutBuildMddForPropositionalFormula(network, automaton, formula->right);
00520   /*assert(right !=  NIL(mdd_t)); */
00521   switch(formula->type) {
00522     case Ctlsp_NOT_c:
00523       result = mdd_not(left);
00524       break;
00525     case Ctlsp_OR_c:
00526       result = mdd_or(left, right, 1, 1);
00527       break;
00528     case Ctlsp_AND_c:
00529       result = mdd_and(left, right, 1, 1);
00530       break;
00531     case Ctlsp_THEN_c:
00532       result = mdd_or(left, right, 0, 1); 
00533       break;
00534     case Ctlsp_EQ_c:
00535       result = mdd_xnor(left, right);
00536       break;
00537     case Ctlsp_XOR_c:
00538       result = mdd_xor(left, right);
00539       break;
00540   default:
00541     /*
00542       return NIL(mdd_t) if the type is not supported
00543      */
00544     fail("Unexpected type");
00545   }
00546   return result;
00547 }
00548 
00573 int 
00574 BmcAutGenerateCnfForBddOffSet(
00575    bdd_t          *function,
00576    int             current,
00577    int             next,
00578    BmcCnfClauses_t *cnfClauses,
00579    st_table        *nsPsTable)
00580 {
00581   bdd_manager *bddManager = bdd_get_manager(function);
00582   bdd_node    *node, *funcNode;
00583   int         is_complemented;
00584   bdd_gen     *gen;
00585   int         varIndex; 
00586   array_t     *tmpClause;
00587   array_t     *cube;
00588   int         i, value;
00589   int         state = current;
00590   bdd_t       *bddFunction;
00591   bdd_t       *newVar;
00592 
00593   int         total=0, ndc=0;
00594   float       per;
00595 
00596   if (function == NULL){
00597     return 0;
00598   }
00599  
00600   funcNode = bdd_get_node(function, &is_complemented);
00601  
00602   if (bdd_is_constant(funcNode)){
00603     if (is_complemented){
00604       /* add an empty clause to indicate FALSE (un-satisfiable)*/
00605       BmcAddEmptyClause(cnfClauses);
00606     }
00607     /*bdd_free(bddFunction);
00608       bdd_free(newVar);*/
00609     return 0;
00610   }
00611 
00612   newVar = bdd_create_variable(bddManager);
00613   bddFunction = bdd_xnor(newVar, function);
00614   bddFunction = bdd_not(bddFunction);
00615 
00616   foreach_bdd_cube(bddFunction, gen, cube){
00617     tmpClause = array_alloc(int,0);
00618     arrayForEachItem(int, cube, i, value) {
00619       total++;
00620       if (value != 2){
00621         int j;
00622 
00623         ndc++;
00624         /*
00625           If the BDD varaible is a next state varaible, we use the corresponding
00626           current state varaible but with next state index.
00627          */
00628         
00629         if (nsPsTable && st_lookup_int(nsPsTable, (char *)(long)i, &j)){
00630           node = bdd_bdd_ith_var(bddManager, j);
00631           state = next;
00632         } else {
00633           node = bdd_bdd_ith_var(bddManager, i);
00634           state = current;
00635         }
00636         varIndex  = BmcGetCnfVarIndexForBddNode(bddManager, bdd_regular(node), state, cnfClauses);
00637         if (value == 1){
00638           varIndex = -varIndex; 
00639         }
00640         array_insert_last(int, tmpClause, varIndex);
00641       }
00642     }
00643     BmcCnfInsertClause(cnfClauses, tmpClause);
00644     array_free(tmpClause);
00645   }/* foreach_bdd_cube() */
00646   varIndex  = BmcGetCnfVarIndexForBddNode(bddManager,
00647                                        bdd_regular(bdd_get_node(newVar, &is_complemented)),
00648                                        current, cnfClauses);
00649   per = ((float) ((float)ndc/(float)total))*100; 
00650   return (varIndex);
00651 } /* BmcAutGenerateCnfForBddOffSet() */
00652 
00653 
00662 BmcCheckForTermination_t *
00663 BmcAutTerminationAlloc(
00664   Ntk_Network_t   *network,
00665   Ctlsp_Formula_t *ltlFormula,
00666   array_t         *constraintArray)
00667 {
00668   BmcCheckForTermination_t  *result = ALLOC(BmcCheckForTermination_t, 1);
00669   Ltl_Automaton_t           *automaton;
00670   LtlMcOption_t             *ltlOptions = LtlMcOptionAlloc();
00671   
00672   if (!result){
00673     return result;
00674   }
00675   /*
00676     Build the Buechi Automaton for the negation of the LTL formula.
00677   */
00678   ltlOptions->algorithm    = Ltl2Aut_WRING_c;
00679   ltlOptions->rewriting    = TRUE;
00680   ltlOptions->prunefair    = TRUE;
00681   ltlOptions->iocompatible = TRUE;
00682   ltlOptions->directsim    = TRUE;
00683   ltlOptions->reversesim   = TRUE;
00684   ltlOptions->verbosity    = McVerbosityNone_c;
00685   ltlOptions->noStrengthReduction = 1;
00686   
00687   automaton  = LtlMcFormulaToAutomaton(network, ltlFormula, ltlOptions, 0);
00688   assert(automaton != NIL(Ltl_Automaton_t));
00689   
00690   /*BmcAutEncodeAutomatonStates(network, automaton); */
00691   /*mcAutEncodeAutomatonStates2(network, automaton);*/
00692   BmcAutEncodeAutomatonStates3(network, automaton);
00693   BmcAutBuildTransitionRelation(network, automaton);
00694     
00695   LtlMcOptionFree(ltlOptions);
00696 
00697   result->k = 0;
00698   result->m = -1;
00699   result->n = -1;
00700   result->checkLevel = 0;
00701   result->action = 0;
00702   result->automaton = automaton;
00703 
00704   result->externalConstraints  = NIL(Ctlsp_Formula_t);
00705   if(constraintArray != NIL(array_t)){
00706     Ctlsp_Formula_t *formula1, *formula2;
00707     int              j;
00708     
00709     formula1 = NIL(Ctlsp_Formula_t);
00710     arrayForEachItem(Ctlsp_Formula_t *, constraintArray, j, formula2) {
00711       formula2 = Ctlsp_FormulaDup(formula2);
00712       if(formula1 == NIL(Ctlsp_Formula_t)) {
00713         formula1 = formula2;
00714       } else {
00715         formula1 =  Ctlsp_FormulaCreate(Ctlsp_OR_c, formula1, formula2);
00716       }
00717     }
00718     result->externalConstraints = formula1;
00719   }
00720   result->internalConstraints = automaton->fairSets;
00721   return result;
00722 }
00723 
00733 Ltl_Automaton_t *
00734 BmcAutLtlToAutomaton(
00735   Ntk_Network_t   *network,
00736   Ctlsp_Formula_t *ltlFormula)
00737 {
00738   Ltl_Automaton_t  *automaton;
00739   LtlMcOption_t    *ltlOptions = LtlMcOptionAlloc();
00740   
00741   /*
00742     Build the Buechi Automaton for the negation of the LTL formula.
00743   */
00744   ltlOptions->algorithm    = Ltl2Aut_WRING_c;
00745   ltlOptions->rewriting    = TRUE;
00746   ltlOptions->prunefair    = TRUE;
00747   ltlOptions->iocompatible = TRUE;
00748   ltlOptions->directsim    = TRUE;
00749   ltlOptions->reversesim   = TRUE;
00750   ltlOptions->verbosity    = McVerbosityNone_c;
00751   ltlOptions->noStrengthReduction = 1;
00752   
00753   automaton  = LtlMcFormulaToAutomaton(network, ltlFormula, ltlOptions, 0);
00754   assert(automaton != NIL(Ltl_Automaton_t));
00755  
00756   return automaton;
00757 }
00758 
00759 
00768 void
00769 BmcAutTerminationFree(
00770   BmcCheckForTermination_t *result)
00771 {
00772   LtlTableau_t    *tableau;
00773   Ltl_Automaton_t *automaton = result->automaton;
00774     
00775   tableau = automaton->tableau; 
00776   Ltl_AutomatonFree((gGeneric) automaton);
00777   LtlTableauFree(tableau);
00778   if(result->externalConstraints  != NIL(Ctlsp_Formula_t)){
00779     Ctlsp_FormulaFree(result->externalConstraints);
00780   }
00781   
00782   FREE(result);
00783 }
00784 
00785 
00786 /*---------------------------------------------------------------------------*/
00787 /* Definition of static functions                                            */
00788 /*---------------------------------------------------------------------------*/
00789 
00797 static st_table *
00798 AutomatonVertexGetImg(
00799   graph_t *G,
00800   vertex_t *vtx)
00801 {
00802   lsList Img;
00803   lsGen lsgen;
00804   edge_t *e;
00805   vertex_t *s;
00806   st_table *uTable;
00807 
00808   Img = g_get_out_edges(vtx);
00809 
00810   uTable = st_init_table(st_ptrcmp, st_ptrhash);
00811   lsForEachItem(Img, lsgen, e) {
00812     s = g_e_dest(e);
00813     st_insert(uTable, (char *) s, (char *) s);
00814   }
00815 
00816   return uTable;
00817 }
00818 
00826 static st_table *
00827 AutomatonVertexGetPreImg(
00828   graph_t *G,
00829   vertex_t *vtx)
00830 {
00831   lsList preImg;
00832   lsGen lsgen;
00833   edge_t *e;
00834   vertex_t *s;
00835   st_table *uTable;
00836 
00837   preImg = g_get_in_edges(vtx);
00838 
00839   uTable = st_init_table(st_ptrcmp, st_ptrhash);
00840   lsForEachItem(preImg, lsgen,  e) {
00841     s = g_e_source(e);
00842     st_insert(uTable, (char *) s, (char *) s);
00843   }
00844   
00845   return uTable;
00846 }
00847 
00855 static int
00856 stIntersect(
00857   st_table *tbl1,
00858   st_table *tbl2)
00859 {
00860   st_generator *stgen;
00861   vertex_t *vtx;
00862 
00863   st_foreach_item(tbl1, stgen, &vtx, NULL) {
00864     if (st_is_member(tbl2,(char *)vtx)) {
00865       st_free_gen(stgen);
00866       return 1;
00867     }
00868   }
00869   return 0;
00870 }
00871 
00883 static int
00884 NoOfBitEncode(
00885    int n)
00886 {
00887     int i = 0;
00888     int j = 1;
00889 
00890     if (n < 2) return 1; /* Takes care of value <= 1 */
00891 
00892     while (j < n) {
00893         j = j * 2;
00894         i++;
00895     }
00896     return i;
00897 }
00898 
00910 static bdd_t *
00911 encodeOfInteger(
00912   mdd_manager *manager,
00913   array_t *varArray,
00914   int val)
00915 {
00916   int i;
00917   bdd_t *returnValue =  mdd_one(manager);
00918   int tmp = val;
00919   bdd_t  *var;
00920 
00921   for(i=0; i< array_n(varArray); i++){
00922     var = array_fetch(bdd_t*, varArray, i);
00923     if(tmp%2 == 0){
00924       returnValue = bdd_and(returnValue, var, 1, 0); 
00925     } else {
00926       returnValue = bdd_and(returnValue, var, 1, 1);
00927     }
00928     tmp = tmp / 2;
00929   }
00930   return returnValue;
00931 }
00932