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