VIS

src/bmc/bmcCirCUs.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: bmcCirCUs.c,v 1.56 2010/04/09 23:50:57 fabio Exp $";
00022 
00023 /*---------------------------------------------------------------------------*/
00024 /* Constant declarations                                                     */
00025 /*---------------------------------------------------------------------------*/
00026 
00027 /*---------------------------------------------------------------------------*/
00028 /* Type declarations                                                         */
00029 /*---------------------------------------------------------------------------*/
00030 
00031 /*---------------------------------------------------------------------------*/
00032 /* Structure declarations                                                    */
00033 /*---------------------------------------------------------------------------*/
00034 
00035 /*---------------------------------------------------------------------------*/
00036 /* Variable declarations                                                     */
00037 /*---------------------------------------------------------------------------*/
00038 
00041 /*---------------------------------------------------------------------------*/
00042 /* Static function prototypes                                                */
00043 /*---------------------------------------------------------------------------*/
00044 
00045 static int printSatValue(bAig_Manager_t *manager, st_table *nodeToMvfAigTable, st_table *li2index, bAigEdge_t **baigArr, array_t *nodeArr, int bound, int *prevValue);
00046 static int printSatValueAiger(bAig_Manager_t *manager, st_table *nodeToMvfAigTable, st_table *li2index, bAigEdge_t **baigArr, array_t *nodeArr, int bound, int *prevValue);
00047 static int StringCheckIsInteger(char *string, int *value);
00048 static int verifyIfConstant(bAigEdge_t property);
00049 
00052 /*---------------------------------------------------------------------------*/
00053 /* Definition of exported functions                                          */
00054 /*---------------------------------------------------------------------------*/
00055 
00056 /*---------------------------------------------------------------------------*/
00057 /* Definition of internal functions                                          */
00058 /*---------------------------------------------------------------------------*/
00059 
00077 void
00078 BmcCirCUsLtlVerifyProp(
00079     Ntk_Network_t   *network,
00080     Ctlsp_Formula_t *ltl,
00081     st_table        *coiTable,
00082     BmcOption_t     *options)
00083 {
00084   mAig_Manager_t    *manager = Ntk_NetworkReadMAigManager(network);
00085   st_table          *nodeToMvfAigTable = NIL(st_table);
00086   long              startTime, endTime;
00087   bAigEdge_t        property;
00088   int               satFlag;
00089   satInterface_t    *interface;
00090   array_t           *objArray;
00091 
00092   assert(Ctlsp_isPropositionalFormula(ltl));
00093 
00094   startTime = util_cpu_ctime();
00095   if (options->verbosityLevel >= BmcVerbosityNone_c){
00096     fprintf(vis_stdout, "LTL formula is propositional\n");
00097   }
00098   property = BmcCirCUsCreatebAigOfPropFormulaOriginal(network, manager, ltl);
00099   if (property == mAig_NULL){
00100     return;
00101   }
00102   if (verifyIfConstant(property)){
00103     if (options->verbosityLevel != BmcVerbosityNone_c){
00104       fprintf(vis_stdout, "-- bmc time = %10g\n",
00105               (double)(util_cpu_ctime() - startTime) / 1000.0);
00106     }
00107     return;
00108   }
00109  
00110   nodeToMvfAigTable = (st_table *) Ntk_NetworkReadApplInfo(network,
00111                                                            MVFAIG_NETWORK_APPL_KEY);
00112   assert(nodeToMvfAigTable != NIL(st_table));
00113   
00114   interface = 0;
00115   objArray  = array_alloc(bAigEdge_t, 0);
00116   bAig_ExpandTimeFrame(network, manager, 1, BMC_INITIAL_STATES);
00117   property = BmcCirCUsCreatebAigOfPropFormula(network, manager,
00118                                               0, ltl, BMC_INITIAL_STATES);
00119   array_insert(bAigEdge_t, objArray, 0, property);
00120   options->cnfPrefix = 0;
00121   interface = BmcCirCUsInterfaceWithObjArr(manager, network,
00122                                            objArray, NIL(array_t),
00123                                            options, interface);
00124   satFlag = interface->status;
00125   sat_FreeInterface(interface);
00126 
00127   if(satFlag == SAT_SAT) {
00128     fprintf(vis_stdout, "# BMC: formula failed\n");
00129     if(options->dbgLevel == 1){
00130       fprintf(vis_stdout, "# BMC: found a counterexample of length 0\n");
00131       BmcCirCUsPrintCounterExample(network, nodeToMvfAigTable, coiTable, 0, 0,
00132                                    options, BMC_INITIAL_STATES);
00133     }
00134     if(options->dbgLevel == 2){
00135       fprintf(vis_stdout, "# BMC: found a counterexample of length 0\n");
00136       fprintf(vis_stdout, "# The counterexample for Structural Sat problem is incomplete.\n");
00137       BmcCirCUsPrintCounterExampleAiger(network, nodeToMvfAigTable, coiTable, 0, 0,
00138                                    options, BMC_INITIAL_STATES);
00139     }
00140 
00141   }
00142   else if(satFlag != SAT_SAT) {
00143     if(options->verbosityLevel != BmcVerbosityNone_c){
00144       fprintf(vis_stdout,"# BMC: no counterexample found of length 0\n");
00145     }
00146     fprintf(vis_stdout,"# BMC: formula passed\n");
00147     (void) fprintf(vis_stdout, "#      Termination depth = 0\n");
00148   }
00149   if (options->verbosityLevel != BmcVerbosityNone_c){
00150     endTime = util_cpu_ctime();
00151     fprintf(vis_stdout, "-- bmc time = %10g\n", (double)(endTime - startTime) / 1000.0);
00152   }
00153   array_free(objArray);
00154   fflush(vis_stdout);
00155   return;
00156 } /* BmcCirCUsLtlVerifyProp() */
00157 
00158 
00188 int
00189 BmcCirCUsLtlCheckInductiveInvariant(
00190   Ntk_Network_t   *network,
00191   Ctlsp_Formula_t *ltl,
00192   BmcOption_t     *options,
00193   st_table        *CoiTable)
00194 {
00195   mAig_Manager_t  *manager = Ntk_NetworkReadMAigManager(network);
00196   bAigEdge_t      property, result;
00197   int             satFlag;
00198   satInterface_t  *interface;
00199   array_t         *objArray   = array_alloc(bAigEdge_t, 1);
00200   int             returnValue = 0;  /* the property is not an inductive
00201                                        invariant */
00202   /*
00203     Check if the property holds in all initial states.
00204    */
00205   interface = 0;
00206   bAig_ExpandTimeFrame(network, manager, 1, BMC_INITIAL_STATES);
00207   property = BmcCirCUsCreatebAigOfPropFormula(network, manager, 0, ltl->right, BMC_INITIAL_STATES);
00208 
00209   array_insert(bAigEdge_t, objArray, 0, property);
00210   options->cnfPrefix = 0;
00211   interface = BmcCirCUsInterfaceWithObjArr(manager, network, objArray,
00212                                  NIL(array_t), options, interface);
00213   satFlag = interface->status;
00214   sat_FreeInterface(interface);
00215 
00216   if(satFlag == SAT_UNSAT) {
00217     /*
00218       Check the induction step.
00219     */
00220     interface = 0;
00221     bAig_ExpandTimeFrame(network, manager, 2, BMC_NO_INITIAL_STATES);
00222     property = BmcCirCUsCreatebAigOfPropFormula(network, manager, 0, ltl->right, BMC_NO_INITIAL_STATES);
00223     /*
00224       The property is true at state 0.  Remember that the passing property is
00225       the negation of the original property.
00226     */
00227     result = bAig_Not(property);
00228     property = BmcCirCUsCreatebAigOfPropFormula(network, manager, 1, ltl->right, BMC_NO_INITIAL_STATES);
00229     /*
00230       The property is false at state 1
00231     */
00232     result = bAig_And(manager, result, property);
00233     array_insert(bAigEdge_t, objArray, 0, result);
00234     options->cnfPrefix = 1;
00235     interface = BmcCirCUsInterfaceWithObjArr(manager, network, objArray,
00236                                    NIL(array_t), options, interface);
00237     satFlag = interface->status;
00238     sat_FreeInterface(interface);
00239     if(satFlag == SAT_UNSAT) {
00240       returnValue = 1; /* the property is an inductive invariant */
00241      
00242     }
00243   }
00244   array_free(objArray);
00245   return returnValue; 
00246 } /* BmcCirCUsLtlCheckInductiveInvariant */
00247 
00248 
00272 void
00273 BmcCirCUsLtlVerifyGp(
00274     Ntk_Network_t   *network,
00275     Ctlsp_Formula_t *ltl,
00276     st_table        *coiTable,
00277     BmcOption_t     *options)
00278 {
00279   mAig_Manager_t    *manager = Ntk_NetworkReadMAigManager(network);
00280   st_table          *nodeToMvfAigTable = NIL(st_table);
00281   long              startTime, endTime;
00282   bAigEdge_t        property, result, simplePath;
00283   int               j, satFlag, k;
00284   int               checkInductiveInvariant;
00285   array_t           *objArray;
00286   array_t           *auxObjArray;
00287   satInterface_t    *ceInterface, *etInterface, *tInterface;
00288   st_table          *coiIndexTable;
00289   Bmc_PropertyStatus formulaStatus;
00290 
00291   assert(Ctlsp_LtlFormulaIsFp(ltl));
00292   
00293   startTime = util_cpu_ctime();
00294 
00295   if (options->verbosityLevel != BmcVerbosityNone_c){
00296     fprintf(vis_stdout, "LTL formula is of type G(p)\n");
00297   }
00298   property = BmcCirCUsCreatebAigOfPropFormulaOriginal(network, manager, ltl->right);
00299   
00300   if (property == mAig_NULL){
00301     return;
00302   }
00303   if (verifyIfConstant(property)){
00304     if (options->verbosityLevel != BmcVerbosityNone_c){
00305       fprintf(vis_stdout, "-- bmc time = %10g\n",
00306               (double)(util_cpu_ctime() - startTime) / 1000.0);
00307     }
00308     return;
00309   }
00310 
00311   if (options->verbosityLevel >= BmcVerbosityMax_c){
00312     (void) fprintf(vis_stdout, "\nBMC: Check if the property is an inductive invariant\n");
00313   }
00314   checkInductiveInvariant = BmcCirCUsLtlCheckInductiveInvariant(network, ltl, options, coiTable);
00315   if (checkInductiveInvariant == 1){
00316     (void) fprintf(vis_stdout,"# BMC: The property is an inductive invariant\n");
00317     (void) fprintf(vis_stdout,"# BMC: formula passed\n");
00318     (void) fprintf(vis_stdout, "#      Termination depth = 0\n");
00319     if (options->verbosityLevel != BmcVerbosityNone_c){
00320       fprintf(vis_stdout, "-- bmc time = %10g\n",
00321               (double)(util_cpu_ctime() - startTime) / 1000.0);
00322     }
00323     return;
00324   }
00325   
00326   nodeToMvfAigTable = (st_table *) Ntk_NetworkReadApplInfo(network,
00327                                                            MVFAIG_NETWORK_APPL_KEY);
00328   assert(nodeToMvfAigTable != NIL(st_table));
00329 
00330   ceInterface = 0;
00331   etInterface = 0;
00332   tInterface  = 0;
00333   if (options->verbosityLevel != BmcVerbosityNone_c){
00334     (void)fprintf(vis_stdout, "Apply BMC on counterexample of length >= %d and <= %d (+%d)\n",
00335                   options->minK, options->maxK, options->step);
00336   }
00337   /*
00338     Hold objects 
00339   */
00340   objArray = array_alloc(bAigEdge_t, 2);
00341   /*
00342     Unused entry is set to bAig_One
00343    */
00344   array_insert(bAigEdge_t, objArray, 1, bAig_One);
00345   /*
00346     Hold auxiliary objects (constraints on the path)
00347   */
00348   auxObjArray = array_alloc(bAigEdge_t, 0);
00349   
00350   bAig_ExpandTimeFrame(network, manager, 1, BMC_NO_INITIAL_STATES); 
00351   coiIndexTable = BmcCirCUsGetCoiIndexTable(network, coiTable);
00352   
00353   formulaStatus = BmcPropertyUndecided_c;
00354   for(k = options->minK; k <= options->maxK; k += options->step){
00355     if (options->verbosityLevel == BmcVerbosityMax_c){
00356       fprintf(vis_stdout, "\nBMC: Generate counterexample of length %d\n", k);
00357     }
00358     /*
00359       Expand counterexample length to k.  In BMC, counterexample of length k means
00360       k+1 time frames.
00361      */
00362     bAig_ExpandTimeFrame(network, manager, k+1, BMC_INITIAL_STATES);
00363     /*
00364       The property true at any states from (k-step+1) to k 
00365      */
00366     result = bAig_Zero;
00367     for(j=k-options->step+1; j<=k; j++) {
00368       /*
00369         For k = options->minK, j goes outside the lower boundary of
00370         counterexample search.
00371       */
00372       if(j < options->minK) continue;
00373       
00374       property = BmcCirCUsCreatebAigOfPropFormula(network, manager, j, ltl->right, BMC_INITIAL_STATES);
00375       result   = bAig_Or(manager, result, property);
00376     }
00377     array_insert(bAigEdge_t, objArray, 0, result);
00378     options->cnfPrefix = k;
00379     ceInterface = BmcCirCUsInterfaceWithObjArr(manager, network, objArray,
00380                                            auxObjArray, options,
00381                                            ceInterface);
00382     satFlag = ceInterface->status;
00383     if(satFlag == SAT_SAT){
00384       formulaStatus = BmcPropertyFailed_c;
00385       break;
00386     }
00387     /*
00388       Given that the property does not hold at all previous states.
00389      */
00390     array_insert_last(bAigEdge_t, auxObjArray, bAig_Not(result));
00391 
00392     /*
00393       Prove if the property passes using the induction proof of SSS0.
00394     */
00395     if((options->inductiveStep !=0) &&
00396        (k % options->inductiveStep == 0)){
00397       array_t *auxArray;
00398       int i;
00399       
00400       if (options->verbosityLevel == BmcVerbosityMax_c) {
00401         (void) fprintf(vis_stdout, "\nBMC: Check for termination\n");
00402       }      
00403       /*
00404         Expand counterexample length to k+1.  In BMC, counterexample of length k+1 means
00405         k+2 time frames.
00406       */
00407       bAig_ExpandTimeFrame(network, manager, k+2, BMC_NO_INITIAL_STATES);
00408       simplePath = BmcCirCUsSimlePathConstraint(network, 0, k+1, nodeToMvfAigTable,
00409                                                 coiIndexTable, BMC_NO_INITIAL_STATES);
00410       property = BmcCirCUsCreatebAigOfPropFormula(network, manager, k+1, ltl->right,
00411                                                   BMC_NO_INITIAL_STATES);
00412       array_insert(bAigEdge_t, objArray, 0, simplePath);
00413       array_insert(bAigEdge_t, objArray, 1, property);
00414       auxArray = array_alloc(bAigEdge_t, 0);
00415       for(i=0; i<=k; i++){
00416         array_insert_last(bAigEdge_t, auxArray,
00417                           bAig_Not(
00418                             BmcCirCUsCreatebAigOfPropFormula(network, manager, i, ltl->right,
00419                                                              BMC_NO_INITIAL_STATES)
00420                             ));
00421       }
00422       options->cnfPrefix = k+1;
00423       tInterface = BmcCirCUsInterfaceWithObjArr(manager, network,
00424                                       objArray, auxArray,
00425                                       options, tInterface);
00426       array_free(auxArray); 
00427       array_insert(bAigEdge_t, objArray, 1, bAig_One);
00428       if(tInterface->status == SAT_UNSAT){
00429         if (options->verbosityLevel == BmcVerbosityMax_c) {
00430           (void) fprintf(vis_stdout,
00431                          "# BMC: No simple path leading to a bad state\n");
00432         }
00433         formulaStatus = BmcPropertyPassed_c;
00434         break;
00435       }
00436       
00437       if(options->earlyTermination){
00438         /*
00439           Early termination condition
00440           
00441           Check if there is no simple path starts from initial states
00442           
00443         */
00444         simplePath = BmcCirCUsSimlePathConstraint(network, 0, k+1, nodeToMvfAigTable,
00445                                                   coiIndexTable,
00446                                                   BMC_INITIAL_STATES);
00447         array_insert(bAigEdge_t, objArray, 0, simplePath);
00448         etInterface = BmcCirCUsInterfaceWithObjArr(manager, network,
00449                                                objArray, NIL(array_t),
00450                                                options, etInterface);
00451         options->cnfPrefix = k+1;
00452         if(etInterface->status == SAT_UNSAT){
00453           if (options->verbosityLevel == BmcVerbosityMax_c) {
00454             (void) fprintf(vis_stdout,
00455                            "# BMC: No simple path starting at an initial state\n");
00456           }
00457           formulaStatus = BmcPropertyPassed_c;
00458           break;
00459         }
00460       }
00461       
00462     } /* check for termination*/
00463   } /* loop over k*/
00464   array_free(objArray);
00465   array_free(auxObjArray);
00466   sat_FreeInterface(ceInterface);
00467   if(etInterface !=0){
00468     sat_FreeInterface(etInterface);
00469   }
00470   if(tInterface !=0){
00471     sat_FreeInterface(tInterface);
00472   }
00473   st_free_table(coiIndexTable);
00474 
00475   if(formulaStatus == BmcPropertyUndecided_c){
00476     if (options->verbosityLevel != BmcVerbosityNone_c){
00477       (void) fprintf(vis_stdout,
00478                      "# BMC: no counterexample found of length up to %d\n",
00479                      options->maxK);
00480     }
00481   }
00482   if(formulaStatus == BmcPropertyFailed_c) {
00483     (void) fprintf(vis_stdout, "# BMC: formula failed\n");
00484     if(options->verbosityLevel != BmcVerbosityNone_c){
00485       (void) fprintf(vis_stdout,
00486                      "# BMC: Found a counterexample of length = %d \n", k);
00487     }
00488     if(options->dbgLevel == 1){
00489       BmcCirCUsPrintCounterExample(network, nodeToMvfAigTable, coiTable, k, 0,
00490                                    options, BMC_INITIAL_STATES);
00491     }
00492     if(options->dbgLevel == 2){
00493       BmcCirCUsPrintCounterExampleAiger(network, nodeToMvfAigTable, coiTable, k, 0,
00494                                    options, BMC_INITIAL_STATES);
00495     }
00496   } else if(formulaStatus == BmcPropertyPassed_c) {
00497     (void) fprintf(vis_stdout, "# BMC: formula Passed\n");
00498     (void) fprintf(vis_stdout, "#      Termination depth = %d\n", k);
00499   } else if(formulaStatus == BmcPropertyUndecided_c) {
00500     (void) fprintf(vis_stdout,"# BMC: formula undecided\n");
00501   }
00502   
00503   if (options->verbosityLevel != BmcVerbosityNone_c){
00504     endTime = util_cpu_ctime();
00505     fprintf(vis_stdout, "-- bmc time = %10g\n", (double)(endTime - startTime) / 1000.0);
00506   }
00507   fflush(vis_stdout);
00508 
00509   return;
00510 } /* BmcCirCUsLtlVerifyGp() */
00511 
00534 void
00535 BmcCirCUsLtlVerifyFp(
00536     Ntk_Network_t   *network,
00537     Ctlsp_Formula_t *ltl,
00538     st_table        *coiTable,
00539     BmcOption_t     *options)
00540 {
00541   mAig_Manager_t    *manager = Ntk_NetworkReadMAigManager(network);
00542   st_table          *nodeToMvfAigTable = NIL(st_table);
00543   long              startTime, endTime;
00544   bAigEdge_t        property, pathProperty, simplePath, tloop, loop;
00545   int               bound, k, satFlag;
00546   array_t           *loop_array = NIL(array_t);
00547   array_t           *objArray;
00548   array_t           *auxObjArray;
00549   st_table          *coiIndexTable;
00550   satInterface_t    *ceInterface;
00551   satInterface_t    *tInterface;
00552   Bmc_PropertyStatus formulaStatus;
00553 
00554   startTime = util_cpu_ctime();
00555   if(options->verbosityLevel != BmcVerbosityNone_c){
00556     fprintf(vis_stdout,"LTL formula is of type F(p)\n");
00557   }
00558   property = BmcCirCUsCreatebAigOfPropFormulaOriginal(network, manager,
00559                                                       ltl->right);
00560   if (verifyIfConstant(property)){
00561     if (options->verbosityLevel != BmcVerbosityNone_c){
00562       fprintf(vis_stdout, "-- bmc time = %10g\n",
00563               (double)(util_cpu_ctime() - startTime) / 1000.0);
00564     }
00565     return;
00566   }
00567 
00568   nodeToMvfAigTable = 
00569           (st_table *) Ntk_NetworkReadApplInfo(network, MVFAIG_NETWORK_APPL_KEY);
00570   assert(nodeToMvfAigTable != NIL(st_table));
00571   
00572   bAig_ExpandTimeFrame(network, manager, 0, BMC_INITIAL_STATES);
00573   coiIndexTable = BmcCirCUsGetCoiIndexTable(network, coiTable);
00574 
00575  /*
00576     Hold objects 
00577   */
00578   objArray = array_alloc(bAigEdge_t, 2);
00579   /*
00580     Unused entry is set to bAig_One
00581    */
00582   array_insert(bAigEdge_t, objArray, 1, bAig_One);
00583   /*
00584     Hold auxiliary objects (constraints on the path)
00585   */
00586   auxObjArray = array_alloc(bAigEdge_t, 0);
00587   
00588   ceInterface = 0;
00589   tInterface  = 0;
00590   formulaStatus = BmcPropertyUndecided_c;
00591   if(options->verbosityLevel != BmcVerbosityNone_c){
00592     fprintf(vis_stdout,"Apply BMC on counterexample of length >= %d and <= %d (+%d)\n",
00593                        options->minK, options->maxK, options->step);
00594 
00595   }
00596   bound = options->minK;
00597   while(bound<=options->maxK) {
00598     if(options->verbosityLevel == BmcVerbosityMax_c)
00599       fprintf(vis_stdout, "\nBMC: Generate counterexample of length %d\n", bound);
00600     /*
00601       Expand counterexample length to bound.  In BMC, counterexample of length bound means
00602       bound+1 time frames.
00603     */
00604     bAig_ExpandTimeFrame(network, manager, bound+1, BMC_INITIAL_STATES );
00608     loop_array = array_alloc(bAigEdge_t *, 0);
00609     tloop = bAig_Zero;
00610     /*
00611       Loop from state 'bound' to any previous states.
00612      */
00613     for(k=0; k<=bound; k++) {
00614       loop = BmcCirCUsConnectFromStateToState(network, bound, k, nodeToMvfAigTable,
00615                                               coiIndexTable, BMC_INITIAL_STATES);
00616       array_insert(bAigEdge_t, loop_array, k, loop);
00617       tloop = bAig_Or(manager, tloop, loop);
00618     }
00619     array_insert(bAigEdge_t, objArray, 0, tloop);
00620     /*
00621       tloop equals true for k-loop path 
00622      */
00623     /*
00624       Property false at all states
00625      */
00626     pathProperty = bAig_One;
00627     for(k=bound; k>=0; k--) {
00628       property = BmcCirCUsCreatebAigOfPropFormula(network, manager, k, ltl->right, BMC_INITIAL_STATES);
00629       pathProperty = bAig_And(manager, pathProperty, property);
00630     }
00631     array_insert(bAigEdge_t, objArray, 1, pathProperty);
00632     
00633     options->cnfPrefix = bound;
00634     ceInterface = BmcCirCUsInterfaceWithObjArr(manager, network,
00635                                                objArray, auxObjArray,
00636                                                options, ceInterface);
00637     satFlag = ceInterface->status;
00638     if(satFlag == SAT_SAT){
00639       formulaStatus = BmcPropertyFailed_c;
00640       break;
00641     }
00642 
00643     array_insert_last(bAigEdge_t, auxObjArray, bAig_Not(tloop));
00644 
00645     if((options->inductiveStep !=0) &&
00646        (bound % options->inductiveStep == 0)){
00647 
00648       if (options->verbosityLevel == BmcVerbosityMax_c) {
00649         (void) fprintf(vis_stdout,
00650                        "\nBMC: Check for termination\n");
00651       }
00652       simplePath = BmcCirCUsSimlePathConstraint(network, 0, bound, nodeToMvfAigTable,
00653                                                 coiIndexTable,
00654                                                 BMC_INITIAL_STATES);
00655       array_insert(bAigEdge_t, objArray, 0, simplePath);
00656       array_insert(bAigEdge_t, objArray, 1, pathProperty);
00657       tInterface = BmcCirCUsInterfaceWithObjArr(manager, network,
00658                                                 objArray, auxObjArray,
00659                                                 options, tInterface);
00660       if(tInterface->status == SAT_UNSAT){
00661         formulaStatus = BmcPropertyPassed_c;
00662         break;
00663       }
00664     }
00665     bound += options->step;
00666   }
00667   array_free(objArray);
00668   array_free(auxObjArray);
00669   st_free_table(coiIndexTable);
00670   sat_FreeInterface(ceInterface);
00671   sat_FreeInterface(tInterface);
00672 
00673   if(formulaStatus == BmcPropertyUndecided_c){
00674     if (options->verbosityLevel != BmcVerbosityNone_c){
00675       (void) fprintf(vis_stdout,
00676                      "# BMC: no counterexample found of length up to %d\n",
00677                      options->maxK);
00678     }
00679   }
00680   if(formulaStatus == BmcPropertyFailed_c) {
00681     (void) fprintf(vis_stdout, "# BMC: formula failed\n");
00682     if(options->verbosityLevel != BmcVerbosityNone_c){
00683       (void) fprintf(vis_stdout,
00684                      "# BMC: Found a counterexample of length = %d \n", bound);
00685     }
00686     if(options->dbgLevel == 1){
00687      BmcCirCUsPrintCounterExample(network, nodeToMvfAigTable, coiTable, bound, loop_array,
00688                                    options, BMC_INITIAL_STATES);
00689     }
00690     if(options->dbgLevel == 2){
00691      BmcCirCUsPrintCounterExampleAiger(network, nodeToMvfAigTable, coiTable, bound, loop_array,
00692                                    options, BMC_INITIAL_STATES);
00693     }
00694 
00695   } else if(formulaStatus == BmcPropertyPassed_c) {
00696     (void) fprintf(vis_stdout, "# BMC: formula Passed\n");
00697     (void) fprintf(vis_stdout, "#      Termination depth = %d\n", bound);
00698   } else if(formulaStatus == BmcPropertyUndecided_c) {
00699     (void) fprintf(vis_stdout,"# BMC: formula undecided\n");
00700   }
00701   if (options->verbosityLevel != BmcVerbosityNone_c) {
00702     endTime = util_cpu_ctime();
00703     fprintf(vis_stdout, "-- bmc time = %10g\n", (double)(endTime - startTime) / 1000.0);
00704   }
00705   fflush(vis_stdout);  
00706   array_free(loop_array);
00707 
00708 } /* BmcCirCUsLtlVerifyFp() */
00709 
00723 bAigEdge_t
00724 BmcCirCUsGenerateLogicForLtl(
00725     Ntk_Network_t   *network,
00726     Ctlsp_Formula_t *ltl,
00727     int from,
00728     int to,
00729     int loop)
00730 {
00731   bAigEdge_t property, temp;
00732   bAigEdge_t left, right, result;
00733   int j, k;
00734   mAig_Manager_t  *manager = Ntk_NetworkReadMAigManager(network);
00735 
00736   if(Ctlsp_isPropositionalFormula(ltl)){
00737     property = BmcCirCUsCreatebAigOfPropFormula(network, manager, from, ltl, BMC_INITIAL_STATES);
00738     return(property);
00739   }
00740 
00741   switch(ltl->type) {
00742     case Ctlsp_NOT_c:
00743       if (!Ctlsp_isPropositionalFormula(ltl->left)){
00744         fprintf(vis_stderr,"BMC error: the LTL formula is not in NNF\n");
00745         return 0;
00746       }
00747     case Ctlsp_AND_c:
00748       left = BmcCirCUsGenerateLogicForLtl(network, ltl->left, from, to, loop);
00749       if(left == bAig_Zero)     return(bAig_Zero);
00750       right = BmcCirCUsGenerateLogicForLtl(network, ltl->right, from, to, loop);
00751       return(bAig_And(manager, left, right));
00752     case Ctlsp_OR_c:
00753       left = BmcCirCUsGenerateLogicForLtl(network, ltl->left, from, to, loop);
00754       if(left == bAig_One)      return(bAig_One);
00755       right = BmcCirCUsGenerateLogicForLtl(network, ltl->right, from, to, loop);
00756       return(bAig_Or(manager, left, right));
00757     case Ctlsp_F_c:
00758       if(loop >= 0)     from = (loop<from) ? loop : from;
00759       result = bAig_Zero;
00760       for(j=from; j<=to; j++)  {
00761         left = BmcCirCUsGenerateLogicForLtl(network, ltl->left, j, to, loop);
00762         if(left == bAig_One)    return(left);
00763         result = bAig_Or(manager, left, result);
00764       }
00765       return(result);
00766     case Ctlsp_G_c:
00767       if(loop < 0)      return(bAig_Zero);
00768       from = (loop < from) ? loop : from;
00769       result = bAig_One;
00770       for(j=from; j<=to; j++) {
00771         left = BmcCirCUsGenerateLogicForLtl(network, ltl->left, j, to, loop);
00772         result = bAig_And(manager, result, left);
00773         if(result == bAig_Zero) break;
00774       }
00775       return(result);
00776     case Ctlsp_X_c:
00777       if(loop>=0 && from == to) from = loop;
00778       else if(from < to)        from = from + 1;
00779       else                      return(bAig_Zero);
00780       left = BmcCirCUsGenerateLogicForLtl(network, ltl->left, from, to, loop);
00781       return(left);
00782     case Ctlsp_U_c:
00783       result = bAig_Zero;
00784       for(j=from; j<=to; j++) {
00785         right = BmcCirCUsGenerateLogicForLtl(network, ltl->right, j, to, loop);
00786         temp = right;
00787         for(k=from; (k<=j-1); k++) {
00788           left = BmcCirCUsGenerateLogicForLtl(network, ltl->left, k, to, loop);
00789           temp = bAig_And(manager, temp, left);
00790           if(temp == bAig_Zero) break;
00791         }
00792         result = bAig_Or(manager, result, temp);
00793         if(result == bAig_One) break;
00794       }
00795       if(loop>=0 && result != bAig_One) {
00796         for(j=loop; j<=from-1; j++) {
00797           right = BmcCirCUsGenerateLogicForLtl(network, ltl->right, j, to, loop);
00798           temp = right;
00799           for(k=from; k<=to; k++) {
00800             left = BmcCirCUsGenerateLogicForLtl(network, ltl->left, k, to, loop);
00801             temp = bAig_And(manager, temp, left);
00802             if(temp == bAig_Zero)       break;
00803           }
00804           for(k=loop; k<=j-1; k++) {
00805             left = BmcCirCUsGenerateLogicForLtl(network, ltl->left, k, to, loop);
00806             temp = bAig_And(manager, temp, left);
00807             if(temp == bAig_Zero)       break;
00808           }
00809           result = bAig_Or(manager, result, temp);
00810           if(result == bAig_One) break;
00811         }
00812       }
00813       return(result);
00814     case Ctlsp_R_c:
00815       result = bAig_Zero;
00816       if(loop >= 0) {
00817         temp = bAig_One;
00818         for(j=(from<loop ? from : loop); j<=to; j++) {
00819           right = BmcCirCUsGenerateLogicForLtl(network, ltl->right, j, to, loop);
00820           temp = bAig_And(manager, temp, right);
00821           if(temp == bAig_Zero) break;
00822         }
00823         result = bAig_Or(manager, result, temp);
00824       }
00825       if(result != bAig_One) {
00826         for(j=from; j<=to; j++) {
00827           left = BmcCirCUsGenerateLogicForLtl(network, ltl->left, j, to, loop);
00828           temp = left;
00829           for(k=from; k<=j; k++) {
00830             right = BmcCirCUsGenerateLogicForLtl(network, ltl->right, k, to, loop);
00831             temp = bAig_And(manager, temp, right);
00832             if(temp == bAig_Zero)       break;
00833           }
00834           result = bAig_Or(manager, temp, result);
00835           if(result == bAig_One) break;
00836         }
00837         if(loop >= 0 && result != bAig_One) {
00838           for(j=loop; j<=from-1; j++) {
00839             left = BmcCirCUsGenerateLogicForLtl(network, ltl->left, j, to, loop);
00840 
00841             temp = left;
00842             for(k=from; k<=to; k++) {
00843               right = BmcCirCUsGenerateLogicForLtl(network, ltl->right, k, to, loop);
00844               temp = bAig_And(manager, temp, right);
00845               if(temp == bAig_Zero)     break;
00846             }
00847 
00848             for(k=loop; k<=j; k++) {
00849               right = BmcCirCUsGenerateLogicForLtl(network, ltl->right, k, to, loop);
00850               temp = bAig_And(manager, temp, right);
00851               if(temp == bAig_Zero)     break;
00852             }
00853 
00854             result = bAig_Or(manager, result, temp);
00855             if(result == bAig_One) break;
00856           }
00857         }
00858       }
00859       return(result);
00860     default:
00861       fail("Unexpected LTL formula type");
00862       break;
00863   }
00864   assert(0);
00865   return(-1);
00866 
00867 }
00868 
00881 bAigEdge_t
00882 BmcCirCUsGenerateLogicForLtlSNF(
00883   Ntk_Network_t   *network,
00884   array_t         *formulaArray,
00885   int             fromState,
00886   int             toState,
00887   int             loop)
00888 {
00889   mAig_Manager_t  *manager = Ntk_NetworkReadMAigManager(network);
00890   Ctlsp_Formula_t *formula;
00891   bAigEdge_t      property = bAig_One;
00892   bAigEdge_t      left, right, result;
00893   int             i, k;
00894   Ctlsp_Formula_t *leftChild, *rightChild;
00895 
00896   for (i = 0; i < array_n(formulaArray); i++) { 
00897     formula    = array_fetch(Ctlsp_Formula_t *, formulaArray, i);  
00898     leftChild  = Ctlsp_FormulaReadLeftChild(formula);
00899     rightChild = Ctlsp_FormulaReadRightChild(formula);
00900 
00901     if(!strcmp(Ctlsp_FormulaReadVariableName(leftChild), " SNFstart")){
00902       result = BmcCirCUsGenerateLogicForLtl(network, rightChild,
00903                                             0, toState, loop);
00904     } else 
00905       if(!strcmp(Ctlsp_FormulaReadVariableName(leftChild), " SNFbound")){
00906         result =  BmcCirCUsGenerateLogicForLtl(network, rightChild,
00907                                                toState, toState, loop);
00908       } else {
00909         result = bAig_One;
00910         for(k=fromState; k<= toState; k++){
00911           left  = BmcCirCUsGenerateLogicForLtl(network, leftChild,
00912                                                k, toState, loop);
00913           right = BmcCirCUsGenerateLogicForLtl(network, rightChild,
00914                                                k, toState, loop);
00915           result = bAig_And(manager, result,
00916                             bAig_Then(manager, left, right));
00917         }
00918       }
00919     property = bAig_And(manager, property, result);
00920   }
00921   return property;
00922 } /* BmcCirCUsGenerateLogicForLtlSNF */
00923 
00924 
00943 bAigEdge_t
00944 BmcCirCUsGenerateLogicForLtlFixPoint(
00945   Ntk_Network_t   *network,
00946   Ctlsp_Formula_t *ltl,
00947   int             from,
00948   int             to,
00949   array_t         *loopArray)
00950 {
00951   bAigEdge_t result;
00952   st_table   *ltl2AigTable;
00953 
00954   assert(ltl != NIL(Ctlsp_Formula_t));
00955   
00956   ltl2AigTable = st_init_table(strcmp, st_strhash);
00957   result = BmcCirCUsGenerateLogicForLtlFixPointRecursive(network, ltl,
00958                                   from, to, 0, loopArray, ltl2AigTable);
00959   st_free_table(ltl2AigTable);
00960 
00961   return result;
00962 } /* BmcCirCUsGenerateLogicForLtlFixPoint */
00963 
00975 bAigEdge_t
00976 BmcCirCUsGenerateLogicForLtlFixPointRecursive(
00977   Ntk_Network_t   *network,
00978   Ctlsp_Formula_t *ltl,
00979   int             from,
00980   int             to,
00981   int             translation, /* 0 auxilary translation. 1 final translation */
00982   array_t         *loopArray,
00983   st_table        *ltl2AigTable)
00984 {
00985   mAig_Manager_t  *manager = Ntk_NetworkReadMAigManager(network);
00986   bAigEdge_t      property, temp;
00987   bAigEdge_t      left, right, result;
00988 
00989   int      j;
00990 
00991   char     *nameKey;
00992   char     tmpName[100];
00993 
00994   /*
00995     Check if AIG was built for this LTL formula at a given time
00996    */
00997   sprintf(tmpName, "%ld_%d%d", (long)ltl, from, translation);
00998   nameKey = util_strsav(tmpName);
00999   if(st_lookup(ltl2AigTable, nameKey, &result)){
01000     FREE(nameKey);
01001     return result;
01002   }
01003   FREE(nameKey);
01004   
01005   if(Ctlsp_isPropositionalFormula(ltl)){
01006     property = BmcCirCUsCreatebAigOfPropFormula(network, manager,
01007                                                 from, ltl, BMC_INITIAL_STATES);
01008     sprintf(tmpName, "%ld_%d%d", (long)ltl, from, 1);
01009     nameKey = util_strsav(tmpName);
01010     st_insert(ltl2AigTable, nameKey, (char*) (long) property);
01011     return(property);
01012   }
01013   switch(ltl->type) {
01014   case Ctlsp_NOT_c:
01015     if (!Ctlsp_isPropositionalFormula(ltl->left)){
01016       fprintf(vis_stderr,"BMC error: the LTL formula is not in NNF\n");
01017 
01018       return 0;
01019     }
01020   case Ctlsp_AND_c:
01021     left = BmcCirCUsGenerateLogicForLtlFixPointRecursive(network, ltl->left, from, to,
01022                                                          translation, loopArray, ltl2AigTable);
01023     if(left == bAig_Zero){
01024       return(bAig_Zero);
01025     }
01026     right = BmcCirCUsGenerateLogicForLtlFixPointRecursive(network, ltl->right, from, to,
01027                                                           translation, loopArray, ltl2AigTable);
01028     return(bAig_And(manager, left, right));
01029   case Ctlsp_OR_c:
01030     left = BmcCirCUsGenerateLogicForLtlFixPointRecursive(network, ltl->left, from, to,
01031                                                          translation, loopArray, ltl2AigTable);
01032     if(left == bAig_One){
01033       return(bAig_One);
01034     }
01035     right = BmcCirCUsGenerateLogicForLtlFixPointRecursive(network, ltl->right, from, to,
01036                                                           translation, loopArray, ltl2AigTable);
01037     return(bAig_Or(manager, left, right));
01038   case Ctlsp_X_c:
01039     if(from < to){
01040       result = BmcCirCUsGenerateLogicForLtlFixPointRecursive(network, ltl->left, from+1, to,
01041                                                              1, loopArray, ltl2AigTable);
01042     } else {
01043       result =  bAig_Zero;
01044       for(j=1; j<=to; j++) {
01045         left  = BmcCirCUsGenerateLogicForLtlFixPointRecursive(network, ltl->left,  j, to,
01046                                                               1, loopArray, ltl2AigTable);
01047         temp = bAig_And(manager, array_fetch(bAigEdge_t, loopArray, j), left);
01048         result = bAig_Or(manager, result, temp);
01049       }
01050     }
01051     sprintf(tmpName, "%ld_%d%d", (long) ltl, from, 1);
01052     nameKey = util_strsav(tmpName);
01053     st_insert(ltl2AigTable, nameKey, (char*) (long) result);
01054     return result;
01055   case Ctlsp_U_c:
01056     sprintf(tmpName, "%ld_%d%d", (long) ltl, to, 0); /* 0 for auxiliary translation*/
01057     nameKey = util_strsav(tmpName);
01058     right = BmcCirCUsGenerateLogicForLtlFixPointRecursive(network, ltl->right, to, to, 1, loopArray, ltl2AigTable);
01059     st_insert(ltl2AigTable, nameKey, (char*) (long) right);
01060     /*
01061       Compute the auxiliary translation.
01062     */
01063     for(j=to-1; j>=from; j--) {
01064       result = BmcCirCUsGenerateLogicForLtlFixPointRecursive(network, ltl, j+1, to, 0, loopArray, ltl2AigTable);
01065       
01066       right = BmcCirCUsGenerateLogicForLtlFixPointRecursive(network, ltl->right, j, to, 1, loopArray, ltl2AigTable);
01067       left  = BmcCirCUsGenerateLogicForLtlFixPointRecursive(network, ltl->left,  j, to, 1, loopArray, ltl2AigTable);
01068       
01069       result  = bAig_And(manager,left, result);
01070       result  = bAig_Or(manager,right, result);
01071       
01072       sprintf(tmpName, "%ld_%d%d", (long)ltl, j, 0); /* 0 for auxiliary translation*/
01073       nameKey = util_strsav(tmpName);
01074       st_insert(ltl2AigTable, nameKey, (char*) (long) result);
01075     }
01076     /*
01077       Compute the final translation at k.
01078     */
01079     result =  bAig_Zero;
01080     for(j=1; j<=to; j++) {
01081       temp = bAig_And(manager, array_fetch(bAigEdge_t, loopArray, j),
01082                       BmcCirCUsGenerateLogicForLtlFixPointRecursive(
01083                         network, ltl, j, to, 0, loopArray, ltl2AigTable));
01084       result = bAig_Or(manager, result, temp);
01085     }
01086     right = BmcCirCUsGenerateLogicForLtlFixPointRecursive(network, ltl->right, to, to, 1, loopArray, ltl2AigTable);
01087     left  = BmcCirCUsGenerateLogicForLtlFixPointRecursive(network, ltl->left,
01088                                                           to, to, 1, loopArray,
01089                                                           ltl2AigTable);
01090     
01091     result  = bAig_And(manager,left, result);
01092     result  = bAig_Or(manager,right, result);
01093     
01094     sprintf(tmpName, "%ld_%d%d", (long)ltl, to, 1); /* 1 for final translation*/
01095     nameKey = util_strsav(tmpName);
01096     st_insert(ltl2AigTable, nameKey, (char*) (long) result);
01097     /*
01098       Compute the final translation.
01099     */
01100     for(j=to-1; j>=from; j--) {
01101       result = BmcCirCUsGenerateLogicForLtlFixPointRecursive(network, ltl, j+1, to, 1, loopArray, ltl2AigTable);
01102 
01103       right = BmcCirCUsGenerateLogicForLtlFixPointRecursive(network, ltl->right, j, to, 1, loopArray, ltl2AigTable);
01104       left  = BmcCirCUsGenerateLogicForLtlFixPointRecursive(network, ltl->left,  j, to, 1, loopArray, ltl2AigTable);
01105     
01106       result  = bAig_And(manager,left, result);
01107       result  = bAig_Or(manager,right, result);
01108 
01109       sprintf(tmpName, "%ld_%d%d", (long)ltl, j, 1);
01110       nameKey = util_strsav(tmpName);
01111       st_insert(ltl2AigTable, nameKey, (char*) (long) result);
01112     }
01113     return(result);
01114   case Ctlsp_R_c:
01115     sprintf(tmpName, "%ld_%d%d", (long)ltl, to, 0); /* 0 for auxiliary translation*/
01116     right = BmcCirCUsGenerateLogicForLtlFixPointRecursive(network, ltl->right, to, to, 1, loopArray, ltl2AigTable);
01117     nameKey = util_strsav(tmpName);
01118     st_insert(ltl2AigTable, nameKey, (char*) (long) right);
01119     /*
01120       Compute the auxiliary translation.
01121     */
01122     for(j=to-1; j>=from; j--) {
01123       result = BmcCirCUsGenerateLogicForLtlFixPointRecursive(network, ltl, j+1, to, 0, loopArray, ltl2AigTable);
01124       
01125       right = BmcCirCUsGenerateLogicForLtlFixPointRecursive(network, ltl->right, j, to, 1, loopArray, ltl2AigTable);
01126       left  = BmcCirCUsGenerateLogicForLtlFixPointRecursive(network, ltl->left,  j, to, 1, loopArray, ltl2AigTable);
01127       
01128       result  = bAig_Or(manager,left, result);
01129       result  = bAig_And(manager,right, result);
01130       
01131       sprintf(tmpName, "%ld_%d%d", (long) ltl, j, 0); /* 0 for auxiliary translation*/
01132       nameKey = util_strsav(tmpName);
01133       st_insert(ltl2AigTable, nameKey, (char*) (long) result);
01134     }
01135     /*
01136       Compute the final translation at k.
01137     */
01138     result =  bAig_Zero;
01139     for(j=1; j<=to; j++) {
01140       temp = bAig_And(manager, array_fetch(bAigEdge_t, loopArray, j),
01141                       BmcCirCUsGenerateLogicForLtlFixPointRecursive(
01142                         network, ltl, j, to, 0, loopArray, ltl2AigTable));
01143       result = bAig_Or(manager, result, temp);
01144     }
01145     right = BmcCirCUsGenerateLogicForLtlFixPointRecursive(network, ltl->right,
01146                                                           to, to, 1, loopArray,
01147                                                           ltl2AigTable);
01148     left  = BmcCirCUsGenerateLogicForLtlFixPointRecursive(network, ltl->left,
01149                                                           to, to, 1, loopArray,
01150                                                           ltl2AigTable);    
01151     result  = bAig_Or(manager,left, result);
01152     result  = bAig_And(manager,right, result);
01153     
01154     sprintf(tmpName, "%ld_%d%d", (long) ltl, to+1, 1); /* 1 for final translation*/
01155     nameKey = util_strsav(tmpName);
01156     st_insert(ltl2AigTable, nameKey, (char*) (long) result);
01157     /*
01158       Compute the final translation.
01159     */
01160     for(j=to-1; j>=from; j--) {
01161       result = BmcCirCUsGenerateLogicForLtlFixPointRecursive(network, ltl, j+1, to, 1, loopArray, ltl2AigTable);
01162 
01163       right = BmcCirCUsGenerateLogicForLtlFixPointRecursive(network, ltl->right, j, to, 1, loopArray, ltl2AigTable);
01164       left  = BmcCirCUsGenerateLogicForLtlFixPointRecursive(network, ltl->left,  j, to, 1, loopArray, ltl2AigTable);
01165     
01166       result  = bAig_Or(manager,left, result);
01167       result  = bAig_And(manager,right, result);
01168 
01169       sprintf(tmpName, "%ld_%d%d", (long)ltl, j, 1);
01170       nameKey = util_strsav(tmpName);
01171       st_insert(ltl2AigTable, nameKey, (char*) (long) result);
01172     }
01173     return(result);
01174   case Ctlsp_F_c:
01175     /*
01176       Compute only the auxiliary translation.
01177     */
01178     sprintf(tmpName, "%ld_%d%d", (long)ltl, to, 0); /* 0 for auxiliary translation*/
01179     nameKey = util_strsav(tmpName);
01180     left = BmcCirCUsGenerateLogicForLtlFixPointRecursive(network, ltl->left,
01181                                                          to, to, 1, loopArray,
01182                                                          ltl2AigTable);
01183     st_insert(ltl2AigTable, nameKey, (char*) (long) left);
01184 
01185     for(j=to-1; j>=from; j--) {
01186       result = BmcCirCUsGenerateLogicForLtlFixPointRecursive(network, ltl,
01187                                                              j+1, to, 0,
01188                                                              loopArray,
01189                                                              ltl2AigTable);
01190       left = BmcCirCUsGenerateLogicForLtlFixPointRecursive(network, ltl->left,
01191                                                            j, to, 1, loopArray,
01192                                                            ltl2AigTable);
01193       result  = bAig_Or(manager,left, result);
01194       
01195       sprintf(tmpName, "%ld_%d%d", (long)ltl, j, 0); /* 0 for auxiliary translation*/
01196       nameKey = util_strsav(tmpName);
01197       st_insert(ltl2AigTable, nameKey, (char*) (long) result);
01198     }
01199     result =  bAig_Zero;
01200     for(j=1; j<=to; j++) {
01201       temp = bAig_And(manager, array_fetch(bAigEdge_t, loopArray, j),
01202                       BmcCirCUsGenerateLogicForLtlFixPointRecursive(
01203                         network, ltl, j, to, 0, loopArray, ltl2AigTable));
01204       result = bAig_Or(manager, result, temp);
01205     }
01206     return(result);
01207   default:
01208     fail("Unexpected LTL formula type");
01209     break;
01210   }
01211   assert(0);
01212   return(-1);
01213 }
01214 
01235 void
01236 BmcCirCUsLtlVerifyFGp(
01237    Ntk_Network_t   *network,
01238    Ctlsp_Formula_t *ltlFormula,
01239    st_table        *coiTable,
01240    BmcOption_t     *options)
01241 {
01242   mAig_Manager_t   *manager = Ntk_NetworkReadMAigManager(network);
01243   st_table         *nodeToMvfAigTable = NIL(st_table);  /* node to mvfAig */
01244 
01245   int              j, k, l, satFlag;
01246 
01247   long             startTime, endTime;
01248   int              minK = options->minK;
01249   int              maxK = options->maxK;
01250   Ctlsp_Formula_t  *propFormula;
01251   bAigEdge_t       property, loop, pathProperty, tloop;
01252   array_t          *loop_array = NIL(array_t);
01253   array_t          *previousResultArray;
01254   st_table         *coiIndexTable;
01255   satInterface_t   *ceInterface;
01256   
01257   Bmc_PropertyStatus formulaStatus;
01258 
01259   int              m=-1, n=-1;
01260   int              checkLevel = 0;
01261   /*
01262     Refer to Theorem 1 in the paper "Proving More Properties with Bounded Model Checking"
01263     
01264     If checkLevel == 0 -->  check for beta' only. If UNSAT, m=k and chekLevel = 1
01265     If checkLevel == 1 -->  check for beta  only. If UNSAT, checkLevel = 2.
01266     If checkLevel == 2 -->  check for alpha only. If UNSAT, n=k and checkLevel = 3.
01267     If gama is UNSAT up to (m+n-1) and checkLvel = 3, formula passes.
01268     checkLevel = 4 if (m+n-1) > maxK; */
01269 
01270   /*
01271     Remember the LTL property was negated
01272   */
01273   assert(Ctlsp_LtlFormulaIsGFp(ltlFormula));
01274 
01275   /* ************** */
01276   /* Initialization */
01277   /* ************** */
01278   
01279   startTime = util_cpu_ctime();
01280   if(options->verbosityLevel >= BmcVerbosityMax_c){
01281     fprintf(vis_stdout,"LTL formula is of type FG(p)\n");
01282   }
01283   propFormula = Ctlsp_FormulaReadRightChild(Ctlsp_FormulaReadRightChild(ltlFormula));
01284   property = BmcCirCUsCreatebAigOfPropFormulaOriginal(network, manager,
01285                                                       propFormula);
01286   if (verifyIfConstant(property)){
01287     if (options->verbosityLevel != BmcVerbosityNone_c){
01288       fprintf(vis_stdout, "-- bmc time = %10g\n",
01289               (double)(util_cpu_ctime() - startTime) / 1000.0);
01290     }
01291     return;
01292   }
01293  
01294   /*
01295     nodeToMvfAigTable maps each node to its multi-function And/Inv graph
01296   */
01297   nodeToMvfAigTable =
01298     (st_table *) Ntk_NetworkReadApplInfo(network, MVFAIG_NETWORK_APPL_KEY);
01299   assert(nodeToMvfAigTable != NIL(st_table));
01300   
01301   bAig_ExpandTimeFrame(network, manager, 0, BMC_INITIAL_STATES);
01302   coiIndexTable = BmcCirCUsGetCoiIndexTable(network, coiTable);
01303   
01304   previousResultArray = array_alloc(bAigEdge_t, 0);
01305   ceInterface = 0;
01306   if(options->verbosityLevel != BmcVerbosityNone_c){
01307     fprintf(vis_stdout,"Apply BMC on counterexample of length >= %d and <= %d (+%d)\n",
01308             options->minK, options->maxK, options->step);
01309     
01310   }
01311   k= minK;
01312   formulaStatus = BmcPropertyUndecided_c;
01313   while(k <= maxK){
01314     if (options->verbosityLevel >= BmcVerbosityMax_c) {
01315       (void) fprintf(vis_stdout, "\nGenerate counterexample of length %d\n", k);
01316     }
01317    /*
01318      Expand counterexample length to bound.  In BMC, counterexample of length bound means
01319      k+1 time frames.
01320    */
01321     bAig_ExpandTimeFrame(network, manager, k+1, BMC_INITIAL_STATES );
01322 
01323     /*
01324       k-loop
01325     */
01326     loop_array = array_alloc(bAigEdge_t *, 0);
01327     tloop = bAig_Zero;
01328     /*
01329       Loop from last state to any previous states.
01330     */
01331     for(l=0; l<=k; l++) {
01332       loop = BmcCirCUsConnectFromStateToState(network, k, l, nodeToMvfAigTable,
01333                                               coiIndexTable, BMC_INITIAL_STATES);
01334       array_insert(bAigEdge_t, loop_array, l, loop);
01335       pathProperty = bAig_Zero;
01336       for(j=l; j<=k; j++){
01337         property = BmcCirCUsCreatebAigOfPropFormula(network, manager, j, propFormula, BMC_INITIAL_STATES);
01338         pathProperty = bAig_Or(manager, pathProperty, property);
01339       }
01340       
01341       tloop = bAig_Or(manager, tloop, bAig_And(manager, pathProperty, loop));
01342     }
01343     options->cnfPrefix = k;
01344     ceInterface = BmcCirCUsInterface(manager, network, tloop,
01345                                      previousResultArray, options,
01346                                      ceInterface);
01347     satFlag = ceInterface->status;
01348     if(satFlag == SAT_SAT){
01349       formulaStatus = BmcPropertyFailed_c;
01350       break;
01351     }
01352     array_free(loop_array);
01353 
01354     /* ==================
01355        Prove termination
01356        ================== */
01357     if((checkLevel < 3) &&
01358        (options->inductiveStep !=0) &&
01359        (k % options->inductiveStep == 0))
01360       {
01361         satInterface_t *tInterface=0, *etInterface=0;
01362         bAigEdge_t     simplePath, property;
01363         int            i;
01364         
01365         /* ===========================
01366            Early termination condition
01367            ===========================
01368         */
01369         if (options->earlyTermination) {
01370           if (options->verbosityLevel >= BmcVerbosityMax_c) {
01371             (void) fprintf(vis_stdout, "\nChecking for early termination at k= %d\n", k);
01372           }
01373           bAig_ExpandTimeFrame(network, manager, k+1, BMC_INITIAL_STATES);
01374           simplePath = BmcCirCUsSimlePathConstraint(network, 0, k, nodeToMvfAigTable,
01375                                                     coiIndexTable, BMC_INITIAL_STATES);
01376           options->cnfPrefix = k;
01377           etInterface = BmcCirCUsInterface(manager, network,
01378                                            simplePath,
01379                                            previousResultArray,
01380                                            options, etInterface);
01381           if(etInterface->status == SAT_UNSAT){
01382             formulaStatus = BmcPropertyPassed_c;
01383             if (options->verbosityLevel >= BmcVerbosityMax_c) {
01384               (void) fprintf(vis_stdout, "# BMC: by early termination\n");
01385             }
01386             break;
01387           }
01388         } /* Early termination */
01389         /*
01390           Check for \beta''(k)
01391         */
01392         if(checkLevel == 0){
01393           if (options->verbosityLevel == BmcVerbosityMax_c) {
01394             (void) fprintf(vis_stdout, "# BMC: Check Beta''\n");
01395           }
01396           
01397           bAig_ExpandTimeFrame(network, manager, k+2, BMC_NO_INITIAL_STATES);
01398           simplePath = BmcCirCUsSimlePathConstraint(network, 0, k+1, nodeToMvfAigTable,
01399                                                  coiIndexTable, BMC_NO_INITIAL_STATES);
01400           property = bAig_One;
01401           for(i=1; i<=k+1; i++){
01402             property = bAig_And(manager, property,
01403                                 bAig_Not(BmcCirCUsCreatebAigOfPropFormula(
01404                                   network, manager, i,
01405                                   propFormula, BMC_NO_INITIAL_STATES)));
01406           }
01407           property = bAig_And(manager, property,
01408                               BmcCirCUsCreatebAigOfPropFormula(
01409                                 network, manager, 0,
01410                                 propFormula, BMC_NO_INITIAL_STATES));
01411           options->cnfPrefix = k+1;
01412           tInterface = 0;
01413           tInterface = BmcCirCUsInterface(manager, network,
01414                                           bAig_And(manager, property, simplePath),
01415                                           previousResultArray, options, tInterface);
01416           if(tInterface->status == SAT_UNSAT){
01417             m = k;
01418             if (options->verbosityLevel >= BmcVerbosityMax_c) {
01419               (void)fprintf(vis_stderr,"m = %d\n", m);
01420             }
01421             checkLevel = 1;
01422           }
01423         } /* Check for Beta'' */
01424         /*
01425           Check for \beta'(k)
01426         */
01427         if(checkLevel == 0){
01428           if (options->verbosityLevel == BmcVerbosityMax_c) {
01429             (void) fprintf(vis_stdout, "# BMC: Check Beta'\n");
01430           }
01431           bAig_ExpandTimeFrame(network, manager, k+2, BMC_NO_INITIAL_STATES);
01432           simplePath = BmcCirCUsSimlePathConstraint(network, 0, k+1, nodeToMvfAigTable,
01433                                                  coiIndexTable, BMC_NO_INITIAL_STATES);
01434           property = bAig_One;
01435           for(i=0; i<=k; i++){
01436             property = bAig_And(manager, property,
01437                                 bAig_Not(BmcCirCUsCreatebAigOfPropFormula(
01438                                   network, manager, i,
01439                                   propFormula, BMC_NO_INITIAL_STATES)));
01440           }
01441           property = bAig_And(manager, property,
01442                               BmcCirCUsCreatebAigOfPropFormula(
01443                                 network, manager, k+1,
01444                                 propFormula, BMC_NO_INITIAL_STATES));
01445           options->cnfPrefix = k+1;
01446           tInterface = 0;
01447           tInterface = BmcCirCUsInterface(manager, network,
01448                                           bAig_And(manager, property, simplePath),
01449                                           previousResultArray, options, tInterface);
01450           if(tInterface->status == SAT_UNSAT){
01451             m = k;
01452             if (options->verbosityLevel >= BmcVerbosityMax_c) {
01453               (void)fprintf(vis_stderr,"m = %d\n", m);
01454             }
01455             checkLevel = 1;
01456           } 
01457         } /* Check for Beta' */
01458         /*
01459           Check for Beta
01460         */
01461         if(checkLevel == 1){
01462           if (options->verbosityLevel == BmcVerbosityMax_c) {
01463             (void) fprintf(vis_stdout, "# BMC: Check Beta\n");
01464           }
01465           bAig_ExpandTimeFrame(network, manager, k+2, BMC_NO_INITIAL_STATES);
01466           simplePath = BmcCirCUsSimlePathConstraint(network, 0, k+1, nodeToMvfAigTable,
01467                                                  coiIndexTable, BMC_NO_INITIAL_STATES);
01468           property = bAig_And(manager,
01469                               bAig_Not(BmcCirCUsCreatebAigOfPropFormula(
01470                                 network, manager, k,
01471                                 propFormula, BMC_NO_INITIAL_STATES)),
01472                               BmcCirCUsCreatebAigOfPropFormula(
01473                                 network, manager, k+1,
01474                                 propFormula, BMC_NO_INITIAL_STATES));
01475           options->cnfPrefix = k+1;
01476           tInterface = BmcCirCUsInterface(manager, network,
01477                                           bAig_And(manager, property, simplePath),
01478                                           previousResultArray, options, tInterface);
01479           if(tInterface->status == SAT_UNSAT){
01480             checkLevel = 2;
01481           }
01482         } /* Check Beta*/
01483   
01484         if(checkLevel == 2){ /* we check Alpha if Beta is unsatisfiable */
01485           if (options->verbosityLevel == BmcVerbosityMax_c) {
01486             (void) fprintf(vis_stdout, "# BMC: Check Alpha \n");
01487           }
01488           bAig_ExpandTimeFrame(network, manager, k+1, BMC_INITIAL_STATES);
01489           simplePath = BmcCirCUsSimlePathConstraint(network, 0, k, nodeToMvfAigTable,
01490                                                   coiIndexTable, BMC_INITIAL_STATES);
01491           property = BmcCirCUsCreatebAigOfPropFormula(
01492                                   network, manager, k,
01493                                   propFormula, BMC_INITIAL_STATES);
01494           options->cnfPrefix = k;
01495           tInterface = 0;
01496           tInterface = BmcCirCUsInterface(manager, network,
01497                                           bAig_And(manager, property, simplePath),
01498                                           previousResultArray, options, tInterface);
01499           if(tInterface->status == SAT_UNSAT){
01500             n = k;
01501             checkLevel = 3;
01502             if (options->verbosityLevel == BmcVerbosityMax_c) {
01503               (void)fprintf(vis_stdout,"Value of m=%d  n=%d\n", m, n);
01504             }
01505             if (m+n-1 <= maxK){
01506               maxK = m+n-1;
01507               checkLevel = 3;
01508             } else {
01509               checkLevel = 4;
01510             }
01511           }
01512         }/* Chek for Alpha */
01513         
01514         if (options->verbosityLevel != BmcVerbosityNone_c) {
01515           endTime = util_cpu_ctime();
01516           fprintf(vis_stdout, "-- Check for termination time = %10g\n",
01517                   (double)(endTime - startTime) / 1000.0);
01518         }
01519   
01520       } /* Check for termination */
01521     k += options->step;
01522   } /* while result and k*/
01523  
01524   if(formulaStatus == BmcPropertyFailed_c) {
01525     (void) fprintf(vis_stdout, "# BMC: formula failed\n");
01526     if(options->verbosityLevel != BmcVerbosityNone_c){
01527       (void) fprintf(vis_stdout,
01528                        "# BMC: Found a counterexample of length = %d \n", k);
01529     }
01530     if(options->dbgLevel == 1){
01531       BmcCirCUsPrintCounterExample(network, nodeToMvfAigTable, coiTable, k, loop_array,
01532                                    options, BMC_INITIAL_STATES);
01533     }
01534     if(options->dbgLevel == 2){
01535       BmcCirCUsPrintCounterExampleAiger(network, nodeToMvfAigTable, coiTable, k, loop_array,
01536                                    options, BMC_INITIAL_STATES);
01537     }
01538 
01539     array_free(loop_array);
01540   }
01541   if(checkLevel == 3){
01542     (void) fprintf(vis_stdout, "# BMC: no counterexample of length <= (m+n-1) %d is found \n", m+n-1);
01543     formulaStatus = BmcPropertyPassed_c;
01544   }
01545   if(formulaStatus == BmcPropertyPassed_c) {
01546     (void) fprintf(vis_stdout, "# BMC: formula Passed\n");
01547     (void) fprintf(vis_stdout, "#      Termination depth = %d\n", k);
01548   } else if(formulaStatus == BmcPropertyUndecided_c) {
01549     (void) fprintf(vis_stdout,"# BMC: formula undecided\n");
01550     if (options->verbosityLevel != BmcVerbosityNone_c){
01551       (void) fprintf(vis_stdout,
01552                      "# BMC: no counterexample found of length up to %d\n",
01553                      maxK);
01554     }
01555   }
01556   if (options->verbosityLevel != BmcVerbosityNone_c) {
01557     endTime = util_cpu_ctime();
01558     fprintf(vis_stdout, "-- bmc time = %10g\n",
01559             (double)(endTime - startTime) / 1000.0);
01560   }
01561   
01562   array_free(previousResultArray);
01563   
01564   fflush(vis_stdout);
01565   return;
01566 } /* BmcCirCUsLtlVerifyGFp() */
01567 
01585 void
01586 BmcCirCUsLtlVerifyGeneralLtl(
01587     Ntk_Network_t   *network,
01588     Ctlsp_Formula_t *ltl,
01589     st_table        *coiTable,
01590     array_t         *constraintArray,
01591     BmcOption_t     *options,
01592     int             snf)
01593 {
01594   mAig_Manager_t    *manager = Ntk_NetworkReadMAigManager(network);
01595   st_table          *nodeToMvfAigTable = NIL(st_table);
01596   long              startTime, endTime;
01597   boolean           fairness  = (options->fairFile != NIL(FILE));
01598   int               minK = options->minK;
01599   int               maxK = options->maxK;
01600   boolean           boundedFormula;
01601   array_t           *ltlConstraintArray = NIL(array_t);
01602   array_t           *fairnessArray = NIL(array_t);
01603   int               depth, l, bound, f, satFlag, i;
01604   bAigEdge_t        noLoop, loop, ploop; 
01605   bAigEdge_t        result=bAig_NULL, temp, fair;
01606   array_t           *loop_arr = NIL(array_t);
01607   array_t           *objArray;
01608   array_t           *auxObjArray;
01609   st_table          *coiIndexTable;
01610   Ctlsp_Formula_t   *formula;
01611   satInterface_t    *interface;
01612   array_t           *formulaArray = NIL(array_t);
01613   int               nextAction = 0;
01614   /*
01615     Use when proving termination
01616    */
01617   BmcCheckForTermination_t *terminationStatus = 0;
01618   Bmc_PropertyStatus       formulaStatus;
01619 
01620   nodeToMvfAigTable = 
01621           (st_table *) Ntk_NetworkReadApplInfo(network,
01622                                                MVFAIG_NETWORK_APPL_KEY);
01623   assert(nodeToMvfAigTable != NIL(st_table));
01624 
01625   if(fairness) {
01626     Ctlsp_Formula_t *formula; /* a generic LTL formula */
01627     int              i;       /* iteration variable */
01628 
01629     ltlConstraintArray = array_alloc(Ctlsp_Formula_t *, 0);
01630     
01631     arrayForEachItem(Ctlsp_Formula_t *, constraintArray, i, formula) {
01632       fprintf(vis_stdout, "Formula: ddd");
01633       Ctlsp_FormulaPrint(vis_stdout, formula);
01634       fprintf(vis_stdout, "\n");
01635       BmcGetCoiForLtlFormula(network, formula, coiTable);
01636       formula =  Ctlsp_FormulaCreate(Ctlsp_F_c, formula, NIL(Ctlsp_Formula_t));
01637       array_insert_last(Ctlsp_Formula_t *, ltlConstraintArray, formula);
01638     }
01639   }
01640   /*
01641     For bounded formulae use a tighter upper bound if possible.
01642   */
01643   boundedFormula = Ctlsp_LtlFormulaTestIsBounded(ltl, &depth);
01644   if (boundedFormula && depth < maxK && depth >= minK) {
01645     maxK = depth;
01646   } else {
01647     if(options->inductiveStep !=0){
01648       /*
01649         Use the termination criteria to prove the property passes.    
01650       */
01651       terminationStatus = BmcAutTerminationAlloc(network,
01652                                                  Ctlsp_LtllFormulaNegate(ltl),
01653                                                  constraintArray);
01654       assert(terminationStatus);
01655     }
01656   }
01657   if (options->verbosityLevel != BmcVerbosityNone_c){
01658     (void) fprintf(vis_stdout, "General LTL BMC\n");
01659     if (boundedFormula){
01660       (void) fprintf(vis_stdout, "Bounded formula of depth %d\n", depth);
01661     }
01662     (void) fprintf(vis_stdout, "Apply BMC on counterexample of length >= %d and <= %d (+%d) \n",
01663                   minK, maxK, options->step);
01664   }
01665   bAig_ExpandTimeFrame(network, manager, 1, 1);
01666   coiIndexTable = BmcCirCUsGetCoiIndexTable(network, coiTable);
01667   interface    = 0;
01668   /*
01669     Hold objects 
01670   */
01671   objArray = array_alloc(bAigEdge_t, 1);
01672   /*
01673     Hold auxiliary objects (constraints on the path)
01674   */
01675   auxObjArray = array_alloc(bAigEdge_t, 0);
01676 
01677   formulaStatus = BmcPropertyUndecided_c;
01678   bound = minK;
01679   if(snf){
01680     formulaArray = Ctlsp_LtlTranslateIntoSNF(ltl);
01681   }
01682   startTime = util_cpu_ctime();
01683   while(bound<=maxK) {
01684     if(options->verbosityLevel == BmcVerbosityMax_c){
01685       fprintf(vis_stdout, "\nGenerate counterexample of length %d\n", bound);
01686     }
01687 
01688     loop_arr = 0;
01689     bAig_ExpandTimeFrame(network, manager, bound+1, BMC_INITIAL_STATES);
01690 
01691     if(fairness){
01692       /*
01693         In case of fairness constraints, we only include a loop part of BMC
01694         encoding
01695       */
01696       noLoop = bAig_Zero;
01697     } else {
01698       if(snf){
01699         noLoop = BmcCirCUsGenerateLogicForLtlSNF(network, formulaArray, 0, bound, -1);
01700       } else {
01701         noLoop = BmcCirCUsGenerateLogicForLtl(network, ltl, 0, bound, -1);
01702       }
01703     }
01704     result = noLoop;
01705     if(noLoop != bAig_One) {
01706       loop_arr = array_alloc(bAigEdge_t, 0);
01707       for(l=0; l<=bound; l++) {
01708         if(snf){
01709           loop = BmcCirCUsGenerateLogicForLtlSNF(network, formulaArray, 0,
01710                                                  bound, l);
01711         } else { 
01712           loop = BmcCirCUsGenerateLogicForLtl(network, ltl, 0, bound, l);
01713         }
01714         if(loop == bAig_Zero)   continue;
01715 
01716         if(fairness) {
01717           fairnessArray = array_alloc(bAigEdge_t, 0);
01718           arrayForEachItem(Ctlsp_Formula_t *, ltlConstraintArray, i, formula) {
01719             fair = BmcCirCUsGenerateLogicForLtl(network, formula, l, bound, -1);
01720             array_insert_last(bAigEdge_t, fairnessArray, fair);
01721           }
01722         }
01723 
01724         if(loop != bAig_Zero) {
01725           ploop = BmcCirCUsConnectFromStateToState(network, bound, l, nodeToMvfAigTable, coiIndexTable, 1);
01726           array_insert(bAigEdge_t, loop_arr, l, ploop);
01727           temp = bAig_And(manager, loop, ploop);
01728           if(fairness) {
01729             for(f=0; f < array_n(fairnessArray); f++){
01730               fair = array_fetch(bAigEdge_t, fairnessArray, f);
01731               temp = bAig_And(manager, temp, fair); 
01732             }
01733           }
01734           result = bAig_Or(manager, result, temp);
01735         }
01736         if(fairness){
01737           array_free(fairnessArray);
01738         }
01739       }
01740     }
01741     /*
01742     loop = result;
01743     
01744     if((noLoop == bAig_Zero) && (loop == bAig_Zero)){
01745     */
01746     /*
01747       result = noLoop | loop(0) | loop(1) ... | loop(bound)
01748      */
01749     
01750     if(result == bAig_Zero){
01751       if (options->verbosityLevel != BmcVerbosityNone_c){
01752         fprintf(vis_stdout,"# BMC: the formula is trivially true");
01753         fprintf(vis_stdout," for counterexamples of length %d\n", bound);
01754       }
01755     } else {
01756       array_insert(bAigEdge_t, objArray, 0, result);
01757       options->cnfPrefix = bound;
01758       interface = BmcCirCUsInterfaceWithObjArr(manager, network,
01759                                                objArray, auxObjArray,
01760                                                options, interface);
01761       satFlag = interface->status;
01762       if(satFlag == SAT_SAT) {
01763         formulaStatus = BmcPropertyFailed_c;
01764         break;
01765       }
01766       array_insert_last(bAigEdge_t, auxObjArray, bAig_Not(result));
01767     }
01768     /*
01769       Use the termination check if the the LTL formula is not bounded
01770     */
01771     if(!boundedFormula &&
01772        (formulaStatus == BmcPropertyUndecided_c) &&
01773        (nextAction != 1)){
01774       if((options->inductiveStep !=0) &&
01775          (bound % options->inductiveStep == 0))
01776         {
01777           /*
01778             Check for termination for the current value of k.
01779           */
01780           terminationStatus->k = bound;
01781           BmcCirCUsAutLtlCheckForTermination(network, manager,
01782                                              nodeToMvfAigTable,
01783                                              terminationStatus,
01784                                              coiIndexTable, options);
01785           nextAction = terminationStatus->action;
01786           if(nextAction == 1){
01787             maxK = terminationStatus->k;
01788           } else
01789             if(nextAction == 3){
01790               formulaStatus = BmcPropertyPassed_c;
01791               break;
01792             }
01793         }
01794     } /* terminationStatus */
01795     
01796     if(loop_arr) {
01797       array_free(loop_arr);
01798     }
01799     bound += options->step;
01800   }
01801   array_free(objArray);
01802   array_free(auxObjArray);
01803   st_free_table(coiIndexTable);
01804   sat_FreeInterface(interface);
01805 
01806   if(formulaStatus == BmcPropertyUndecided_c){
01807     if(nextAction == 1){
01808       /*
01809         No counterexample of length up to maxK is found. By termination
01810         criterion, formula passes
01811       */
01812       formulaStatus = BmcPropertyPassed_c;
01813     } else 
01814       if (boundedFormula && depth <= options->maxK){
01815         /*
01816           No counterexample of length up to the bounded depth of the LTL formula is
01817           found. Formula passes
01818         */
01819         formulaStatus = BmcPropertyPassed_c;
01820       }
01821   }
01822   
01823   if(options->satSolverError){
01824     (void) fprintf(vis_stdout,"# BMC: Error in calling SAT solver\n");
01825   } else {
01826     if(formulaStatus == BmcPropertyFailed_c) {
01827       (void) fprintf(vis_stdout, "# BMC: formula failed\n");
01828       if(options->verbosityLevel != BmcVerbosityNone_c){
01829         (void) fprintf(vis_stdout,
01830                        "# BMC: Found a counterexample of length = %d \n", bound);
01831       }
01832       if (options->dbgLevel == 1) {
01833         BmcCirCUsPrintCounterExample(network, nodeToMvfAigTable, coiTable, bound, loop_arr,
01834                                      options, BMC_INITIAL_STATES);
01835       }
01836       if (options->dbgLevel == 2) {
01837         BmcCirCUsPrintCounterExampleAiger(network, nodeToMvfAigTable, coiTable, bound, loop_arr,
01838                                      options, BMC_INITIAL_STATES);
01839       }
01840     } else if(formulaStatus == BmcPropertyPassed_c) {
01841       (void) fprintf(vis_stdout, "# BMC: formula Passed\n");
01842       (void) fprintf(vis_stdout, "#      Termination depth = %d\n", maxK);
01843     } else if(formulaStatus == BmcPropertyUndecided_c) {
01844       (void) fprintf(vis_stdout,"# BMC: formula undecided\n");
01845       if (options->verbosityLevel != BmcVerbosityNone_c){
01846         (void) fprintf(vis_stdout,
01847                        "# BMC: no counterexample found of length up to %d\n",
01848                        maxK);
01849       }
01850     }
01851   }
01852  
01853   /*
01854     free all used memories
01855   */
01856   if(terminationStatus){
01857     BmcAutTerminationFree(terminationStatus);
01858   }
01859   if(fairness){
01860     array_free(ltlConstraintArray);
01861   }
01862   if(snf){
01863     Ctlsp_FormulaArrayFree(formulaArray);
01864   }
01865   if (options->verbosityLevel != BmcVerbosityNone_c) {
01866     endTime = util_cpu_ctime();
01867     fprintf(vis_stdout, "-- bmc time = %10g\n", (double)(endTime - startTime) / 1000.0);
01868   }
01869 
01870   fflush(vis_stdout);
01871 }
01872 
01885 void
01886 BmcCirCUsLtlVerifyGeneralLtlFixPoint(
01887     Ntk_Network_t   *network,
01888     Ctlsp_Formula_t *ltl,
01889     st_table        *coiTable,
01890     array_t         *constraintArray,
01891     BmcOption_t     *options)
01892 {
01893   mAig_Manager_t    *manager = Ntk_NetworkReadMAigManager(network);
01894   st_table          *nodeToMvfAigTable = NIL(st_table);
01895   long              startTime, endTime;
01896   bAigEdge_t        property, fair;
01897   boolean           fairness  = (options->fairFile != NIL(FILE));
01898   int               minK = options->minK;
01899   int               maxK = options->maxK;
01900   boolean           boundedFormula;
01901   array_t           *ltlConstraintArray = NIL(array_t);
01902   array_t           *objArray;
01903   array_t           *auxObjArray;
01904   st_table          *coiIndexTable;
01905   Ctlsp_Formula_t   *formula;
01906   satInterface_t    *interface;
01907   int               nextAction = 0;
01908   
01909   BmcCheckForTermination_t *terminationStatus = 0;
01910   Bmc_PropertyStatus       formulaStatus;
01911  
01912   array_t    *loopArray = NIL(array_t), *smallerExists;
01913   bAigEdge_t tmp, loop, atMostOnce, loopConstraints;
01914   int        i, k, depth, satFlag;
01915   
01916   startTime = util_cpu_ctime();
01917 
01918   nodeToMvfAigTable = 
01919           (st_table *) Ntk_NetworkReadApplInfo(network,
01920                                                MVFAIG_NETWORK_APPL_KEY);
01921   assert(nodeToMvfAigTable != NIL(st_table));
01922 
01923   if(fairness) {    
01924     ltlConstraintArray = array_alloc(Ctlsp_Formula_t *, 0);
01925 
01926     arrayForEachItem(Ctlsp_Formula_t *, constraintArray, i, formula) {
01927       BmcGetCoiForLtlFormula(network, formula, coiTable);
01928       formula =  Ctlsp_FormulaCreate(Ctlsp_F_c, formula, NIL(Ctlsp_Formula_t));
01929       array_insert(Ctlsp_Formula_t *, ltlConstraintArray, i, formula);
01930     }
01931   }
01932 
01933   /*
01934     For bounded formulae use a tighter upper bound if possible.
01935   */
01936   boundedFormula = Ctlsp_LtlFormulaTestIsBounded(ltl, &depth);
01937   if (boundedFormula && depth < maxK && depth >= minK) {
01938     maxK = depth;
01939   } else {
01940     if(options->inductiveStep !=0){
01941       /*
01942         Use the termination criteria to prove the property passes.    
01943       */
01944       terminationStatus = BmcAutTerminationAlloc(network,
01945                                                  Ctlsp_LtllFormulaNegate(ltl),
01946                                                  constraintArray);
01947       assert(terminationStatus);
01948     }
01949   }
01950   
01951   if (options->verbosityLevel != BmcVerbosityNone_c){
01952     (void) fprintf(vis_stdout, "General LTL BMC\n");
01953     (void) fprintf(vis_stdout, "Apply BMC on counterexample of length >= %d and <= %d (+%d) \n",
01954                   minK, maxK, options->step);
01955   }
01956 
01957   bAig_ExpandTimeFrame(network, manager, 1, BMC_INITIAL_STATES);
01958   /*
01959     We need the above line inorder to run the next one.
01960    */
01961   coiIndexTable = BmcCirCUsGetCoiIndexTable(network, coiTable);
01962   interface = 0;
01963 
01964   /*
01965     Hold objects 
01966   */
01967   objArray = array_alloc(bAigEdge_t, 3);
01968   /*
01969     Hold auxiliary objects (constraints on the path)
01970   */
01971   auxObjArray = array_alloc(bAigEdge_t, 0);
01972 
01973   formulaStatus = BmcPropertyUndecided_c;
01974   k = minK;
01975   while(k<=maxK) {
01976     if(options->verbosityLevel == BmcVerbosityMax_c){
01977       fprintf(vis_stdout, "\nGenerate counterexample of length %d\n", k);
01978     }
01979     bAig_ExpandTimeFrame(network, manager, k+1, BMC_INITIAL_STATES);
01980 
01981     loopArray = array_alloc(bAigEdge_t, k+1);
01982     array_insert(bAigEdge_t, loopArray, 0, bAig_Zero);
01983     smallerExists   = array_alloc(bAigEdge_t, k+1);
01984     array_insert(bAigEdge_t, smallerExists, 0, bAig_Zero);
01985 
01986     loop = bAig_One;
01987     for(i=1; i<= k; i++){
01988       tmp = bAig_CreateNode(manager, bAig_NULL, bAig_NULL);
01989       array_insert(bAigEdge_t, loopArray, i, tmp);
01990       tmp = bAig_Then(manager, tmp,
01991                       BmcCirCUsConnectFromStateToState(network, k-1, i-1, nodeToMvfAigTable,
01992                                                        coiIndexTable, BMC_INITIAL_STATES));
01993       loop = bAig_And(manager, loop, tmp); 
01994     }
01995     array_insert(bAigEdge_t, smallerExists, 1, bAig_Zero);
01996     for(i=1; i<= k; i++){
01997       bAigEdge_t left, right;
01998 
01999       left = array_fetch(bAigEdge_t, smallerExists, i);
02000       right = array_fetch(bAigEdge_t, loopArray, i);
02001       
02002       array_insert(bAigEdge_t, smallerExists, i+1,
02003                    bAig_Or(manager, left, right));
02004     }
02005     atMostOnce =  bAig_One;
02006     for(i=1; i<= k; i++){
02007       bAigEdge_t left, right;
02008 
02009       left = array_fetch(bAigEdge_t, smallerExists, i);
02010       right = array_fetch(bAigEdge_t, loopArray, i);
02011       
02012       tmp = bAig_Then(manager, left, bAig_Not(right));
02013       atMostOnce = bAig_And(manager, atMostOnce, tmp);
02014     }
02015 
02016     loopConstraints = bAig_And(manager, loop, atMostOnce);
02017 
02018     property = BmcCirCUsGenerateLogicForLtlFixPoint(network, ltl, 0, k, loopArray);
02019 
02020     if(fairness) {
02021       fair = bAig_One;
02022       arrayForEachItem(Ctlsp_Formula_t *, ltlConstraintArray, i, formula) {
02023         fair = bAig_And(manager, fair,
02024                         BmcCirCUsGenerateLogicForLtlFixPoint(network, formula,
02025                                                              0, k, loopArray));
02026       }
02027       array_insert(bAigEdge_t, objArray, 2, fair);
02028     } else {
02029       array_insert(bAigEdge_t, objArray, 2,  bAig_One);
02030     }
02031 
02032     array_insert(bAigEdge_t, objArray, 0, loopConstraints);
02033     array_insert(bAigEdge_t, objArray, 1, property);
02034     options->cnfPrefix = k;
02035     interface = BmcCirCUsInterfaceWithObjArr(manager, network,
02036                                              objArray, objArray,
02037                                              options, interface);
02038     array_free(smallerExists);
02039     
02040     satFlag = interface->status;
02041     if(satFlag == SAT_SAT) {
02042       formulaStatus = BmcPropertyFailed_c;
02043       break;
02044     }
02045     array_free(loopArray);
02046     /*
02047       Use the termination check if the the LTL formula is not bounded
02048     */
02049     if(!boundedFormula &&
02050        (formulaStatus == BmcPropertyUndecided_c) &&
02051        (nextAction != 1)){
02052       if((options->inductiveStep !=0) &&
02053          (k % options->inductiveStep == 0))
02054         {
02055           /*
02056             Check for termination for the current value of k.
02057           */
02058           terminationStatus->k = k;
02059           BmcCirCUsAutLtlCheckForTermination(network, manager,
02060                                              nodeToMvfAigTable,
02061                                              terminationStatus,
02062                                              coiIndexTable, options);
02063           nextAction = terminationStatus->action;
02064           if(nextAction == 1){
02065             maxK = terminationStatus->k;
02066           } else 
02067             if(nextAction == 3){
02068               formulaStatus = BmcPropertyPassed_c;
02069               maxK = k;
02070               break;
02071             }
02072 
02073         }
02074     } /* terminationStatus */
02075       
02076     k += options->step;
02077   }
02078   array_free(objArray);
02079   array_free(auxObjArray);
02080   st_free_table(coiIndexTable);
02081   sat_FreeInterface(interface);
02082 
02083   if(formulaStatus == BmcPropertyUndecided_c){
02084     /*
02085       If no counterexample of length up to a certain bound, then the property
02086       passes.
02087     */
02088     if(nextAction == 1){
02089       formulaStatus = BmcPropertyPassed_c;
02090     } else 
02091       if (boundedFormula && depth <= options->maxK){
02092         formulaStatus = BmcPropertyPassed_c;
02093       }
02094   }
02095   if(options->satSolverError){
02096     (void) fprintf(vis_stdout,"# BMC: Error in calling SAT solver\n");
02097   } else {
02098     if(formulaStatus == BmcPropertyFailed_c) {
02099       (void) fprintf(vis_stdout, "# BMC: formula failed\n");
02100       if(options->verbosityLevel != BmcVerbosityNone_c){
02101         (void) fprintf(vis_stdout,
02102                        "# BMC: Found a counterexample of length = %d \n", k);
02103       }
02104       if (options->dbgLevel == 1) {
02105         int loop = k;
02106         /*
02107           Adjust loopArray to print a proper counterexample.  The encoding
02108           scheme does not differentiate between loop and no-loop path.  If the
02109           path has a loop, then the path length is k-1.
02110         */
02111         for(i=1; i< k; i++){
02112           bAigEdge_t   v      = array_fetch(bAigEdge_t, loopArray, i+1);
02113           unsigned int lvalue = aig_value(v); 
02114           
02115           if(lvalue == 1) {
02116             loop = k-1;
02117           }
02118           array_insert(bAigEdge_t, loopArray, i, v);
02119         }
02120         if (options->dbgLevel == 1) {
02121           BmcCirCUsPrintCounterExample(network, nodeToMvfAigTable,
02122                                      coiTable, loop, loopArray,
02123                                      options, BMC_INITIAL_STATES);
02124         }
02125         if (options->dbgLevel == 1) {
02126           BmcCirCUsPrintCounterExampleAiger(network, nodeToMvfAigTable,
02127                                      coiTable, loop, loopArray,
02128                                      options, BMC_INITIAL_STATES);
02129         }
02130         array_free(loopArray);
02131       }
02132     } else if(formulaStatus == BmcPropertyPassed_c) {
02133       (void) fprintf(vis_stdout, "# BMC: formula Passed\n");
02134       (void) fprintf(vis_stdout, "#      Termination depth = %d\n", maxK);
02135     } else if(formulaStatus == BmcPropertyUndecided_c) {
02136       (void) fprintf(vis_stdout,"# BMC: formula undecided\n");
02137       if (options->verbosityLevel != BmcVerbosityNone_c){
02138         (void) fprintf(vis_stdout,
02139                        "# BMC: no counterexample found of length up to %d\n",
02140                        maxK);
02141       }
02142     }
02143   }
02144   
02145   /*
02146     free all used memories
02147   */
02148   if(terminationStatus){
02149     BmcAutTerminationFree(terminationStatus);
02150   }
02151   if(fairness){
02152      array_free(ltlConstraintArray);
02153   }
02154  
02155   if (options->verbosityLevel != BmcVerbosityNone_c) {
02156     endTime = util_cpu_ctime();
02157     fprintf(vis_stdout, "-- bmc time = %10g\n", (double)(endTime - startTime) / 1000.0);
02158   }
02159 
02160   fflush(vis_stdout);
02161 }
02162 
02163 
02176 void
02177 BmcCirCUsLtlCheckSafety(
02178     Ntk_Network_t   *network,
02179     Ctlsp_Formula_t *ltl,
02180     BmcOption_t     *options,
02181     st_table        *coiTable)
02182 {
02183   mAig_Manager_t    *manager = Ntk_NetworkReadMAigManager(network);
02184   st_table          *nodeToMvfAigTable = NIL(st_table);
02185   long              startTime, endTime;
02186   bAigEdge_t        noLoop;
02187   int               depth, satFlag, bound;
02188   int               minK = options->minK;
02189   int               maxK = options->maxK;
02190   int               boundedFormula;
02191   array_t           *previousResultArray;
02192   satInterface_t    *interface;
02193   array_t           *objArray;
02194   BmcCheckForTermination_t *terminationStatus = 0;
02195   Bmc_PropertyStatus       formulaStatus;
02196   st_table          *coiIndexTable;
02197 
02198   assert(Ctlsp_LtlFormulaTestIsSyntacticallyCoSafe(ltl));
02199   
02200   startTime = util_cpu_ctime();
02201 
02202   nodeToMvfAigTable = 
02203     (st_table *) Ntk_NetworkReadApplInfo(network,
02204                                          MVFAIG_NETWORK_APPL_KEY);
02205   assert(nodeToMvfAigTable != NIL(st_table));
02206   
02207   /*
02208     For bounded formulae use a tighter upper bound if possible.
02209   */
02210   boundedFormula = Ctlsp_LtlFormulaTestIsBounded(ltl, &depth);
02211   if (boundedFormula && depth < maxK && depth >= minK) {
02212     maxK = depth;
02213   } else {
02214     if(options->inductiveStep !=0){
02215       /*
02216         Use the termination criteria to prove the property passes.    
02217       */
02218       terminationStatus = BmcAutTerminationAlloc(network,
02219                                                  Ctlsp_LtllFormulaNegate(ltl),
02220                                                  NIL(array_t));
02221       assert(Ltl_AutomatonGetStrength(terminationStatus->automaton) == 0); /* Terminal Automaton*/
02222       assert(terminationStatus);
02223     }
02224   }
02225   if (options->verbosityLevel != BmcVerbosityNone_c){
02226     (void) fprintf(vis_stdout, "saftey LTL BMC\n");
02227     if (boundedFormula){
02228       (void) fprintf(vis_stdout, "Bounded formula of depth %d\n", depth);
02229     }
02230     (void) fprintf(vis_stdout, "Apply BMC on counterexample of length >= %d and <= %d (+%d) \n",
02231                   minK, maxK, options->step);
02232   }
02233   satFlag   = SAT_UNSAT;
02234   bAig_ExpandTimeFrame(network, manager, 0, BMC_INITIAL_STATES);
02235   coiIndexTable = BmcCirCUsGetCoiIndexTable(network, coiTable);
02236   interface = 0;
02237   formulaStatus = BmcPropertyUndecided_c;
02238   /*
02239     Hold objects 
02240   */
02241   objArray = array_alloc(bAigEdge_t, 1);
02242 
02243   previousResultArray = array_alloc(bAigEdge_t, 0);
02244   bound=minK;
02245   while(bound<=maxK) {
02246     
02247     if(options->verbosityLevel == BmcVerbosityMax_c)
02248       fprintf(vis_stdout, "\nGenerate counterexample of length %d\n", bound);
02249     fflush(vis_stdout);
02250 
02251     bAig_ExpandTimeFrame(network, manager, bound+1, BMC_INITIAL_STATES);
02252 
02253     /*
02254       A counterexample to a safety property is finite path at which the
02255       safety property does not hold.
02256      */
02257     noLoop = BmcCirCUsGenerateLogicForLtl(network, ltl, 0, bound, -1);
02258     array_insert(bAigEdge_t, objArray, 0, noLoop);
02259     
02260     options->cnfPrefix = bound;
02261     interface = BmcCirCUsInterfaceWithObjArr(manager, network,
02262                                              objArray,
02263                                              previousResultArray,
02264                                              options,
02265                                              interface);
02266     satFlag = interface->status;
02267     if(satFlag == SAT_SAT) {
02268       formulaStatus = BmcPropertyFailed_c;
02269       break;
02270     }
02271     array_insert_last(bAigEdge_t, previousResultArray, bAig_Not(noLoop));
02272 
02273     /*
02274       Use the termination check if the the LTL formula is not bounded
02275     */
02276     if(!boundedFormula &&
02277        (options->inductiveStep !=0) &&
02278        (bound % options->inductiveStep == 0))
02279       {
02280         terminationStatus->k = bound;
02281         BmcCirCUsAutLtlCheckTerminalAutomaton(network, manager,
02282                                               nodeToMvfAigTable,
02283                                               terminationStatus,
02284                                               coiIndexTable, options);
02285         if(terminationStatus->action == 1){
02286           formulaStatus = BmcPropertyPassed_c;
02287           maxK = bound;
02288           break;
02289         }
02290       }
02291     bound += options->step;
02292   }
02293   array_free(objArray);
02294   array_free(previousResultArray);
02295   sat_FreeInterface(interface);
02296 
02297   if ((formulaStatus != BmcPropertyFailed_c) && boundedFormula && depth <= options->maxK){
02298     /*
02299       No counterexample of length up to the bounded depth of the LTL formula is
02300       found. Formula passes
02301     */
02302     formulaStatus = BmcPropertyPassed_c;
02303   }
02304   
02305   if(options->satSolverError){
02306     (void) fprintf(vis_stdout,"# BMC: Error in calling SAT solver\n");
02307   } else {
02308     if(formulaStatus == BmcPropertyFailed_c) {
02309       (void) fprintf(vis_stdout, "# BMC: formula failed\n");
02310       if(options->verbosityLevel != BmcVerbosityNone_c){
02311         (void) fprintf(vis_stdout,
02312                        "# BMC: Found a counterexample of length = %d \n", bound);
02313       }
02314       if (options->dbgLevel == 1) {
02315         BmcCirCUsPrintCounterExample(network, nodeToMvfAigTable, coiTable, bound, NIL(array_t),
02316                                      options, BMC_INITIAL_STATES);
02317       }
02318       if (options->dbgLevel == 2) {
02319         BmcCirCUsPrintCounterExampleAiger(network, nodeToMvfAigTable, coiTable, bound, NIL(array_t),
02320                                      options, BMC_INITIAL_STATES);
02321       }
02322     } else if(formulaStatus == BmcPropertyPassed_c) {
02323       (void) fprintf(vis_stdout, "# BMC: formula Passed\n");
02324       (void) fprintf(vis_stdout, "#      Termination depth = %d\n", maxK);
02325     } else if(formulaStatus == BmcPropertyUndecided_c) {
02326       (void) fprintf(vis_stdout,"# BMC: formula undecided\n");
02327       if (options->verbosityLevel != BmcVerbosityNone_c){
02328         (void) fprintf(vis_stdout,
02329                        "# BMC: no counterexample found of length up to %d \n",
02330                        maxK);
02331       }
02332     }
02333   }
02334 
02335   if (options->verbosityLevel != BmcVerbosityNone_c) {
02336     endTime = util_cpu_ctime();
02337     fprintf(vis_stdout, "-- bmc time = %10g\n", (double)(endTime - startTime) / 1000.0);
02338   }
02339   fflush(vis_stdout);  
02340   return;
02341 
02342 }
02343 
02344 
02357 bAigEdge_t
02358 BmcCirCUsConnectFromStateToState(
02359     Ntk_Network_t   *network,
02360     int from,
02361     int to,
02362     st_table *nodeToMvfAigTable,
02363     st_table *coiIndexTable,
02364     int withInitialState)
02365 {
02366   bAigEdge_t *fli, *tli;
02367   bAigEdge_t loop, tv;
02368   int l, index, nLatches;
02369   bAigTimeFrame_t *timeframe;
02370   mAig_Manager_t    *manager = Ntk_NetworkReadMAigManager(network);
02371 
02372   if(withInitialState)  timeframe = manager->timeframe;
02373   else                  timeframe = manager->timeframeWOI;
02374 
02375   fli = timeframe->latchInputs[from+1];
02376   tli = timeframe->latchInputs[to]; 
02377   loop = bAig_One;
02378   nLatches = timeframe->nLatches;
02379   for(l=0; l<nLatches; l++) {
02380     if(!st_lookup_int(coiIndexTable, (char *)(long)l, &index))  continue;
02381     tv = bAig_Eq(manager, fli[l], tli[l]);
02382     loop = bAig_And(manager, tv, loop);
02383     if(loop == bAig_Zero)       break;
02384   }
02385   return(loop);
02386 }
02387 
02388 
02404 bAigEdge_t
02405 BmcCirCUsSimlePathConstraint(
02406   Ntk_Network_t *network,
02407   int           fromState,
02408   int           toState,
02409   st_table      *nodeToMvfAigTable,
02410   st_table      *coiIndexTable,
02411   int withInitialState)
02412 {
02413   int             i, j; 
02414   bAigEdge_t      loop, nLoop;
02415   mAig_Manager_t  *manager = Ntk_NetworkReadMAigManager(network);
02416 
02417   nLoop = bAig_One;
02418   for(i=fromState+1; i<=toState; i++) {
02419     for(j=fromState; j<i; j++) {
02420       /*
02421         We want state Si == Sj, but the following function returns
02422         S(i+1) == Sj.  So we call the function with i-1.
02423       */
02424       loop = BmcCirCUsConnectFromStateToState(
02425              network, i-1, j, nodeToMvfAigTable, coiIndexTable, withInitialState);
02426       nLoop = bAig_And(manager, nLoop, bAig_Not(loop));
02427     }
02428   }
02429   return(nLoop);
02430 } /* BmcCirCUsSimplePathConstraint */
02431 
02432 
02445 bAigEdge_t
02446 BmcCirCUsGenerateSimplePath(
02447         Ntk_Network_t   *network,
02448         int from,
02449         int to,
02450         st_table *nodeToMvfAigTable,
02451         st_table *coiIndexTable,
02452         int withInitialState)
02453 {
02454 int i, j; 
02455 bAigEdge_t loop, nloop;
02456 mAig_Manager_t    *manager;
02457     
02458   manager = Ntk_NetworkReadMAigManager(network);
02459 
02460   bAig_ExpandTimeFrame(network, manager, to, withInitialState);
02461 
02462   nloop = bAig_One;
02463   for(i=from+1; i<=to; i++) {
02464     for(j=from; j<i; j++) {
02465       loop = BmcCirCUsConnectFromStateToState(
02466              network, i-1, j, nodeToMvfAigTable, coiIndexTable, withInitialState);
02467       nloop = bAig_And(manager, nloop, bAig_Not(loop));
02468     }
02469   }
02470   return(nloop);
02471 }
02472 
02473 
02486 void
02487 BmcCirCUsPrintCounterExample(
02488   Ntk_Network_t   *network,
02489   st_table        *nodeToMvfAigTable,
02490   st_table        *coiTable,
02491   int             length,
02492   array_t         *loop_arr,
02493   BmcOption_t     *options,
02494   int withInitialState)
02495 {
02496   int *prevLatchValues, *prevInputValues;
02497   mAig_Manager_t    *manager = Ntk_NetworkReadMAigManager(network);
02498   int loop, k;
02499   unsigned int lvalue;
02500   bAigEdge_t v;
02501   array_t *latchArr;
02502   lsGen gen;
02503   Ntk_Node_t *node;
02504   int tmp;
02505   bAigTimeFrame_t *timeframe;
02506   FILE *dbgOut = NULL;
02507 
02508   latchArr = array_alloc(Ntk_Node_t *, 0);
02509   Ntk_NetworkForEachLatch(network, gen, node){
02510     if (st_lookup_int(coiTable, (char *) node, &tmp)){
02511       array_insert_last(Ntk_Node_t *, latchArr, node);
02512     }
02513   }
02514 
02515   if(options->dbgOut)
02516   {
02517     dbgOut = vis_stdout;
02518     vis_stdout = options->dbgOut;
02519   }
02520 
02523   if(withInitialState)  timeframe = manager->timeframe;
02524   else                  timeframe = manager->timeframeWOI;
02525 
02526   prevLatchValues = ALLOC(int, timeframe->nLatches);
02527   prevInputValues = ALLOC(int, timeframe->nInputs);
02528 
02529   loop = -1;
02530   if(loop_arr != 0) {
02531     for(k=array_n(loop_arr)-1; k>=0; k--) {
02532       v = array_fetch(bAigEdge_t, loop_arr, k);
02533       lvalue = aig_value(v);
02534       if(lvalue == 1) {
02535         loop = k;
02536         break;
02537       }
02538     }
02539   }
02540   for(k=0; k<=length; k++) {
02541     if(k == 0) fprintf(vis_stdout, "\n--State %d:\n", k);
02542     else       fprintf(vis_stdout, "\n--Goes to state %d:\n", k);
02543   
02544     printSatValue(manager, nodeToMvfAigTable, 
02545                     timeframe->li2index, 
02546                     timeframe->latchInputs, latchArr,
02547                     k, prevLatchValues);
02548 
02549     if(options->printInputs == TRUE && k!=0) {
02550       fprintf(vis_stdout, "--On input:\n");
02551       printSatValue(manager, nodeToMvfAigTable, 
02552                     timeframe->pi2index,
02553                     timeframe->inputs, timeframe->inputArr,
02554                     k-1, prevInputValues);
02555     }
02556   }
02557 
02558   if(loop >=0) {
02559     fprintf(vis_stdout, "\n--Goes back to state %d:\n", loop);
02560 
02561     printSatValue(manager, nodeToMvfAigTable, 
02562                     timeframe->li2index,
02563                     timeframe->latchInputs, latchArr,
02564                     loop, prevLatchValues);
02565 
02566     if(options->printInputs == TRUE && k!=0) {
02567       fprintf(vis_stdout, "--On input:\n");
02568       printSatValue(manager, nodeToMvfAigTable, 
02569                     timeframe->pi2index,
02570                     timeframe->inputs, timeframe->inputArr,
02571                     length, prevInputValues);
02572     }
02573   }
02574 
02575   array_free(latchArr);
02576   if(options->dbgOut)
02577   {
02578     vis_stdout = dbgOut;
02579   }
02580   return;
02581 }
02582 
02583 
02584 
02600 void
02601 BmcCirCUsPrintCounterExampleAiger(
02602   Ntk_Network_t   *network,
02603   st_table        *nodeToMvfAigTable,
02604   st_table        *coiTable,
02605   int             length,
02606   array_t         *loop_arr,
02607   BmcOption_t     *options,
02608   int withInitialState)
02609 {
02610   int *prevLatchValues, *prevInputValues;
02611   mAig_Manager_t    *manager = Ntk_NetworkReadMAigManager(network);
02612   int loop, k;
02613   unsigned int lvalue;
02614   bAigEdge_t v;
02615   array_t *latchArr;
02616   lsGen gen;
02617   Ntk_Node_t *node;
02618   int tmp;
02619   bAigTimeFrame_t *timeframe;
02620   FILE *dbgOut = NULL;
02621 
02622   latchArr = array_alloc(Ntk_Node_t *, 0);
02623   Ntk_NetworkForEachLatch(network, gen, node){
02624     if (st_lookup_int(coiTable, (char *) node, &tmp)){
02625       array_insert_last(Ntk_Node_t *, latchArr, node);
02626     }
02627   }
02628 
02629   /* writing into a file is not being done in a standard way, need to confirm
02630      the writing of trace into a file with the vis standard */
02631 
02632   if(options->dbgOut)
02633   {
02634     dbgOut = vis_stdout;
02635     vis_stdout = options->dbgOut;
02636   }
02637 
02640   if(withInitialState)  timeframe = manager->timeframe;
02641   else                  timeframe = manager->timeframeWOI;
02642 
02643   prevLatchValues = ALLOC(int, timeframe->nLatches);
02644   prevInputValues = ALLOC(int, timeframe->nInputs);
02645 
02646   loop = -1;
02647   if(loop_arr != 0) {
02648     for(k=array_n(loop_arr)-1; k>=0; k--) {
02649       v = array_fetch(bAigEdge_t, loop_arr, k);
02650       lvalue = aig_value(v);
02651       if(lvalue == 1) {
02652         loop = k;
02653         break;
02654       }
02655     }
02656   }
02657   
02658   /* we need to get rid of the file generation for next vis release and look
02659      into ntk package so that the original order can be maintained */
02660 
02661   FILE *order = Cmd_FileOpen("inputOrder.txt", "w", NIL(char *), 0) ;
02662   for(k=0; k<array_n(timeframe->inputArr); k++)
02663   {
02664     node = array_fetch(Ntk_Node_t *, timeframe->inputArr, k);
02665     fprintf(order, "%s\n", Ntk_NodeReadName(node));
02666   }
02667   fclose(order);
02668     
02669   for(k=0; k<=length; k++) {
02670     /*if(k == 0) fprintf(vis_stdout, "\n--State %d:\n", k);
02671     else       fprintf(vis_stdout, "\n--Goes to state %d:\n", k);*/
02672 
02673     /*if((loop>=0)||(k<length))
02674     { */
02675       printSatValueAiger(manager, nodeToMvfAigTable, 
02676                     timeframe->li2index, 
02677                     timeframe->latchInputs, latchArr,
02678                     k, prevLatchValues);
02679       fprintf(vis_stdout, " ");
02680 
02681     if((loop<0)||(k<length))
02682     { 
02683       if(k!=length+1) {
02684         printSatValueAiger(manager, nodeToMvfAigTable, 
02685                     timeframe->pi2index,
02686                     timeframe->inputs, timeframe->inputArr,
02687                     k, prevInputValues);
02688         fprintf(vis_stdout, " ");
02689       }
02690 
02691       if(k!=length+1) {
02692         printSatValueAiger(manager, nodeToMvfAigTable, 
02693                     timeframe->o2index,
02694                     timeframe->outputs, timeframe->outputArr,
02695                     k, prevInputValues);
02696         fprintf(vis_stdout, " ");
02697       }
02698 
02699       if(k!=length+1) {
02700         printSatValueAiger(manager, nodeToMvfAigTable,
02701                     timeframe->li2index,
02702                     timeframe->latchInputs, latchArr,
02703                     k+1, prevLatchValues);
02704         fprintf(vis_stdout, " ");
02705       }
02706       if((loop < 0)||(k!=length))
02707       {
02708         fprintf(vis_stdout, "\n");
02709       }
02710     }
02711   }
02712 
02713   if(loop >=0) {
02714     /*fprintf(vis_stdout, "\n--Goes back to state %d:\n", loop);*/
02715 
02716     if(k!=0) {
02717       printSatValueAiger(manager, nodeToMvfAigTable,
02718                     timeframe->pi2index,
02719                     timeframe->inputs, timeframe->inputArr,
02720                     length, prevInputValues);
02721       fprintf(vis_stdout, " ");
02722     }
02723 
02724     printSatValueAiger(manager, nodeToMvfAigTable,
02725                     timeframe->o2index,
02726                     timeframe->outputs, timeframe->outputArr,
02727                     k, prevInputValues);
02728     fprintf(vis_stdout, " ");
02729 
02730     printSatValueAiger(manager, nodeToMvfAigTable, 
02731                     timeframe->li2index,
02732                     timeframe->latchInputs, latchArr,
02733                     loop, prevLatchValues);
02734     
02735     fprintf(vis_stdout, "\n");
02736   }
02737 
02738   array_free(latchArr);
02739   if(options->dbgOut)
02740   {
02741     vis_stdout = dbgOut;
02742   }
02743   return;
02744 } /* BmcCirCUsPrintCounterExampleAiger */
02745 
02759 static int
02760 printSatValue(
02761     bAig_Manager_t *manager,
02762     st_table        *nodeToMvfAigTable,
02763     st_table *li2index,
02764     bAigEdge_t **baigArr,
02765     array_t *nodeArr, 
02766     int bound,
02767     int *prevValue)
02768 {
02769   Ntk_Node_t * node;
02770   int value, lvalue;
02771   char *symbolicValue;
02772   bAigEdge_t *li, v, tv;
02773   int i, j, timeframe, index;
02774   int changed=0;
02775   MvfAig_Function_t  *mvfAig;
02776 
02777   timeframe = bound;
02778   li = baigArr[timeframe];
02779   for(i=0; i<array_n(nodeArr); i++) {
02780     if(timeframe == 0)  prevValue[i] = -1;
02781     node = array_fetch(Ntk_Node_t *, nodeArr, i);
02782     mvfAig = Bmc_ReadMvfAig(node, nodeToMvfAigTable);
02783 
02784     if(mvfAig == 0)     continue;
02785 
02786     value = -1;
02787     for (j=0; j< array_n(mvfAig); j++) {
02788       v = MvfAig_FunctionReadComponent(mvfAig, j);
02789       index = -1;
02790       if(!st_lookup_int(li2index, (char *)v, &index)) {
02791         fprintf(vis_stdout, "printSatValueERROR \n");
02792       }
02793       v = li[index];
02794       if(v == bAig_One) {
02795         value = j;
02796         break;
02797       }
02798 
02799       if(v != bAig_Zero) {
02800         tv = bAig_GetCanonical(manager, v);
02801         lvalue = bAig_GetValueOfNode(manager, tv);
02802         if(lvalue == 1){        
02803           value = j;
02804           break;
02805         }
02806       }
02807     }
02808     if(value >=0) {
02809       if (value != prevValue[i]){
02810         Var_Variable_t *nodeVar = Ntk_NodeReadVariable(node);
02811         prevValue[i] = value;
02812         changed = 1;
02813         if (Var_VariableTestIsSymbolic(nodeVar)) {
02814           symbolicValue = Var_VariableReadSymbolicValueFromIndex(nodeVar, value);
02815           fprintf(vis_stdout,"%s:%s\n",  Ntk_NodeReadName(node), symbolicValue);
02816         } 
02817         else {
02818           fprintf(vis_stdout,"%s:%d\n",  Ntk_NodeReadName(node), value);
02819         }
02820       }
02821     }
02822   } /* for j loop */
02823   if (changed == 0){
02824     fprintf(vis_stdout, "<Unchanged>\n");
02825   }
02826   return 0;
02827 }
02828 
02841 static int
02842 printSatValueAiger(
02843     bAig_Manager_t *manager,
02844     st_table        *nodeToMvfAigTable,
02845     st_table *li2index,
02846     bAigEdge_t **baigArr,
02847     array_t *nodeArr, 
02848     int bound,
02849     int *prevValue)
02850 {
02851   Ntk_Node_t * node;
02852   int value, lvalue;
02853   char *symbolicValue;
02854   bAigEdge_t *li, v, tv;
02855   int i, j, timeframe, index;
02856   MvfAig_Function_t  *mvfAig;
02857 
02858   timeframe = bound;
02859   li = baigArr[timeframe];
02860   for(i=0; i<array_n(nodeArr); i++) {
02861     if(timeframe == 0)  prevValue[i] = -1;
02862     node = array_fetch(Ntk_Node_t *, nodeArr, i);
02863     mvfAig = Bmc_ReadMvfAig(node, nodeToMvfAigTable);
02864 
02865     if(mvfAig == 0)     continue;
02866 
02867     value = -1;
02868     for (j=0; j< array_n(mvfAig); j++) {
02869       v = MvfAig_FunctionReadComponent(mvfAig, j);
02870       index = -1;
02871       if(!st_lookup_int(li2index, (char *)v, &index)) {
02872         fprintf(vis_stdout, "printSatValueERROR \n");
02873       }
02874       v = li[index];
02875       if(v == bAig_One) {
02876         value = j;
02877         break;
02878       }
02879 
02880       if(v != bAig_Zero) {
02881         tv = bAig_GetCanonical(manager, v);
02882         lvalue = bAig_GetValueOfNode(manager, tv);
02883         if(lvalue == 1){        
02884           value = j;
02885           break;
02886         }
02887       }
02888     }
02889     if(value >=0) {
02890       Var_Variable_t *nodeVar = Ntk_NodeReadVariable(node);
02891       prevValue[i] = value;
02892       if (Var_VariableTestIsSymbolic(nodeVar)) {
02893         symbolicValue = Var_VariableReadSymbolicValueFromIndex(nodeVar, value);
02894         fprintf(vis_stdout,"%s", symbolicValue);
02895       } 
02896       else {
02897         fprintf(vis_stdout,"%d", value);
02898       }
02899     }
02900     else
02901     {
02902       fprintf(vis_stdout,"x");
02903     }
02904   } /* for j loop */
02905   return 0;
02906 } /* printSatValueAiger */
02907 
02922 bAigEdge_t 
02923 BmcCirCUsCreatebAigOfPropFormula(
02924     Ntk_Network_t *network,
02925     bAig_Manager_t *manager,
02926     int bound,
02927     Ctlsp_Formula_t *ltl,
02928     int withInitialState)
02929 {
02930   int index;
02931   bAigEdge_t result, left, right, *li;
02932   bAigTimeFrame_t *timeframe;
02933 
02934   if (ltl == NIL(Ctlsp_Formula_t))      return mAig_NULL; 
02935   if (ltl->type == Ctlsp_TRUE_c)        return mAig_One; 
02936   if (ltl->type == Ctlsp_FALSE_c)       return mAig_Zero; 
02937 
02938   assert(Ctlsp_isPropositionalFormula(ltl));
02939   
02940   if(withInitialState) timeframe = manager->timeframe;
02941   else                 timeframe = manager->timeframeWOI;
02942 
02943   if (ltl->type == Ctlsp_ID_c){
02944       char *nodeNameString  = Ctlsp_FormulaReadVariableName(ltl);
02945       char *nodeValueString = Ctlsp_FormulaReadValueName(ltl);
02946       Ntk_Node_t *node      = Ntk_NetworkFindNodeByName(network, nodeNameString);
02947 
02948       Var_Variable_t *nodeVar;
02949       int             nodeValue;
02950 
02951       MvfAig_Function_t  *tmpMvfAig;
02952       st_table           *nodeToMvfAigTable; /* maps each node to its mvfAig */
02953       
02954       if (node == NIL(Ntk_Node_t)) {
02955         char   *nameKey;
02956         char   tmpName[100];
02957         
02958         sprintf(tmpName, "%s_%d", nodeNameString, bound);
02959         nameKey = util_strsav(tmpName);
02960 
02961         result  = bAig_FindNodeByName(manager, nameKey);
02962         if(result == bAig_NULL){
02963            result = bAig_CreateVarNode(manager, nameKey); 
02964         } else {
02965           
02966           FREE(nameKey);
02967         }
02968 
02969         
02970         return result;
02971       }
02972 
02973       nodeToMvfAigTable = (st_table *) Ntk_NetworkReadApplInfo(network, MVFAIG_NETWORK_APPL_KEY);
02974       assert(nodeToMvfAigTable != NIL(st_table));
02975 
02976       tmpMvfAig = Bmc_ReadMvfAig(node, nodeToMvfAigTable);
02977       if (tmpMvfAig ==  NIL(MvfAig_Function_t)){
02978           tmpMvfAig = Bmc_NodeBuildMVF(network, node);
02979           array_free(tmpMvfAig);
02980           tmpMvfAig = Bmc_ReadMvfAig(node, nodeToMvfAigTable);
02981       }
02982       
02983       nodeVar = Ntk_NodeReadVariable(node);
02984       if (Var_VariableTestIsSymbolic(nodeVar)) {
02985         nodeValue = Var_VariableReadIndexFromSymbolicValue(nodeVar, nodeValueString);
02986         if ( nodeValue == -1 ) {
02987           (void) fprintf(vis_stderr, "Value specified in RHS is not in domain of variable\n");
02988           (void) fprintf(vis_stderr,"%s = %s\n", nodeNameString, nodeValueString);
02989           return mAig_NULL;
02990         }
02991       }
02992       else { 
02993         int check;    
02994          check = StringCheckIsInteger(nodeValueString, &nodeValue);
02995          if( check == 0 ) {
02996           (void) fprintf(vis_stderr,"Illegal value in the RHS\n");
02997           (void) fprintf(vis_stderr,"%s = %s\n", nodeNameString, nodeValueString);
02998           return mAig_NULL;
02999          }
03000          if( check == 1 ) {
03001           (void) fprintf(vis_stderr,"Value in the RHS is out of range of int\n");
03002           (void) fprintf(vis_stderr,"%s = %s", nodeNameString, nodeValueString);
03003           return mAig_NULL;
03004          }
03005          if ( !(Var_VariableTestIsValueInRange(nodeVar, nodeValue))) {
03006           (void) fprintf(vis_stderr,"Value specified in RHS is not in domain of variable\n");
03007           (void) fprintf(vis_stderr,"%s = %s\n", nodeNameString, nodeValueString);
03008           return mAig_NULL;
03009 
03010          }
03011       }
03012       result = MvfAig_FunctionReadComponent(tmpMvfAig, nodeValue);
03013       result = bAig_GetCanonical(manager, result);
03014       if(st_lookup_int(timeframe->li2index, (char *)result, &index)) {
03015         li = timeframe->latchInputs[bound];
03016         result = bAig_GetCanonical(manager, li[index]);
03017       }
03018       else if(st_lookup_int(timeframe->o2index, (char *)result, &index)) {
03019         li = timeframe->outputs[bound];
03020         result = bAig_GetCanonical(manager, li[index]);
03021       }
03022       else if(st_lookup_int(timeframe->i2index, (char *)result, &index)) {
03023         li = timeframe->internals[bound];
03024         result = bAig_GetCanonical(manager, li[index]);
03025       }
03026       return result;
03027   }
03028 
03029   left = BmcCirCUsCreatebAigOfPropFormula(network, manager, bound, ltl->left, withInitialState);
03030   if (left == mAig_NULL){
03031     return mAig_NULL;
03032   }  
03033   right = BmcCirCUsCreatebAigOfPropFormula(network, manager, bound, ltl->right, withInitialState);
03034   if (right == mAig_NULL && ltl->type ==Ctlsp_NOT_c ){
03035     return mAig_Not(left);
03036   }  
03037   else if(right == mAig_NULL) {
03038     return mAig_NULL;
03039   }
03040 
03041   switch(ltl->type) {
03047     case Ctlsp_OR_c:
03048       result = mAig_Or(manager, left, right);
03049       break;
03050     case Ctlsp_AND_c:
03051       result = mAig_And(manager, left, right);
03052       break;
03053     case Ctlsp_THEN_c:
03054       result = mAig_Then(manager, left, right); 
03055       break;
03056     case Ctlsp_EQ_c:
03057       result = mAig_Eq(manager, left, right);
03058       break;
03059     case Ctlsp_XOR_c:
03060       result = mAig_Xor(manager, left, right);
03061       break;
03062     default:
03063       fail("Unexpected type");
03064   }
03065   return result;
03066 } /* BmcCirCUsCreatebAigOfPropFormula */
03067 
03082 bAigEdge_t 
03083 BmcCirCUsCreatebAigOfPropFormulaOriginal(
03084     Ntk_Network_t *network,
03085     bAig_Manager_t *manager,
03086     Ctlsp_Formula_t *ltl
03087     )
03088 {
03089   bAigEdge_t result, left, right;
03090 
03091   if (ltl == NIL(Ctlsp_Formula_t))      return mAig_NULL; 
03092   if (ltl->type == Ctlsp_TRUE_c)        return mAig_One; 
03093   if (ltl->type == Ctlsp_FALSE_c)       return mAig_Zero; 
03094 
03095   assert(Ctlsp_isPropositionalFormula(ltl));
03096     
03097   if (ltl->type == Ctlsp_ID_c){
03098       char *nodeNameString  = Ctlsp_FormulaReadVariableName(ltl);
03099       char *nodeValueString = Ctlsp_FormulaReadValueName(ltl);
03100       Ntk_Node_t *node      = Ntk_NetworkFindNodeByName(network, nodeNameString);
03101 
03102       Var_Variable_t *nodeVar;
03103       int             nodeValue;
03104 
03105       MvfAig_Function_t  *tmpMvfAig;
03106       st_table           *nodeToMvfAigTable; /* maps each node to its mvfAig */
03107       
03108       if (node == NIL(Ntk_Node_t)) {
03109           (void) fprintf(vis_stderr, "bmc error: Could not find node corresponding to the name\t %s\n", nodeNameString);
03110           return mAig_NULL;
03111       }
03112 
03113       nodeToMvfAigTable = (st_table *) Ntk_NetworkReadApplInfo(network, MVFAIG_NETWORK_APPL_KEY);
03114       if (nodeToMvfAigTable == NIL(st_table)){
03115          (void) fprintf(vis_stderr, "bmc error: please run build_partiton_maigs first");
03116          return mAig_NULL;
03117       }
03118       tmpMvfAig = Bmc_ReadMvfAig(node, nodeToMvfAigTable);
03119       if (tmpMvfAig ==  NIL(MvfAig_Function_t)){
03120           tmpMvfAig = Bmc_NodeBuildMVF(network, node);
03121           array_free(tmpMvfAig);
03122           tmpMvfAig = Bmc_ReadMvfAig(node, nodeToMvfAigTable);
03123       }
03124       
03125       nodeVar = Ntk_NodeReadVariable(node);
03126       if (Var_VariableTestIsSymbolic(nodeVar)) {
03127         nodeValue = Var_VariableReadIndexFromSymbolicValue(nodeVar, nodeValueString);
03128         if ( nodeValue == -1 ) {
03129           (void) fprintf(vis_stderr, "Value specified in RHS is not in domain of variable\n");
03130           (void) fprintf(vis_stderr,"%s = %s\n", nodeNameString, nodeValueString);
03131           return mAig_NULL;
03132         }
03133       }
03134       else { 
03135         int check;    
03136          check = StringCheckIsInteger(nodeValueString, &nodeValue);
03137          if( check == 0 ) {
03138           (void) fprintf(vis_stderr,"Illegal value in the RHS\n");
03139           (void) fprintf(vis_stderr,"%s = %s\n", nodeNameString, nodeValueString);
03140           return mAig_NULL;
03141          }
03142          if( check == 1 ) {
03143           (void) fprintf(vis_stderr,"Value in the RHS is out of range of int\n");
03144           (void) fprintf(vis_stderr,"%s = %s", nodeNameString, nodeValueString);
03145           return mAig_NULL;
03146          }
03147          if ( !(Var_VariableTestIsValueInRange(nodeVar, nodeValue))) {
03148           (void) fprintf(vis_stderr,"Value specified in RHS is not in domain of variable\n");
03149           (void) fprintf(vis_stderr,"%s = %s\n", nodeNameString, nodeValueString);
03150           return mAig_NULL;
03151 
03152          }
03153       }
03154       result = bAig_GetCanonical(manager,
03155               MvfAig_FunctionReadComponent(tmpMvfAig, nodeValue));
03156       return result;
03157   }
03158 
03159   left = BmcCirCUsCreatebAigOfPropFormulaOriginal(network, manager, ltl->left);
03160   if (left == mAig_NULL){
03161     return mAig_NULL;
03162   }  
03163   right = BmcCirCUsCreatebAigOfPropFormulaOriginal(network, manager, ltl->right);
03164   if (right == mAig_NULL && ltl->type ==Ctlsp_NOT_c ){
03165     return mAig_Not(left);
03166   }  
03167   else if(right == mAig_NULL) {
03168     return mAig_NULL;
03169   }
03170 
03171   switch(ltl->type) {
03177     case Ctlsp_OR_c:
03178       result = mAig_Or(manager, left, right);
03179       break;
03180     case Ctlsp_AND_c:
03181       result = mAig_And(manager, left, right);
03182       break;
03183     case Ctlsp_THEN_c:
03184       result = mAig_Then(manager, left, right); 
03185       break;
03186     case Ctlsp_EQ_c:
03187       result = mAig_Eq(manager, left, right);
03188       break;
03189     case Ctlsp_XOR_c:
03190       result = mAig_Xor(manager, left, right);
03191       break;
03192     default:
03193       fail("Unexpected LTL type");
03194   }
03195   return result;
03196 } /* BmcCirCUsCreatebAigOfPropFormulaOriginal */
03197 
03210 static int
03211 StringCheckIsInteger(
03212   char *string,
03213   int *value)
03214 {
03215   char *ptr;
03216   long l;
03217   
03218   l = strtol (string, &ptr, 0) ;
03219   if(*ptr != '\0')
03220     return 0;
03221   if ((l > MAXINT) || (l < -1 - MAXINT))
03222     return 1 ;
03223   *value = (int) l;
03224   return 2 ;
03225 }
03226 
03227 
03240 satInterface_t *
03241 BmcCirCUsInterface(
03242     bAig_Manager_t *manager,
03243     Ntk_Network_t  *network,
03244     bAigEdge_t     object,
03245     array_t        *auxObjectArray,
03246     BmcOption_t    *bmcOption,
03247     satInterface_t *interface)
03248 {
03249 satManager_t   *cm;
03250 satOption_t    *option;
03251 satLevel_t *d;
03252 int i, size;
03253 bAigEdge_t tv;
03254 
03255 /* allocate sat manager */
03256   cm = sat_InitManager(interface);
03257   cm->nodesArraySize = manager->nodesArraySize;
03258   cm->initNodesArraySize = manager->nodesArraySize;
03259   cm->maxNodesArraySize = manager->maxNodesArraySize;
03260   cm->nodesArray = manager->NodesArray;
03261   cm->HashTable = manager->HashTable;
03262   cm->literals = manager->literals;
03263   cm->initNumVariables = (manager->nodesArraySize/bAigNodeSize);
03264   cm->initNumClauses = 0;
03265   cm->initNumLiterals = 0;
03266   cm->comment = ALLOC(char, 2);
03267   cm->comment[0] = ' ';
03268   cm->comment[1] = '\0';
03269   cm->stdErr = vis_stderr;
03270   cm->stdOut = vis_stdout;
03271   cm->status = 0;
03272   cm->orderedVariableArray = 0;
03273   cm->unitLits = sat_ArrayAlloc(16);
03274   cm->pureLits = sat_ArrayAlloc(16);
03275   cm->option = 0;
03276   cm->each = 0;
03277   cm->decisionHead = 0;
03278   cm->variableArray = 0;
03279   cm->queue = 0;
03280   cm->BDDQueue = 0;
03281   cm->unusedAigQueue = 0;
03282   if(interface)
03283     cm->nonobjUnitLitArray = interface->nonobjUnitLitArray;
03284 
03285   if(auxObjectArray) {
03286     cm->auxObj = sat_ArrayAlloc(auxObjectArray->num+1);
03287     size = auxObjectArray->num;
03288     for(i=0; i<size; i++) {
03289       tv = array_fetch(bAigEdge_t, auxObjectArray, i);
03290       if(tv == 1)       continue;
03291       else if(tv == 0) {
03292         cm->status = SAT_UNSAT;
03293         break;
03294       }
03295       sat_ArrayInsert(cm->auxObj, tv);
03296     }
03297   }
03298   if(object == 0)      cm->status = SAT_UNSAT;
03299   else if(object == 1) cm->status = SAT_SAT;
03300 
03301   if(cm->status == 0) {
03302     cm->obj = sat_ArrayAlloc(1);
03303     sat_ArrayInsert(cm->obj, object);
03304 
03305     /* initialize option */
03306     option = sat_InitOption();
03307     option->cnfPrefix = bmcOption->cnfPrefix;
03308     /*option->verbose = bmcOption->verbosityLevel; */
03309     option->verbose = 0;
03310     option->timeoutLimit = bmcOption->timeOutPeriod;
03311 
03312     sat_SetIncrementalOption(option, bmcOption->incremental);
03313 
03314     cm->option = option;
03315     cm->each = sat_InitStatistics();
03316 
03317     BmcRestoreAssertion(manager, cm);
03318     /* value reset.. */
03319     sat_CleanDatabase(cm);
03320     /* set cone of influence */
03321     sat_SetConeOfInfluence(cm);
03322     sat_AllocLiteralsDB(cm);
03323 
03324     if(bmcOption->cnfFileName != NIL(char)) {
03325       sat_WriteCNF(cm, bmcOption->cnfFileName);
03326     }
03327     if(bmcOption->clauses == 0){ /* CirCUs circuit*/
03328       if (bmcOption->verbosityLevel == BmcVerbosityMax_c) {      
03329         fprintf(vis_stdout,
03330                 "Number of Variables = %d Number of Clauses = %d\n",
03331                 sat_GetNumberOfInitialVariables(cm),  sat_GetNumberOfInitialClauses(cm));
03332       }
03333       if (bmcOption->verbosityLevel >= BmcVerbosityMax_c) {
03334         (void)fprintf(vis_stdout,"Calling SAT solver (CirCUs) ...");
03335         (void) fflush(vis_stdout);
03336       }
03337       sat_Main(cm);
03338       if (bmcOption->verbosityLevel >= BmcVerbosityMax_c) {
03339         (void) fprintf(vis_stdout," done ");
03340         (void) fprintf(vis_stdout, "(%g s)\n", cm->each->satTime);
03341       }
03342       
03343     } else if(bmcOption->clauses == 1) { /* CirCUs CNF */
03344       satArray_t *result;
03345       char       *fileName = NIL(char);
03346    
03347       sat_WriteCNF(cm, bmcOption->satInFile);
03348       if(bmcOption->satSolver == cusp){
03349         fileName = BmcCirCUsCallCusp(bmcOption);
03350       }
03351       if(bmcOption->satSolver == CirCUs){
03352         fileName = BmcCirCUsCallCirCUs(bmcOption);
03353       }
03354       if(fileName != NIL(char)){
03355         result = sat_ReadForcedAssignment(fileName);
03356         d =  sat_AllocLevel(cm);
03357         sat_PutAssignmentValueMain(cm, d, result);
03358         sat_ArrayFree(result);
03359       }
03360     }   
03361   }
03362   sat_CombineStatistics(cm);
03363 
03364   if(interface == 0)
03365     interface = ALLOC(satInterface_t, 1);
03366 
03367   interface->total = cm->total;
03368   interface->nonobjUnitLitArray = cm->nonobjUnitLitArray;
03369   interface->objUnitLitArray = 0;
03370   interface->savedConflictClauses = cm->savedConflictClauses;
03371   interface->trieArray = cm->trieArray;
03372   interface->status = cm->status;
03373   cm->total = 0;
03374   cm->nonobjUnitLitArray = 0;
03375   cm->savedConflictClauses = 0;
03376 
03377   if(cm->maxNodesArraySize > manager->maxNodesArraySize) {
03378     manager->maxNodesArraySize = cm->maxNodesArraySize;
03379     manager->nameList   = REALLOC(char *, manager->nameList  , manager->maxNodesArraySize/bAigNodeSize);
03380     manager->bddIdArray = REALLOC(int ,   manager->bddIdArray  , manager->maxNodesArraySize/bAigNodeSize);
03381     manager->bddArray   = REALLOC(bdd_t *, manager->bddArray  , manager->maxNodesArraySize/bAigNodeSize);
03382   }
03383   manager->NodesArray = cm->nodesArray;
03384   manager->literals = cm->literals;
03385 
03386   /* For the case that the input contains CNF clauese; */
03387   if(cm->literals)
03388     cm->literals->last = cm->literals->initialSize;
03389   cm->nodesArray = 0;
03390   cm->HashTable = 0;
03391   cm->timeframe = 0;
03392   cm->timeframeWOI = 0;
03393   cm->literals = 0;
03394 
03395   sat_FreeManager(cm);
03396 
03397   return(interface);
03398 }
03399 
03412 satInterface_t *
03413 BmcCirCUsInterfaceWithObjArr(
03414     bAig_Manager_t *manager,
03415     Ntk_Network_t *network,
03416     array_t *objectArray,
03417     array_t *auxObjectArray,
03418     BmcOption_t *bmcOption,
03419     satInterface_t *interface)
03420 {
03421 satManager_t *cm;
03422 satOption_t *option;
03423 int i, size;
03424 bAigEdge_t tv;
03425 
03426 /* allocate sat manager */
03427   cm = sat_InitManager(interface);
03428   cm->nodesArraySize = manager->nodesArraySize;
03429   cm->initNodesArraySize = manager->nodesArraySize;
03430   cm->maxNodesArraySize = manager->maxNodesArraySize;
03431   cm->nodesArray = manager->NodesArray;
03432   cm->HashTable = manager->HashTable;
03433   cm->literals = manager->literals;
03434   cm->initNumVariables = (manager->nodesArraySize/bAigNodeSize);
03435   cm->initNumClauses = 0;
03436   cm->initNumLiterals = 0;
03437   cm->comment = ALLOC(char, 2);
03438   cm->comment[0] = ' ';
03439   cm->comment[1] = '\0';
03440   cm->stdErr = vis_stderr;
03441   cm->stdOut = vis_stdout;
03442   cm->status = 0;
03443   cm->orderedVariableArray = 0;
03444   cm->unitLits = sat_ArrayAlloc(16);
03445   cm->pureLits = sat_ArrayAlloc(16);
03446   cm->option = 0;
03447   cm->each = 0;
03448   cm->decisionHead = 0;
03449   cm->variableArray = 0;
03450   cm->queue = 0;
03451   cm->BDDQueue = 0;
03452   cm->unusedAigQueue = 0;
03453   if(interface)
03454     cm->nonobjUnitLitArray = interface->nonobjUnitLitArray;
03455 
03456   if(auxObjectArray) {
03457     cm->auxObj = sat_ArrayAlloc(auxObjectArray->num+1);
03458     size = auxObjectArray->num;
03459     for(i=0; i<size; i++) {
03460       tv = array_fetch(bAigEdge_t, auxObjectArray, i);
03461       if(tv == 1)       continue;
03462       else if(tv == 0) {
03463         cm->status = SAT_UNSAT;
03464         break;
03465       }
03466       sat_ArrayInsert(cm->auxObj, tv);
03467     }
03468   }
03469   if(objectArray) {
03470     cm->obj = sat_ArrayAlloc(objectArray->num+1);
03471     size = objectArray->num;
03472     for(i=0; i<size; i++) {
03473       tv = array_fetch(bAigEdge_t, objectArray, i);
03474       if(tv == 1)       continue;
03475       else if(tv == 0) {
03476         cm->status = SAT_UNSAT;
03477         break;
03478       }
03479       sat_ArrayInsert(cm->obj, tv);
03480     }
03481   }
03482 
03483   if(cm->status == 0) {
03484     /* initialize option */
03485     option = sat_InitOption();
03486     option->cnfPrefix = bmcOption->cnfPrefix;
03487     /*option->verbose = bmcOption->verbosityLevel; */
03488     option->verbose = 0;
03489     option->timeoutLimit = bmcOption->timeOutPeriod;
03490 
03491     sat_SetIncrementalOption(option, bmcOption->incremental);
03492 
03493     cm->option = option;
03494     cm->each = sat_InitStatistics();
03495 
03496     BmcRestoreAssertion(manager, cm);
03497     /* value reset.. */
03498     sat_CleanDatabase(cm);
03499     /* set cone of influence */
03500     sat_SetConeOfInfluence(cm);
03501     sat_AllocLiteralsDB(cm);
03502 
03503     if(bmcOption->cnfFileName != NIL(char)) {
03504       sat_WriteCNF(cm, bmcOption->cnfFileName);
03505     }
03506     if(bmcOption->clauses == 0){ /* CirCUs circuit*/
03507       if (bmcOption->verbosityLevel == BmcVerbosityMax_c) {      
03508         fprintf(vis_stdout,
03509                 "Number of Variables = %d Number of Clauses = %d\n",
03510                 sat_GetNumberOfInitialVariables(cm),  sat_GetNumberOfInitialClauses(cm));
03511       }
03512       if (bmcOption->verbosityLevel >= BmcVerbosityMax_c) {
03513         (void)fprintf(vis_stdout,"Calling SAT solver (CirCUs) ...");
03514         (void) fflush(vis_stdout);
03515       }
03516       sat_Main(cm);
03517       if (bmcOption->verbosityLevel >= BmcVerbosityMax_c) {
03518         (void) fprintf(vis_stdout," done ");
03519         (void) fprintf(vis_stdout, "(%g s)\n", cm->each->satTime);
03520       }
03521     }else if(bmcOption->clauses == 1) { /* CirCUs CNF */
03522       satArray_t *result;
03523       char       *fileName = NIL(char);
03524    
03525       sat_WriteCNF(cm, bmcOption->satInFile);
03526       if(bmcOption->satSolver == cusp){
03527         fileName = BmcCirCUsCallCusp(bmcOption);
03528       } else{ 
03529         if(bmcOption->satSolver == CirCUs){
03530           fileName = BmcCirCUsCallCirCUs(bmcOption);
03531         }
03532       }
03533       if(fileName != NIL(char)){
03534         satLevel_t *d;
03535         
03536         cm->status = SAT_SAT;
03537         result = sat_ReadForcedAssignment(fileName);
03538         d =  sat_AllocLevel(cm);
03539         sat_PutAssignmentValueMain(cm, d, result);
03540         sat_ArrayFree(result);
03541       } else {
03542         cm->status = SAT_UNSAT;
03543       }
03544     }
03545     /*sat_ReportStatistics(cm, cm->each);*/
03546   }
03547   sat_CombineStatistics(cm);
03548 
03549   if(interface == 0){
03550     interface = ALLOC(satInterface_t, 1);
03551   }
03552   interface->total = cm->total;
03553   interface->nonobjUnitLitArray = cm->nonobjUnitLitArray;
03554   interface->objUnitLitArray = 0;
03555   interface->savedConflictClauses = cm->savedConflictClauses;
03556   interface->trieArray = cm->trieArray;
03557   interface->status = cm->status;
03558   cm->total = 0;
03559   cm->nonobjUnitLitArray = 0;
03560   cm->savedConflictClauses = 0;
03561 
03562   if(cm->maxNodesArraySize > manager->maxNodesArraySize) {
03563     manager->maxNodesArraySize = cm->maxNodesArraySize;
03564     manager->nameList   = REALLOC(char *, manager->nameList  , manager->maxNodesArraySize/bAigNodeSize);
03565     manager->bddIdArray = REALLOC(int ,   manager->bddIdArray  , manager->maxNodesArraySize/bAigNodeSize);
03566     manager->bddArray   = REALLOC(bdd_t *, manager->bddArray  , manager->maxNodesArraySize/bAigNodeSize);
03567   }
03568   manager->NodesArray = cm->nodesArray;
03569   manager->literals = cm->literals;
03570 
03571   /*
03572     For the case that the input contains CNF clauses;
03573   */
03574   if(cm->literals)
03575     cm->literals->last = cm->literals->initialSize;
03576   cm->nodesArray = 0;
03577   cm->HashTable = 0;
03578   cm->timeframe = 0;
03579   cm->timeframeWOI = 0;
03580   cm->literals = 0;
03581 
03582   sat_FreeManager(cm);
03583 
03584   return(interface);
03585 }
03586 
03587 
03599 satManager_t *
03600 BmcCirCUsCreateManager(
03601   Ntk_Network_t *network)
03602 {
03603   satManager_t *cm;
03604   bAig_Manager_t *manager;
03605   satOption_t *option;
03606 
03607   manager = Ntk_NetworkReadMAigManager(network);
03608   /* allocate sat manager*/
03609   cm = sat_InitManager(0);
03610   cm->nodesArraySize = manager->nodesArraySize;
03611   cm->initNodesArraySize = manager->nodesArraySize;
03612   cm->maxNodesArraySize = manager->maxNodesArraySize;
03613   cm->nodesArray = manager->NodesArray;
03614   cm->HashTable = manager->HashTable;
03615   cm->literals = manager->literals;
03616   cm->initNumVariables = (manager->nodesArraySize/bAigNodeSize);
03617   cm->initNumClauses = 0;
03618   cm->initNumLiterals = 0;
03619   cm->comment = ALLOC(char, 2);
03620   cm->comment[0] = ' ';
03621   cm->comment[1] = '\0';
03622   cm->stdErr = vis_stderr;
03623   cm->stdOut = vis_stdout;
03624   cm->status = 0;
03625   cm->orderedVariableArray = 0;
03626   cm->unitLits = sat_ArrayAlloc(16);
03627   cm->pureLits = sat_ArrayAlloc(16);
03628   cm->option = 0;
03629   cm->each = 0;
03630   cm->decisionHead = 0;
03631   cm->variableArray = 0;
03632   cm->queue = 0;
03633   cm->BDDQueue = 0;
03634   cm->unusedAigQueue = 0;
03635 
03636   if(cm->status == 0) {
03637     /* initialize option*/
03638     option = sat_InitOption();
03639     /*option->verbose = bmcOption->verbosityLevel;*/
03640     option->verbose = 0;
03641 
03642     cm->option = option;
03643     cm->each = sat_InitStatistics();
03644 
03645     BmcRestoreAssertion(manager, cm);
03646     /* value reset..*/
03647     sat_CleanDatabase(cm);
03648     /* set cone of influence*/
03649     sat_SetConeOfInfluence(cm);
03650     sat_AllocLiteralsDB(cm);
03651 
03652     /*sat_ReportStatistics(cm, cm->each);*/
03653   }
03654   sat_CombineStatistics(cm);
03655 
03656   /*
03657     For the case that the input contains CNF clauese;
03658   */
03659   if(cm->literals)
03660     cm->literals->last = cm->literals->initialSize;
03661 
03662   return(cm);
03663 }
03677 st_table *
03678 BmcCirCUsGetCoiIndexTable(
03679         Ntk_Network_t *network,
03680         st_table *coiTable)
03681 {
03682   mAig_Manager_t  *manager = Ntk_NetworkReadMAigManager(network);
03683   Ntk_Node_t   *node;
03684   st_generator *gen;
03685   int          tmp;
03686   st_table     *node2MvfAigTable = 
03687     (st_table *)Ntk_NetworkReadApplInfo(network, MVFAIG_NETWORK_APPL_KEY);
03688   int mvfSize, index, i;
03689   bAigEdge_t         v;
03690   MvfAig_Function_t  *mvfAig;
03691   st_table           *li2index, *coiIndexTable;
03692   
03693   assert(manager->timeframe != 0);
03694   /*
03695     Mohammad Says:
03696     This may solve the problem of calling expandTimeframe before calling this
03697     function. Check with HoonSang.
03698     
03699     if(timeframe == 0) 
03700     timeframe = bAig_InitTimeFrame(network, manager, 1);
03701   */
03702   
03703   /*
03704     li2index stores AIG id for inputs of all latches
03705    */
03706   li2index = manager->timeframe->li2index;
03707   coiIndexTable = st_init_table(st_numcmp, st_numhash);
03708 
03709   st_foreach_item_int(coiTable, gen, &node, &tmp) {
03710     if(!Ntk_NodeTestIsLatch(node))      continue;
03711     st_lookup(node2MvfAigTable, node, &mvfAig);
03712     mvfSize = array_n(mvfAig);
03713     for(i=0; i< mvfSize; i++){
03714       v = bAig_GetCanonical(manager, MvfAig_FunctionReadComponent(mvfAig, i));
03715       if(st_lookup_int(li2index, (char *)v, &index)) 
03716         st_insert(coiIndexTable, (char *)(long)index, (char *)(long)index);
03717     }
03718   }
03719   return(coiIndexTable);
03720 }
03721 
03733 void
03734 BmcRestoreAssertion(bAig_Manager_t *manager, satManager_t *cm)
03735 {
03736 int size, i, v;
03737 array_t *asserted;
03738 
03739   if(manager->timeframe && manager->timeframe->assertedArray) {
03740     asserted = manager->timeframe->assertedArray;
03741     size = asserted->num;
03742     cm->assertion = sat_ArrayAlloc(size);
03743     for(i=0; i<size; i++) {
03744       v = array_fetch(int, asserted, i);
03745       sat_ArrayInsert(cm->assertion, v);
03746     }
03747   }
03748   else {
03749     cm->assertion = 0;
03750   }
03751 }
03752 
03753 
03754 
03755 /*---------------------------------------------------------------------------*/
03756 /* Definition of static functions                                            */
03757 /*---------------------------------------------------------------------------*/
03758 
03770 static int
03771 verifyIfConstant(
03772   bAigEdge_t   property)
03773 {
03774 
03775   if (property == bAig_One){
03776     fprintf(vis_stdout,"# BMC: Empty counterexample because the property is always FALSE\n");
03777     fprintf(vis_stdout,"# BMC: formula failed\n");
03778     return 1;
03779   } else if (property == bAig_Zero){
03780     fprintf(vis_stdout,"# BMC: The property is always TRUE\n");
03781     fprintf(vis_stdout,"# BMC: formula passed\n");
03782     return 1;
03783   }
03784   return 0;
03785 }