VIS

src/abs/absInternal.c

Go to the documentation of this file.
00001 
00017 #include "absInt.h"
00018 
00019 static char rcsid[] UNUSED = "$Id: absInternal.c,v 1.30 2005/04/16 04:22:21 fabio Exp $";
00020 
00021 
00022 /*---------------------------------------------------------------------------*/
00023 /* Macro declarations                                                        */
00024 /*---------------------------------------------------------------------------*/
00025 
00026 /*---------------------------------------------------------------------------*/
00027 /* Variable declarations                                                     */
00028 /*---------------------------------------------------------------------------*/
00029 static int vertexCounter = 0;
00030 
00033 /*---------------------------------------------------------------------------*/
00034 /* Static function prototypes                                                */
00035 /*---------------------------------------------------------------------------*/
00036 
00037 static mdd_t * ComputeEGtrue(Abs_VerificationInfo_t *absInfo, mdd_t *careStates);
00038 static void SelectIdentifierVertices(AbsVertexInfo_t *vertexPtr, array_t *result, st_table *visited);
00039 
00043 /*---------------------------------------------------------------------------*/
00044 /* Definition of exported functions                                          */
00045 /*---------------------------------------------------------------------------*/
00046 
00055 Abs_VerificationInfo_t *
00056 Abs_VerificationComputeInfo(
00057   Ntk_Network_t *network)
00058 {
00059   Abs_VerificationInfo_t *absInfo;
00060   Ntk_Node_t            *nodePtr;
00061   graph_t               *partition;
00062   mdd_manager           *mddManager;
00063   st_table              *table;
00064   lsGen                 lsgen;
00065 
00066 
00067   /* Create the data structure to store all the needed info */
00068   absInfo = AbsVerificationInfoInitialize();
00069 
00070   /* Fill the data structure in */
00071   AbsVerificationInfoSetNetwork(absInfo, network);
00072   partition = Part_NetworkReadPartition(network);
00073   AbsVerificationInfoSetPartition(absInfo, partition);
00074   mddManager = Part_PartitionReadMddManager(partition);
00075   AbsVerificationInfoSetMddManager(absInfo, mddManager);
00076   
00077   /* Compute the state variable pairs */
00078   table = st_init_table(st_numcmp, st_numhash);
00079   Ntk_NetworkForEachLatch(network, lsgen, nodePtr) {
00080     Ntk_Node_t *latchInputPtr;
00081     int        mddId, mddId2;
00082     
00083     mddId = Ntk_NodeReadMddId(nodePtr);
00084     latchInputPtr = Ntk_NodeReadShadow(nodePtr);
00085     mddId2 = Ntk_NodeReadMddId(latchInputPtr);
00086     st_insert(table, (char *)(long)mddId, (char *)(long)mddId2);
00087   }
00088   AbsVerificationInfoSetStateVars(absInfo, table);
00089   
00090   /* Compute the quantify variables */
00091   table = st_init_table(st_numcmp, st_numhash);
00092   Ntk_NetworkForEachInput(network, lsgen, nodePtr) {
00093     int mddId;
00094     
00095     mddId = Ntk_NodeReadMddId(nodePtr);
00096     st_insert(table, (char *)(long)mddId, NIL(char));
00097   }
00098   AbsVerificationInfoSetQuantifyVars(absInfo, table);
00099   
00100   /* Initalize the catalog to detect common expressions */
00101   AbsVerificationInfoSetCatalog(absInfo, AbsVertexCatalogInitialize());
00102   
00103   return absInfo;
00104 } /* End of Abs_VerificationComputeInfo */
00105 
00106 
00107 /*---------------------------------------------------------------------------*/
00108 /* Definition of internal functions                                          */
00109 /*---------------------------------------------------------------------------*/
00110 
00121 AbsVertexInfo_t *
00122 AbsVertexInitialize(void)
00123 {
00124   AbsVertexInfo_t *result;
00125 
00126   result = ALLOC(AbsVertexInfo_t, 1);
00127 
00128   AbsVertexSetType(result, false_c);
00129   AbsVertexSetId(result, vertexCounter++);
00130   AbsVertexSetSat(result, NIL(mdd_t));
00131   AbsVertexSetRefs(result, 1);
00132   AbsVertexSetServed(result, 0);
00133   AbsVertexSetPolarity(result, FALSE);
00134   AbsVertexSetDepth(result, -1);
00135   AbsVertexSetLocalApprox(result, FALSE);
00136   AbsVertexSetGlobalApprox(result, FALSE);
00137   AbsVertexSetConstant(result, FALSE);
00138   AbsVertexSetTrueRefine(result, FALSE);
00139   AbsVertexSetLeftKid(result, NIL(AbsVertexInfo_t));
00140   AbsVertexSetRightKid(result, NIL(AbsVertexInfo_t));
00141   result->parent = lsCreate();
00142  
00143   /* Not all of these need to be initialized, but to be sure... */
00144   AbsVertexSetSolutions(result, NIL(st_table));
00145   AbsVertexSetVarId(result, 0);
00146   AbsVertexSetFpVar(result, NIL(AbsVertexInfo_t));
00147   AbsVertexSetVarId(result, 0);
00148   AbsVertexSetGoalSet(result, NIL(mdd_t));
00149   AbsVertexSetRings(result, NIL(array_t));
00150   AbsVertexSetRingApprox(result, NIL(array_t));
00151   AbsVertexSetSubApprox(result, NIL(array_t));
00152   AbsVertexSetUseExtraCareSet(result, FALSE);
00153   AbsVertexSetName(result, NIL(char));
00154   AbsVertexSetValue(result, NIL(char));
00155 
00156   return result;
00157 } /* End of AbsVertexInitialize */
00158 
00170 void
00171 AbsVertexFree(
00172   AbsVertexCatalog_t *catalog,
00173   AbsVertexInfo_t *v,
00174   AbsVertexInfo_t *fromVertex)
00175 {
00176   /* Decrement the number of references */
00177   AbsVertexReadRefs(v)--;
00178 
00179   /* Remove the pointer from its parent to itself */
00180   if (fromVertex != NIL(AbsVertexInfo_t)) {
00181     AbsVertexInfo_t *result;
00182     lsGen listGen;
00183     lsHandle item, toDelete;
00184     lsGeneric userData;
00185 
00186     listGen = lsStart(AbsVertexReadParent(v));
00187     toDelete = (lsHandle) 0;
00188     while(toDelete == (lsHandle) 0 &&
00189           lsNext(listGen, &result, &item) == LS_OK) {
00190       if (result == fromVertex) {
00191         toDelete = item;
00192       }
00193     }
00194     lsFinish(listGen);
00195 
00196     if (toDelete != (lsHandle)0) {
00197       lsRemoveItem(toDelete, &userData);
00198     }
00199   }
00200 
00201   /* If it is not the last reference we are done */
00202   if (AbsVertexReadRefs(v) != 0) {
00203     return;
00204   }
00205 
00206   /* Vertices that need recursion over the leftKid */
00207   if (AbsVertexReadType(v) == fixedPoint_c ||
00208       AbsVertexReadType(v) == and_c ||
00209       AbsVertexReadType(v) == xor_c ||
00210       AbsVertexReadType(v) == xnor_c ||
00211       AbsVertexReadType(v) == not_c ||
00212       AbsVertexReadType(v) == preImage_c) {
00213     AbsVertexFree(catalog, AbsVertexReadLeftKid(v), v);
00214   }
00215   
00216   /* Vertices that need recursion over the rightKid */
00217   if (AbsVertexReadType(v) == and_c ||
00218       AbsVertexReadType(v) == xor_c ||
00219       AbsVertexReadType(v) == xnor_c) {
00220     AbsVertexFree(catalog, AbsVertexReadRightKid(v), v);
00221   }
00222 
00223   /* Remove the vertex from the catalog */
00224   AbsCatalogDelete(catalog, v);
00225 
00226   /* The variable vertex does not reference the sat set */
00227   if (AbsVertexReadType(v) != variable_c && 
00228       AbsVertexReadSat(v) != NIL(mdd_t)) {
00229     mdd_free(AbsVertexReadSat(v));
00230   }
00231 
00232   if (AbsVertexReadType(v) == variable_c && 
00233       AbsVertexReadGoalSet(v) != NIL(mdd_t)) {
00234     mdd_free(AbsVertexReadGoalSet(v));
00235   }
00236   
00237   lsDestroy(AbsVertexReadParent(v), (void (*)(lsGeneric))0);
00238 
00239   /* Free the union fields depending on the type of vertex */
00240   if (AbsVertexReadType(v) == preImage_c) {
00241     if (AbsVertexReadSolutions(v) != NIL(st_table)) {
00242       AbsEvalCacheEntry_t *value;
00243       bdd_node            *key;
00244       st_generator        *stgen;
00245 
00246       st_foreach_item(AbsVertexReadSolutions(v), stgen, &key, &value) {
00247         AbsCacheEntryFree(value);
00248       }
00249       st_free_table(AbsVertexReadSolutions(v));
00250     }
00251   }
00252   else if (AbsVertexReadType(v) == fixedPoint_c) {
00253     if (AbsVertexReadRings(v) != NIL(array_t)) {
00254       mdd_t *unit;
00255       int i;
00256 
00257       arrayForEachItem(mdd_t *, AbsVertexReadRings(v), i, unit) {
00258         mdd_free(unit);
00259       }
00260       array_free(AbsVertexReadRings(v));
00261     }
00262     if (AbsVertexReadRingApprox(v) != NIL(array_t)) {
00263       array_free(AbsVertexReadRingApprox(v));
00264     }
00265     if (AbsVertexReadSubApprox(v) != NIL(array_t)) {
00266       array_free(AbsVertexReadSubApprox(v));
00267     }
00268   }
00269   else if (AbsVertexReadType(v) == identifier_c) {
00270     FREE(AbsVertexReadName(v));
00271     FREE(AbsVertexReadValue(v));
00272   }
00273 
00274   /* Deallocate the memory for the structure itself */
00275   FREE(v);
00276 } /* End of AbsVertexFree */
00277 
00288 Abs_VerificationInfo_t *
00289 AbsVerificationInfoInitialize(void)
00290 {
00291   Abs_VerificationInfo_t *result;
00292 
00293   result = ALLOC(Abs_VerificationInfo_t, 1);
00294 
00295   AbsVerificationInfoSetNetwork(result, NIL(Ntk_Network_t));
00296   AbsVerificationInfoSetPartition(result, NIL(graph_t));
00297   AbsVerificationInfoSetFsm(result, NIL(Fsm_Fsm_t));
00298   AbsVerificationInfoSetNumStateVars(result, 0);
00299   AbsVerificationInfoSetApproxFsm(result, NIL(Fsm_Fsm_t));
00300   AbsVerificationInfoSetStateVars(result, NIL(st_table));
00301   AbsVerificationInfoSetQuantifyVars(result, NIL(st_table));
00302   AbsVerificationInfoSetCareSet(result, NIL(mdd_t));
00303   AbsVerificationInfoSetTmpCareSet(result, NIL(mdd_t));
00304   AbsVerificationInfoSetImageCache(result, NIL(st_table));
00305   AbsVerificationInfoSetMddManager(result, NIL(mdd_manager));
00306   AbsVerificationInfoSetCatalog(result, NIL(AbsVertexCatalog_t));
00307   AbsVerificationInfoSetStats(result, AbsStatsInitialize());
00308   AbsVerificationInfoSetOptions(result, NIL(AbsOptions_t));
00309   
00310   return result;
00311 } /* End of AbsVerificationInfoInitialize */
00312 
00328 void
00329 AbsVerificationInfoFree(
00330   Abs_VerificationInfo_t *v)
00331 {
00332   if (AbsVerificationInfoReadStateVars(v) != NIL(st_table)) {
00333     st_free_table(AbsVerificationInfoReadStateVars(v));
00334   }
00335 
00336   if (AbsVerificationInfoReadQuantifyVars(v) != NIL(st_table)) {
00337     st_free_table(AbsVerificationInfoReadQuantifyVars(v));
00338   }
00339 
00340   if (AbsVerificationInfoReadImageCache(v) != NIL(st_table)) {
00341     AbsEvalCacheEntry_t *value;
00342     bdd_node            *key;
00343     st_generator        *stgen;
00344 
00345     st_foreach_item(AbsVerificationInfoReadImageCache(v), stgen,
00346                     &key, &value) {
00347       AbsCacheEntryFree(value);
00348     }
00349     st_free_table(AbsVerificationInfoReadImageCache(v));
00350   }
00351 
00352   if (AbsVerificationInfoReadCareSet(v) != NIL(mdd_t)) {
00353     mdd_free(AbsVerificationInfoReadCareSet(v));
00354   }
00355 
00356   if (AbsVerificationInfoReadTmpCareSet(v) != NIL(mdd_t)) {
00357     mdd_free(AbsVerificationInfoReadTmpCareSet(v));
00358   }
00359 
00360   if (AbsVerificationInfoReadCatalog(v) != NIL(AbsVertexCatalog_t)) {
00361     AbsVertexCatalogFree(AbsVerificationInfoReadCatalog(v));
00362   }
00363 
00364   AbsStatsFree(AbsVerificationInfoReadStats(v));
00365 
00366   FREE(v);
00367 
00368   /* 
00369    * The options field is not freed since it is assumed that it has been
00370    * allocated outside the AbsVerificationInitialize procedure
00371    */
00372 
00373   return;
00374 } /* End of AbsVerificationInfoFree */
00375 
00385 AbsOptions_t *
00386 AbsOptionsInitialize(void)
00387 {
00388   AbsOptions_t *result;
00389 
00390   result = ALLOC(AbsOptions_t, 1);
00391 
00392   AbsOptionsSetVerbosity(result, 0);
00393   AbsOptionsSetTimeOut(result, 0);
00394   AbsOptionsSetFileName(result, NIL(char));
00395   AbsOptionsSetReachability(result, FALSE);
00396   AbsOptionsSetFairFileName(result, NIL(char));
00397   AbsOptionsSetExact(result, FALSE);
00398   AbsOptionsSetPrintStats(result, FALSE);
00399   AbsOptionsSetMinimizeIterate(result, FALSE);
00400   AbsOptionsSetNegateFormula(result, FALSE);
00401   AbsOptionsSetPartApprox(result, FALSE);
00402 
00403   return result;
00404 } /* End of AbsOptionsInitialize */
00405 
00415 void
00416 AbsOptionsFree(AbsOptions_t *unit)
00417 {
00418   if (AbsOptionsReadFileName(unit) != NIL(char)) {
00419     FREE(AbsOptionsReadFileName(unit));
00420   }
00421   
00422   if (AbsOptionsReadFairFileName(unit) != NIL(char)) {
00423     FREE(AbsOptionsReadFairFileName(unit));
00424   }
00425 
00426   FREE(unit);
00427   
00428   return;
00429 } /* End of AbsOptionsInitialize */
00430 
00431 
00442 AbsStats_t *
00443 AbsStatsInitialize(void)
00444 {
00445   AbsStats_t *result;
00446 
00447   result = ALLOC(AbsStats_t, 1);
00448   
00449   AbsStatsSetNumReorderings(result, 0);
00450   AbsStatsSetEvalFixedPoint(result, 0);
00451   AbsStatsSetEvalAnd(result, 0);
00452   AbsStatsSetEvalNot(result, 0);
00453   AbsStatsSetEvalPreImage(result, 0);
00454   AbsStatsSetEvalIdentifier(result, 0);
00455   AbsStatsSetEvalVariable(result, 0);
00456   AbsStatsSetRefineFixedPoint(result, 0);
00457   AbsStatsSetRefineAnd(result, 0);
00458   AbsStatsSetRefineNot(result, 0);
00459   AbsStatsSetRefinePreImage(result, 0);
00460   AbsStatsSetRefineIdentifier(result, 0);
00461   AbsStatsSetRefineVariable(result, 0);
00462   AbsStatsSetExactPreImage(result, 0);
00463   AbsStatsSetApproxPreImage(result, 0);
00464   AbsStatsSetExactImage(result, 0);
00465   AbsStatsSetPreImageCacheEntries(result, 0);
00466   AbsStatsSetImageCacheEntries(result, 0);
00467   AbsStatsSetImageCpuTime(result, 0);
00468   AbsStatsSetPreImageCpuTime(result, 0);
00469   AbsStatsSetAppPreCpuTime(result, 0);
00470 
00471   return result;
00472 
00473 } /* End of AbsStatsInitialize */
00474 
00484 void
00485 AbsStatsFree(
00486   AbsStats_t *unit)
00487 {
00488   FREE(unit);
00489 } /* End of AbsStatsFree */
00490 
00500 AbsEvalCacheEntry_t *
00501 AbsCacheEntryInitialize(void)
00502 {
00503   AbsEvalCacheEntry_t *result;
00504 
00505   result = ALLOC(AbsEvalCacheEntry_t, 1);
00506 
00507   AbsEvalCacheEntrySetKey(result, NIL(mdd_t));
00508   AbsEvalCacheEntrySetApprox(result, FALSE);
00509   AbsEvalCacheEntrySetComplement(result, 0);
00510   AbsEvalCacheEntrySetResult(result, NIL(mdd_t));
00511   AbsEvalCacheEntrySetCareSet(result, NIL(mdd_t));
00512 
00513   return result;
00514 } /* End of AbsCacheEntryInitialize */
00515 
00525 void
00526 AbsCacheEntryFree(
00527   AbsEvalCacheEntry_t *unit)
00528 {
00529   mdd_free(AbsEvalCacheEntryReadKey(unit));
00530   mdd_free(AbsEvalCacheEntryReadResult(unit));
00531   mdd_free(AbsEvalCacheEntryReadCareSet(unit));
00532 
00533   FREE(unit);
00534 } /* End of AbsCacheEntryFree */
00535 
00545 void
00546 AbsEvalCacheInsert(
00547   st_table *solutions,
00548   mdd_t *key,
00549   mdd_t *result,
00550   mdd_t *careSet,
00551   boolean approx,
00552   boolean replace)
00553 {
00554   AbsEvalCacheEntry_t *entry;
00555   int                 complement;
00556   bdd_node            *f;
00557 
00558   entry = NIL(AbsEvalCacheEntry_t);
00559   f = bdd_get_node(key, &complement);
00560 
00561   /* If the replacement is required, delete the element from the table */
00562   if (replace) {
00563     st_delete(solutions, &f, &entry);
00564 
00565     mdd_free(AbsEvalCacheEntryReadKey(entry));
00566     mdd_free(AbsEvalCacheEntryReadResult(entry));
00567     mdd_free(AbsEvalCacheEntryReadCareSet(entry));
00568   }
00569 
00570   assert(!st_is_member(solutions, (char *)f));
00571 
00572   if (entry == NIL(AbsEvalCacheEntry_t)) {
00573     entry = AbsCacheEntryInitialize();
00574   }
00575 
00576   AbsEvalCacheEntrySetKey(entry, mdd_dup(key));
00577   AbsEvalCacheEntrySetApprox(entry, approx);
00578   AbsEvalCacheEntrySetComplement(entry, complement);
00579   AbsEvalCacheEntrySetResult(entry, mdd_dup(result));
00580   AbsEvalCacheEntrySetCareSet(entry, mdd_dup(careSet));
00581   
00582   /* Insert the new entry in the cache */
00583   st_insert(solutions, (char *)f, (char *)entry);
00584 
00585   return;
00586 } /* End of AbsEvalCacheInsert */
00587 
00597 boolean
00598 AbsEvalCacheLookup(
00599   st_table *solutions,
00600   mdd_t *key,
00601   mdd_t *careSet,
00602   boolean approx,
00603   mdd_t **result,
00604   boolean *storedApprox)
00605 {
00606   AbsEvalCacheEntry_t *entry;
00607   bdd_node            *f;
00608   int                 complement;
00609   
00610   f = bdd_get_node(key, &complement);
00611 
00612   if (st_lookup(solutions, f, &entry)) {
00613     if (complement == AbsEvalCacheEntryReadComplement(entry) &&
00614         (approx || !AbsEvalCacheEntryReadApprox(entry)) &&
00615         mdd_lequal(careSet, AbsEvalCacheEntryReadCareSet(entry), 1, 1)) {
00616       *result = AbsEvalCacheEntryReadResult(entry);
00617       if (storedApprox != 0) {
00618         *storedApprox = AbsEvalCacheEntryReadApprox(entry);
00619       }
00620       return TRUE;
00621     }
00622     else {
00623       st_delete(solutions, &f, &entry);
00624       AbsCacheEntryFree(entry);
00625     }
00626   }
00627 
00628   return FALSE;
00629 } /* End of AbsEvalCacheLookup */
00630 
00640 void
00641 AbsVerificationFlushCache(
00642   Abs_VerificationInfo_t *absInfo)
00643 {
00644   AbsEvalCacheEntry_t *value;
00645   st_table            *table;
00646   bdd_node            *key;
00647   st_generator        *stgen;
00648 
00649   table = AbsVerificationInfoReadImageCache(absInfo);
00650 
00651   if (table == NIL(st_table)) {
00652     return;
00653   }
00654 
00655   st_foreach_item(table, stgen, &key, &value) {
00656     AbsCacheEntryFree(value);
00657   }
00658 
00659   st_free_table(table);
00660   AbsVerificationInfoSetImageCache(absInfo, NIL(st_table));
00661 
00662   return;
00663 } /* End of AbsVerificationFlushCache */
00664 
00675 void
00676 AbsVertexFlushCache(
00677   AbsVertexInfo_t *vertexPtr)
00678 {
00679   if (AbsVertexReadType(vertexPtr) == preImage_c) {
00680     if (AbsVertexReadSolutions(vertexPtr) != NIL(st_table)) {
00681       AbsEvalCacheEntry_t *value;
00682       bdd_node            *key;
00683       st_generator        *stgen;
00684       
00685       st_foreach_item(AbsVertexReadSolutions(vertexPtr), stgen, &key,
00686                       &value) {
00687         AbsCacheEntryFree(value);
00688       }
00689       st_free_table(AbsVertexReadSolutions(vertexPtr));
00690       AbsVertexSetSolutions(vertexPtr, NIL(st_table));
00691     }
00692   }
00693 
00694   if (AbsVertexReadLeftKid(vertexPtr) != NIL(AbsVertexInfo_t)) {
00695     AbsVertexFlushCache(AbsVertexReadLeftKid(vertexPtr));
00696   }
00697 
00698   if (AbsVertexReadRightKid(vertexPtr) != NIL(AbsVertexInfo_t)) {
00699     AbsVertexFlushCache(AbsVertexReadRightKid(vertexPtr));
00700   }
00701 
00702   return;
00703 } /* End of AbsVertexFlushCache */
00704 
00715 mdd_t *
00716 AbsImageReadOrCompute(
00717   Abs_VerificationInfo_t *absInfo,
00718   Img_ImageInfo_t *imageInfo,
00719   mdd_t *set,
00720   mdd_t *careSet
00721 )
00722 {
00723   AbsEvalCacheEntry_t *entry;
00724   st_table            *table;
00725   bdd_node            *f;
00726   mdd_t               *result;
00727   long                cpuTime;
00728   int                 complement;
00729 
00730   entry = NIL(AbsEvalCacheEntry_t);
00731   table = AbsVerificationInfoReadImageCache(absInfo);
00732   f = bdd_get_node(set, &complement);
00733 
00734   /* See if the table has been created */
00735   if (table == NIL(st_table)) {
00736     table = st_init_table(st_ptrcmp, st_ptrhash);
00737     AbsVerificationInfoSetImageCache(absInfo, table);
00738   }
00739   else {
00740     /* Look up for the operation */
00741     if (st_lookup(table, f, &entry)) {
00742       if (complement == AbsEvalCacheEntryReadComplement(entry) &&
00743           mdd_lequal(careSet, AbsEvalCacheEntryReadCareSet(entry), 1, 1)) {
00744         result = mdd_dup(AbsEvalCacheEntryReadResult(entry));
00745         return result;
00746       }
00747       else {
00748         st_delete(table, &f, &entry);
00749 
00750         mdd_free(AbsEvalCacheEntryReadKey(entry));
00751         mdd_free(AbsEvalCacheEntryReadResult(entry));
00752         mdd_free(AbsEvalCacheEntryReadCareSet(entry));
00753       }
00754     }
00755   }
00756 
00757   /* The result has not been found. Compute it and insert it in the cache */
00758   cpuTime = util_cpu_time();
00759   result = Img_ImageInfoComputeFwdWithDomainVars(imageInfo, set, set, careSet);
00760   AbsStatsReadImageCpuTime(AbsVerificationInfoReadStats(absInfo))+= 
00761     util_cpu_time() - cpuTime;
00762   AbsStatsReadExactImage(AbsVerificationInfoReadStats(absInfo))++;
00763 
00764   if (entry == NIL(AbsEvalCacheEntry_t)) {
00765     entry = AbsCacheEntryInitialize();
00766   }
00767 
00768   AbsEvalCacheEntrySetKey(entry, mdd_dup(set));
00769   AbsEvalCacheEntrySetComplement(entry, complement);
00770   AbsEvalCacheEntrySetResult(entry, mdd_dup(result));
00771   AbsEvalCacheEntrySetCareSet(entry, mdd_dup(careSet));
00772   
00773   /* Insert the new entry in the cache */
00774   st_insert(table, (char *)f, (char *)entry);
00775 
00776   AbsStatsReadImageCacheEntries(AbsVerificationInfoReadStats(absInfo))++;
00777 
00778   return result;
00779 } /* End of AbsImageReadOrCompute */
00780 
00793 array_t *
00794 AbsFormulaArrayVerify(
00795   Abs_VerificationInfo_t *absInfo,
00796   array_t *formulaArray)
00797 {
00798   AbsOptions_t    *options;
00799   AbsVertexInfo_t *formulaPtr;
00800   Fsm_Fsm_t       *fsm;
00801   array_t         *result;
00802   mdd_manager     *mddManager;
00803   int             fIndex;
00804   int             numReorderings;
00805 
00806   /* Initialize some variables */
00807   options = AbsVerificationInfoReadOptions(absInfo);
00808   mddManager = AbsVerificationInfoReadMddManager(absInfo);
00809   numReorderings = bdd_read_reorderings(mddManager);
00810   
00811   /* Print the configuration of the system */
00812   if (AbsOptionsReadVerbosity(options) & ABS_VB_PIFF) {
00813     (void) fprintf(vis_stdout, "ABS: System with (PI,FF) = (%d,%d)\n", 
00814                    st_count(AbsVerificationInfoReadQuantifyVars(absInfo)), 
00815                    st_count(AbsVerificationInfoReadStateVars(absInfo)));
00816   }
00817 
00818   /* Create the array of results */
00819   result = array_alloc(AbsVerificationResult_t, array_n(formulaArray));
00820 
00821   /* Obtain the fsm representing the complete circuit */
00822   fsm = Fsm_FsmCreateFromNetworkWithPartition(
00823           AbsVerificationInfoReadNetwork(absInfo), NIL(graph_t));
00824 
00825   /* Traverse the array of formulas and verify all of them */
00826   arrayForEachItem(AbsVertexInfo_t *, formulaArray, fIndex, formulaPtr) {
00827     Fsm_Fsm_t *localSystem;
00828     Fsm_Fsm_t *approxSystem;
00829     array_t   *stateVarIds;
00830     mdd_t     *initialStates;
00831     mdd_t     *careStates;
00832     long      cpuTime;
00833     int       numBddVars;
00834     int       mddId;
00835     int       i;
00836 
00837     /* Variable Initialization */
00838     approxSystem = NIL(Fsm_Fsm_t);
00839 
00840     /* Set the cpu-time lap */
00841     cpuTime = util_cpu_time();
00842 
00843     /* Print the labeled operational graph */
00844     if (AbsOptionsReadVerbosity(options) & ABS_VB_GRAPH) {
00845       (void) fprintf(vis_stdout, "ABS: === Labeled Operational Graph ===\n");
00846       AbsVertexPrint(formulaPtr, NIL(st_table), TRUE,
00847                      AbsOptionsReadVerbosity(options));
00848       (void) fprintf(vis_stdout, "ABS: === End of Graph ===\n");
00849     }
00850     
00851     /* Simplify the system with respect to the given formula */
00852     localSystem = AbsCreateReducedFsm(absInfo, formulaPtr, &approxSystem);
00853     if (localSystem == NIL(Fsm_Fsm_t)) {
00854       localSystem = fsm;
00855     }
00856     if (approxSystem == NIL(Fsm_Fsm_t)) {
00857       approxSystem = fsm;
00858     }
00859 
00860     AbsVerificationInfoSetFsm(absInfo, localSystem);
00861 
00862     /* Compute the number of bdd variables needed to encode the state space */
00863     stateVarIds = Fsm_FsmReadPresentStateVars(localSystem);
00864     numBddVars = 0;
00865     arrayForEachItem(int, stateVarIds, i, mddId) {
00866       array_t *mvarList = mdd_ret_mvar_list(mddManager);
00867       mvar_type mddVar  = array_fetch(mvar_type, mvarList, mddId);
00868       numBddVars += mddVar.encode_length;
00869     }
00870     AbsVerificationInfoSetNumStateVars(absInfo, numBddVars);
00871 
00872     AbsVerificationInfoSetApproxFsm(absInfo, approxSystem);
00873 
00874     if (AbsOptionsReadVerbosity(options) & ABS_VB_SIMPLE) {
00875       (void) fprintf(vis_stdout, 
00876                      "ABS: System Simplified from %d to %d latches\n",
00877                      array_n(Fsm_FsmReadPresentStateVars(fsm)),
00878                      array_n(Fsm_FsmReadPresentStateVars(localSystem)));
00879       (void) fprintf(vis_stdout, 
00880                      "ABS: System Approximated by %d of %d latches\n",
00881                      array_n(Fsm_FsmReadPresentStateVars(approxSystem)),
00882                      array_n(Fsm_FsmReadPresentStateVars(localSystem)));
00883     }
00884                    
00885     /* Compute reachability if requested */
00886     if (AbsOptionsReadReachability(options)) {
00887       mdd_t *reachableStates;
00888       long  cpuTime;
00889       
00890       cpuTime = util_cpu_time();
00891       
00892       reachableStates = Fsm_FsmComputeReachableStates(localSystem, 0, 1, 0, 0, 
00893                         0, 0, 0,Fsm_Rch_Default_c, 0, 0, NIL(array_t), FALSE,
00894                         NIL(array_t));
00895       if (AbsOptionsReadVerbosity(options) & ABS_VB_PPROGR) {
00896         (void) fprintf(vis_stdout, "ABS: %7.1f secs spent in reachability \n",
00897                        (util_cpu_time() - cpuTime)/1000.0);
00898       }
00899 
00900       /* Print the number of reachable states */
00901       if (AbsOptionsReadVerbosity(options) & ABS_VB_PRCH) {
00902         array_t *sVars;
00903         
00904         sVars = Fsm_FsmReadPresentStateVars(localSystem);
00905         (void) fprintf(vis_stdout, "ABS: System with %.0f reachable states.\n",
00906                        mdd_count_onset(mddManager, reachableStates, sVars));
00907       }
00908       
00909       careStates = reachableStates;
00910     } /* End of reachability analysis */
00911     else {
00912       careStates = mdd_one(mddManager);
00913     }
00914 
00915     /* Compute the initial states */
00916     initialStates = Fsm_FsmComputeInitialStates(localSystem);
00917     if (initialStates == NIL(mdd_t)) {
00918       (void) fprintf(vis_stdout, "** abs error: Unable to compute initial states.\n");
00919       (void) fprintf(vis_stdout, "ABS: %s\n", error_string());
00920       
00921       AbsVerificationInfoFree(absInfo);
00922       array_free(result);
00923       /* Deallocate the FSM if the system was reduced */
00924       if (localSystem != fsm) {
00925         Fsm_FsmFree(localSystem);
00926       }
00927       return NIL(array_t);
00928     }
00929 
00930     /* Set the don't care information */
00931     if (AbsVerificationInfoReadCareSet(absInfo) != NIL(mdd_t)) {
00932       mdd_free(AbsVerificationInfoReadCareSet(absInfo));
00933     }
00934     AbsVerificationInfoSetCareSet(absInfo, careStates);
00935     if (AbsVerificationInfoReadTmpCareSet(absInfo) != NIL(mdd_t)) {
00936       mdd_free(AbsVerificationInfoReadTmpCareSet(absInfo));
00937     }
00938     AbsVerificationInfoSetTmpCareSet(absInfo, mdd_one(mddManager));
00939 
00940     /* Compute the formula EG(true) if required */
00941     if (AbsOptionsReadEnvelope(options)) {
00942       mdd_t *newCareStates;
00943       mdd_t *tmp1;
00944 
00945       newCareStates = ComputeEGtrue(absInfo, careStates);
00946       tmp1 = mdd_and(newCareStates, careStates, 1, 1);
00947       mdd_free(careStates);
00948       mdd_free(newCareStates);
00949       careStates = tmp1;
00950       AbsVerificationInfoSetCareSet(absInfo, careStates);
00951     }
00952 
00953     /* Print verbosity message */
00954     if (AbsOptionsReadVerbosity(options) & ABS_VB_VTXCNT) {
00955       (void) fprintf(vis_stdout, "ABS: === Initial Verification ===\n");
00956     }
00957     
00958     /* Create the initial evaluation of the formula */
00959     AbsSubFormulaVerify(absInfo, formulaPtr);
00960     
00961     assert(!AbsVertexReadTrueRefine(formulaPtr));
00962 
00963     /* Print verbosity message */
00964     if (AbsOptionsReadVerbosity(options) & ABS_VB_VTXCNT) {
00965       (void) fprintf(vis_stdout, "ABS: === End of Initial Verification ===\n");
00966     }
00967     
00968     /* Print cpu-time information */
00969     if (AbsOptionsReadVerbosity(options) & ABS_VB_PPROGR) {
00970       (void) fprintf(vis_stdout, "ABS: Initial verification: %7.1f secs.\n",
00971                      (util_cpu_time() - cpuTime)/1000.0);
00972     }
00973 
00974     /* Check if the initial states satisfy the formula */
00975     if (mdd_lequal(initialStates, AbsVertexReadSat(formulaPtr), 1, 1)) {
00976         array_insert(int, result, fIndex, trueVerification_c);
00977     }
00978     else {
00979       if (AbsVertexReadGlobalApprox(formulaPtr)) {
00980         mdd_t *goalSet;
00981         mdd_t *refinement;
00982 
00983         /* 
00984          * Compute the set of states remaining in the goal. We are assuming
00985          * that the parity of the top vertex is negative 
00986          */
00987         assert(!AbsVertexReadPolarity(formulaPtr));
00988 
00989         /* Compute the initial goal set */
00990         goalSet = mdd_and(initialStates, AbsVertexReadSat(formulaPtr), 1, 0);
00991 
00992         /* Notify that the refinement process is beginning */
00993         if (AbsOptionsReadVerbosity(options) &ABS_VB_PPROGR) {
00994           (void) fprintf(vis_stdout, 
00995                          "ABS: Verification has been approximated. ");
00996           (void) fprintf(vis_stdout, "Beginning approximation refinement\n");
00997         }
00998 
00999         /* Print the number of states to refine */
01000         if (AbsOptionsReadVerbosity(options) & ABS_VB_PRINIT) {
01001           array_t *sVars;
01002 
01003           sVars = Fsm_FsmReadPresentStateVars(fsm);
01004           (void) fprintf(vis_stdout, 
01005                          "ABS: %.0f states out of %.0f to be refined\n",
01006                          mdd_count_onset(mddManager, goalSet, sVars),
01007                          mdd_count_onset(mddManager, initialStates, sVars));
01008         }
01009 
01010         /* Effectively perform the refinement */
01011         refinement = AbsSubFormulaRefine(absInfo, formulaPtr, goalSet); 
01012 
01013         /* Insert the outcome of the refinement in the solution */
01014         if (mdd_is_tautology(refinement, 0)) {
01015           array_insert(int, result, fIndex, trueVerification_c);
01016         }
01017         else {
01018           if (!AbsVertexReadTrueRefine(formulaPtr)) {
01019             array_insert(int, result, fIndex, inconclusiveVerification_c);
01020           }
01021           else {
01022             array_insert(int, result, fIndex, falseVerification_c);
01023           }
01024         }
01025         mdd_free(goalSet);
01026         mdd_free(refinement);
01027       }
01028       else {
01029         array_insert(int, result, fIndex, falseVerification_c);
01030       }
01031     }
01032     mdd_free(initialStates);
01033     
01034     /* Print cpu-time information */
01035     if (AbsOptionsReadVerbosity(options) & ABS_VB_PPROGR) {
01036       (void) fprintf(vis_stdout, "ABS: Formula #%d verified in %7.1f secs.\n",
01037                      fIndex + 1, (util_cpu_time() - cpuTime)/1000.0);
01038     }
01039 
01040     /* Print the number of states in the on set of Sat */
01041     if (AbsOptionsReadVerbosity(options) & ABS_VB_TSAT) {
01042       array_t *sVars;
01043       
01044       sVars = Fsm_FsmReadPresentStateVars(localSystem);
01045       (void) fprintf(vis_stdout, "ABS: %.0f States in sat of the formula.\n",
01046                      mdd_count_onset(mddManager, AbsVertexReadSat(formulaPtr), 
01047                                      sVars));
01048     }
01049 
01050     /* Clean up */
01051     AbsVertexFlushCache(formulaPtr);
01052     AbsVerificationFlushCache(absInfo);
01053     if (approxSystem != fsm) {
01054       Fsm_FsmFree(approxSystem);
01055     }
01056     if (localSystem != fsm) {
01057       Fsm_FsmFree(localSystem);
01058     }
01059   } /* End of the loop over the array of formulas to be verified */
01060 
01061   /* Set the number of reorderings in the stats */
01062   AbsStatsSetNumReorderings(AbsVerificationInfoReadStats(absInfo),
01063                             bdd_read_reorderings(mddManager) - numReorderings);
01064 
01065   /* Clean up */
01066   Fsm_FsmFree(fsm);
01067 
01068   return result;
01069 }
01070 
01079 Fsm_Fsm_t *
01080 AbsCreateReducedFsm(
01081   Abs_VerificationInfo_t *absInfo,
01082   AbsVertexInfo_t *vertexPtr,
01083   Fsm_Fsm_t **approxFsm)
01084 {
01085   AbsVertexInfo_t *vPtr;
01086   Ntk_Network_t   *network;
01087   Ntk_Node_t      *nodePtr;
01088   Fsm_Fsm_t       *result;
01089   lsGen           gen;
01090   array_t         *vertexArray;
01091   array_t         *nodeArray;
01092   array_t         *supportArray;
01093   array_t         *inputs;
01094   array_t         *latches;
01095   st_table        *visited;
01096   int             i;
01097 
01098   if (vertexPtr == NIL(AbsVertexInfo_t)) {
01099     return NIL(Fsm_Fsm_t);
01100   }
01101 
01102   network = AbsVerificationInfoReadNetwork(absInfo);
01103 
01104   /* Select the vertices of type "identifier" */
01105   visited = st_init_table(st_ptrcmp, st_ptrhash);
01106   vertexArray = array_alloc(AbsVertexInfo_t *, 0);
01107   SelectIdentifierVertices(vertexPtr, vertexArray, visited);
01108   st_free_table(visited);
01109 
01110   if (array_n(vertexArray) == 0) {
01111     array_free(vertexArray);
01112     return NIL(Fsm_Fsm_t);
01113   }
01114 
01115   /* Create the array of network nodes corresponding to the identifiers */
01116   visited = st_init_table(st_ptrcmp, st_ptrhash);
01117   nodeArray = array_alloc(Ntk_Node_t *, 0);
01118   arrayForEachItem(AbsVertexInfo_t *, vertexArray, i, vPtr) {
01119     nodePtr = Ntk_NetworkFindNodeByName(network, AbsVertexReadName(vPtr));
01120 
01121     assert(nodePtr != NIL(Ntk_Node_t));
01122 
01123     if (!st_is_member(visited, (char *)nodePtr)) {
01124       array_insert_last(Ntk_Node_t *, nodeArray, nodePtr);
01125       st_insert(visited, (char *)nodePtr, NIL(char));
01126     }
01127   }
01128   array_free(vertexArray);
01129 
01130   /* Create the input and array latches to compute the approxFsm */
01131   inputs = array_alloc(Ntk_Node_t *, 0);
01132   Ntk_NetworkForEachInput(network, gen, nodePtr) {
01133     array_insert_last(Ntk_Node_t *, inputs, nodePtr);
01134   }
01135   latches = array_alloc(Ntk_Node_t *, 0);
01136   Ntk_NetworkForEachLatch(network, gen, nodePtr) {
01137     if (st_is_member(visited, (char *)nodePtr)) {
01138       array_insert_last(Ntk_Node_t *, latches, nodePtr);
01139     }
01140     else {
01141       array_insert_last(Ntk_Node_t *, inputs, nodePtr);
01142     }
01143   }
01144   st_free_table(visited);
01145 
01146   /* Obtain the approximated system */
01147   *approxFsm = Fsm_FsmCreateReducedFsm(network, NIL(graph_t), latches, inputs, 
01148                                        NIL(array_t));
01149   array_free(inputs);
01150   array_free(latches);
01151 
01152   /* Obtain the transitive fanin of the nodes */
01153   supportArray = Ntk_NodeComputeCombinationalSupport(network, nodeArray, FALSE);
01154   array_free(nodeArray);
01155 
01156   /* If the transitive fanin of the nodes is empty, return */
01157   if (array_n(supportArray) == 0) {
01158     array_free(supportArray);
01159     return NIL(Fsm_Fsm_t);
01160   }
01161 
01162   /* Divide the nodes between inputs and latches and create the final FSM */
01163   inputs = array_alloc(Ntk_Node_t *, 0);
01164   latches = array_alloc(Ntk_Node_t *, 0);
01165   arrayForEachItem(Ntk_Node_t *, supportArray, i, nodePtr) {
01166     if (Ntk_NodeTestIsInput(nodePtr)) {
01167       array_insert_last(Ntk_Node_t *, inputs, nodePtr);
01168     }
01169     else {
01170       assert(Ntk_NodeTestIsLatch(nodePtr));
01171       array_insert_last(Ntk_Node_t *, latches, nodePtr);
01172     }
01173   }
01174   array_free(supportArray);
01175 
01176   /* If the collection of inputs and latches is the whole FSM, return */
01177   if (array_n(inputs) == Ntk_NetworkReadNumInputs(network) &&
01178       array_n(latches) == Ntk_NetworkReadNumLatches(network)) {
01179     array_free(inputs);
01180     array_free(latches);
01181     return NIL(Fsm_Fsm_t);
01182   }
01183 
01184   result = Fsm_FsmCreateReducedFsm(network, NIL(graph_t), latches, inputs, 
01185                                    NIL(array_t));
01186 
01187   /* Clean up */
01188   array_free(inputs);
01189   array_free(latches);
01190 
01191   return result;
01192 } /* End of AbsCreateReducedFsm */
01193 
01202 boolean
01203 AbsMddEqualModCareSet(
01204   mdd_t *f,
01205   mdd_t *g,
01206   mdd_t *careSet)
01207 {
01208   boolean result = mdd_equal_mod_care_set(f, g, careSet);
01209   return result;
01210 } /* End of AbsMddEqualModCareSet */
01211 
01220 boolean
01221 AbsMddLEqualModCareSet(
01222   mdd_t *f,
01223   mdd_t *g,
01224   mdd_t *careSet)
01225 {
01226   boolean result = mdd_lequal_mod_care_set(f, g, 1, 1, careSet);
01227   return result;
01228 } /* End of AbsMddLEqualModCareSet */
01229 
01230 /*---------------------------------------------------------------------------*/
01231 /* Definition of static functions                                            */
01232 /*---------------------------------------------------------------------------*/
01233 
01249 static mdd_t *
01250 ComputeEGtrue(
01251   Abs_VerificationInfo_t *absInfo,
01252   mdd_t *careStates)
01253 {
01254   AbsOptions_t    *options;
01255   AbsVertexInfo_t *vertex;
01256   Ctlp_Formula_t  *egFormula;
01257   Ctlp_Formula_t  *trueFormula;
01258   mdd_manager     *mddManager;
01259   array_t         *inputTranslation;
01260   array_t         *outputTranslation;
01261   mdd_t           *envelope;
01262   long            cpuTime;
01263   
01264   cpuTime = util_cpu_time();
01265   options = AbsVerificationInfoReadOptions(absInfo);
01266   mddManager = AbsVerificationInfoReadMddManager(absInfo);
01267   
01268   /* Compute the EG(true) fixed point */
01269   trueFormula = Ctlp_FormulaCreate(Ctlp_TRUE_c, NIL(void), NIL(void));
01270   egFormula = Ctlp_FormulaCreate(Ctlp_EG_c, trueFormula, NIL(void));
01271   
01272   /* Translate into the graph representation */
01273   inputTranslation = array_alloc(Ctlp_Formula_t *, 1);
01274   array_insert(Ctlp_Formula_t *, inputTranslation, 0, egFormula);
01275   outputTranslation = AbsCtlFormulaArrayTranslate(absInfo, inputTranslation, 
01276                                                   NIL(array_t));
01277   vertex = array_fetch(AbsVertexInfo_t *, outputTranslation, 0);
01278   array_free(inputTranslation);
01279   array_free(outputTranslation);
01280   
01281   /* Evaluate the formula */
01282   AbsSubFormulaVerify(absInfo, vertex);
01283   
01284   envelope = mdd_dup(AbsVertexReadSat(vertex));
01285   
01286   /* Clean up */
01287   Ctlp_FormulaFree(egFormula);
01288   AbsVertexFree(AbsVerificationInfoReadCatalog(absInfo), vertex, 
01289                 NIL(AbsVertexInfo_t));
01290   
01291   /* Print the number of envelope states */
01292   if (AbsOptionsReadVerbosity(options) & ABS_VB_PENV) {
01293     array_t *sVars;
01294     mdd_t *states;
01295   
01296     sVars = Fsm_FsmReadPresentStateVars(AbsVerificationInfoReadFsm(absInfo));
01297     states = mdd_and(envelope, careStates, 1, 1);
01298     (void) fprintf(vis_stdout, "ABS: Envelope with %.0f care states.\n",
01299                    mdd_count_onset(mddManager, states, sVars));
01300     mdd_free(states);
01301   }
01302   
01303   if (AbsOptionsReadVerbosity(options) & ABS_VB_PENV) {
01304     (void) fprintf(vis_stdout, "ABS: %7.1f secs computing EG(TRUE)\n",
01305                    (util_cpu_time() - cpuTime)/1000.0);
01306   }
01307 
01308   return envelope;
01309 } /* End of ComputeEGtrue */
01310 
01319 static void
01320 SelectIdentifierVertices(
01321   AbsVertexInfo_t *vertexPtr,
01322   array_t *result,
01323   st_table *visited)
01324 {
01325   assert(result != NIL(array_t));
01326 
01327   if (vertexPtr == NIL(AbsVertexInfo_t)) {
01328     return;
01329   }
01330 
01331   if (st_is_member(visited, (char *)vertexPtr)) {
01332     return;
01333   }
01334 
01335   if (AbsVertexReadType(vertexPtr) == identifier_c) {
01336     array_insert_last(AbsVertexInfo_t *, result, vertexPtr);
01337     st_insert(visited, (char *)vertexPtr, NIL(char));
01338     return;
01339   }
01340   else {
01341     SelectIdentifierVertices(AbsVertexReadLeftKid(vertexPtr), result, visited);
01342     SelectIdentifierVertices(AbsVertexReadRightKid(vertexPtr), result, visited);
01343   }
01344 
01345   st_insert(visited, (char *)vertexPtr, NIL(char));
01346 
01347   return;
01348 } /* End of SelectIdentifierVertices */