VIS

src/ctlp/ctlpUtil.c

Go to the documentation of this file.
00001 
00053 #include "ctlpInt.h"
00054 #include "errno.h"
00055 
00056 static char rcsid[] UNUSED = "$Id: ctlpUtil.c,v 1.71 2009/04/11 18:25:53 fabio Exp $";
00057 
00058 
00059 /*---------------------------------------------------------------------------*/
00060 /* Variable declarations                                                     */
00061 /*---------------------------------------------------------------------------*/
00062 
00070 static array_t *globalFormulaArray;
00071 static int      changeBracket = 1;
00072 
00073 /* see ctlpInt.h for documentation */
00074 int CtlpGlobalError;
00075 Ctlp_Formula_t *CtlpGlobalFormula;
00076 st_table *CtlpMacroTable;
00077 
00078 /*---------------------------------------------------------------------------*/
00079 /* Macro declarations                                                        */
00080 /*---------------------------------------------------------------------------*/
00081 
00082 
00085 /*---------------------------------------------------------------------------*/
00086 /* Static function prototypes                                                */
00087 /*---------------------------------------------------------------------------*/
00088 
00089 static Ctlp_Formula_t * FormulaCreateWithType(Ctlp_FormulaType type);
00090 static int FormulaCompare(const char *key1, const char *key2);
00091 static int FormulaHash(char *key, int modulus);
00092 static Ctlp_Formula_t * FormulaHashIntoUniqueTable(Ctlp_Formula_t *formula, st_table *uniqueTable);
00093 static Ctlp_Formula_t * FormulaConvertToExistentialDAG(Ctlp_Formula_t *formula);
00094 static void FormulaConvertToForward(Ctlp_Formula_t *formula, int compareValue);
00095 static void FormulaInsertForwardCompareNodes(Ctlp_Formula_t *formula, Ctlp_Formula_t *parent, int compareValue);
00096 static int FormulaGetCompareValue(Ctlp_Formula_t *formula);
00097 static int FormulaIsConvertible(Ctlp_Formula_t *formula);
00098 static Ctlp_Formula_t * ReplaceSimpleFormula(Ctlp_Formula_t *formula);
00099 
00103 /*---------------------------------------------------------------------------*/
00104 /* Definition of exported functions                                          */
00105 /*---------------------------------------------------------------------------*/
00106 
00122 array_t *
00123 Ctlp_FileParseFormulaArray(
00124   FILE * fp)
00125 {
00126   st_generator *stGen;
00127   char *name;
00128   Ctlp_Formula_t *formula;
00129   char *flagValue;
00130   /*
00131    * Initialize the global variables.
00132    */
00133   globalFormulaArray = array_alloc(Ctlp_Formula_t *, 0);
00134   CtlpGlobalError = 0;
00135   CtlpGlobalFormula = NIL(Ctlp_Formula_t);
00136   CtlpMacroTable = st_init_table(strcmp,st_strhash);
00137   CtlpFileSetup(fp);
00138   /*
00139    * Check if changing "[] -> <>" is disabled.
00140    */
00141   flagValue = Cmd_FlagReadByName("ctl_change_bracket");
00142   if (flagValue != NIL(char)) {
00143     if (strcmp(flagValue, "yes") == 0)
00144       changeBracket = 1;
00145     else if (strcmp(flagValue, "no") == 0)
00146       changeBracket = 0;
00147     else {
00148       fprintf(vis_stderr,
00149         "** ctl error : invalid value %s for ctl_change_bracket[yes/no]. ***\n",
00150         flagValue);
00151     }
00152   }
00153 
00154   (void)CtlpYyparse();
00155   st_foreach_item(CtlpMacroTable,stGen,&name,&formula){
00156      FREE(name);
00157      CtlpFormulaFree(formula);
00158   }
00159   st_free_table(CtlpMacroTable);
00160 
00161   /*
00162    * Clean up if there was an error, otherwise return the array.
00163    */
00164   if (CtlpGlobalError){
00165     Ctlp_FormulaArrayFree(globalFormulaArray);
00166     return NIL(array_t);
00167   }
00168   else {
00169     return globalFormulaArray;
00170   }
00171 }
00172 
00184 char *
00185 Ctlp_FormulaConvertToString(
00186   Ctlp_Formula_t * formula)
00187 {
00188   char *s1        = NIL(char);
00189   char *s2        = NIL(char);
00190   char *tmpString = NIL(char);
00191   char *result;
00192 
00193 
00194   if (formula == NIL(Ctlp_Formula_t)) {
00195     return NIL(char);
00196   }
00197 
00198   /* The formula is a leaf. */
00199   if (formula->type == Ctlp_ID_c){
00200     return util_strcat3((char *)(formula->left), "=",(char *)(formula->right));
00201   }
00202 
00203   /* If the formula is a non-leaf, the function is called recursively */
00204   s1 = Ctlp_FormulaConvertToString(formula->left);
00205   s2 = Ctlp_FormulaConvertToString(formula->right);
00206 
00207   switch(formula->type) {
00208     /*
00209      * The cases are listed in rough order of their expected frequency.
00210      */
00211     case Ctlp_OR_c:
00212       tmpString = util_strcat3(s1, " + ",s2);
00213       result    = util_strcat3("(", tmpString, ")");
00214       break;
00215     case Ctlp_AND_c:
00216       tmpString = util_strcat3(s1, " * ", s2);
00217       result    = util_strcat3("(", tmpString, ")");
00218       break;
00219     case Ctlp_THEN_c:
00220       tmpString = util_strcat3(s1, " -> ", s2);
00221       result    = util_strcat3("(", tmpString, ")");
00222       break;
00223     case Ctlp_XOR_c:
00224       tmpString = util_strcat3(s1, " ^ ", s2);
00225       result    = util_strcat3("(", tmpString, ")");
00226       break;
00227     case Ctlp_EQ_c:
00228       tmpString = util_strcat3(s1, " <-> ", s2);
00229       result    = util_strcat3("(", tmpString, ")");
00230       break;
00231     case Ctlp_NOT_c:
00232       tmpString = util_strcat3("(", s1, ")");
00233       result    = util_strcat3("!", tmpString, "");
00234       break;
00235     case Ctlp_EX_c:
00236       result = util_strcat3("EX(", s1, ")");
00237       FREE(s1);
00238       break;
00239     case Ctlp_EG_c:
00240       result = util_strcat3("EG(", s1, ")");
00241       break;
00242     case Ctlp_EF_c:
00243       result = util_strcat3("EF(", s1, ")");
00244       break;
00245     case Ctlp_EU_c:
00246       tmpString = util_strcat3("E(", s1, " U ");
00247       result    = util_strcat3(tmpString, s2, ")");
00248       break;
00249     case Ctlp_AX_c:
00250       result = util_strcat3("AX(", s1, ")");
00251       break;
00252     case Ctlp_AG_c:
00253       result = util_strcat3("AG(", s1, ")");
00254       break;
00255     case Ctlp_AF_c:
00256       result = util_strcat3("AF(", s1, ")");
00257       break;
00258     case Ctlp_AU_c:
00259       tmpString = util_strcat3("A(", s1, " U ");
00260       result    = util_strcat3(tmpString, s2, ")");
00261       break;
00262     case Ctlp_TRUE_c:
00263       result = util_strsav("TRUE");
00264       break;
00265     case Ctlp_FALSE_c:
00266       result = util_strsav("FALSE");
00267       break;
00268     case Ctlp_Init_c:
00269       result = util_strsav("Init");
00270       break;
00271     case Ctlp_Cmp_c:
00272       if (formula->compareValue == 0)
00273         tmpString = util_strcat3("[", s1, "] = ");
00274       else
00275         tmpString = util_strcat3("[", s1, "] != ");
00276       result    = util_strcat3(tmpString, s2, "");
00277       break;
00278     case Ctlp_FwdU_c:
00279       tmpString = util_strcat3("FwdU(", s1, ",");
00280       result    = util_strcat3(tmpString, s2, ")");
00281       break;
00282     case Ctlp_FwdG_c:
00283       tmpString = util_strcat3("FwdG(", s1, ",");
00284       result    = util_strcat3(tmpString, s2, ")");
00285       break;
00286     case Ctlp_EY_c:
00287       result = util_strcat3("EY(", s1, ")");
00288       break;
00289     default:
00290       fail("Unexpected type");
00291   }
00292 
00293   if (s1 != NIL(char)) {
00294     FREE(s1);
00295   }
00296 
00297   if (s2 != NIL(char)) {
00298     FREE(s2);
00299   }
00300 
00301   if (tmpString != NIL(char)) {
00302     FREE(tmpString);
00303   }
00304 
00305   return result;
00306 }
00307 
00308 
00320 void
00321 Ctlp_FormulaPrint(
00322   FILE * fp,
00323   Ctlp_Formula_t * formula)
00324 {
00325   char *tmpString;
00326   if (formula == NIL(Ctlp_Formula_t)) {
00327     return;
00328   }
00329   tmpString = Ctlp_FormulaConvertToString(formula);
00330   (void) fprintf(fp, "%s", tmpString);
00331   FREE(tmpString);
00332 }
00333 
00334 
00347 Ctlp_FormulaType
00348 Ctlp_FormulaReadType(
00349   Ctlp_Formula_t * formula)
00350 {
00351   assert( formula != NIL(Ctlp_Formula_t) );
00352   return (formula->type);
00353 }
00354 
00355 #if 0
00356 boolean
00357 Ctlp_FormulaReadEvenNegations(
00358   Ctlp_Formula_t * formula)
00359 {
00360   assert(formula != NIL(Ctlp_Formula_t));
00361   return (formula->even_negations);
00362 }
00363 #endif
00364 
00365 
00378 int
00379 Ctlp_FormulaReadCompareValue(
00380   Ctlp_Formula_t * formula)
00381 {
00382   int value;
00383 
00384   assert( formula != NIL(Ctlp_Formula_t));
00385   value = formula->compareValue;
00386   return (value);
00387 }
00388 
00389 
00400 char *
00401 Ctlp_FormulaReadVariableName(
00402   Ctlp_Formula_t * formula)
00403 {
00404   if (formula->type != Ctlp_ID_c){
00405     fail("Ctlp_FormulaReadVariableName() was called on a non-leaf formula.");
00406   }
00407   return ((char *)(formula->left));
00408 }
00409 
00410 
00421 char *
00422 Ctlp_FormulaReadValueName(
00423   Ctlp_Formula_t * formula)
00424 {
00425   if (formula->type != Ctlp_ID_c){
00426     fail("Ctlp_FormulaReadValueName() was called on a non-leaf formula.");
00427   }
00428   return ((char *)(formula->right));
00429 }
00430 
00443 Ctlp_Formula_t *
00444 Ctlp_FormulaReadLeftChild(
00445   Ctlp_Formula_t * formula)
00446 {
00447   if (formula->type != Ctlp_ID_c){
00448     return (formula->left);
00449   }
00450   return NIL(Ctlp_Formula_t);
00451 }
00452 
00453 
00466 Ctlp_Formula_t *
00467 Ctlp_FormulaReadRightChild(
00468   Ctlp_Formula_t * formula)
00469 {
00470   if (formula->type != Ctlp_ID_c){
00471     return (formula->right);
00472   }
00473   return NIL(Ctlp_Formula_t);
00474 }
00475 
00476 
00492 mdd_t *
00493 Ctlp_FormulaObtainStates(
00494   Ctlp_Formula_t * formula)
00495 {
00496   assert(formula != NIL(Ctlp_Formula_t));
00497   if (formula->states == NIL(mdd_t) ||
00498       formula->latest == Ctlp_Incomparable_c) {
00499     return NIL(mdd_t);
00500   }
00501   else {
00502     return mdd_dup(formula->states);
00503   }
00504 }
00505 
00506 
00521 void
00522 Ctlp_FormulaSetStates(
00523   Ctlp_Formula_t * formula,
00524   mdd_t * states)
00525 {
00526   assert(formula != NIL(Ctlp_Formula_t));
00527   /* RB: added the next two lines.  Given the Description, this was a
00528      bug */
00529   if(formula->states != NIL(mdd_t))
00530     mdd_free(formula->states);
00531   formula->states = states;
00532   formula->latest = Ctlp_Exact_c;
00533 }
00534 
00535 
00551 mdd_t *
00552 Ctlp_FormulaObtainLatestApprox(
00553   Ctlp_Formula_t *formula)
00554 {
00555   if (formula->latest == Ctlp_Exact_c)
00556     return mdd_dup(formula->states);
00557 
00558   if (formula->latest == Ctlp_Overapprox_c)
00559     return mdd_dup(formula->overapprox);
00560 
00561   if (formula->latest == Ctlp_Underapprox_c)
00562     return mdd_dup(formula->underapprox);
00563 
00564   if (formula->latest == Ctlp_Incomparable_c)
00565     return mdd_dup(formula->states);
00566 
00567   assert(0);  /* we should never get here */
00568   return NIL(mdd_t);
00569 }
00570 
00571 
00585 mdd_t *
00586 Ctlp_FormulaObtainApproxStates(
00587   Ctlp_Formula_t *formula,
00588   Ctlp_Approx_t approx)
00589 {
00590   if(approx == Ctlp_Incomparable_c)
00591     return NIL(mdd_t);
00592 
00593   if (formula->states != NIL(mdd_t))
00594     return mdd_dup(formula->states);
00595 
00596   if(approx == Ctlp_Exact_c)
00597     return NIL(mdd_t);
00598 
00599   if(approx == Ctlp_Overapprox_c){
00600     if(formula->overapprox == NIL(mdd_t))
00601       return NIL(mdd_t);
00602     else
00603       return mdd_dup(formula->overapprox);
00604   }
00605 
00606   if(approx == Ctlp_Underapprox_c){
00607     if(formula->underapprox == NIL(mdd_t))
00608       return NIL(mdd_t);
00609     else
00610       return mdd_dup(formula->underapprox);
00611   }
00612 
00613   assert(0);  /* we should never get here */
00614   return NIL(mdd_t);
00615 }
00616 
00617 
00636 void
00637 Ctlp_FormulaSetApproxStates(
00638   Ctlp_Formula_t * formula,
00639   mdd_t * states,
00640   Ctlp_Approx_t approx)
00641 {
00642   if (formula->latest == Ctlp_Exact_c) {
00643     mdd_free(states);
00644     return;
00645   }
00646 
00647   formula->latest = approx;
00648 
00649   if (approx == Ctlp_Exact_c) {
00650     if (formula->states != NIL(mdd_t))
00651       mdd_free(formula->states);
00652     formula->states = states;
00653 
00654     if (formula->underapprox != NIL(mdd_t)) {
00655       mdd_free(formula->underapprox);
00656       formula->underapprox = NIL(mdd_t);
00657     }
00658 
00659     if (formula->overapprox != NIL(mdd_t)) {
00660       mdd_free(formula->overapprox);
00661       formula->overapprox = NIL(mdd_t);
00662     }
00663 
00664     return;
00665   }
00666 
00667   if (approx == Ctlp_Underapprox_c) {
00668     /* you could perform a union instead, but typical use will
00669        have monotonically increasing underapproximations */
00670     if(formula->underapprox != NIL(mdd_t))
00671       mdd_free(formula->underapprox);
00672     formula->underapprox = states;
00673   }
00674 
00675   if (approx == Ctlp_Overapprox_c) {
00676     /* you could perform an intersection instead */
00677     if (formula->overapprox != NIL(mdd_t))
00678       mdd_free(formula->overapprox);
00679     formula->overapprox = states;
00680   }
00681 
00682   /* This case is possible; for instance when both children of an implication
00683    * with (All, S) condition are underapproximated.  We may lose some states
00684    * from the left if they are not in S.  These cause an overapproximation.
00685    * We may also lose some states from the right.  These cause an
00686    * underapproximation.  When the two effects are combined, we get something
00687    * incomparable, yet sufficient to produce the exact result, because it is
00688    * accurate over S. */
00689   if (approx == Ctlp_Incomparable_c) {
00690     if (formula->states != NIL(mdd_t))
00691       mdd_free(formula->states);
00692     formula->states = states;
00693   }
00694 
00695   return;
00696 }
00697 
00698 
00713 void
00714 Ctlp_FormulaSetDbgInfo(
00715   Ctlp_Formula_t * formula,
00716   void *data,
00717   Ctlp_DbgInfoFreeFn freeFn)
00718 {
00719   if (formula->dbgInfo.data != NIL(void)){
00720     assert(formula->dbgInfo.freeFn != NULL);
00721 
00722     (*formula->dbgInfo.freeFn)(formula);
00723   }
00724 
00725   formula->dbgInfo.data   = data;
00726   formula->dbgInfo.freeFn = freeFn;
00727 }
00728 
00729 
00742 void *
00743 Ctlp_FormulaReadDebugData(
00744   Ctlp_Formula_t * formula)
00745 {
00746   return formula->dbgInfo.data;
00747 }
00748 
00749 
00763 boolean
00764 Ctlp_FormulaTestIsConverted(
00765   Ctlp_Formula_t * formula)
00766 {
00767   return formula->dbgInfo.convertedFlag;
00768 }
00769 
00770 
00782 boolean
00783 Ctlp_FormulaTestIsQuantifierFree(
00784   Ctlp_Formula_t *formula)
00785 {
00786   boolean lCheck;
00787   boolean rCheck;
00788   Ctlp_Formula_t *leftChild;
00789   Ctlp_Formula_t *rightChild;
00790   Ctlp_FormulaType type;
00791 
00792   if ( formula == NIL( Ctlp_Formula_t ) ) {
00793     return TRUE;
00794   }
00795 
00796   type = Ctlp_FormulaReadType( formula );
00797 
00798   if ( ( type == Ctlp_ID_c ) ||
00799        ( type == Ctlp_TRUE_c ) ||
00800        ( type == Ctlp_FALSE_c ) ) {
00801     return TRUE;
00802   }
00803 
00804   if ( ( type !=  Ctlp_OR_c )   &&
00805        ( type !=  Ctlp_AND_c )  &&
00806        ( type !=  Ctlp_NOT_c )  &&
00807        ( type !=  Ctlp_THEN_c ) &&
00808        ( type !=  Ctlp_XOR_c )  &&
00809        ( type !=  Ctlp_EQ_c ) ) {
00810     return FALSE;
00811   }
00812 
00813   leftChild = Ctlp_FormulaReadLeftChild( formula );
00814   lCheck = Ctlp_FormulaTestIsQuantifierFree( leftChild );
00815 
00816   if (lCheck == FALSE)
00817     return FALSE;
00818 
00819   rightChild = Ctlp_FormulaReadRightChild( formula );
00820   rCheck = Ctlp_FormulaTestIsQuantifierFree( rightChild );
00821 
00822   return rCheck;
00823 }
00824 
00825 
00840 void
00841 Ctlp_FormulaNegations(
00842   Ctlp_Formula_t * formula,
00843   Ctlp_Parity_t parity)
00844 {
00845 
00846   Ctlp_FormulaType formulaType;
00847   Ctlp_Formula_t *leftChild;
00848   Ctlp_Formula_t *rightChild;
00849   Ctlp_Parity_t newparity;
00850 
00851   assert(formula != NIL(Ctlp_Formula_t));
00852   if (formula->negation_parity == parity)
00853     return; /* already done */
00854   if (formula->negation_parity != Ctlp_NoParity_c)
00855     parity = Ctlp_EvenOdd_c; /* reconverging paths with different parity */
00856   formula->negation_parity = parity;
00857 
00858   formulaType = Ctlp_FormulaReadType(formula);
00859   leftChild = Ctlp_FormulaReadLeftChild(formula);
00860   rightChild = Ctlp_FormulaReadRightChild(formula);
00861 
00862   switch (formulaType) {
00863   case Ctlp_AX_c:
00864   case Ctlp_AG_c:
00865   case Ctlp_AF_c:
00866   case Ctlp_EX_c:
00867   case Ctlp_EG_c:
00868   case Ctlp_EF_c:
00869     Ctlp_FormulaNegations(leftChild,parity);
00870     break;
00871   case Ctlp_AU_c:
00872   case Ctlp_EU_c:
00873   case Ctlp_OR_c:
00874   case Ctlp_AND_c:
00875     Ctlp_FormulaNegations(leftChild,parity);
00876     Ctlp_FormulaNegations(rightChild,parity);
00877     break;
00878   case Ctlp_NOT_c:
00879     if (parity == Ctlp_Even_c)
00880       newparity = Ctlp_Odd_c;
00881     else if (parity == Ctlp_Odd_c)
00882       newparity = Ctlp_Even_c;
00883     else newparity = Ctlp_EvenOdd_c;
00884     Ctlp_FormulaNegations(leftChild,newparity);
00885     break;
00886   case Ctlp_THEN_c:
00887     if (parity == Ctlp_Even_c)
00888       newparity = Ctlp_Odd_c;
00889     else if (parity == Ctlp_Odd_c)
00890       newparity = Ctlp_Even_c;
00891     else newparity = Ctlp_EvenOdd_c;
00892     Ctlp_FormulaNegations(leftChild,newparity);
00893     Ctlp_FormulaNegations(rightChild,parity);
00894     break;
00895   case Ctlp_XOR_c:
00896   case Ctlp_EQ_c:
00897     Ctlp_FormulaNegations(leftChild,Ctlp_EvenOdd_c);
00898     Ctlp_FormulaNegations(rightChild,Ctlp_EvenOdd_c);
00899     break;
00900   default:
00901       break;
00902   }
00903 }
00904 
00905 
00920 Ctlp_FormulaACTLSubClass
00921 Ctlp_CheckIfWACTL(
00922   Ctlp_Formula_t *formula)
00923 {
00924   Ctlp_FormulaType formulaType;
00925   Ctlp_Formula_t *rightFormula, *leftFormula;
00926   Ctlp_FormulaACTLSubClass resultLeft, resultRight;
00927 
00928   assert(formula != NIL(Ctlp_Formula_t));
00929   if(formula == NIL(Ctlp_Formula_t))
00930     return Ctlp_WACTLsimple_c;
00931 
00932   formulaType = Ctlp_FormulaReadType(formula);
00933   leftFormula = Ctlp_FormulaReadLeftChild(formula);
00934   rightFormula = Ctlp_FormulaReadRightChild(formula);
00935 
00936   /* Depending on the formula type, create result or recur. */
00937   switch (formulaType) {
00938   case Ctlp_AX_c:
00939   case Ctlp_AG_c:
00940   case Ctlp_AF_c:
00941     resultLeft = Ctlp_CheckIfWACTL(leftFormula);
00942     if (resultLeft == Ctlp_NONWACTL_c)
00943       return Ctlp_NONWACTL_c;
00944     else
00945       return Ctlp_WACTLstate_c;
00946     break;
00947   case Ctlp_AU_c:
00948     resultLeft = Ctlp_CheckIfWACTL(leftFormula);
00949     if (resultLeft == Ctlp_NONWACTL_c)
00950       return Ctlp_NONWACTL_c;
00951     resultRight = Ctlp_CheckIfWACTL(rightFormula);
00952     if (resultRight == Ctlp_NONWACTL_c)
00953       return Ctlp_NONWACTL_c;
00954     if (resultLeft == Ctlp_WACTLsimple_c || resultRight == Ctlp_WACTLsimple_c)
00955       return Ctlp_WACTLstate_c;
00956     else
00957       return Ctlp_NONWACTL_c;
00958     break;
00959   case Ctlp_OR_c:
00960   case Ctlp_AND_c:
00961   case Ctlp_THEN_c:
00962     resultLeft = Ctlp_CheckIfWACTL(leftFormula);
00963     if (resultLeft == Ctlp_NONWACTL_c) {
00964       return Ctlp_NONWACTL_c;
00965     } else {
00966       resultRight = Ctlp_CheckIfWACTL(rightFormula);
00967       if (resultRight == Ctlp_WACTLsimple_c) {
00968         return resultLeft;
00969       } else if (resultLeft == Ctlp_WACTLsimple_c) {
00970         return resultRight;
00971       } else {
00972         return Ctlp_NONWACTL_c;
00973       }
00974     }
00975     break;
00976   case Ctlp_NOT_c:
00977     resultLeft = Ctlp_CheckIfWACTL(leftFormula);
00978     return resultLeft;
00979     break;
00980   case Ctlp_XOR_c:
00981   case Ctlp_EQ_c:
00982     resultLeft = Ctlp_CheckIfWACTL(leftFormula);
00983     if (resultLeft != Ctlp_WACTLsimple_c) {
00984       return Ctlp_NONWACTL_c;
00985     } else {
00986       resultRight = Ctlp_CheckIfWACTL(rightFormula);
00987       if (resultRight == Ctlp_WACTLsimple_c)
00988         return Ctlp_WACTLsimple_c;
00989       else
00990         return Ctlp_NONWACTL_c;
00991     }
00992     break;
00993   case Ctlp_ID_c:
00994   case Ctlp_TRUE_c:
00995   case Ctlp_FALSE_c:
00996     return Ctlp_WACTLsimple_c;
00997     break;
00998   default:
00999     fprintf(vis_stderr, "#Ctlp Result : The formula should be in Universal operators!\n");
01000     return Ctlp_NONWACTL_c;
01001     break;
01002   }
01003 } /* End of Ctlp_CheckTypeOfExistentialFormula */
01004 
01005 
01013 Ctlp_Formula_t *
01014 Ctlp_FormulaReadOriginalFormula(
01015   Ctlp_Formula_t * formula)
01016 {
01017   return formula->dbgInfo.originalFormula;
01018 }
01019 
01020 
01034 void
01035 Ctlp_FormulaFree(
01036   Ctlp_Formula_t *formula)
01037 {
01038   CtlpFormulaDecrementRefCount(formula);
01039 }
01040 
01053 void
01054 Ctlp_FlushStates(
01055   Ctlp_Formula_t * formula)
01056 {
01057   if (formula != NIL(Ctlp_Formula_t)) {
01058 
01059     if (formula->type != Ctlp_ID_c){
01060       if (formula->left  != NIL(Ctlp_Formula_t)) {
01061         Ctlp_FlushStates(formula->left);
01062       }
01063       if (formula->right != NIL(Ctlp_Formula_t)) {
01064         Ctlp_FlushStates(formula->right);
01065       }
01066     }
01067 
01068     if (formula->states != NIL(mdd_t)){
01069       mdd_free(formula->states);
01070       formula->states = NIL(mdd_t);
01071     }
01072     if (formula->underapprox != NIL(mdd_t)){
01073       mdd_free(formula->underapprox);
01074       formula->underapprox = NIL(mdd_t);
01075     }
01076     if (formula->overapprox != NIL(mdd_t)){
01077       mdd_free(formula->overapprox);
01078       formula->overapprox = NIL(mdd_t);
01079     }
01080 
01081     if (formula->dbgInfo.data != NIL(void)){
01082       (*formula->dbgInfo.freeFn)(formula);
01083       formula->dbgInfo.data = NIL(void);
01084     }
01085 
01086   }
01087 
01088 }
01089 
01104 Ctlp_Formula_t *
01105 Ctlp_FormulaDup(
01106   Ctlp_Formula_t * formula)
01107 {
01108   Ctlp_Formula_t *result = NIL(Ctlp_Formula_t);
01109 
01110   if ( formula == NIL(Ctlp_Formula_t)) {
01111         return NIL(Ctlp_Formula_t);
01112   }
01113 
01114   result = ALLOC(Ctlp_Formula_t, 1);
01115 
01116   result->type                    = formula->type;
01117   result->states                  = NIL(mdd_t);
01118   result->underapprox             = NIL(mdd_t);
01119   result->overapprox              = NIL(mdd_t);
01120   result->latest                  = Ctlp_Incomparable_c;
01121   result->Bottomstates            = NIL(array_t);
01122   result->Topstates               = NIL(array_t);
01123   result->negation_parity         = Ctlp_NoParity_c;
01124   result->leaves                  = formula->leaves == NIL(array_t) ?
01125     NIL(array_t) : array_dup(formula->leaves);
01126   result->matchfound_top          = NIL(array_t);
01127   result->matchelement_top        = NIL(array_t);
01128   result->matchfound_bot          = NIL(array_t);
01129   result->matchelement_bot        = NIL(array_t);
01130   result->refCount                = 1;
01131   result->dbgInfo.data            = NIL(void);
01132   result->dbgInfo.freeFn          = (Ctlp_DbgInfoFreeFn) NULL;
01133   result->dbgInfo.convertedFlag   = FALSE;
01134   result->dbgInfo.originalFormula = NIL(Ctlp_Formula_t);
01135   result->top                     = 0;
01136   result->compareValue            = 0;
01137 
01138   if ( formula->type != Ctlp_ID_c )  {
01139     result->left                    = Ctlp_FormulaDup( formula->left );
01140     result->right                   = Ctlp_FormulaDup( formula->right );
01141   }
01142   else {
01143     result->left  = (Ctlp_Formula_t *) util_strsav((char *)formula->left );
01144     result->right = (Ctlp_Formula_t *) util_strsav((char *)formula->right );
01145   }
01146   result->share           = 1;
01147   result->BotOnionRings   = NIL(array_t);
01148   result->TopOnionRings   = NIL(array_t);
01149   return result;
01150 }
01151 
01164 Ctlp_Formula_t *
01165 Ctlp_FormulaConverttoComplement(
01166   Ctlp_Formula_t * formula)
01167 {
01168   Ctlp_Formula_t *result;
01169 
01170   if (formula == NIL(Ctlp_Formula_t)) {
01171         return NIL(Ctlp_Formula_t);
01172   }
01173   result = Ctlp_FormulaCreate(Ctlp_NOT_c,formula,NIL(Ctlp_Formula_t));
01174   CtlpFormulaIncrementRefCount(formula);
01175 #if 0
01176   result = FormulaCreateWithType(Ctlp_NOT_c);
01177   result->left = FormulaCreateWithType(formula->type);
01178   result->left->left = formula->left;
01179   result->left->right = formula->right;
01180   switch (formula->type) {
01181   case Ctlp_ID_c:
01182   case Ctlp_TRUE_c:
01183   case Ctlp_FALSE_c:
01184   case Ctlp_Init_c:
01185     break;
01186   default:
01187     CtlpFormulaIncrementRefCount(formula->left);
01188     CtlpFormulaIncrementRefCount(formula->right);
01189     break;
01190   }
01191 #endif
01192   return result;
01193 } /* Ctlp_FormulaConverttoComplement */
01194 
01195 
01208 Ctlp_Formula_t *
01209 Ctlp_FormulaConvertAFtoAU(
01210   Ctlp_Formula_t * formula)
01211 {
01212   Ctlp_Formula_t *result;
01213   /* AFf --> (A true U f)  */
01214   assert(formula->type == Ctlp_AF_c);
01215   result = FormulaCreateWithType(Ctlp_AU_c);
01216   result->left  = FormulaCreateWithType(Ctlp_TRUE_c);
01217   result->right = formula->left;
01218   CtlpFormulaIncrementRefCount(formula->left);
01219   return result;
01220 }
01221 
01222 
01235 Ctlp_Formula_t *
01236 Ctlp_FormulaConvertEFtoOR(
01237   Ctlp_Formula_t * formula)
01238 {
01239   Ctlp_Formula_t *result;
01240   /* EFf --> f + EX(EF(f))  */
01241   assert(formula->type == Ctlp_EF_c);
01242   result = FormulaCreateWithType(Ctlp_OR_c);
01243   result->left = formula->left;
01244   result->right = FormulaCreateWithType(Ctlp_EX_c);
01245   result->right->left = formula;
01246   CtlpFormulaIncrementRefCount(formula->left);
01247   CtlpFormulaIncrementRefCount(formula);
01248   return result;
01249 }
01250 
01251 
01264 Ctlp_Formula_t *
01265 Ctlp_FormulaConvertEUtoOR(
01266   Ctlp_Formula_t * formula)
01267 {
01268   Ctlp_Formula_t *result;
01269   assert(formula->type == Ctlp_EU_c);
01270   /* E(f1)U(f2) --> f2 + f1*EX( E(f1)U(f2) )  */
01271   result = FormulaCreateWithType(Ctlp_OR_c);
01272   result->left = formula->right;
01273   result->right = FormulaCreateWithType(Ctlp_AND_c);
01274   result->right->left = formula->left;
01275   result->right->right = FormulaCreateWithType(Ctlp_EX_c);
01276   result->right->right->left = formula;
01277   CtlpFormulaIncrementRefCount(formula->left);
01278   CtlpFormulaIncrementRefCount(formula->right);
01279   CtlpFormulaIncrementRefCount(formula);
01280   return result;
01281 }
01282 
01283 
01296 Ctlp_Formula_t *
01297 Ctlp_FormulaConvertXORtoOR(
01298   Ctlp_Formula_t * formula)
01299 {
01300   Ctlp_Formula_t *result;
01301   assert(formula->type == Ctlp_XOR_c);
01302   result = FormulaCreateWithType(Ctlp_OR_c);
01303   result->left = FormulaCreateWithType(Ctlp_AND_c);
01304   result->right = FormulaCreateWithType(Ctlp_AND_c);
01305   result->left->left = Ctlp_FormulaConverttoComplement(formula->left);
01306   result->left->right = formula->right;
01307   result->right->left = formula->left;
01308   result->right->right = Ctlp_FormulaConverttoComplement(formula->right);
01309   CtlpFormulaIncrementRefCount(formula->left);
01310   CtlpFormulaIncrementRefCount(formula->right);
01311   return result;
01312 }
01313 
01314 
01327 Ctlp_Formula_t *
01328 Ctlp_FormulaConvertEQtoOR(
01329   Ctlp_Formula_t * formula)
01330 {
01331   Ctlp_Formula_t *result;
01332   assert(formula->type == Ctlp_EQ_c);
01333   result = FormulaCreateWithType(Ctlp_OR_c);
01334   result->left = FormulaCreateWithType(Ctlp_AND_c);
01335   result->right = FormulaCreateWithType(Ctlp_AND_c);
01336   result->left->left = formula->left;
01337   result->left->right = formula->right;
01338   result->right->left = Ctlp_FormulaConverttoComplement(formula->left);
01339   result->right->right = Ctlp_FormulaConverttoComplement(formula->right);
01340   CtlpFormulaIncrementRefCount(formula->left);
01341   CtlpFormulaIncrementRefCount(formula->right);
01342   return result;
01343 }
01344 
01345 
01356 Ctlp_Formula_t *
01357 Ctlp_FormulaPushNegation(
01358   Ctlp_Formula_t * formula)
01359 {
01360   Ctlp_Formula_t *result;
01361   if (formula == NIL(Ctlp_Formula_t)) {
01362     return NIL(Ctlp_Formula_t);
01363   }
01364 
01365   switch(formula->type) {
01366     /*
01367      * The cases are listed in rough order of their expected frequency.
01368      */
01369   case Ctlp_OR_c: 
01370     result = FormulaCreateWithType(Ctlp_AND_c);
01371     result->left  = Ctlp_FormulaConverttoComplement(formula->left);
01372     result->right = Ctlp_FormulaConverttoComplement(formula->right);
01373     break;
01374   case Ctlp_AND_c: 
01375     result = FormulaCreateWithType(Ctlp_OR_c);
01376     result->left  = Ctlp_FormulaConverttoComplement(formula->left);
01377     result->right = Ctlp_FormulaConverttoComplement(formula->right);
01378     break;
01379   case Ctlp_THEN_c: 
01380     result = FormulaCreateWithType(Ctlp_AND_c);
01381     result->left  = formula->left;
01382     CtlpFormulaIncrementRefCount(formula->left);
01383     result->right = Ctlp_FormulaConverttoComplement(formula->right);
01384     break;
01385   case Ctlp_XOR_c: 
01386     result = FormulaCreateWithType(Ctlp_EQ_c);
01387     result->left  = formula->left;
01388     result->right = formula->right;
01389     CtlpFormulaIncrementRefCount(formula->left);
01390     CtlpFormulaIncrementRefCount(formula->right);
01391     break;
01392   case Ctlp_EQ_c: 
01393     result = FormulaCreateWithType(Ctlp_XOR_c);
01394     result->left  = formula->left;
01395     result->right = formula->right;
01396     CtlpFormulaIncrementRefCount(formula->left);
01397     CtlpFormulaIncrementRefCount(formula->right);
01398     break;
01399   case Ctlp_NOT_c:/* !(!f1) = f1*/
01400     result = formula->left;
01401     CtlpFormulaIncrementRefCount(formula->left);
01402     break;
01403   case Ctlp_EX_c:/* !(EX(f1)) = AX(!f1)*/
01404     result = FormulaCreateWithType(Ctlp_AX_c);
01405     result->left  = Ctlp_FormulaConverttoComplement(formula->left);
01406     break;
01407   case Ctlp_EG_c: 
01408     result = FormulaCreateWithType(Ctlp_AF_c);
01409     result->left  = Ctlp_FormulaConverttoComplement(formula->left);
01410     break;
01411   case Ctlp_EF_c: 
01412     result = FormulaCreateWithType(Ctlp_AG_c);
01413     result->left  = Ctlp_FormulaConverttoComplement(formula->left);
01414     break;
01415   case Ctlp_EU_c: /* !(EpUq) = A(!q)U(!(p+q) + AG(!q))*/
01416     result = FormulaCreateWithType(Ctlp_AU_c);
01417     result->left  = Ctlp_FormulaConverttoComplement(formula->right);
01418     result->right = FormulaCreateWithType(Ctlp_OR_c);
01419     result->right->left = FormulaCreateWithType(Ctlp_NOT_c);
01420     result->right->left->left = FormulaCreateWithType(Ctlp_OR_c);
01421     result->right->left->left->left = formula->left;
01422     result->right->left->left->right = formula->right;
01423     result->right->right = FormulaCreateWithType(Ctlp_AG_c);
01424     result->right->right->left = Ctlp_FormulaConverttoComplement(formula->right);
01425     CtlpFormulaIncrementRefCount(formula->left);
01426     CtlpFormulaIncrementRefCount(formula->right);
01427     break;
01428   case Ctlp_AX_c:/* !AX(f1) = EX(!f1)*/
01429     result = FormulaCreateWithType(Ctlp_EX_c);
01430     result->left  = Ctlp_FormulaConverttoComplement(formula->left);
01431     break;
01432   case Ctlp_AG_c:/* !AG(f1) = EF(!f1) */
01433     result = FormulaCreateWithType(Ctlp_EF_c);
01434     result->left  = Ctlp_FormulaConverttoComplement(formula->left);
01435     break;
01436   case Ctlp_AF_c: /* !AF(f1) = EG(!f1)*/
01437     result = FormulaCreateWithType(Ctlp_EG_c);
01438     result->left  = Ctlp_FormulaConverttoComplement(formula->left);
01439     break;
01440   case Ctlp_AU_c: /* !(ApUq) = (E(!q)U(!(p+q)))+(EG!q)*/
01441     result = FormulaCreateWithType(Ctlp_OR_c);
01442     result->left = FormulaCreateWithType(Ctlp_EU_c);
01443     result->left->left  = Ctlp_FormulaConverttoComplement(formula->right);
01444     result->left->right = FormulaCreateWithType(Ctlp_NOT_c);
01445     result->left->right->left= FormulaCreateWithType(Ctlp_OR_c);
01446     result->left->right->left->left = formula->left;
01447     result->left->right->left->right = formula->right;
01448     result->right = FormulaCreateWithType(Ctlp_EG_c);
01449     result->right->left = Ctlp_FormulaConverttoComplement(formula->right);
01450     CtlpFormulaIncrementRefCount(formula->left);
01451     CtlpFormulaIncrementRefCount(formula->right);
01452     break;
01453   case Ctlp_TRUE_c:/* !TRUE = FALSE*/
01454     result = FormulaCreateWithType(Ctlp_FALSE_c);
01455     break;
01456   case Ctlp_FALSE_c:
01457     result = FormulaCreateWithType(Ctlp_TRUE_c);
01458     break;
01459   case Ctlp_Init_c: /* ???*/
01460   case Ctlp_Cmp_c: /* ???*/
01461     /* if (formula->compareValue == 0)
01462         tmpString = util_strcat3("[", s1, "] = ");
01463       else
01464         tmpString = util_strcat3("[", s1, "] != ");
01465       result    = util_strcat3(tmpString, s2, "");
01466       break;*/
01467   case Ctlp_FwdU_c: /* ???*/
01468   case Ctlp_FwdG_c:  /* ??? */
01469   case Ctlp_EY_c: /* ??? */
01470     result = formula;
01471     break;
01472   default:
01473       fail("Unexpected type");
01474   }
01475 
01476   return result;
01477 }
01478 /*****************************************************************************/
01479 
01494 void
01495 Ctlp_FormulaArrayFree(
01496   array_t * formulaArray /* of Ctlp_Formula_t */)
01497 {
01498   int i;
01499   int numFormulas = array_n(formulaArray);
01500 
01501   assert(formulaArray != NIL(array_t));
01502   for (i = 0; i < numFormulas; i++) {
01503     Ctlp_Formula_t *formula = array_fetch(Ctlp_Formula_t *, formulaArray, i);
01504 
01505     CtlpFormulaDecrementRefCount(formula);
01506   }
01507 
01508   array_free(formulaArray);
01509 }
01510 
01511 
01551 Ctlp_Formula_t *
01552 Ctlp_FormulaConvertToExistentialForm(
01553   Ctlp_Formula_t * formula)
01554 {
01555   Ctlp_Formula_t *new_;
01556   char *variableNameCopy, *valueNameCopy;
01557 
01558   if (formula == NIL(Ctlp_Formula_t)) {
01559     return NIL(Ctlp_Formula_t);
01560   }
01561 
01562   /*
01563    * Recursively convert each subformula.
01564    */
01565 
01566   switch(formula->type) {
01567     case Ctlp_EF_c:
01568       /* EFf --> (E true U f)  */
01569       new_ = FormulaCreateWithType(Ctlp_EU_c);
01570       new_->left  = FormulaCreateWithType(Ctlp_TRUE_c);
01571       new_->right = Ctlp_FormulaConvertToExistentialForm(formula->left);
01572       new_->dbgInfo.convertedFlag = TRUE;
01573       break;
01574 
01575     case Ctlp_AX_c:
01576       /* AXf --> !(EX(!f)) */
01577       new_ = FormulaCreateWithType(Ctlp_NOT_c);
01578       new_->left = FormulaCreateWithType(Ctlp_EX_c);
01579       new_->left->left = FormulaCreateWithType(Ctlp_NOT_c);
01580       new_->left->left->left = Ctlp_FormulaConvertToExistentialForm(formula->left);
01581       new_->dbgInfo.convertedFlag = TRUE;
01582       break;
01583 
01584     case Ctlp_AG_c:
01585       /* AGf --> ![(E true U !f)] */
01586       new_ = FormulaCreateWithType(Ctlp_NOT_c);
01587       new_->left = FormulaCreateWithType(Ctlp_EU_c);
01588       new_->left->left = FormulaCreateWithType(Ctlp_TRUE_c);
01589       new_->left->right = FormulaCreateWithType(Ctlp_NOT_c);
01590       new_->left->right->left = Ctlp_FormulaConvertToExistentialForm(formula->left);
01591       new_->dbgInfo.convertedFlag = TRUE;
01592       break;
01593 
01594     case Ctlp_AF_c:
01595       /* AFf --> ![EG(!f)] */
01596       new_ = FormulaCreateWithType(Ctlp_NOT_c);
01597       new_->left = FormulaCreateWithType(Ctlp_EG_c);
01598       new_->left->left = FormulaCreateWithType(Ctlp_NOT_c);
01599       new_->left->left->left = Ctlp_FormulaConvertToExistentialForm(formula->left);
01600       new_->dbgInfo.convertedFlag = TRUE;
01601       break;
01602 
01603     case Ctlp_AU_c:
01604       /* A[fUg] --> !((E[!g U (!f*!g)]) + (EG!g)) */
01605 
01606       new_ = FormulaCreateWithType(Ctlp_NOT_c); /* top */
01607       new_->left = FormulaCreateWithType(Ctlp_OR_c); /* ((E[!g U (!f*!g)]) + (EG!g)) */
01608 
01609       new_->left->right = FormulaCreateWithType(Ctlp_EG_c); /* EG !g */
01610       new_->left->right->left = FormulaCreateWithType(Ctlp_NOT_c); /* !g */
01611       new_->left->right->left->left = Ctlp_FormulaConvertToExistentialForm(formula->right); /* g */
01612 
01613       new_->left->left = FormulaCreateWithType(Ctlp_EU_c); /* E[!g U (!f*!g)] */
01614       new_->left->left->left = FormulaCreateWithType(Ctlp_NOT_c); /* !g */
01615       new_->left->left->left->left = Ctlp_FormulaConvertToExistentialForm(formula->right); /* g */
01616       new_->left->left->right = FormulaCreateWithType(Ctlp_AND_c); /* !f*!g */
01617       new_->left->left->right->left = FormulaCreateWithType(Ctlp_NOT_c); /* !f */
01618       new_->left->left->right->left->left = Ctlp_FormulaConvertToExistentialForm(formula->left); /* f */
01619       new_->left->left->right->right = FormulaCreateWithType(Ctlp_NOT_c); /* !g */
01620       new_->left->left->right->right->left = Ctlp_FormulaConvertToExistentialForm(formula->right); /* g */
01621       new_->dbgInfo.convertedFlag = TRUE;
01622       break;
01623 
01624     case Ctlp_ID_c:
01625       /* Make a copy of the name, and create a new formula. */
01626       variableNameCopy = util_strsav((char *)(formula->left));
01627       valueNameCopy = util_strsav((char *)(formula->right));
01628       new_ = Ctlp_FormulaCreate(Ctlp_ID_c, variableNameCopy, valueNameCopy);
01629       break;
01630 
01631     case Ctlp_THEN_c:
01632     case Ctlp_EX_c:
01633     case Ctlp_EG_c:
01634     case Ctlp_EU_c:
01635     case Ctlp_OR_c:
01636     case Ctlp_AND_c:
01637     case Ctlp_NOT_c:
01638     case Ctlp_XOR_c:
01639     case Ctlp_EQ_c:
01640     case Ctlp_TRUE_c:
01641     case Ctlp_FALSE_c:
01642       /* These are already in the correct form.  Just convert subformulas. */
01643       new_ = FormulaCreateWithType(formula->type);
01644       new_->left = Ctlp_FormulaConvertToExistentialForm(formula->left);
01645       new_->right = Ctlp_FormulaConvertToExistentialForm(formula->right);
01646       break;
01647 
01648     default:
01649       fail("Unexpected type");
01650   }
01651 
01652   new_->dbgInfo.originalFormula = formula;
01653   return new_;
01654 }
01655 
01681 Ctlp_Formula_t *
01682 Ctlp_FormulaConvertToSimpleExistentialForm(
01683   Ctlp_Formula_t * formula)
01684 {
01685   Ctlp_Formula_t *new_;
01686   char *variableNameCopy, *valueNameCopy;
01687 
01688   if (formula == NIL(Ctlp_Formula_t)) {
01689     return NIL(Ctlp_Formula_t);
01690   }
01691 
01692   /*
01693    * Recursively convert each subformula.
01694    */
01695 
01696   switch(formula->type) {
01697     case Ctlp_EF_c:
01698       /* EFf --> (E true U f)  */
01699       new_ = FormulaCreateWithType(Ctlp_EU_c);
01700       new_->left  = FormulaCreateWithType(Ctlp_TRUE_c);
01701       new_->right = Ctlp_FormulaConvertToSimpleExistentialForm(formula->left);
01702       new_->dbgInfo.convertedFlag = TRUE;
01703       break;
01704 
01705     case Ctlp_AX_c:
01706       /* AXf --> !(EX(!f)) */
01707       new_ = FormulaCreateWithType(Ctlp_NOT_c);
01708       new_->left = FormulaCreateWithType(Ctlp_EX_c);
01709       new_->left->left = FormulaCreateWithType(Ctlp_NOT_c);
01710       new_->left->left->left =
01711         Ctlp_FormulaConvertToSimpleExistentialForm(formula->left);
01712       new_->dbgInfo.convertedFlag = TRUE;
01713       break;
01714 
01715     case Ctlp_AG_c:
01716       /* AGf --> ![(E true U !f)] */
01717       new_ = FormulaCreateWithType(Ctlp_NOT_c);
01718       new_->left = FormulaCreateWithType(Ctlp_EU_c);
01719       new_->left->left = FormulaCreateWithType(Ctlp_TRUE_c);
01720       new_->left->right = FormulaCreateWithType(Ctlp_NOT_c);
01721       new_->left->right->left =
01722         Ctlp_FormulaConvertToSimpleExistentialForm(formula->left);
01723       new_->dbgInfo.convertedFlag = TRUE;
01724       break;
01725 
01726     case Ctlp_AF_c:
01727       /* AFf --> ![EG(!f)] */
01728       new_ = FormulaCreateWithType(Ctlp_NOT_c);
01729       new_->left = FormulaCreateWithType(Ctlp_EG_c);
01730       new_->left->left = FormulaCreateWithType(Ctlp_NOT_c);
01731       new_->left->left->left = Ctlp_FormulaConvertToSimpleExistentialForm(formula->left);
01732       new_->dbgInfo.convertedFlag = TRUE;
01733       break;
01734 
01735     case Ctlp_AU_c:
01736       /* A[fUg] --> !(E[!g U (!f*!g)]) * !(EG!g)) */
01737 
01738       new_ = FormulaCreateWithType(Ctlp_AND_c); /* top */
01739       new_->left = FormulaCreateWithType(Ctlp_NOT_c);
01740       new_->right = FormulaCreateWithType(Ctlp_NOT_c);
01741       new_->left->left = FormulaCreateWithType(Ctlp_EG_c); /* EG !g */
01742       new_->left->left->left = FormulaCreateWithType(Ctlp_NOT_c); /* !g */
01743       new_->left->left->left->left =
01744         Ctlp_FormulaConvertToSimpleExistentialForm(formula->right); /* g */
01745 
01746       new_->right->left = FormulaCreateWithType(Ctlp_EU_c); /* E[!g U (!f*!g)] */
01747       new_->right->left->left = FormulaCreateWithType(Ctlp_NOT_c); /* !g */
01748       new_->right->left->left->left =
01749         Ctlp_FormulaConvertToSimpleExistentialForm(formula->right); /* g */
01750       new_->right->left->right = FormulaCreateWithType(Ctlp_AND_c); /* !f*!g */
01751       new_->right->left->right->left = FormulaCreateWithType(Ctlp_NOT_c); /* !f */
01752       new_->right->left->right->left->left =
01753         Ctlp_FormulaConvertToSimpleExistentialForm(formula->left); /* f */
01754       new_->right->left->right->right = FormulaCreateWithType(Ctlp_NOT_c); /* !g */
01755       new_->right->left->right->right->left =
01756         Ctlp_FormulaConvertToSimpleExistentialForm(formula->right); /* g */
01757       new_->dbgInfo.convertedFlag = TRUE;
01758       break;
01759 
01760     case Ctlp_ID_c:
01761       /* Make a copy of the name, and create a new formula. */
01762       variableNameCopy = util_strsav((char *)(formula->left));
01763       valueNameCopy = util_strsav((char *)(formula->right));
01764       new_ = Ctlp_FormulaCreate(Ctlp_ID_c, variableNameCopy, valueNameCopy);
01765       break;
01766 
01767       /* RB: I think THEN (and also OR, and maybe some others) should also have converted set. */
01768     case Ctlp_THEN_c:
01769       /* p->q --> !(p * !q) */
01770       new_ = FormulaCreateWithType(Ctlp_NOT_c);
01771       new_->left = FormulaCreateWithType(Ctlp_AND_c);
01772       new_->left->left =
01773         Ctlp_FormulaConvertToSimpleExistentialForm(formula->left);
01774       new_->left->right = FormulaCreateWithType(Ctlp_NOT_c);
01775       new_->left->right->left =
01776         Ctlp_FormulaConvertToSimpleExistentialForm(formula->right);
01777       break;
01778 
01779     case Ctlp_EX_c:
01780     case Ctlp_EG_c:
01781     case Ctlp_EU_c:
01782     case Ctlp_AND_c:
01783     case Ctlp_NOT_c:
01784     case Ctlp_TRUE_c:
01785     case Ctlp_FALSE_c:
01786       /* These are already in the correct form.  Just convert subformulas. */
01787       new_ = FormulaCreateWithType(formula->type);
01788       new_->left = Ctlp_FormulaConvertToSimpleExistentialForm(formula->left);
01789       new_->right = Ctlp_FormulaConvertToSimpleExistentialForm(formula->right);
01790       break;
01791 
01792     case Ctlp_OR_c:
01793       /* p + q --> !(!p * !q) */
01794       new_ = FormulaCreateWithType(Ctlp_NOT_c);
01795       new_->left = FormulaCreateWithType(Ctlp_AND_c);
01796       new_->left->left = FormulaCreateWithType(Ctlp_NOT_c);
01797       new_->left->right = FormulaCreateWithType(Ctlp_NOT_c);
01798       new_->left->left->left =
01799         Ctlp_FormulaConvertToSimpleExistentialForm(formula->left);
01800       new_->left->right->left =
01801         Ctlp_FormulaConvertToSimpleExistentialForm(formula->right);
01802       break;
01803     case Ctlp_XOR_c:
01804       /* p ^ q --> !(p * q) * !(!p * !q) */
01805       new_ = FormulaCreateWithType(Ctlp_AND_c);
01806       new_->left = FormulaCreateWithType(Ctlp_NOT_c);
01807       new_->left->left = FormulaCreateWithType(Ctlp_AND_c);
01808       new_->left->left->left =
01809         Ctlp_FormulaConvertToSimpleExistentialForm(formula->left);
01810       new_->left->left->right =
01811         Ctlp_FormulaConvertToSimpleExistentialForm(formula->right);
01812       new_->right = FormulaCreateWithType(Ctlp_NOT_c);
01813       new_->right->left = FormulaCreateWithType(Ctlp_AND_c);
01814       new_->right->left->left =  FormulaCreateWithType(Ctlp_NOT_c);
01815       new_->right->left->left->left =
01816         Ctlp_FormulaConvertToSimpleExistentialForm(formula->left);
01817       new_->right->left->right = FormulaCreateWithType(Ctlp_NOT_c);
01818       new_->right->left->right->left =
01819         Ctlp_FormulaConvertToSimpleExistentialForm(formula->right);
01820       break;
01821 
01822     case Ctlp_EQ_c:
01823       /* p <-> q --> !(p * !q) * !(!p * q) */
01824       new_ = FormulaCreateWithType(Ctlp_AND_c);
01825       new_->left = FormulaCreateWithType(Ctlp_NOT_c);
01826       new_->left->left = FormulaCreateWithType(Ctlp_AND_c);
01827       new_->left->left->left =
01828         Ctlp_FormulaConvertToSimpleExistentialForm(formula->left);
01829       new_->left->left->right = FormulaCreateWithType(Ctlp_NOT_c);
01830       new_->left->left->right->left =
01831         Ctlp_FormulaConvertToSimpleExistentialForm(formula->right);
01832       new_->right = FormulaCreateWithType(Ctlp_NOT_c);
01833       new_->right->left = FormulaCreateWithType(Ctlp_AND_c);
01834       new_->right->left->left =  FormulaCreateWithType(Ctlp_NOT_c);
01835       new_->right->left->left->left =
01836         Ctlp_FormulaConvertToSimpleExistentialForm(formula->left);
01837       new_->right->left->right =
01838         Ctlp_FormulaConvertToSimpleExistentialForm(formula->right);
01839       break;
01840 
01841     default:
01842       fail("Unexpected type");
01843   }
01844 
01845   new_->dbgInfo.originalFormula = formula;
01846   return new_;
01847 }
01848 
01865 array_t *
01866 Ctlp_FormulaArrayConvertToExistentialFormTree(
01867   array_t * formulaArray /* of Ctlp_Formula_t  */)
01868 {
01869   int i;
01870   int numFormulas = array_n(formulaArray);
01871   array_t *convertedArray = array_alloc(Ctlp_Formula_t *, numFormulas);
01872 
01873   assert(formulaArray != NIL(array_t));
01874 
01875   for (i = 0; i < numFormulas; i++) {
01876     Ctlp_Formula_t *formula          = array_fetch(Ctlp_Formula_t *, formulaArray, i);
01877     Ctlp_Formula_t *convertedFormula = Ctlp_FormulaConvertToExistentialForm(formula);
01878 
01879     array_insert(Ctlp_Formula_t *, convertedArray, i, convertedFormula);
01880   }
01881 
01882   return convertedArray;
01883 }
01884 
01899 array_t *
01900 Ctlp_FormulaArrayConvertToSimpleExistentialFormTree(
01901   array_t * formulaArray /* of Ctlp_Formula_t  */)
01902 {
01903   int i;
01904   int numFormulas;
01905   array_t *convertedArray;
01906 
01907   assert( formulaArray != NIL(array_t));
01908 
01909   numFormulas = array_n(formulaArray);
01910   convertedArray = array_alloc(Ctlp_Formula_t *, numFormulas);
01911 
01912   for (i = 0; i < numFormulas; i++) {
01913     Ctlp_Formula_t *formula;
01914     Ctlp_Formula_t *convertedFormula;
01915 
01916     formula = array_fetch(Ctlp_Formula_t *, formulaArray, i);
01917     convertedFormula = Ctlp_FormulaConvertToSimpleExistentialForm(formula);
01918 
01919     array_insert(Ctlp_Formula_t *, convertedArray, i, convertedFormula);
01920   }
01921 
01922   return convertedArray;
01923 }
01924 
01962 array_t *
01963 Ctlp_FormulaArrayConvertToDAG(
01964   array_t *formulaArray)
01965 {
01966   int i;
01967   Ctlp_Formula_t *formula, *uniqueFormula;
01968   st_table *uniqueTable = st_init_table(FormulaCompare, FormulaHash);
01969   int numFormulae = array_n(formulaArray);
01970   array_t *rootsOfFormulaDAG = array_alloc(Ctlp_Formula_t *, numFormulae);
01971 
01972   assert(formulaArray != NIL(array_t));
01973 
01974   for(i=0; i < numFormulae; i++) {
01975     formula = array_fetch(Ctlp_Formula_t *, formulaArray, i);
01976     uniqueFormula = FormulaHashIntoUniqueTable(formula, uniqueTable);
01977     if(uniqueFormula != formula) {
01978       CtlpFormulaDecrementRefCount(formula);
01979       CtlpFormulaIncrementRefCount(uniqueFormula);
01980       array_insert(Ctlp_Formula_t *, rootsOfFormulaDAG, i, uniqueFormula);
01981     }
01982     else
01983       array_insert(Ctlp_Formula_t *, rootsOfFormulaDAG, i, formula);
01984   }
01985   st_free_table(uniqueTable);
01986   return rootsOfFormulaDAG;
01987 }
01988 
02008 array_t *
02009 Ctlp_FormulaDAGConvertToExistentialFormDAG(
02010   array_t *formulaDAG)
02011 {
02012   int i;
02013   Ctlp_Formula_t *formula;
02014   int numFormulae = array_n(formulaDAG);
02015   array_t *existentialFormulaDAG = array_alloc(Ctlp_Formula_t *, numFormulae);
02016 
02017   assert( formulaDAG != NIL(array_t));
02018 
02019   for(i=0; i<numFormulae; i++) {
02020     formula = array_fetch(Ctlp_Formula_t *, formulaDAG, i);
02021     array_insert(Ctlp_Formula_t *, existentialFormulaDAG, i,
02022                  FormulaConvertToExistentialDAG(formula));
02023   }
02024   for(i=0; i<numFormulae; i++) {
02025     formula = array_fetch(Ctlp_Formula_t *, formulaDAG, i);
02026     CtlpFormulaSetStatesToNULL(formula);
02027   }
02028   return existentialFormulaDAG;
02029 }
02030 
02031 
02050 Ctlp_Formula_t *
02051 Ctlp_FormulaCreate(
02052   Ctlp_FormulaType  type,
02053   void * left,
02054   void * right)
02055 {
02056   Ctlp_Formula_t *formula = ALLOC(Ctlp_Formula_t, 1);
02057 
02058   formula->type                    = type;
02059   formula->left                    = (Ctlp_Formula_t *)left;
02060   formula->right                   = (Ctlp_Formula_t *)right;
02061   formula->refCount                = 1;
02062   formula->states                  = NIL(mdd_t);
02063   formula->underapprox             = NIL(mdd_t);
02064   formula->overapprox              = NIL(mdd_t);
02065   formula->Topstates               = NIL(array_t);
02066   formula->Bottomstates            = NIL(array_t);
02067   formula->leaves                  = NIL(array_t);
02068   formula->matchfound_top          = NIL(array_t);
02069   formula->matchelement_top        = NIL(array_t);
02070   formula->matchfound_bot          = NIL(array_t);
02071   formula->matchelement_bot        = NIL(array_t);
02072   formula->negation_parity         = Ctlp_NoParity_c;
02073   formula->share                   = 1;
02074   formula->dbgInfo.data            = NIL(void);
02075   formula->dbgInfo.freeFn          = (Ctlp_DbgInfoFreeFn) NULL;
02076   formula->dbgInfo.convertedFlag   = FALSE;
02077   formula->dbgInfo.originalFormula = NIL(Ctlp_Formula_t);
02078   formula->top                     = 0;
02079   formula->compareValue            = 0;
02080   formula->latest                  = Ctlp_Incomparable_c;
02081   formula->BotOnionRings           = NIL(array_t);
02082   formula->TopOnionRings           = NIL(array_t);
02083 
02084   return formula;
02085 }
02086 
02087 
02100 Ctlp_Formula_t *
02101 Ctlp_FormulaCreateOr(
02102   char *name,
02103   char *valueStr)
02104 {
02105   Ctlp_Formula_t *formula, *tempFormula;
02106   char *preStr;
02107 
02108   preStr = strtok(valueStr,",");
02109   formula = Ctlp_FormulaCreate(Ctlp_ID_c, util_strsav(name),
02110                                util_strsav(preStr));
02111   if (formula == NIL(Ctlp_Formula_t)) {
02112      return NIL(Ctlp_Formula_t);
02113   }
02114   while ((preStr = strtok(NIL(char),",")) != NIL(char)) {
02115     tempFormula = Ctlp_FormulaCreate(Ctlp_ID_c, util_strsav(name),
02116                                      util_strsav(preStr));
02117     if (tempFormula == NIL(Ctlp_Formula_t)) {
02118       Ctlp_FormulaFree(formula);
02119       return NIL(Ctlp_Formula_t);
02120     }
02121     formula = Ctlp_FormulaCreate(Ctlp_OR_c,formula,tempFormula);
02122   }
02123   return formula;
02124 }
02125 
02126 
02142 Ctlp_Formula_t *
02143 Ctlp_FormulaCreateVectorAnd(
02144   char *nameVector,
02145   char *value)
02146 {
02147   Ctlp_Formula_t *formula, *tempFormula;
02148   int startValue, endValue, inc, i,j, interval,startInd;
02149   char *binValueStr, *varName, *name;
02150   char *bitValue;
02151 
02152   varName = CtlpGetVectorInfoFromStr(nameVector,&startValue,&endValue,&interval,&inc);
02153   binValueStr = ALLOC(char,interval+1);
02154   if (!CtlpStringChangeValueStrToBinString(value,binValueStr,interval) ){
02155     FREE(varName);
02156     FREE(binValueStr);
02157     return NIL(Ctlp_Formula_t);
02158   }
02159 
02160   name = ALLOC(char,MAX_LENGTH_OF_VAR_NAME);
02161   (void) sprintf(name,"%s[%d]",varName,startValue);
02162   (void) CtlpChangeBracket(name);
02163 
02164   bitValue = ALLOC(char,2);
02165   bitValue[0] = binValueStr[0];
02166   bitValue[1] = '\0';
02167 
02168   formula = Ctlp_FormulaCreate(Ctlp_ID_c, util_strsav(name),
02169                                util_strsav(bitValue));
02170   j = 0;
02171   startInd = startValue;
02172   for(i=startValue;i!=endValue;i=i+inc){
02173     startInd += inc;
02174     j++;
02175     (void) sprintf(name,"%s[%d]",varName,startInd);
02176     (void) CtlpChangeBracket(name);
02177     bitValue[0] = binValueStr[j];
02178     tempFormula = Ctlp_FormulaCreate(Ctlp_ID_c, util_strsav(name),
02179                                      util_strsav(bitValue));
02180     formula = Ctlp_FormulaCreate(Ctlp_AND_c,formula,tempFormula);
02181   }
02182   FREE(varName);
02183   FREE(name);
02184   FREE(binValueStr);
02185   FREE(bitValue);
02186   return formula;
02187 }
02188 
02189 
02205 Ctlp_Formula_t *
02206 Ctlp_FormulaCreateVectorOr(
02207   char *nameVector,
02208   char *valueStr)
02209 {
02210   Ctlp_Formula_t *formula,*tempFormula;
02211   char *preStr;
02212 
02213   preStr = strtok(valueStr,",");
02214   formula = Ctlp_FormulaCreateVectorAnd(nameVector,preStr);
02215   if ( formula == NIL(Ctlp_Formula_t)){
02216     return NIL(Ctlp_Formula_t);
02217   }
02218   while( (preStr = strtok(NIL(char),",")) != NIL(char) ){
02219     tempFormula = Ctlp_FormulaCreateVectorAnd(nameVector,preStr);
02220     if ( tempFormula == NIL(Ctlp_Formula_t)){
02221       Ctlp_FormulaFree(formula);
02222       return NIL(Ctlp_Formula_t);
02223     }
02224     formula = Ctlp_FormulaCreate(Ctlp_OR_c,formula,tempFormula);
02225   }
02226   return formula;
02227 }
02228 
02229 
02242 Ctlp_Formula_t *
02243 Ctlp_FormulaCreateEquiv(
02244    char *left,
02245    char *right)
02246 {
02247    Ctlp_Formula_t *formula,*formula1,*formula2;
02248 
02249    char *one;
02250    char *zero;
02251 
02252    one = "1";
02253    zero = "0";
02254 
02255    formula1 = Ctlp_FormulaCreate(Ctlp_ID_c, util_strsav(left),
02256                                  util_strsav(one));
02257    formula2 = Ctlp_FormulaCreate(Ctlp_ID_c, util_strsav(right),
02258                                  util_strsav(zero));
02259    formula = Ctlp_FormulaCreate(Ctlp_XOR_c,formula1,formula2);
02260    return formula;
02261 }
02262 
02275 Ctlp_Formula_t *
02276 Ctlp_FormulaCreateVectorEquiv(
02277   char *left,
02278   char *right)
02279 {
02280   Ctlp_Formula_t *formula,*tempFormula;
02281   char *leftName,*rightName;
02282   char *leftVar, *rightVar;
02283   int  leftStart,leftEnd,rightStart,rightEnd,leftInterval,rightInterval;
02284   int  leftInc,rightInc,leftInd,rightInd,i;
02285 
02286   leftName  = CtlpGetVectorInfoFromStr(left,&leftStart,&leftEnd,&leftInterval,&leftInc);
02287   rightName = CtlpGetVectorInfoFromStr(right,&rightStart,&rightEnd,&rightInterval,&rightInc);
02288   if (leftInterval != rightInterval){
02289      return NIL(Ctlp_Formula_t);
02290   }
02291   leftVar = ALLOC(char,MAX_LENGTH_OF_VAR_NAME);
02292   (void) sprintf(leftVar,"%s[%d]",leftName,leftStart);
02293   (void) CtlpChangeBracket(leftVar);
02294   rightVar = ALLOC(char,MAX_LENGTH_OF_VAR_NAME);
02295   (void) sprintf(rightVar,"%s[%d]",rightName,rightStart);
02296   (void) CtlpChangeBracket(rightVar);
02297 
02298   formula = Ctlp_FormulaCreateEquiv(leftVar,rightVar);
02299   leftInd  = leftStart;
02300   rightInd = rightStart;
02301   for(i=leftStart;i!=leftEnd;i+=leftInc){
02302      leftInd  += leftInc;
02303      rightInd += rightInc;
02304      (void) sprintf(leftVar,"%s[%d]",leftName,leftInd);
02305      (void) CtlpChangeBracket(leftVar);
02306      (void) sprintf(rightVar,"%s[%d]",rightName,rightInd);
02307      (void) CtlpChangeBracket(rightVar);
02308      tempFormula = Ctlp_FormulaCreateEquiv(leftVar,rightVar);
02309      formula = Ctlp_FormulaCreate(Ctlp_AND_c,formula,tempFormula);
02310   }
02311   FREE(leftName);
02312   FREE(rightName);
02313   FREE(leftVar);
02314   FREE(rightVar);
02315   return formula;
02316 }
02317 
02318 
02331 Ctlp_Formula_t *
02332 Ctlp_FormulaCreateAXMult(
02333   char *string,
02334   Ctlp_Formula_t *formula)
02335 {
02336   int i,num;
02337   char *str, *ptr;
02338   Ctlp_Formula_t *result;
02339   str = strchr(string,':');
02340   if ( str == NULL) return(NIL(Ctlp_Formula_t));
02341   str++;
02342 
02343   num = strtol(str,&ptr,0);
02344 
02345   if (num<=0){
02346     return (NIL(Ctlp_Formula_t));
02347   }
02348   result = Ctlp_FormulaCreate(Ctlp_AX_c,formula,NIL(Ctlp_Formula_t));
02349   for(i=1;i<num;i++){
02350     result = Ctlp_FormulaCreate(Ctlp_AX_c,result,NIL(Ctlp_Formula_t));
02351   }
02352   return result;
02353 }
02354 
02355 
02368 Ctlp_Formula_t *
02369 Ctlp_FormulaCreateEXMult(
02370   char *string,
02371   Ctlp_Formula_t *formula)
02372 {
02373   int i, num;
02374   char *str, *ptr;
02375   Ctlp_Formula_t *result;
02376   str = strchr(string,':');
02377   if ( str == NULL) return(NIL(Ctlp_Formula_t));
02378   str++;
02379 
02380   num = strtol(str,&ptr,0);
02381 
02382   if (num<=0){
02383     return (NIL(Ctlp_Formula_t));
02384   }
02385   result = Ctlp_FormulaCreate(Ctlp_EX_c,formula,NIL(Ctlp_Formula_t));
02386   for(i=1;i<num;i++){
02387     result = Ctlp_FormulaCreate(Ctlp_EX_c,result,NIL(Ctlp_Formula_t));
02388   }
02389   return result;
02390 }
02391 
02405 array_t *
02406 Ctlp_FormulaArrayConvertToForward(array_t *formulaArray, int singleInitial,
02407                                   boolean doNotShareFlag)
02408 {
02409   int i;
02410   Ctlp_Formula_t *formula, *existentialFormula, *forwardFormula;
02411   int numFormulae = array_n(formulaArray);
02412   array_t *forwardFormulaArray = array_alloc(Ctlp_Formula_t *, numFormulae);
02413   array_t *forwardDagArray;
02414   int compareValue;
02415 
02416   for(i=0; i < numFormulae; i++) {
02417     formula = array_fetch(Ctlp_Formula_t *, formulaArray, i);
02418     existentialFormula = Ctlp_FormulaConvertToExistentialForm(formula);
02419     assert(existentialFormula != NIL(Ctlp_Formula_t));
02420     formula = NIL(Ctlp_Formula_t);
02421    /*
02422     ** compareValue = 0 : check with FALSE
02423     ** compareValue = 1 : check with not-FALSE
02424     */
02425     if (singleInitial)
02426       compareValue = FormulaGetCompareValue(existentialFormula);
02427     else
02428       compareValue = 0;
02429     forwardFormula = FormulaCreateWithType(Ctlp_AND_c);
02430     forwardFormula->left = FormulaCreateWithType(Ctlp_Init_c);
02431     if (compareValue == 0) {
02432       forwardFormula->right = FormulaCreateWithType(Ctlp_NOT_c);
02433       forwardFormula->right->left = existentialFormula;
02434     } else
02435       forwardFormula->right = existentialFormula;
02436     forwardFormula->right->states = (mdd_t *)forwardFormula;
02437     /* if formula was converted before, keep that reference */
02438     if(existentialFormula->dbgInfo.originalFormula != NIL(Ctlp_Formula_t))
02439       forwardFormula->dbgInfo.originalFormula =
02440         existentialFormula->dbgInfo.originalFormula;
02441     else
02442       forwardFormula->dbgInfo.originalFormula = existentialFormula;
02443 
02444     forwardFormula->top = 1;
02445     forwardFormula->compareValue = compareValue;
02446     FormulaConvertToForward(forwardFormula->right, compareValue);
02447     CtlpFormulaSetStatesToNULL(forwardFormula);
02448     FormulaInsertForwardCompareNodes(forwardFormula, NULL, compareValue);
02449     array_insert(Ctlp_Formula_t *, forwardFormulaArray, i, forwardFormula);
02450   }
02451 
02452   if (doNotShareFlag)
02453     return(forwardFormulaArray);
02454 
02455   forwardDagArray = Ctlp_FormulaArrayConvertToDAG(forwardFormulaArray);
02456   array_free(forwardFormulaArray);
02457   return forwardDagArray;
02458 }
02459 
02460 
02472 char *
02473 Ctlp_FormulaGetTypeString(Ctlp_Formula_t *formula)
02474 {
02475   char *result;
02476 
02477   switch(formula->type) {
02478     /*
02479      * The cases are listed in rough order of their expected frequency.
02480      */
02481     case Ctlp_ID_c:
02482       result = util_strsav("ID");
02483       break;
02484     case Ctlp_OR_c:
02485       result = util_strsav("OR");
02486       break;
02487     case Ctlp_AND_c:
02488       result = util_strsav("AND");
02489       break;
02490     case Ctlp_THEN_c:
02491       result = util_strsav("THEN");
02492       break;
02493     case Ctlp_XOR_c:
02494       result = util_strsav("XOR");
02495       break;
02496     case Ctlp_EQ_c:
02497       result = util_strsav("EQ");
02498       break;
02499     case Ctlp_NOT_c:
02500       result = util_strsav("NOT");
02501       break;
02502     case Ctlp_EX_c:
02503       result = util_strsav("EX");
02504       break;
02505     case Ctlp_EG_c:
02506       result = util_strsav("EG");
02507       break;
02508     case Ctlp_EF_c:
02509       result = util_strsav("EF");
02510       break;
02511     case Ctlp_EU_c:
02512       result = util_strsav("EU");
02513       break;
02514     case Ctlp_AX_c:
02515       result = util_strsav("AX");
02516       break;
02517     case Ctlp_AG_c:
02518       result = util_strsav("AG");
02519       break;
02520     case Ctlp_AF_c:
02521       result = util_strsav("AF");
02522       break;
02523     case Ctlp_AU_c:
02524       result = util_strsav("AU");
02525       break;
02526     case Ctlp_TRUE_c:
02527       result = util_strsav("TRUE");
02528       break;
02529     case Ctlp_FALSE_c:
02530       result = util_strsav("FALSE");
02531       break;
02532     case Ctlp_Init_c:
02533       result = util_strsav("Init");
02534       break;
02535     case Ctlp_Cmp_c:
02536       result = util_strsav("Cmp");
02537       break;
02538     case Ctlp_FwdU_c:
02539       result = util_strsav("FwdU");
02540       break;
02541     case Ctlp_FwdG_c:
02542       result = util_strsav("FwdG");
02543       break;
02544     case Ctlp_EY_c:
02545       result = util_strsav("EY");
02546       break;
02547     case Ctlp_EH_c:
02548       result = util_strsav("EH");
02549       break;
02550     default:
02551       fail("Unexpected type");
02552   }
02553   return(result);
02554 }
02555 
02556 
02577 Ctlp_FormulaClass
02578 Ctlp_CheckClassOfExistentialFormula(
02579   Ctlp_Formula_t *formula)
02580 {
02581   Ctlp_FormulaType formulaType;
02582   Ctlp_Formula_t *rightFormula, *leftFormula;
02583   Ctlp_FormulaClass resultLeft, resultRight, tempResult, currentClass;
02584 
02585   assert(formula != NIL(Ctlp_Formula_t));
02586   if(formula == NIL(Ctlp_Formula_t))
02587     return Ctlp_QuantifierFree_c;
02588 
02589   formulaType = Ctlp_FormulaReadType(formula);
02590   leftFormula = Ctlp_FormulaReadLeftChild(formula);
02591   rightFormula = Ctlp_FormulaReadRightChild(formula);
02592 
02593   /* Depending on the formula type, create result or recur */
02594   switch (formulaType) {
02595   case Ctlp_EX_c:
02596   case Ctlp_EG_c:
02597   case Ctlp_EF_c:
02598   case Ctlp_EU_c:
02599   case Ctlp_FwdU_c:
02600   case Ctlp_FwdG_c:
02601   case Ctlp_EY_c:
02602   case Ctlp_EH_c:
02603     resultLeft = Ctlp_CheckClassOfExistentialFormula(leftFormula);
02604     if (formulaType == Ctlp_EU_c || formulaType == Ctlp_FwdU_c ||
02605         formulaType == Ctlp_FwdG_c )
02606       resultRight = Ctlp_CheckClassOfExistentialFormula(rightFormula);
02607     else
02608       resultRight = Ctlp_QuantifierFree_c;
02609 
02610     tempResult = CtlpResolveClass(resultLeft, resultRight);
02611     currentClass = Ctlp_ECTL_c;
02612     return CtlpResolveClass(currentClass, tempResult);
02613   case Ctlp_AX_c:
02614   case Ctlp_AG_c:
02615   case Ctlp_AF_c:
02616   case Ctlp_AU_c:
02617     /* The formula is supposed to be only existential */
02618     fprintf(vis_stdout,
02619             "** Ctlp Error: unexpected (universal) operator type\n");
02620     assert(0);
02621     return Ctlp_Mixed_c;
02622   case Ctlp_OR_c:
02623   case Ctlp_AND_c:
02624     resultLeft = Ctlp_CheckClassOfExistentialFormula(leftFormula);
02625     resultRight = Ctlp_CheckClassOfExistentialFormula(rightFormula);
02626     return CtlpResolveClass(resultLeft, resultRight);
02627   case Ctlp_NOT_c:
02628     tempResult = Ctlp_CheckClassOfExistentialFormula(leftFormula);
02629     return CtlpNegateFormulaClass(tempResult);
02630    case Ctlp_THEN_c:
02631     resultLeft = Ctlp_CheckClassOfExistentialFormula(leftFormula);
02632     resultRight = Ctlp_CheckClassOfExistentialFormula(rightFormula);
02633     tempResult = CtlpNegateFormulaClass(resultLeft);
02634     return CtlpResolveClass(tempResult, resultRight);
02635   case Ctlp_XOR_c:
02636   case Ctlp_EQ_c:
02637     resultLeft =  Ctlp_CheckClassOfExistentialFormula(leftFormula);
02638     resultRight = Ctlp_CheckClassOfExistentialFormula(rightFormula);
02639     tempResult = CtlpResolveClass(resultLeft, resultRight);
02640     if( tempResult == Ctlp_QuantifierFree_c)
02641       return Ctlp_QuantifierFree_c;
02642     else
02643       return Ctlp_Mixed_c;
02644   case Ctlp_ID_c:
02645   case Ctlp_TRUE_c:
02646   case Ctlp_FALSE_c:
02647   case Ctlp_Init_c:
02648      return Ctlp_QuantifierFree_c;
02649   case Ctlp_Cmp_c:
02650     return Ctlp_Mixed_c;
02651   default:
02652     fprintf(vis_stderr, "**Ctlp Error: Unexpected operator detected.\n");
02653     assert(0);
02654     return Ctlp_Mixed_c;
02655   }
02656 } /* End of Ctlp_CheckTypeOfExistentialFormula */
02657 
02673 Ctlp_FormulaClass
02674 Ctlp_CheckClassOfExistentialFormulaArray(
02675   array_t *formulaArray)
02676 {
02677   Ctlp_FormulaClass result;
02678   Ctlp_Formula_t *formula;
02679   int formulanr;
02680 
02681   result = Ctlp_QuantifierFree_c;
02682   arrayForEachItem(Ctlp_Formula_t *, formulaArray, formulanr, formula){
02683     Ctlp_FormulaClass  formulaType;
02684     formulaType = Ctlp_CheckClassOfExistentialFormula(formula);
02685     result = CtlpResolveClass(result, formulaType);
02686     if(result == Ctlp_Mixed_c)
02687       return result;
02688   }
02689   return result;
02690 } /* End of Ctlp_CheckTypeOfExistentialFormulaArray */
02691 
02692 
02706 boolean
02707 Ctlp_FormulaIdentical(
02708   Ctlp_Formula_t *formula1,
02709   Ctlp_Formula_t *formula2)
02710 {
02711   return(FormulaCompare((char *)formula1, (char *)formula2) == 0);
02712 }
02713 
02714 
02741 void
02742 Ctlp_FormulaMakeMonotonic(
02743   Ctlp_Formula_t *formula)
02744 {
02745   Ctlp_Formula_t *left, *right;
02746   Ctlp_FormulaType type;
02747 
02748   if (formula == NIL(Ctlp_Formula_t)) {
02749     return;
02750   }
02751 
02752   /* Make sure (recursively) that this (sub)-formula is still in its pristine
02753    * state.  Specifically, that the parse graph is a tree.
02754    */
02755   assert(formula->refCount == 1 &&
02756          formula->states == NIL(mdd_t) &&
02757          formula->underapprox == NIL(mdd_t) &&
02758          formula->overapprox == NIL(mdd_t) &&
02759          formula->latest == Ctlp_Incomparable_c &&
02760          formula->dbgInfo.data == NIL(void) &&
02761          formula->dbgInfo.freeFn == (Ctlp_DbgInfoFreeFn) NULL &&
02762          formula->dbgInfo.convertedFlag == FALSE &&
02763          formula->dbgInfo.originalFormula == NIL(Ctlp_Formula_t) &&
02764          formula->top == 0 &&
02765          formula->compareValue == 0
02766          );
02767 
02768   type = Ctlp_FormulaReadType(formula);
02769 
02770   /* Leaves remain unchanged. */
02771   if (type == Ctlp_ID_c || type == Ctlp_TRUE_c || type == Ctlp_FALSE_c) {
02772     return;
02773   }
02774 
02775   /* First recursively fix the children. */
02776   left  = Ctlp_FormulaReadLeftChild(formula);
02777   Ctlp_FormulaMakeMonotonic(left);
02778   right = Ctlp_FormulaReadRightChild(formula);
02779   Ctlp_FormulaMakeMonotonic(right);
02780 
02781   /* Fix this node if it is not monotonic. */
02782   switch (type) {
02783   case Ctlp_EX_c:
02784   case Ctlp_EG_c:
02785   case Ctlp_EF_c:
02786   case Ctlp_EU_c:
02787   case Ctlp_AX_c:
02788   case Ctlp_AG_c:
02789   case Ctlp_AF_c:
02790   case Ctlp_AU_c:
02791   case Ctlp_OR_c:
02792   case Ctlp_AND_c:
02793   case Ctlp_NOT_c:
02794   case Ctlp_THEN_c:
02795   case Ctlp_EY_c:
02796   case Ctlp_EH_c:
02797     /* Nothing to be done */
02798     break;
02799   case Ctlp_EQ_c: {
02800     Ctlp_Formula_t *dupLeft, *dupRight;
02801     Ctlp_Formula_t *thenLeft, *thenRight;
02802     dupLeft   = Ctlp_FormulaDup(left);
02803     dupRight  = Ctlp_FormulaDup(right);
02804     thenLeft  = Ctlp_FormulaCreate(Ctlp_THEN_c, left, right);
02805     thenRight = Ctlp_FormulaCreate(Ctlp_THEN_c, dupRight, dupLeft);
02806     /* Fix the node in place. */
02807     formula->type  = Ctlp_AND_c;
02808     formula->left  = thenLeft;
02809     formula->right = thenRight;
02810     break;
02811   }
02812   case Ctlp_XOR_c: {
02813     Ctlp_Formula_t *dupLeft, *dupRight;
02814     Ctlp_Formula_t *negLeft, *negRight;
02815     Ctlp_Formula_t *andLeft, *andRight;
02816     dupLeft  = Ctlp_FormulaDup(left);
02817     dupRight = Ctlp_FormulaDup(right);
02818     negLeft  = Ctlp_FormulaCreate(Ctlp_NOT_c, dupLeft, NIL(Ctlp_Formula_t));
02819     negRight = Ctlp_FormulaCreate(Ctlp_NOT_c, dupRight, NIL(Ctlp_Formula_t));
02820     andLeft  = Ctlp_FormulaCreate(Ctlp_AND_c, left, negRight);
02821     andRight = Ctlp_FormulaCreate(Ctlp_AND_c, negLeft, right);
02822     /* Fix the node in place. */
02823     formula->type  = Ctlp_OR_c;
02824     formula->left  = andLeft;
02825     formula->right = andRight;
02826     break;
02827   }
02828   default:
02829     /* Forward CTL operators (that are not supported) and leaves (that are
02830      * dealt with above) would fall here.
02831      */
02832     fail("unexpected CTL formula type\n");
02833   }
02834 
02835   return;
02836 
02837 } /* Ctlp_FormulaMakeMonotonic */
02838 
02839 
02851 void
02852 Ctlp_FormulaArrayMakeMonotonic(
02853   array_t *formulaArray /* of Ctlp_Formula_t */)
02854 {
02855   int i;
02856   Ctlp_Formula_t *formula;
02857 
02858   if (formulaArray == NIL(array_t)) return;
02859   arrayForEachItem(Ctlp_Formula_t *, formulaArray, i, formula) {
02860     Ctlp_FormulaMakeMonotonic(formula);
02861   }
02862 
02863 } /* Ctlp_FormulaArrayMakeMonotonic */
02864 
02865 
02866 /*---------------------------------------------------------------------------*/
02867 /* Definition of internal functions                                          */
02868 /*---------------------------------------------------------------------------*/
02869 
02870 
02883 void
02884 CtlpFormulaIncrementRefCount(
02885   Ctlp_Formula_t *formula)
02886 {
02887   if(formula!=NIL(Ctlp_Formula_t)) {
02888     ++(formula->refCount);
02889   }
02890 }
02891 
02906 void
02907 CtlpFormulaDecrementRefCount(
02908   Ctlp_Formula_t *formula)
02909 {
02910   if(formula!=NIL(Ctlp_Formula_t)) {
02911     assert(formula->refCount>0);
02912     if(--(formula->refCount) == 0)
02913       CtlpFormulaFree(formula);
02914   }
02915 }
02925 void
02926 CtlpFormulaAddToGlobalArray(
02927   Ctlp_Formula_t * formula)
02928 {
02929   array_insert_last(Ctlp_Formula_t *, globalFormulaArray, formula);
02930 }
02931 
02946 void
02947 CtlpFormulaFree(
02948   Ctlp_Formula_t * formula)
02949 {
02950   if (formula != NIL(Ctlp_Formula_t)) {
02951 
02952     /*
02953      * Free any fields that are not NULL.
02954      */
02955 
02956     if (formula->type == Ctlp_ID_c) {
02957       FREE(formula->left);
02958       FREE(formula->right);
02959     }
02960     else {
02961       if (formula->left  != NIL(Ctlp_Formula_t)) {
02962         CtlpFormulaDecrementRefCount(formula->left);
02963       }
02964       if (formula->right != NIL(Ctlp_Formula_t)) {
02965         CtlpFormulaDecrementRefCount(formula->right);
02966       }
02967     }
02968     if (formula->states != NIL(mdd_t))
02969       mdd_free(formula->states);
02970     if (formula->underapprox != NIL(mdd_t))
02971       mdd_free(formula->underapprox);
02972     if (formula->overapprox != NIL(mdd_t))
02973       mdd_free(formula->overapprox);
02974     if (formula->Bottomstates != NIL(array_t))
02975       mdd_array_free(formula->Bottomstates);
02976     if (formula->Topstates != NIL(array_t))
02977       mdd_array_free(formula->Topstates);
02978     if (formula->matchfound_top != NIL(array_t))
02979       array_free(formula->matchfound_top);
02980     if (formula->matchelement_top != NIL(array_t))
02981       array_free(formula->matchelement_top);
02982     if (formula->matchfound_bot != NIL(array_t))
02983       array_free(formula->matchfound_bot);
02984     if (formula->matchelement_bot != NIL(array_t))
02985       array_free(formula->matchelement_bot);
02986     if (formula->leaves != NIL(array_t))
02987       array_free(formula->leaves);
02988     if (formula->dbgInfo.data != NIL(void)) {
02989       (*formula->dbgInfo.freeFn)(formula);
02990     }
02991     FREE(formula);
02992   }
02993 }
02994 
02995 
03010 int
03011 CtlpStringChangeValueStrToBinString(
03012   char *value,
03013   char *binValueStr,
03014   int  interval)
03015 {
03016   int i;
03017   long int num, mask;
03018   double maxNum;
03019   char *ptr;
03020 
03021   mask = 1;
03022   maxNum = pow(2.0,(double)interval);
03023   errno = 0;
03024 
03025   if(value[0] == 'b'){
03026     if ((int)strlen(value)-1 == interval){
03027                         for(i=1;i<=interval;i++){
03028         if (value[i] == '0' || value[i] == '1'){
03029           binValueStr[i-1] =  value[i];
03030         }else{
03031           return 0;
03032         }
03033       }
03034       binValueStr[interval] = '\0';
03035     }else{
03036       return 0;
03037     }
03038   }else if (value[0] == 'x'){
03039     for(i=1; i < (int)strlen(value); i++){
03040       if (!isxdigit((int)value[i])){
03041         return 0;
03042       }
03043     }
03044     num = strtol(++value,&ptr,16);
03045     if (errno) return 0;
03046     if ( num >= maxNum) return 0;
03047     for(i=0;i<interval;i++){
03048       if(num & (mask<<i)) binValueStr[interval-i-1] = '1';
03049       else binValueStr[interval-i-1] = '0';
03050     }
03051     binValueStr[interval] = '\0';
03052   }else{
03053     for(i=0;i<(int)strlen(value);i++){
03054       if (!isdigit((int)value[i])){
03055         return 0;
03056       }
03057     }
03058     num = strtol(value,&ptr,0);
03059     if (errno) return 0;
03060     if ( num >= maxNum) return 0;
03061     mask = 1;
03062     for(i=0;i<interval;i++){
03063       if(num & (mask<<i)) binValueStr[interval-i-1] = '1';
03064       else binValueStr[interval-i-1] = '0';
03065     }
03066     binValueStr[interval] = '\0';
03067   }
03068 
03069   return(1);
03070 }
03071 
03072 
03085 void
03086 CtlpChangeBracket(
03087   char *inStr)
03088 {
03089   int i, j;
03090   char *str;
03091 
03092   j = 0;
03093   for (i=0;i<(int)strlen(inStr)+1;i++){
03094     if (inStr[i] != ' '){
03095       inStr[i-j] = inStr[i];
03096     }else{
03097       j++;
03098     }
03099   }
03100 
03101   if (changeBracket == 0)
03102     return;
03103 
03104   str = strchr(inStr,'[');
03105   if (str == NULL) return;
03106 
03107   *str = '<';
03108   str = strchr(inStr,']');
03109   *str = '>';
03110 }
03111 
03112 
03126 char *
03127 CtlpGetVectorInfoFromStr(
03128    char *str,
03129    int  *start,
03130    int  *end,
03131    int  *interval,
03132    int  *inc)
03133 {
03134   char *str1, *str2, *str3;
03135   char *startStr, *endStr;
03136   char *name, *ptr;
03137 
03138   str1 = strchr(str,'[');
03139   str2 = strchr(str,':');
03140   str3 = strchr(str,']');
03141   startStr = ALLOC(char, str2-str1);
03142   endStr = ALLOC(char, str3-str2);
03143   name = ALLOC(char, str1-str+1);
03144 
03145   (void) strncpy(name, str, str1-str);
03146   (void) strncpy(startStr, str1+1, str2-str1-1);
03147   (void) strncpy(endStr, str2+1, str3-str2-1);
03148 
03149   startStr[str2-str1-1] = '\0';
03150   endStr[str3-str2-1] = '\0';
03151   name[str1-str] = '\0';
03152   *start = strtol(startStr,&ptr,0);
03153   *end = strtol(endStr,&ptr,0);
03154   if(*start > *end){
03155       *inc = -1;
03156       *interval = *start - *end + 1;
03157   } else {
03158       *inc = 1;
03159       *interval = *end - *start + 1;
03160   }
03161   FREE(startStr);
03162   FREE(endStr);
03163   return name;
03164 }
03165 
03178 int
03179 CtlpFormulaAddToTable(
03180    char *name,
03181    Ctlp_Formula_t *formula,
03182    st_table *macroTable)
03183 {
03184    if(macroTable == NIL(st_table)){
03185       macroTable = st_init_table(strcmp, st_strhash);
03186    }
03187    if(st_is_member(macroTable, name)){
03188       return 0;
03189    }
03190    st_insert(macroTable, name, (char *)formula);
03191    return 1;
03192 }
03193 
03194 
03206 Ctlp_Formula_t *
03207 CtlpFormulaFindInTable(
03208    char *name,
03209    st_table *macroTable)
03210 {
03211    Ctlp_Formula_t *formula;
03212    if (st_lookup(macroTable, name, &formula)){
03213       return (Ctlp_FormulaDup(formula));
03214    }else{
03215       return NIL(Ctlp_Formula_t);
03216    }
03217 }
03218 
03232 Ctlp_FormulaClass
03233 CtlpResolveClass(
03234   Ctlp_FormulaClass class1,
03235   Ctlp_FormulaClass class2)
03236 {
03237   if ((class1 == Ctlp_Mixed_c) || (class2 == Ctlp_Mixed_c))
03238     return Ctlp_Mixed_c;
03239   if (class1 == Ctlp_QuantifierFree_c)
03240     return class2;
03241   if (class2 == Ctlp_QuantifierFree_c)
03242     return class1;
03243   if (class1 == class2)
03244     return class1;
03245 
03246   return Ctlp_Mixed_c;
03247 
03248 }
03249 
03250 
03264 Ctlp_FormulaClass
03265 CtlpNegateFormulaClass(
03266   Ctlp_FormulaClass class_
03267 )
03268 {
03269   switch(class_){
03270   case Ctlp_Mixed_c:
03271     return Ctlp_Mixed_c;
03272   case Ctlp_QuantifierFree_c:
03273     return Ctlp_QuantifierFree_c;
03274   case Ctlp_ECTL_c:
03275     return Ctlp_ACTL_c;
03276   case Ctlp_ACTL_c:
03277     return Ctlp_ECTL_c;
03278   default:
03279     fprintf(vis_stderr, "**Ctlp Error: Unknown formula class\n");
03280     assert(0);
03281     return Ctlp_Mixed_c;
03282   }
03283 }
03284 
03285 
03309 Ctlp_Formula_t *
03310 Ctlp_FormulaCreateWitnessFormula(
03311   Ctlp_Formula_t *formula)
03312 {
03313   Ctlp_FormulaType formulaType;
03314   Ctlp_Formula_t *rightFormula, *leftFormula;
03315   Ctlp_Formula_t *newLeftFormula, *newRightFormula;
03316 
03317   assert(formula != NIL(Ctlp_Formula_t));
03318 
03319   if(formula == NIL(Ctlp_Formula_t))
03320     return NIL(Ctlp_Formula_t);
03321 
03322   formulaType = Ctlp_FormulaReadType(formula);
03323   leftFormula = Ctlp_FormulaReadLeftChild(formula);
03324   rightFormula = Ctlp_FormulaReadRightChild(formula);
03325 
03326   if (Ctlp_FormulaTestIsQuantifierFree(formula)) {
03327     return ReplaceSimpleFormula(formula);
03328   }
03329 
03330   switch (formulaType) {
03331   case Ctlp_AX_c:
03332   case Ctlp_EX_c:
03333   case Ctlp_AG_c:
03334   case Ctlp_EG_c:
03335   case Ctlp_AF_c:
03336   case Ctlp_EF_c:
03337   case Ctlp_NOT_c:
03338     newLeftFormula = Ctlp_FormulaCreateWitnessFormula(leftFormula);
03339     newRightFormula = NIL(Ctlp_Formula_t);
03340     break;
03341   case Ctlp_AU_c:
03342   case Ctlp_EU_c:
03343     /* If both or neither operands are simple, we choose the left one
03344        as important.  Deal with special case of converted AG p (E true U p). */
03345     if ((formulaType == Ctlp_EU_c &&
03346          Ctlp_FormulaReadType(leftFormula) == Ctlp_TRUE_c) ||
03347         (Ctlp_FormulaTestIsQuantifierFree(leftFormula) &&
03348          !Ctlp_FormulaTestIsQuantifierFree(rightFormula))) {
03349       newLeftFormula = Ctlp_FormulaDup(leftFormula);
03350       newRightFormula = Ctlp_FormulaCreateWitnessFormula(rightFormula);
03351     } else {
03352       newLeftFormula = Ctlp_FormulaCreateWitnessFormula(leftFormula);
03353       newRightFormula = Ctlp_FormulaDup(rightFormula);
03354     }
03355     break;
03356   case Ctlp_OR_c:
03357   case Ctlp_AND_c:
03358   case Ctlp_THEN_c:
03359     /* Here we know one is not simple */
03360     if (Ctlp_FormulaTestIsQuantifierFree(leftFormula)) {
03361       newLeftFormula = Ctlp_FormulaDup(leftFormula);
03362       newRightFormula = Ctlp_FormulaCreateWitnessFormula(rightFormula);
03363     } else {
03364       newLeftFormula = Ctlp_FormulaCreateWitnessFormula(leftFormula);
03365       newRightFormula = Ctlp_FormulaDup(rightFormula);
03366     }
03367     break;
03368   case Ctlp_XOR_c:
03369   case Ctlp_EQ_c:
03370     newLeftFormula = Ctlp_FormulaDup(leftFormula);
03371     newRightFormula = Ctlp_FormulaDup(rightFormula);
03372     break;
03373   default:
03374     newLeftFormula = NIL(Ctlp_Formula_t);
03375     newRightFormula = NIL(Ctlp_Formula_t);
03376     fprintf(vis_stderr, "**Ctlp Error: Unexpected operator detected.\n");
03377     assert(0);
03378     break;
03379   }
03380   return Ctlp_FormulaCreate(formulaType,newLeftFormula,newRightFormula);
03381 
03382 } /* Ctlp_FormulaCreateWitnessFormula */
03383 
03384 
03385 /*---------------------------------------------------------------------------*/
03386 /* Definition of static functions                                            */
03387 /*---------------------------------------------------------------------------*/
03388 
03400 static Ctlp_Formula_t *
03401 FormulaCreateWithType(
03402   Ctlp_FormulaType  type)
03403 {
03404   return (Ctlp_FormulaCreate(type, NIL(Ctlp_Formula_t), NIL(Ctlp_Formula_t)));
03405 }
03406 
03407 
03421 static int
03422 FormulaCompare(
03423   const char *key1,
03424   const char *key2)
03425 {
03426   Ctlp_Formula_t *formula1 = (Ctlp_Formula_t *) key1;
03427   Ctlp_Formula_t *formula2 = (Ctlp_Formula_t *) key2;
03428 
03429   assert(key1 != NIL(char));
03430   assert(key2 != NIL(char));
03431 
03432 
03433   if(formula1->type != formula2->type) {
03434     return -1;
03435   }
03436   if(formula1->type == Ctlp_ID_c) {
03437     if(strcmp((char *) (formula1->left), (char *) (formula2->left)) ||
03438        strcmp((char *) (formula1->right), (char *) (formula2->right))) {
03439       return -1;
03440     } else
03441       return 0;
03442   } else {
03443     if(formula1->left != formula2->left)
03444       return -1;
03445     if(formula1->right != formula2->right)
03446       return -1;
03447     if (formula1->type == Ctlp_Cmp_c &&
03448         formula1->compareValue != formula2->compareValue) {
03449       return -1;
03450     }
03451     return 0;
03452   }
03453 }
03454 
03469 static int
03470 FormulaHash(
03471   char *key,
03472   int modulus)
03473 {
03474   char *hashString;
03475   int hashValue;
03476   Ctlp_Formula_t *formula = (Ctlp_Formula_t *) key;
03477 
03478   if(formula->type==Ctlp_ID_c) {
03479     hashString = util_strcat3((char *) (formula->left), (char *)
03480                               (formula->right), "");
03481     hashValue = st_strhash(hashString, modulus);
03482     FREE(hashString);
03483     return hashValue;
03484   }
03485   return (int) ((((unsigned long) formula->left >>2) +
03486                  ((unsigned long) formula->right >>2)) % modulus);
03487 }
03488 
03507 static Ctlp_Formula_t *
03508 FormulaHashIntoUniqueTable(
03509   Ctlp_Formula_t *formula,
03510   st_table *uniqueTable)
03511 {
03512   Ctlp_Formula_t *uniqueFormula, *uniqueLeft, *uniqueRight;
03513 
03514   if(formula == NIL(Ctlp_Formula_t))
03515     return NIL(Ctlp_Formula_t);
03516   if(st_lookup(uniqueTable, formula, &uniqueFormula)) {
03517     return uniqueFormula;
03518   }
03519   else {
03520     if(formula->type == Ctlp_ID_c) {
03521       st_insert(uniqueTable, formula, formula);
03522       return formula;
03523     }
03524     else {
03525       uniqueLeft = FormulaHashIntoUniqueTable(formula->left, uniqueTable);
03526       if(uniqueLeft != NIL(Ctlp_Formula_t))
03527         if(uniqueLeft != formula->left) {
03528           CtlpFormulaDecrementRefCount(formula->left);
03529           formula->left = uniqueLeft;
03530           CtlpFormulaIncrementRefCount(formula->left);
03531         }
03532       uniqueRight = FormulaHashIntoUniqueTable(formula->right, uniqueTable);
03533       if(uniqueRight != NIL(Ctlp_Formula_t))
03534         if(uniqueRight != formula->right) {
03535           CtlpFormulaDecrementRefCount(formula->right);
03536           formula->right = uniqueRight;
03537           CtlpFormulaIncrementRefCount(formula->right);
03538         }
03539       if(st_lookup(uniqueTable, formula, &uniqueFormula)) {
03540         return uniqueFormula;
03541       }
03542       else {
03543         st_insert(uniqueTable, formula, formula);
03544         return formula;
03545       }
03546     }
03547   }
03548 }
03549 
03565 static Ctlp_Formula_t *
03566 FormulaConvertToExistentialDAG(
03567   Ctlp_Formula_t *formula)
03568 {
03569 
03570   Ctlp_Formula_t *new_;
03571   char *variableNameCopy, *valueNameCopy;
03572 
03573   if(formula==NIL(Ctlp_Formula_t))
03574     return NIL(Ctlp_Formula_t);
03575 
03576   if(formula->states!=NIL(mdd_t)) {
03577     Ctlp_Formula_t *temp = (Ctlp_Formula_t *) (formula->states);
03578 
03579     ++(temp->refCount);
03580     return temp;
03581   }
03582 
03583   /*
03584    * Recursively convert each subformula.
03585    */
03586 
03587   switch(formula->type) {
03588     case Ctlp_EF_c:
03589       /* EFf --> (E true U f)  */
03590       new_ = FormulaCreateWithType(Ctlp_EU_c);
03591       new_->left  = FormulaCreateWithType(Ctlp_TRUE_c);
03592       new_->right = FormulaConvertToExistentialDAG(formula->left);
03593       new_->dbgInfo.convertedFlag = TRUE;
03594       break;
03595 
03596     case Ctlp_AX_c:
03597       /* AXf --> !(EX(!f)) */
03598       new_ = FormulaCreateWithType(Ctlp_NOT_c);
03599       new_->left = FormulaCreateWithType(Ctlp_EX_c);
03600       new_->left->left = FormulaCreateWithType(Ctlp_NOT_c);
03601       new_->left->left->left = FormulaConvertToExistentialDAG(formula->left);
03602       new_->dbgInfo.convertedFlag = TRUE;
03603       break;
03604 
03605     case Ctlp_AG_c:
03606       /* AGf --> ![(E true U !f)] */
03607       new_ = FormulaCreateWithType(Ctlp_NOT_c);
03608       new_->left = FormulaCreateWithType(Ctlp_EU_c);
03609       new_->left->left = FormulaCreateWithType(Ctlp_TRUE_c);
03610       new_->left->right = FormulaCreateWithType(Ctlp_NOT_c);
03611       new_->left->right->left = FormulaConvertToExistentialDAG(formula->left);
03612       new_->dbgInfo.convertedFlag = TRUE;
03613       break;
03614 
03615     case Ctlp_AF_c:
03616       /* AFf --> ![EG(!f)] */
03617       new_ = FormulaCreateWithType(Ctlp_NOT_c);
03618       new_->left = FormulaCreateWithType(Ctlp_EG_c);
03619       new_->left->left = FormulaCreateWithType(Ctlp_NOT_c);
03620       new_->left->left->left = FormulaConvertToExistentialDAG(formula->left);
03621       new_->dbgInfo.convertedFlag = TRUE;
03622       break;
03623 
03624     case Ctlp_AU_c:
03625       /* A[fUg] --> !((E[!g U (!f*!g)]) + (EG!g)) */
03626 
03627       new_ = FormulaCreateWithType(Ctlp_NOT_c); /* top */
03628       new_->left = FormulaCreateWithType(Ctlp_OR_c); /* ((E[!g U (!f*!g)]) + (EG!g)) */
03629 
03630       new_->left->right = FormulaCreateWithType(Ctlp_EG_c); /* EG !g */
03631       new_->left->right->left = FormulaCreateWithType(Ctlp_NOT_c); /* !g */
03632       new_->left->right->left->left = FormulaConvertToExistentialDAG(formula->right); /* g */
03633 
03634       new_->left->left = FormulaCreateWithType(Ctlp_EU_c); /* E[!g U (!f*!g)] */
03635       new_->left->left->left = FormulaCreateWithType(Ctlp_NOT_c); /* !g */
03636       new_->left->left->left->left = FormulaConvertToExistentialDAG(formula->right); /* g */
03637       new_->left->left->right = FormulaCreateWithType(Ctlp_AND_c); /* !f*!g */
03638       new_->left->left->right->left = FormulaCreateWithType(Ctlp_NOT_c); /* !f */
03639       new_->left->left->right->left->left = FormulaConvertToExistentialDAG(formula->left); /* f */
03640       new_->left->left->right->right = FormulaCreateWithType(Ctlp_NOT_c); /* !g */
03641       new_->left->left->right->right->left = FormulaConvertToExistentialDAG(formula->right); /* g */
03642       new_->dbgInfo.convertedFlag = TRUE;
03643       break;
03644 
03645     case Ctlp_ID_c:
03646       /* Make a copy of the name, and create a new formula. */
03647       variableNameCopy = util_strsav((char *)(formula->left));
03648       valueNameCopy = util_strsav((char *)(formula->right));
03649       new_ = Ctlp_FormulaCreate(Ctlp_ID_c, variableNameCopy, valueNameCopy);
03650       break;
03651 
03652     case Ctlp_THEN_c:
03653     case Ctlp_EX_c:
03654     case Ctlp_EG_c:
03655     case Ctlp_EU_c:
03656     case Ctlp_OR_c:
03657     case Ctlp_AND_c:
03658     case Ctlp_NOT_c:
03659     case Ctlp_XOR_c:
03660     case Ctlp_EQ_c:
03661     case Ctlp_TRUE_c:
03662     case Ctlp_FALSE_c:
03663       /* These are already in the correct form.  Just convert subformulas. */
03664       new_ = FormulaCreateWithType(formula->type);
03665       new_->left = FormulaConvertToExistentialDAG(formula->left);
03666       new_->right = FormulaConvertToExistentialDAG(formula->right);
03667       break;
03668 
03669     default:
03670       fail("Unexpected type");
03671   }
03672 
03673   formula->states = (mdd_t *) new_; /*using states as pointer to the converted
03674                                      formula */
03675   new_->dbgInfo.originalFormula = formula;
03676   return new_;
03677 }
03678 
03679 
03696 static void
03697 FormulaConvertToForward(Ctlp_Formula_t *formula, int compareValue)
03698 {
03699   Ctlp_Formula_t *parent, *save;
03700   Ctlp_Formula_t *p, *q, *r, *f, *g;
03701   int            p_qf, q_qf;
03702   int            same_order;
03703 
03704   if (formula == NIL(Ctlp_Formula_t))
03705     return;
03706 
03707   parent = (Ctlp_Formula_t *)formula->states;
03708   r = parent->left; /* already converted */
03709 
03710   /*
03711    * Recursively convert each subformula.
03712    */
03713 
03714   switch(formula->type) {
03715     case Ctlp_EX_c:
03716       /*
03717       ** p ^ EXf -> Img(p) ^ f , Img(p) = EY(p)
03718       **
03719       **   *           *
03720       **  / \         / \
03721       ** p  EX  =>  EY   f
03722       **    |       |
03723       **    f       p
03724       */
03725 
03726       formula->type = Ctlp_EY_c;
03727       save = formula->left;
03728       formula->left = parent->left;
03729       parent->left = formula;
03730       parent->right = save;
03731 
03732       parent->top = 1;
03733       parent->compareValue = compareValue;
03734       parent->right->states = (mdd_t *)parent;
03735 
03736       FormulaConvertToForward(parent->right, compareValue);
03737       break;
03738 
03739     case Ctlp_EF_c:
03740       /*
03741       ** EFf --> (E true U f)
03742       ** p ^ (E true U f) --> FwdU(p, true) ^ f
03743       **
03744       **   *             *
03745       **  / \          /   \
03746       ** p  EF  =>  FwdU    f
03747       **    |        / \
03748       **    f       p  true
03749       */
03750 
03751       formula->type = Ctlp_FwdU_c;
03752       save = formula->left;
03753       formula->right = FormulaCreateWithType(Ctlp_TRUE_c);
03754       formula->left = parent->left;
03755       parent->left = formula;
03756       parent->right = save;
03757 
03758       parent->top = 1;
03759       parent->compareValue = compareValue;
03760       parent->right->states = (mdd_t *)parent;
03761 
03762 
03763       FormulaConvertToForward(parent->right, compareValue);
03764       break;
03765 
03766     case Ctlp_EU_c:
03767       /*
03768       ** p ^ (E q U f) --> FwdU(p, q) ^ f
03769       **
03770       **   *             *
03771       **  / \          /   \
03772       ** p  EU  =>   FwdU   f
03773       **    /\        / \
03774       **   q  f      p   q
03775       */
03776 
03777       formula->type = Ctlp_FwdU_c;
03778       save = formula->right;
03779       formula->right = formula->left;
03780       formula->left = parent->left;
03781       parent->left = formula;
03782       parent->right = save;
03783 
03784       parent->top = 1;
03785       parent->compareValue = compareValue;
03786       parent->right->states = (mdd_t *)parent;
03787 
03788       FormulaConvertToForward(parent->right, compareValue);
03789       break;
03790 
03791     case Ctlp_EG_c:
03792       /*
03793       ** p ^ EGq --> FwdG(p, q)
03794       **
03795       **   *        FwdG
03796       **  / \        / \
03797       ** p  EG  =>  p   q
03798       **    /
03799       **   q
03800       */
03801 
03802       parent->type = Ctlp_FwdG_c;
03803       parent->right = formula->left;
03804 
03805       formula->left = NIL(Ctlp_Formula_t);
03806       formula->states = NIL(mdd_t);
03807       Ctlp_FormulaFree(formula);
03808 
03809       parent->top = 1;
03810       parent->compareValue = compareValue;
03811       break;
03812 
03813     case Ctlp_NOT_c:
03814       if (formula->left->type == Ctlp_NOT_c) {
03815         /*
03816         **   *             *
03817         **  / \      =>   / \
03818         ** r  NOT        r   f
03819         **     /
03820         **   NOT
03821         **   /
03822         **  f
03823         */
03824 
03825         parent->right = formula->left->left;
03826         formula->left->left = NIL(Ctlp_Formula_t);
03827         formula->left->states = NIL(mdd_t);
03828         Ctlp_FormulaFree(formula->left);
03829         formula->left = NIL(Ctlp_Formula_t);
03830         formula->states = NIL(mdd_t);
03831         Ctlp_FormulaFree(formula);
03832 
03833         parent->top = 1;
03834         parent->compareValue = compareValue;
03835         parent->right->states = (mdd_t *)parent;
03836 
03837         FormulaConvertToForward(parent->right, compareValue);
03838       } else if (formula->left->type == Ctlp_THEN_c) {
03839         /*
03840         **   *
03841         **  / \
03842         ** r  NOT
03843         **    /
03844         **  THEN
03845         **   / \
03846         **  p   q
03847         */
03848 
03849         p = formula->left->left;
03850         q = formula->left->right;
03851         p_qf = Ctlp_FormulaTestIsQuantifierFree(p);
03852         q_qf = Ctlp_FormulaTestIsQuantifierFree(q);
03853 
03854         if (p_qf && q_qf)
03855           break;
03856         else if (p_qf ||
03857                  (p_qf == 0 && q_qf == 0 && !FormulaIsConvertible(q))) {
03858           /*
03859           ** !(p -> q) = p * !q
03860           **
03861           **   *     =>     *     =>      *
03862           **  / \          / \          /   \
03863           ** r  NOT       r   *        *    NOT
03864           **    /            / \      / \   /
03865           **  THEN          p  NOT   r   p q
03866           **   / \              /
03867           **  p   q            q
03868           */
03869 
03870           parent->left = formula->left;
03871           parent->left->type = Ctlp_AND_c;
03872           parent->left->left = r;
03873           parent->left->right = p;
03874           parent->right = formula;
03875           parent->right->left = q;
03876 
03877           parent->top = 1;
03878           parent->compareValue = compareValue;
03879           parent->right->states = (mdd_t *)parent;
03880 
03881           FormulaConvertToForward(parent->right, compareValue);
03882         } else {
03883           /*
03884           ** !(p -> q) = p * !q
03885           **
03886           **   *     =>     *     =>      *
03887           **  / \          / \          /   \
03888           ** r  NOT       r   *        *     p
03889           **    /            / \      / \
03890           **  THEN          p  NOT   r  NOT
03891           **   / \              /       /
03892           **  p   q            q       q
03893           */
03894 
03895           parent->left = formula->left;
03896           parent->left->type = Ctlp_AND_c;
03897           parent->left->left = r;
03898           parent->left->right = formula;
03899           parent->left->right->left = q;
03900           parent->left->right->right = NIL(Ctlp_Formula_t);
03901           parent->right = p;
03902 
03903           parent->top = 1;
03904           parent->compareValue = compareValue;
03905           p->states = (mdd_t *)parent;
03906 
03907           FormulaConvertToForward(p, compareValue);
03908         }
03909       } else if (formula->left->type == Ctlp_OR_c) {
03910         /*
03911         ** !(p + q) = !p * !q
03912         **
03913         **   *     =>     *     =>        *
03914         **  / \          / \            /   \
03915         ** r  NOT       r   *          *    NOT
03916         **    /            / \        / \    /
03917         **    OR         NOT NOT     r  NOT g=q(p)
03918         **   / \          /   /         /
03919         **  p   q        p   q         f=p(q)
03920         */
03921 
03922         p = formula->left->left;
03923         q = formula->left->right;
03924         p_qf = Ctlp_FormulaTestIsQuantifierFree(p);
03925         q_qf = Ctlp_FormulaTestIsQuantifierFree(q);
03926 
03927         if (p_qf && q_qf)
03928           break;
03929         else if (p_qf) {
03930           f = p;
03931           g = q;
03932         } else if (q_qf) {
03933           f = q;
03934           g = p;
03935         } else  {
03936           if (!FormulaIsConvertible(q)) {
03937             f = p;
03938             g = q;
03939           } else {
03940             f = q;
03941             g = p;
03942           }
03943         }
03944 
03945         parent->left = formula->left;
03946         parent->left->type = Ctlp_AND_c;
03947         parent->left->left = r;
03948         parent->left->right = formula;
03949         parent->left->right->left = f;
03950         parent->left->right->right = NIL(Ctlp_Formula_t);
03951         parent->right = FormulaCreateWithType(Ctlp_NOT_c);
03952         parent->right->left = g;
03953 
03954         parent->top = 1;
03955         parent->compareValue = compareValue;
03956         parent->right->states = (mdd_t *)parent;
03957 
03958         FormulaConvertToForward(parent->right, compareValue);
03959       } else if (formula->left->type == Ctlp_AND_c) {
03960         /*
03961         ** !(p * q) = !p + !q
03962         **
03963         **   *          *(+)           *(+)
03964         **  / \         / \           /    \
03965         ** r  NOT  =>  r  OR    =>   *      *
03966         **    /           / \       / \    / \
03967         **   AND        NOT NOT    r  NOT r  NOT
03968         **   / \        /   /         /      /
03969         **  p   q      p   q         p      q
03970         */
03971 
03972         p = formula->left->left;
03973         q = formula->left->right;
03974 
03975         if (Ctlp_FormulaTestIsQuantifierFree(p) &&
03976             Ctlp_FormulaTestIsQuantifierFree(q)) {
03977           break;
03978         }
03979 
03980         if (compareValue)
03981           parent->type = Ctlp_OR_c;
03982         parent->left = formula->left;
03983         parent->left->left = r;
03984         parent->left->right = formula;
03985         parent->left->right->left = p;
03986 
03987         parent->right = FormulaCreateWithType(Ctlp_AND_c);
03988         parent->right->left = Ctlp_FormulaDup(r);
03989         parent->right->right = FormulaCreateWithType(Ctlp_NOT_c);
03990         parent->right->right->left = q;
03991 
03992         parent->top = 0;
03993         parent->left->top = 1;
03994         parent->right->top = 1;
03995         parent->left->compareValue = compareValue;
03996         parent->right->compareValue = compareValue;
03997         parent->left->right->states = (mdd_t *)parent->left;
03998         parent->right->right->states = (mdd_t *)parent->right;
03999 
04000         FormulaConvertToForward(parent->left->right, compareValue);
04001         FormulaConvertToForward(parent->right->right, compareValue);
04002       } else if (formula->left->type == Ctlp_XOR_c) {
04003         /*
04004         ** !(p ^ q) = p * q + !p * !q
04005         **
04006         **   *              *(+)                   *(+)
04007         **  / \            /     \               /      \
04008         ** |   |   =>     *       *      =>    *          *
04009         ** |   |         / \     / \          / \      /     \
04010         ** r  NOT       r   *   r   *        *   g    *      NOT
04011         **    /            / \     / \      / \      / \     /
04012         **   XOR          p   q  NOT NOT   r   f    r  NOT  g=q(p)
04013         **   / \                 /   /                 /
04014         **  p   q               p   q                 f=p(q)
04015         */
04016 
04017         p = formula->left->left;
04018         q = formula->left->right;
04019         p_qf = Ctlp_FormulaTestIsQuantifierFree(p);
04020         q_qf = Ctlp_FormulaTestIsQuantifierFree(q);
04021 
04022         same_order = 1;
04023         if (p_qf && q_qf)
04024           break;
04025         else if (p_qf) {
04026           f = p;
04027           g = q;
04028         } else if (q_qf) {
04029           f = q;
04030           g = p;
04031         } else {
04032           if (FormulaIsConvertible(p) && !FormulaIsConvertible(q)) {
04033             /*
04034             ** !(p ^ q) = q * p + !p * !q
04035             **
04036             **   *              *(+)                   *(+)
04037             **  / \            /     \               /      \
04038             ** |   |   =>     *       *      =>    *          *
04039             ** |   |         / \     / \          / \      /     \
04040             ** r  NOT       r   *   r   *        *   p    *      NOT
04041             **    /            / \     / \      / \      / \     /
04042             **   XOR          p   q  NOT NOT   r   q    r  NOT  q
04043             **   / \                 /   /                 /
04044             **  p   q               p   q                 p
04045             */
04046 
04047             f = q;
04048             g = p;
04049             same_order = 0;
04050           } else if (!FormulaIsConvertible(p) && FormulaIsConvertible(q)) {
04051             /*
04052             ** !(p ^ q) = p * q + !q * !p
04053             **
04054             **   *              *(+)                   *(+)
04055             **  / \            /     \               /      \
04056             ** |   |   =>     *       *      =>    *          *
04057             ** |   |         / \     / \          / \      /     \
04058             ** r  NOT       r   *   r   *        *   q    *      NOT
04059             **    /            / \     / \      / \      / \     /
04060             **   XOR          p   q  NOT NOT   r   p    r  NOT  p
04061             **   / \                 /   /                 /
04062             **  p   q               p   q                 q
04063             */
04064 
04065             f = p;
04066             g = q;
04067             same_order = 0;
04068           } else {
04069             f = p;
04070             g = q;
04071           }
04072         }
04073 
04074         if (compareValue)
04075           parent->type = Ctlp_OR_c;
04076         parent->left = formula;
04077         parent->left->type = Ctlp_AND_c;
04078         parent->left->left->type = Ctlp_AND_c;
04079         parent->left->left->left = r;
04080         parent->left->left->right = f;
04081         parent->left->right = g;
04082 
04083         parent->right = FormulaCreateWithType(Ctlp_AND_c);
04084         parent->right->left = FormulaCreateWithType(Ctlp_AND_c);
04085         parent->right->left->left = Ctlp_FormulaDup(r);
04086         parent->right->left->right = FormulaCreateWithType(Ctlp_NOT_c);
04087         if (same_order)
04088           parent->right->left->right->left = Ctlp_FormulaDup(f);
04089         else
04090           parent->right->left->right->left = Ctlp_FormulaDup(g);
04091         parent->right->right = FormulaCreateWithType(Ctlp_NOT_c);
04092         if (same_order)
04093           parent->right->right->left = Ctlp_FormulaDup(g);
04094         else
04095           parent->right->right->left = Ctlp_FormulaDup(f);
04096 
04097         parent->top = 0;
04098         parent->left->top = 1;
04099         parent->right->top = 1;
04100         parent->left->compareValue = compareValue;
04101         parent->right->compareValue = compareValue;
04102         parent->left->right->states = (mdd_t *)parent->left;
04103         parent->right->right->states = (mdd_t *)parent->right;
04104 
04105         FormulaConvertToForward(parent->left->right, compareValue);
04106         FormulaConvertToForward(parent->right->right, compareValue);
04107       } else if (formula->left->type == Ctlp_EQ_c) {
04108         /*
04109         ** !(EQ(p, q) = XOR(p, q)
04110         **
04111         **   *              *(+)                   *(+)
04112         **  / \            /     \                /     \
04113         ** |   |   =>     *       *      =>     *         *
04114         ** |   |         / \     / \          /   \     /   \
04115         ** r  NOT       r   *   r   *        *     g   *    NOT
04116         **    /            / \     / \      / \       / \   /
04117         **   EQ           p  NOT NOT  q    r  NOT    r   f g=q(p)
04118         **   / \             /   /            /
04119         **  p   q           q   p            f=p(q)
04120         */
04121 
04122         p = formula->left->left;
04123         q = formula->left->right;
04124         p_qf = Ctlp_FormulaTestIsQuantifierFree(p);
04125         q_qf = Ctlp_FormulaTestIsQuantifierFree(q);
04126 
04127         if (p_qf && q_qf)
04128           break;
04129         else if (p_qf) {
04130           f = p;
04131           g = q;
04132         } else if (q_qf) {
04133           f = q;
04134           g = p;
04135         } else {
04136           if (FormulaIsConvertible(p) && FormulaIsConvertible(q)) {
04137             /*
04138             ** !(EQ(p, q) = XOR(p, q)
04139             **
04140             **   *              *(+)                   *(+)
04141             **  / \            /     \                /     \
04142             ** |   |   =>     *       *      =>     *         *
04143             ** |   |         / \     / \          /   \     /   \
04144             ** r  NOT       r   *   r   *        *     p   *     q
04145             **    /            / \     / \      / \       / \
04146             **   EQ           p  NOT NOT  q    r  NOT    r  NOT
04147             **   / \             /   /            /         /
04148             **  p   q           q   p            q         p
04149             */
04150 
04151             if (compareValue)
04152               parent->type = Ctlp_OR_c;
04153             parent->left = parent->right;
04154             parent->left->type = Ctlp_AND_c;
04155             parent->left->left->type = Ctlp_AND_c;
04156             parent->left->left->left = r;
04157             parent->left->left->right = FormulaCreateWithType(Ctlp_NOT_c);
04158             parent->left->left->right->left = q;
04159             parent->left->right = p;
04160 
04161             parent->right = FormulaCreateWithType(Ctlp_AND_c);
04162             parent->right->left = FormulaCreateWithType(Ctlp_AND_c);
04163             parent->right->left->left = Ctlp_FormulaDup(r);
04164             parent->right->left->right = FormulaCreateWithType(Ctlp_NOT_c);
04165             parent->right->left->right->left = Ctlp_FormulaDup(p);
04166             parent->right->right = Ctlp_FormulaDup(q);
04167 
04168             parent->top = 0;
04169             parent->left->top = 1;
04170             parent->right->top = 1;
04171             parent->left->compareValue = compareValue;
04172             parent->right->compareValue = compareValue;
04173             parent->left->right->states = (mdd_t *)parent->left;
04174             parent->right->right->states = (mdd_t *)parent->right;
04175 
04176             FormulaConvertToForward(parent->left->right, compareValue);
04177             FormulaConvertToForward(parent->right->right, compareValue);
04178             break;
04179           } else if (!FormulaIsConvertible(p) && !FormulaIsConvertible(q)) {
04180             /*
04181             ** !(EQ(p, q) = XOR(p, q)
04182             **
04183             **   *              *(+)                   *(+)
04184             **  / \            /     \                /     \
04185             ** |   |   =>     *       *      =>     *         *
04186             ** |   |         / \     / \          /   \     /   \
04187             ** r  NOT       r   *   r   *        *    NOT  *    NOT
04188             **    /            / \     / \      / \   /   / \   /
04189             **   EQ           p  NOT NOT  q    r   p q   r   q p
04190             **   / \             /   /
04191             **  p   q           q   p
04192             */
04193 
04194             if (compareValue)
04195               parent->type = Ctlp_OR_c;
04196             parent->left = parent->right;
04197             parent->left->type = Ctlp_AND_c;
04198             parent->left->left->type = Ctlp_AND_c;
04199             parent->left->left->left = r;
04200             parent->left->left->right = p;
04201             parent->left->right = FormulaCreateWithType(Ctlp_NOT_c);
04202             parent->left->right->left = q;
04203 
04204             parent->right = FormulaCreateWithType(Ctlp_AND_c);
04205             parent->right->left = FormulaCreateWithType(Ctlp_AND_c);
04206             parent->right->left->left = Ctlp_FormulaDup(r);
04207             parent->right->left->right = Ctlp_FormulaDup(q);
04208             parent->right->right = FormulaCreateWithType(Ctlp_NOT_c);
04209             parent->right->right->left = Ctlp_FormulaDup(p);
04210 
04211             parent->top = 0;
04212             parent->left->top = 1;
04213             parent->right->top = 1;
04214             parent->left->compareValue = compareValue;
04215             parent->right->compareValue = compareValue;
04216             parent->left->right->states = (mdd_t *)parent->left;
04217             parent->right->right->states = (mdd_t *)parent->right;
04218 
04219             FormulaConvertToForward(parent->left->right, compareValue);
04220             FormulaConvertToForward(parent->right->right, compareValue);
04221             break;
04222           } else {
04223             f = p;
04224             g = q;
04225           }
04226         }
04227 
04228         if (compareValue)
04229           parent->type = Ctlp_OR_c;
04230         parent->left = parent->right;
04231         parent->left->type = Ctlp_AND_c;
04232         parent->left->left->type = Ctlp_AND_c;
04233         parent->left->left->left = r;
04234         parent->left->left->right = FormulaCreateWithType(Ctlp_NOT_c);
04235         parent->left->left->right->left = f;
04236         parent->left->right = g;
04237 
04238         parent->right = FormulaCreateWithType(Ctlp_AND_c);
04239         parent->right->left = FormulaCreateWithType(Ctlp_AND_c);
04240         parent->right->left->left = Ctlp_FormulaDup(r);
04241         parent->right->left->right = Ctlp_FormulaDup(f);
04242         parent->right->right = FormulaCreateWithType(Ctlp_NOT_c);
04243         parent->right->right->left = Ctlp_FormulaDup(g);
04244 
04245         parent->top = 0;
04246         parent->left->top = 1;
04247         parent->right->top = 1;
04248         parent->left->compareValue = compareValue;
04249         parent->right->compareValue = compareValue;
04250         parent->left->right->states = (mdd_t *)parent->left;
04251         parent->right->right->states = (mdd_t *)parent->right;
04252 
04253         FormulaConvertToForward(parent->left->right, compareValue);
04254         FormulaConvertToForward(parent->right->right, compareValue);
04255       }
04256       break;
04257 
04258     case Ctlp_THEN_c:
04259       /*
04260       ** (p -> q) = !p + q
04261       **
04262       **   *              *(+)
04263       **  / \            /    \
04264       ** r THEN  =>     *      *
04265       **    / \        / \    / \
04266       **   p   q      r  NOT r   q
04267       **                 /
04268       **                p
04269       */
04270 
04271       p = formula->left;
04272       q = formula->right;
04273 
04274       if (Ctlp_FormulaTestIsQuantifierFree(p) &&
04275           Ctlp_FormulaTestIsQuantifierFree(q)) {
04276         break;
04277       }
04278 
04279       if (compareValue)
04280         parent->type = Ctlp_OR_c;
04281       parent->left = formula;
04282       parent->left->type = Ctlp_AND_c;
04283       parent->left->left = r;
04284       parent->left->right = FormulaCreateWithType(Ctlp_NOT_c);
04285       parent->left->right->left = p;
04286 
04287       parent->right = FormulaCreateWithType(Ctlp_AND_c);
04288       parent->right->left = Ctlp_FormulaDup(r);
04289       parent->right->right = q;
04290 
04291       parent->top = 0;
04292       parent->left->top = 1;
04293       parent->right->top = 1;
04294       parent->left->compareValue = compareValue;
04295       parent->right->compareValue = compareValue;
04296       parent->left->right->states = (mdd_t *)parent->left;
04297       parent->right->right->states = (mdd_t *)parent->right;
04298 
04299       FormulaConvertToForward(parent->left->right, compareValue);
04300       FormulaConvertToForward(parent->right->right, compareValue);
04301       break;
04302 
04303     case Ctlp_OR_c:
04304       /*
04305       **   *              *(+)
04306       **  / \            /    \
04307       ** r  OR   =>     *      *
04308       **    / \        / \    / \
04309       **   p   q      r   p  r   q
04310       */
04311 
04312       p = formula->left;
04313       q = formula->right;
04314 
04315       if (Ctlp_FormulaTestIsQuantifierFree(p) &&
04316           Ctlp_FormulaTestIsQuantifierFree(q)) {
04317         break;
04318       }
04319 
04320       if (compareValue)
04321         parent->type = Ctlp_OR_c;
04322       parent->left = formula;
04323       parent->left->type = Ctlp_AND_c;
04324       parent->left->left = r;
04325       parent->left->right = p;
04326 
04327       parent->right = FormulaCreateWithType(Ctlp_AND_c);
04328       parent->right->left = Ctlp_FormulaDup(r);
04329       parent->right->right = q;
04330 
04331       parent->top = 0;
04332       parent->left->top = 1;
04333       parent->right->top = 1;
04334       parent->left->compareValue = compareValue;
04335       parent->right->compareValue = compareValue;
04336       parent->left->right->states = (mdd_t *)parent->left;
04337       parent->right->right->states = (mdd_t *)parent->right;
04338 
04339       FormulaConvertToForward(parent->left->right, compareValue);
04340       FormulaConvertToForward(parent->right->right, compareValue);
04341       break;
04342 
04343     case Ctlp_AND_c:
04344       /*
04345       **   *     =>     *
04346       **  / \          / \
04347       ** r  AND      AND  g=q(p)
04348       **    / \      / \
04349       **   p   q    r   f=p(q)
04350       */
04351 
04352       p = formula->left;
04353       q = formula->right;
04354       p_qf = Ctlp_FormulaTestIsQuantifierFree(p);
04355       q_qf = Ctlp_FormulaTestIsQuantifierFree(q);
04356 
04357       if (p_qf && q_qf)
04358         break;
04359       else if (q_qf) {
04360         f = q;
04361         g = p;
04362       } else {
04363         f = p;
04364         g = q;
04365       }
04366 
04367       parent->left = parent->right;
04368       parent->left->left = r;
04369       parent->left->right = f;
04370       parent->right = g;
04371 
04372       parent->top = 1;
04373       parent->compareValue = compareValue;
04374       g->states = (mdd_t *)parent;
04375 
04376       FormulaConvertToForward(g, compareValue);
04377       break;
04378 
04379     case Ctlp_XOR_c:
04380       /*
04381       **   *             *(+)                  *(+)
04382       **  / \           /    \                /     \
04383       ** |   |   =>    *      *     =>      *         *
04384       ** |   |        / \    / \          /   \      / \
04385       ** r  XOR      r   *  r   *        *    NOT   *   g=q(p)
04386       **    / \         / \    / \      / \   /    / \
04387       **   p   q       q  NOT NOT p    r   f g    r  NOT
04388       **                  /   /                      /
04389       **                 p   q                      f=p(q)
04390       */
04391 
04392       p = formula->left;
04393       q = formula->right;
04394       p_qf = Ctlp_FormulaTestIsQuantifierFree(p);
04395       q_qf = Ctlp_FormulaTestIsQuantifierFree(q);
04396 
04397       if (p_qf && q_qf)
04398         break;
04399       else if (p_qf) {
04400         f = p;
04401         g = q;
04402       } else if (q_qf) {
04403         f = q;
04404         g = p;
04405       } else {
04406         if (FormulaIsConvertible(p) && FormulaIsConvertible(q)) {
04407           /*
04408           **   *             *(+)                  *(+)
04409           **  / \           /    \                /     \
04410           ** |   |   =>    *      *     =>      *         *
04411           ** |   |        / \    / \          /   \      / \
04412           ** r  XOR      r   *  r   *        *     q    *   p
04413           **    / \         / \    / \      / \        / \
04414           **   p   q       q  NOT NOT p    r  NOT     r  NOT
04415           **                  /   /           /          /
04416           **                 p   q           p          q
04417           */
04418 
04419           if (compareValue)
04420             parent->type = Ctlp_OR_c;
04421           parent->left = parent->right;
04422           parent->left->type = Ctlp_AND_c;
04423           parent->left->left->type = Ctlp_AND_c;
04424           parent->left->left->left = r;
04425           parent->left->left->right = FormulaCreateWithType(Ctlp_NOT_c);
04426           parent->left->left->right->left = p;
04427           parent->left->right = q;
04428 
04429           parent->right = FormulaCreateWithType(Ctlp_AND_c);
04430           parent->right->left = FormulaCreateWithType(Ctlp_AND_c);
04431           parent->right->left->left = Ctlp_FormulaDup(r);
04432           parent->right->left->right = FormulaCreateWithType(Ctlp_NOT_c);
04433           parent->right->left->right->left = Ctlp_FormulaDup(q);
04434           parent->right->right = Ctlp_FormulaDup(p);
04435 
04436           parent->top = 0;
04437           parent->left->top = 1;
04438           parent->right->top = 1;
04439           parent->left->compareValue = compareValue;
04440           parent->right->compareValue = compareValue;
04441           parent->left->right->states = (mdd_t *)parent->left;
04442           parent->right->right->states = (mdd_t *)parent->right;
04443 
04444           FormulaConvertToForward(parent->left->right, compareValue);
04445           FormulaConvertToForward(parent->right->right, compareValue);
04446           break;
04447         } else if (!FormulaIsConvertible(p) && !FormulaIsConvertible(q)) {
04448           /*
04449           **   *             *(+)                   *(+)
04450           **  / \           /    \                /      \
04451           ** |   |   =>    *      *     =>      *          *
04452           ** |   |        / \    / \          /   \      /   \
04453           ** r  XOR      r   *  r   *        *    NOT   *    NOT
04454           **    / \         / \    / \      / \   /    / \   /
04455           **   p   q       q  NOT NOT p    r   p q    r   q p
04456           **                  /   /
04457           **                 p   q
04458           */
04459 
04460           if (compareValue)
04461             parent->type = Ctlp_OR_c;
04462           parent->left = parent->right;
04463           parent->left->type = Ctlp_AND_c;
04464           parent->left->left->type = Ctlp_AND_c;
04465           parent->left->left->left = r;
04466           parent->left->left->right = p;
04467           parent->left->right = FormulaCreateWithType(Ctlp_NOT_c);
04468           parent->left->right->left = q;
04469 
04470           parent->right = FormulaCreateWithType(Ctlp_AND_c);
04471           parent->right->left = FormulaCreateWithType(Ctlp_AND_c);
04472           parent->right->left->left = Ctlp_FormulaDup(r);
04473           parent->right->left->right = Ctlp_FormulaDup(q);
04474           parent->right->right = FormulaCreateWithType(Ctlp_NOT_c);
04475           parent->right->right->left = Ctlp_FormulaDup(p);
04476 
04477           parent->top = 0;
04478           parent->left->top = 1;
04479           parent->right->top = 1;
04480           parent->left->compareValue = compareValue;
04481           parent->right->compareValue = compareValue;
04482           parent->left->right->states = (mdd_t *)parent->left;
04483           parent->right->right->states = (mdd_t *)parent->right;
04484 
04485           FormulaConvertToForward(parent->left->right, compareValue);
04486           FormulaConvertToForward(parent->right->right, compareValue);
04487           break;
04488         } else {
04489           f = p;
04490           g = q;
04491         }
04492       }
04493 
04494       if (compareValue)
04495         parent->type = Ctlp_OR_c;
04496       parent->left = parent->right;
04497       parent->left->type = Ctlp_AND_c;
04498       parent->left->left = FormulaCreateWithType(Ctlp_AND_c);
04499       parent->left->left->left = r;
04500       parent->left->left->right = f;
04501       parent->left->right = FormulaCreateWithType(Ctlp_NOT_c);
04502       parent->left->right->left = g;
04503 
04504       parent->right = FormulaCreateWithType(Ctlp_AND_c);
04505       parent->right->left = FormulaCreateWithType(Ctlp_AND_c);
04506       parent->right->left->left = Ctlp_FormulaDup(r);
04507       parent->right->left->right = FormulaCreateWithType(Ctlp_NOT_c);
04508       parent->right->left->right->left = Ctlp_FormulaDup(f);
04509       parent->right->right = Ctlp_FormulaDup(g);
04510 
04511       parent->top = 0;
04512       parent->left->top = 1;
04513       parent->right->top = 1;
04514       parent->left->compareValue = compareValue;
04515       parent->right->compareValue = compareValue;
04516       parent->left->right->states = (mdd_t *)parent->left;
04517       parent->right->right->states = (mdd_t *)parent->right;
04518 
04519       FormulaConvertToForward(parent->left->right, compareValue);
04520       FormulaConvertToForward(parent->right->right, compareValue);
04521       break;
04522 
04523     case Ctlp_EQ_c:
04524       /*
04525       **   *              *(+)                   *(+)
04526       **  / \            /     \               /      \
04527       ** |   |   =>     *       *      =>    *          *
04528       ** |   |         / \     / \          / \      /     \
04529       ** r  EQ        r   *   r   *        *   g    *      NOT
04530       **    /\           / \     / \      / \      / \     /
04531       **   p  q         p   q  NOT NOT   r   f    r  NOT  g=q(p)
04532       **                       /   /                 /
04533       **                      p   q                 f=p(q)
04534       */
04535 
04536       p = formula->left;
04537       q = formula->right;
04538       p_qf = Ctlp_FormulaTestIsQuantifierFree(p);
04539       q_qf = Ctlp_FormulaTestIsQuantifierFree(q);
04540 
04541       same_order = 1;
04542       if (p_qf && q_qf)
04543         break;
04544       else if (p_qf) {
04545         f = p;
04546         g = q;
04547       } else if (q_qf) {
04548         f = q;
04549         g = p;
04550       } else {
04551         if (FormulaIsConvertible(p) && !FormulaIsConvertible(q)) {
04552           /*
04553           **   *              *(+)                   *(+)
04554           **  / \            /     \               /      \
04555           ** |   |   =>     *       *      =>    *          *
04556           ** |   |         / \     / \          / \      /     \
04557           ** r  EQ        r   *   r   *        *   p    *      NOT
04558           **    /\           / \     / \      / \      / \     /
04559           **   p  q         p   q  NOT NOT   r   q    r  NOT  q
04560           **                       /   /                 /
04561           **                      p   q                 p
04562           */
04563 
04564           f = q;
04565           g = p;
04566           same_order = 0;
04567         } else if (!FormulaIsConvertible(p) && FormulaIsConvertible(q)) {
04568           /*
04569           **   *              *(+)                   *(+)
04570           **  / \            /     \               /      \
04571           ** |   |   =>     *       *      =>    *          *
04572           ** |   |         / \     / \          / \      /     \
04573           ** r  EQ        r   *   r   *        *   q    *      NOT
04574           **    /\           / \     / \      / \      / \     /
04575           **   p  q         p   q  NOT NOT   r   p    r  NOT  p
04576           **                       /   /                 /
04577           **                      p   q                 q
04578           */
04579 
04580           f = p;
04581           g = q;
04582           same_order = 0;
04583         } else {
04584           f = p;
04585           g = q;
04586         }
04587       }
04588 
04589       if (compareValue)
04590         parent->type = Ctlp_OR_c;
04591       parent->left = parent->right;
04592       parent->left->type = Ctlp_AND_c;
04593       parent->left->left = FormulaCreateWithType(Ctlp_AND_c);
04594       parent->left->left->left = r;
04595       parent->left->left->right = f;
04596       parent->left->right = g;
04597 
04598       parent->right = FormulaCreateWithType(Ctlp_AND_c);
04599       parent->right->left = FormulaCreateWithType(Ctlp_AND_c);
04600       parent->right->left->left = Ctlp_FormulaDup(r);
04601       parent->right->left->right = FormulaCreateWithType(Ctlp_NOT_c);
04602       if (same_order)
04603         parent->right->left->right->left = Ctlp_FormulaDup(f);
04604       else
04605         parent->right->left->right->left = Ctlp_FormulaDup(g);
04606       parent->right->right = FormulaCreateWithType(Ctlp_NOT_c);
04607       if (same_order)
04608         parent->right->right->left = Ctlp_FormulaDup(g);
04609       else
04610         parent->right->right->left = Ctlp_FormulaDup(f);
04611 
04612       parent->top = 0;
04613       parent->left->top = 1;
04614       parent->right->top = 1;
04615       parent->left->compareValue = compareValue;
04616       parent->right->compareValue = compareValue;
04617       parent->left->right->states = (mdd_t *)parent->left;
04618       parent->right->right->states = (mdd_t *)parent->right;
04619 
04620       FormulaConvertToForward(parent->left->right, compareValue);
04621       FormulaConvertToForward(parent->right->right, compareValue);
04622       break;
04623 
04624     case Ctlp_AX_c:
04625     case Ctlp_AG_c:
04626     case Ctlp_AF_c:
04627     case Ctlp_AU_c:
04628       fprintf(vis_stderr,
04629         "** ctl error : invalid node type in converting to forward formula.\n"
04630               );
04631       assert(0);
04632       break;
04633 
04634     case Ctlp_ID_c:
04635     case Ctlp_TRUE_c:
04636     case Ctlp_FALSE_c:
04637       break;
04638 
04639     default:
04640       fail("Unexpected type");
04641   }
04642 }
04643 
04644 
04656 static void
04657 FormulaInsertForwardCompareNodes(Ctlp_Formula_t *formula,
04658                                  Ctlp_Formula_t *parent,
04659                                  int compareValue)
04660 {
04661   Ctlp_Formula_t *new_;
04662 
04663   if (formula->top) {
04664     if (!parent) {
04665       new_ = FormulaCreateWithType(Ctlp_Cmp_c);
04666       memcpy((void *)new_, (void *)formula, sizeof(Ctlp_Formula_t));
04667       formula->type = Ctlp_Cmp_c;
04668       formula->left = new_;
04669       formula->right = FormulaCreateWithType(Ctlp_FALSE_c);
04670       formula->compareValue = compareValue;
04671     } else {
04672       new_ = FormulaCreateWithType(Ctlp_Cmp_c);
04673       new_->left = formula;
04674       new_->right = FormulaCreateWithType(Ctlp_FALSE_c);
04675       new_->compareValue = compareValue;
04676       if (parent->left == formula)
04677         parent->left = new_;
04678       else
04679         parent->right = new_;
04680     }
04681     return;
04682   }
04683   FormulaInsertForwardCompareNodes(formula->left, formula, compareValue);
04684   FormulaInsertForwardCompareNodes(formula->right, formula, compareValue);
04685 }
04686 
04687 
04700 static int
04701 FormulaGetCompareValue(Ctlp_Formula_t *formula)
04702 {
04703   int   compareValue;
04704 
04705   if (FormulaIsConvertible(formula))
04706     compareValue = 1; /* check whether the result is not FALSE */
04707   else
04708     compareValue = 0; /* check whether the result is FALSE. */
04709 
04710   return(compareValue);
04711 }
04712 
04713 
04727 static int
04728 FormulaIsConvertible(Ctlp_Formula_t *formula)
04729 {
04730   int   convertible;
04731   int   value1, value2;
04732 
04733   if (Ctlp_FormulaTestIsQuantifierFree(formula))
04734     convertible = 1;
04735   else if (formula->type == Ctlp_ID_c)
04736     convertible = 1;
04737   else if (formula->type == Ctlp_EX_c ||
04738            formula->type == Ctlp_EU_c ||
04739            formula->type == Ctlp_EF_c ||
04740            formula->type == Ctlp_EG_c) {
04741     convertible = 1;
04742   } else if (formula->type == Ctlp_NOT_c) {
04743     if (formula->left->type == Ctlp_NOT_c) {
04744       if (formula->left->left->type == Ctlp_EX_c ||
04745           formula->left->left->type == Ctlp_EU_c ||
04746           formula->left->left->type == Ctlp_EF_c ||
04747           formula->left->left->type == Ctlp_EG_c) {
04748         convertible = 1;
04749       } else {
04750         convertible = FormulaIsConvertible(formula->left->left);
04751       }
04752     } else {
04753       if (formula->left->type == Ctlp_EX_c ||
04754           formula->left->type == Ctlp_EU_c ||
04755           formula->left->type == Ctlp_EF_c ||
04756           formula->left->type == Ctlp_EG_c) {
04757         convertible = 0;
04758       } else {
04759         value1 = FormulaIsConvertible(formula->left);
04760         value2 = FormulaIsConvertible(formula->right);
04761         switch (formula->type) {
04762         case Ctlp_AND_c:
04763         case Ctlp_OR_c:
04764           convertible = (value1 & 0x1) * (value2 & 0x1);
04765           break;
04766         case Ctlp_THEN_c:
04767           convertible = value1 * (value2 & 0x1);
04768           break;
04769         default :
04770           convertible = 2;
04771           break;
04772         }
04773       }
04774     }
04775   } else {
04776     value1 = FormulaIsConvertible(formula->left);
04777     value2 = FormulaIsConvertible(formula->right);
04778     switch (formula->type) {
04779     case Ctlp_AND_c:
04780     case Ctlp_OR_c:
04781       convertible = value1 * value2;
04782       break;
04783     case Ctlp_THEN_c:
04784       convertible = (value1 & 0x1) * value2;
04785       break;
04786     default :
04787       convertible = 2;
04788       break;
04789     }
04790   }
04791 
04792   return(convertible);
04793 }
04794 
04795 
04813 static Ctlp_Formula_t *
04814 ReplaceSimpleFormula(
04815   Ctlp_Formula_t * formula)
04816 {
04817   Ctlp_Formula_t *newFormula;
04818 
04819   assert(formula->negation_parity == Ctlp_Even_c ||
04820          formula->negation_parity == Ctlp_Odd_c);
04821 
04822   if (Ctlp_FormulaReadType(formula) == Ctlp_THEN_c) {
04823     Ctlp_Formula_t *leftFormula, *rightFormula;
04824     Ctlp_Formula_t *newLeftFormula, *newRightFormula;
04825 
04826     leftFormula = Ctlp_FormulaReadLeftChild(formula);
04827     rightFormula = Ctlp_FormulaReadRightChild(formula);
04828     newLeftFormula = Ctlp_FormulaDup(leftFormula);
04829     newRightFormula = ReplaceSimpleFormula(rightFormula);
04830     return Ctlp_FormulaCreate(Ctlp_THEN_c,newLeftFormula,newRightFormula);
04831   }
04832 
04833   fprintf(vis_stderr, "Replacing formula ");
04834   Ctlp_FormulaPrint(vis_stderr, formula);
04835   if (formula->negation_parity == Ctlp_Even_c){
04836     fprintf(vis_stderr, " by FALSE\n");
04837     newFormula = FormulaCreateWithType(Ctlp_FALSE_c);
04838   } else{
04839     fprintf(vis_stderr, " by TRUE\n");
04840     newFormula = FormulaCreateWithType(Ctlp_TRUE_c);
04841   }
04842   newFormula->negation_parity = formula->negation_parity;
04843   return(newFormula);
04844 }