VIS

src/bmc/bmcUtil.c

Go to the documentation of this file.
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