VIS

src/imc/imcImc.c

Go to the documentation of this file.
00001 
00017 #include "imcInt.h" 
00018 #include "part.h"
00019 #include "img.h"
00020 #include "ntm.h"
00021 
00022 static char rcsid[] UNUSED = "$Id: imcImc.c,v 1.21 2005/04/27 00:13:01 fabio Exp $";
00023 
00024 /*---------------------------------------------------------------------------*/
00025 /* Constant declarations                                                     */
00026 /*---------------------------------------------------------------------------*/
00027 
00028 
00029 /*---------------------------------------------------------------------------*/
00030 /* Type declarations                                                         */
00031 /*---------------------------------------------------------------------------*/
00032 
00033 
00034 /*---------------------------------------------------------------------------*/
00035 /* Structure declarations                                                    */
00036 /*---------------------------------------------------------------------------*/
00037 
00038 
00039 /*---------------------------------------------------------------------------*/
00040 /* Variable declarations                                                     */
00041 /*---------------------------------------------------------------------------*/
00042 
00043 
00044 /*---------------------------------------------------------------------------*/
00045 /* Macro declarations                                                        */
00046 /*---------------------------------------------------------------------------*/
00047 
00048 
00051 /*---------------------------------------------------------------------------*/
00052 /* Static function prototypes                                                */
00053 /*---------------------------------------------------------------------------*/
00054 
00055 static int stringCompare(const void * s1, const void * s2);
00056 
00060 /*---------------------------------------------------------------------------*/
00061 /* Definition of exported functions                                          */
00062 /*---------------------------------------------------------------------------*/
00063 
00075 Imc_VerificationResult
00076 Imc_ImcEvaluateFormulaLinearRefine(
00077   Ntk_Network_t         *network,
00078   Ctlp_Formula_t        *orgFormula,
00079   Ctlp_Formula_t        *formula,
00080   Ctlp_FormulaClass     formulaClass,
00081   int                   incrementalSize,
00082   Imc_VerbosityLevel    verbosity,
00083   Imc_RefineMethod      refine,
00084   mdd_t                 *careStates,
00085   Fsm_Fsm_t             *exactFsm,
00086   Imc_DcLevel           dcLevel,
00087   Imc_GraphType         graphType,
00088   Imc_LowerMethod       lowerMethod,
00089   Imc_UpperMethod       upperMethod,
00090   boolean               computeExact,
00091   boolean               needLower,
00092   boolean               needUpper,
00093   Imc_PartMethod        partMethod,
00094   Hrc_Node_t            *currentNode,
00095   char                  *modelName)
00096 {
00097   Imc_Info_t            *imcInfo;
00098   st_table              *latchNameTable;
00099   int                   numberOfLatches, numberOfIncludedLatches;
00100   int                   iterationCount;
00101   Imc_VerificationResult verification = Imc_VerificationError_c;
00102 
00103   /*
00104    * Initialize data structures.
00105    */
00106   imcInfo = Imc_ImcInfoInitialize(network, formula, formulaClass, verbosity,
00107                                   refine, careStates, dcLevel, incrementalSize,
00108                                   graphType, exactFsm, lowerMethod, upperMethod,
00109                                   computeExact, needLower, needUpper,
00110                                   partMethod, currentNode, modelName);
00111 
00112   if (imcInfo == NIL(Imc_Info_t))return(Imc_VerificationError_c); /* FIXED */
00113 
00114   numberOfLatches = array_n(imcInfo->systemInfo->latchNameArray);
00115  
00116   iterationCount = 1;
00117 
00118   numberOfIncludedLatches = array_n(imcInfo->systemInfo->includedLatchIndex);
00119 
00120   if (verbosity != Imc_VerbosityNone_c) {
00121     fprintf(vis_stdout, "IMC : Reduced system has ");
00122     Imc_ImcPrintSystemSize(imcInfo);
00123   }
00124   if(verbosity != Imc_VerbosityNone_c) {
00125     fprintf(vis_stdout, "IMC : Approximate system has ");
00126     Imc_ImcPrintApproxSystemSize(imcInfo);
00127   }
00128 
00129   assert(numberOfLatches >= numberOfIncludedLatches);
00130   while(numberOfLatches >= numberOfIncludedLatches) {
00131  
00132     /*
00133      * verification is one of {Imc_VerificationTrue_c, Imc_VerificationFalse_c,
00134      * Imc_VerificationInconclusive_c}.
00135      */
00136     verification = Imc_ImcVerifyFormula(imcInfo, formula);
00137 
00138     if (verification == Imc_VerificationError_c) {
00139 
00140       (void)fprintf(vis_stdout, "# IMC: formula inconclusive.\n");
00141 
00142       /* Free all */
00143       Imc_ImcInfoFree(imcInfo);
00144       return verification;
00145 
00146     }else if (verification != Imc_VerificationInconclusive_c){ 
00147 
00148       if ((verification == Imc_VerificationTrue_c)) {
00149         (void) fprintf(vis_stdout, "# IMC: formula passed.\n");
00150       }else{
00151         (void) fprintf(vis_stdout, "# IMC: formula failed.\n");
00152       }
00153       fprintf(vis_stdout, "IMC : ");
00154       Ctlp_FormulaPrint( vis_stdout, orgFormula );
00155       fprintf(vis_stdout, "\n");
00156       fprintf(vis_stdout, "IMC : ");
00157       Ctlp_FormulaPrint( vis_stdout, formula);
00158       fprintf(vis_stdout, "\n");
00159 
00160       Imc_ImcInfoFree(imcInfo);
00161       return verification;
00162     }else{
00163       if (numberOfLatches == numberOfIncludedLatches){
00164         if (imcInfo->graphType == Imc_GraphPDOG_c){
00165           (void) fprintf(vis_stdout, "# IMC: formula passed.\n");
00166         }else if (imcInfo->graphType == Imc_GraphNDOG_c){
00167           (void) fprintf(vis_stdout, "# IMC: formula failed.\n");
00168         }
00169         fprintf(vis_stdout, "IMC : ");
00170         Ctlp_FormulaPrint( vis_stdout,orgFormula);
00171         fprintf(vis_stdout, "\n");
00172         fprintf(vis_stdout, "IMC : ");
00173         Ctlp_FormulaPrint( vis_stdout, formula); 
00174         fprintf(vis_stdout, "\n");
00175 
00176         Imc_ImcInfoFree(imcInfo);
00177         return verification;
00178       }
00179     }       
00180 
00181     latchNameTable = array_fetch(st_table *, 
00182                      imcInfo->staticRefineSchedule, iterationCount);
00183     
00184     Imc_ImcSystemInfoUpdate(imcInfo, latchNameTable);
00185 
00186     /*
00187      * Refine the approximate system.
00188      */ 
00189     if (imcInfo->needUpper){
00190       Imc_UpperSystemInfoFree(imcInfo->upperSystemInfo);
00191       Imc_UpperSystemInfoInitialize(imcInfo, latchNameTable);
00192     }
00193 
00194     if (imcInfo->needLower){
00195       Imc_LowerSystemInfoFree(imcInfo->lowerSystemInfo);
00196       Imc_LowerSystemInfoInitialize(imcInfo, latchNameTable);
00197     }
00198 
00199     Imc_NodeInfoReset(imcInfo);
00200 
00201     numberOfIncludedLatches = 
00202         array_n(imcInfo->systemInfo->includedLatchIndex);
00203 
00204     iterationCount++;
00205 
00206     if(verbosity != Imc_VerbosityNone_c) {
00207       fprintf(vis_stdout, "IMC : Approximate system has ");
00208       Imc_ImcPrintApproxSystemSize(imcInfo);
00209     }
00210 
00211   } /* end of while(numberOfLatches >= numberOfIncludedLatches) */
00212 
00213   return(verification); /* FIXED */
00214 }
00215 
00227 Imc_VerificationResult
00228 Imc_ImcVerifyFormula(
00229   Imc_Info_t *imcInfo,
00230   Ctlp_Formula_t *formula)
00231 {
00232   Imc_VerificationResult result;
00233 
00234   if (!Imc_ImcEvaluateCTLFormula(imcInfo, formula, Imc_PolarityPos_c)){
00235     return Imc_VerificationError_c;
00236   }
00237 
00238   result = Imc_SatCheck(imcInfo, formula);
00239 
00240   return result;
00241 }
00242 
00257 Imc_VerificationResult
00258 Imc_SatCheck(
00259   Imc_Info_t *imcInfo,
00260   Ctlp_Formula_t *formula)
00261 {
00262   mdd_t *initialStates = imcInfo->initialStates;
00263   Imc_NodeInfo_t *nodeInfo;
00264 
00265   if (!st_lookup(imcInfo->nodeInfoTable, formula, &nodeInfo)){
00266     return Imc_VerificationError_c; /* FIXED */
00267   }
00268   
00269   if (nodeInfo->lowerSat != NIL(mdd_t)){
00270     if (mdd_lequal(initialStates, nodeInfo->lowerSat, 1, 1)){
00271       return Imc_VerificationTrue_c;
00272     }
00273   }
00274   if (nodeInfo->upperSat != NIL(mdd_t)){
00275     if (!mdd_lequal_mod_care_set(initialStates, nodeInfo->upperSat, 1, 1,
00276                                  imcInfo->modelCareStates)){ /* FIXED */
00277       return Imc_VerificationFalse_c;
00278     }
00279   }
00280   return Imc_VerificationInconclusive_c;
00281 }
00282 
00300 Imc_Info_t *
00301 Imc_ImcInfoInitialize(
00302   Ntk_Network_t      *network,
00303   Ctlp_Formula_t     *formula,
00304   Ctlp_FormulaClass  formulaClass,
00305   Imc_VerbosityLevel verbosity,
00306   Imc_RefineMethod   refine,
00307   mdd_t              *careStates,
00308   Imc_DcLevel        dcLevel,
00309   int                incrementalSize,
00310   Imc_GraphType      graphType,
00311   Fsm_Fsm_t          *exactFsm,
00312   Imc_LowerMethod    lowerMethod,
00313   Imc_UpperMethod    upperMethod,
00314   boolean            computeExact,
00315   boolean            needLower,
00316   boolean            needUpper,
00317   Imc_PartMethod     partMethod,
00318   Hrc_Node_t         *currentNode, 
00319   char               *modelName)
00320 {
00321   int                 i;
00322   char                *flagValue;  
00323   Imc_Info_t          *imcInfo;
00324   mdd_t               *initialStates;
00325   array_t             *scheduleArray;
00326   st_table            *latchNameTable;
00327   st_table            *newLatchNameTable;
00328   st_table            *globalLatchNameTable;
00329   array_t             *psMddIdArray;
00330   array_t             *nsMddIdArray;
00331   array_t             *inputMddIdArray;
00332   array_t             *supportMddIdArray;
00333   array_t             *preQMddIdArray;
00334   array_t             *imgQMddIdArray;
00335   Part_CMethod        correlationMethod;
00336   Ntk_Node_t          *latch, *input;
00337   lsGen               gen;
00338   array_t             *latchNameArray;
00339 
00340   imcInfo = ALLOC(Imc_Info_t, 1);
00341 
00342   /*
00343    * Initialize 
00344    */
00345   imcInfo->network         = network;
00346   imcInfo->globalFsm       = exactFsm;
00347   imcInfo->formulaClass    = formulaClass;
00348   imcInfo->incrementalSize = incrementalSize;
00349   imcInfo->dcLevel         = dcLevel;
00350   imcInfo->refine          = refine;
00351   imcInfo->verbosity       = verbosity;
00352   imcInfo->upperSystemInfo = NIL(Imc_UpperSystemInfo_t);
00353   imcInfo->lowerSystemInfo = NIL(Imc_LowerSystemInfo_t);
00354   imcInfo->initialStates   = NIL(mdd_t); 
00355   imcInfo->nodeInfoTable   = NIL(st_table);
00356   imcInfo->graphType       = graphType;
00357   imcInfo->nodeInfoTable   = st_init_table(st_ptrcmp , st_ptrhash);
00358   imcInfo->mddMgr          = Ntk_NetworkReadMddManager(network);
00359   imcInfo->lowerMethod     = lowerMethod;
00360   imcInfo->upperMethod     = upperMethod;
00361   imcInfo->currentNode     = currentNode;
00362   imcInfo->modelName       = modelName;
00363 
00364   if (exactFsm == NIL(Fsm_Fsm_t)){
00365     imcInfo->useLocalFsm = TRUE;
00366   }else{
00367     imcInfo->useLocalFsm = FALSE;
00368   }
00369 
00370   /*
00371    * Initialize image and preimage computation info.
00372    */
00373   if (exactFsm != NIL(Fsm_Fsm_t)){
00374     psMddIdArray = array_dup(Fsm_FsmReadPresentStateVars(exactFsm));
00375     nsMddIdArray = array_dup(Fsm_FsmReadNextStateVars(exactFsm));
00376     inputMddIdArray = array_dup(Fsm_FsmReadInputVars(exactFsm));
00377   }else{
00378     latchNameArray = array_alloc(char *, 0);
00379     psMddIdArray = array_alloc(int, 0);
00380     nsMddIdArray = array_alloc(int, 0);
00381     inputMddIdArray = array_alloc(int, 0);
00382     /* sort by name of latch */
00383     Ntk_NetworkForEachLatch(network, gen, latch){
00384       array_insert_last(char*, latchNameArray,
00385                         Ntk_NodeReadName(latch));
00386     }
00387 
00388     array_sort(latchNameArray, stringCompare);
00389 
00390     for (i = 0; i < array_n(latchNameArray); i++) {
00391       char *nodeName;
00392       nodeName = array_fetch(char *, latchNameArray, i);
00393       latch = Ntk_NetworkFindNodeByName(network, nodeName);
00394       array_insert_last(int, psMddIdArray,
00395                       Ntk_NodeReadMddId(latch));
00396       array_insert_last(int, nsMddIdArray,
00397                       Ntk_NodeReadMddId(Ntk_NodeReadShadow(latch)));
00398     }
00399  
00400     array_free(latchNameArray);
00401   
00402     Ntk_NetworkForEachInput(network, gen, input){
00403       array_insert_last(int, inputMddIdArray, Ntk_NodeReadMddId(input));
00404     }
00405   }
00406 
00407   imgQMddIdArray = array_dup(psMddIdArray);
00408   array_append(imgQMddIdArray,inputMddIdArray); 
00409 
00410   supportMddIdArray = array_dup(imgQMddIdArray);
00411   array_append(supportMddIdArray,nsMddIdArray);
00412 
00413   preQMddIdArray = array_dup(nsMddIdArray);
00414   array_append(preQMddIdArray,inputMddIdArray); 
00415 
00416   array_free(psMddIdArray);
00417   array_free(nsMddIdArray);
00418   array_free(inputMddIdArray);
00419   
00420   imcInfo->supportMddIdArray = supportMddIdArray;
00421   imcInfo->imgQMddIdArray = imgQMddIdArray;
00422   imcInfo->preQMddIdArray = preQMddIdArray;
00423   imcInfo->needLower = needLower;
00424   imcInfo->needUpper = needUpper;
00425   imcInfo->partMethod = partMethod;
00426 
00427   if (careStates == NIL(mdd_t)){
00428     imcInfo->modelCareStates = mdd_one(imcInfo->mddMgr);
00429   }else{
00430     imcInfo->modelCareStates = mdd_dup(careStates);
00431   }
00432 
00433   /*
00434    * If refine oprion is Imc_RefineLatchRelation_c,
00435    * correlation method should be defined.
00436    */
00437   flagValue = Cmd_FlagReadByName("part_group_correlation_method");
00438   if(flagValue == NIL(char)){
00439     correlationMethod = Part_CorrelationWithBDD; 
00440   }else if (strcmp(flagValue, "support") == 0){
00441     correlationMethod = Part_CorrelationWithSupport; 
00442   }else if (strcmp(flagValue, "mdd") == 0){
00443     correlationMethod = Part_CorrelationWithBDD;
00444   }else{
00445     correlationMethod = Part_CorrelationWithSupport;
00446   }
00447 
00448   if ((refine == Imc_RefineLatchRelation_c) &&
00449       (correlationMethod == Part_CorrelationWithBDD) &&
00450       (partMethod == Imc_PartInc_c)){
00451     correlationMethod = Part_CorrelationWithSupport;
00452   }
00453   imcInfo->correlationMethod = correlationMethod;
00454 
00455   if (computeExact){
00456     scheduleArray = ImcCreateScheduleArray(network, formula, TRUE, 
00457                       Imc_RefineLatchRelation_c, verbosity, incrementalSize,
00458                       correlationMethod);
00459     imcInfo->staticRefineSchedule = NIL(array_t);
00460     latchNameTable = array_fetch(st_table *, scheduleArray, 0);
00461     st_free_table(latchNameTable);
00462     latchNameTable = array_fetch(st_table *, scheduleArray, 1);
00463     newLatchNameTable = st_copy(latchNameTable);
00464     array_insert(st_table *, scheduleArray, 0, newLatchNameTable);
00465 
00466   }else if (refine == Imc_RefineLatchRelation_c){
00467     scheduleArray = ImcCreateScheduleArray(network, formula, FALSE, refine, 
00468                     verbosity, incrementalSize, correlationMethod);
00469     imcInfo->staticRefineSchedule = scheduleArray;
00470 
00471   }else if (refine == Imc_RefineSort_c){
00472     scheduleArray = ImcCreateScheduleArray(network, formula, TRUE, refine, 
00473                     verbosity, incrementalSize, correlationMethod);
00474     imcInfo->staticRefineSchedule = scheduleArray;
00475 
00476   }else{
00477     fprintf(vis_stdout, "** imc error: Unkown refinement method.\n");
00478     Imc_ImcInfoFree(imcInfo);
00479     return NIL(Imc_Info_t);
00480   }
00481 
00482   if (scheduleArray == NIL(array_t)){
00483     fprintf(vis_stdout, "** imc error: Can't get an initial system.\n");
00484     Imc_ImcInfoFree(imcInfo);
00485     return NIL(Imc_Info_t);
00486   }
00487     
00488   globalLatchNameTable = array_fetch(st_table *, scheduleArray, array_n(scheduleArray)-1);
00489   latchNameTable = array_fetch(st_table *, scheduleArray, 0);  
00490 
00491   /*
00492    * Initialize a total system info.
00493    */
00494   Imc_SystemInfoInitialize(imcInfo, globalLatchNameTable, latchNameTable);  
00495 
00496   /*
00497    * Initialize an initial approximate system info.
00498    */
00499   if (needUpper){
00500     Imc_UpperSystemInfoInitialize(imcInfo,latchNameTable);
00501   }
00502   if (needLower){
00503     Imc_LowerSystemInfoInitialize(imcInfo,latchNameTable);
00504   }
00505 
00506   initialStates = Fsm_FsmComputeInitialStates(imcInfo->globalFsm);  
00507   if (initialStates == NIL(mdd_t)){
00508     fprintf(vis_stdout,"** imc error : System has no initial state.\n");
00509     Imc_ImcInfoFree(imcInfo);
00510     return NIL(Imc_Info_t);
00511   }
00512   imcInfo->initialStates = initialStates;  
00513 
00514   if (computeExact){
00515     arrayForEachItem(st_table *, scheduleArray, i, latchNameTable){
00516       st_free_table(latchNameTable);
00517     }
00518     array_free(scheduleArray);
00519   }
00520 
00521   return(imcInfo);
00522 }
00523 
00524 
00536 void
00537 Imc_ImcInfoFree(
00538   Imc_Info_t *imcInfo)
00539 {
00540   int i;
00541   st_table *latchNameTable;
00542 
00543   Imc_UpperSystemInfoFree(imcInfo->upperSystemInfo);
00544   Imc_LowerSystemInfoFree(imcInfo->lowerSystemInfo);
00545   ImcNodeInfoTableFree(imcInfo->nodeInfoTable);
00546   if (imcInfo->initialStates != NIL(mdd_t)) mdd_free(imcInfo->initialStates); 
00547 
00548   if (imcInfo->modelCareStates!=NIL(mdd_t)) mdd_free(imcInfo->modelCareStates);
00549   if (imcInfo->staticRefineSchedule != NIL(array_t)){
00550     arrayForEachItem(st_table *,imcInfo->staticRefineSchedule, i, latchNameTable){
00551       st_free_table(latchNameTable);
00552     }
00553     array_free(imcInfo->staticRefineSchedule);
00554   }
00555   if (imcInfo->supportMddIdArray != NIL(array_t)) 
00556     array_free(imcInfo->supportMddIdArray);
00557   if (imcInfo->imgQMddIdArray != NIL(array_t)) 
00558     array_free(imcInfo->imgQMddIdArray);
00559   if (imcInfo->preQMddIdArray != NIL(array_t)) 
00560     array_free(imcInfo->preQMddIdArray);
00561 
00562   if ((imcInfo->useLocalFsm) && (imcInfo->globalFsm != NIL(Fsm_Fsm_t))){
00563     Fsm_FsmSubsystemFree(imcInfo->globalFsm);
00564   }
00565 
00566   Imc_SystemInfoFree(imcInfo->systemInfo);
00567 
00568   FREE(imcInfo);
00569 }
00570 
00571 
00583 void
00584 Imc_SystemInfoInitialize(
00585   Imc_Info_t *imcInfo,
00586   st_table *globalLatchNameTable,
00587   st_table *initialLatchNameTable)
00588 {
00589   int i, psMddId, nsMddId, latchSize;
00590   char *name, *dataInputName;
00591   Ntk_Node_t *node, *latchInput;  
00592   Ntk_Network_t *network = imcInfo->network;
00593   graph_t *partition = Part_NetworkReadPartition(network);
00594   vertex_t *vertex;
00595   Mvf_Function_t *mvf;
00596   mdd_t *singleTR, *subTR, *tempMdd;
00597   st_generator *stGen;
00598   lsList latchInputList;
00599   lsGen gen;
00600   st_table *partNameTable;
00601   Imc_SystemInfo_t *systemInfo;
00602   array_t *bddIdArray;
00603   array_t *latchNameArray = 
00604            array_alloc(char *, st_count(globalLatchNameTable));
00605   st_table *latchNameTable = st_init_table(strcmp, st_strhash );
00606   st_table *latchInputTable = st_init_table(st_ptrcmp, st_ptrhash );
00607   st_table *nsMddIdToIndex = st_init_table(st_numcmp, st_numhash);
00608   st_table *psMddIdToIndex = st_init_table(st_numcmp, st_numhash);
00609   array_t *latchNodeArray = 
00610            array_alloc(Ntk_Node_t *, st_count(globalLatchNameTable));
00611   array_t *nsMddIdArray = array_alloc(int,st_count(globalLatchNameTable));
00612   array_t *psMddIdArray = array_alloc(int,st_count(globalLatchNameTable));
00613   array_t *TRArray = array_alloc(mdd_t *,st_count(globalLatchNameTable));
00614   array_t *lowerTRArray = array_alloc(mdd_t *,st_count(globalLatchNameTable));
00615   array_t *mvfArray = array_alloc(mdd_t *,st_count(globalLatchNameTable));
00616   array_t *latchSizeArray = array_alloc(int,st_count(globalLatchNameTable));
00617   array_t *includedLatchIndex = array_alloc(int, 0);
00618   array_t *includedNsMddId = array_alloc(int, 0);
00619   array_t *excludedLatchIndex = array_alloc(int, 0);
00620   array_t *excludedNsMddId = array_alloc(int, 0);
00621   array_t *excludedPsMddId = array_alloc(int, 0);
00622   array_t *includedPsMddId = array_alloc(int, 0);
00623   st_table *excludedPsMddIdTable = st_init_table(st_numcmp, st_numhash);
00624 
00625   systemInfo = ALLOC(Imc_SystemInfo_t, 1);
00626 
00627   st_foreach_item(globalLatchNameTable, stGen, &name, NIL(char *)){
00628     array_insert_last(char *, latchNameArray, name);
00629   }
00630 
00631   array_sort(latchNameArray, stringCompare);
00632 
00633   if (partition == NIL(graph_t)){
00634     if ((imcInfo->partMethod == Imc_PartInc_c) &&
00635         !((imcInfo->needLower) && 
00636          (imcInfo->lowerMethod != Imc_LowerUniversalQuantification_c))){
00637       partNameTable = initialLatchNameTable;
00638     }else{
00639       partNameTable = globalLatchNameTable;
00640     }
00641     st_foreach_item(partNameTable, stGen, &name, NIL(char *)){
00642       node = Ntk_NetworkFindNodeByName(network, name);
00643       latchInput = Ntk_LatchReadDataInput(node);
00644       st_insert(latchInputTable, (char *)latchInput, (char *)(long)(-1));
00645     }
00646     latchInputList = lsCreate();
00647     st_foreach_item(latchInputTable, stGen, &node, NULL){
00648       lsNewEnd(latchInputList, (lsGeneric)node, LS_NH);
00649     }
00650     st_free_table(latchInputTable);
00651     Ntk_NetworkForEachCombOutput(network, gen, node){
00652       if (Ntk_NodeTestIsLatchInitialInput(node)){
00653         lsNewEnd(latchInputList, (lsGeneric)node, LS_NH);
00654       }
00655     }
00656 
00657     partition = Part_NetworkCreatePartition(network, imcInfo->currentNode, 
00658                   imcInfo->modelName, latchInputList, (lsList)0, NIL(mdd_t),
00659                   Part_InOut_c, (lsList)0, FALSE, 0, 0);
00660     lsDestroy(latchInputList, (void (*)(lsGeneric))0); 
00661     
00662     Ntk_NetworkAddApplInfo(network, PART_NETWORK_APPL_KEY,
00663                   (Ntk_ApplInfoFreeFn) Part_PartitionFreeCallback,
00664                   (void *) partition);
00665 
00666     imcInfo->globalFsm = Fsm_FsmCreateSubsystemFromNetwork(network,partition,
00667                                                     partNameTable, FALSE, 0);
00668 
00669     imcInfo->useLocalFsm = TRUE;
00670   }else{
00671     st_foreach_item(initialLatchNameTable, stGen, &name, NIL(char *)){
00672       node = Ntk_NetworkFindNodeByName(network, name);
00673       latchInput = Ntk_LatchReadDataInput(node);
00674       st_insert(latchInputTable, (char *)latchInput, (char *)(long)(-1));
00675     }
00676     latchInputList = lsCreate();
00677     st_foreach_item(latchInputTable, stGen, &node, NIL(char *)){
00678       lsNewEnd(latchInputList, (lsGeneric)node, LS_NH);
00679     }
00680     st_free_table(latchInputTable);
00681     Ntk_NetworkForEachCombOutput(network, gen, node){
00682       if (Ntk_NodeTestIsLatchInitialInput(node)){
00683         lsNewEnd(latchInputList, (lsGeneric)node, LS_NH);
00684       }
00685     }
00686     (void) Part_PartitionChangeRoots(network, partition,
00687                                      latchInputList, 0);
00688     lsDestroy(latchInputList, (void (*)(lsGeneric))0);
00689   }
00690 
00691   for (i=0;i<array_n(latchNameArray);i++){
00692     name = array_fetch(char *, latchNameArray, i);
00693     node = Ntk_NetworkFindNodeByName(network, name);
00694     psMddId = Ntk_NodeReadMddId(node);
00695     nsMddId = Ntk_NodeReadMddId(Ntk_NodeReadShadow(node));
00696 
00697     dataInputName = Ntk_NodeReadName(Ntk_LatchReadDataInput(node));
00698 
00699     if (st_is_member(initialLatchNameTable, name)) { 
00700       vertex = Part_PartitionFindVertexByName(partition, dataInputName);
00701       mvf = Part_VertexReadFunction(vertex);      
00702       singleTR = Mvf_FunctionBuildRelationWithVariable(mvf, nsMddId);
00703       array_insert(mdd_t *, TRArray, i, 
00704                    bdd_minimize(singleTR, imcInfo->modelCareStates));
00705       array_insert(mdd_t *, lowerTRArray, i, NIL(mdd_t));
00706       array_insert(Mvf_Function_t *, mvfArray, i, NIL(Mvf_Function_t));
00707       mdd_free(singleTR);
00708     }else{
00709       array_insert(Mvf_Function_t *, mvfArray, i, NIL(Mvf_Function_t));
00710       array_insert(mdd_t *, lowerTRArray, i, NIL(mdd_t));
00711       array_insert(mdd_t *, TRArray, i, NIL(mdd_t));
00712     }
00713     
00714 
00715     if (!st_is_member(initialLatchNameTable, name)){
00716       if (imcInfo->needLower && 
00717          imcInfo->lowerMethod != Imc_LowerUniversalQuantification_c){
00718         singleTR = array_fetch(mdd_t *, TRArray, i);
00719         if (singleTR == NIL(mdd_t)){
00720           vertex = Part_PartitionFindVertexByName(partition, dataInputName);
00721           mvf = Part_VertexReadFunction(vertex);                  
00722           singleTR = Mvf_FunctionBuildRelationWithVariable(mvf, nsMddId);
00723           tempMdd = mdd_and(singleTR, imcInfo->modelCareStates, 1, 1);
00724           mdd_free(singleTR);
00725         }else{
00726           tempMdd = mdd_and(singleTR, imcInfo->modelCareStates, 1, 1);
00727         }           
00728         subTR = bdd_approx_remap_ua(tempMdd,(bdd_approx_dir_t)BDD_UNDER_APPROX,
00729                                     array_n(imcInfo->supportMddIdArray), 0, 1.0);
00730         mdd_free(tempMdd);
00731         tempMdd = bdd_minimize(subTR, imcInfo->modelCareStates);
00732         mdd_free(subTR);
00733         subTR = tempMdd;
00734         array_insert(mdd_t *, lowerTRArray, i, subTR);
00735         array_insert(Mvf_Function_t *, mvfArray, i, NIL(Mvf_Function_t));
00736       }   
00737     }
00738 
00739     if (st_is_member(initialLatchNameTable, name)){
00740       array_insert_last(int, includedLatchIndex, i);
00741       array_insert_last(int, includedNsMddId, nsMddId);
00742       array_insert_last(int, includedPsMddId, psMddId);
00743     }else{
00744       array_insert_last(int, excludedLatchIndex, i);
00745       array_insert_last(int, excludedNsMddId, nsMddId);
00746       array_insert_last(int, excludedPsMddId, psMddId);
00747       st_insert(excludedPsMddIdTable, (char *)(long)psMddId, 
00748                       (char *)0);
00749     }      
00750     bddIdArray = mdd_id_to_bdd_id_array(imcInfo->mddMgr, nsMddId);
00751     latchSize = array_n(bddIdArray);
00752     array_free(bddIdArray);
00753     st_insert(latchNameTable, name, (char *)(long)i);
00754     st_insert(nsMddIdToIndex,(char *)(long)nsMddId, (char *)(long)i); 
00755     st_insert(psMddIdToIndex,(char *)(long)psMddId, (char *)(long)i);
00756     array_insert(Ntk_Node_t *, latchNodeArray, i, node);
00757     array_insert(int, latchSizeArray, i, latchSize);
00758  
00759     array_insert(int, nsMddIdArray, i, nsMddId);
00760     array_insert(int, psMddIdArray, i, psMddId);
00761   }
00762   
00763   systemInfo->latchNameTable = latchNameTable;
00764   systemInfo->latchNameArray = latchNameArray;
00765   systemInfo->latchNodeArray = latchNodeArray;  
00766   systemInfo->nsMddIdArray = nsMddIdArray;
00767   systemInfo->psMddIdArray = psMddIdArray;
00768   systemInfo->inputMddIdArray = 
00769     array_dup(Fsm_FsmReadInputVars(imcInfo->globalFsm));
00770   systemInfo->TRArray = TRArray;
00771   systemInfo->lowerTRArray = lowerTRArray;
00772   systemInfo->mvfArray = mvfArray;
00773   systemInfo->latchSizeArray = latchSizeArray;
00774   systemInfo->nsMddIdToIndex = nsMddIdToIndex;
00775   systemInfo->psMddIdToIndex = psMddIdToIndex;
00776   systemInfo->excludedLatchIndex  = excludedLatchIndex;
00777   systemInfo->includedLatchIndex  = includedLatchIndex; 
00778   systemInfo->excludedNsMddId  = excludedNsMddId;
00779   systemInfo->includedNsMddId  = includedNsMddId; 
00780   systemInfo->excludedPsMddId  = excludedPsMddId; 
00781   systemInfo->includedPsMddId  = includedPsMddId; 
00782   systemInfo->excludedPsMddIdTable  = excludedPsMddIdTable;
00783 
00784   imcInfo->systemInfo = systemInfo;
00785 }
00786 
00798 void
00799 Imc_SystemInfoFree(
00800   Imc_SystemInfo_t *systemInfo)
00801 {
00802   int i;
00803   mdd_t *singleTR;
00804 
00805   if (systemInfo->latchNameTable != NIL(st_table))
00806     st_free_table(systemInfo->latchNameTable);
00807   if (systemInfo->latchNameArray != NIL(array_t))
00808     array_free(systemInfo->latchNameArray);
00809   if (systemInfo->latchNodeArray != NIL(array_t))
00810     array_free(systemInfo->latchNodeArray);
00811   if (systemInfo->nsMddIdArray != NIL(array_t))
00812     array_free(systemInfo->nsMddIdArray);
00813   if (systemInfo->psMddIdArray != NIL(array_t))
00814     array_free(systemInfo->psMddIdArray);
00815   if (systemInfo->inputMddIdArray != NIL(array_t))
00816     array_free(systemInfo->inputMddIdArray);
00817   if (systemInfo->TRArray != NIL(array_t)){
00818     for(i=0;i<array_n(systemInfo->TRArray);i++){
00819       singleTR = array_fetch(mdd_t *, systemInfo->TRArray, i);
00820       if (singleTR != NIL(mdd_t)){
00821         mdd_free(singleTR);
00822       }
00823     }
00824     array_free(systemInfo->TRArray);   
00825   }
00826 
00827   if (systemInfo->lowerTRArray != NIL(array_t)){
00828     for(i=0;i<array_n(systemInfo->lowerTRArray);i++){
00829       singleTR = array_fetch(mdd_t *, systemInfo->lowerTRArray, i);
00830       if (singleTR != NIL(mdd_t)){
00831         mdd_free(singleTR);
00832       }
00833     }
00834     array_free(systemInfo->lowerTRArray);
00835   }
00836 
00837   if (systemInfo->mvfArray != NIL(array_t))
00838     array_free(systemInfo->mvfArray);
00839   if (systemInfo->latchSizeArray != NIL(array_t))
00840     array_free(systemInfo->latchSizeArray);
00841   if (systemInfo->nsMddIdToIndex != NIL(st_table))
00842     st_free_table(systemInfo->nsMddIdToIndex);
00843   if (systemInfo->psMddIdToIndex != NIL(st_table))
00844     st_free_table(systemInfo->psMddIdToIndex);
00845   if (systemInfo->excludedLatchIndex != NIL(array_t))
00846     array_free(systemInfo->excludedLatchIndex);
00847   if (systemInfo->includedLatchIndex != NIL(array_t))
00848     array_free(systemInfo->includedLatchIndex);
00849   if (systemInfo->excludedNsMddId != NIL(array_t))
00850     array_free(systemInfo->excludedNsMddId);
00851   if (systemInfo->includedNsMddId != NIL(array_t))
00852     array_free(systemInfo->includedNsMddId);
00853   if (systemInfo->excludedPsMddId != NIL(array_t))
00854      array_free(systemInfo->excludedPsMddId);
00855   if (systemInfo->includedPsMddId != NIL(array_t))
00856      array_free(systemInfo->includedPsMddId);
00857   if (systemInfo->excludedPsMddIdTable != NIL(st_table))
00858     st_free_table(systemInfo->excludedPsMddIdTable);
00859 
00860   FREE(systemInfo);
00861 }
00862 
00875 void
00876 Imc_ImcSystemInfoUpdate(
00877   Imc_Info_t *imcInfo,
00878   st_table *newLatchNameTable)
00879 {
00880   int i, nsMddId, psMddId, index;
00881   char *name, *dataInputName;
00882   mdd_t *singleTR;
00883   st_generator *stGen;
00884   Ntk_Node_t *node, *latchInput;
00885   Mvf_Function_t *mvf;
00886   vertex_t *vertex;
00887   lsList latchInputList;
00888   lsGen gen;
00889   graph_t *partition = Part_NetworkReadPartition(imcInfo->network);
00890   st_table *latchInputTable;
00891   Imc_SystemInfo_t *systemInfo = imcInfo->systemInfo;
00892 
00893   if ((imcInfo->partMethod == Imc_PartInc_c) &&
00894       !(imcInfo->needLower && 
00895         imcInfo->lowerMethod != Imc_LowerUniversalQuantification_c)){
00896     latchInputTable = st_init_table(st_ptrcmp, st_ptrhash );
00897     st_foreach_item(newLatchNameTable, stGen, &name, NIL(char *)){
00898       node = Ntk_NetworkFindNodeByName(imcInfo->network, name);
00899       latchInput = Ntk_LatchReadDataInput(node);
00900       st_insert(latchInputTable, (char *)latchInput, (char *)(long)(-1));
00901     }
00902     latchInputList = lsCreate();
00903     st_foreach_item(latchInputTable, stGen, &node, NULL){
00904       lsNewEnd(latchInputList, (lsGeneric)node, LS_NH);
00905     }
00906     st_free_table(latchInputTable);
00907     Ntk_NetworkForEachCombOutput(imcInfo->network, gen, node){
00908       if (Ntk_NodeTestIsLatchInitialInput(node)){
00909         lsNewEnd(latchInputList, (lsGeneric)node, LS_NH);
00910       }
00911     }
00912     (void) Part_PartitionChangeRoots(imcInfo->network, partition,
00913                                      latchInputList, 0);
00914     lsDestroy(latchInputList, (void (*)(lsGeneric))0); 
00915   }
00916 
00917   if (systemInfo->excludedLatchIndex != NIL(array_t)){
00918     array_free(systemInfo->excludedLatchIndex);
00919     systemInfo->excludedLatchIndex = array_alloc(int, 0);
00920   }
00921   if (systemInfo->includedLatchIndex != NIL(array_t)){
00922     array_free(systemInfo->includedLatchIndex);
00923     systemInfo->includedLatchIndex = array_alloc(int, 0);
00924   }
00925   if (systemInfo->excludedNsMddId != NIL(array_t)){
00926     array_free(systemInfo->excludedNsMddId);
00927     systemInfo->excludedNsMddId = array_alloc(int, 0);
00928   }
00929   if (systemInfo->includedNsMddId != NIL(array_t)){
00930     array_free(systemInfo->includedNsMddId);
00931     systemInfo->includedNsMddId = array_alloc(int, 0);
00932   }
00933   if (systemInfo->excludedPsMddId != NIL(array_t)){
00934      array_free(systemInfo->excludedPsMddId);
00935      systemInfo->excludedPsMddId = array_alloc(int, 0);
00936   }
00937   if (systemInfo->includedPsMddId != NIL(array_t)){
00938      array_free(systemInfo->includedPsMddId);
00939      systemInfo->includedPsMddId = array_alloc(int, 0);
00940   }
00941   if (systemInfo->excludedPsMddIdTable != NIL(st_table)){
00942     st_free_table(systemInfo->excludedPsMddIdTable);
00943     systemInfo->excludedPsMddIdTable = st_init_table(st_numcmp, st_numhash);
00944   }
00945   
00946   for(i=0;i<array_n(imcInfo->systemInfo->latchNameArray);i++){
00947     name = array_fetch(char *,imcInfo->systemInfo->latchNameArray,i);
00948     node = Ntk_NetworkFindNodeByName(imcInfo->network, name);
00949     psMddId = Ntk_NodeReadMddId(node);
00950     nsMddId = Ntk_NodeReadMddId(Ntk_NodeReadShadow(node));
00951 
00952     if (st_is_member(newLatchNameTable, name)){
00953       array_insert_last(int, systemInfo->includedLatchIndex, i);
00954       array_insert_last(int, systemInfo->includedNsMddId, nsMddId);
00955       array_insert_last(int, systemInfo->includedPsMddId, psMddId);
00956     }else{
00957       array_insert_last(int, systemInfo->excludedLatchIndex, i);
00958       array_insert_last(int, systemInfo->excludedNsMddId, nsMddId);
00959       array_insert_last(int, systemInfo->excludedPsMddId, psMddId);
00960       st_insert(systemInfo->excludedPsMddIdTable, (char *)(long)psMddId, 
00961                       (char *)0);
00962     }      
00963   }
00964      
00965   st_foreach_item(newLatchNameTable, stGen, &name, NIL(char *)){
00966     st_lookup_int(imcInfo->systemInfo->latchNameTable,name, &index);
00967     nsMddId = array_fetch(int, imcInfo->systemInfo->nsMddIdArray, index);
00968     psMddId = array_fetch(int, imcInfo->systemInfo->psMddIdArray, index);
00969 
00970     mvf = array_fetch(Mvf_Function_t *, imcInfo->systemInfo->mvfArray, index);
00971 
00972     if (mvf == NIL(Mvf_Function_t)){
00973       node = Ntk_NetworkFindNodeByName(imcInfo->network, name); 
00974       latchInput = Ntk_LatchReadDataInput(node);
00975       dataInputName = Ntk_NodeReadName(Ntk_LatchReadDataInput(node));  
00976       vertex = Part_PartitionFindVertexByName(partition, dataInputName);
00977       mvf = Part_VertexReadFunction(vertex);
00978     }
00979 
00980     singleTR = array_fetch(mdd_t *, imcInfo->systemInfo->TRArray, index);
00981 
00982     if (singleTR == NIL(mdd_t)){ 
00983       singleTR = Mvf_FunctionBuildRelationWithVariable(mvf, nsMddId);
00984       array_insert(mdd_t *, imcInfo->systemInfo->TRArray, index, 
00985                    bdd_minimize(singleTR, imcInfo->modelCareStates));
00986 
00987       array_insert(Mvf_Function_t *, imcInfo->systemInfo->mvfArray, index, 
00988                    NIL(Mvf_Function_t));
00989       mdd_free(singleTR);
00990     }
00991 
00992     singleTR = array_fetch(mdd_t *, imcInfo->systemInfo->lowerTRArray, index);
00993     if (singleTR != NIL(mdd_t)){ 
00994       mdd_free(singleTR);
00995       array_insert(mdd_t *,imcInfo->systemInfo->lowerTRArray,index,NIL(mdd_t));
00996     }        
00997   }
00998 }
00999 
01011 void
01012 Imc_UpperSystemInfoInitialize(
01013   Imc_Info_t *imcInfo,
01014   st_table   *latchNameTable)
01015 {
01016   int                   i, index;
01017   int                   count;
01018   char                  *name;
01019   Imc_UpperSystemInfo_t *upperSystem;
01020   st_table              *globalLatchNameTable;
01021   array_t               *globalLatchNameArray;
01022   array_t               *relationArray;
01023   mdd_t                 *singleTR;
01024 
01025   upperSystem = ALLOC(Imc_UpperSystemInfo_t, 1);
01026   upperSystem->systemInfo = imcInfo->systemInfo;
01027 
01028   globalLatchNameTable = imcInfo->systemInfo->latchNameTable;
01029   globalLatchNameArray = imcInfo->systemInfo->latchNameArray;
01030 
01031   relationArray = array_alloc(mdd_t *, st_count(latchNameTable));
01032 
01033   count = 0;
01034 
01035   for (i=0;i<array_n(globalLatchNameArray);i++){
01036     name = array_fetch(char *, globalLatchNameArray, i);  
01037     if (st_is_member(latchNameTable, name)){
01038       st_lookup_int(globalLatchNameTable, name, (int *)&index);
01039       singleTR = array_fetch(mdd_t *, imcInfo->systemInfo->TRArray, index);
01040       array_insert(mdd_t *, relationArray, count++, singleTR);
01041     }
01042   }
01043 
01044   Img_ClusterRelationArray(imcInfo->mddMgr, Img_Iwls95_c, Img_Backward_c,
01045                            relationArray,
01046                            imcInfo->systemInfo->psMddIdArray,
01047                            imcInfo->systemInfo->nsMddIdArray,
01048                            imcInfo->systemInfo->inputMddIdArray,
01049                            &upperSystem->bwdRealationArray,
01050                            &upperSystem->bwdSmoothVarsArray,
01051                            NIL(array_t *), 0); /* FIXED */
01052   upperSystem->fwdRealationArray = NIL(array_t);
01053   upperSystem->fwdSmoothVarsArray = NIL(array_t);
01054   upperSystem->bwdMinimizedRealationArray = NIL(array_t);
01055 
01056   upperSystem->careStates = mdd_dup(imcInfo->modelCareStates);
01057 
01058   array_free(relationArray);
01059  
01060   imcInfo->upperSystemInfo = upperSystem;
01061 
01062   if ((imcInfo->verbosity == Imc_VerbosityMin_c) ||
01063       (imcInfo->verbosity == Imc_VerbosityMax_c)){
01064     fprintf(vis_stdout, "IMC: |BWD Upper T| = %10ld BDD nodes (%-4d components)\n",
01065       bdd_size_multiple(upperSystem->bwdRealationArray),
01066       array_n(upperSystem->bwdRealationArray));
01067   }
01068   return;
01069 }
01070 
01083 void
01084 Imc_UpperSystemMinimize(
01085   Imc_Info_t *imcInfo,
01086   mdd_t *careStates)
01087 {
01088   int i;
01089   mdd_t *singleTR;
01090   mdd_t *tempMdd;
01091   Imc_UpperSystemInfo_t *upperSystem = imcInfo->upperSystemInfo;
01092 
01093   if (mdd_equal(careStates,upperSystem->careStates)) return;
01094 
01095   if (upperSystem->bwdMinimizedRealationArray == NIL(array_t)){
01096     upperSystem->bwdMinimizedRealationArray = 
01097       array_alloc(mdd_t *, array_n(upperSystem->bwdRealationArray));
01098     for (i=0;i<array_n(upperSystem->bwdRealationArray);i++){
01099       array_insert(mdd_t *, upperSystem->bwdMinimizedRealationArray, i, NIL(mdd_t));
01100     }
01101   }
01102 
01103   for (i=0;i<array_n(upperSystem->bwdRealationArray);i++){ 
01104     singleTR = array_fetch(mdd_t *, upperSystem->bwdMinimizedRealationArray, i);
01105     if (singleTR != NIL(mdd_t)){
01106       mdd_free(singleTR);
01107     }
01108     singleTR = array_fetch(mdd_t *, upperSystem->bwdRealationArray, i);
01109     tempMdd = bdd_minimize(singleTR, careStates);
01110     array_insert(mdd_t *, upperSystem->bwdMinimizedRealationArray, i, tempMdd);
01111   }
01112  
01113   if (upperSystem->careStates != NIL(mdd_t)){
01114     mdd_free(upperSystem->careStates);
01115   }
01116   upperSystem->careStates = mdd_dup(careStates);
01117 
01118   if ((imcInfo->verbosity == Imc_VerbosityMin_c) ||
01119       (imcInfo->verbosity == Imc_VerbosityMax_c)){
01120     fprintf(vis_stdout, "IMC: |Minimized BWD Upper T| = %10ld BDD nodes (%-4d components)\n",
01121       bdd_size_multiple(upperSystem->bwdMinimizedRealationArray),
01122       array_n(upperSystem->bwdMinimizedRealationArray));
01123   }
01124 
01125   return;
01126 }
01127 
01139 void
01140 Imc_UpperSystemInfoFree(
01141   Imc_UpperSystemInfo_t *upperSystem)
01142 {
01143   int i;
01144   array_t *tempArray;
01145 
01146   if (upperSystem == NIL(Imc_UpperSystemInfo_t)) return;   
01147 
01148   if (upperSystem->careStates != NIL(mdd_t)){
01149     mdd_free(upperSystem->careStates);
01150   }
01151 
01152   if (upperSystem->fwdRealationArray != NIL(array_t)){
01153     mdd_array_free(upperSystem->fwdRealationArray);
01154     upperSystem->fwdRealationArray = NIL(array_t);
01155   }
01156   if (upperSystem->fwdSmoothVarsArray != NIL(array_t)){
01157     array_free(upperSystem->fwdSmoothVarsArray);
01158     upperSystem->fwdSmoothVarsArray = NIL(array_t);
01159   }
01160   if (upperSystem->bwdRealationArray != NIL(array_t)){
01161     mdd_array_free(upperSystem->bwdRealationArray);
01162     upperSystem->bwdRealationArray = NIL(array_t);
01163   }
01164   if (upperSystem->bwdMinimizedRealationArray != NIL(array_t)){
01165     mdd_array_free(upperSystem->bwdMinimizedRealationArray);
01166     upperSystem->bwdMinimizedRealationArray = NIL(array_t);
01167   }
01168   if (upperSystem->bwdSmoothVarsArray != NIL(array_t)){
01169     for (i=0; i<array_n(upperSystem->bwdSmoothVarsArray);i++){
01170       tempArray = array_fetch(array_t *, upperSystem->bwdSmoothVarsArray, i);
01171       mdd_array_free(tempArray);
01172     }
01173     array_free(upperSystem->bwdSmoothVarsArray);
01174     upperSystem->bwdSmoothVarsArray = NIL(array_t);
01175   }
01176 
01177   FREE(upperSystem);
01178   return;
01179 }
01180 
01181 
01193 void
01194 Imc_LowerSystemInfoInitialize(
01195   Imc_Info_t *imcInfo,
01196   st_table   *latchNameTable)
01197 {
01198   int                   i, index;
01199   char                  *name;
01200   st_generator          *stGen;
01201   mdd_t                 *singleTR;
01202   Imc_LowerSystemInfo_t *lowerSystem;
01203   array_t               *tempArray;
01204   array_t               *relationArray;
01205   st_table              *globalLatchNameTable;
01206   array_t               *latchNameArray;
01207 
01208   lowerSystem = ALLOC(Imc_LowerSystemInfo_t, 1);
01209 
01210   if ((imcInfo->lowerMethod == Imc_LowerUniversalQuantification_c) &&
01211       (imcInfo->upperSystemInfo != NIL(Imc_UpperSystemInfo_t))){
01212     lowerSystem->bwdRealationArray = mdd_array_duplicate(
01213       imcInfo->upperSystemInfo->bwdRealationArray);
01214     lowerSystem->bwdSmoothVarsArray = array_alloc(array_t *,
01215       array_n(imcInfo->upperSystemInfo->bwdSmoothVarsArray));
01216     for (i=0;i<array_n(imcInfo->upperSystemInfo->bwdSmoothVarsArray);i++){
01217       tempArray =  array_fetch(array_t *,
01218         imcInfo->upperSystemInfo->bwdSmoothVarsArray, i);
01219       array_insert(array_t *, lowerSystem->bwdSmoothVarsArray, i,
01220         mdd_array_duplicate(tempArray));
01221     }
01222     lowerSystem->careStates = mdd_dup(imcInfo->modelCareStates);
01223     lowerSystem->bwdMinimizedRealationArray = NIL(array_t);
01224     imcInfo->lowerSystemInfo = lowerSystem;
01225     return;
01226   }
01227 
01228   globalLatchNameTable = imcInfo->systemInfo->latchNameTable;
01229 
01230   latchNameArray = array_alloc(char *, 0);
01231   st_foreach_item(globalLatchNameTable, stGen, &name, NIL(char *)){
01232     array_insert_last(char *, latchNameArray, name);
01233   }
01234 
01235   array_sort(latchNameArray, stringCompare);
01236 
01237   relationArray = array_alloc(mdd_t *, 0);
01238 
01239   for (i=0;i<array_n(latchNameArray);i++){
01240     name = array_fetch(char *, latchNameArray, i);
01241     st_lookup_int(globalLatchNameTable, name, (int *)&index);
01242     if (st_lookup(latchNameTable, name, NIL(char *))){
01243       singleTR = array_fetch(mdd_t *, imcInfo->systemInfo->TRArray, index);
01244     }else{
01245       singleTR = array_fetch(mdd_t *, imcInfo->systemInfo->lowerTRArray, index);
01246     }
01247     if (singleTR != NIL(mdd_t)){
01248       array_insert_last(mdd_t *, relationArray, singleTR);
01249     }
01250   }
01251 
01252   array_free(latchNameArray);
01253 
01254   Img_ClusterRelationArray(imcInfo->mddMgr, Img_Iwls95_c, Img_Backward_c,
01255                            relationArray,
01256                            imcInfo->systemInfo->psMddIdArray,
01257                            imcInfo->systemInfo->nsMddIdArray,
01258                            imcInfo->systemInfo->inputMddIdArray,
01259                            &lowerSystem->bwdRealationArray,
01260                            &lowerSystem->bwdSmoothVarsArray,
01261                            NIL(array_t *), 0); /* FIXED */
01262   lowerSystem->bwdMinimizedRealationArray = NIL(array_t);
01263 
01264   lowerSystem->careStates = mdd_dup(imcInfo->modelCareStates);;
01265 
01266   imcInfo->lowerSystemInfo = lowerSystem;
01267 
01268   if ((imcInfo->verbosity == Imc_VerbosityMin_c) ||
01269       (imcInfo->verbosity == Imc_VerbosityMax_c)){
01270     fprintf(vis_stdout, "IMC: |BWD Lower T| = %10ld BDD nodes (%-4d components)\n",
01271       bdd_size_multiple(lowerSystem->bwdRealationArray),
01272       array_n(lowerSystem->bwdRealationArray));
01273   }
01274 
01275   array_free(relationArray); /* Should be freed here, I guess, Chao Wang */
01276   
01277   return;
01278 }
01279 
01292 void
01293 Imc_LowerSystemMinimize(
01294   Imc_Info_t *imcInfo,
01295   mdd_t *careStates)
01296 {
01297   int i;
01298   mdd_t *singleTR;
01299   mdd_t *tempMdd;
01300 
01301   Imc_LowerSystemInfo_t *lowerSystem = imcInfo->lowerSystemInfo;
01302 
01303   if (mdd_equal(careStates,lowerSystem->careStates)) return;
01304 
01305   if (lowerSystem->bwdMinimizedRealationArray == NIL(array_t)){
01306     lowerSystem->bwdMinimizedRealationArray = 
01307       array_alloc(mdd_t *, array_n(lowerSystem->bwdRealationArray));
01308     for (i=0;i<array_n(lowerSystem->bwdRealationArray);i++){
01309       array_insert(mdd_t *, lowerSystem->bwdMinimizedRealationArray, i, NIL(mdd_t));
01310     }
01311   } 
01312 
01313   for (i=0;i<array_n(lowerSystem->bwdRealationArray);i++){
01314     singleTR = array_fetch(mdd_t *, lowerSystem->bwdMinimizedRealationArray, i);
01315     if (singleTR != NIL(mdd_t)){
01316       mdd_free(singleTR);
01317     }
01318     singleTR = array_fetch(mdd_t *, lowerSystem->bwdRealationArray, i);
01319     tempMdd = bdd_minimize(singleTR, careStates);
01320     array_insert(mdd_t *, lowerSystem->bwdMinimizedRealationArray, i, tempMdd);
01321   }
01322 
01323   if (lowerSystem->careStates != NIL(mdd_t)){
01324     mdd_free(lowerSystem->careStates);
01325   }
01326 
01327   lowerSystem->careStates = mdd_dup(careStates);
01328   if ((imcInfo->verbosity == Imc_VerbosityMin_c) ||
01329       (imcInfo->verbosity == Imc_VerbosityMax_c)){
01330     fprintf(vis_stdout, "IMC: |Minimized BWD Lower T| = %10ld BDD nodes (%-4d components)\n",
01331       bdd_size_multiple(lowerSystem->bwdMinimizedRealationArray),
01332       array_n(lowerSystem->bwdMinimizedRealationArray));
01333   }
01334 }
01335 
01336 
01348 void
01349 Imc_LowerSystemInfoFree(
01350   Imc_LowerSystemInfo_t *lowerSystem)
01351 {
01352   int i;
01353   array_t *tempArray;
01354 
01355   if (lowerSystem == NIL(Imc_LowerSystemInfo_t)) return;   
01356 
01357   if (lowerSystem->careStates != NIL(mdd_t)){
01358     mdd_free(lowerSystem->careStates);
01359   }
01360 
01361   if (lowerSystem->bwdRealationArray != NIL(array_t)){
01362     mdd_array_free(lowerSystem->bwdRealationArray);
01363     lowerSystem->bwdRealationArray = NIL(array_t);
01364   }
01365   if (lowerSystem->bwdMinimizedRealationArray != NIL(array_t)){
01366     mdd_array_free(lowerSystem->bwdMinimizedRealationArray);
01367     lowerSystem->bwdMinimizedRealationArray = NIL(array_t);
01368   }
01369   if (lowerSystem->bwdSmoothVarsArray != NIL(array_t)){
01370     for (i=0; i<array_n(lowerSystem->bwdSmoothVarsArray);i++){
01371       tempArray = array_fetch(array_t *, lowerSystem->bwdSmoothVarsArray, i);
01372       mdd_array_free(tempArray);
01373     }
01374     array_free(lowerSystem->bwdSmoothVarsArray);
01375     lowerSystem->bwdSmoothVarsArray = NIL(array_t); /* FIXED */
01376   }
01377 
01378   FREE(lowerSystem);
01379   return;
01380 }
01381 
01393 Imc_NodeInfo_t *
01394 Imc_NodeInfoInitialize(
01395   Imc_Polarity polarity)
01396 {
01397   Imc_NodeInfo_t *nodeInfo; 
01398 
01399   nodeInfo = ALLOC(Imc_NodeInfo_t, 1);
01400 
01401   nodeInfo->isExact = FALSE;
01402   nodeInfo->polarity = polarity;
01403   nodeInfo->upperSat = NIL(mdd_t);
01404   nodeInfo->lowerSat = NIL(mdd_t);
01405   nodeInfo->propagatedGoalSet = NIL(mdd_t);
01406   nodeInfo->propagatedGoalSetTrue = NIL(mdd_t);
01407   nodeInfo->goalSet = NIL(mdd_t);
01408   nodeInfo->goalSetTrue = NIL(mdd_t);
01409   nodeInfo->answer = Imc_VerificationInconclusive_c;
01410   nodeInfo->upperDone = FALSE;
01411   nodeInfo->lowerDone = FALSE;
01412   nodeInfo->pseudoEdges = NIL(mdd_t);
01413   return nodeInfo;
01414 }
01415 
01416 
01428 void
01429 Imc_NodeInfoReset(
01430   Imc_Info_t *imcInfo)
01431 {
01432   Ctlp_Formula_t *formula;
01433   st_table *nodeInfoTable = imcInfo->nodeInfoTable;
01434   st_generator *stGen;
01435   Imc_NodeInfo_t *nodeInfo;
01436 
01437   st_foreach_item(nodeInfoTable, stGen, &formula, &nodeInfo){
01438     if (!nodeInfo->isExact){
01439       nodeInfo->lowerDone = FALSE;
01440       nodeInfo->upperDone = FALSE;
01441     }
01442     if (nodeInfo->propagatedGoalSet != NIL(mdd_t)){
01443       mdd_free(nodeInfo->propagatedGoalSet);
01444       nodeInfo->propagatedGoalSet = NIL(mdd_t);
01445     }
01446     if (nodeInfo->propagatedGoalSetTrue != NIL(mdd_t)){
01447       mdd_free(nodeInfo->propagatedGoalSetTrue);
01448       nodeInfo->propagatedGoalSetTrue = NIL(mdd_t);
01449     }
01450     if (nodeInfo->goalSet != NIL(mdd_t)){
01451       mdd_free(nodeInfo->goalSet);
01452       nodeInfo->goalSet = NIL(mdd_t);
01453     }
01454     if (nodeInfo->goalSetTrue != NIL(mdd_t)){
01455       mdd_free(nodeInfo->goalSetTrue);
01456       nodeInfo->goalSetTrue = NIL(mdd_t);
01457     }
01458     if (nodeInfo->pseudoEdges != NIL(mdd_t)){
01459       mdd_free(nodeInfo->pseudoEdges);
01460       nodeInfo->pseudoEdges = NIL(mdd_t);
01461     }   
01462   }
01463 }
01464 
01465 
01477 void
01478 Imc_NodeInfoFree(
01479   Imc_NodeInfo_t *nodeInfo)
01480 {
01481   if (nodeInfo->upperSat != NIL(mdd_t)){
01482     mdd_free(nodeInfo->upperSat);
01483   }
01484   if (nodeInfo->lowerSat != NIL(mdd_t)){
01485     mdd_free(nodeInfo->lowerSat);
01486   }
01487   if (nodeInfo->goalSet != NIL(mdd_t)){
01488     mdd_free(nodeInfo->goalSet);
01489   }
01490   if (nodeInfo->goalSetTrue != NIL(mdd_t)){  
01491     mdd_free(nodeInfo->goalSetTrue);
01492   }
01493   if (nodeInfo->propagatedGoalSet != NIL(mdd_t)){
01494     mdd_free(nodeInfo->propagatedGoalSet);
01495   }
01496   if (nodeInfo->propagatedGoalSetTrue != NIL(mdd_t)){  
01497     mdd_free(nodeInfo->propagatedGoalSetTrue);
01498   }
01499   if (nodeInfo->pseudoEdges != NIL(mdd_t)){  
01500     mdd_free(nodeInfo->pseudoEdges);
01501   }
01502   FREE(nodeInfo);
01503 }
01504 
01505 
01517 void
01518 Imc_ImcPrintSystemSize(
01519   Imc_Info_t *imcInfo)
01520 {
01521   array_t *includedBooleanVars;
01522   array_t *psMddIdArray = imcInfo->systemInfo->psMddIdArray;
01523 
01524   includedBooleanVars = mdd_id_array_to_bdd_id_array(imcInfo->mddMgr,
01525                         psMddIdArray);
01526 
01527   fprintf(vis_stdout, "%d(%d) ",
01528           array_n(psMddIdArray), array_n(includedBooleanVars));
01529   fprintf(vis_stdout, "multi-value(boolean) latches.\n");
01530 
01531   array_free(includedBooleanVars);  
01532 }
01533 
01534 
01546 void
01547 Imc_ImcPrintApproxSystemSize(
01548   Imc_Info_t *imcInfo)
01549 {
01550   int i, index, psMddId;
01551   array_t *includedBooleanVars;
01552   array_t *includedPsMddIdArray;
01553   array_t *psMddIdArray = imcInfo->systemInfo->psMddIdArray;
01554   array_t *includedLatchIndex = imcInfo->systemInfo->includedLatchIndex;
01555   
01556   includedPsMddIdArray = array_alloc(int,array_n(includedLatchIndex));
01557 
01558   for(i=0;i<array_n(includedLatchIndex);i++){
01559     index = array_fetch(int,includedLatchIndex, i); 
01560     psMddId = array_fetch(int, psMddIdArray, index); 
01561     array_insert(int, includedPsMddIdArray, i, psMddId);
01562   }
01563  
01564   includedBooleanVars = mdd_id_array_to_bdd_id_array(imcInfo->mddMgr,
01565                         includedPsMddIdArray);
01566 
01567   fprintf(vis_stdout, "%d(%d) ",
01568           array_n(includedPsMddIdArray), array_n(includedBooleanVars));
01569   fprintf(vis_stdout, "multi-value(boolean) latches.\n");
01570 
01571   array_free(includedPsMddIdArray);
01572   array_free(includedBooleanVars);  
01573 }
01574 
01587 mdd_t *
01588 Imc_GetUpperSat(
01589   Imc_Info_t *imcInfo,
01590   Ctlp_Formula_t *formula)
01591 {
01592   Imc_NodeInfo_t *nodeInfo;
01593 
01594   if (!st_lookup(imcInfo->nodeInfoTable, formula, &nodeInfo)){
01595     return NIL(mdd_t); 
01596   }
01597 
01598   return nodeInfo->upperSat;
01599 }
01600 
01613 mdd_t *
01614 Imc_GetLowerSat(
01615   Imc_Info_t *imcInfo,
01616   Ctlp_Formula_t *formula)
01617 {
01618   Imc_NodeInfo_t *nodeInfo;
01619 
01620   if (!st_lookup(imcInfo->nodeInfoTable, formula, &nodeInfo)){
01621     return NIL(mdd_t); 
01622   }
01623 
01624   return nodeInfo->lowerSat;
01625 }
01626 
01640 int 
01641 Imc_ImcEvaluateCTLFormula(
01642   Imc_Info_t            *imcInfo,
01643   Ctlp_Formula_t        *ctlFormula, 
01644   Imc_Polarity          polarity)
01645 {
01646   Imc_Polarity newPolarity, approxPolarity;
01647   Ctlp_Formula_t *leftChild, *rightChild;
01648   Imc_NodeInfo_t *nodeInfo;
01649   Imc_GraphType graphType = imcInfo->graphType;
01650 
01651   if (Ctlp_FormulaReadType( ctlFormula ) == Ctlp_NOT_c){
01652     newPolarity = (polarity == Imc_PolarityNeg_c) ? Imc_PolarityPos_c: 
01653                   (polarity == Imc_PolarityPos_c) ? Imc_PolarityNeg_c:
01654                   polarity;
01655   }else{
01656     newPolarity = polarity;
01657   }
01658 
01659   if (graphType == Imc_GraphNDOG_c){
01660     /* In-Ho : Why change the polarity ? */
01661     approxPolarity = (polarity == Imc_PolarityNeg_c) ? Imc_PolarityPos_c:
01662                      Imc_PolarityNeg_c;
01663   }else{
01664     approxPolarity = polarity;
01665   } 
01666 
01667   if (!st_lookup(imcInfo->nodeInfoTable, ctlFormula, &nodeInfo)){
01668     nodeInfo = Imc_NodeInfoInitialize(polarity);
01669     st_insert(imcInfo->nodeInfoTable, ctlFormula, nodeInfo);
01670   }else if ((nodeInfo->isExact) ||
01671             ((approxPolarity == Imc_PolarityNeg_c) && (nodeInfo->lowerDone)) ||
01672             ((approxPolarity == Imc_PolarityPos_c) && (nodeInfo->upperDone))){
01673     if (imcInfo->verbosity == Imc_VerbosityMax_c){
01674       if ((Ctlp_FormulaReadType( ctlFormula ) == Ctlp_ID_c ) ||
01675           (Ctlp_FormulaReadType( ctlFormula ) == Ctlp_TRUE_c ) ||
01676           (Ctlp_FormulaReadType( ctlFormula ) == Ctlp_FALSE_c )){ 
01677         fprintf(vis_stdout, "IMC : node simple already computed.\n");
01678       }else if ((Ctlp_FormulaReadType( ctlFormula ) == Ctlp_AND_c ) ||
01679                 (Ctlp_FormulaReadType( ctlFormula ) == Ctlp_NOT_c )){ 
01680         fprintf(vis_stdout, "IMC : node boolean already computed.\n");
01681       }else{
01682         /* In-Ho : Why only ECTL? */
01683         fprintf(vis_stdout, "IMC : node ECTL already computed.\n");
01684       }
01685     }
01686     return 1;
01687   }
01688   
01689   leftChild = Ctlp_FormulaReadLeftChild(ctlFormula);
01690   if (leftChild) {
01691     if (!Imc_ImcEvaluateCTLFormula(imcInfo,leftChild,newPolarity)){
01692        return 0;
01693     } 
01694   }
01695   rightChild = Ctlp_FormulaReadRightChild(ctlFormula);
01696   if (rightChild) {
01697     if (!Imc_ImcEvaluateCTLFormula(imcInfo,rightChild,newPolarity)){ 
01698        return 0;
01699     } 
01700   }
01701 
01702   switch ( Ctlp_FormulaReadType( ctlFormula ) ) {
01703 
01704     case Ctlp_ID_c : 
01705       if (!ImcModelCheckAtomicFormula(imcInfo,ctlFormula)) return 0; 
01706       break;
01707     case Ctlp_TRUE_c : 
01708       if (!ImcModelCheckTrueFalseFormula(imcInfo,ctlFormula, TRUE)) return 0; 
01709       break;
01710     case Ctlp_FALSE_c : 
01711       if (!ImcModelCheckTrueFalseFormula(imcInfo,ctlFormula, FALSE)) return 0;
01712       break;
01713     case Ctlp_NOT_c :
01714       if ((approxPolarity == Imc_PolarityPos_c) || (graphType == Imc_GraphMOG_c)){
01715               if (!ImcModelCheckNotFormula(imcInfo,ctlFormula, TRUE)) return 0;
01716       }
01717       if ((approxPolarity == Imc_PolarityNeg_c) || (graphType == Imc_GraphMOG_c)){
01718               if(!ImcModelCheckNotFormula(imcInfo,ctlFormula, FALSE)) return 0;
01719       } 
01720       break;
01721     case Ctlp_AND_c :
01722       if ((approxPolarity == Imc_PolarityPos_c) || (graphType == Imc_GraphMOG_c)){       
01723         if (!ImcModelCheckAndFormula(imcInfo,ctlFormula,TRUE))return 0;
01724       }
01725       if ((approxPolarity == Imc_PolarityNeg_c) || (graphType == Imc_GraphMOG_c)){
01726         if (!ImcModelCheckAndFormula(imcInfo,ctlFormula,FALSE)) return 0;
01727       }   
01728       break;
01729     case Ctlp_EX_c :
01730       if ((approxPolarity == Imc_PolarityPos_c) || (graphType == Imc_GraphMOG_c)){
01731         if (!Imc_ImcEvaluateEXApprox(imcInfo,ctlFormula, TRUE, FALSE)) return 0;
01732       }
01733       if ((approxPolarity == Imc_PolarityNeg_c) || (graphType == Imc_GraphMOG_c)){
01734         if (!Imc_ImcEvaluateEXApprox(imcInfo,ctlFormula, FALSE, FALSE)) return 0;
01735       }
01736       break;
01737 
01738     case Ctlp_EU_c :
01739       if ((approxPolarity == Imc_PolarityPos_c) || (graphType == Imc_GraphMOG_c)){ 
01740         if (!Imc_ImcEvaluateEUApprox(imcInfo,ctlFormula,TRUE, FALSE)) return 0;
01741       }
01742       if ((approxPolarity == Imc_PolarityNeg_c) || (graphType == Imc_GraphMOG_c)){
01743         if (!Imc_ImcEvaluateEUApprox(imcInfo,ctlFormula, FALSE, FALSE)) return 0;
01744       }
01745       break;
01746 
01747     case Ctlp_EG_c :
01748       if ((approxPolarity == Imc_PolarityPos_c) || (graphType == Imc_GraphMOG_c)){
01749         if (!Imc_ImcEvaluateEGApprox(imcInfo,ctlFormula,TRUE, FALSE)) return 0;
01750       }
01751       if ((approxPolarity == Imc_PolarityNeg_c) || (graphType == Imc_GraphMOG_c)){
01752         if (!Imc_ImcEvaluateEGApprox(imcInfo,ctlFormula, FALSE, FALSE)) return 0;
01753       } 
01754       break;
01755 
01756     default: fail("Encountered unknown type of CTL formula\n");
01757   }
01758 
01759   if (nodeInfo->upperDone && nodeInfo->lowerDone){
01760     if (!nodeInfo->isExact && mdd_equal_mod_care_set(nodeInfo->upperSat, 
01761          nodeInfo->lowerSat, imcInfo->modelCareStates)){ /* FIXED */
01762       nodeInfo->isExact = TRUE;
01763     }
01764   }
01765 
01766   return 1;
01767 }
01768 
01782 int
01783 Imc_ImcEvaluateEXApprox(
01784   Imc_Info_t *imcInfo,
01785   Ctlp_Formula_t *formula,
01786   boolean isUpper,
01787   boolean isRecomputation)
01788 {
01789   mdd_t *targetStates;
01790   Ctlp_Formula_t *leftChild;
01791   mdd_t *result = NIL(mdd_t);
01792   mdd_t *tempResult;
01793   mdd_t *localCareStates;
01794   mdd_t *globalCareStates;
01795   boolean useLocalCare = FALSE;
01796   Imc_NodeInfo_t *nodeInfo, *lNodeInfo;
01797   boolean isExact;
01798   
01799   globalCareStates = imcInfo->modelCareStates;
01800 
01801   if (!st_lookup(imcInfo->nodeInfoTable, formula, &nodeInfo)){
01802     fprintf(vis_stdout, "** imc error : EX nodeinfo is not initilize.\n");
01803     return 0;
01804   }
01805 
01806   leftChild = Ctlp_FormulaReadLeftChild(formula);
01807   if (!st_lookup(imcInfo->nodeInfoTable, leftChild, &lNodeInfo)){
01808     fprintf(vis_stdout, "** imc error : EX left nodeinfo is not initilize.\n");
01809     return 0;
01810   }
01811 
01812   if ( imcInfo->verbosity == Imc_VerbosityMax_c ){      
01813      if (isUpper){
01814       fprintf(vis_stdout, "IMC :  SAT(EX)+ computation start.\n");
01815     }else{
01816       fprintf(vis_stdout, "IMC :  SAT(EX)- computation start.\n");
01817     }
01818   }
01819 
01820   /*
01821    * If exact sat is already computed from other side of approximation,
01822    * use it.
01823    */
01824   if (nodeInfo->isExact){
01825     if ( imcInfo->verbosity == Imc_VerbosityMax_c ){      
01826       if (isUpper){
01827         fprintf(vis_stdout, "IMC :  SAT(EX)+ computation end.\n");
01828       }else{
01829         fprintf(vis_stdout, "IMC :  SAT(EX)- computation end.\n");
01830       }
01831     }
01832     return 1;
01833   }
01834 
01835 
01836   /*
01837    * If this is not for recomputation, do general satisfying states computation.
01838    * Otherwise, compute the subset of the propagated goalset where the formula
01839    * satisfies.
01840    * Test if tighter satisfying don't care states(ASDC) can be used to reduce
01841    * transition sub-relations.
01842    */
01843   if (nodeInfo->upperSat != NIL(mdd_t)){
01844     localCareStates = mdd_and(nodeInfo->upperSat,globalCareStates, 1, 1); 
01845   }else{
01846     localCareStates = mdd_dup(globalCareStates);
01847   }
01848 
01849   if ((mdd_lequal(localCareStates,globalCareStates, 1, 1)) &&
01850       (!mdd_equal(localCareStates,globalCareStates))){
01851     useLocalCare = TRUE;
01852   }
01853 
01854   if (!isRecomputation){
01855     if (isUpper){
01856       targetStates = lNodeInfo->upperSat;
01857     }else{
01858       targetStates = lNodeInfo->lowerSat;
01859     }
01860   }else{
01861     targetStates = lNodeInfo->propagatedGoalSetTrue;
01862   }
01863 
01864   if (targetStates == NIL(mdd_t)) return 0;
01865 
01866   if ((isUpper)|| (isRecomputation)) 
01867     Imc_UpperSystemMinimize(imcInfo, localCareStates);
01868   else
01869     Imc_LowerSystemMinimize(imcInfo, localCareStates);  
01870 
01871   if ((isUpper) || (isRecomputation)){
01872     tempResult = Imc_ComputeUpperPreimage(imcInfo, localCareStates, targetStates, 
01873                                           &isExact);
01874   }else{
01875     tempResult = Imc_ComputeLowerPreimage(imcInfo, localCareStates, targetStates, 
01876                                           &isExact);
01877   }
01878 
01879   if (tempResult == NIL(mdd_t)) return 0;
01880 
01881   if ((imcInfo->verbosity == Imc_VerbosityMax_c) ||
01882       (imcInfo->verbosity == Imc_VerbosityMin_c)) {
01883     mdd_t *tmpMdd = mdd_and(tempResult, localCareStates, 1, 1 );
01884     double minterm = mdd_count_onset(imcInfo->mddMgr, tmpMdd, 
01885               imcInfo->systemInfo->psMddIdArray);
01886     if (isUpper){
01887       fprintf(vis_stdout, "IMC : |SAT(EX)+| = %.0f (%10g)\n", minterm, minterm);
01888     }else{
01889       fprintf(vis_stdout, "IMC : |SAT(EX)-| = %.0f (%10g)\n", minterm, minterm);
01890     }
01891     mdd_free(tmpMdd);
01892   }
01893 
01894   if (useLocalCare){
01895      result = mdd_and(tempResult, localCareStates, 1, 1); 
01896      mdd_free(tempResult);
01897      tempResult = bdd_minimize(result, globalCareStates);
01898      mdd_free(result);
01899      result = tempResult;
01900   }else{
01901      result = tempResult;
01902   }
01903 
01904   mdd_free(localCareStates);
01905 
01906   if (isRecomputation){
01907     tempResult = mdd_and(nodeInfo->goalSet, result, 1, 1);
01908     mdd_free(result);
01909     nodeInfo->propagatedGoalSetTrue = 
01910       mdd_or(nodeInfo->goalSetTrue, tempResult, 1, 1);
01911     mdd_free(tempResult);
01912     return 1;
01913   }
01914 
01915   if (isUpper){
01916     if (nodeInfo->upperSat != NIL(mdd_t)){
01917       mdd_free(nodeInfo->upperSat);
01918     }
01919     nodeInfo->upperSat = result;
01920     nodeInfo->upperDone = TRUE;
01921   }else{
01922     if (nodeInfo->lowerSat != NIL(mdd_t)){
01923       tempResult = mdd_or(nodeInfo->lowerSat, result, 1, 1);
01924       mdd_free(nodeInfo->lowerSat);
01925       mdd_free(result);
01926       result = tempResult;
01927     }
01928     nodeInfo->lowerSat = result;
01929     nodeInfo->lowerDone = TRUE;
01930   }
01931 
01932   if ( imcInfo->verbosity == Imc_VerbosityMax_c ){      
01933     if (isUpper){
01934       fprintf(vis_stdout, "IMC :  SAT(EX)+ computation end.\n");
01935     }else{
01936       fprintf(vis_stdout, "IMC :  SAT(EX)- computation end.\n");
01937     }
01938   }
01939 
01940   if (lNodeInfo->isExact && isExact){
01941     nodeInfo->isExact = TRUE;
01942     if ( imcInfo->verbosity == Imc_VerbosityMax_c ){
01943       if (isUpper){
01944         fprintf(vis_stdout, "IMC :  SAT(EX)+ computation is exact.\n");
01945       }else{
01946         fprintf(vis_stdout, "IMC :  SAT(EX)- computation is exact.\n");
01947       }
01948     }      
01949     if (isUpper){
01950       if (nodeInfo->lowerSat != NIL(mdd_t)) mdd_free(nodeInfo->lowerSat);
01951       nodeInfo->lowerSat = mdd_dup(nodeInfo->upperSat);
01952       nodeInfo->lowerDone = TRUE;
01953     }else{
01954       if (nodeInfo->upperSat != NIL(mdd_t)) mdd_free(nodeInfo->upperSat);
01955       nodeInfo->upperSat = mdd_dup(nodeInfo->lowerSat);
01956       nodeInfo->upperDone = TRUE;
01957     } 
01958   }else{
01959     nodeInfo->isExact = FALSE;
01960   }  
01961 
01962   return 1;
01963 }
01964 
01978 int
01979 Imc_ImcEvaluateEUApprox(
01980   Imc_Info_t *imcInfo,
01981   Ctlp_Formula_t *formula,
01982   boolean isUpper,
01983   boolean isRecomputation)
01984 {
01985   mdd_t *localCareStates;
01986   mdd_t *targetStates, *invariantStates;
01987   mdd_t *aMdd, *bMdd, *cMdd;
01988   mdd_t *result;
01989   mdd_t *tmpMdd1, *tmpMdd2;
01990   mdd_t * globalCareStates;
01991   double size1, size2;
01992   Ctlp_Formula_t *lFormula, *rFormula;
01993   Imc_NodeInfo_t *nodeInfo, *lNodeInfo, *rNodeInfo;
01994   boolean isExact, globalIsExact;
01995 
01996   globalIsExact = TRUE;
01997   globalCareStates = imcInfo->modelCareStates;
01998   lFormula = Ctlp_FormulaReadLeftChild(formula);
01999   rFormula = Ctlp_FormulaReadRightChild(formula);
02000 
02001   if (!st_lookup(imcInfo->nodeInfoTable, formula, &nodeInfo)){
02002     fprintf(vis_stdout, "** imc error : EU nodeinfo is not initilize.\n");
02003     return 0;
02004   }
02005   if (!st_lookup(imcInfo->nodeInfoTable, lFormula, &lNodeInfo)){
02006     fprintf(vis_stdout, "** imc error : EU left nodeinfo is not initilize.\n");
02007     return 0;
02008   }
02009   if (!st_lookup(imcInfo->nodeInfoTable, rFormula, &rNodeInfo)){
02010     fprintf(vis_stdout, "** imc error : EU right nodeinfo is not initilize.\n");
02011     return 0;
02012   }
02013 
02014   if ( imcInfo->verbosity == Imc_VerbosityMax_c ){      
02015     if (isUpper){
02016       fprintf(vis_stdout, "IMC :  SAT(EU)+ computation start.\n");
02017     }else{
02018       fprintf(vis_stdout, "IMC :  SAT(EU)- computation start.\n");
02019     }
02020   }
02021 
02022   /*
02023    * If exact sat is already computed from other side of approximation,
02024    * use it.
02025    */
02026   if (nodeInfo->isExact){
02027     if ( imcInfo->verbosity == Imc_VerbosityMax_c ){      
02028       if (isUpper){
02029         fprintf(vis_stdout, "IMC :  SAT(EU)+ computation end.\n");
02030       }else{
02031         fprintf(vis_stdout, "IMC :  SAT(EU)- computation end.\n");
02032       }
02033     }
02034     return 1;
02035   }
02036 
02037 
02038   /*
02039    * Test if tighter satisfying don't care states(ASDC) can be used to reduce
02040    * transition sub-relations.
02041    */
02042   
02043   if (nodeInfo->upperSat != NIL(mdd_t)){
02044     localCareStates = mdd_and(nodeInfo->upperSat,globalCareStates, 1, 1); 
02045   }else{
02046     localCareStates = mdd_dup(globalCareStates);
02047   }
02048 
02049   if ((mdd_lequal(localCareStates,globalCareStates, 1, 1)) &&
02050       (!mdd_equal(localCareStates,globalCareStates))){
02051   }
02052 
02053   if (!isRecomputation){
02054     if (isUpper){
02055       if (nodeInfo->lowerSat != NIL(mdd_t)){
02056         targetStates = mdd_or(rNodeInfo->upperSat, nodeInfo->lowerSat, 1, 1);
02057       }else{
02058         targetStates = mdd_dup(rNodeInfo->upperSat);
02059       }
02060       invariantStates = lNodeInfo->upperSat;
02061     }else{
02062       targetStates = mdd_dup(rNodeInfo->lowerSat);
02063       invariantStates = lNodeInfo->lowerSat;
02064     }
02065   }else{
02066     targetStates = mdd_dup(rNodeInfo->propagatedGoalSetTrue);
02067     invariantStates = lNodeInfo->propagatedGoalSetTrue;    
02068   }
02069 
02070   result = targetStates;
02071 
02072   if ((isUpper) || (isRecomputation))
02073     Imc_UpperSystemMinimize(imcInfo, localCareStates);
02074   else
02075     Imc_LowerSystemMinimize(imcInfo, localCareStates);
02076 
02077   while (TRUE) { 
02078 
02079     if (isUpper){
02080       aMdd = Imc_ComputeUpperPreimage(imcInfo, localCareStates, 
02081                                       result, &isExact);      
02082     }else{
02083       aMdd = Imc_ComputeLowerPreimage(imcInfo, localCareStates, 
02084                                       result, &isExact);
02085     }
02086     if (aMdd == NIL(mdd_t)) return 0;
02087 
02088     globalIsExact = (globalIsExact && isExact);
02089 
02090     bMdd = mdd_and( aMdd, invariantStates, 1, 1 );
02091     mdd_free( aMdd );
02092     aMdd = mdd_and(bMdd, localCareStates, 1, 1);
02093     mdd_free(bMdd);
02094     bMdd = bdd_minimize(aMdd, globalCareStates);
02095     mdd_free(aMdd);
02096     cMdd = mdd_or(result, bMdd, 1, 1);
02097     mdd_free( bMdd );
02098     
02099     tmpMdd1 = mdd_and( result, globalCareStates, 1, 1 );
02100     tmpMdd2 = mdd_and( cMdd, globalCareStates, 1, 1 );
02101     if (mdd_equal(tmpMdd1, tmpMdd2)){
02102       mdd_free(cMdd);
02103       break;
02104     }else if (mdd_equal(tmpMdd2, localCareStates)){ 
02105       mdd_free(result);
02106       result = cMdd;     
02107       break;
02108     }else if (( imcInfo->verbosity == Imc_VerbosityMax_c ) ||
02109               (imcInfo->verbosity == Imc_VerbosityMin_c)) { 
02110       size1 = mdd_count_onset(imcInfo->mddMgr, tmpMdd1,
02111                                imcInfo->systemInfo->psMddIdArray);
02112       size2 = mdd_count_onset(imcInfo->mddMgr, tmpMdd2,
02113                                imcInfo->systemInfo->psMddIdArray);
02114       if (isUpper){
02115         fprintf(vis_stdout, "IMC : |SAT(EU)+| = %.0f (%10g)-> %.0f (%10g)\n", 
02116                 size1, size1, size2, size2);
02117       }else{
02118         fprintf(vis_stdout, "IMC : |SAT(EU)-| = %.0f (%10g)-> %.0f (%10g)\n", 
02119                 size1, size1, size2, size2);
02120       }
02121     }      
02122     mdd_free(tmpMdd1);
02123     mdd_free(tmpMdd2);
02124 
02125     mdd_free( result );
02126     result = bdd_minimize(cMdd, globalCareStates);
02127     mdd_free(cMdd);
02128   }
02129 
02130   if ((imcInfo->verbosity == Imc_VerbosityMax_c) ||
02131       (imcInfo->verbosity == Imc_VerbosityMin_c)) {
02132     size1 = mdd_count_onset(imcInfo->mddMgr, tmpMdd1,
02133                              imcInfo->systemInfo->psMddIdArray);
02134     size2 = mdd_count_onset(imcInfo->mddMgr, tmpMdd2,
02135                        imcInfo->systemInfo->psMddIdArray);    
02136     if (isUpper){
02137       fprintf(vis_stdout, "IMC : |SAT(EU)+| = %.0f (%10g)-> %.0f (%10g)\n", 
02138               size1, size1, size2, size2);
02139     }else{
02140       fprintf(vis_stdout, "IMC : |SAT(EU)-| = %.0f (%10g)-> %.0f (%10g)\n", 
02141               size1, size1, size2, size2);
02142     }
02143   }
02144 
02145   mdd_free(tmpMdd1);
02146   mdd_free(tmpMdd2);
02147 
02148   mdd_free(localCareStates);
02149 
02150   if (isRecomputation){
02151     tmpMdd1 = mdd_and(nodeInfo->goalSet, result, 1, 1);
02152     mdd_free(result);
02153     nodeInfo->propagatedGoalSetTrue = mdd_or(nodeInfo->goalSetTrue, tmpMdd1, 1, 1);
02154     mdd_free(tmpMdd1);
02155     return 1;
02156   }
02157 
02158   if (isUpper){
02159     if (nodeInfo->upperSat != NIL(mdd_t)){
02160       mdd_free(nodeInfo->upperSat);
02161     }
02162     nodeInfo->upperSat = result;
02163     nodeInfo->upperDone = TRUE;
02164   }else{
02165     if (nodeInfo->lowerSat != NIL(mdd_t)){
02166       tmpMdd1 = mdd_or(nodeInfo->lowerSat, result, 1, 1);
02167       mdd_free(nodeInfo->lowerSat);
02168       mdd_free(result);
02169       result = tmpMdd1;
02170     }
02171     nodeInfo->lowerSat = result;
02172     nodeInfo->lowerDone = TRUE;
02173   } 
02174 
02175   if ( imcInfo->verbosity == Imc_VerbosityMax_c ){      
02176     if (isUpper){
02177       fprintf(vis_stdout, "IMC :  SAT(EU)+ computation end.\n");
02178     }else{
02179       fprintf(vis_stdout, "IMC :  SAT(EU)- computation end.\n");
02180     }
02181   }
02182 
02183   if (lNodeInfo->isExact && rNodeInfo->isExact && globalIsExact){
02184     nodeInfo->isExact = TRUE;
02185     if ( imcInfo->verbosity == Imc_VerbosityMax_c ){
02186       if (isUpper){
02187         fprintf(vis_stdout, "IMC :  SAT(EU)+ computation is exact.\n");
02188       }else{
02189         fprintf(vis_stdout, "IMC :  SAT(EU)- computation is exact.\n");
02190       }
02191     }   
02192     if (isUpper){
02193       if (nodeInfo->lowerSat != NIL(mdd_t)) mdd_free(nodeInfo->lowerSat);
02194       nodeInfo->lowerSat = mdd_dup(nodeInfo->upperSat);
02195       nodeInfo->lowerDone = TRUE;
02196     }else{
02197       if (nodeInfo->upperSat != NIL(mdd_t)) mdd_free(nodeInfo->upperSat);
02198       nodeInfo->upperSat = mdd_dup(nodeInfo->lowerSat);
02199       nodeInfo->upperDone = TRUE;
02200     } 
02201   }else{
02202     nodeInfo->isExact = FALSE;
02203   } 
02204 
02205   return 1;
02206 }
02207 
02219 int
02220 Imc_ImcEvaluateEGApprox( 
02221   Imc_Info_t *imcInfo,
02222   Ctlp_Formula_t *formula,
02223   boolean isUpper,
02224   boolean isRecomputation)
02225 {
02226   mdd_t *Zmdd;
02227   mdd_t *bMdd;
02228   mdd_t *ZprimeMdd;
02229   mdd_t *tmpMdd1, *tmpMdd2;
02230   mdd_t *result;
02231   mdd_t *localCareStates;
02232   mdd_t *globalCareStates;
02233   mdd_t *invariantStates;
02234   double size1, size2;
02235   Ctlp_Formula_t *lFormula;
02236   Imc_NodeInfo_t *nodeInfo, *lNodeInfo;
02237   boolean isExact, globalIsExact;
02238   
02239 
02240   lFormula = Ctlp_FormulaReadLeftChild(formula);
02241 
02242   if (!st_lookup(imcInfo->nodeInfoTable, formula, &nodeInfo)){
02243     fprintf(vis_stdout, "** imc error : EG nodeinfo is not initilize.\n");
02244     return 0;
02245   }
02246   if (!st_lookup(imcInfo->nodeInfoTable, lFormula, &lNodeInfo)){
02247     fprintf(vis_stdout, "** imc error : EG left nodeinfo is not initilize.\n");
02248     return 0;
02249   }
02250 
02251   if ( imcInfo->verbosity == Imc_VerbosityMax_c ){      
02252     if (isUpper){
02253       fprintf(vis_stdout, "IMC :  SAT(EG)+ computation start.\n");
02254     }else{
02255       fprintf(vis_stdout, "IMC :  SAT(EG)- computation start.\n");
02256     }
02257   }
02258 
02259   /*
02260    * If exact sat is already computed from other side of approximation,
02261    * use it.
02262    */
02263   if (nodeInfo->isExact){
02264     if ( imcInfo->verbosity == Imc_VerbosityMax_c ){      
02265       if (isUpper){
02266         fprintf(vis_stdout, "IMC :  SAT(EG)+ computation end.\n");
02267       }else{
02268         fprintf(vis_stdout, "IMC :  SAT(EG)- computation end.\n");
02269       }
02270     }
02271     return 1;
02272   }
02273 
02274   globalCareStates = imcInfo->modelCareStates;
02275 
02276   /*
02277    * Test if tighter satisfying don't care states(ASDC) can be used to reduce
02278    * transition sub-relations.
02279    */
02280   if (nodeInfo->upperSat != NIL(mdd_t)){ 
02281     localCareStates = mdd_and(nodeInfo->upperSat,globalCareStates, 1, 1); 
02282   }else{
02283     localCareStates = mdd_dup(globalCareStates);
02284   }
02285 
02286   if ((mdd_lequal(localCareStates,globalCareStates, 1, 1)) &&
02287       (!mdd_equal(localCareStates,globalCareStates))){
02288   }
02289 
02290   if (!isRecomputation){
02291     if (isUpper){
02292       if (nodeInfo->upperSat != NIL(mdd_t)){
02293         invariantStates = mdd_and(lNodeInfo->upperSat, nodeInfo->upperSat,1,1);
02294       }else{
02295         invariantStates = mdd_dup(lNodeInfo->upperSat);
02296       } 
02297     }else{
02298       if (nodeInfo->upperSat != NIL(mdd_t)){
02299         invariantStates = mdd_and(lNodeInfo->lowerSat, nodeInfo->upperSat,1,1);
02300       }else{
02301         invariantStates = mdd_dup(lNodeInfo->lowerSat);
02302       }
02303     }
02304   }else{
02305     invariantStates = mdd_dup(lNodeInfo->propagatedGoalSetTrue);
02306   }
02307 
02308   Zmdd = mdd_dup(invariantStates);
02309   ZprimeMdd = NIL(mdd_t);
02310 
02311   globalIsExact = TRUE;
02312 
02313   if ((isUpper) || (isRecomputation))
02314     Imc_UpperSystemMinimize(imcInfo, localCareStates);
02315   else
02316     Imc_LowerSystemMinimize(imcInfo, localCareStates);
02317 
02318   while (TRUE) {
02319 
02320     if (isUpper){
02321       bMdd = Imc_ComputeUpperPreimage(imcInfo, localCareStates, 
02322                                       Zmdd, &isExact);
02323     }else{
02324       bMdd = Imc_ComputeLowerPreimage(imcInfo, localCareStates, 
02325                                       Zmdd, &isExact);
02326     }
02327     if (bMdd == NIL(mdd_t)){
02328       mdd_free(invariantStates);
02329       mdd_free(Zmdd);
02330       if (ZprimeMdd !=NIL(mdd_t)) mdd_free(ZprimeMdd);
02331       return 0;
02332     }
02333 
02334     ZprimeMdd = mdd_and(Zmdd, bMdd, 1, 1);
02335     globalIsExact = (globalIsExact && isExact);
02336 
02337     mdd_free(bMdd);
02338     
02339     tmpMdd1 = mdd_and( Zmdd, globalCareStates, 1, 1 );
02340     tmpMdd2 = mdd_and( ZprimeMdd, localCareStates, 1, 1 );
02341 
02342     mdd_free(Zmdd);
02343     mdd_free(ZprimeMdd);
02344 
02345     if ((mdd_equal(tmpMdd1, tmpMdd2)) ||
02346         (mdd_is_tautology(tmpMdd2, 0))){
02347       break;
02348     }else if (( imcInfo->verbosity == Imc_VerbosityMax_c ) ||
02349               (imcInfo->verbosity == Imc_VerbosityMin_c)) {      
02350       size1 = mdd_count_onset(imcInfo->mddMgr, tmpMdd1,
02351                                imcInfo->systemInfo->psMddIdArray);
02352       size2 = mdd_count_onset(imcInfo->mddMgr, tmpMdd2,
02353                                imcInfo->systemInfo->psMddIdArray);
02354       if (isUpper){
02355         fprintf(vis_stdout, "IMC : |SAT(EG)+| = %.0f (%10g)-> %.0f (%10g)\n", 
02356                 size1, size1, size2, size2);
02357       }else{
02358         fprintf(vis_stdout, "IMC : |SAT(EG)-| = %.0f (%10g)-> %.0f (%10g)\n", 
02359                 size1, size1, size2, size2);
02360       }
02361     }
02362 
02363     mdd_free(tmpMdd1);
02364     Zmdd = bdd_minimize(tmpMdd2, globalCareStates);
02365     mdd_free(tmpMdd2);
02366   }
02367         
02368   if (( imcInfo->verbosity == Imc_VerbosityMax_c ) ||
02369       (imcInfo->verbosity == Imc_VerbosityMin_c)) {
02370     size1 = mdd_count_onset(imcInfo->mddMgr, tmpMdd1,
02371                              imcInfo->systemInfo->psMddIdArray);
02372     size2 = mdd_count_onset(imcInfo->mddMgr, tmpMdd2,
02373                              imcInfo->systemInfo->psMddIdArray);
02374     if (isUpper){
02375       fprintf(vis_stdout, "IMC : |SAT(EG)+| = %.0f (%10g)-> %.0f (%10g)\n", 
02376               size1, size1, size2, size2);
02377     }else{
02378       fprintf(vis_stdout, "IMC : |SAT(EG)-| = %.0f (%10g)-> %.0f (%10g)\n", 
02379               size1, size1, size2, size2);
02380     }
02381   }
02382 
02383   mdd_free(tmpMdd1);
02384   mdd_free(localCareStates);
02385 
02386   result = bdd_minimize(tmpMdd2, globalCareStates);
02387   mdd_free(tmpMdd2);
02388 
02389   if (isRecomputation){
02390     tmpMdd1 = mdd_and(nodeInfo->goalSet, result, 1, 1);
02391     mdd_free(result);
02392     nodeInfo->propagatedGoalSetTrue = mdd_or(nodeInfo->goalSetTrue,tmpMdd1,1,1);
02393     mdd_free(tmpMdd1);
02394     return 1;
02395   }
02396 
02397   mdd_free(invariantStates);
02398 
02399   if (isUpper){
02400     if (nodeInfo->upperSat != NIL(mdd_t)){
02401       mdd_free(nodeInfo->upperSat);
02402     }
02403     nodeInfo->upperSat = result;
02404     nodeInfo->upperDone = TRUE;
02405   }else{
02406     if (nodeInfo->lowerSat != NIL(mdd_t)){
02407       tmpMdd1 = mdd_or(nodeInfo->lowerSat, result, 1, 1);
02408       mdd_free(nodeInfo->lowerSat);
02409       mdd_free(result);
02410       result = bdd_minimize(tmpMdd1, globalCareStates);
02411       mdd_free(tmpMdd1);
02412     }
02413     nodeInfo->lowerSat = result;
02414     nodeInfo->lowerDone = TRUE;
02415   } 
02416 
02417   if ( imcInfo->verbosity == Imc_VerbosityMax_c ){      
02418     if (isUpper){
02419       fprintf(vis_stdout, "IMC :  SAT(EG)+ computation end.\n");
02420     }else{
02421       fprintf(vis_stdout, "IMC :  SAT(EG)- computation end.\n");
02422     }
02423   }
02424 
02425   if (lNodeInfo->isExact && globalIsExact){
02426     nodeInfo->isExact = TRUE;
02427     if ( imcInfo->verbosity == Imc_VerbosityMax_c ){
02428       if (isUpper){
02429         fprintf(vis_stdout, "IMC :  SAT(EG)+ computation is exact.\n");
02430       }else{
02431         fprintf(vis_stdout, "IMC :  SAT(EG)- computation is exact.\n");
02432       }
02433     }    
02434     if (isUpper){
02435       if (nodeInfo->lowerSat != NIL(mdd_t)) mdd_free(nodeInfo->lowerSat);
02436       nodeInfo->lowerSat = mdd_dup(nodeInfo->upperSat);
02437       nodeInfo->lowerDone = TRUE;
02438     }else{
02439       if (nodeInfo->upperSat != NIL(mdd_t)) mdd_free(nodeInfo->upperSat);
02440       nodeInfo->upperSat = mdd_dup(nodeInfo->lowerSat);
02441       nodeInfo->upperDone = TRUE;
02442     } 
02443   }else{
02444     nodeInfo->isExact = FALSE;
02445   } 
02446 
02447   return 1;
02448 }
02449 
02460 mdd_t *
02461 Imc_ComputeUpperPreimage(
02462   Imc_Info_t *imcInfo,
02463   mdd_t *rangeCareStates,
02464   mdd_t *targetStates,
02465   boolean *isExact)
02466 {
02467   if (imcInfo->upperMethod == Imc_UpperExistentialQuantification_c){
02468     return Imc_ComputeApproxPreimageByQuantification(imcInfo, rangeCareStates,
02469              targetStates, isExact, FALSE);
02470   }
02471 
02472   return NIL(mdd_t);
02473 }
02474 
02475 
02486 mdd_t *
02487 Imc_ComputeApproxPreimageByQuantification(
02488   Imc_Info_t *imcInfo, 
02489   mdd_t *rangeCareStates, 
02490   mdd_t *targetStates,
02491   boolean *isExact,
02492   boolean computeLower)
02493 {
02494   int i;
02495   int psMddId;
02496   double orgSize, newSize;
02497   mdd_t *result;
02498   mdd_t *nextTarget;
02499   mdd_t *reducedTarget;
02500   mdd_t *tempMdd;
02501   mdd_t *reducedTargetInCare;
02502   mdd_t *targetInCare;
02503   array_t *supportArray;
02504 
02505   *isExact = TRUE;
02506   if (mdd_is_tautology(targetStates, 0)){
02507     return mdd_zero(imcInfo->mddMgr);
02508   }
02509 
02510   supportArray = mdd_get_support(imcInfo->mddMgr, targetStates);
02511 
02512   for(i=0;i<array_n(supportArray);i++){
02513     psMddId = array_fetch(int, supportArray, i);
02514     if (st_is_member(imcInfo->systemInfo->excludedPsMddIdTable, 
02515                      (char *)(long)psMddId)){
02516       *isExact = FALSE;
02517       break;
02518     }
02519   }
02520   array_free(supportArray);
02521  
02522   if (array_n(imcInfo->systemInfo->excludedPsMddId) >0){
02523     if (!computeLower){
02524       reducedTarget = mdd_smooth(imcInfo->mddMgr, targetStates, 
02525                                imcInfo->systemInfo->excludedPsMddId);
02526     }else{
02527       reducedTarget = mdd_consensus(imcInfo->mddMgr, targetStates, 
02528                                imcInfo->systemInfo->excludedPsMddId);
02529     }
02530     if ((mdd_is_tautology(reducedTarget,1)) || (mdd_is_tautology(reducedTarget,0))){
02531       return reducedTarget;
02532     }
02533   }else{
02534     reducedTarget = mdd_dup(targetStates);
02535   }
02536 
02537   if (imcInfo->verbosity == Imc_VerbosityMax_c){
02538     targetInCare = mdd_and(targetStates, imcInfo->modelCareStates, 1, 1);
02539     reducedTargetInCare = mdd_and(reducedTarget, imcInfo->modelCareStates, 1, 1);
02540     orgSize = mdd_count_onset(imcInfo->mddMgr, targetInCare,
02541                         imcInfo->systemInfo->psMddIdArray);
02542     newSize = mdd_count_onset(imcInfo->mddMgr, reducedTargetInCare,
02543                           imcInfo->systemInfo->psMddIdArray);
02544     if (!computeLower){
02545       fprintf(vis_stdout, "IMC : Upper Approximation    |S| = %.0f (%10g)-> %.0f (%10g)\n",
02546               orgSize, orgSize, newSize, newSize);
02547     }else{
02548       fprintf(vis_stdout, "IMC : Lower Approximation    |S| = %.0f (%10g)-> %.0f (%10g)\n",
02549               orgSize, orgSize, newSize, newSize);
02550     }
02551     mdd_free(targetInCare);
02552     mdd_free(reducedTargetInCare);
02553   }
02554 
02555   nextTarget = mdd_substitute(imcInfo->mddMgr, reducedTarget,
02556                               imcInfo->systemInfo->psMddIdArray,
02557                               imcInfo->systemInfo->nsMddIdArray);
02558 
02559   mdd_free(reducedTarget);
02560 
02561   if (!computeLower){
02562     if (imcInfo->upperSystemInfo->bwdMinimizedRealationArray == NIL(array_t)){
02563       result = Imc_ProductAbstract(imcInfo->mddMgr, 
02564                                    imcInfo->upperSystemInfo->bwdRealationArray,
02565                                    imcInfo->upperSystemInfo->bwdSmoothVarsArray,
02566                                    nextTarget);
02567     }else{
02568       result = Imc_ProductAbstract(imcInfo->mddMgr, 
02569                                    imcInfo->upperSystemInfo->bwdMinimizedRealationArray,
02570                                    imcInfo->upperSystemInfo->bwdSmoothVarsArray,
02571                                    nextTarget);
02572     }
02573   }else{
02574     if (imcInfo->lowerSystemInfo->bwdMinimizedRealationArray == NIL(array_t)){
02575       result = Imc_ProductAbstract(imcInfo->mddMgr, 
02576                                    imcInfo->lowerSystemInfo->bwdRealationArray,
02577                                    imcInfo->lowerSystemInfo->bwdSmoothVarsArray,
02578                                    nextTarget);
02579     }else{
02580       result = Imc_ProductAbstract(imcInfo->mddMgr, 
02581                                    imcInfo->lowerSystemInfo->bwdMinimizedRealationArray,
02582                                    imcInfo->lowerSystemInfo->bwdSmoothVarsArray,
02583                                    nextTarget);
02584     }
02585   }
02586 
02587   mdd_free(nextTarget);
02588 
02589   if (imcInfo->verbosity == Imc_VerbosityMax_c){
02590     double exactSize, approxSize;
02591     tempMdd = mdd_and(result, rangeCareStates, 1, 1);  
02592     approxSize = mdd_count_onset(imcInfo->mddMgr, result,
02593                     imcInfo->systemInfo->psMddIdArray);
02594     exactSize = mdd_count_onset(imcInfo->mddMgr, tempMdd,
02595                       imcInfo->systemInfo->psMddIdArray);
02596     mdd_free(tempMdd);
02597     if (!computeLower){
02598       fprintf(vis_stdout, "IMC : Upper Preimage      |S+DC| = %.0f (%10g)\n",
02599               approxSize, approxSize);
02600       fprintf(vis_stdout, "IMC : Upper Preimage         |S| = %.0f (%10g)\n",
02601               exactSize, exactSize);
02602     }else{
02603       fprintf(vis_stdout, "IMC : Lower Preimage      |S+DC| = %.0f (%10g)\n",
02604               approxSize, approxSize);
02605       fprintf(vis_stdout, "IMC : Lower Preimage         |S| = %.0f (%10g)\n",
02606               exactSize, exactSize);
02607     } 
02608   }
02609 
02610   /* 
02611    * If preimage is zero, don't need compute again
02612    */
02613   if (mdd_is_tautology(result,0)){
02614     *isExact = TRUE;
02615   }
02616 
02617   return result;
02618 }
02619 
02630 mdd_t *
02631 Imc_ComputeLowerPreimage(
02632   Imc_Info_t *imcInfo,
02633   mdd_t *rangeCareStates,
02634   mdd_t *targetStates,
02635   boolean *isExact)
02636 {
02637   if (imcInfo->lowerMethod == Imc_LowerSubsetTR_c){
02638     return Imc_ComputeLowerPreimageBySubsetTR(imcInfo, rangeCareStates,
02639                                                 targetStates, isExact);
02640   }else if (imcInfo->lowerMethod == Imc_LowerUniversalQuantification_c){
02641     return Imc_ComputeApproxPreimageByQuantification(imcInfo, rangeCareStates,
02642              targetStates, isExact, TRUE);
02643   }
02644 
02645   return NIL(mdd_t);
02646 }
02647 
02648 
02660 mdd_t *
02661 Imc_ComputeLowerPreimageBySubsetTR(
02662   Imc_Info_t *imcInfo,
02663   mdd_t *rangeCareStates,
02664   mdd_t *targetStates,
02665   boolean *isExact)
02666 {
02667   mdd_t *tempMdd, *result;
02668   mdd_t *toStates;
02669 
02670   *isExact = TRUE;
02671 
02672   if (mdd_is_tautology(targetStates,0)){
02673     return mdd_zero(imcInfo->mddMgr);
02674   }
02675 
02676   if (mdd_is_tautology(targetStates, 1)){
02677     return mdd_one(imcInfo->mddMgr);
02678   }
02679 
02680   /*
02681    * T_i is T_i for all included latches.
02682    */
02683 
02684   /*arrayOfMdd = array_alloc(mdd_t *, 0); never used, I guess. Chao Wang*/
02685 
02686   toStates = mdd_substitute(imcInfo->mddMgr, targetStates,
02687                             imcInfo->systemInfo->psMddIdArray,
02688                             imcInfo->systemInfo->nsMddIdArray);
02689 
02690   /* Not works with partitioned transition relation 
02691   supportArray = mdd_get_support(imcInfo->mddMgr, targetStates);
02692 
02693   for(i=0;i<array_n(supportArray);i++){
02694     psMddId = array_fetch(int, supportArray,i);
02695 
02696     if (st_is_member(imcInfo->systemInfo->excludedPsMddIdTable, 
02697         (char *)(long)psMddId)){
02698       *isExact = FALSE;
02699     }
02700   }
02701   array_free(supportArray);
02702   */
02703   if (st_count(imcInfo->systemInfo->excludedPsMddIdTable)>0){
02704     *isExact = FALSE;
02705   }
02706 
02707   if (imcInfo->lowerSystemInfo->bwdMinimizedRealationArray == NIL(array_t)){
02708     result = Imc_ProductAbstract(imcInfo->mddMgr,
02709                                  imcInfo->lowerSystemInfo->bwdRealationArray,
02710                                  imcInfo->lowerSystemInfo->bwdSmoothVarsArray,
02711                                  toStates);
02712   }else{
02713     result = Imc_ProductAbstract(imcInfo->mddMgr,
02714                                  imcInfo->lowerSystemInfo->bwdMinimizedRealationArray,
02715                                  imcInfo->lowerSystemInfo->bwdSmoothVarsArray,
02716                                  toStates);
02717   }
02718 
02719   mdd_free(toStates);
02720 
02721   if (imcInfo->verbosity == Imc_VerbosityMax_c){
02722     double exactSize, approxSize;
02723     tempMdd = mdd_and(result, rangeCareStates, 1, 1);  
02724     approxSize = mdd_count_onset(imcInfo->mddMgr, result,
02725                     imcInfo->systemInfo->psMddIdArray);
02726     exactSize = mdd_count_onset(imcInfo->mddMgr, tempMdd,
02727                       imcInfo->systemInfo->psMddIdArray);
02728     mdd_free(tempMdd);
02729     fprintf(vis_stdout, "IMC : Lower Preimage      |S+DC| = %.0f (%10g)\n",
02730             approxSize, approxSize);
02731     fprintf(vis_stdout, "IMC : Lower Preimage         |S| = %.0f (%10g)\n",
02732             exactSize, exactSize);
02733   }
02734 
02735   return result;
02736 }
02737 
02751 mdd_t *
02752 Imc_ProductAbstract(
02753   mdd_manager *mddMgr,
02754   array_t *relationArray,
02755   array_t *smoothVarsMddIdArray,
02756   mdd_t *toStates)
02757 {
02758   int i;
02759   mdd_t *product, *tempProd;
02760   mdd_t *singleTR;
02761   array_t *smoothVars;
02762 
02763   product = mdd_dup(toStates);
02764 
02765   for(i=0;i<array_n(relationArray);i++){
02766     singleTR = array_fetch(mdd_t *, relationArray, i);
02767     smoothVars = array_fetch(array_t*, smoothVarsMddIdArray, i);
02768     if (array_n(smoothVars) == 0){
02769       tempProd = mdd_and(product, singleTR, 1, 1);
02770     }else{
02771       tempProd = bdd_and_smooth(product, singleTR, smoothVars);
02772     }
02773     mdd_free(product);
02774     product = tempProd;
02775   }
02776   if (i < array_n(smoothVarsMddIdArray)) {
02777     smoothVars = array_fetch(array_t*, smoothVarsMddIdArray, i);
02778     tempProd = bdd_smooth(product, smoothVars);
02779     mdd_free(product);
02780     product = tempProd;
02781   }
02782 
02783   return product;  
02784 }
02785 
02786 
02787 /*---------------------------------------------------------------------------*/
02788 /* Definition of internal functions                                          */
02789 /*---------------------------------------------------------------------------*/
02790 
02808 array_t *
02809 ImcCreateScheduleArray(
02810   Ntk_Network_t         *network,
02811   Ctlp_Formula_t        *formula,
02812   boolean               dynamicIncrease,
02813   Imc_RefineMethod      refine,
02814   int                   verbosity,
02815   int                   incrementalSize,
02816   Part_CMethod          correlationMethod)
02817 {
02818   array_t               *partitionArray;
02819   Part_Subsystem_t      *partitionSubsystem;
02820   Part_SubsystemInfo_t  *subsystemInfo; 
02821   st_table              *latchNameTable;
02822   st_table              *latchNameTableSum, *latchNameTableSumCopy;
02823   int                   i;
02824   char                  *flagValue;
02825   st_generator          *stGen;
02826   char                  *name;
02827   array_t               *ctlArray;
02828   double                affinityFactor;
02829   array_t               *scheduleArray;
02830   boolean               dynamicAndDependency;
02831   array_t               *tempArray, *tempArray2;
02832   int                   count;
02833 
02834   /* affinity factor to decompose state space */
02835   flagValue = Cmd_FlagReadByName("part_group_affinity_factor");
02836   if(flagValue != NIL(char)){
02837     affinityFactor = atof(flagValue); 
02838   }
02839   else{
02840     /* default value */
02841     affinityFactor = 0.5; 
02842   }
02843 
02844   if (refine == Imc_RefineSort_c) dynamicAndDependency = TRUE;
02845   else dynamicAndDependency = FALSE;
02846 
02847   /* 
02848    * Obtain submachines as array. 
02849    * The first sub-system includes variables in CTL formulas and other
02850    * latches are groupted in the same way as Part_PartCreateSubsystems()
02851    */
02852   ctlArray = array_alloc(Ctlp_Formula_t *, 1);
02853   subsystemInfo = Part_PartitionSubsystemInfoInit(network);
02854   Part_PartitionSubsystemInfoSetBound(subsystemInfo, incrementalSize);
02855   Part_PartitionSubsystemInfoSetVerbosity(subsystemInfo, verbosity);
02856   Part_PartitionSubsystemInfoSetCorrelationMethod(subsystemInfo,
02857     correlationMethod); 
02858   Part_PartitionSubsystemInfoSetAffinityFactor(subsystemInfo, affinityFactor);
02859   array_insert(Ctlp_Formula_t *, ctlArray, 0, formula);
02860 
02861   partitionArray = Part_PartCreateSubsystemsWithCTL(subsystemInfo,
02862                    ctlArray, NIL(array_t), dynamicIncrease,dynamicAndDependency);
02863   Part_PartitionSubsystemInfoFree(subsystemInfo);
02864   array_free(ctlArray);
02865   scheduleArray = array_alloc(st_table *, 0);
02866 
02867 
02868   /* 
02869    * For each partitioned submachines build an FSM. 
02870    */
02871   latchNameTableSum = st_init_table(strcmp, st_strhash);
02872   if (!dynamicAndDependency){
02873     for (i=0;i<array_n(partitionArray);i++){
02874       partitionSubsystem = array_fetch(Part_Subsystem_t *, partitionArray, i);
02875       if (partitionSubsystem != NIL(Part_Subsystem_t)) {
02876         latchNameTable = Part_PartitionSubsystemReadVertexTable(partitionSubsystem);
02877         st_foreach_item(latchNameTable, stGen, &name, NIL(char *)) {
02878           if (!st_lookup(latchNameTableSum, name, NIL(char *))){ 
02879             st_insert(latchNameTableSum, name, NIL(char));
02880           }
02881         }
02882         Part_PartitionSubsystemFree(partitionSubsystem);
02883       } 
02884       latchNameTableSumCopy = st_copy(latchNameTableSum);
02885       array_insert_last(st_table *, scheduleArray, latchNameTableSumCopy);
02886     }
02887   }else{
02888     partitionSubsystem = array_fetch(Part_Subsystem_t *, partitionArray, 0);
02889     latchNameTable = Part_PartitionSubsystemReadVertexTable(partitionSubsystem);
02890     st_foreach_item(latchNameTable, stGen, &name, NIL(char *)) {
02891       st_insert(latchNameTableSum, name, NIL(char));
02892     }
02893     latchNameTableSumCopy = st_copy(latchNameTableSum);
02894     array_insert_last(st_table *, scheduleArray, latchNameTableSumCopy);
02895     Part_PartitionSubsystemFree(partitionSubsystem);
02896 
02897     partitionSubsystem = array_fetch(Part_Subsystem_t *, partitionArray, 1);
02898     tempArray = array_alloc(char *, 0);    
02899     if (partitionSubsystem != NIL(Part_Subsystem_t)){
02900       latchNameTable = Part_PartitionSubsystemReadVertexTable(partitionSubsystem);
02901       st_foreach_item(latchNameTable, stGen, &name, NIL(char *)) {
02902         array_insert_last(char *, tempArray, name);
02903       }
02904       array_sort(tempArray, stringCompare);
02905       Part_PartitionSubsystemFree(partitionSubsystem);
02906     }
02907     
02908     partitionSubsystem = array_fetch(Part_Subsystem_t *, partitionArray, 2);
02909     tempArray2 = array_alloc(char *, 0);
02910     if (partitionSubsystem != NIL(Part_Subsystem_t)) {
02911       latchNameTable = Part_PartitionSubsystemReadVertexTable(partitionSubsystem);
02912       st_foreach_item(latchNameTable, stGen, &name, NIL(char *)) {
02913         array_insert_last(char *, tempArray2, name);
02914       }
02915       array_sort(tempArray2, stringCompare);
02916       Part_PartitionSubsystemFree(partitionSubsystem);
02917     }
02918 
02919     array_append(tempArray, tempArray2);
02920     array_free(tempArray2);
02921 
02922     count = 0;
02923     arrayForEachItem(char *, tempArray, i, name){   
02924       if (!st_lookup(latchNameTableSum, name, NIL(char *))){ 
02925         st_insert(latchNameTableSum, (char *)name, (char *)0);
02926         count++;
02927       }
02928       if ((count == incrementalSize) && (i < array_n(tempArray)-1)){
02929         latchNameTableSumCopy = st_copy(latchNameTableSum);
02930         array_insert_last(st_table *, scheduleArray, latchNameTableSumCopy);
02931         count = 0;
02932       }
02933     }
02934     array_free(tempArray);
02935     latchNameTableSumCopy = st_copy(latchNameTableSum);
02936     array_insert_last(st_table *, scheduleArray, latchNameTableSumCopy);
02937   }
02938 
02939   array_free(partitionArray);
02940   st_free_table(latchNameTableSum);
02941 
02942   return scheduleArray;
02943 }
02944 
02945 
02956 int
02957 ImcModelCheckAtomicFormula(
02958   Imc_Info_t *imcInfo, 
02959   Ctlp_Formula_t *formula)
02960 {
02961   mdd_t * resultMdd;
02962   mdd_t *tmpMdd;
02963   Fsm_Fsm_t *modelFsm = imcInfo->globalFsm;
02964   Ntk_Network_t *network = Fsm_FsmReadNetwork( modelFsm );
02965   char *nodeNameString = Ctlp_FormulaReadVariableName( formula );
02966   char *nodeValueString = Ctlp_FormulaReadValueName( formula );
02967   Ntk_Node_t *node = Ntk_NetworkFindNodeByName( network, nodeNameString );
02968   Var_Variable_t *nodeVar;
02969   int nodeValue;
02970   graph_t *modelPartition;
02971   vertex_t *partitionVertex;
02972   Mvf_Function_t *MVF;
02973   Imc_NodeInfo_t *nodeInfo;
02974 
02975   if (!st_lookup(imcInfo->nodeInfoTable, formula, &nodeInfo)){
02976     fprintf(vis_stdout, "** imc error : Atomic nodeinfo is not initilize.\n");
02977     return 0;
02978   }
02979 
02980   nodeVar = Ntk_NodeReadVariable( node );
02981   if ( Var_VariableTestIsSymbolic( nodeVar ) ){
02982     nodeValue = Var_VariableReadIndexFromSymbolicValue( nodeVar, nodeValueString );
02983   }
02984   else {
02985     nodeValue = atoi( nodeValueString );
02986   } 
02987 
02988   modelPartition = Part_NetworkReadPartition( network );
02989   if ( !( partitionVertex = Part_PartitionFindVertexByName( modelPartition,
02990                                                             nodeNameString ) )) { 
02991     lsGen tmpGen;
02992     Ntk_Node_t *tmpNode;
02993     array_t *mvfArray;
02994     array_t *tmpRoots = array_alloc( Ntk_Node_t *, 0 );
02995     st_table *tmpLeaves = st_init_table( st_ptrcmp, st_ptrhash );
02996     array_insert_last( Ntk_Node_t *, tmpRoots, node );
02997 
02998     Ntk_NetworkForEachCombInput( network, tmpGen, tmpNode ) {
02999       st_insert( tmpLeaves, (char *) tmpNode, (char *) NTM_UNUSED );
03000     }
03001 
03002     mvfArray =  Ntm_NetworkBuildMvfs( network, tmpRoots, tmpLeaves,
03003                                       NIL(mdd_t) );
03004     MVF = array_fetch( Mvf_Function_t *, mvfArray, 0 );
03005     array_free( tmpRoots );
03006     st_free_table( tmpLeaves );
03007     array_free( mvfArray );
03008 
03009     tmpMdd = Mvf_FunctionReadComponent( MVF, nodeValue );
03010     resultMdd = mdd_dup( tmpMdd );
03011     Mvf_FunctionFree( MVF );
03012   }
03013   else {
03014     MVF = Part_VertexReadFunction( partitionVertex );
03015     tmpMdd = Mvf_FunctionReadComponent( MVF, nodeValue );
03016     resultMdd = mdd_dup( tmpMdd );
03017   }
03018 
03019   tmpMdd = bdd_minimize(resultMdd, imcInfo->modelCareStates);
03020   mdd_free(resultMdd);
03021   resultMdd = tmpMdd;
03022 
03023   nodeInfo->upperSat = resultMdd;
03024   nodeInfo->lowerSat = mdd_dup(resultMdd);
03025   nodeInfo->upperDone = TRUE;
03026   nodeInfo->lowerDone = TRUE;
03027   nodeInfo->isExact = TRUE;
03028   return 1;  
03029 }
03030 
03040 int
03041 ImcModelCheckTrueFalseFormula(
03042   Imc_Info_t *imcInfo, 
03043   Ctlp_Formula_t *formula,
03044   boolean isTrue)
03045 {
03046   mdd_t *resultMdd;
03047   Imc_NodeInfo_t *nodeInfo;
03048 
03049   if (!st_lookup(imcInfo->nodeInfoTable, formula, &nodeInfo)){
03050     fprintf(vis_stdout, "** imc error : TRUE or FALSE nodeinfo is not initilize.\n");
03051     return 0;
03052   }
03053 
03054   /*
03055    * Already computed, then return. 
03056    */
03057   if (nodeInfo->isExact) return 1;
03058 
03059   if (isTrue)
03060     resultMdd = mdd_one(imcInfo->mddMgr);
03061   else
03062     resultMdd = mdd_zero(imcInfo->mddMgr);
03063 
03064   nodeInfo->upperSat = resultMdd;
03065   nodeInfo->lowerSat = mdd_dup(resultMdd);  
03066   nodeInfo->upperDone = TRUE;
03067   nodeInfo->lowerDone = TRUE;
03068   nodeInfo->isExact = TRUE;
03069   return 1;
03070 }
03071 
03081 int
03082 ImcModelCheckNotFormula(
03083   Imc_Info_t *imcInfo, 
03084   Ctlp_Formula_t *formula,
03085   boolean isUpper
03086   )
03087 {
03088   mdd_t *upperSAT, *lowerSAT;
03089   Ctlp_Formula_t *leftChild;
03090   Imc_NodeInfo_t *nodeInfo, *leftNodeInfo;
03091 
03092   if (!st_lookup(imcInfo->nodeInfoTable, formula, &nodeInfo)){
03093     return 0;
03094   }
03095 
03096 
03097   leftChild = Ctlp_FormulaReadLeftChild(formula);
03098   if (!st_lookup(imcInfo->nodeInfoTable, leftChild, &leftNodeInfo)){
03099     fprintf(vis_stdout, "** imc error : NOT nodeinfo is not initilize.\n");
03100     return 0;
03101   }
03102 
03103 
03104   if (isUpper){
03105     if  (leftNodeInfo->lowerSat == NIL(mdd_t)){
03106       return 0;
03107     }else{
03108       if (nodeInfo->upperSat != NIL(mdd_t)) mdd_free(nodeInfo->upperSat);
03109       upperSAT = mdd_not(leftNodeInfo->lowerSat);
03110       nodeInfo->upperSat = upperSAT;
03111       nodeInfo->upperDone = TRUE;
03112     }
03113   }else{
03114     if  (leftNodeInfo->upperSat == NIL(mdd_t)){
03115       return 0;
03116     }else{
03117       if (nodeInfo->lowerSat != NIL(mdd_t)) mdd_free(nodeInfo->lowerSat);
03118       lowerSAT = mdd_not(leftNodeInfo->upperSat);
03119       nodeInfo->lowerSat = lowerSAT;
03120       nodeInfo->lowerDone = TRUE;
03121     }
03122   }
03123 
03124   if (leftNodeInfo->isExact){
03125     nodeInfo->isExact = TRUE;
03126     if (isUpper){
03127       if (nodeInfo->lowerSat != NIL(mdd_t)) mdd_free(nodeInfo->lowerSat);
03128       nodeInfo->lowerSat = mdd_dup(nodeInfo->upperSat);
03129       nodeInfo->lowerDone = TRUE;
03130     }else{
03131       if (nodeInfo->upperSat != NIL(mdd_t)) mdd_free(nodeInfo->upperSat);
03132       nodeInfo->upperSat = mdd_dup(nodeInfo->lowerSat);
03133       nodeInfo->upperDone = TRUE;
03134     }
03135   }
03136 
03137   return 1;
03138 }
03139 
03149 int
03150 ImcModelCheckAndFormula(
03151   Imc_Info_t *imcInfo, 
03152   Ctlp_Formula_t *formula,
03153   boolean isUpper)
03154 {
03155   mdd_t *tmpMdd;
03156   mdd_t *upperSat, *lowerSat;
03157   Ctlp_Formula_t *leftChild, *rightChild;
03158   Imc_NodeInfo_t *nodeInfo, *leftNodeInfo, *rightNodeInfo;
03159 
03160   if (!st_lookup(imcInfo->nodeInfoTable, formula, &nodeInfo)){
03161     return 0;
03162   }
03163 
03164   /*
03165    * Already computed, then return. 
03166    */
03167   if (nodeInfo->isExact) return 1;
03168 
03169   leftChild = Ctlp_FormulaReadLeftChild(formula);
03170   rightChild = Ctlp_FormulaReadRightChild(formula);
03171   if (!st_lookup(imcInfo->nodeInfoTable, leftChild, &leftNodeInfo)){
03172     fprintf(vis_stdout, "** imc error : AND left nodeinfo is not initilize.\n");
03173     return 0;
03174   }
03175   if (!st_lookup(imcInfo->nodeInfoTable, rightChild, &rightNodeInfo)){
03176     fprintf(vis_stdout, "** imc error : AND right nodeinfo is not initilize.\n");
03177     return 0;
03178   } 
03179 
03180   /*
03181    * Already computed, then return. 
03182    */
03183   if (isUpper){
03184     if ((leftNodeInfo->upperSat == NIL(mdd_t))||
03185         (rightNodeInfo->upperSat == NIL(mdd_t))){
03186       fprintf(vis_stdout, "** imc error : AND child nodeinfo->upperSat is not computed.\n");
03187       return 0;
03188     }else{
03189       tmpMdd = mdd_and(leftNodeInfo->upperSat,rightNodeInfo->upperSat, 1, 1);
03190       upperSat = bdd_minimize(tmpMdd, imcInfo->modelCareStates);
03191       mdd_free(tmpMdd);
03192       if (nodeInfo->upperSat != NIL(mdd_t)) mdd_free(nodeInfo->upperSat);
03193       nodeInfo->upperSat = upperSat;
03194       nodeInfo->upperDone = TRUE;
03195     }
03196   }else{
03197     if ((leftNodeInfo->lowerSat == NIL(mdd_t))||
03198         (rightNodeInfo->lowerSat == NIL(mdd_t))){
03199       fprintf(vis_stdout, "** imc error : AND child nodeinfo->lowerSat is not computed.\n");
03200       return 0;
03201     }else{
03202       tmpMdd = mdd_and(leftNodeInfo->lowerSat,rightNodeInfo->lowerSat, 1, 1);
03203       
03204       lowerSat = bdd_minimize(tmpMdd, imcInfo->modelCareStates);
03205       mdd_free(tmpMdd);
03206       if (nodeInfo->lowerSat != NIL(mdd_t)) mdd_free(nodeInfo->lowerSat);
03207       nodeInfo->lowerSat = lowerSat;
03208       nodeInfo->lowerDone = TRUE;
03209     }
03210   }
03211 
03212   if ((leftNodeInfo->isExact) && (rightNodeInfo->isExact)){
03213     nodeInfo->isExact = TRUE;
03214     if (isUpper){
03215       if (nodeInfo->lowerSat != NIL(mdd_t)) mdd_free(nodeInfo->lowerSat);
03216       nodeInfo->lowerSat = mdd_dup(nodeInfo->upperSat);
03217       nodeInfo->lowerDone = TRUE;
03218     }else{
03219       if (nodeInfo->upperSat != NIL(mdd_t)) mdd_free(nodeInfo->upperSat);
03220       nodeInfo->upperSat = mdd_dup(nodeInfo->lowerSat);
03221       nodeInfo->upperDone = TRUE;
03222     }
03223   }
03224 
03225   return 1;
03226 }
03227 
03237 void
03238 ImcPrintLatchInApproxSystem(
03239   Imc_Info_t *imcInfo)
03240 {
03241   int i, index;
03242   char *name;
03243   array_t *includedLatchIndex = imcInfo->systemInfo->includedLatchIndex;
03244 
03245   fprintf(vis_stdout, "Latches in approximate system\n");
03246   fprintf(vis_stdout, "-----------------------------\n");
03247 
03248   for(i=0;i<array_n(includedLatchIndex);i++){
03249     index = array_fetch(int,includedLatchIndex,i);
03250     name = array_fetch(char *, imcInfo->systemInfo->latchNameArray, index);
03251     fprintf(vis_stdout, "%s\n", name);
03252   }
03253 }
03254 
03264 void
03265 ImcNodeInfoTableFree(
03266   st_table *nodeInfoTable)
03267 {
03268   Ctlp_Formula_t *formula;
03269   Imc_NodeInfo_t *nodeInfo;
03270   st_generator *stGen;
03271 
03272   st_foreach_item(nodeInfoTable, stGen, &formula, &nodeInfo){
03273     Imc_NodeInfoFree(nodeInfo);
03274   }
03275 
03276   st_free_table(nodeInfoTable);
03277 }
03278 
03279 /*---------------------------------------------------------------------------*/
03280 /* Definition of static functions                                            */
03281 /*---------------------------------------------------------------------------*/
03282 
03290 static int
03291 stringCompare(
03292   const void * s1,
03293   const void * s2)
03294 {
03295   return(strcmp(*(char **)s1, *(char **)s2));
03296 }
03297