VIS
|
00001 00017 #include "bmcInt.h" 00018 #include "sat.h" 00019 #include "baig.h" 00020 00021 static char rcsid[] UNUSED = "$Id: bmcUtil.c,v 1.82 2010/04/10 04:07:06 fabio Exp $"; 00022 00023 /*---------------------------------------------------------------------------*/ 00024 /* Constant declarations */ 00025 /*---------------------------------------------------------------------------*/ 00026 00027 #define MAX_LENGTH 320 /* Max. length of a string while reading a file */ 00028 00029 /*---------------------------------------------------------------------------*/ 00030 /* Type declarations */ 00031 /*---------------------------------------------------------------------------*/ 00032 00033 00034 /*---------------------------------------------------------------------------*/ 00035 /* Structure declarations */ 00036 /*---------------------------------------------------------------------------*/ 00037 00038 00039 /*---------------------------------------------------------------------------*/ 00040 /* Variable declarations */ 00041 /*---------------------------------------------------------------------------*/ 00042 00043 00046 /*---------------------------------------------------------------------------*/ 00047 /* Static function prototypes */ 00048 /*---------------------------------------------------------------------------*/ 00049 00050 static int StringCheckIsInteger(char *string, int *value); 00051 static int nameCompare(const void * name1, const void * name2); 00052 static void printValue(mAig_Manager_t *manager, Ntk_Network_t *network, st_table *nodeToMvfAigTable, BmcCnfClauses_t *cnfClauses, array_t *varNames, st_table *resultTable, int state, int *prevValue); 00053 static void printValueAiger(mAig_Manager_t *manager, Ntk_Network_t *network, st_table *nodeToMvfAigTable, BmcCnfClauses_t *cnfClauses, array_t *varNames, st_table *resultTable, int state, int *prevValue); 00054 static void printValueAigerInputs(mAig_Manager_t *manager, Ntk_Network_t *network, st_table *nodeToMvfAigTable, BmcCnfClauses_t *cnfClauses, array_t *varNames, st_table *resultTable, int state, int *prevValue); 00055 00058 /*---------------------------------------------------------------------------*/ 00059 /* Definition of exported functions */ 00060 /*---------------------------------------------------------------------------*/ 00061 00062 00070 mdd_t * 00071 Bmc_ComputeCloseCube( 00072 mdd_t *states, 00073 mdd_t *target, 00074 int *dist, 00075 Fsm_Fsm_t *modelFsm) 00076 { 00077 array_t *PSVars = Fsm_FsmReadPresentStateVars( modelFsm ); 00078 mdd_manager *mddMgr = Ntk_NetworkReadMddManager( Fsm_FsmReadNetwork( modelFsm ) ); 00079 mdd_t *result = BmcComputeCloseCube( states, target, dist, PSVars, mddMgr ); 00080 00081 return result; 00082 } 00083 00092 MvfAig_Function_t * 00093 Bmc_NodeBuildMVF( 00094 Ntk_Network_t *network, 00095 Ntk_Node_t *node) 00096 { 00097 MvfAig_Function_t * MvfAig; 00098 lsGen tmpGen; 00099 Ntk_Node_t *tmpNode; 00100 array_t *mvfArray; 00101 array_t *tmpRoots = array_alloc(Ntk_Node_t *, 0); 00102 st_table *tmpLeaves = st_init_table(st_ptrcmp, st_ptrhash); 00103 array_insert_last(Ntk_Node_t *, tmpRoots, node); 00104 00105 Ntk_NetworkForEachCombInput(network, tmpGen, tmpNode) { 00106 st_insert(tmpLeaves, (char *) tmpNode, (char *) ntmaig_UNUSED); 00107 } 00108 00109 mvfArray = ntmaig_NetworkBuildMvfAigs(network, tmpRoots, tmpLeaves); 00110 MvfAig = array_fetch(MvfAig_Function_t *, mvfArray, 0); 00111 array_free(tmpRoots); 00112 st_free_table(tmpLeaves); 00113 array_free(mvfArray); 00114 return MvfAig; 00115 } 00116 00117 00126 MvfAig_Function_t * 00127 Bmc_ReadMvfAig( 00128 Ntk_Node_t * node, 00129 st_table * nodeToMvfAigTable) 00130 { 00131 MvfAig_Function_t *result; 00132 if (st_lookup(nodeToMvfAigTable, node, &result)){ 00133 return result; 00134 } 00135 return NIL(MvfAig_Function_t); 00136 } 00137 00138 00139 /*---------------------------------------------------------------------------*/ 00140 /* Definition of internal functions */ 00141 /*---------------------------------------------------------------------------*/ 00142 00152 mdd_t * 00153 BmcFsmEvaluateX( 00154 Fsm_Fsm_t *modelFsm, 00155 mdd_t *targetMdd) 00156 { 00157 mdd_t *fromLowerBound; 00158 mdd_t *fromUpperBound; 00159 mdd_t *result; 00160 Img_ImageInfo_t * imageInfo; 00161 mdd_t *careStates; 00162 array_t *careStatesArray = array_alloc(array_t *, 0); 00163 00164 imageInfo = Fsm_FsmReadOrCreateImageInfo(modelFsm, 1, 0); 00165 00166 /* 00167 * The lower bound is the conjunction of the fair states, 00168 * and the target states. 00169 */ 00170 fromLowerBound = mdd_dup(targetMdd); 00171 /* 00172 * The upper bound is the same as the lower bound. 00173 */ 00174 fromUpperBound = mdd_dup(fromLowerBound); 00175 /* 00176 careSet is the set of all unreachabel states. 00177 */ 00178 careStates = mdd_one(Fsm_FsmReadMddManager(modelFsm)); 00179 array_insert(mdd_t *, careStatesArray, 0, careStates); 00180 00181 result = Img_ImageInfoComputePreImageWithDomainVars(imageInfo, 00182 fromLowerBound, fromUpperBound, careStatesArray); 00183 mdd_free(fromLowerBound); 00184 mdd_free(fromUpperBound); 00185 00186 return result; 00187 00188 } /* BmcFsmEvaluateX */ 00189 00190 00201 mdd_t * 00202 BmcComputeCloseCube( 00203 mdd_t *aSet, 00204 mdd_t *target, 00205 int *dist, 00206 array_t *Support, 00207 mdd_manager *mddMgr) 00208 { 00209 if (bdd_get_package_name() == CUDD && target != NIL(mdd_t)) { 00210 mdd_t *range; /* range of Support */ 00211 mdd_t *legalSet; /* aSet without the don't cares */ 00212 mdd_t *closeCube; 00213 00214 00215 /* Check that support of set is contained in Support. 00216 assert(SetCheckSupport(aSet, Support, mddMgr)); */ 00217 assert(!mdd_is_tautology(aSet, 0)); 00218 range = mdd_range_mdd(mddMgr, Support); 00219 legalSet = bdd_and(aSet, range, 1, 1); 00220 mdd_free(range); 00221 closeCube = mdd_closest_cube(legalSet, target, dist); 00222 00223 mdd_free(legalSet); 00224 00225 return closeCube; 00226 } else { 00227 return aSet; 00228 /*return BMC_ComputeAMinterm(aSet, Support, mddMgr);*/ 00229 }/* if CUDD */ 00230 00231 } /* BmcComputeCloseCube */ 00232 00233 00252 mAigEdge_t 00253 BmcCreateMaigOfInitialStates( 00254 Ntk_Network_t *network, 00255 st_table *nodeToMvfAigTable, 00256 st_table *CoiTable) 00257 { 00258 mAig_Manager_t *manager = Ntk_NetworkReadMAigManager(network); 00259 st_generator *stGen; 00260 00261 Ntk_Node_t *latch, *latchInit; 00262 MvfAig_Function_t *initMvfAig, *latchMvfAig; 00263 00264 bAigEdge_t resultAnd = bAig_One; 00265 bAigEdge_t resultOr; 00266 int i; 00267 00268 st_foreach_item(CoiTable, stGen, &latch, NULL) { 00269 00270 00271 latchInit = Ntk_LatchReadInitialInput(latch); 00272 00273 /* Get the multi-valued function for each node*/ 00274 initMvfAig = Bmc_ReadMvfAig(latchInit, nodeToMvfAigTable); 00275 if (initMvfAig == NIL(MvfAig_Function_t)){ 00276 (void) fprintf(vis_stdout, "No multi-valued function for this node %s \n", Ntk_NodeReadName(latchInit)); 00277 return bAig_NULL; 00278 } 00279 latchMvfAig = Bmc_ReadMvfAig(latch, nodeToMvfAigTable); 00280 if (latchMvfAig == NIL(MvfAig_Function_t)){ 00281 latchMvfAig = Bmc_NodeBuildMVF(network, latch); 00282 array_free(latchMvfAig); 00283 latchMvfAig = Bmc_ReadMvfAig(latch, nodeToMvfAigTable); 00284 } 00285 resultOr = bAig_Zero; 00286 for(i=0; i<array_n(initMvfAig); i++){ 00287 resultOr = mAig_Or(manager, resultOr, 00288 bAig_Eq(manager, 00289 bAig_GetCanonical(manager, MvfAig_FunctionReadComponent(initMvfAig, i)), 00290 bAig_GetCanonical(manager, MvfAig_FunctionReadComponent(latchMvfAig, i)) 00291 ) 00292 ); 00293 if(resultOr == bAig_One){ 00294 break; 00295 } 00296 } 00297 resultAnd = mAig_And(manager, resultAnd, resultOr); 00298 if(resultAnd == bAig_Zero){ 00299 break; 00300 } 00301 }/* for each latch*/ 00302 00303 return resultAnd; 00304 } 00305 00306 00321 mAigEdge_t 00322 BmcCreateMaigOfPropFormula( 00323 Ntk_Network_t *network, 00324 mAig_Manager_t *manager, 00325 Ctlsp_Formula_t *formula) 00326 { 00327 mAigEdge_t left, right, result; 00328 00329 if (formula == NIL(Ctlsp_Formula_t)) { 00330 return mAig_NULL; 00331 } 00332 if (formula->type == Ctlsp_TRUE_c){ 00333 return mAig_One; 00334 } 00335 if (formula->type == Ctlsp_FALSE_c){ 00336 return mAig_Zero; 00337 } 00338 00339 assert(Ctlsp_isPropositionalFormula(formula)); 00340 00341 if (formula->type == Ctlsp_ID_c){ 00342 char *nodeNameString = Ctlsp_FormulaReadVariableName(formula); 00343 char *nodeValueString = Ctlsp_FormulaReadValueName(formula); 00344 Ntk_Node_t *node = Ntk_NetworkFindNodeByName(network, nodeNameString); 00345 00346 Var_Variable_t *nodeVar; 00347 int nodeValue; 00348 00349 MvfAig_Function_t *tmpMvfAig; 00350 st_table *nodeToMvfAigTable; /* maps each node to its mvfAig */ 00351 00352 if (node == NIL(Ntk_Node_t)) { 00353 (void) fprintf(vis_stderr, "bmc error: Could not find node corresponding to the name\t %s\n", nodeNameString); 00354 return mAig_NULL; 00355 } 00356 nodeToMvfAigTable = (st_table *) Ntk_NetworkReadApplInfo(network, MVFAIG_NETWORK_APPL_KEY); 00357 if (nodeToMvfAigTable == NIL(st_table)){ 00358 (void) fprintf(vis_stderr, "bmc error: please run build_partiton_maigs first"); 00359 return mAig_NULL; 00360 } 00361 tmpMvfAig = Bmc_ReadMvfAig(node, nodeToMvfAigTable); 00362 if (tmpMvfAig == NIL(MvfAig_Function_t)){ 00363 tmpMvfAig = Bmc_NodeBuildMVF(network, node); 00364 array_free(tmpMvfAig); 00365 tmpMvfAig = Bmc_ReadMvfAig(node, nodeToMvfAigTable); 00366 } 00367 nodeVar = Ntk_NodeReadVariable(node); 00368 if (Var_VariableTestIsSymbolic(nodeVar)) { 00369 nodeValue = Var_VariableReadIndexFromSymbolicValue(nodeVar, nodeValueString); 00370 if ( nodeValue == -1 ) { 00371 (void) fprintf(vis_stderr, "Value specified in RHS is not in domain of variable\n"); 00372 (void) fprintf(vis_stderr,"%s = %s\n", nodeNameString, nodeValueString); 00373 return mAig_NULL; 00374 } 00375 } 00376 else { 00377 int check; 00378 check = StringCheckIsInteger(nodeValueString, &nodeValue); 00379 if( check == 0 ) { 00380 (void) fprintf(vis_stderr,"Illegal value in the RHS\n"); 00381 (void) fprintf(vis_stderr,"%s = %s\n", nodeNameString, nodeValueString); 00382 return mAig_NULL; 00383 } 00384 if( check == 1 ) { 00385 (void) fprintf(vis_stderr,"Value in the RHS is out of range of int\n"); 00386 (void) fprintf(vis_stderr,"%s = %s", nodeNameString, nodeValueString); 00387 return mAig_NULL; 00388 } 00389 if ( !(Var_VariableTestIsValueInRange(nodeVar, nodeValue))) { 00390 (void) fprintf(vis_stderr,"Value specified in RHS is not in domain of variable\n"); 00391 (void) fprintf(vis_stderr,"%s = %s\n", nodeNameString, nodeValueString); 00392 return mAig_NULL; 00393 00394 } 00395 } 00396 result = MvfAig_FunctionReadComponent(tmpMvfAig, nodeValue); 00397 return bAig_GetCanonical(manager, result); 00398 } 00399 /* 00400 right can be mAig_NULL for unery operators, but left can't be mAig_Null 00401 */ 00402 left = BmcCreateMaigOfPropFormula(network, manager, formula->left); 00403 if (left == mAig_NULL){ 00404 return mAig_NULL; 00405 } 00406 right = BmcCreateMaigOfPropFormula(network, manager, formula->right); 00407 00408 switch(formula->type) { 00409 case Ctlsp_NOT_c: 00410 result = mAig_Not(left); 00411 break; 00412 case Ctlsp_OR_c: 00413 result = mAig_Or(manager, left, right); 00414 break; 00415 case Ctlsp_AND_c: 00416 result = mAig_And(manager, left, right); 00417 break; 00418 case Ctlsp_THEN_c: 00419 result = mAig_Then(manager, left, right); 00420 break; 00421 case Ctlsp_EQ_c: 00422 result = mAig_Eq(manager, left, right); 00423 break; 00424 case Ctlsp_XOR_c: 00425 result = mAig_Xor(manager, left, right); 00426 break; 00427 default: 00428 fail("Unexpected LTL type"); 00429 } 00430 return result; 00431 } /* BmcCreateMaigOfPropFormula */ 00432 00446 mdd_t * 00447 BmcCreateMddOfSafetyProperty( 00448 Fsm_Fsm_t *fsm, 00449 Ctlsp_Formula_t *formula) 00450 { 00451 00452 mdd_manager *manager = Ntk_NetworkReadMddManager(Fsm_FsmReadNetwork(fsm)); 00453 mdd_t *left, *right, *result; 00454 00455 if (formula == NIL(Ctlsp_Formula_t)) { 00456 return NIL(mdd_t); 00457 } 00458 if (formula->type == Ctlsp_TRUE_c){ 00459 return bdd_one(manager); 00460 } 00461 if (formula->type == Ctlsp_FALSE_c){ 00462 return mdd_zero(manager); 00463 } 00464 00465 #if 0 00466 if (!Ctlsp_isPropositionalFormula(formula)) { 00467 (void) fprintf(vis_stderr, "bmc error: Only propositional formula can be converted to bdd \n"); 00468 fprintf(vis_stdout, "\nFormula: "); 00469 Ctlsp_FormulaPrint(vis_stdout, formula); 00470 fprintf(vis_stdout, "\n"); 00471 return NIL(mdd_t); 00472 } 00473 #endif 00474 /* 00475 Atomic proposition. 00476 */ 00477 if (formula->type == Ctlsp_ID_c){ 00478 return BmcModelCheckAtomicFormula(fsm, formula); 00479 } 00480 /* 00481 right can be NIL(mdd_t) for unery operators, but left can't be NIL(mdd_t) 00482 */ 00483 left = BmcCreateMddOfSafetyProperty(fsm, formula->left); 00484 if (left == NIL(mdd_t)){ 00485 return NIL(mdd_t); 00486 } 00487 right = BmcCreateMddOfSafetyProperty(fsm, formula->right); 00488 assert(right != NIL(mdd_t)); 00489 switch(formula->type) { 00490 case Ctlsp_NOT_c: 00491 result = mdd_not(left); 00492 break; 00493 case Ctlsp_OR_c: 00494 result = mdd_or(left, right, 1, 1); 00495 break; 00496 case Ctlsp_AND_c: 00497 result = mdd_and(left, right, 1, 1); 00498 break; 00499 case Ctlsp_THEN_c: 00500 result = mdd_or(left, right, 0, 1); 00501 break; 00502 case Ctlsp_EQ_c: 00503 result = mdd_xnor(left, right); 00504 break; 00505 case Ctlsp_XOR_c: 00506 result = mdd_xor(left, right); 00507 break; 00508 case Ctlsp_X_c: 00509 result = BmcFsmEvaluateX(fsm, left); 00510 break; 00511 default: 00512 /* 00513 return NIL(mdd_t) if the type is not supported 00514 */ 00515 return NIL(mdd_t); 00516 /* 00517 fail("Unexpected type"); 00518 */ 00519 } 00520 return result; 00521 } 00522 00523 00542 int 00543 BmcGenerateCnfFormulaForAigFunction( 00544 bAig_Manager_t *manager, 00545 bAigEdge_t node, 00546 int k, 00547 BmcCnfClauses_t *cnfClauses) 00548 { 00549 int leftIndex, rightIndex, nodeIndex; 00550 array_t *clause; 00551 00552 assert( (node != bAig_One) && (node != bAig_Zero)); 00553 00554 if(bAig_IsInverted(node)){ 00555 /* 00556 The generated clauses are in dimacs formate that uses negative number to indicate complement 00557 */ 00558 return -1*BmcGenerateCnfFormulaForAigFunction(manager, bAig_NonInvertedEdge(node), k, cnfClauses); 00559 } 00560 if (BmcCnfReadOrInsertNode(cnfClauses, bAig_NodeReadName(manager, node), k, &nodeIndex)){ 00561 return nodeIndex; 00562 } 00563 if (bAig_isVarNode(manager, node)){ 00564 return nodeIndex; 00565 } 00566 leftIndex = BmcGenerateCnfFormulaForAigFunction(manager, 00567 bAig_GetCanonical(manager, leftChild(node)), 00568 k, cnfClauses); 00569 rightIndex = BmcGenerateCnfFormulaForAigFunction(manager, 00570 bAig_GetCanonical(manager, rightChild(node)), 00571 k, cnfClauses); 00572 clause = array_alloc(int, 3); 00573 array_insert(int, clause, 0, -leftIndex ); 00574 array_insert(int, clause, 1, -rightIndex); 00575 array_insert(int, clause, 2, nodeIndex ); 00576 BmcCnfInsertClause(cnfClauses, clause); 00577 array_free(clause); 00578 00579 clause = array_alloc(int, 2); 00580 array_insert(int, clause, 0, leftIndex); 00581 array_insert(int, clause, 1, -nodeIndex); 00582 BmcCnfInsertClause(cnfClauses, clause); 00583 array_free(clause); 00584 00585 clause = array_alloc(int, 2); 00586 array_insert(int, clause, 0, rightIndex); 00587 array_insert(int, clause, 1, -nodeIndex); 00588 BmcCnfInsertClause(cnfClauses, clause); 00589 array_free(clause); 00590 00591 return(nodeIndex); 00592 } 00593 00623 int 00624 BmcGenerateCnfFormulaForBdd( 00625 bdd_t *bddFunction, 00626 int k, 00627 BmcCnfClauses_t *cnfClauses) 00628 { 00629 bdd_manager *bddManager = bdd_get_manager(bddFunction); 00630 bdd_node *node, *thenNode, *elseNode, *funcNode; 00631 int is_complemented; 00632 int nodeIndex=0, thenIndex, elseIndex; 00633 bdd_gen *gen; 00634 int varIndex, flag; 00635 array_t *tmpClause; 00636 00637 st_table *bddToCnfIndexTable; 00638 00639 bdd_t *currentBddNode; 00640 int cut = 5; 00641 00642 if (bddFunction == NULL){ 00643 return 0; 00644 } 00645 funcNode = bdd_get_node(bddFunction, &is_complemented); 00646 if (bdd_is_constant(funcNode)){ 00647 if (is_complemented){ 00648 /* add an empty clause to indicate FALSE (un-satisfiable)*/ 00649 BmcAddEmptyClause(cnfClauses); 00650 } 00651 return 0; 00652 } 00653 if(bdd_size(bddFunction) <= cut){ 00654 return BmcGenerateCnfFormulaForBddOffSet(bddFunction, k, cnfClauses); 00655 } 00656 00657 bddToCnfIndexTable = st_init_table(st_numcmp, st_numhash); 00658 foreach_bdd_node(bddFunction, gen, node){ 00659 if (bdd_is_constant(node)){ /* do nothing */ 00660 continue; 00661 } 00662 00663 /* 00664 bdd_size() returns 1 if bdd is constant one. 00665 */ 00666 /* 00667 Use offset method to generate CNF if the size of the node <= cut (include the constant 1 node). 00668 */ 00669 /*#if 0*/ 00670 if(bdd_size(currentBddNode = bdd_construct_bdd_t(bddManager, bdd_regular(node))) <= cut){ 00671 if (bdd_size(currentBddNode) == cut){ 00672 nodeIndex = BmcGenerateCnfFormulaForBddOffSet(currentBddNode, k, cnfClauses); 00673 st_insert(bddToCnfIndexTable, (char *) (long) bdd_regular(node), (char *) (long)nodeIndex); 00674 continue; 00675 } 00676 continue; 00677 } 00678 /*#endif*/ 00679 varIndex = BmcGetCnfVarIndexForBddNode(bddManager, bdd_regular(node), k, cnfClauses); 00680 nodeIndex = varIndex; 00681 00682 thenNode = bdd_bdd_T(node); 00683 elseNode = bdd_bdd_E(node); 00684 00685 if (!((bdd_is_constant(thenNode)) && (bdd_is_constant(elseNode)))){ 00686 nodeIndex = cnfClauses->cnfGlobalIndex++; /* index of the function of this node */ 00687 00688 if (bdd_is_constant(thenNode)){ /* the thenNode can be only constant one*/ 00689 flag = st_lookup_int(bddToCnfIndexTable, bdd_regular(elseNode), &elseIndex); 00690 assert(flag); 00691 /* 00692 test if the elseNode is complemented arc? 00693 */ 00694 if (bdd_is_complement(elseNode)){ 00695 elseIndex = -1*elseIndex; 00696 } 00697 BmcCnfGenerateClausesForOR(elseIndex, varIndex, nodeIndex, cnfClauses); 00698 } else if (bdd_is_constant(elseNode)){ /* one or zero */ 00699 flag = st_lookup_int(bddToCnfIndexTable, bdd_regular(thenNode), &thenIndex); 00700 assert(flag); 00701 /* 00702 test if the elseNode is complemented arc? 00703 */ 00704 if (bdd_is_complement(elseNode)){ /* Constant zero */ 00705 BmcCnfGenerateClausesForAND(thenIndex, varIndex, nodeIndex, cnfClauses); 00706 } else { /* Constant one */ 00707 BmcCnfGenerateClausesForOR(thenIndex, -varIndex, nodeIndex, cnfClauses); 00708 } 00709 } else { 00710 flag = st_lookup_int(bddToCnfIndexTable, bdd_regular(thenNode), &thenIndex); 00711 if(flag == 0){ 00712 thenIndex = BmcGenerateCnfFormulaForBddOffSet(bdd_construct_bdd_t(bddManager, bdd_regular(thenNode)), k, cnfClauses); 00713 st_insert(bddToCnfIndexTable, (char *) (long) bdd_regular(thenNode), (char *) (long)thenIndex); 00714 } 00715 /*assert(flag);*/ 00716 00717 flag = st_lookup_int(bddToCnfIndexTable, bdd_regular(elseNode), &elseIndex); 00718 if(flag == 0){ 00719 elseIndex = BmcGenerateCnfFormulaForBddOffSet( bdd_construct_bdd_t(bddManager, bdd_regular(elseNode)), k, cnfClauses); 00720 st_insert(bddToCnfIndexTable, (char *) (long) bdd_regular(elseNode), (char *)(long) elseIndex); 00721 } 00722 /*assert(flag);*/ 00723 /* 00724 test if the elseNode is complemented arc? 00725 */ 00726 if (bdd_is_complement(elseNode)){ 00727 elseIndex = -1*elseIndex; 00728 } 00729 tmpClause = array_alloc(int, 3); 00730 00731 assert(abs(thenIndex) <= cnfClauses->cnfGlobalIndex); 00732 assert(abs(varIndex) <= cnfClauses->cnfGlobalIndex); 00733 assert(abs(nodeIndex) <= cnfClauses->cnfGlobalIndex); 00734 00735 array_insert(int, tmpClause, 0, -thenIndex); 00736 array_insert(int, tmpClause, 1, -varIndex); 00737 array_insert(int, tmpClause, 2, nodeIndex); 00738 BmcCnfInsertClause(cnfClauses, tmpClause); 00739 00740 array_insert(int, tmpClause, 0, thenIndex); 00741 array_insert(int, tmpClause, 1, -varIndex); 00742 array_insert(int, tmpClause, 2, -nodeIndex); 00743 BmcCnfInsertClause(cnfClauses, tmpClause); 00744 00745 array_insert(int, tmpClause, 0, -elseIndex); 00746 array_insert(int, tmpClause, 1, varIndex); 00747 array_insert(int, tmpClause, 2, nodeIndex); 00748 BmcCnfInsertClause(cnfClauses, tmpClause); 00749 00750 array_insert(int, tmpClause, 0, elseIndex); 00751 array_insert(int, tmpClause, 1, varIndex); 00752 array_insert(int, tmpClause, 2, -nodeIndex); 00753 BmcCnfInsertClause(cnfClauses, tmpClause); 00754 00755 array_free(tmpClause); 00756 } 00757 } 00758 st_insert(bddToCnfIndexTable, (char *) (long) bdd_regular(node), (char *) (long) nodeIndex); 00759 } /* foreach_bdd_node() */ 00760 st_free_table(bddToCnfIndexTable); 00761 return (is_complemented? -nodeIndex: nodeIndex); 00762 } /* BmcGenerateCnfFormulaForBdd() */ 00763 00764 00765 00780 int 00781 BmcGenerateCnfFormulaForBddOffSet( 00782 bdd_t *bddFunction, 00783 int k, 00784 BmcCnfClauses_t *cnfClauses) 00785 { 00786 bdd_manager *bddManager = bdd_get_manager(bddFunction); 00787 bdd_node *node, *funcNode; 00788 int is_complemented; 00789 bdd_gen *gen; 00790 int varIndex; 00791 array_t *tmpClause; 00792 array_t *cube; 00793 int i, value; 00794 bdd_t *newVar; 00795 00796 if (bddFunction == NULL){ 00797 return 0; 00798 } 00799 /* 00800 Because the top node of bddFunction represents a variable in 00801 bddFunction, newVar is used to represent the function of 00802 bddFunction. Setting the cnfIndex of newVar to 1(0) is like 00803 setting the function of bddFunction to 1(0). 00804 */ 00805 newVar = bdd_create_variable(bddManager); 00806 bddFunction = bdd_xnor(newVar, bddFunction); 00807 funcNode = bdd_get_node(bddFunction, &is_complemented); 00808 if (bdd_is_constant(funcNode)){ 00809 if (is_complemented){ 00810 /* add an empty clause to indicate FALSE (un-satisfiable)*/ 00811 BmcAddEmptyClause(cnfClauses); 00812 } 00813 return 0; 00814 } 00815 bddFunction = bdd_not(bddFunction); 00816 00817 foreach_bdd_cube(bddFunction, gen, cube){ 00818 tmpClause = array_alloc(int,0); 00819 arrayForEachItem(int, cube, i, value) { 00820 if (value != 2){ 00821 node = bdd_bdd_ith_var(bddManager, i); 00822 varIndex = BmcGetCnfVarIndexForBddNode(bddManager, bdd_regular(node), k, cnfClauses); 00823 if (value == 1){ 00824 varIndex = -varIndex; 00825 } 00826 array_insert_last(int, tmpClause, varIndex); 00827 } 00828 } 00829 BmcCnfInsertClause(cnfClauses, tmpClause); 00830 array_free(tmpClause); 00831 }/* foreach_bdd_cube() */ 00832 varIndex = BmcGetCnfVarIndexForBddNode(bddManager, 00833 bdd_regular(bdd_get_node(newVar, &is_complemented)), 00834 k, cnfClauses); 00835 return (varIndex); 00836 } /* BmcGenerateCnfFormulaForBddOffSet() */ 00837 00838 #if 0 00839 00857 int 00858 BmcGenerateCnfForAigFunction( 00859 bAig_Manager_t *manager, 00860 Ntk_Network_t *network, 00861 bAigEdge_t node, 00862 int k, 00863 BmcCnfClauses_t *cnfClauses) 00864 { 00865 int leftIndex, rightIndex, nodeIndex; 00866 array_t *clause; 00867 00868 if(bAig_IsInverted(node)){ 00869 /* 00870 The generated clauses are in dimacs formate that uses negative number to indicate complement 00871 */ 00872 return -1*BmcGenerateCnfFormulaForAigFunction(manager, bAig_NonInvertedEdge(node), k, cnfClauses); 00873 } 00874 { 00875 char *name = bAig_NodeReadName(manager, node); 00876 char *found = strchr(name, '='); 00877 00878 if (found != NIL(char)){ 00879 int value = atoi(found+1); 00880 int length = found-name; 00881 char toName[length+1]; 00882 Ntk_Node_t *node; 00883 00884 toName[length] = '\0'; 00885 strncpy(toName, name, length); 00886 node = Ntk_NetworkFindNodeByName(network, toName); 00887 if ((node != NIL( Ntk_Node_t)) && Ntk_NodeTestIsLatch(node)){ 00888 MvfAig_Function_t *tmpMvfAig; 00889 st_table *nodeToMvfAigTable = (st_table *) Ntk_NetworkReadApplInfo(network, MVFAIG_NETWORK_APPL_KEY); 00890 bAigEdge_t mAigNode; 00891 00892 if (nodeToMvfAigTable == NIL(st_table)){ 00893 (void) fprintf(vis_stderr, "bmc error: please run build_partiton_maigs first"); 00894 return mAig_NULL; 00895 } 00896 if (k==0){ 00897 node = Ntk_LatchReadInitialInput(node); 00898 } else { 00899 node = Ntk_LatchReadDataInput(node); 00900 k--; 00901 } 00902 tmpMvfAig = Bmc_ReadMvfAig(node, nodeToMvfAigTable); 00903 if (tmpMvfAig == NIL(MvfAig_Function_t)){ 00904 tmpMvfAig = Bmc_NodeBuildMVF(network, node); 00905 array_free(tmpMvfAig); 00906 tmpMvfAig = Bmc_ReadMvfAig(node, nodeToMvfAigTable); 00907 } 00908 mAigNode = MvfAig_FunctionReadComponent(tmpMvfAig, value); 00909 BmcGenerateCnfForAigFunction(manager, network, mAigNode, k, cnfClauses); 00910 } 00911 } 00912 } 00913 if (BmcCnfReadOrInsertNode(cnfClauses, bAig_NodeReadName(manager, node), k, &nodeIndex)){ 00914 return nodeIndex; 00915 } 00916 if (bAig_isVarNode(manager, node)){ 00917 return nodeIndex; 00918 } 00919 leftIndex = BmcGenerateCnfForAigFunction(manager, network, leftChild(node), k, cnfClauses); 00920 rightIndex = BmcGenerateCnfForAigFunction(manager, network, rightChild(node), k, cnfClauses); 00921 00922 clause = array_alloc(int, 3); 00923 array_insert(int, clause, 0, -leftIndex ); 00924 array_insert(int, clause, 1, -rightIndex); 00925 array_insert(int, clause, 2, nodeIndex ); 00926 BmcCnfInsertClause(cnfClauses, clause); 00927 array_free(clause); 00928 00929 clause = array_alloc(int, 2); 00930 array_insert(int, clause, 0, leftIndex); 00931 array_insert(int, clause, 1, -nodeIndex); 00932 BmcCnfInsertClause(cnfClauses, clause); 00933 array_free(clause); 00934 00935 clause = array_alloc(int, 2); 00936 array_insert(int, clause, 0, rightIndex); 00937 array_insert(int, clause, 1, -nodeIndex); 00938 BmcCnfInsertClause(cnfClauses, clause); 00939 array_free(clause); 00940 00941 return(nodeIndex); 00942 00943 } 00944 #endif 00945 00958 void 00959 BmcGenerateClausesFromStateTostate( 00960 bAig_Manager_t *manager, 00961 bAigEdge_t *fromAigArray, 00962 bAigEdge_t *toAigArray, 00963 int mvfSize, 00964 int fromState, 00965 int toState, 00966 BmcCnfClauses_t *cnfClauses, 00967 int outIndex) 00968 { 00969 array_t *clause, *tmpclause; 00970 int toIndex, fromIndex, cnfIndex; 00971 int i; 00972 00973 /* used to turn off the warning messages: might be left uninitialized. 00974 We are sure that these two variables will not be used uninitialized. 00975 */ 00976 toIndex =0; 00977 fromIndex = 0; 00978 00979 for(i=0; i< mvfSize; i++){ 00980 if ((fromAigArray[i] == bAig_One) && (toAigArray[i] == bAig_One)){ 00981 return; /* the clause is always true */ 00982 } 00983 } 00984 clause = array_alloc(int, 0); 00985 for(i=0; i< mvfSize; i++){ 00986 if ((fromAigArray[i] != bAig_Zero) && (toAigArray[i] != bAig_Zero)){ 00987 if (toAigArray[i] != bAig_One){ 00988 /* to State */ 00989 00990 toIndex = BmcGenerateCnfFormulaForAigFunction(manager,toAigArray[i], 00991 toState,cnfClauses); 00992 } 00993 if (fromAigArray[i] != bAig_One){ 00994 /* from State */ 00995 fromIndex = BmcGenerateCnfFormulaForAigFunction(manager, 00996 fromAigArray[i], 00997 fromState, 00998 cnfClauses); 00999 } 01000 /* 01001 Create new var for the output of this node. We don't create variable for this node, we only 01002 use its index number. 01003 */ 01004 cnfIndex = cnfClauses->cnfGlobalIndex++; /* index of the output of the OR of T(from, to) */ 01005 01006 assert(abs(cnfIndex) <= cnfClauses->cnfGlobalIndex); 01007 assert(abs(fromIndex) <= cnfClauses->cnfGlobalIndex); 01008 assert(abs(toIndex) <= cnfClauses->cnfGlobalIndex); 01009 01010 if (toAigArray[i] == bAig_One){ 01011 tmpclause = array_alloc(int, 2); 01012 array_insert(int, tmpclause, 0, -fromIndex); 01013 array_insert(int, tmpclause, 1, cnfIndex); 01014 BmcCnfInsertClause(cnfClauses, tmpclause); 01015 array_free(tmpclause); 01016 01017 tmpclause = array_alloc(int, 2); 01018 array_insert(int, tmpclause, 0, fromIndex); 01019 array_insert(int, tmpclause, 1, -cnfIndex); 01020 BmcCnfInsertClause(cnfClauses, tmpclause); 01021 array_free(tmpclause); 01022 01023 } else if (fromAigArray[i] == bAig_One){ 01024 tmpclause = array_alloc(int, 2); 01025 array_insert(int, tmpclause, 0, -toIndex); 01026 array_insert(int, tmpclause, 1, cnfIndex); 01027 BmcCnfInsertClause(cnfClauses, tmpclause); 01028 array_free(tmpclause); 01029 01030 tmpclause = array_alloc(int, 2); 01031 array_insert(int, tmpclause, 0, toIndex); 01032 array_insert(int, tmpclause, 1, -cnfIndex); 01033 BmcCnfInsertClause(cnfClauses, tmpclause); 01034 array_free(tmpclause); 01035 01036 } else { 01037 tmpclause = array_alloc(int, 3); 01038 array_insert(int, tmpclause, 0, -toIndex); 01039 array_insert(int, tmpclause, 1, -fromIndex); 01040 array_insert(int, tmpclause, 2, cnfIndex); 01041 BmcCnfInsertClause(cnfClauses, tmpclause); 01042 array_free(tmpclause); 01043 01044 tmpclause = array_alloc(int, 2); 01045 array_insert(int, tmpclause, 0, toIndex); 01046 array_insert(int, tmpclause, 1, -cnfIndex); 01047 BmcCnfInsertClause(cnfClauses, tmpclause); 01048 array_free(tmpclause); 01049 01050 tmpclause = array_alloc(int, 2); 01051 array_insert(int, tmpclause, 0, fromIndex); 01052 array_insert(int, tmpclause, 1, -cnfIndex); 01053 BmcCnfInsertClause(cnfClauses, tmpclause); 01054 array_free(tmpclause); 01055 } 01056 array_insert_last(int, clause, cnfIndex); 01057 } /* if */ 01058 } /* for i loop */ 01059 if (outIndex != 0 ){ 01060 array_insert_last(int, clause, -outIndex); 01061 } 01062 BmcCnfInsertClause(cnfClauses, clause); 01063 array_free(clause); 01064 01065 return; 01066 } 01067 01075 void 01076 BmcWriteClauses( 01077 mAig_Manager_t *maigManager, 01078 FILE *cnfFile, 01079 BmcCnfClauses_t *cnfClauses, 01080 BmcOption_t *options) 01081 { 01082 st_generator *stGen; 01083 char *name; 01084 int cnfIndex, i, k; 01085 01086 if (options->verbosityLevel == BmcVerbosityMax_c) { 01087 fprintf(vis_stdout, 01088 "Number of Variables = %d Number of Clauses = %d\n", 01089 cnfClauses->cnfGlobalIndex-1, cnfClauses->noOfClauses); 01090 } 01091 st_foreach_item_int(cnfClauses->cnfIndexTable, stGen, &name, &cnfIndex) { 01092 fprintf(cnfFile, "c %s %d\n",name, cnfIndex); 01093 } 01094 (void) fprintf(cnfFile, "p cnf %d %d\n", cnfClauses->cnfGlobalIndex-1, 01095 cnfClauses->noOfClauses); 01096 if (cnfClauses->clauseArray != NIL(array_t)) { 01097 for (i = 0; i < cnfClauses->nextIndex; i++) { 01098 k = array_fetch(int, cnfClauses->clauseArray, i); 01099 (void) fprintf(cnfFile, "%d%c", k, (k == 0) ? '\n' : ' '); 01100 } 01101 } 01102 return; 01103 } 01104 01114 array_t * 01115 BmcCheckSAT(BmcOption_t *options) 01116 { 01117 array_t *result = NIL(array_t); 01118 01119 01120 if(options->satSolver == cusp){ 01121 result = BmcCallCusp(options); 01122 } 01123 if(options->satSolver == CirCUs){ 01124 result = BmcCallCirCUs(options); 01125 } 01126 /* Adjust alarm if timeout in effect. This is necessary because the 01127 * alarm may have gone off while the SAT solver is running. Since 01128 * the CPU time of a child process is charged to the parent only when 01129 * the child terminates, the SIGALRM handler assumes that more time 01130 * is left than it is in reality. We could do this adjustment right 01131 * after calling the SAT solver, but we prefer to give ourselves the 01132 * extra time to report the result even if this means using more time 01133 * than we are allotted. 01134 */ 01135 if (options->timeOutPeriod > 0) { 01136 int residualTime = options->timeOutPeriod - 01137 (util_cpu_ctime() - options->startTime) / 1000; 01138 /* Make sure we do not cancel the alarm if no time is left. */ 01139 if (residualTime <= 0) { 01140 residualTime = 1; 01141 } 01142 (void) alarm(residualTime); 01143 } 01144 01145 return result; 01146 } 01147 01157 array_t * 01158 BmcCallCirCUs( 01159 BmcOption_t *options) 01160 { 01161 satOption_t *satOption; 01162 array_t *result = NIL(array_t); 01163 satManager_t *cm; 01164 int maxSize; 01165 01166 satOption = sat_InitOption(); 01167 satOption->verbose = options->verbosityLevel; 01168 satOption->verbose = 0; 01169 01170 cm = sat_InitManager(0); 01171 cm->comment = ALLOC(char, 2); 01172 cm->comment[0] = ' '; 01173 cm->comment[1] = '\0'; 01174 cm->stdOut = stdout; 01175 cm->stdErr = stderr; 01176 01177 cm->option = satOption; 01178 cm->each = sat_InitStatistics(); 01179 01180 cm->unitLits = sat_ArrayAlloc(16); 01181 cm->pureLits = sat_ArrayAlloc(16); 01182 01183 maxSize = 10000 << (bAigNodeSize-4); 01184 cm->nodesArray = ALLOC(bAigEdge_t, maxSize); 01185 cm->maxNodesArraySize = maxSize; 01186 cm->nodesArraySize = bAigNodeSize; 01187 01188 sat_AllocLiteralsDB(cm); 01189 01190 sat_ReadCNF(cm, options->satInFile); 01191 01192 if (options->verbosityLevel == BmcVerbosityMax_c) { 01193 (void)fprintf(vis_stdout,"Calling SAT solver (CirCUs) ..."); 01194 (void) fflush(vis_stdout); 01195 } 01196 sat_Main(cm); 01197 if (options->verbosityLevel == BmcVerbosityMax_c) { 01198 (void) fprintf(vis_stdout," done "); 01199 (void) fprintf(vis_stdout, "(%g s)\n", cm->each->satTime); 01200 } 01201 if(cm->status == SAT_UNSAT) { 01202 if (options->verbosityLevel != BmcVerbosityNone_c){ 01203 (void) fprintf(vis_stdout, "# SAT: Counterexample not found\n"); 01204 01205 } 01206 fflush(cm->stdOut); 01207 } else if(cm->status == SAT_SAT) { 01208 if (options->verbosityLevel != BmcVerbosityNone_c){ 01209 (void) fprintf(vis_stdout, "# SAT: Counterexample found\n"); 01210 } 01211 if (options->verbosityLevel == BmcVerbosityMax_c){ 01212 sat_ReportStatistics(cm, cm->each); 01213 } 01214 fflush(cm->stdOut); 01215 result = array_alloc(int, 0); 01216 { 01217 int i, size, value; 01218 01219 size = cm->initNumVariables * bAigNodeSize; 01220 for(i=bAigNodeSize; i<=size; i+=bAigNodeSize) { 01221 value = SATvalue(i); 01222 if(value == 1) { 01223 array_insert_last(int, result, SATnodeID(i)); 01224 } 01225 else if(value == 0) { 01226 array_insert_last(int, result, -(SATnodeID(i))); 01227 } 01228 } 01229 } 01230 } 01231 //Bing: To avoid SEVERE memory leakage 01232 FREE(cm->nodesArray); 01233 01234 sat_FreeManager(cm); 01235 01236 return result; 01237 } /* BmcCallCirCUs */ 01238 01248 array_t * 01249 BmcCallCusp(BmcOption_t *options) 01250 { 01251 FILE *fp; 01252 static char parseBuffer[1024]; 01253 int satStatus; 01254 char line[MAX_LENGTH]; 01255 int num = 0; 01256 array_t *result = NIL(array_t); 01257 char *tmpStr, *tmpStr1, *tmpStr2; 01258 long solverStart; 01259 int satTimeOutPeriod = 0; 01260 01261 strcpy(parseBuffer,"cusp -distill -velim -cnf "); 01262 options->satSolverError = FALSE; /* assume no error*/ 01263 if (options->timeOutPeriod > 0) { 01264 /* Compute the residual CPU time and subtract a little time to 01265 give vis a chance to clean up before its own time out expires. 01266 */ 01267 satTimeOutPeriod = options->timeOutPeriod - 1 - 01268 (util_cpu_ctime() - options->startTime) / 1000; 01269 if (satTimeOutPeriod <= 0){ /* no time left to run SAT solver*/ 01270 options->satSolverError=TRUE; 01271 return NIL(array_t); 01272 } 01273 tmpStr2 = util_inttostr(satTimeOutPeriod); 01274 tmpStr1 = util_strcat3(options->satInFile," -t ", tmpStr2); 01275 tmpStr = util_strcat3(tmpStr1, " >", options->satOutFile); 01276 FREE(tmpStr1); 01277 FREE(tmpStr2); 01278 } else { 01279 tmpStr = util_strcat3(options->satInFile, " >", options->satOutFile); 01280 } 01281 strcat(parseBuffer, tmpStr); 01282 FREE(tmpStr); 01283 01284 if (options->verbosityLevel == BmcVerbosityMax_c) { 01285 (void)fprintf(vis_stdout,"Calling SAT solver (cusp) ..."); 01286 (void) fflush(vis_stdout); 01287 solverStart = util_cpu_ctime(); 01288 } else { /* to remove uninitialized variables warning */ 01289 solverStart = 0; 01290 } 01291 /* Call Sat Solver*/ 01292 satStatus = system(parseBuffer); 01293 if (satStatus != 0){ 01294 (void) fprintf(vis_stderr, "Can't run cusp. It may not be in your path. Status = %d\n", satStatus); 01295 options->satSolverError = TRUE; 01296 return NIL(array_t); 01297 } 01298 01299 if (options->verbosityLevel == BmcVerbosityMax_c) { 01300 (void) fprintf(vis_stdout," done "); 01301 (void) fprintf(vis_stdout, "(%g s)\n", 01302 (double) (util_cpu_ctime() - solverStart)/1000.0); 01303 } 01304 fp = Cmd_FileOpen(options->satOutFile, "r", NIL(char *), 0); 01305 if (fp == NIL(FILE)) { 01306 (void) fprintf(vis_stderr, "** bmc error: Cannot open the file %s\n", 01307 options->satOutFile); 01308 options->satSolverError = TRUE; 01309 return NIL(array_t); 01310 } 01311 /* Skip the lines until the result */ 01312 while(1) { 01313 if (fgets(line, MAX_LENGTH - 1, fp) == NULL) break; 01314 if(strstr(line,"UNSATISFIABLE") || 01315 strstr(line,"SATISFIABLE") || 01316 strstr(line,"MEMOUT") || 01317 strstr(line,"TIMEOUT")) 01318 break; 01319 } 01320 01321 if(strstr(line,"UNSATISFIABLE") != NIL(char)) { 01322 if (options->verbosityLevel != BmcVerbosityNone_c){ 01323 (void) fprintf(vis_stdout, "# SAT: Counterexample not found\n"); 01324 01325 } 01326 } else if(strstr(line,"SATISFIABLE") != NIL(char)) { 01327 if (options->verbosityLevel != BmcVerbosityNone_c){ 01328 (void) fprintf(vis_stdout, "# SAT: Counterexample found\n"); 01329 } 01330 /* Skip the initial v of the result line */ 01331 result = array_alloc(int, 0); 01332 while (fgets(line, MAX_LENGTH - 1, fp) != NULL) { 01333 char *word; 01334 if (line[0] != 'v') { 01335 (void) fprintf(vis_stderr, 01336 "** bmc error: Cannot find assignment in file %s\n", 01337 options->satOutFile); 01338 options->satSolverError = TRUE; 01339 return NIL(array_t); 01340 } 01341 word = strtok(&(line[1])," \n"); 01342 while (word != NIL(char)) { 01343 num = atoi(word); 01344 if (num == 0) break; 01345 array_insert_last(int, result, num); 01346 word = strtok(NIL(char)," \n"); 01347 } 01348 if (num == 0) break; 01349 } 01350 } else if(strstr(line,"MEMOUT") != NIL(char)) { 01351 (void) fprintf(vis_stdout,"# SAT: SAT Solver Memory out\n"); 01352 options->satSolverError = TRUE; 01353 } else if(strstr(line,"TIMEOUT") != NIL(char)) { 01354 (void) fprintf(vis_stdout, 01355 "# SAT: SAT Solver Time out occurred after %d seconds.\n", 01356 satTimeOutPeriod); 01357 options->satSolverError = TRUE; 01358 } else { 01359 (void) fprintf(vis_stdout, "# SAT: SAT Solver failed, try again\n"); 01360 options->satSolverError = TRUE; 01361 } 01362 (void) fflush(vis_stdout); 01363 (void) fclose(fp); 01364 01365 return result; 01366 } /* BmcCallCusp */ 01367 01368 01380 void 01381 BmcPrintCounterExample( 01382 Ntk_Network_t *network, 01383 st_table *nodeToMvfAigTable, 01384 BmcCnfClauses_t *cnfClauses, 01385 array_t *result, 01386 int length, 01387 st_table *CoiTable, 01388 BmcOption_t *options, 01389 array_t *loopClause) 01390 { 01391 mAig_Manager_t *manager = Ntk_NetworkReadMAigManager(network); 01392 lsGen gen; 01393 st_generator *stGen; 01394 Ntk_Node_t *node; 01395 int k; 01396 array_t *latches = array_alloc(int, 0); 01397 int *prevValueLatches; 01398 array_t *inputs = array_alloc(int, 0); 01399 int *prevValueInputs; 01400 int tmp; 01401 int loop; 01402 st_table *resultTable = st_init_table(st_numcmp, st_numhash); 01403 01404 /* 01405 Initialize resultTable from the result to speed up the search in the result array. 01406 */ 01407 for(k=0; k< array_n(result); k++){ 01408 st_insert(resultTable, (char *) (long) array_fetch(int, result, k), (char *) 0); 01409 } 01410 /* sort latches by name */ 01411 st_foreach_item(CoiTable, stGen, &node, NULL) { 01412 array_insert_last(char*, latches, Ntk_NodeReadName(node)); 01413 } 01414 array_sort(latches, nameCompare); 01415 /* 01416 Use to store the last value of each latch. If the current value of a latch 01417 differs from its corresponding value in this array, we will print the new values. 01418 */ 01419 prevValueLatches = ALLOC(int, array_n(latches)); 01420 prevValueInputs = 0; 01421 if(options->printInputs == TRUE){ 01422 /* sort inputs by name */ 01423 Ntk_NetworkForEachInput(network, gen, node){ 01424 array_insert_last(char*, inputs, Ntk_NodeReadName(node)); 01425 } 01426 array_sort(inputs, nameCompare); 01427 prevValueInputs = ALLOC(int, array_n(inputs)); 01428 } 01429 loop = -1; /* no loop back */ 01430 if(loopClause != NIL(array_t)){ 01431 for(k=0; k < array_n(loopClause); k++){ 01432 /* if (searchArray(result, array_fetch(int, loopClause, k)) > -1){ */ 01433 if (st_lookup_int(resultTable, (char *)(long)array_fetch(int, loopClause, k), &tmp)){ 01434 loop = k; 01435 break; 01436 } 01437 } 01438 } 01439 /* 01440 Ntk_NetworkForEachPrimaryOutput(network, gen, node){ 01441 array_insert_last(char*, outputs, Ntk_NodeReadName(node)); 01442 } 01443 array_sort(outputs, nameCompare); 01444 */ 01445 for (k=0; k<= length; k++){ 01446 if (k == 0){ 01447 (void) fprintf(vis_stdout, "\n--State %d:\n", k); 01448 } else { 01449 (void) fprintf(vis_stdout, "\n--Goes to state %d:\n", k); 01450 } 01451 /* 01452 Print the current values of the latches if they are different form their 01453 previous values. 01454 */ 01455 printValue(manager, network, nodeToMvfAigTable, cnfClauses, 01456 latches, resultTable, k, prevValueLatches); 01457 #if 0 01458 (void) fprintf(vis_stdout, "--Primary output:\n"); 01459 printValue(manager, network, nodeToMvfAigTable, cnfClauses, outputs, result, k); 01460 #endif 01461 if((options->printInputs == TRUE) && (k !=0)) { 01462 (void) fprintf(vis_stdout, "--On input:\n"); 01463 printValue(manager, network, nodeToMvfAigTable, cnfClauses, 01464 inputs, resultTable, k-1, prevValueInputs); 01465 } 01466 } /* for k loop */ 01467 if(loop != -1){ 01468 (void) fprintf(vis_stdout, "\n--Goes back to state %d:\n", loop); 01469 printValue(manager, network, nodeToMvfAigTable, cnfClauses, 01470 latches, resultTable, loop, prevValueLatches); 01471 if((options->printInputs == TRUE)) { 01472 (void) fprintf(vis_stdout, "--On input:\n"); 01473 printValue(manager, network, nodeToMvfAigTable, cnfClauses, 01474 inputs, resultTable, length, prevValueInputs); 01475 } 01476 } 01477 array_free(latches); 01478 FREE(prevValueLatches); 01479 if(options->printInputs == TRUE){ 01480 array_free(inputs); 01481 FREE(prevValueInputs); 01482 } 01483 st_free_table(resultTable); 01484 return; 01485 } /* BmcPrintCounterExample() */ 01486 01498 void 01499 BmcPrintCounterExampleAiger( 01500 Ntk_Network_t *network, 01501 st_table *nodeToMvfAigTable, 01502 BmcCnfClauses_t *cnfClauses, 01503 array_t *result, 01504 int length, 01505 st_table *CoiTable, 01506 BmcOption_t *options, 01507 array_t *loopClause) 01508 { 01509 mAig_Manager_t *manager = Ntk_NetworkReadMAigManager(network); 01510 lsGen gen; 01511 st_generator *stGen; 01512 Ntk_Node_t *node; 01513 int k; 01514 array_t *latches = array_alloc(int, 0); 01515 int *prevValueLatches; 01516 array_t *inputs = array_alloc(int, 0); 01517 array_t *outputs = array_alloc(int, 0); 01518 int *prevValueInputs; 01519 int *prevValueOutputs; 01520 int tmp; 01521 int loop; 01522 st_table *resultTable = st_init_table(st_numcmp, st_numhash); 01523 char *nodeName; 01524 01525 /* 01526 Initialize resultTable from the result to speed up the search in the result array. 01527 */ 01528 for(k=0; k< array_n(result); k++){ 01529 st_insert(resultTable, (char *) (long) array_fetch(int, result, k), (char *) 0); 01530 } 01531 /* sort latches by name */ 01532 st_foreach_item(CoiTable, stGen, &node, NULL) { 01533 array_insert_last(char*, latches, Ntk_NodeReadName(node)); 01534 } 01535 /* 01536 Use to store the last value of each latch. If the current value of a latch 01537 differs from its corresponding value in this array, we will print the new values. 01538 */ 01539 01540 /* the file generation needs to be removed for final vis release */ 01541 01542 FILE *order = Cmd_FileOpen("inputOrder.txt", "w", NIL(char *), 0); 01543 for (k=0; k< array_n(latches); k++) 01544 { 01545 nodeName = array_fetch(char *, latches, k); 01546 if((nodeName[0] == '$') && (nodeName[1] == '_')) 01547 { 01548 fprintf(order, "%s\n", &nodeName[2]); 01549 } 01550 } 01551 fclose(order); 01552 01553 prevValueLatches = ALLOC(int, array_n(latches)); 01554 Ntk_NetworkForEachInput(network, gen, node){ 01555 array_insert_last(char*, inputs, Ntk_NodeReadName(node)); 01556 } 01557 01558 prevValueInputs = ALLOC(int, array_n(inputs)); 01559 loop = -1; /* no loop back */ 01560 if(loopClause != NIL(array_t)){ 01561 for(k=0; k < array_n(loopClause); k++){ 01562 /* if (searchArray(result, array_fetch(int, loopClause, k)) > -1){ */ 01563 if (st_lookup_int(resultTable, (char *)(long)array_fetch(int, loopClause, k), &tmp)){ 01564 loop = k; 01565 break; 01566 } 01567 } 01568 } 01569 01570 Ntk_NetworkForEachPrimaryOutput(network, gen, node){ 01571 array_insert_last(char*, outputs, Ntk_NodeReadName(node)); 01572 } 01573 prevValueOutputs = ALLOC(int, array_n(outputs)); 01574 01575 for (k=0; k< length; k++){ 01576 /* This will print latches whose name doesn't start with $_. The latches whose 01577 name starts with $_ are latches added to the model by the aigtoblif translator. 01578 */ 01579 printValueAiger(manager, network, nodeToMvfAigTable, cnfClauses, 01580 latches, resultTable, k, prevValueLatches); 01581 fprintf(vis_stdout, " "); 01582 #if 0 01583 (void) fprintf(vis_stdout, "--Primary output:\n"); 01584 printValue(manager, network, nodeToMvfAigTable, cnfClauses, outputs, result, k); 01585 #endif 01586 01587 if((loop<0)||(k<length)) 01588 { 01589 01590 /* we augment the original .mv model with latches in front of inputs and hence 01591 instead of inputs we print out the value of latches, this would have to be 01592 restored in the final release */ 01593 01594 printValueAigerInputs(manager, network, nodeToMvfAigTable, cnfClauses, 01595 latches, resultTable, k, prevValueInputs); 01596 fprintf(vis_stdout, " "); 01597 01598 /* the sat-solver doesn't propagate the values to output so we generate the output 01599 1 knowing when ouptut would be 1, we will have to remove this for vis release */ 01600 01601 if((k+1)==length) 01602 { 01603 fprintf(vis_stdout, "1 "); 01604 } 01605 else 01606 { 01607 fprintf(vis_stdout, "0 "); 01608 } 01609 01610 printValueAiger(manager, network, nodeToMvfAigTable, cnfClauses, 01611 latches, resultTable, k+1, prevValueLatches); 01612 } 01613 if((loop < 0)||(k!=length)) 01614 { 01615 fprintf(vis_stdout, "\n"); 01616 } 01617 01618 } /* for k loop */ 01619 if(loop != -1){ 01620 (void) fprintf(vis_stdout, "\n--Goes back to state %d:\n", loop); 01621 printValueAiger(manager, network, nodeToMvfAigTable, cnfClauses, 01622 latches, resultTable, loop, prevValueLatches); 01623 (void) fprintf(vis_stdout, "--On input:\n"); 01624 printValueAiger(manager, network, nodeToMvfAigTable, cnfClauses, 01625 inputs, resultTable, length, prevValueInputs); 01626 } 01627 array_free(latches); 01628 FREE(prevValueLatches); 01629 if(options->printInputs == TRUE){ 01630 array_free(inputs); 01631 FREE(prevValueInputs); 01632 } 01633 st_free_table(resultTable); 01634 return; 01635 } /* BmcPrintCounterExampleAiger() */ 01636 01637 01649 void 01650 BmcAutPrintCounterExample( 01651 Ntk_Network_t *network, 01652 Ltl_Automaton_t *automaton, 01653 st_table *nodeToMvfAigTable, 01654 BmcCnfClauses_t *cnfClauses, 01655 array_t *result, 01656 int length, 01657 st_table *CoiTable, 01658 BmcOption_t *options, 01659 array_t *loopClause) 01660 { 01661 mAig_Manager_t *manager = Ntk_NetworkReadMAigManager(network); 01662 lsGen gen; 01663 st_generator *stGen; 01664 Ntk_Node_t *node; 01665 int k; 01666 array_t *latches = array_alloc(int, 0); 01667 int *prevValueLatches; 01668 array_t *inputs = array_alloc(int, 0); 01669 int *prevValueInputs; 01670 int tmp; 01671 int loop; 01672 st_table *resultTable = st_init_table(st_numcmp, st_numhash); 01673 01674 /* 01675 Initialize resultTable from the result to speed up the search in the result array. 01676 */ 01677 for(k=0; k< array_n(result); k++){ 01678 st_insert(resultTable, (char *) (long) array_fetch(int, result, k), (char *) 0); 01679 } 01680 /* sort latches by name */ 01681 st_foreach_item(CoiTable, stGen, &node, NULL) { 01682 array_insert_last(char*, latches, Ntk_NodeReadName(node)); 01683 } 01684 array_sort(latches, nameCompare); 01685 /* 01686 Use to store the last value of each latch. If the current value of a latch 01687 differs from its corresponding value in this array, we will print the new values. 01688 */ 01689 prevValueLatches = ALLOC(int, array_n(latches)); 01690 prevValueInputs = 0; 01691 if(options->printInputs == TRUE){ 01692 /* sort inputs by name */ 01693 Ntk_NetworkForEachInput(network, gen, node){ 01694 array_insert_last(char*, inputs, Ntk_NodeReadName(node)); 01695 } 01696 array_sort(inputs, nameCompare); 01697 prevValueInputs = ALLOC(int, array_n(inputs)); 01698 } 01699 loop = -1; /* no loop back */ 01700 if(loopClause != NIL(array_t)){ 01701 for(k=0; k < array_n(loopClause); k++){ 01702 /* if (searchArray(result, array_fetch(int, loopClause, k)) > -1){ */ 01703 if (st_lookup_int(resultTable, (char *)(long)array_fetch(int, loopClause, k), &tmp)){ 01704 loop = k; 01705 break; 01706 } 01707 } 01708 } 01709 /* 01710 Ntk_NetworkForEachPrimaryOutput(network, gen, node){ 01711 array_insert_last(char*, outputs, Ntk_NodeReadName(node)); 01712 } 01713 array_sort(outputs, nameCompare); 01714 */ 01715 for (k=0; k<= length; k++){ 01716 if (k == 0){ 01717 (void) fprintf(vis_stdout, "\n--State %d:\n", k); 01718 } else { 01719 (void) fprintf(vis_stdout, "\n--Goes to state %d:\n", k); 01720 } 01721 /* 01722 Print the current values of the latches if they are different form their 01723 previous values. 01724 */ 01725 printValue(manager, network, nodeToMvfAigTable, cnfClauses, 01726 latches, resultTable, k, prevValueLatches); 01727 01728 { 01729 lsGen lsGen; 01730 vertex_t *vtx; 01731 Ltl_AutomatonNode_t *state; 01732 int stateIndex; 01733 bdd_node *node; 01734 int is_complemented; 01735 01736 01737 foreach_vertex(automaton->G, lsGen, vtx) { 01738 state = (Ltl_AutomatonNode_t *) vtx->user_data; 01739 01740 node = bdd_get_node(state->Encode, &is_complemented); 01741 01742 stateIndex = state->cnfIndex[k]; 01743 01744 01745 01746 01747 if (st_lookup_int(resultTable, (char *)(long)stateIndex, &tmp)){ 01748 (void) fprintf(vis_stdout,"n%d \n", state->index); 01749 } 01750 } 01751 } 01752 #if 0 01753 (void) fprintf(vis_stdout, "--Primary output:\n"); 01754 printValue(manager, network, nodeToMvfAigTable, cnfClauses, outputs, result, k); 01755 #endif 01756 if((options->printInputs == TRUE) && (k !=0)) { 01757 (void) fprintf(vis_stdout, "--On input:\n"); 01758 printValue(manager, network, nodeToMvfAigTable, cnfClauses, 01759 inputs, resultTable, k-1, prevValueInputs); 01760 } 01761 } /* for k loop */ 01762 if(loop != -1){ 01763 (void) fprintf(vis_stdout, "\n--Goes back to state %d:\n", loop); 01764 printValue(manager, network, nodeToMvfAigTable, cnfClauses, 01765 latches, resultTable, loop, prevValueLatches); 01766 if((options->printInputs == TRUE)) { 01767 (void) fprintf(vis_stdout, "--On input:\n"); 01768 printValue(manager, network, nodeToMvfAigTable, cnfClauses, 01769 inputs, resultTable, length, prevValueInputs); 01770 } 01771 } 01772 array_free(latches); 01773 FREE(prevValueLatches); 01774 if(options->printInputs == TRUE){ 01775 array_free(inputs); 01776 FREE(prevValueInputs); 01777 } 01778 st_free_table(resultTable); 01779 return; 01780 } /* BmcPrintCounterExample() */ 01781 01782 01816 void 01817 BmcCnfGenerateClausesForPath( 01818 Ntk_Network_t *network, 01819 int from, 01820 int to, 01821 int initialState, 01822 BmcCnfClauses_t *cnfClauses, 01823 st_table *nodeToMvfAigTable, 01824 st_table *CoiTable) 01825 { 01826 mAig_Manager_t *manager = Ntk_NetworkReadMAigManager(network); 01827 st_generator *stGen; 01828 01829 Ntk_Node_t *latch, *latchData, *latchInit; 01830 MvfAig_Function_t *initMvfAig, *dataMvfAig, *latchMvfAig; 01831 bAigEdge_t *initBAig, *latchBAig, *dataBAig; 01832 01833 int i, k, mvfSize; 01834 01835 st_foreach_item(CoiTable, stGen, &latch, NULL) { 01836 01837 01838 latchInit = Ntk_LatchReadInitialInput(latch); 01839 latchData = Ntk_LatchReadDataInput(latch); 01840 01841 /* Get the multi-valued function for each node*/ 01842 initMvfAig = Bmc_ReadMvfAig(latchInit, nodeToMvfAigTable); 01843 if (initMvfAig == NIL(MvfAig_Function_t)){ 01844 (void) fprintf(vis_stdout, "No multi-valued function for this node %s \n", Ntk_NodeReadName(latchInit)); 01845 return; 01846 } 01847 dataMvfAig = Bmc_ReadMvfAig(latchData, nodeToMvfAigTable); 01848 if (dataMvfAig == NIL(MvfAig_Function_t)){ 01849 (void) fprintf(vis_stdout, "No multi-valued function for this node %s \n", Ntk_NodeReadName(latchData)); 01850 return; 01851 } 01852 latchMvfAig = Bmc_ReadMvfAig(latch, nodeToMvfAigTable); 01853 if (latchMvfAig == NIL(MvfAig_Function_t)){ 01854 latchMvfAig = Bmc_NodeBuildMVF(network, latch); 01855 array_free(latchMvfAig); 01856 latchMvfAig = Bmc_ReadMvfAig(latch, nodeToMvfAigTable); 01857 } 01858 01859 mvfSize = array_n(initMvfAig); 01860 initBAig = ALLOC(bAigEdge_t, mvfSize); 01861 dataBAig = ALLOC(bAigEdge_t, mvfSize); 01862 latchBAig = ALLOC(bAigEdge_t, mvfSize); 01863 01864 for(i=0; i< mvfSize; i++){ 01865 dataBAig[i] = bAig_GetCanonical(manager, MvfAig_FunctionReadComponent(dataMvfAig, i)); 01866 latchBAig[i] = bAig_GetCanonical(manager, MvfAig_FunctionReadComponent(latchMvfAig, i)); 01867 initBAig[i] = bAig_GetCanonical(manager, MvfAig_FunctionReadComponent(initMvfAig, i)); 01868 } 01869 /* 01870 if (from == 0){ 01871 */ 01872 if (initialState == BMC_INITIAL_STATES){ 01873 /* Generate the CNF for the initial state of the latch */ 01874 BmcGenerateClausesFromStateTostate(manager, initBAig, latchBAig, mvfSize, -1, 0, cnfClauses, 0); 01875 } 01876 /* Generate the CNF for the transition functions */ 01877 for (k=from; k < to; k++){ 01878 BmcGenerateClausesFromStateTostate(manager, dataBAig, latchBAig, mvfSize, k, k+1, cnfClauses, 0); 01879 } /* for k state loop */ 01880 01881 FREE(initBAig); 01882 FREE(dataBAig); 01883 FREE(latchBAig); 01884 }/* For each latch loop*/ 01885 01886 return; 01887 } 01888 01907 void 01908 BmcCnfGenerateClausesForLoopFreePath( 01909 Ntk_Network_t *network, 01910 int fromState, 01911 int toState, 01912 int initialState, 01913 BmcCnfClauses_t *cnfClauses, 01914 st_table *nodeToMvfAigTable, 01915 st_table *CoiTable) 01916 { 01917 int state; 01918 01919 /* 01920 Generate clauses for a path from fromState to toState. 01921 */ 01922 BmcCnfGenerateClausesForPath(network, fromState, toState, initialState, cnfClauses, nodeToMvfAigTable, CoiTable); 01923 01924 /* 01925 Restrict the above path to be loop-free path. 01926 */ 01927 /* 01928 for(state=0; state< toState; state++){ 01929 */ 01930 /* 01931 Don't include the last state because we know it is not equal any of the previous states. 01932 The property fails at this state, and true at all other states. 01933 */ 01934 /* 01935 for(state=1; state < toState; state++){ 01936 */ 01937 for(state= fromState + 1; state <= toState; state++){ 01938 BmcCnfGenerateClausesForNoLoopToAnyPreviouseStates(network, fromState, state, cnfClauses, nodeToMvfAigTable, CoiTable); 01939 } 01940 01941 return; 01942 } 01943 01960 void 01961 BmcCnfGenerateClausesForNoLoopToAnyPreviouseStates( 01962 Ntk_Network_t *network, 01963 int fromState, 01964 int toState, 01965 BmcCnfClauses_t *cnfClauses, 01966 st_table *nodeToMvfAigTable, 01967 st_table *CoiTable) 01968 { 01969 mAig_Manager_t *manager = Ntk_NetworkReadMAigManager(network); 01970 st_generator *stGen; 01971 01972 Ntk_Node_t *latch; 01973 MvfAig_Function_t *latchMvfAig; 01974 bAigEdge_t *latchBAig; 01975 array_t *orClause; 01976 int lastIndex, prevIndex, andIndex1, andIndex2; 01977 int i, k, mvfSize; 01978 01979 /* 01980 Generates the clauses to check if the toState is not equal to any previouse states starting 01981 from fromState. 01982 01983 Assume there are two state varaibles a and b. To check if Si != Sj, we must generate clauses 01984 for the formula ( ai != aj + bi != bj). 01985 */ 01986 for(k=fromState; k < toState; k++){ 01987 orClause = array_alloc(int,0); 01988 st_foreach_item(CoiTable, stGen, &latch, NULL) { 01989 01990 01991 latchMvfAig = Bmc_ReadMvfAig(latch, nodeToMvfAigTable); 01992 if (latchMvfAig == NIL(MvfAig_Function_t)){ 01993 latchMvfAig = Bmc_NodeBuildMVF(network, latch); 01994 array_free(latchMvfAig); 01995 latchMvfAig = Bmc_ReadMvfAig(latch, nodeToMvfAigTable); 01996 } 01997 mvfSize = array_n(latchMvfAig); 01998 latchBAig = ALLOC(bAigEdge_t, mvfSize); 01999 02000 for(i=0; i< mvfSize; i++){ 02001 latchBAig[i] = bAig_GetCanonical(manager, MvfAig_FunctionReadComponent(latchMvfAig, i)); 02002 } 02003 02004 for (i=0; i< mvfSize; i++){ 02005 prevIndex = BmcGenerateCnfFormulaForAigFunction(manager, latchBAig[i], k ,cnfClauses); 02006 lastIndex = BmcGenerateCnfFormulaForAigFunction(manager, latchBAig[i], toState ,cnfClauses); 02007 andIndex1 = cnfClauses->cnfGlobalIndex++; 02008 BmcCnfGenerateClausesForAND(prevIndex, -lastIndex, andIndex1, cnfClauses); 02009 andIndex2 = cnfClauses->cnfGlobalIndex++; 02010 BmcCnfGenerateClausesForAND(-prevIndex, lastIndex, andIndex2, cnfClauses); 02011 02012 array_insert_last(int, orClause, andIndex1); 02013 array_insert_last(int, orClause, andIndex2); 02014 } 02015 FREE(latchBAig); 02016 }/* For each latch loop*/ 02017 BmcCnfInsertClause(cnfClauses, orClause); 02018 array_free(orClause); 02019 } /* foreach k*/ 02020 return; 02021 } 02022 02023 02041 void 02042 BmcCnfGenerateClausesForLoopToAnyPreviouseStates( 02043 Ntk_Network_t *network, 02044 int fromState, 02045 int toState, 02046 BmcCnfClauses_t *cnfClauses, 02047 st_table *nodeToMvfAigTable, 02048 st_table *CoiTable) 02049 { 02050 mAig_Manager_t *manager = Ntk_NetworkReadMAigManager(network); 02051 st_generator *stGen; 02052 02053 Ntk_Node_t *latch; 02054 MvfAig_Function_t *latchMvfAig; 02055 bAigEdge_t *latchBAig; 02056 array_t *orClause; 02057 int lastIndex, prevIndex, andIndex1, andIndex2; 02058 int i, k, mvfSize; 02059 02060 /* 02061 Generates the clauses to check if the toState is not equal to any previouse states starting 02062 from fromState. 02063 02064 Assume there are two state varaibles a and b. To check if Si != Sj, we must generate clauses 02065 for the formula ( ai != aj + bi != bj). 02066 */ 02067 for(k=fromState; k < toState; k++){ 02068 orClause = array_alloc(int,0); 02069 st_foreach_item(CoiTable, stGen, &latch, NULL) { 02070 02071 02072 latchMvfAig = Bmc_ReadMvfAig(latch, nodeToMvfAigTable); 02073 if (latchMvfAig == NIL(MvfAig_Function_t)){ 02074 latchMvfAig = Bmc_NodeBuildMVF(network, latch); 02075 array_free(latchMvfAig); 02076 latchMvfAig = Bmc_ReadMvfAig(latch, nodeToMvfAigTable); 02077 } 02078 mvfSize = array_n(latchMvfAig); 02079 latchBAig = ALLOC(bAigEdge_t, mvfSize); 02080 02081 for(i=0; i< mvfSize; i++){ 02082 latchBAig[i] = bAig_GetCanonical(manager, MvfAig_FunctionReadComponent(latchMvfAig, i)); 02083 } 02084 02085 for (i=0; i< mvfSize; i++){ 02086 prevIndex = BmcGenerateCnfFormulaForAigFunction(manager, latchBAig[i], k ,cnfClauses); 02087 lastIndex = BmcGenerateCnfFormulaForAigFunction(manager, latchBAig[i], toState ,cnfClauses); 02088 andIndex1 = cnfClauses->cnfGlobalIndex++; 02089 BmcCnfGenerateClausesForAND(prevIndex, lastIndex, andIndex1, cnfClauses); 02090 andIndex2 = cnfClauses->cnfGlobalIndex++; 02091 BmcCnfGenerateClausesForAND(-prevIndex, -lastIndex, andIndex2, cnfClauses); 02092 02093 array_insert_last(int, orClause, andIndex1); 02094 array_insert_last(int, orClause, andIndex2); 02095 } 02096 FREE(latchBAig); 02097 }/* For each latch loop*/ 02098 BmcCnfInsertClause(cnfClauses, orClause); 02099 array_free(orClause); 02100 } /* foreach k*/ 02101 return; 02102 } 02103 02133 void 02134 BmcCnfGenerateClausesFromStateToState( 02135 Ntk_Network_t *network, 02136 int from, 02137 int to, 02138 BmcCnfClauses_t *cnfClauses, 02139 st_table *nodeToMvfAigTable, 02140 st_table *CoiTable, 02141 int loop) 02142 { 02143 mAig_Manager_t *manager = Ntk_NetworkReadMAigManager(network); 02144 st_generator *stGen; 02145 Ntk_Node_t *latch, *latchData; 02146 MvfAig_Function_t *dataMvfAig, *latchMvfAig; 02147 bAigEdge_t *latchBAig, *dataBAig; 02148 int i, mvfSize; 02149 02150 st_foreach_item(CoiTable, stGen, &latch, NULL) { 02151 latchData = Ntk_LatchReadDataInput(latch); 02152 02153 dataMvfAig = Bmc_ReadMvfAig(latchData, nodeToMvfAigTable); 02154 if (dataMvfAig == NIL(MvfAig_Function_t)){ 02155 (void) fprintf(vis_stdout, 02156 "No multi-valued function for this node %s \n", 02157 Ntk_NodeReadName(latchData)); 02158 return; 02159 } 02160 latchMvfAig = Bmc_ReadMvfAig(latch, nodeToMvfAigTable); 02161 if (latchMvfAig == NIL(MvfAig_Function_t)){ 02162 latchMvfAig = Bmc_NodeBuildMVF(network, latch); 02163 } 02164 mvfSize = array_n(dataMvfAig); 02165 dataBAig = ALLOC(bAigEdge_t, mvfSize); 02166 latchBAig = ALLOC(bAigEdge_t, mvfSize); 02167 for(i=0; i< mvfSize; i++){ 02168 dataBAig[i] = bAig_GetCanonical(manager, MvfAig_FunctionReadComponent(dataMvfAig, i)); 02169 latchBAig[i] = bAig_GetCanonical(manager, MvfAig_FunctionReadComponent(latchMvfAig, i)); 02170 } 02171 BmcGenerateClausesFromStateTostate(manager, dataBAig, latchBAig, mvfSize, 02172 from, to, cnfClauses, loop); 02173 FREE(dataBAig); 02174 FREE(latchBAig); 02175 } /* For each latch loop*/ 02176 return; 02177 } 02178 02190 void 02191 BmcCnfGenerateClausesForAND( 02192 int a, 02193 int b, 02194 int c, 02195 BmcCnfClauses_t *cnfClauses) 02196 { 02197 array_t *tmpClause; 02198 02199 tmpClause = array_alloc(int, 3); 02200 array_insert(int, tmpClause, 0, -a); 02201 array_insert(int, tmpClause, 1, -b); 02202 array_insert(int, tmpClause, 2, c); 02203 BmcCnfInsertClause(cnfClauses, tmpClause); 02204 array_free(tmpClause); 02205 02206 tmpClause = array_alloc(int, 2); 02207 02208 array_insert(int, tmpClause, 0, a); 02209 array_insert(int, tmpClause, 1, -c); 02210 BmcCnfInsertClause(cnfClauses, tmpClause); 02211 02212 array_insert(int, tmpClause, 0, b); 02213 BmcCnfInsertClause(cnfClauses, tmpClause); 02214 02215 array_free(tmpClause); 02216 return; 02217 } 02218 02230 void 02231 BmcCnfGenerateClausesForOR( 02232 int a, 02233 int b, 02234 int c, 02235 BmcCnfClauses_t *cnfClauses) 02236 { 02237 array_t *tmpClause; 02238 02239 tmpClause = array_alloc(int, 3); 02240 array_insert(int, tmpClause, 0, a); 02241 array_insert(int, tmpClause, 1, b); 02242 array_insert(int, tmpClause, 2, -c); 02243 BmcCnfInsertClause(cnfClauses, tmpClause); 02244 array_free(tmpClause); 02245 02246 tmpClause = array_alloc(int, 2); 02247 array_insert(int, tmpClause, 0, -a); 02248 array_insert(int, tmpClause, 1, c); 02249 BmcCnfInsertClause(cnfClauses, tmpClause); 02250 02251 array_insert(int, tmpClause, 0, -b); 02252 BmcCnfInsertClause(cnfClauses, tmpClause); 02253 02254 array_free(tmpClause); 02255 return; 02256 } 02257 02266 BmcCnfClauses_t * 02267 BmcCnfClausesAlloc(void) 02268 { 02269 BmcCnfClauses_t *result = ALLOC(BmcCnfClauses_t, 1); 02270 02271 if (!result){ 02272 return result; 02273 } 02274 result->clauseArray = array_alloc(int, 0); 02275 result->cnfIndexTable = st_init_table(strcmp, st_strhash); 02276 result->freezedKeys = array_alloc(nameType_t *, 0); 02277 02278 result->nextIndex = 0; 02279 result->noOfClauses = 0; 02280 result->cnfGlobalIndex = 1; 02281 result->emptyClause = FALSE; 02282 result->freezed = FALSE; 02283 02284 return result; 02285 } /*BmcCnfClausesAlloc()*/ 02286 02295 void 02296 BmcCnfClausesFree( 02297 BmcCnfClauses_t *cnfClauses) 02298 { 02299 st_generator *stGen; 02300 char *name; 02301 int cnfIndex; 02302 02303 array_free(cnfClauses->clauseArray); 02304 array_free(cnfClauses->freezedKeys); 02305 02306 if (cnfClauses->cnfIndexTable != NIL(st_table)){ 02307 st_foreach_item_int(cnfClauses->cnfIndexTable, stGen, (char **) &name, &cnfIndex) { 02308 FREE(name); 02309 } 02310 st_free_table(cnfClauses->cnfIndexTable); 02311 } 02312 FREE(cnfClauses); 02313 cnfClauses = NIL(BmcCnfClauses_t); 02314 } /* BmcCnfClausesFree() */ 02315 02328 BmcCnfStates_t * 02329 BmcCnfClausesFreeze( 02330 BmcCnfClauses_t * cnfClauses) 02331 { 02332 BmcCnfStates_t *state = ALLOC(BmcCnfStates_t, 1); 02333 02334 state->nextIndex = cnfClauses->nextIndex; 02335 state->noOfClauses = cnfClauses->noOfClauses; 02336 state->cnfGlobalIndex = cnfClauses->cnfGlobalIndex; 02337 02338 /* This variable is used when deleting any new entries in cnfClauses->freezedKeys 02339 that will be added after CNF is freezed.*/ 02340 state->freezedKeySize = array_n(cnfClauses->freezedKeys); 02341 02342 state->emptyClause = cnfClauses->emptyClause; 02343 state->freezed = cnfClauses->freezed; 02344 cnfClauses->freezed = TRUE; 02345 return state; 02346 } /* mcCnfClausesFreeze() */ 02347 02358 void 02359 BmcCnfClausesUnFreeze( 02360 BmcCnfClauses_t *cnfClauses, 02361 BmcCnfStates_t *state) 02362 { 02363 int i; 02364 02365 cnfClauses->freezed = FALSE; 02366 if (array_n(cnfClauses->freezedKeys) != 0){ 02367 int freezedKeySize = array_n(cnfClauses->freezedKeys); 02368 02369 for (i=0; i< (freezedKeySize-state->freezedKeySize); i++){ 02370 (cnfClauses->freezedKeys)->num--; 02371 } 02372 } 02373 } /* BmcCnfClausesUnFreeze() */ 02374 02386 void 02387 BmcCnfClausesRestore( 02388 BmcCnfClauses_t *cnfClauses, 02389 BmcCnfStates_t *state) 02390 { 02391 int i, index; 02392 nameType_t *key; 02393 02394 cnfClauses->nextIndex = state->nextIndex; 02395 cnfClauses->noOfClauses = state->noOfClauses; 02396 cnfClauses->cnfGlobalIndex = state->cnfGlobalIndex; 02397 cnfClauses->emptyClause = state->emptyClause; 02398 cnfClauses->freezed = state->freezed; 02399 02400 if (array_n(cnfClauses->freezedKeys) != 0){ 02401 int freezedKeySize = array_n(cnfClauses->freezedKeys); 02402 02403 for (i=0; i< (freezedKeySize-state->freezedKeySize); i++){ 02404 key = array_fetch_last(nameType_t *, cnfClauses->freezedKeys); 02405 if (st_delete_int(cnfClauses->cnfIndexTable, &key, &index)){ 02406 FREE(key); 02407 } 02408 (cnfClauses->freezedKeys)->num--; 02409 } 02410 } 02411 } /* BmcCnfClausesRestore() */ 02412 02424 void 02425 BmcCnfInsertClause( 02426 BmcCnfClauses_t *cnfClauses, 02427 array_t *clause) 02428 { 02429 int i, lit; 02430 02431 if (clause != NIL(array_t)){ 02432 if (array_n(clause) == 0){ /* empty clause */ 02433 cnfClauses->emptyClause = TRUE; 02434 return; 02435 } 02436 for (i=0; i< array_n(clause); i++){ 02437 lit = array_fetch(int, clause, i); 02438 array_insert(int, cnfClauses->clauseArray, cnfClauses->nextIndex++, lit); 02439 } 02440 array_insert(int, cnfClauses->clauseArray, cnfClauses->nextIndex++, 0); /*End Of clause*/ 02441 cnfClauses->noOfClauses++; 02442 cnfClauses->emptyClause = FALSE; 02443 } 02444 return; 02445 }/* BmcCnfInsertClause() */ 02446 02455 void 02456 BmcAddEmptyClause( 02457 BmcCnfClauses_t *cnfClauses) 02458 { 02459 cnfClauses->emptyClause = TRUE; 02460 }/* BmcAddEmptyClause() */ 02461 02472 int 02473 BmcCnfReadOrInsertNode( 02474 BmcCnfClauses_t *cnfClauses, 02475 nameType_t *nodeName, 02476 int state, 02477 int *nodeIndex) 02478 { 02479 nameType_t *varName; 02480 int index; 02481 char *stateStr = util_inttostr(state); 02482 02483 varName = util_strcat3(nodeName, "_", stateStr); 02484 FREE(stateStr); 02485 if (!st_lookup_int(cnfClauses->cnfIndexTable, varName, &index)) { 02486 index = cnfClauses->cnfGlobalIndex++; 02487 st_insert(cnfClauses->cnfIndexTable, varName, (char*) (long) index); 02488 if(cnfClauses->freezed == TRUE){ 02489 array_insert_last(nameType_t *, cnfClauses->freezedKeys, varName); 02490 } 02491 *nodeIndex = index; 02492 return 0; /* Inserted */ 02493 } 02494 else { /* The node has been visited */ 02495 *nodeIndex = index; 02496 FREE(varName); 02497 return 1; 02498 } 02499 } 02500 02501 02512 void 02513 BmcGetCoiForLtlFormula( 02514 Ntk_Network_t *network, 02515 Ctlsp_Formula_t *formula, 02516 st_table *ltlCoiTable) 02517 { 02518 st_table *visited = st_init_table(st_ptrcmp, st_ptrhash); 02519 02520 BmcGetCoiForLtlFormulaRecursive(network, formula, ltlCoiTable, visited); 02521 st_free_table(visited); 02522 return; 02523 } /* BmcGetCoiForLtlFormula() */ 02524 02534 void 02535 BmcGetCoiForLtlFormulaRecursive( 02536 Ntk_Network_t *network, 02537 Ctlsp_Formula_t *formula, 02538 st_table *ltlCoiTable, 02539 st_table *visited) 02540 { 02541 if (formula == NIL(Ctlsp_Formula_t)) { 02542 return; 02543 } 02544 /* leaf node */ 02545 if (formula->type == Ctlsp_ID_c){ 02546 char *name = Ctlsp_FormulaReadVariableName(formula); 02547 Ntk_Node_t *node = Ntk_NetworkFindNodeByName(network, name); 02548 int tmp; 02549 02550 if (st_lookup_int(visited, (char *) node, &tmp)){ 02551 /* Node already visited */ 02552 return; 02553 } 02554 BmcGetCoiForNtkNode(node, ltlCoiTable, visited); 02555 return; 02556 } 02557 BmcGetCoiForLtlFormulaRecursive(network, formula->left, ltlCoiTable, visited); 02558 BmcGetCoiForLtlFormulaRecursive(network, formula->right, ltlCoiTable, visited); 02559 02560 return; 02561 } /* BmcGetCoiForLtlFormulaRecursive() */ 02562 02574 void 02575 BmcGetCoiForNtkNode( 02576 Ntk_Node_t *node, 02577 st_table *CoiTable, 02578 st_table *visited) 02579 { 02580 int i, j; 02581 Ntk_Node_t *faninNode; 02582 02583 if(node == NIL(Ntk_Node_t)){ 02584 return; 02585 } 02586 if (st_lookup_int(visited, (char *) node, &j)){ 02587 /* Node already visited */ 02588 return; 02589 } 02590 st_insert(visited, (char *) node, (char *) 0); 02591 if (Ntk_NodeTestIsLatch(node)){ 02592 st_insert(CoiTable, (char *) node, (char *) 0); 02593 } 02594 Ntk_NodeForEachFanin(node, i, faninNode) { 02595 BmcGetCoiForNtkNode(faninNode, CoiTable, visited); 02596 } 02597 return; 02598 } /* BmcGetCoiForNtkNode() */ 02599 02600 02614 mdd_t * 02615 BmcModelCheckAtomicFormula( 02616 Fsm_Fsm_t *modelFsm, 02617 Ctlsp_Formula_t *ctlFormula) 02618 { 02619 mdd_t * resultMdd; 02620 mdd_t *tmpMdd; 02621 Ntk_Network_t *network = Fsm_FsmReadNetwork(modelFsm); 02622 char *nodeNameString = Ctlsp_FormulaReadVariableName(ctlFormula); 02623 char *nodeValueString = Ctlsp_FormulaReadValueName(ctlFormula); 02624 Ntk_Node_t *node = Ntk_NetworkFindNodeByName(network, nodeNameString); 02625 02626 Var_Variable_t *nodeVar; 02627 int nodeValue; 02628 02629 graph_t *modelPartition; 02630 vertex_t *partitionVertex; 02631 Mvf_Function_t *MVF; 02632 02633 nodeVar = Ntk_NodeReadVariable(node); 02634 if (Var_VariableTestIsSymbolic(nodeVar)) { 02635 nodeValue = Var_VariableReadIndexFromSymbolicValue(nodeVar, nodeValueString); 02636 } 02637 else { 02638 nodeValue = atoi(nodeValueString); 02639 } 02640 02641 modelPartition = Part_NetworkReadPartition(network); 02642 if (!(partitionVertex = Part_PartitionFindVertexByName(modelPartition, 02643 nodeNameString))) { 02644 lsGen tmpGen; 02645 Ntk_Node_t *tmpNode; 02646 array_t *mvfArray; 02647 array_t *tmpRoots = array_alloc(Ntk_Node_t *, 0); 02648 st_table *tmpLeaves = st_init_table(st_ptrcmp, st_ptrhash); 02649 array_insert_last(Ntk_Node_t *, tmpRoots, node); 02650 02651 Ntk_NetworkForEachCombInput(network, tmpGen, tmpNode) { 02652 st_insert(tmpLeaves, (char *) tmpNode, (char *) NTM_UNUSED); 02653 } 02654 02655 mvfArray = Ntm_NetworkBuildMvfs(network, tmpRoots, tmpLeaves, 02656 NIL(mdd_t)); 02657 MVF = array_fetch(Mvf_Function_t *, mvfArray, 0); 02658 array_free(tmpRoots); 02659 st_free_table(tmpLeaves); 02660 array_free(mvfArray); 02661 02662 tmpMdd = Mvf_FunctionReadComponent(MVF, nodeValue); 02663 resultMdd = mdd_dup(tmpMdd); 02664 Mvf_FunctionFree(MVF); 02665 } 02666 else { 02667 MVF = Part_VertexReadFunction(partitionVertex); 02668 tmpMdd = Mvf_FunctionReadComponent(MVF, nodeValue); 02669 resultMdd = mdd_dup(tmpMdd); 02670 } 02671 if (Part_PartitionReadMethod(modelPartition) == Part_Frontier_c && 02672 Ntk_NodeTestIsCombOutput(node)) { 02673 array_t *psVars = Fsm_FsmReadPresentStateVars(modelFsm); 02674 mdd_manager *mgr = Ntk_NetworkReadMddManager(Fsm_FsmReadNetwork(modelFsm)); 02675 array_t *supportList; 02676 st_table *supportTable = st_init_table(st_numcmp, st_numhash); 02677 int i, j; 02678 int existIntermediateVars; 02679 int mddId; 02680 Mvf_Function_t *mvf; 02681 vertex_t *vertex; 02682 array_t *varBddRelationArray, *varArray; 02683 mdd_t *iv, *ivMdd, *relation; 02684 02685 for (i = 0; i < array_n(psVars); i++) { 02686 mddId = array_fetch(int, psVars, i); 02687 st_insert(supportTable, (char *)(long)mddId, NULL); 02688 } 02689 02690 existIntermediateVars = 1; 02691 while (existIntermediateVars) { 02692 existIntermediateVars = 0; 02693 supportList = mdd_get_support(mgr, resultMdd); 02694 for (i = 0; i < array_n(supportList); i++) { 02695 mddId = array_fetch(int, supportList, i); 02696 if (!st_lookup(supportTable, (char *)(long)mddId, NULL)) { 02697 vertex = Part_PartitionFindVertexByMddId(modelPartition, mddId); 02698 mvf = Part_VertexReadFunction(vertex); 02699 varBddRelationArray = mdd_fn_array_to_bdd_rel_array(mgr, mddId, mvf); 02700 varArray = mdd_id_to_bdd_array(mgr, mddId); 02701 assert(array_n(varBddRelationArray) == array_n(varArray)); 02702 for (j = 0; j < array_n(varBddRelationArray); j++) { 02703 iv = array_fetch(mdd_t *, varArray, j); 02704 relation = array_fetch(mdd_t *, varBddRelationArray, j); 02705 ivMdd = bdd_cofactor(relation, iv); 02706 mdd_free(relation); 02707 tmpMdd = resultMdd; 02708 resultMdd = bdd_compose(resultMdd, iv, ivMdd); 02709 mdd_free(tmpMdd); 02710 mdd_free(iv); 02711 mdd_free(ivMdd); 02712 } 02713 array_free(varBddRelationArray); 02714 array_free(varArray); 02715 existIntermediateVars = 1; 02716 } 02717 } 02718 array_free(supportList); 02719 } 02720 st_free_table(supportTable); 02721 } 02722 return resultMdd; 02723 } 02724 02736 array_t * 02737 BmcReadFairnessConstraints( 02738 FILE *fp /* pointer to the fairness constraint file */) 02739 { 02740 array_t *constraintArray; /* raw fairness constraints */ 02741 array_t *ltlConstraintArray; /* constraints converted to LTL */ 02742 02743 if (fp == NIL(FILE) ) { 02744 /* Nothing to be done. */ 02745 return NIL(array_t); 02746 } 02747 02748 /* Read constraints from file and check for errors. */ 02749 constraintArray = Ctlsp_FileParseFormulaArray(fp); 02750 if (constraintArray == NIL(array_t)) { 02751 (void) fprintf(vis_stderr, 02752 "** ctlsp error: error reading fairness constraints.\n"); 02753 return NIL(array_t); 02754 } 02755 if (array_n(constraintArray) == 0) { 02756 (void) fprintf(vis_stderr, "** ctlsp error: fairness file is empty.\n"); 02757 return NIL(array_t); 02758 } 02759 /* 02760 * Check that each constraint is an LTL formula. 02761 */ 02762 ltlConstraintArray = Ctlsp_FormulaArrayConvertToLTL(constraintArray); 02763 Ctlsp_FormulaArrayFree(constraintArray); 02764 if (ltlConstraintArray == NIL(array_t)) { 02765 (void) fprintf(vis_stderr, 02766 "** ctlsp error: fairness constraints are not LTL formulae.\n"); 02767 return NIL(array_t); 02768 } 02769 02770 return ltlConstraintArray; 02771 02772 } /* BmcReadFairnessConstraints */ 02773 02774 02782 int 02783 BmcGetCnfVarIndexForBddNode( 02784 bdd_manager *bddManager, 02785 bdd_node *node, 02786 int state, 02787 BmcCnfClauses_t *cnfClauses) 02788 { 02789 array_t *mvar_list = mdd_ret_mvar_list(bddManager); 02790 array_t *bvar_list = mdd_ret_bvar_list(bddManager); 02791 02792 char name[100]; 02793 char *nodeName; 02794 bvar_type bv; 02795 mvar_type mv; 02796 int nodeIndex = bdd_node_read_index(node); 02797 int index, rtnNodeIndex, rtnCode; 02798 02799 02800 /* 02801 If the node is for a multi-valued varaible. 02802 */ 02803 if (nodeIndex < array_n(bvar_list)){ 02804 bv = array_fetch(bvar_type, bvar_list, nodeIndex); 02805 /* 02806 get the multi-valued varaible. 02807 */ 02808 mv = array_fetch(mvar_type, mvar_list, bv.mvar_id); 02809 arrayForEachItem(int, mv.bvars, index, rtnNodeIndex) { 02810 if (nodeIndex == rtnNodeIndex){ 02811 break; 02812 } 02813 } 02814 assert(index < mv.encode_length); 02815 /* 02816 printf("Name of bdd node %s %d\n", mv.name, index); 02817 */ 02818 sprintf(name, "%s_%d", mv.name, index); 02819 } else { 02820 sprintf(name, "Bdd_%d", nodeIndex); 02821 } 02822 nodeName = util_strsav(name); 02823 rtnCode = BmcCnfReadOrInsertNode(cnfClauses, nodeName, state, &nodeIndex); 02824 if(rtnCode == 1) { 02825 FREE(nodeName); 02826 } 02827 return nodeIndex; 02828 } 02829 02830 /*---------------------------------------------------------------------------*/ 02831 /* Definition of static functions */ 02832 /*---------------------------------------------------------------------------*/ 02833 02844 static int 02845 StringCheckIsInteger( 02846 char *string, 02847 int *value) 02848 { 02849 char *ptr; 02850 long l; 02851 02852 l = strtol (string, &ptr, 0) ; 02853 if(*ptr != '\0') 02854 return 0; 02855 if ((l > MAXINT) || (l < -1 - MAXINT)) 02856 return 1 ; 02857 *value = (int) l; 02858 return 2 ; 02859 } 02860 02870 static int 02871 nameCompare( 02872 const void * name1, 02873 const void * name2) 02874 { 02875 return(strcmp(*(char**)name1, *(char **)name2)); 02876 02877 } /* end of signatureCompare */ 02878 02879 02880 02881 02893 static void 02894 printValue( 02895 mAig_Manager_t *manager, 02896 Ntk_Network_t *network, 02897 st_table *nodeToMvfAigTable, 02898 BmcCnfClauses_t *cnfClauses, 02899 array_t *varNames, 02900 st_table *resultTable, 02901 int state, 02902 int *prevValue) 02903 { 02904 Ntk_Node_t *node; 02905 int i, j; 02906 bAigEdge_t bAigId; 02907 nameType_t *varName, *nodeName; 02908 int value, index; 02909 MvfAig_Function_t *MvfAig; 02910 int changed = 0; 02911 int tmp; 02912 02913 for (j=0; j< array_n(varNames); j++) { 02914 if (state == 0){ 02915 prevValue[j] = -1; 02916 } 02917 nodeName = array_fetch(char *, varNames, j); 02918 /* 02919 Fetch the node corresponding to this node name. 02920 */ 02921 node = Ntk_NetworkFindNodeByName(network, nodeName); 02922 /* 02923 Get the multi-valued function for each node 02924 */ 02925 MvfAig = Bmc_ReadMvfAig(node, nodeToMvfAigTable); 02926 /* 02927 In case of the multi-valued function is not build for this node, do nothing. 02928 We may notify the user. 02929 */ 02930 if (MvfAig == NIL(MvfAig_Function_t)){ 02931 continue; 02932 } 02933 /* 02934 No CNF index for this variable at time "state in the " 02935 */ 02936 value = -1; 02937 for (i=0; i< array_n(MvfAig); i++) { 02938 bAigId = MvfAig_FunctionReadComponent(MvfAig, i); 02939 /* 02940 constant value 02941 */ 02942 if (bAigId == bAig_One){ 02943 /* 02944 This variable equal the constant i. 02945 */ 02946 value = i; 02947 break; 02948 } 02949 if (bAigId != bAig_Zero){ 02950 char *tmpStr; 02951 02952 nodeName = bAig_NodeReadName(manager, bAigId); 02953 /* 02954 Build the variable name at state "state". 02955 */ 02956 tmpStr = util_inttostr(state); 02957 varName = util_strcat3(nodeName, "_", tmpStr); 02958 if (st_lookup_int(cnfClauses->cnfIndexTable, varName, &index)) { 02959 if (bAig_IsInverted(bAigId)){ 02960 index = -index; 02961 } 02962 /*if (searchArray(result, index) > -1){*/ 02963 if (st_lookup_int(resultTable, (char *)(long)index, &tmp)){ 02964 value = i; 02965 break; 02966 } 02967 } /* if st_lookup_int() */ 02968 FREE(tmpStr); 02969 FREE(varName); 02970 } /* if (bAigId != bAig_Zero) */ 02971 } 02972 if (value >= 0){ 02973 if (value != prevValue[j]){ 02974 Var_Variable_t *nodeVar = Ntk_NodeReadVariable(node); 02975 02976 prevValue[j] = value; 02977 changed = 1; 02978 if (Var_VariableTestIsSymbolic(nodeVar)) { 02979 char *symbolicValue = Var_VariableReadSymbolicValueFromIndex(nodeVar, value); 02980 02981 (void) fprintf(vis_stdout,"%s:%s\n", Ntk_NodeReadName(node), symbolicValue); 02982 } 02983 else { 02984 (void) fprintf(vis_stdout,"%s:%d\n", Ntk_NodeReadName(node), value); 02985 } 02986 } 02987 } else { 02988 /* 02989 This variable does not have value in the current time frame. It means its value 02990 is not important at this time frame. 02991 */ 02992 (void) fprintf(vis_stdout,"%s:X\n", Ntk_NodeReadName(node)); 02993 } 02994 } /* for j loop */ 02995 if (changed == 0){ 02996 fprintf( vis_stdout, "<Unchanged>\n"); 02997 } 02998 02999 }/* end of printValue() */ 03000 03001 03002 03016 static void 03017 printValueAiger( 03018 mAig_Manager_t *manager, 03019 Ntk_Network_t *network, 03020 st_table *nodeToMvfAigTable, 03021 BmcCnfClauses_t *cnfClauses, 03022 array_t *varNames, 03023 st_table *resultTable, 03024 int state, 03025 int *prevValue) 03026 { 03027 Ntk_Node_t *node; 03028 int i, j; 03029 bAigEdge_t bAigId; 03030 nameType_t *varName, *nodeName; 03031 int value, index; 03032 MvfAig_Function_t *MvfAig; 03033 int tmp; 03034 char * NodeName; 03035 03036 for (j=0; j< array_n(varNames); j++) { 03037 if (state == 0){ 03038 prevValue[j] = -1; 03039 } 03040 nodeName = array_fetch(char *, varNames, j); 03041 /* 03042 Fetch the node corresponding to this node name. 03043 */ 03044 node = Ntk_NetworkFindNodeByName(network, nodeName); 03045 /* 03046 Get the multi-valued function for each node 03047 */ 03048 MvfAig = Bmc_ReadMvfAig(node, nodeToMvfAigTable); 03049 /* 03050 In case of the multi-valued function is not build for this node, do nothing. 03051 We may notify the user. 03052 */ 03053 if (MvfAig == NIL(MvfAig_Function_t)){ 03054 continue; 03055 } 03056 /* 03057 No CNF index for this variable at time "state in the " 03058 */ 03059 value = -1; 03060 for (i=0; i< array_n(MvfAig); i++) { 03061 bAigId = MvfAig_FunctionReadComponent(MvfAig, i); 03062 /* 03063 constant value 03064 */ 03065 if (bAigId == bAig_One){ 03066 /* 03067 This variable equal the constant i. 03068 */ 03069 value = i; 03070 break; 03071 } 03072 if (bAigId != bAig_Zero){ 03073 char *tmpStr; 03074 03075 nodeName = bAig_NodeReadName(manager, bAigId); 03076 /* 03077 Build the variable name at state "state". 03078 */ 03079 tmpStr = util_inttostr(state); 03080 varName = util_strcat3(nodeName, "_", tmpStr); 03081 if (st_lookup_int(cnfClauses->cnfIndexTable, varName, &index)) { 03082 if (bAig_IsInverted(bAigId)){ 03083 index = -index; 03084 } 03085 /*if (searchArray(result, index) > -1){*/ 03086 if (st_lookup_int(resultTable, (char *)(long)index, &tmp)){ 03087 value = i; 03088 break; 03089 } 03090 } /* if st_lookup_int() */ 03091 FREE(tmpStr); 03092 FREE(varName); 03093 } /* if (bAigId != bAig_Zero) */ 03094 } 03095 NodeName = Ntk_NodeReadName(node); 03096 if(!((NodeName[0] == '$') && (NodeName[1] == '_'))) 03097 { 03098 if (value >= 0){ 03099 Var_Variable_t *nodeVar = Ntk_NodeReadVariable(node); 03100 03101 prevValue[j] = value; 03102 if (Var_VariableTestIsSymbolic(nodeVar)) { 03103 char *symbolicValue = Var_VariableReadSymbolicValueFromIndex(nodeVar, value); 03104 03105 (void) fprintf(vis_stdout,"%s", symbolicValue); 03106 } 03107 else { 03108 (void) fprintf(vis_stdout,"%d", value); 03109 } 03110 } else { 03111 /* 03112 This variable does not have value in the current time frame. It means its value 03113 is not important at this time frame. 03114 */ 03115 (void) fprintf(vis_stdout,"x" ); 03116 } 03117 } /* these nodes are latches in front of inputs so they will be printed out as inputs */ 03118 } /* for j loop */ 03119 }/* end of printValueAiger() */ 03120 03121 03136 static void 03137 printValueAigerInputs( 03138 mAig_Manager_t *manager, 03139 Ntk_Network_t *network, 03140 st_table *nodeToMvfAigTable, 03141 BmcCnfClauses_t *cnfClauses, 03142 array_t *varNames, 03143 st_table *resultTable, 03144 int state, 03145 int *prevValue) 03146 { 03147 Ntk_Node_t *node; 03148 int i, j; 03149 bAigEdge_t bAigId; 03150 nameType_t *varName, *nodeName; 03151 int value, index; 03152 MvfAig_Function_t *MvfAig; 03153 int tmp; 03154 char * NodeName; 03155 03156 for (j=0; j< array_n(varNames); j++) { 03157 if (state == 0){ 03158 prevValue[j] = -1; 03159 } 03160 nodeName = array_fetch(char *, varNames, j); 03161 /* 03162 Fetch the node corresponding to this node name. 03163 */ 03164 node = Ntk_NetworkFindNodeByName(network, nodeName); 03165 /* 03166 Get the multi-valued function for each node 03167 */ 03168 MvfAig = Bmc_ReadMvfAig(node, nodeToMvfAigTable); 03169 /* 03170 In case of the multi-valued function is not build for this node, do nothing. 03171 We may notify the user. 03172 */ 03173 if (MvfAig == NIL(MvfAig_Function_t)){ 03174 continue; 03175 } 03176 /* 03177 No CNF index for this variable at time "state in the " 03178 */ 03179 value = -1; 03180 for (i=0; i< array_n(MvfAig); i++) { 03181 bAigId = MvfAig_FunctionReadComponent(MvfAig, i); 03182 /* 03183 constant value 03184 */ 03185 if (bAigId == bAig_One){ 03186 /* 03187 This variable equal the constant i. 03188 */ 03189 value = i; 03190 break; 03191 } 03192 if (bAigId != bAig_Zero){ 03193 char *tmpStr; 03194 03195 nodeName = bAig_NodeReadName(manager, bAigId); 03196 /* 03197 Build the variable name at state "state". 03198 */ 03199 tmpStr = util_inttostr(state); 03200 varName = util_strcat3(nodeName, "_", tmpStr); 03201 if (st_lookup_int(cnfClauses->cnfIndexTable, varName, &index)) { 03202 if (bAig_IsInverted(bAigId)){ 03203 index = -index; 03204 } 03205 /*if (searchArray(result, index) > -1){*/ 03206 if (st_lookup_int(resultTable, (char *)(long)index, &tmp)){ 03207 value = i; 03208 break; 03209 } 03210 } /* if st_lookup_int() */ 03211 FREE(tmpStr); 03212 FREE(varName); 03213 } /* if (bAigId != bAig_Zero) */ 03214 } 03215 NodeName = Ntk_NodeReadName(node); 03216 if((NodeName[0] == '$') && (NodeName[1] == '_')) 03217 { 03218 if (value >= 0){ 03219 Var_Variable_t *nodeVar = Ntk_NodeReadVariable(node); 03220 03221 prevValue[j] = value; 03222 if (Var_VariableTestIsSymbolic(nodeVar)) { 03223 char *symbolicValue = Var_VariableReadSymbolicValueFromIndex(nodeVar, value); 03224 03225 (void) fprintf(vis_stdout,"%s", symbolicValue); 03226 } 03227 else { 03228 (void) fprintf(vis_stdout,"%d", value); 03229 } 03230 } else { 03231 /* 03232 This variable does not have value in the current time frame. It means its value 03233 is not important at this time frame. 03234 */ 03235 (void) fprintf(vis_stdout,"x" ); 03236 } 03237 } /* these nodes are latches in front of inputs so they will be printed out as inputs */ 03238 } /* for j loop */ 03239 }/* end of printValueAigerInputs() */ 03240 03241 03242