VIS

src/grab/grabUtil.c

Go to the documentation of this file.
00001 
00030 #include "grabInt.h"
00031 
00032 /*---------------------------------------------------------------------------*/
00033 /* Constant declarations                                                     */
00034 /*---------------------------------------------------------------------------*/
00035 
00036 /*---------------------------------------------------------------------------*/
00037 /* Structure declarations                                                    */
00038 /*---------------------------------------------------------------------------*/
00039 
00040 /*---------------------------------------------------------------------------*/
00041 /* Type declarations                                                         */
00042 /*---------------------------------------------------------------------------*/
00043 
00044 /*---------------------------------------------------------------------------*/
00045 /* Variable declarations                                                     */
00046 /*---------------------------------------------------------------------------*/
00047 
00048 /*---------------------------------------------------------------------------*/
00049 /* Macro declarations                                                        */
00050 /*---------------------------------------------------------------------------*/
00051 
00054 /*---------------------------------------------------------------------------*/
00055 /* Static function prototypes                                                */
00056 /*---------------------------------------------------------------------------*/
00057 
00058 static void GetFormulaNodes(Ntk_Network_t *network, Ctlp_Formula_t *F, array_t *formulaNodes);
00059 static void GetFaninLatches(Ntk_Node_t *node, st_table *visited, st_table *absVarTable);
00060 static void NodeTableAddCtlFormulaNodes(Ntk_Network_t *network, Ctlp_Formula_t *formula, st_table * nodesTable);
00061 
00064 /*---------------------------------------------------------------------------*/
00065 /* Definition of internal functions                                          */
00066 /*---------------------------------------------------------------------------*/
00067 
00078 st_table *
00079 GrabComputeCOIAbstraction(
00080   Ntk_Network_t *network,
00081   Ctlp_Formula_t *invFormula)
00082 {
00083   st_table     *formulaNodes;
00084   array_t      *formulaCombNodes;
00085   Ntk_Node_t   *node;
00086   array_t      *nodeArray;
00087   int          i;
00088   st_generator *stGen;
00089   st_table *absVarTable;
00090 
00091   /* find network nodes in the immediate support of the property */
00092   formulaNodes = st_init_table(st_ptrcmp, st_ptrhash);
00093   NodeTableAddCtlFormulaNodes(network, invFormula, formulaNodes);
00094 
00095   /* find network nodes in the transitive fan-in */
00096   nodeArray = array_alloc(Ntk_Node_t *, 0);
00097   st_foreach_item(formulaNodes, stGen,  & node, NIL(char *)) {
00098     array_insert_last( Ntk_Node_t *, nodeArray, node);
00099   }
00100   st_free_table(formulaNodes);
00101   formulaCombNodes = Ntk_NodeComputeTransitiveFaninNodes(network, nodeArray,
00102                                                          FALSE, TRUE);
00103   array_free(nodeArray);
00104 
00105   /* extract all the latches */
00106   absVarTable = st_init_table(st_ptrcmp, st_ptrhash);
00107   arrayForEachItem(Ntk_Node_t *, formulaCombNodes, i, node) {
00108     if (Ntk_NodeTestIsLatch(node) == TRUE) {
00109       st_insert(absVarTable, node, (char *)0);
00110     }
00111   }
00112   array_free(formulaCombNodes);
00113   
00114   return absVarTable;
00115 }
00116 
00127 st_table *
00128 GrabComputeInitialAbstraction(
00129   Ntk_Network_t *network, 
00130   Ctlp_Formula_t *invFormula)
00131 {
00132   array_t    *formulaNodes = array_alloc(Ntk_Node_t *, 0);
00133   Ntk_Node_t *node;
00134   int        i;
00135   st_table   *absVarTable, *visited;
00136 
00137   GetFormulaNodes(network, invFormula, formulaNodes);
00138 
00139   absVarTable = st_init_table(st_ptrcmp, st_ptrhash);
00140   visited = st_init_table(st_ptrcmp, st_ptrhash);
00141   arrayForEachItem(Ntk_Node_t *, formulaNodes, i, node) {
00142     GetFaninLatches(node, visited, absVarTable);
00143   }
00144 
00145   st_free_table(visited);
00146   array_free(formulaNodes);
00147   
00148   return absVarTable;
00149 }
00150 
00170 void
00171 GrabUpdateAbstractPartition(
00172   Ntk_Network_t *network,
00173   st_table *coiBnvTable,
00174   st_table *absVarTable,
00175   st_table *absBnvTable,
00176   int partitionFlag)
00177 {
00178   graph_t *newPart;
00179   st_table *useAbsBnvTable = absBnvTable? absBnvTable:coiBnvTable;
00180   
00181   if (partitionFlag == GRAB_PARTITION_BUILD) {
00182 
00183     /* free the existing partition */
00184     Ntk_NetworkFreeApplInfo(network, PART_NETWORK_APPL_KEY);
00185 
00186     /* insert bnvs whenever necessary. Note that when the current
00187      * partition is not available, this function will create new bnvs
00188      * and put them into the coiBnvTable. Otherwise, it retrieves
00189      * existing bnvs from the current partiton */
00190     Part_PartitionReadOrCreateBnvs(network, absVarTable, coiBnvTable);
00191 
00192     /* create the new partition */
00193     newPart = g_alloc();
00194     newPart->user_data = (gGeneric)PartPartitionInfoCreate("default",
00195                                         Ntk_NetworkReadMddManager(network),
00196                                                            Part_Frontier_c);
00197     Part_PartitionWithExistingBnvs(network, newPart, coiBnvTable, 
00198                                    absVarTable, useAbsBnvTable);
00199     Ntk_NetworkAddApplInfo(network, PART_NETWORK_APPL_KEY,
00200                            (Ntk_ApplInfoFreeFn) Part_PartitionFreeCallback,
00201                            (void *) newPart);
00202 
00203   }else if (partitionFlag == GRAB_PARTITION_UPDATE) {
00204     fprintf(vis_stdout, 
00205             "\n ** grab error: GRAB_PARTITION_UPDATE not implemented\n");
00206     assert(0);
00207   }
00208 
00209 }
00210 
00229 Fsm_Fsm_t *
00230 GrabCreateAbstractFsm( 
00231   Ntk_Network_t *network,
00232   st_table *coiBnvTable,
00233   st_table *absVarTable,
00234   st_table *absBnvTable,
00235   int partitionFlag,
00236   int independentFlag)
00237 {
00238   Fsm_Fsm_t    *fsm;
00239   array_t *absLatches = array_alloc(Ntk_Node_t *, 0);
00240   array_t *invisibleVars = array_alloc(Ntk_Node_t *, 0);
00241   array_t *absInputs = array_alloc(Ntk_Node_t *, 0);
00242   array_t *rootNodesArray = array_alloc(Ntk_Node_t *, 0);
00243   st_table *rawLeafNodesTable = st_init_table(st_ptrcmp, st_ptrhash);
00244   lsList topologicalNodeList;
00245   lsGen  lsgen;
00246   st_generator *stgen;
00247   Ntk_Node_t *node;
00248 
00249   GrabUpdateAbstractPartition(network, coiBnvTable, absVarTable, absBnvTable,
00250                               partitionFlag);
00251 
00252   /* first, compute the absLatches, invisibleVars, and absInputs:
00253    * absLatches includes all the visible latch variables;
00254    * invisibleVars includes all the invisible latches variables; 
00255    * absInputs includes all the primary and pseudo inputs.
00256    */
00257   st_foreach_item(absVarTable, stgen, &node, NIL(char *)) {
00258     array_insert_last(Ntk_Node_t *, absLatches, node);
00259     array_insert_last(Ntk_Node_t *, rootNodesArray, 
00260                       Ntk_LatchReadDataInput(node));
00261     array_insert_last(Ntk_Node_t *, rootNodesArray, 
00262                       Ntk_LatchReadInitialInput(node));
00263   }
00264     
00265   Ntk_NetworkForEachCombInput(network, lsgen, node) {
00266     st_insert(rawLeafNodesTable, node, (char *) (long) (-1) );
00267   }
00268   st_foreach_item(coiBnvTable, stgen, &node, NIL(char *)) {
00269     /* unless it blongs to the current Abstract Model */
00270     if (absBnvTable && !st_is_member(absBnvTable, node))
00271       st_insert(rawLeafNodesTable, node, (char *) (long) (-1) );
00272   }
00273 
00274   topologicalNodeList = Ntk_NetworkComputeTopologicalOrder(network,
00275                                                            rootNodesArray,
00276                                                            rawLeafNodesTable);
00277   lsForEachItem(topologicalNodeList, lsgen, node){
00278     if (st_is_member(rawLeafNodesTable, node) &&
00279         !st_is_member(absVarTable, node) ) {
00280       /*if (Ntk_NodeTestIsLatch(node) || 
00281         coiBnvTable && st_is_member(coiBnvTable, node))*/
00282       if (Ntk_NodeTestIsLatch(node) || 
00283           (coiBnvTable && st_is_member(coiBnvTable, node)))
00284         array_insert_last(Ntk_Node_t *, invisibleVars, node);
00285       else
00286         array_insert_last(Ntk_Node_t *, absInputs, node);
00287     }
00288   }
00289   
00290   lsDestroy(topologicalNodeList, (void (*)(lsGeneric))0);
00291   st_free_table(rawLeafNodesTable);
00292   array_free(rootNodesArray);
00293 
00294 
00295   /* now, create the abstract Fsm according to the value of
00296    * independentFlag when independentFlag is TRUE, the present state
00297    * varaibles are absLatches; otherwise, they contain both absLatches
00298    * and invisibleVars (with such a FSM, preimages may contain
00299    * invisible vars in their supports)
00300    */
00301   fsm = Fsm_FsmCreateAbstractFsm(network, NIL(graph_t), 
00302                                  absLatches, invisibleVars, absInputs, 
00303                                  NIL(array_t), independentFlag);
00304 
00305 #if 0
00306   /* for debugging */
00307   if (partitionFlag == GRAB_PARTITION_NOCHANGE) {
00308     GrabPrintNodeArray("absLatches", absLatches);
00309     GrabPrintNodeArray("invisibleVars", invisibleVars);
00310     GrabPrintNodeArray("absInputs", absInputs);
00311   }
00312 #endif
00313 
00314   array_free(invisibleVars);
00315   array_free(absInputs);
00316   array_free(absLatches);
00317 
00318 
00319   return fsm;
00320 }
00321 
00346 mdd_t *
00347 GrabComputeInitialStates(
00348   Ntk_Network_t *network,
00349   array_t *psVars)
00350 {
00351   int            i = 0;
00352   mdd_t         *initStates;
00353   Ntk_Node_t    *node;
00354   array_t       *initRelnArray;
00355   array_t       *initMvfs;
00356   array_t       *initNodes;
00357   array_t       *initVertices;
00358   array_t       *latchMddIds;
00359   array_t       *inputVars = array_alloc(int, 0);
00360   array_t       *combArray;
00361   st_table      *supportNodes;
00362   st_table      *supportVertices;
00363   mdd_manager   *mddManager = Ntk_NetworkReadMddManager(network);
00364   graph_t       *partition  =
00365     (graph_t *) Ntk_NetworkReadApplInfo(network, PART_NETWORK_APPL_KEY);
00366   int            numLatches;
00367   Img_MethodType imageMethod;
00368   
00369   numLatches = array_n(psVars);
00370 
00371   /* Get the array of initial nodes, both as network nodes and as
00372    * partition vertices.
00373    */
00374   initNodes    = array_alloc(Ntk_Node_t *, numLatches);
00375   initVertices = array_alloc(vertex_t *, numLatches);
00376   latchMddIds  = array_alloc(int, numLatches);
00377   for (i=0; i<numLatches; i++){
00378     int latchMddId = array_fetch(int, psVars, i);
00379     Ntk_Node_t *latch = Ntk_NetworkFindNodeByMddId(network, latchMddId);
00380     Ntk_Node_t *initNode   = Ntk_LatchReadInitialInput(latch);
00381     vertex_t   *initVertex = Part_PartitionFindVertexByName(partition,
00382                                 Ntk_NodeReadName(initNode));
00383     array_insert(Ntk_Node_t *, initNodes, i, initNode);
00384     array_insert(vertex_t *, initVertices, i, initVertex);
00385     array_insert(int, latchMddIds, i, Ntk_NodeReadMddId(latch));
00386   }
00387 
00388   /* Get the table of legal support nodes, both as network nodes and
00389    * as partition vertices. Inputs (both primary and pseudo) and
00390    * constants constitute the legal support nodes.
00391    */
00392   supportNodes    = st_init_table(st_ptrcmp, st_ptrhash);
00393   supportVertices = st_init_table(st_ptrcmp, st_ptrhash);
00394   combArray = Ntk_NodeComputeTransitiveFaninNodes(network, initNodes, TRUE,
00395                                                   TRUE);
00396   arrayForEachItem(Ntk_Node_t *, combArray, i, node) {
00397     vertex_t *vertex = Part_PartitionFindVertexByName(partition,
00398                                                       Ntk_NodeReadName(node));
00399     if (Ntk_NodeTestIsConstant(node) || Ntk_NodeTestIsInput(node)) {
00400       st_insert(supportNodes,  node, NIL(char));
00401       st_insert(supportVertices,  vertex, NIL(char));
00402     }
00403     if (Ntk_NodeTestIsInput(node)) {
00404       assert(Ntk_NodeReadMddId(node) != -1);
00405       array_insert_last(int, inputVars, Ntk_NodeReadMddId(node));
00406     }
00407   }
00408   array_free(combArray);
00409   array_free(initNodes);
00410   st_free_table(supportNodes);
00411 
00412   /* Compute the initial states 
00413    */
00414   initMvfs = Part_PartitionCollapse(partition, initVertices,
00415                                     supportVertices, NIL(mdd_t)); 
00416   array_free(initVertices);
00417   st_free_table(supportVertices);
00418 
00419   /* Compute the relation (x_i = g_i(u)) for each latch. */
00420   initRelnArray = array_alloc(mdd_t*, numLatches);
00421   for (i = 0; i < numLatches; i++) {
00422     int latchMddId = array_fetch(int, latchMddIds, i);
00423     Mvf_Function_t *initMvf = array_fetch(Mvf_Function_t *, initMvfs, i);
00424     mdd_t *initLatchReln = Mvf_FunctionBuildRelationWithVariable(initMvf,
00425                                                                 latchMddId);
00426     array_insert(mdd_t *, initRelnArray, i, initLatchReln);
00427   }
00428 
00429   array_free(latchMddIds);
00430   Mvf_FunctionArrayFree(initMvfs);
00431 
00432   imageMethod = Img_UserSpecifiedMethod();
00433   if (imageMethod != Img_Iwls95_c && imageMethod != Img_Mlp_c)
00434     imageMethod = Img_Iwls95_c;
00435 
00436   initStates = Img_MultiwayLinearAndSmooth(mddManager, initRelnArray,
00437                                            inputVars, psVars,
00438                                            imageMethod, Img_Forward_c); 
00439   
00440   mdd_array_free(initRelnArray); 
00441   
00442   array_free(inputVars);
00443   
00444   return (initStates);
00445 }
00446 
00456 mdd_t *
00457 GrabFsmComputeReachableStates(
00458   Fsm_Fsm_t *absFsm,
00459   st_table  *absVarTable,
00460   st_table  *absBnvTable,
00461   array_t   *invStatesArray,
00462   int       verbose)
00463 {
00464   mdd_manager     *mddManager = Fsm_FsmReadMddManager(absFsm);
00465   Img_ImageInfo_t *imageInfo;
00466   array_t         *fwdOnionRings;
00467   mdd_t           *initStates, *mdd1,  *mddOne, *rchStates, *frontier;
00468   
00469   imageInfo = Fsm_FsmReadOrCreateImageInfo(absFsm, 0, 1);
00470 
00471   fwdOnionRings = array_alloc(mdd_t *, 0);
00472   mddOne = mdd_one(mddManager);
00473   initStates = Fsm_FsmComputeInitialStates(absFsm);
00474   array_insert_last(mdd_t *, fwdOnionRings, initStates);
00475   rchStates = mdd_dup(initStates);
00476 
00477   frontier = initStates;
00478   while(TRUE) {
00479     mdd1 = Img_ImageInfoComputeFwdWithDomainVars(imageInfo, frontier,
00480                                                  rchStates, mddOne);
00481     frontier = mdd_and(mdd1, rchStates, 1, 0);
00482     mdd_free(mdd1);
00483 
00484     mdd1 = rchStates;
00485     rchStates = mdd_or(rchStates, frontier, 1, 1);
00486     mdd_free(mdd1);
00487 
00488     if (mdd_is_tautology(frontier, 0)) {
00489       mdd_free(frontier);
00490       break;
00491     }
00492     array_insert_last(mdd_t *, fwdOnionRings, frontier);
00493 
00494     /* if this happens, the invariant is voilated */
00495     if (!mdd_lequal_array(frontier, invStatesArray, 1, 1))
00496       break;
00497   }
00498 
00499   mdd_free(mddOne);
00500 
00501   FsmSetReachabilityOnionRings(absFsm, fwdOnionRings);
00502 
00503   return rchStates;
00504 }
00505 
00515 mdd_t *
00516 GrabFsmComputeConstrainedReachableStates(
00517   Fsm_Fsm_t *absFsm,
00518   st_table *absVarTable,
00519   st_table *absBnvTable,
00520   array_t *SORs,
00521   int verbose)
00522 {
00523   mdd_manager     *mddManager = Fsm_FsmReadMddManager(absFsm);
00524   Img_ImageInfo_t *imageInfo;
00525   array_t         *rchOnionRings;
00526   mdd_t           *mdd1, *mdd2, *mdd3, *mdd4;
00527   mdd_t           *mddOne, *initStates, *rchStates;
00528   int             i;
00529 
00530   assert (SORs != NIL(array_t));
00531 
00532   imageInfo = Fsm_FsmReadOrCreateImageInfo(absFsm, 0, 1);
00533 
00534   rchOnionRings = array_alloc(mdd_t *, 0);
00535   mddOne = mdd_one(mddManager);
00536 
00537   /* the new initial states */
00538   mdd2 = array_fetch(mdd_t *, SORs, 0);
00539   mdd1 = Fsm_FsmComputeInitialStates(absFsm);
00540   initStates = mdd_and(mdd1, mdd2, 1, 1);
00541   mdd_free(mdd1);
00542   array_insert(mdd_t *, rchOnionRings, 0, initStates);
00543 
00544   /* compute the reachable states inside the previous SORs */
00545   rchStates = mdd_dup(initStates);
00546   for (i=0; i<array_n(SORs)-1; i++) {
00547     mdd1 = array_fetch(mdd_t *, rchOnionRings, i);
00548     mdd2 = Img_ImageInfoComputeFwdWithDomainVars(imageInfo,
00549                                                  mdd1,
00550                                                  rchStates,
00551                                                  mddOne);
00552 
00553     mdd3 = array_fetch(mdd_t *, SORs, i+1);
00554     mdd4 = mdd_and(mdd2, mdd3, 1, 1);
00555     mdd_free(mdd2);
00556 
00557     /* if this happens, the last ring is no longer reachable */
00558     if (mdd_is_tautology(mdd4, 0)) {
00559       mdd_free(mdd4);
00560       break;
00561     }
00562     array_insert(mdd_t *, rchOnionRings, i+1, mdd4);
00563 
00564     mdd1 = rchStates;
00565     rchStates = mdd_or(rchStates, mdd4, 1, 1);
00566     mdd_free(mdd1);
00567   }
00568 
00569   mdd_free(mddOne);
00570 
00571   FsmSetReachabilityOnionRings(absFsm, rchOnionRings);
00572 
00573   return rchStates;
00574 }
00575 
00595 array_t *
00596 GrabFsmComputeSynchronousOnionRings(
00597   Fsm_Fsm_t *absFsm,
00598   st_table  *absVarTable,
00599   st_table  *absBnvTable,
00600   array_t   *oldRings,
00601   mdd_t     *inv_states,
00602   int       cexType,
00603   int       verbose)
00604 {
00605   mdd_manager     *mddManager = Fsm_FsmReadMddManager(absFsm);
00606   Img_ImageInfo_t *imageInfo;
00607   array_t         *onionRings, *synOnionRings;
00608   array_t         *allPSVars;
00609   mdd_t           *mddOne, *ring;
00610   mdd_t           *mdd1, *mdd2, *mdd3, *mdd4;
00611   int             j;
00612 
00613   imageInfo = Fsm_FsmReadOrCreateImageInfo(absFsm, 1, 0);
00614 
00615   /* get the forward reachability onion rings */
00616   onionRings = oldRings;
00617   if (onionRings == NIL(array_t))
00618     onionRings = Fsm_FsmReadReachabilityOnionRings(absFsm);
00619   assert(onionRings);
00620 
00621   synOnionRings = array_alloc(mdd_t *, array_n(onionRings));
00622 
00623   mddOne = mdd_one(mddManager);
00624   allPSVars = Fsm_FsmReadPresentStateVars(absFsm);
00625 
00626   /* the last ring */
00627   mdd2 = array_fetch_last(mdd_t *, onionRings);
00628   mdd1 = mdd_and(mdd2, inv_states, 1, 0);
00629   if (cexType == GRAB_CEX_MINTERM)
00630     ring = Mc_ComputeAMinterm(mdd1, allPSVars, mddManager);
00631   else if (cexType == GRAB_CEX_CUBE) {
00632     array_t *bddIds = mdd_get_bdd_support_ids(mddManager, mdd1);
00633     int nvars = array_n(bddIds);
00634     array_free(bddIds);
00635     ring = bdd_approx_remap_ua(mdd1, (bdd_approx_dir_t)BDD_UNDER_APPROX,
00636                                nvars, 1024, 1);
00637     if (ring == NIL(mdd_t)) 
00638       ring = mdd_dup(mdd1);   
00639   }else 
00640     ring = mdd_dup(mdd1);
00641   mdd_free(mdd1);
00642   array_insert(mdd_t *, synOnionRings, array_n(onionRings)-1, ring);
00643 
00644   /* the rest rings */
00645   for (j=array_n(onionRings)-2; j>=0; j--) {
00646     mdd1 = array_fetch(mdd_t *, synOnionRings, j+1);
00647     mdd2 = Img_ImageInfoComputeBwdWithDomainVars(imageInfo,
00648                                                  mdd1,
00649                                                  mdd1,
00650                                                  mddOne);
00651 
00652     mdd3 = array_fetch(mdd_t *, onionRings, j);
00653     mdd4 = mdd_and(mdd2, mdd3, 1, 1);
00654     mdd_free(mdd2);
00655 
00656     if (cexType == GRAB_CEX_MINTERM) 
00657       ring = Mc_ComputeAMinterm(mdd4, allPSVars, mddManager);
00658     else if (cexType == GRAB_CEX_CUBE) {
00659       array_t *bddIds = mdd_get_bdd_support_ids(mddManager, mdd4);
00660       int nvars = array_n(bddIds);
00661       array_free(bddIds);
00662       ring = bdd_approx_remap_ua(mdd4, (bdd_approx_dir_t)BDD_UNDER_APPROX,
00663                                  nvars, 1024, 1);
00664       if (ring == NIL(mdd_t)) 
00665         ring = mdd_dup(mdd4);   
00666     }else 
00667       ring = mdd_dup(mdd4);
00668     mdd_free(mdd4);
00669     array_insert(mdd_t *, synOnionRings, j, ring);
00670   }
00671   
00672   mdd_free(mddOne);
00673 
00674   return synOnionRings;
00675 }
00676 
00687 array_t *
00688 GrabGetVisibleVarMddIds (
00689   Fsm_Fsm_t *absFsm,
00690   st_table *absVarTable)
00691 {
00692   array_t       *visibleVarMddIds = array_alloc(int, 0);
00693   st_generator  *stgen;
00694   Ntk_Node_t    *node;
00695   int           mddId;
00696 
00697   st_foreach_item(absVarTable, stgen, &node, NIL(char *)) {
00698     mddId = Ntk_NodeReadMddId(node);
00699     array_insert_last(int, visibleVarMddIds, mddId);
00700   }
00701 
00702   return visibleVarMddIds;
00703 }
00704 
00705 
00717 array_t *
00718 GrabGetInvisibleVarMddIds(
00719   Fsm_Fsm_t *absFsm,
00720   st_table *absVarTable,
00721   st_table *absBnvTable)
00722 {
00723   Ntk_Network_t *network = Fsm_FsmReadNetwork(absFsm);
00724   array_t       *inputVars = Fsm_FsmReadInputVars(absFsm);
00725   array_t       *invisibleVarMddIds = array_alloc(int, 0);
00726   Ntk_Node_t    *node;
00727   int           i, mddId;
00728 
00729   arrayForEachItem(int, inputVars, i, mddId) {
00730     node = Ntk_NetworkFindNodeByMddId(network, mddId);
00731     if ( !Ntk_NodeTestIsInput(node) && 
00732          !st_is_member(absVarTable, node) ) {
00733       if (absBnvTable != NIL(st_table)) {
00734         if (!st_is_member(absBnvTable, node)) {
00735           array_insert_last(int, invisibleVarMddIds, mddId);
00736         }
00737       }else
00738         array_insert_last(int, invisibleVarMddIds, mddId);
00739     }
00740   }
00741 
00742   return invisibleVarMddIds;
00743 }
00744 
00754 int
00755 GrabTestRefinementSetSufficient(
00756   Ntk_Network_t *network,
00757   array_t *SORs,
00758   st_table *absVarTable,
00759   int verbose)
00760 {
00761   int  is_sufficient;
00762 
00763   is_sufficient = !Bmc_AbstractCheckAbstractTraces(network,
00764                                                    SORs,
00765                                                    absVarTable,
00766                                                    0, 0, 0);
00767   return is_sufficient;
00768 }
00769 
00779 int
00780 GrabTestRefinementBnvSetSufficient(
00781   Ntk_Network_t   *network,
00782   st_table        *coiBnvTable,
00783   array_t         *SORs,
00784   st_table        *absVarTable,
00785   st_table        *absBnvTable,
00786   int             verbose)
00787 {
00788   int     is_sufficient;
00789   
00790   assert(absBnvTable && coiBnvTable);
00791 
00792   is_sufficient = 
00793     !Bmc_AbstractCheckAbstractTracesWithFineGrain(network,
00794                                                   coiBnvTable,
00795                                                   SORs,
00796                                                   absVarTable,
00797                                                   absBnvTable);
00798   return is_sufficient;
00799 }
00800 
00812 void
00813 GrabMinimizeLatchRefinementSet(
00814   Ntk_Network_t *network,
00815   st_table **absVarTable,
00816   st_table **absBnvTable,
00817   array_t *newlyAddedLatches,  
00818   array_t **newlyAddedBnvs,  
00819   array_t *SORs,
00820   int verbose)
00821 {
00822   st_table      *newVertexTable, *oldBnvTable, *transFaninTable;
00823   array_t       *rootArray, *transFanins, *oldNewlyAddedBnvs;
00824   st_generator  *stgen;
00825   Ntk_Node_t    *node;
00826   int           i, flag, n_size, mddId;
00827   
00828   n_size = array_n(newlyAddedLatches);
00829 
00830   if (verbose >= 3) 
00831     fprintf(vis_stdout,
00832             "-- grab: minimize latch refinement set: previous size is %d\n", 
00833             n_size);
00834 
00835   arrayForEachItem(int, newlyAddedLatches, i, mddId) {
00836     node = Ntk_NetworkFindNodeByMddId(network, mddId);
00837     /* first, try to drop it */
00838     newVertexTable = st_copy(*absVarTable);
00839     flag = st_delete(newVertexTable, &node, NIL(char *));
00840     assert(flag);
00841     /* if the counter-example does not come back, drop it officially */
00842     flag = Bmc_AbstractCheckAbstractTraces(network,SORs,
00843                                            newVertexTable, 0, 0, 0);
00844     if (!flag) {
00845       st_free_table(*absVarTable);
00846       *absVarTable = newVertexTable;
00847       n_size--;
00848     }else {
00849       st_free_table(newVertexTable);
00850       if (verbose >= 3)
00851         fprintf(vis_stdout,"         add back %s (latch)\n", 
00852                 Ntk_NodeReadName(node));
00853     }
00854   }
00855 
00856   if (verbose >= 3)
00857     fprintf(vis_stdout,
00858             "-- grab: minimize latch refinement set: current  size is %d\n", 
00859             n_size);
00860 
00861   /* prune away irrelevant BNVs */
00862   if (*absBnvTable != NIL(st_table) && st_count(*absBnvTable)>0) {
00863 
00864     rootArray = array_alloc(Ntk_Node_t *, 0);
00865     st_foreach_item(*absVarTable, stgen, &node, NIL(char *)) {
00866       array_insert_last(Ntk_Node_t *, rootArray, Ntk_LatchReadDataInput(node));
00867       array_insert_last(Ntk_Node_t *, rootArray, 
00868                         Ntk_LatchReadInitialInput(node));
00869     }
00870     transFanins = Ntk_NodeComputeTransitiveFaninNodes(network, rootArray,
00871                                                       TRUE, /*stopAtLatch*/
00872                                                       FALSE /*combInputsOnly*/
00873                                                       );
00874     array_free(rootArray);
00875 
00876     transFaninTable = st_init_table(st_ptrcmp, st_ptrhash);
00877     arrayForEachItem(Ntk_Node_t *, transFanins, i, node) {
00878       st_insert(transFaninTable, node, NIL(char));
00879     }
00880     array_free(transFanins);
00881         
00882     oldBnvTable = *absBnvTable;
00883     oldNewlyAddedBnvs = *newlyAddedBnvs;
00884     *absBnvTable = st_init_table(st_ptrcmp, st_ptrhash);
00885     *newlyAddedBnvs = array_alloc(int, 0);
00886     st_foreach_item(oldBnvTable, stgen, &node, NIL(char *)) {
00887       if (st_is_member(transFaninTable, node))
00888         st_insert(*absBnvTable, node, NIL(char));
00889     }
00890     arrayForEachItem(int, oldNewlyAddedBnvs, i, mddId) {
00891       node = Ntk_NetworkFindNodeByMddId(network, mddId);
00892       if (st_is_member(transFaninTable, node))
00893         array_insert_last(int, *newlyAddedBnvs, mddId);
00894     }
00895     st_free_table(transFaninTable);
00896 
00897     if (verbose >= 5) {
00898       st_foreach_item(oldBnvTable, stgen, &node, NIL(char *)) {
00899         if (!st_is_member(*absBnvTable, node)) 
00900           fprintf(vis_stdout, "         prune away BNV %s\n", Ntk_NodeReadName(node));
00901       }
00902     }
00903     
00904     array_free(oldNewlyAddedBnvs);
00905     st_free_table(oldBnvTable);
00906   }
00907   
00908 }
00909 
00910 
00922 void
00923 GrabMinimizeBnvRefinementSet(
00924   Ntk_Network_t *network,
00925   st_table *coiBnvTable,
00926   st_table *absVarTable,
00927   st_table **absBnvTable,
00928   array_t *newlyAddedBnvs,    
00929   array_t *SORs,
00930   int verbose)
00931 {
00932   st_table   *newBnvTable;
00933   Ntk_Node_t *node;
00934   int        i, flag, n_size, mddId;
00935   
00936   n_size = array_n(newlyAddedBnvs);
00937 
00938   if (verbose >= 3)
00939     fprintf(vis_stdout,
00940             "-- grab: minimize bnv refinement set: previous size is %d\n", 
00941             n_size);
00942 
00943   arrayForEachItem(int, newlyAddedBnvs, i, mddId) {
00944     node = Ntk_NetworkFindNodeByMddId(network, mddId);
00945     /* first, try to drop it */
00946     newBnvTable = st_copy(*absBnvTable);
00947     flag = st_delete(newBnvTable, &node, NIL(char *));
00948     assert(flag);
00949     /* if the counter-example does not come back, drop it officially */
00950     flag = Bmc_AbstractCheckAbstractTracesWithFineGrain(network,
00951                                                         coiBnvTable, 
00952                                                         SORs,
00953                                                         absVarTable,
00954                                                         newBnvTable);
00955     if (!flag) {
00956       st_free_table(*absBnvTable);
00957       *absBnvTable = newBnvTable;
00958       n_size--;
00959     }else {
00960       st_free_table(newBnvTable);
00961       if (verbose >= 3)
00962         fprintf(vis_stdout,"         add back %s (BNV)\n", 
00963                 Ntk_NodeReadName(node));
00964     }
00965   }
00966 
00967   if (verbose >= 3)
00968     fprintf(vis_stdout,
00969             "-- grab: minimize bnv refinement set: current  size is %d\n", 
00970             n_size);
00971 } 
00972 
00982 void 
00983 GrabNtkClearAllMddIds(
00984   Ntk_Network_t *network)
00985 {
00986 #ifndef NDEBUG
00987   mdd_manager *mddManager = Ntk_NetworkReadMddManager(network);
00988 #endif
00989   Ntk_Node_t *node;
00990   lsGen lsgen;
00991 
00992   assert(mddManager == NIL(mdd_manager));
00993 
00994   Ntk_NetworkForEachNode(network, lsgen, node) {
00995     Ntk_NodeSetMddId(node, NTK_UNASSIGNED_MDD_ID);
00996   }
00997 }
00998 
01008 void 
01009 GrabPrintNodeArray(
01010   char *caption,
01011   array_t *theArray)
01012 {
01013   Ntk_Node_t *node;
01014   char string[32];
01015   int i;
01016 
01017   fprintf(vis_stdout, "\n%s[%d] =\n", caption, theArray?array_n(theArray):0);
01018 
01019   if (!theArray) return;
01020 
01021   arrayForEachItem(Ntk_Node_t *, theArray, i, node) {
01022     if (Ntk_NodeTestIsLatch(node))
01023       strcpy(string, "latch");
01024     else if (Ntk_NodeTestIsInput(node))
01025       strcpy(string, "input");
01026     else if (Ntk_NodeTestIsLatchDataInput(node))
01027       strcpy(string, "latchDataIn");
01028     else if (Ntk_NodeTestIsLatchInitialInput(node))
01029       strcpy(string, "latchInitIn");
01030     else if (Ntk_NodeTestIsConstant(node))
01031       strcpy(string, "const");
01032     else 
01033       strcpy(string, "BNV");
01034 
01035     fprintf(vis_stdout, "%s\t(%s)\n", Ntk_NodeReadName(node), string);
01036   }
01037 }
01038 
01048 void 
01049 GrabPrintMddIdArray(
01050   Ntk_Network_t *network,
01051   char *caption,
01052   array_t *mddIdArray)
01053 {
01054   Ntk_Node_t *node;
01055   array_t *theArray = array_alloc(Ntk_Node_t *, array_n(mddIdArray));
01056   int i, mddId;
01057 
01058   arrayForEachItem(int, mddIdArray, i, mddId) {
01059     node = Ntk_NetworkFindNodeByMddId(network, mddId);
01060     array_insert(Ntk_Node_t *, theArray, i, node);
01061   }
01062 
01063   GrabPrintNodeArray(caption, theArray);
01064 
01065   array_free(theArray);
01066 
01067 }
01068 
01078 void 
01079 GrabPrintNodeList(
01080   char *caption,  
01081   lsList theList)
01082 {
01083   Ntk_Node_t *node;
01084   char string[32];
01085   lsGen lsgen;
01086 
01087   fprintf(vis_stdout, "\n%s[%d] =\n", caption, theList?lsLength(theList):0);
01088   
01089   if (!theList) return;
01090 
01091   lsForEachItem(theList, lsgen, node) {
01092     if (Ntk_NodeTestIsLatch(node))
01093       strcpy(string, "latch");
01094     else if (Ntk_NodeTestIsInput(node))
01095       strcpy(string, "input");
01096     else if (Ntk_NodeTestIsLatchDataInput(node))
01097       strcpy(string, "latchDataIn");
01098     else if (Ntk_NodeTestIsLatchInitialInput(node))
01099       strcpy(string, "latchInitIn");
01100     else if (Ntk_NodeTestIsConstant(node))
01101       strcpy(string, "const");
01102     else 
01103       strcpy(string, "BNV");
01104 
01105     fprintf(vis_stdout, "   %s\t %s\n", string, Ntk_NodeReadName(node));
01106   }
01107 }
01108 
01118 void 
01119 GrabPrintNodeHashTable(
01120   char *caption,
01121   st_table *theTable)
01122 {
01123   Ntk_Node_t *node;
01124   char string[32];
01125   long  value;
01126   st_generator *stgen;
01127 
01128   fprintf(vis_stdout, "\n%s[%d] =\n", caption, theTable?st_count(theTable):0);
01129 
01130   if (!theTable) return;
01131 
01132   st_foreach_item(theTable, stgen, &node, &value) {
01133     if (Ntk_NodeTestIsLatch(node))
01134       strcpy(string, "latch");
01135     else if (Ntk_NodeTestIsInput(node))
01136       strcpy(string, "input");
01137     else if (Ntk_NodeTestIsLatchDataInput(node))
01138       strcpy(string, "latchDataIn");
01139     else if (Ntk_NodeTestIsLatchInitialInput(node))
01140       strcpy(string, "latchInitIn");
01141     else if (Ntk_NodeTestIsConstant(node))
01142       strcpy(string, "const");
01143     else 
01144       strcpy(string, "BNV");
01145 
01146     if (value != 0)
01147       fprintf(vis_stdout, "   %s\t %s\t %ld\n", string, Ntk_NodeReadName(node),
01148               value);
01149     else
01150       fprintf(vis_stdout, "   %s\t %s \n", string, Ntk_NodeReadName(node));
01151   }
01152 }
01153 
01154 /*---------------------------------------------------------------------------*/
01155 /* Definition of static functions                                            */
01156 /*---------------------------------------------------------------------------*/
01157 
01167 static void
01168 GetFormulaNodes(
01169   Ntk_Network_t *network,
01170   Ctlp_Formula_t *F,
01171   array_t *formulaNodes)
01172 {
01173 
01174   if (F == NIL(Ctlp_Formula_t))
01175     return;
01176 
01177   if (Ctlp_FormulaReadType(F) == Ctlp_ID_c) {
01178     char *nodeNameString = Ctlp_FormulaReadVariableName(F);
01179     Ntk_Node_t *node = Ntk_NetworkFindNodeByName(network, nodeNameString);
01180     assert(node);
01181     array_insert_last(Ntk_Node_t *, formulaNodes, node);
01182     return;
01183   }
01184   
01185   GetFormulaNodes(network, Ctlp_FormulaReadRightChild(F), formulaNodes);
01186   GetFormulaNodes(network, Ctlp_FormulaReadLeftChild(F),  formulaNodes);
01187 }
01188 
01189 
01199 static void 
01200 GetFaninLatches(
01201   Ntk_Node_t *node,
01202   st_table *visited,
01203   st_table *absVarTable)
01204 {
01205   if (st_is_member(visited, node))
01206     return;
01207 
01208   st_insert(visited, node, (char *)0);
01209 
01210   if (Ntk_NodeTestIsLatch(node)) 
01211     st_insert(absVarTable, node, (char *)0);
01212   else {
01213     int i;
01214     Ntk_Node_t *fanin;
01215     Ntk_NodeForEachFanin(node, i, fanin) {
01216       GetFaninLatches(fanin, visited, absVarTable);
01217     }
01218   }
01219 }
01220 
01228 static void
01229 NodeTableAddCtlFormulaNodes( 
01230   Ntk_Network_t *network,
01231   Ctlp_Formula_t *formula, 
01232   st_table * nodesTable )
01233 {
01234   if (formula == NIL(Ctlp_Formula_t)) 
01235     return;
01236 
01237   if ( Ctlp_FormulaReadType( formula ) == Ctlp_ID_c ) {
01238     char *nodeNameString = Ctlp_FormulaReadVariableName( formula );
01239     Ntk_Node_t *node = Ntk_NetworkFindNodeByName( network, nodeNameString );
01240     if( node ) 
01241       st_insert( nodesTable, ( char *) node, NIL(char) );
01242     return;
01243   }
01244   
01245   NodeTableAddCtlFormulaNodes( network, Ctlp_FormulaReadRightChild( formula ), nodesTable );
01246   NodeTableAddCtlFormulaNodes( network, Ctlp_FormulaReadLeftChild( formula ), nodesTable );
01247 }
01248 
01249