VIS

src/ctlsp/ctlspUtil.c

Go to the documentation of this file.
00001 
00021 #include "ctlspInt.h"
00022 #include "errno.h"
00023 #include "ntk.h"
00024 
00025 static char rcsid[] UNUSED = "$Id: ctlspUtil.c,v 1.64 2009/04/11 18:25:55 fabio Exp $";
00026 
00027 /*---------------------------------------------------------------------------*/
00028 /* Variable declarations                                                     */
00029 /*---------------------------------------------------------------------------*/
00030 
00038 static array_t *globalFormulaArray;
00039 static int      changeBracket = 1;
00040 
00041 /* see ctlspInt.h for documentation */
00042 int CtlspGlobalError;
00043 Ctlsp_Formula_t *CtlspGlobalFormula;
00044 st_table *CtlspMacroTable;
00045 
00046 /*---------------------------------------------------------------------------*/
00047 /* Macro declarations                                                        */
00048 /*---------------------------------------------------------------------------*/
00049 
00050 
00053 /*---------------------------------------------------------------------------*/
00054 /* Static function prototypes                                                */
00055 /*---------------------------------------------------------------------------*/
00056 
00057 static Ctlsp_Formula_t * FormulaCreateWithType(Ctlsp_FormulaType type);
00058 static int FormulaCompare(const char *key1, const char *key2);
00059 static int FormulaHash(char *key, int modulus);
00060 static Ctlsp_Formula_t * FormulaHashIntoUniqueTable(Ctlsp_Formula_t *formula, st_table *uniqueTable);
00061 static Ctlsp_Formula_t * createSNFnode(Ctlsp_Formula_t *formula, array_t *formulaArray, int *index);
00062 
00066 /*---------------------------------------------------------------------------*/
00067 /* Definition of exported functions                                          */
00068 /*---------------------------------------------------------------------------*/
00069 
00085 array_t *
00086 Ctlsp_FileParseFormulaArray(
00087   FILE * fp)
00088 {
00089   st_generator *stGen;
00090   char *name;
00091   Ctlsp_Formula_t *formula;
00092   char *flagValue;
00093   /*
00094    * Initialize the global variables.
00095    */
00096   globalFormulaArray = array_alloc(Ctlsp_Formula_t *, 0);
00097   CtlspGlobalError = 0;
00098   CtlspGlobalFormula = NIL(Ctlsp_Formula_t);
00099   CtlspMacroTable = st_init_table(strcmp,st_strhash);
00100   CtlspFileSetup(fp);
00101   /*
00102    * Check if changing "[] -> <>" is disabled.
00103    */
00104   flagValue = Cmd_FlagReadByName("ctl_change_bracket");
00105   if (flagValue != NIL(char)) {
00106     if (strcmp(flagValue, "yes") == 0)
00107       changeBracket = 1;
00108     else if (strcmp(flagValue, "no") == 0)
00109       changeBracket = 0;
00110     else {
00111       fprintf(vis_stderr,
00112         "** ctl error : invalid value %s for ctl_change_bracket[yes/no]. ***\n",
00113         flagValue);
00114     }
00115   }
00116 
00117   (void)CtlspYyparse();
00118   st_foreach_item(CtlspMacroTable,stGen,&name, &formula){
00119      FREE(name);
00120      CtlspFormulaFree(formula);
00121   }
00122   st_free_table(CtlspMacroTable);
00123 
00124   /*
00125    * Clean up if there was an error, otherwise return the array.
00126    */
00127   if (CtlspGlobalError){
00128     Ctlsp_FormulaArrayFree(globalFormulaArray);
00129     return NIL(array_t);
00130   }
00131   else {
00132     return globalFormulaArray;
00133   }
00134 }
00135 
00136 
00152 array_t *
00153 Ctlsp_FileParseCTLFormulaArray(
00154   FILE *fp)
00155 {
00156   array_t *ctlsArray = Ctlsp_FileParseFormulaArray(fp);
00157   array_t *ctlArray;
00158 
00159   if (ctlsArray == NIL(array_t)) return NIL(array_t);
00160   ctlArray = Ctlsp_FormulaArrayConvertToCTL(ctlsArray);
00161   Ctlsp_FormulaArrayFree(ctlsArray);
00162   return ctlArray;
00163   
00164 } /* Ctlsp_FileParseCTLFormulaArray */
00165 
00176 char *
00177 Ctlsp_FormulaConvertToString(
00178   Ctlsp_Formula_t * formula)
00179 {
00180   char *s1        = NIL(char);
00181   char *s2        = NIL(char);
00182   char *tmpString = NIL(char);
00183   char *result;
00184 
00185 
00186   if (formula == NIL(Ctlsp_Formula_t)) {
00187     return NIL(char);
00188   }
00189 
00190   /* leaf node */
00191   if (formula->type == Ctlsp_ID_c){
00192   result = util_strcat3((char *)(formula->left), "=",(char *)(formula->right));
00193   /*
00194   tmpString = util_strcat3("[", util_inttostr(formula->CTLclass),"]");
00195   return util_strcat3(result, " ",tmpString);
00196   */
00197   return result;
00198   }
00199 
00200   /* If the formula is a non-leaf, the function is called recursively */
00201   s1 = Ctlsp_FormulaConvertToString(formula->left);
00202   s2 = Ctlsp_FormulaConvertToString(formula->right);
00203 
00204   switch(formula->type) {
00205     /*
00206      * The cases are listed in rough order of their expected frequency.
00207      */
00208     case Ctlsp_OR_c:
00209       tmpString = util_strcat3(s1, " + ",s2);
00210       result    = util_strcat3("(", tmpString, ")");
00211       break;
00212     case Ctlsp_AND_c:
00213       tmpString = util_strcat3(s1, " * ", s2);
00214       result    = util_strcat3("(", tmpString, ")");
00215       break;
00216     case Ctlsp_THEN_c:
00217       tmpString = util_strcat3(s1, " -> ", s2);
00218       result    = util_strcat3("(", tmpString, ")");
00219       break;
00220     case Ctlsp_XOR_c:
00221       tmpString = util_strcat3(s1, " ^ ", s2);
00222       result    = util_strcat3("(", tmpString, ")");
00223       break;
00224     case Ctlsp_EQ_c:
00225       tmpString = util_strcat3(s1, " <-> ", s2);
00226       result    = util_strcat3("(", tmpString, ")");
00227       break;
00228     case Ctlsp_NOT_c:
00229       tmpString = util_strcat3("(", s1, ")");
00230       result    = util_strcat3("!", tmpString, "");
00231       break;
00232     case Ctlsp_E_c:
00233       result = util_strcat3("E(", s1, ")");
00234       FREE(s1);
00235       break;
00236     case Ctlsp_G_c:
00237       result = util_strcat3("G(", s1, ")");
00238       break;
00239     case Ctlsp_F_c:
00240       result = util_strcat3("F(", s1, ")");
00241       break;
00242     case Ctlsp_U_c:
00243       tmpString = util_strcat3("(", s1, " U ");
00244       result    = util_strcat3(tmpString, s2, ")");
00245       break;
00246     case Ctlsp_R_c:
00247       tmpString = util_strcat3("(", s1, " R ");
00248       result    = util_strcat3(tmpString, s2, ")");
00249       break;
00250     case Ctlsp_W_c:
00251       tmpString = util_strcat3("(", s1, " W ");
00252       result    = util_strcat3(tmpString, s2, ")");
00253       break;
00254     case Ctlsp_X_c:
00255       result = util_strcat3("X(", s1, ")");
00256       break;
00257     case Ctlsp_A_c:
00258       result = util_strcat3("A(", s1, ")");
00259       break;;
00260     case Ctlsp_TRUE_c:
00261       result = util_strsav("TRUE");
00262       break;
00263     case Ctlsp_FALSE_c:
00264       result = util_strsav("FALSE");
00265       break;
00266     case Ctlsp_Init_c:
00267       result = util_strsav("Init");
00268       break;
00269     case Ctlsp_Cmp_c:
00270       if (formula->compareValue == 0)
00271         tmpString = util_strcat3("[", s1, "] = ");
00272       else
00273         tmpString = util_strcat3("[", s1, "] != ");
00274       result    = util_strcat3(tmpString, s2, "");
00275       break;
00276     case Ctlsp_Fwd_c:
00277       tmpString = util_strcat3("FwdG(", s1, ",");
00278       result    = util_strcat3(tmpString, s2, ")");
00279       break;
00280       /*   case Ctlsp_EY_c:
00281       result = util_strcat3("EY(", s1, ")");
00282       break;*/
00283     default:
00284       fail("Unexpected type");
00285 
00286   }
00287   if (s1 != NIL(char)) {
00288     FREE(s1);
00289   }
00290   if (s2 != NIL(char)) {
00291     FREE(s2);
00292   }
00293   if (tmpString != NIL(char)) {
00294     FREE(tmpString);
00295   }
00296 
00297   return result;
00298 }
00299 
00300 
00312 void
00313 Ctlsp_FormulaPrint(
00314   FILE * fp,
00315   Ctlsp_Formula_t * formula)
00316 {
00317   char *tmpString;
00318   if (formula == NIL(Ctlsp_Formula_t)) {
00319     return;
00320   }
00321   tmpString = Ctlsp_FormulaConvertToString(formula);
00322   (void) fprintf(fp, "%s", tmpString);
00323   FREE(tmpString);
00324 }
00325 
00326 
00339 Ctlsp_FormulaType
00340 Ctlsp_FormulaReadType(
00341   Ctlsp_Formula_t * formula)
00342 {
00343   return (formula->type);
00344 }
00345 
00346 
00359 int
00360 Ctlsp_FormulaReadCompareValue(
00361   Ctlsp_Formula_t * formula)
00362 {
00363   int value;
00364   value = formula->compareValue;
00365   return (value);
00366 }
00367 
00368 
00379 char *
00380 Ctlsp_FormulaReadVariableName(
00381   Ctlsp_Formula_t * formula)
00382 {
00383   if (formula->type != Ctlsp_ID_c){
00384     fail("Ctlsp_FormulaReadVariableName() was called on a non-leaf formula.");
00385   }
00386   return ((char *)(formula->left));
00387 }
00388 
00389 
00400 char *
00401 Ctlsp_FormulaReadValueName(
00402   Ctlsp_Formula_t * formula)
00403 {
00404   if (formula->type != Ctlsp_ID_c){
00405     fail("Ctlsp_FormulaReadValueName() was called on a non-leaf formula.");
00406   }
00407   return ((char *)(formula->right));
00408 }
00409 
00422 Ctlsp_Formula_t *
00423 Ctlsp_FormulaReadLeftChild(
00424   Ctlsp_Formula_t * formula)
00425 {
00426   if (formula->type != Ctlsp_ID_c){
00427     return (formula->left);
00428   }
00429   return NIL(Ctlsp_Formula_t);
00430 }
00431 
00432 
00445 Ctlsp_Formula_t *
00446 Ctlsp_FormulaReadRightChild(
00447   Ctlsp_Formula_t * formula)
00448 {
00449   if (formula->type != Ctlsp_ID_c){
00450     return (formula->right);
00451   }
00452   return NIL(Ctlsp_Formula_t);
00453 }
00454 
00455 
00471 mdd_t *
00472 Ctlsp_FormulaObtainStates(
00473   Ctlsp_Formula_t * formula)
00474 {
00475   if (formula->states == NIL(mdd_t)) {
00476     return NIL(mdd_t);
00477   }
00478   else {
00479     return mdd_dup(formula->states);
00480   }
00481 }
00495 mdd_t *
00496 Ctlsp_FormulaObtainApproxStates(
00497   Ctlsp_Formula_t *formula,
00498   Ctlsp_Approx_t approx)
00499 {
00500   if(approx == Ctlsp_Incomparable_c)
00501     return NIL(mdd_t);
00502 
00503   if (formula->states != NIL(mdd_t))
00504     return mdd_dup(formula->states);
00505 
00506   if(approx == Ctlsp_Exact_c)
00507     return NIL(mdd_t);
00508 
00509   if(approx == Ctlsp_Overapprox_c){
00510     if(formula->overapprox == NIL(mdd_t))
00511       return NIL(mdd_t);
00512     else
00513       return mdd_dup(formula->overapprox);
00514   }
00515 
00516   if(approx == Ctlsp_Underapprox_c){
00517     if(formula->underapprox == NIL(mdd_t))
00518       return NIL(mdd_t);
00519     else
00520       return mdd_dup(formula->underapprox);
00521   }
00522 
00523   assert(0);  /* we should never get here */
00524   return NIL(mdd_t);
00525 }
00526 
00527 
00542 void
00543 Ctlsp_FormulaSetStates(
00544   Ctlsp_Formula_t * formula,
00545   mdd_t * states)
00546 {
00547   /* RB: added the next two lines.  Given the Description, this was a
00548      bug */
00549     if(formula->states != NIL(mdd_t))
00550       mdd_free(formula->states);
00551     formula->states = states;
00552 }
00553 
00554 
00572 void
00573 Ctlsp_FormulaSetApproxStates(
00574   Ctlsp_Formula_t * formula,
00575   mdd_t * states,
00576   Ctlsp_Approx_t approx)
00577 {
00578   if(approx == Ctlsp_Incomparable_c){
00579     mdd_free(states);
00580     return;
00581   }
00582 
00583   if(approx == Ctlsp_Exact_c){
00584     if(formula->states != NIL(mdd_t))
00585       mdd_free(formula->states);
00586     formula->states = states;
00587 
00588     if(formula->underapprox != NIL(mdd_t)){
00589       mdd_free(formula->underapprox);
00590       formula->underapprox = NIL(mdd_t);
00591     }
00592 
00593     if(formula->overapprox != NIL(mdd_t)){
00594       mdd_free(formula->overapprox);
00595       formula->overapprox = NIL(mdd_t);
00596     }
00597   }
00598 
00599   if( approx == Ctlsp_Underapprox_c){
00600     /* you could perform a union instead, but typical use will
00601        have monotonically increasing underapproximations */
00602     if(formula->underapprox != NIL(mdd_t))
00603       mdd_free(formula->underapprox);
00604     formula->underapprox = states;
00605   }
00606 
00607   if( approx == Ctlsp_Overapprox_c){
00608     /* you could perform an intersaection instead */
00609     if(formula->overapprox != NIL(mdd_t))
00610       mdd_free(formula->overapprox);
00611     formula->overapprox = states;
00612   }
00613 
00614   return;
00615 }
00616 
00617 
00618 
00633 void
00634 Ctlsp_FormulaSetDbgInfo(
00635   Ctlsp_Formula_t * formula,
00636   void *data,
00637   Ctlsp_DbgInfoFreeFn freeFn)
00638 {
00639   formula->dbgInfo.data   = data;
00640   formula->dbgInfo.freeFn = freeFn;
00641 }
00642 
00643 
00656 void *
00657 Ctlsp_FormulaReadDebugData(
00658   Ctlsp_Formula_t * formula)
00659 {
00660   return formula->dbgInfo.data;
00661 }
00662 
00663 
00677 boolean
00678 Ctlsp_FormulaTestIsConverted(
00679   Ctlsp_Formula_t * formula)
00680 {
00681   return formula->dbgInfo.convertedFlag;
00682 }
00683 
00684 
00696 boolean
00697 Ctlsp_FormulaTestIsQuantifierFree(
00698   Ctlsp_Formula_t *formula)
00699 {
00700   boolean lCheck;
00701   boolean rCheck;
00702   Ctlsp_Formula_t *leftChild;
00703   Ctlsp_Formula_t *rightChild;
00704   Ctlsp_FormulaType type;
00705 
00706   if ( formula == NIL( Ctlsp_Formula_t ) ) {
00707     return TRUE;
00708   }
00709 
00710   type = Ctlsp_FormulaReadType( formula );
00711 
00712   if ( ( type == Ctlsp_ID_c ) ||
00713        ( type == Ctlsp_TRUE_c ) ||
00714        ( type == Ctlsp_FALSE_c ) ) {
00715     return TRUE;
00716   }
00717 
00718   if ( ( type == Ctlsp_E_c ) || ( type == Ctlsp_A_c ) ) {
00719     return FALSE;
00720   }
00721 
00722   leftChild = Ctlsp_FormulaReadLeftChild( formula );
00723   lCheck = Ctlsp_FormulaTestIsQuantifierFree( leftChild );
00724 
00725   if (lCheck == FALSE)
00726     return FALSE;
00727 
00728   rightChild = Ctlsp_FormulaReadRightChild( formula );
00729   rCheck = Ctlsp_FormulaTestIsQuantifierFree( rightChild );
00730 
00731   return rCheck;
00732 }
00733 
00734 
00742 Ctlsp_Formula_t *
00743 Ctlsp_FormulaReadOriginalFormula(
00744   Ctlsp_Formula_t * formula)
00745 {
00746   return formula->dbgInfo.originalFormula;
00747 }
00748 
00749 
00757 int
00758 Ctlsp_FormulaReadABIndex(
00759   Ctlsp_Formula_t * formula)
00760 {
00761   return formula->ab_idx;
00762 }
00763 
00771 void
00772 Ctlsp_FormulaSetABIndex(
00773   Ctlsp_Formula_t * formula,
00774   int ab_idx)
00775 {
00776   formula->ab_idx = ab_idx;
00777 }
00778 
00779 
00787 int
00788 Ctlsp_FormulaReadLabelIndex(
00789   Ctlsp_Formula_t * formula)
00790 {
00791   return formula->label_idx;
00792 }
00793 
00801 void
00802 Ctlsp_FormulaSetLabelIndex(
00803   Ctlsp_Formula_t * formula,
00804   int label_idx)
00805 {
00806   formula->label_idx = label_idx;
00807 }
00808 
00809 
00817 char
00818 Ctlsp_FormulaReadRhs(
00819   Ctlsp_Formula_t * formula)
00820 {
00821   return formula->rhs;
00822 }
00823 
00831 void
00832 Ctlsp_FormulaSetRhs(
00833   Ctlsp_Formula_t * formula)
00834 {
00835   formula->rhs = 1;
00836 }
00837 
00845 void
00846 Ctlsp_FormulaResetRhs(
00847   Ctlsp_Formula_t * formula)
00848 {
00849   formula->rhs = 0;
00850 }
00851 
00859 char
00860 Ctlsp_FormulaReadMarked(
00861   Ctlsp_Formula_t * formula)
00862 {
00863   return formula->marked;
00864 }
00865 
00873 void
00874 Ctlsp_FormulaSetMarked(
00875   Ctlsp_Formula_t * formula)
00876 {
00877   formula->marked = 1;
00878 }
00879 
00887 void
00888 Ctlsp_FormulaResetMarked(
00889   Ctlsp_Formula_t * formula)
00890 {
00891   formula->marked = 0;
00892 }
00893 
00907 void
00908 Ctlsp_FormulaFree(
00909   Ctlsp_Formula_t *formula)
00910 {
00911   CtlspFormulaDecrementRefCount(formula);
00912 }
00913 
00926 void
00927 Ctlsp_FlushStates(
00928   Ctlsp_Formula_t * formula)
00929 {
00930   if (formula != NIL(Ctlsp_Formula_t)) {
00931 
00932     if (formula->type != Ctlsp_ID_c){
00933       if (formula->left  != NIL(Ctlsp_Formula_t)) {
00934         Ctlsp_FlushStates(formula->left);
00935       }
00936       if (formula->right != NIL(Ctlsp_Formula_t)) {
00937         Ctlsp_FlushStates(formula->right);
00938       }
00939     }
00940 
00941     if (formula->states != NIL(mdd_t)){
00942       mdd_free(formula->states);
00943       formula->states = NIL(mdd_t);
00944     }
00945     if (formula->underapprox != NIL(mdd_t)){
00946       mdd_free(formula->underapprox);
00947       formula->underapprox = NIL(mdd_t);
00948     }
00949     if (formula->overapprox != NIL(mdd_t)){
00950       mdd_free(formula->overapprox);
00951       formula->overapprox = NIL(mdd_t);
00952     }
00953 
00954     if (formula->dbgInfo.data != NIL(void)){
00955       (*formula->dbgInfo.freeFn)(formula);
00956       formula->dbgInfo.data = NIL(void);
00957     }
00958 
00959   }
00960 
00961 }
00962 
00976 Ctlsp_Formula_t *
00977 Ctlsp_FormulaDup(
00978   Ctlsp_Formula_t * formula)
00979 {
00980   Ctlsp_Formula_t *result = NIL(Ctlsp_Formula_t);
00981 
00982   if ( formula == NIL(Ctlsp_Formula_t)) {
00983         return NIL(Ctlsp_Formula_t);
00984   }
00985 
00986   result = ALLOC(Ctlsp_Formula_t, 1);
00987 
00988   result->type                    = formula->type;
00989   result->class_                  = formula->class_;
00990   result->CTLclass                = formula->CTLclass;
00991   result->states                  = NIL(mdd_t);
00992   result->underapprox             = NIL(mdd_t);
00993   result->overapprox              = NIL(mdd_t);
00994   result->refCount                = 1;
00995   result->dbgInfo.data            = NIL(void);
00996   result->dbgInfo.freeFn          = (Ctlsp_DbgInfoFreeFn) NULL;
00997   result->dbgInfo.convertedFlag   = FALSE;
00998   result->dbgInfo.originalFormula = NIL(Ctlsp_Formula_t);
00999 
01000   if ( formula->type != Ctlsp_ID_c )  {
01001     result->left  = Ctlsp_FormulaDup(formula->left);
01002     result->right = Ctlsp_FormulaDup(formula->right);
01003   }
01004   else {
01005     result->left  = (Ctlsp_Formula_t *) util_strsav((char *)formula->left );
01006     result->right = (Ctlsp_Formula_t *) util_strsav((char *)formula->right );
01007   }
01008 
01009   return result;
01010 }
01011 
01026 void
01027 Ctlsp_FormulaArrayFree(
01028   array_t * formulaArray /* of Ctlsp_Formula_t  */)
01029 {
01030   int i;
01031   int numFormulas = array_n(formulaArray);
01032 
01033   for (i = 0; i < numFormulas; i++) {
01034     Ctlsp_Formula_t *formula = array_fetch(Ctlsp_Formula_t *, formulaArray, i);
01035 
01036     CtlspFormulaDecrementRefCount(formula);
01037   }
01038 
01039   array_free(formulaArray);
01040 }
01078 array_t *
01079 Ctlsp_FormulaArrayConvertToDAG(
01080   array_t *formulaArray)
01081 {
01082   int i;
01083   Ctlsp_Formula_t *formula, *uniqueFormula;
01084   st_table *uniqueTable = st_init_table(FormulaCompare, FormulaHash);
01085   int numFormulae = array_n(formulaArray);
01086   array_t *rootsOfFormulaDAG = array_alloc(Ctlsp_Formula_t *, numFormulae);
01087 
01088   for(i=0; i < numFormulae; i++) {
01089     formula = array_fetch(Ctlsp_Formula_t *, formulaArray, i);
01090     uniqueFormula = FormulaHashIntoUniqueTable(formula, uniqueTable);
01091     if(uniqueFormula != formula) {
01092       CtlspFormulaDecrementRefCount(formula);
01093       CtlspFormulaIncrementRefCount(uniqueFormula);
01094       array_insert(Ctlsp_Formula_t *, rootsOfFormulaDAG, i, uniqueFormula);
01095     }
01096     else
01097       array_insert(Ctlsp_Formula_t *, rootsOfFormulaDAG, i, formula);
01098   }
01099   st_free_table(uniqueTable);
01100   return rootsOfFormulaDAG;
01101 }
01102 
01121 Ctlsp_Formula_t *
01122 Ctlsp_FormulaCreate(
01123   Ctlsp_FormulaType  type,
01124   void * left_,
01125   void * right_)
01126 {
01127   Ctlsp_Formula_t *formula = ALLOC(Ctlsp_Formula_t, 1);
01128   Ctlsp_Formula_t *left    = (Ctlsp_Formula_t *) left_;
01129   Ctlsp_Formula_t *right   = (Ctlsp_Formula_t *) right_;
01130 
01131   formula->type                    = type;
01132   formula->left                    = left;
01133   formula->right                   = right;
01134   formula->states                  = NIL(mdd_t);
01135   formula->underapprox             = NIL(mdd_t);
01136   formula->overapprox              = NIL(mdd_t);
01137   formula->refCount                = 1;
01138   formula->dbgInfo.data            = NIL(void);
01139   formula->dbgInfo.freeFn          = (Ctlsp_DbgInfoFreeFn) NULL;
01140   formula->dbgInfo.convertedFlag   = FALSE;
01141   formula->dbgInfo.originalFormula = NIL(Ctlsp_Formula_t);
01142   formula->top                     = 0;
01143   formula->compareValue            = 0;
01144   formula->class_                  = Ctlsp_propformula_c;
01145   formula->CTLclass                = Ctlsp_CTL_c;
01146   formula->rhs                     = 0;
01147 
01148   if (left == NIL(Ctlsp_Formula_t)){
01149     return formula;
01150   }
01151 
01152   switch(formula->type) {
01153     case Ctlsp_OR_c:
01154     case Ctlsp_AND_c:
01155     case Ctlsp_THEN_c:
01156     case Ctlsp_XOR_c:
01157     case Ctlsp_EQ_c:
01158       Ctlsp_FormulaSetClass(formula, table1(Ctlsp_FormulaReadClass(left),Ctlsp_FormulaReadClass(right)));
01159       if ((Ctlsp_FormulaReadClassOfCTL(left)  ==  Ctlsp_CTL_c) &&
01160           (Ctlsp_FormulaReadClassOfCTL(right) == Ctlsp_CTL_c)){
01161         Ctlsp_FormulaSetClassOfCTL(formula, Ctlsp_CTL_c);
01162       } else {
01163         Ctlsp_FormulaSetClassOfCTL(formula, Ctlsp_NotCTL_c);
01164       }
01165       break;
01166     case Ctlsp_NOT_c:
01167       Ctlsp_FormulaSetClass(formula, Ctlsp_FormulaReadClass(left));
01168       Ctlsp_FormulaSetClassOfCTL(formula, Ctlsp_FormulaReadClassOfCTL(left));
01169       break;
01170     case Ctlsp_E_c:
01171     case Ctlsp_A_c:
01172       Ctlsp_FormulaSetClass(formula, Ctlsp_stateformula_c);
01173       if (Ctlsp_FormulaReadClassOfCTL(left) ==  Ctlsp_PathCTL_c) {
01174         Ctlsp_FormulaSetClassOfCTL(formula, Ctlsp_CTL_c);
01175       } else {
01176         Ctlsp_FormulaSetClassOfCTL(formula, Ctlsp_NotCTL_c);
01177       }
01178       break;
01179     case Ctlsp_G_c:
01180     case Ctlsp_F_c:
01181       Ctlsp_FormulaSetClass(formula, table2(Ctlsp_FormulaReadClass(left)));
01182       if (Ctlsp_FormulaReadClassOfCTL(left) ==  Ctlsp_CTL_c){
01183         Ctlsp_FormulaSetClassOfCTL(formula, Ctlsp_PathCTL_c);
01184       } else {
01185         Ctlsp_FormulaSetClassOfCTL(formula, Ctlsp_NotCTL_c);
01186       }
01187       break;
01188     case Ctlsp_U_c:
01189     case Ctlsp_R_c:
01190     case Ctlsp_W_c:
01191       Ctlsp_FormulaSetClass(formula, table3(Ctlsp_FormulaReadClass(left),Ctlsp_FormulaReadClass(right)));
01192       if ((Ctlsp_FormulaReadClassOfCTL(left) ==  Ctlsp_CTL_c) &&
01193           (Ctlsp_FormulaReadClassOfCTL(right) == Ctlsp_CTL_c)) {
01194         Ctlsp_FormulaSetClassOfCTL(formula, Ctlsp_PathCTL_c);
01195       } else {
01196         Ctlsp_FormulaSetClassOfCTL(formula, Ctlsp_NotCTL_c);
01197       }
01198       break;
01199     case Ctlsp_X_c:
01200       Ctlsp_FormulaSetClass(formula, table2(Ctlsp_FormulaReadClass(left)));
01201       if (Ctlsp_FormulaReadClassOfCTL(left) ==  Ctlsp_CTL_c){
01202 
01203         Ctlsp_FormulaSetClassOfCTL(formula, Ctlsp_PathCTL_c);
01204       }  else {
01205         Ctlsp_FormulaSetClassOfCTL(formula, Ctlsp_NotCTL_c);
01206       }
01207       break;
01208     default:
01209       break;
01210   }
01211   return formula;
01212 }
01213 
01226 Ctlsp_Formula_t *
01227 Ctlsp_FormulaCreateOr(
01228   char *name,
01229   char *valueStr)
01230 {
01231   Ctlsp_Formula_t *formula, *tempFormula;
01232   char *preStr;
01233 
01234   preStr = strtok(valueStr,",");
01235   formula = Ctlsp_FormulaCreate(Ctlsp_ID_c, util_strsav(name),
01236                                util_strsav(preStr));
01237   if (formula == NIL(Ctlsp_Formula_t)) {
01238      return NIL(Ctlsp_Formula_t);
01239   }
01240   while ((preStr = strtok(NIL(char),",")) != NIL(char)) {
01241     tempFormula = Ctlsp_FormulaCreate(Ctlsp_ID_c, util_strsav(name),
01242                                      util_strsav(preStr));
01243     if (tempFormula == NIL(Ctlsp_Formula_t)) {
01244       Ctlsp_FormulaFree(formula);
01245       return NIL(Ctlsp_Formula_t);
01246     }
01247     formula = Ctlsp_FormulaCreate(Ctlsp_OR_c,formula,tempFormula);
01248   }
01249   return formula;
01250 }
01251 
01252 
01268 Ctlsp_Formula_t *
01269 Ctlsp_FormulaCreateVectorAnd(
01270   char *nameVector,
01271   char *value)
01272 {
01273   Ctlsp_Formula_t *formula, *tempFormula;
01274   int startValue, endValue, inc, i,j, interval,startInd;
01275   char *binValueStr, *varName, *name;
01276   char *bitValue;
01277 
01278   varName = CtlspGetVectorInfoFromStr(nameVector,&startValue,&endValue,&interval,&inc);
01279   binValueStr = ALLOC(char,interval+1);
01280   if (!CtlspStringChangeValueStrToBinString(value,binValueStr,interval) ){
01281      FREE(varName);
01282      FREE(binValueStr);
01283      return NIL(Ctlsp_Formula_t);
01284   }
01285 
01286   name = ALLOC(char,MAX_LENGTH_OF_VAR_NAME);
01287   (void) sprintf(name,"%s[%d]",varName,startValue);
01288   (void) CtlspChangeBracket(name);
01289 
01290   bitValue = ALLOC(char,2);
01291   bitValue[0] = binValueStr[0];
01292   bitValue[1] = '\0';
01293 
01294   formula = Ctlsp_FormulaCreate(Ctlsp_ID_c, util_strsav(name),
01295                                util_strsav(bitValue));
01296   j = 0;
01297   startInd = startValue;
01298   for(i=startValue;i!=endValue;i=i+inc){
01299      startInd += inc;
01300      j++;
01301      (void) sprintf(name,"%s[%d]",varName,startInd);
01302      (void) CtlspChangeBracket(name);
01303      bitValue[0] = binValueStr[j];
01304      tempFormula = Ctlsp_FormulaCreate(Ctlsp_ID_c, util_strsav(name),
01305                                       util_strsav(bitValue));
01306      formula = Ctlsp_FormulaCreate(Ctlsp_AND_c,formula,tempFormula);
01307   }
01308   FREE(varName);
01309   FREE(name);
01310   FREE(binValueStr);
01311   FREE(bitValue);
01312   return formula;
01313 }
01314 
01315 
01331 Ctlsp_Formula_t *
01332 Ctlsp_FormulaCreateVectorOr(
01333   char *nameVector,
01334   char *valueStr)
01335 {
01336   Ctlsp_Formula_t *formula,*tempFormula;
01337   char *preStr;
01338 
01339   preStr = strtok(valueStr,",");
01340   formula = Ctlsp_FormulaCreateVectorAnd(nameVector,preStr);
01341   if ( formula == NIL(Ctlsp_Formula_t)){
01342      Ctlsp_FormulaFree(formula);
01343      return NIL(Ctlsp_Formula_t);
01344   }
01345   while( (preStr = strtok(NIL(char),",")) != NIL(char) ){
01346      tempFormula = Ctlsp_FormulaCreateVectorAnd(nameVector,preStr);
01347      if ( tempFormula == NIL(Ctlsp_Formula_t)){
01348         Ctlsp_FormulaFree(formula);
01349         return NIL(Ctlsp_Formula_t);
01350      }
01351      formula = Ctlsp_FormulaCreate(Ctlsp_OR_c,formula,tempFormula);
01352   }
01353   return formula;
01354 }
01355 
01356 
01369 Ctlsp_Formula_t *
01370 Ctlsp_FormulaCreateEquiv(
01371   char *left,
01372   char *right)
01373 {
01374   Ctlsp_Formula_t *formula,*formula1,*formula2;
01375 
01376   char *one;
01377   char *zero;
01378 
01379   one = "1";
01380   zero = "0";
01381 
01382   formula1 = Ctlsp_FormulaCreate(Ctlsp_ID_c, util_strsav(left),
01383                                  util_strsav(one));
01384   formula2 = Ctlsp_FormulaCreate(Ctlsp_ID_c, util_strsav(right),
01385                                  util_strsav(zero));
01386   formula = Ctlsp_FormulaCreate(Ctlsp_XOR_c,formula1,formula2);
01387   return formula;
01388 }
01389 
01402 Ctlsp_Formula_t *
01403 Ctlsp_FormulaCreateVectorEquiv(
01404   char *left,
01405   char *right)
01406 {
01407   Ctlsp_Formula_t *formula,*tempFormula;
01408   char *leftName,*rightName;
01409   char *leftVar, *rightVar;
01410   int  leftStart,leftEnd,rightStart,rightEnd,leftInterval,rightInterval;
01411   int  leftInc,rightInc,leftInd,rightInd,i;
01412 
01413   leftName  = CtlspGetVectorInfoFromStr(left,&leftStart,&leftEnd,&leftInterval,&leftInc);
01414   rightName = CtlspGetVectorInfoFromStr(right,&rightStart,&rightEnd,&rightInterval,&rightInc);
01415   if (leftInterval != rightInterval){
01416      return NIL(Ctlsp_Formula_t);
01417   }
01418   leftVar = ALLOC(char,MAX_LENGTH_OF_VAR_NAME);
01419   (void) sprintf(leftVar,"%s[%d]",leftName,leftStart);
01420   (void) CtlspChangeBracket(leftVar);
01421   rightVar = ALLOC(char,MAX_LENGTH_OF_VAR_NAME);
01422   (void) sprintf(rightVar,"%s[%d]",rightName,rightStart);
01423   (void) CtlspChangeBracket(rightVar);
01424 
01425   formula = Ctlsp_FormulaCreateEquiv(leftVar,rightVar);
01426   leftInd  = leftStart;
01427   rightInd = rightStart;
01428   for(i=leftStart;i!=leftEnd;i+=leftInc){
01429      leftInd  += leftInc;
01430      rightInd += rightInc;
01431      (void) sprintf(leftVar,"%s[%d]",leftName,leftInd);
01432      (void) CtlspChangeBracket(leftVar);
01433      (void) sprintf(rightVar,"%s[%d]",rightName,rightInd);
01434      (void) CtlspChangeBracket(rightVar);
01435      tempFormula = Ctlsp_FormulaCreateEquiv(leftVar,rightVar);
01436      formula = Ctlsp_FormulaCreate(Ctlsp_AND_c,formula,tempFormula);
01437   }
01438   FREE(leftName);
01439   FREE(rightName);
01440   FREE(leftVar);
01441   FREE(rightVar);
01442   return formula;
01443 }
01444 
01445 
01458 Ctlsp_Formula_t *
01459 Ctlsp_FormulaCreateXMult(
01460   char *string,
01461   Ctlsp_Formula_t *formula)
01462 {
01463   int i,num;
01464   char *str, *ptr;
01465   Ctlsp_Formula_t *result = NIL(Ctlsp_Formula_t);
01466   str = strchr(string,':');
01467   if ( str == NULL) return(NIL(Ctlsp_Formula_t));
01468   str++;
01469 
01470   num = strtol(str,&ptr,0);
01471 
01472   for(i=0;i<num;i++){
01473     result = Ctlsp_FormulaCreate(Ctlsp_X_c, formula, NIL(Ctlsp_Formula_t));
01474     Ctlsp_FormulaSetClass(result, table2(Ctlsp_FormulaReadClass(formula)));
01475     if (Ctlsp_FormulaReadClassOfCTL(formula) ==  Ctlsp_CTL_c){
01476       Ctlsp_FormulaSetClassOfCTL(result, Ctlsp_PathCTL_c);
01477      }
01478     else{
01479       Ctlsp_FormulaSetClassOfCTL(result, Ctlsp_NotCTL_c);
01480      }
01481     formula = result;
01482     }
01483   return result;
01484 }
01485 
01498 Ctlsp_Formula_t *
01499 Ctlsp_FormulaCreateEXMult(
01500   char *string,
01501   Ctlsp_Formula_t *formula)
01502 {
01503   int i,num;
01504   char *str, *ptr;
01505   Ctlsp_Formula_t *result = NIL(Ctlsp_Formula_t);
01506 
01507   str = strchr(string,':');
01508   if ( str == NULL) return(NIL(Ctlsp_Formula_t));
01509   str++;
01510 
01511   num = strtol(str,&ptr,0);
01512 
01513   for(i=0;i<num;i++){
01514     result = Ctlsp_FormulaCreate(Ctlsp_X_c, formula, NIL(Ctlsp_Formula_t));
01515     Ctlsp_FormulaSetClass(result, table2(Ctlsp_FormulaReadClass(formula)));
01516     result = Ctlsp_FormulaCreate(Ctlsp_E_c, result, NIL(Ctlsp_Formula_t));
01517     Ctlsp_FormulaSetClass(result, Ctlsp_stateformula_c);
01518     if (Ctlsp_FormulaReadClassOfCTL(formula) ==  Ctlsp_CTL_c)
01519     {
01520       Ctlsp_FormulaSetClassOfCTL(result, Ctlsp_CTL_c);
01521     }
01522     else
01523     {
01524       Ctlsp_FormulaSetClassOfCTL(result, Ctlsp_NotCTL_c);
01525     }
01526     formula = result;
01527   }
01528 
01529   return result;
01530 }
01531 
01544 Ctlsp_Formula_t *
01545 Ctlsp_FormulaCreateAXMult(
01546   char *string,
01547   Ctlsp_Formula_t *formula)
01548 {
01549   int i,num;
01550   char *str, *ptr;
01551   Ctlsp_Formula_t *result = NIL(Ctlsp_Formula_t);
01552 
01553   str = strchr(string,':');
01554   if ( str == NULL) return(NIL(Ctlsp_Formula_t));
01555   str++;
01556 
01557   num = strtol(str,&ptr,0);
01558 
01559   for(i=0;i<num;i++){
01560     result = Ctlsp_FormulaCreate(Ctlsp_X_c, formula, NIL(Ctlsp_Formula_t));
01561     Ctlsp_FormulaSetClass(result, table2(Ctlsp_FormulaReadClass(formula)));
01562     result = Ctlsp_FormulaCreate(Ctlsp_A_c, result, NIL(Ctlsp_Formula_t));
01563     Ctlsp_FormulaSetClass(result, Ctlsp_stateformula_c);
01564     if (Ctlsp_FormulaReadClassOfCTL(formula) ==  Ctlsp_CTL_c)
01565     {
01566       Ctlsp_FormulaSetClassOfCTL(result, Ctlsp_CTL_c);
01567     }
01568     else
01569     {
01570       Ctlsp_FormulaSetClassOfCTL(result, Ctlsp_NotCTL_c);
01571     }
01572     formula = result;
01573   }
01574 
01575   return result;
01576 }
01577 
01578 
01590 char *
01591 Ctlsp_FormulaGetTypeString(Ctlsp_Formula_t *formula)
01592 {
01593   char *result;
01594 
01595   switch(formula->type) {
01596     /*
01597      * The cases are listed in rough order of their expected frequency.
01598      */
01599     case Ctlsp_ID_c:
01600       result = util_strsav("ID");
01601       break;
01602     case Ctlsp_OR_c:
01603       result = util_strsav("OR");
01604       break;
01605     case Ctlsp_AND_c:
01606       result = util_strsav("AND");
01607       break;
01608     case Ctlsp_THEN_c:
01609       result = util_strsav("THEN");
01610       break;
01611     case Ctlsp_XOR_c:
01612       result = util_strsav("XOR");
01613       break;
01614     case Ctlsp_EQ_c:
01615       result = util_strsav("EQ");
01616       break;
01617     case Ctlsp_NOT_c:
01618       result = util_strsav("NOT");
01619       break;
01620     case Ctlsp_E_c:
01621       result = util_strsav("E");
01622       break;
01623     case Ctlsp_G_c:
01624       result = util_strsav("G");
01625       break;
01626     case Ctlsp_F_c:
01627       result = util_strsav("F");
01628       break;
01629     case Ctlsp_U_c:
01630       result = util_strsav("U");
01631       break;
01632     case Ctlsp_R_c:
01633       result = util_strsav("R");
01634       break;
01635     case Ctlsp_W_c:
01636       result = util_strsav("W");
01637       break;
01638     case Ctlsp_X_c:
01639       result = util_strsav("X");
01640       break;
01641     case Ctlsp_A_c:
01642       result = util_strsav("A");
01643       break;
01644     case Ctlsp_TRUE_c:
01645       result = util_strsav("TRUE");
01646       break;
01647     case Ctlsp_FALSE_c:
01648       result = util_strsav("FALSE");
01649       break;
01650     case Ctlsp_Init_c:
01651       result = util_strsav("Init");
01652       break;
01653     case Ctlsp_Cmp_c:
01654       result = util_strsav("Cmp");
01655       break;
01656     case Ctlsp_Fwd_c:
01657       result = util_strsav("Fwd");
01658       break;
01659       /*    case Ctlsp_EY_c:
01660       result = util_strsav("EY");
01661       break;*/
01662       /*  case Ctlsp_EH_c:
01663       result = util_strsav("EH");
01664       break;
01665       break;*/
01666     default:
01667       fail("Unexpected type");
01668   }
01669   return(result);
01670 }
01671 
01672 
01686 Ctlsp_FormulaClass
01687 Ctlsp_CheckClassOfExistentialFormula(
01688   Ctlsp_Formula_t *formula)
01689 {
01690   Ctlsp_FormulaClass result;
01691 
01692   result = CtlspCheckClassOfExistentialFormulaRecur(formula, FALSE);
01693 
01694   return result;
01695 } /* End of Ctlsp_CheckTypeOfExistentialFormula */
01696 
01712 Ctlsp_FormulaClass
01713 Ctlsp_CheckClassOfExistentialFormulaArray(
01714   array_t *formulaArray)
01715 {
01716   Ctlsp_FormulaClass result;
01717   Ctlsp_Formula_t *formula;
01718   int formulanr;
01719 
01720   result = Ctlsp_QuantifierFree_c;
01721   arrayForEachItem(Ctlsp_Formula_t *, formulaArray, formulanr, formula){
01722     Ctlsp_FormulaClass  formulaType;
01723     formulaType = Ctlsp_CheckClassOfExistentialFormula(formula);
01724     result = CtlspResolveClass(result, formulaType);
01725     if(result == Ctlsp_Mixed_c)
01726       return result;
01727   }
01728   return result;
01729 } /* End of Ctlsp_CheckTypeOfExistentialFormulaArray */
01730 
01742 Ctlsp_ClassOfFormula
01743 Ctlsp_FormulaReadClass(Ctlsp_Formula_t *formula)
01744 {
01745   return formula->class_;
01746 }
01747 
01759 void
01760 Ctlsp_FormulaSetClass(Ctlsp_Formula_t *formula, Ctlsp_ClassOfFormula newClass)
01761 {
01762   if (formula == NIL(Ctlsp_Formula_t)){
01763     return;
01764   }
01765   formula->class_ = newClass;
01766 }
01767 
01768 
01781 Ctlsp_ClassOfCTLFormula
01782 Ctlsp_FormulaReadClassOfCTL(Ctlsp_Formula_t *formula)
01783 {
01784   return formula->CTLclass;
01785 }
01786 
01798 void
01799 Ctlsp_FormulaSetClassOfCTL(
01800   Ctlsp_Formula_t *formula,
01801   Ctlsp_ClassOfCTLFormula newCTLclass)
01802 {
01803   if (formula == NIL(Ctlsp_Formula_t)){
01804     return;
01805   }
01806   formula->CTLclass = newCTLclass;
01807 }
01808 
01824 array_t *
01825 Ctlsp_FormulaArrayConvertToLTL(
01826    array_t *formulaArray)
01827 {
01828   array_t *ltlFormulaArray;
01829   int i;
01830 
01831   ltlFormulaArray = array_alloc(Ctlsp_Formula_t *, 0);
01832 
01833   /* Check if all CTL* formulas are LTL formulas */
01834   for (i = 0; i < array_n(formulaArray); i++) {
01835     Ctlsp_Formula_t *formula, *ltlFormula;
01836 
01837     formula = array_fetch(Ctlsp_Formula_t *, formulaArray, i);
01838 
01839     if (!Ctlsp_isLtlFormula(formula)){
01840      Ctlsp_FormulaArrayFree(ltlFormulaArray);
01841      return NIL(array_t);
01842     }
01843     ltlFormula = Ctlsp_FormulaDup(formula);
01844     array_insert_last(Ctlsp_Formula_t *, ltlFormulaArray, ltlFormula);
01845 
01846    } /* For Loop */
01847   return ltlFormulaArray;
01848 } /*  Ctlsp_FormulaArrayConvertToLTL() */
01849 
01867 array_t *
01868 Ctlsp_FormulaArrayConvertToCTL(
01869   array_t *formulaArray)
01870 {
01871   array_t *CtlFormulaArray;
01872   int i;
01873 
01874   CtlFormulaArray = array_alloc(Ctlp_Formula_t *, 0);
01875 
01876   /* Convert each formula in the array to CTL */
01877   for (i = 0; i < array_n(formulaArray); i++) {
01878     Ctlsp_Formula_t *formula;
01879     Ctlp_Formula_t *newFormula;
01880 
01881     formula = array_fetch(Ctlsp_Formula_t *, formulaArray, i);
01882     newFormula = Ctlsp_FormulaConvertToCTL(formula);
01883 
01884     if (newFormula !=  NIL(Ctlp_Formula_t)){
01885        array_insert_last(Ctlp_Formula_t *, CtlFormulaArray, newFormula);
01886     }
01887     else{
01888        (void) fprintf(vis_stderr, "** ctl* error : Can't Convert CTL* No. %d to CTL formula\n\n", i);
01889        Ctlp_FormulaArrayFree(CtlFormulaArray);
01890        return NIL(array_t);
01891     }
01892    } /* For Loop */
01893   return CtlFormulaArray;
01894 } /*  Ctlsp_FormulaArrayConvertToCTL() */
01895 
01911 Ctlp_Formula_t *
01912 Ctlsp_FormulaConvertToCTL(
01913   Ctlsp_Formula_t *formula)
01914 {
01915   if (Ctlsp_FormulaReadClassOfCTL(formula) ==  Ctlsp_CTL_c) {/* CTL* can be converted to CTL */
01916     return CtlspFormulaConvertToCTL(formula);
01917   }
01918   else{
01919     return NIL(Ctlp_Formula_t);
01920   }
01921 } /*  Ctlsp_FormulaConvertToCTL() */
01922 
01933 Ctlp_Formula_t *
01934 Ctlsp_PropositionalFormulaToCTL(
01935   Ctlsp_Formula_t *formula)
01936 {
01937     return CtlspFormulaConvertToCTL(formula);
01938 }
01939 
01940 
01952 int
01953 Ctlsp_isPropositionalFormula(
01954   Ctlsp_Formula_t *formula)
01955 {
01956   return (Ctlsp_FormulaReadClass(formula) == Ctlsp_propformula_c);
01957 } /* Ctlsp_isPropositionalFormula() */
01958 
01970 int
01971 Ctlsp_isCtlFormula(
01972   Ctlsp_Formula_t *formula)
01973 {
01974   return (Ctlsp_FormulaReadClassOfCTL(formula) ==  Ctlsp_CTL_c);
01975 } /* Ctlsp_isCtlFormula() */
01976 
01992 int
01993 Ctlsp_isLtlFormula(
01994   Ctlsp_Formula_t *formula)
01995 {
01996   if (Ctlsp_FormulaReadClass(formula) == Ctlsp_LTLformula_c){
01997     return 1;
01998   }
01999   if (Ctlsp_FormulaReadClass(formula) == Ctlsp_propformula_c){
02000     return 1;
02001   }
02002   if (formula->type ==  Ctlsp_A_c) {
02003     if ((Ctlsp_FormulaReadClass(formula->left) == Ctlsp_LTLformula_c) ||
02004         (Ctlsp_FormulaReadClass(formula->left) == Ctlsp_propformula_c)) {
02005       return 1;
02006       }
02007     else {
02008       return 0;
02009     }
02010   }
02011   return 0;
02012 } /* Ctlsp_isLtlFormula() */
02013 
02030 Ctlsp_Formula_t *
02031 Ctlsp_LtllFormulaNegate(
02032   Ctlsp_Formula_t *ltlFormula)
02033 {
02034   Ctlsp_Formula_t *negLtlFormula, *tmpLtlFormula;
02035 
02036   negLtlFormula = Ctlsp_FormulaCreate(Ctlsp_NOT_c, ltlFormula, NIL(Ctlsp_Formula_t));
02037   tmpLtlFormula = Ctlsp_LtlFormulaExpandAbbreviation(negLtlFormula);
02038   FREE(negLtlFormula);
02039   negLtlFormula = Ctlsp_LtlFormulaNegationNormalForm(tmpLtlFormula);
02040   if(negLtlFormula != tmpLtlFormula) {
02041     Ctlsp_FormulaFree(tmpLtlFormula);
02042   }
02043   tmpLtlFormula = Ctlsp_LtlFormulaSimpleRewriting(negLtlFormula);
02044   Ctlsp_FormulaFree(negLtlFormula);
02045   Ctlsp_LtlSetClass(tmpLtlFormula);
02046 
02047   return tmpLtlFormula;
02048 } /* Ctlsp_LtllFormulaNegate() */
02049 
02068 void
02069 Ctlsp_LtlSetClass(
02070   Ctlsp_Formula_t *formula)
02071 {
02072   Ctlsp_Formula_t *left, *right;
02073 
02074   if (formula == NIL(Ctlsp_Formula_t)){
02075     return;
02076   }
02077   if (formula->type == Ctlsp_ID_c){
02078     return;
02079   }
02080   if (formula->type == Ctlsp_TRUE_c){
02081     return;
02082   }
02083   if (formula->type == Ctlsp_FALSE_c){
02084     return;
02085   }
02086   left  = formula->left;
02087   right = formula->right;
02088 
02089   Ctlsp_LtlSetClass(left);
02090   Ctlsp_LtlSetClass(right);
02091 
02092   switch(formula->type) {
02093     case Ctlsp_OR_c:
02094     case Ctlsp_AND_c:
02095     case Ctlsp_THEN_c:
02096     case Ctlsp_XOR_c:
02097     case Ctlsp_EQ_c:
02098       Ctlsp_FormulaSetClass(formula, table1(Ctlsp_FormulaReadClass(left),Ctlsp_FormulaReadClass(right)));
02099       break;
02100     case Ctlsp_NOT_c:
02101       Ctlsp_FormulaSetClass(formula, Ctlsp_FormulaReadClass(left));
02102       break;
02103     case Ctlsp_E_c:
02104     case Ctlsp_A_c:
02105       Ctlsp_FormulaSetClass(formula, Ctlsp_stateformula_c);
02106       break;
02107     case Ctlsp_G_c:
02108     case Ctlsp_F_c:
02109       Ctlsp_FormulaSetClass(formula, table2(Ctlsp_FormulaReadClass(left)));
02110       break;
02111     case Ctlsp_U_c:
02112     case Ctlsp_R_c:
02113     case Ctlsp_W_c:
02114       Ctlsp_FormulaSetClass(formula, table3(Ctlsp_FormulaReadClass(left),Ctlsp_FormulaReadClass(right)));
02115       break;
02116     case Ctlsp_X_c:
02117       Ctlsp_FormulaSetClass(formula, table2(Ctlsp_FormulaReadClass(left)));
02118       break;
02119     default:
02120       break;
02121   }
02122   return;
02123 }
02124 
02136 int
02137 Ctlsp_LtlFormulaIsGFp(
02138   Ctlsp_Formula_t *formula)
02139 {
02140  Ctlsp_Formula_t *rightChild;
02141  Ctlsp_Formula_t *leftChild;
02142 
02143  assert(formula != NIL(Ctlsp_Formula_t));
02144 
02145  if (Ctlsp_FormulaReadType(formula) == Ctlsp_R_c) {
02146    rightChild = Ctlsp_FormulaReadRightChild(formula);
02147    leftChild  = Ctlsp_FormulaReadLeftChild(formula);
02148 
02149    if ((Ctlsp_FormulaReadType(leftChild) == Ctlsp_FALSE_c) &&
02150        (Ctlsp_FormulaReadType(rightChild) == Ctlsp_U_c)){
02151      if ((Ctlsp_FormulaReadType(Ctlsp_FormulaReadLeftChild(rightChild)) == Ctlsp_TRUE_c) &&
02152          (Ctlsp_isPropositionalFormula(Ctlsp_FormulaReadRightChild(rightChild)))) {
02153        return TRUE;
02154      }
02155    }
02156  }
02157 
02158  return FALSE;
02159 }/* Ctlsp_LtlFormulaIsGFp() */
02160 
02161 
02173 boolean
02174 Ctlsp_LtlFormulaIsGp(
02175   Ctlsp_Formula_t *formula)
02176 {
02177   assert(formula != NIL(Ctlsp_Formula_t));
02178 
02179   if ((Ctlsp_FormulaReadType(formula)== Ctlsp_G_c) &&
02180        Ctlsp_isPropositionalFormula(Ctlsp_FormulaReadLeftChild(formula))){
02181     return TRUE;
02182   }
02183   if (Ctlsp_FormulaReadType(formula) == Ctlsp_R_c) {
02184     if ((Ctlsp_FormulaReadType(Ctlsp_FormulaReadLeftChild(formula)) == Ctlsp_FALSE_c) &&
02185         (Ctlsp_isPropositionalFormula(Ctlsp_FormulaReadRightChild(formula)))) {
02186       return TRUE;
02187     }
02188   }
02189   return FALSE;
02190 } /* Ctlsp_LtlFormulaIsGp */
02191 
02203 boolean
02204 Ctlsp_LtlFormulaIsFp(
02205   Ctlsp_Formula_t *formula)
02206 {
02207   assert(formula != NIL(Ctlsp_Formula_t));
02208 
02209   if ((Ctlsp_FormulaReadType(formula)== Ctlsp_F_c) &&
02210       Ctlsp_isPropositionalFormula(Ctlsp_FormulaReadLeftChild(formula))){
02211     return TRUE;
02212   }
02213   if (Ctlsp_FormulaReadType(formula) == Ctlsp_U_c) {
02214     if ((Ctlsp_FormulaReadType(Ctlsp_FormulaReadLeftChild(formula)) == Ctlsp_TRUE_c) &&
02215         Ctlsp_isPropositionalFormula(Ctlsp_FormulaReadRightChild(formula))) {
02216       return TRUE;
02217     }
02218   }
02219   return FALSE;
02220 } /* Ctlsp_LtlFormulaIsFp */
02221 
02222 #if 0
02223 
02247 boolean
02248 Ctlsp_LtlFormulaIsSafety(
02249   Ctlsp_Formula_t *formula)
02250 {
02251   assert(formula != NIL(Ctlsp_Formula_t));
02252 
02253   if (Ctlsp_isPropositionalFormula(formula)){
02254     return TRUE;
02255   }
02256   if (Ctlsp_LtlFormulaIsW(formula)){
02257     return Ctlsp_LtlFormulaIsSafety(Ctlsp_FormulaReadLeftChild(formula)) &&
02258       Ctlsp_LtlFormulaIsSafety(Ctlsp_FormulaReadRightChild(formula));
02259   }
02260   swtich (Ctlsp_FormulaReadType(formula)){
02261   case Ctlsp_AND_c:
02262   case Ctlsp_OR_c:
02263     return Ctlsp_LtlFormulaIsSafety(Ctlsp_FormulaReadLeftChild(formula)) &&
02264            Ctlsp_LtlFormulaIsSafety(Ctlsp_FormulaReadRightChild(formula));
02265   case Ctlsp_X_c:
02266     return Ctlsp_LtlFormulaIsSafety(Ctlsp_FormulaReadLeftChild(formula));
02267   case Ctlsp_NOT_c:
02268   case Ctlsp_U_c:
02269   case Ctlsp_R_c:
02270     return FALSE;
02271   default:
02272     fail("unexpected node type in abbreviation-free formula\n");
02273     return FALSE; /* not reached */
02274   }
02275 
02276   /*    == Ctlsp_F_c) &&
02277       Ctlsp_isPropositionalFormula(Ctlsp_FormulaReadLeftChild(formula))){
02278     return TRUE;
02279     } */
02280   if (Ctlsp_FormulaReadType(formula) == Ctlsp_U_c) {
02281     if (Ctlsp_FormulaReadType(Ctlsp_FormulaReadLeftChild(formula) == Ctlsp_TRUE_c) &&
02282         Ctlsp_isPropositionalFormula(Ctlsp_FormulaReadRightChild(formula))) {
02283       return TRUE;
02284     }
02285   }
02286   return FALSE;
02287 } /* Ctlsp_LtlFormulaIsSafety */
02288 #endif
02289 
02290 
02308 void
02309 Ctlsp_FormulaArrayAddLtlFairnessConstraints(
02310   array_t *formulaArray     /* array of LTL formulae */,
02311   array_t *constraintArray /* array of fairness constraints */)
02312 {
02313   Ctlsp_Formula_t *formula;     /* a generic LTL formula */
02314   Ctlsp_Formula_t *fairness;    /* a generic fairness constraint */
02315   int i;                        /* iteration variable */
02316 
02317   assert(formulaArray != NIL(array_t));
02318   assert(constraintArray != NIL(array_t));
02319   /*
02320    * Create the overall fairness constraints.  If the given constraints
02321    * are C_1, C_2, ..., C_k, build the formula /\_i GF C_i.
02322    */
02323   fairness = NIL(Ctlsp_Formula_t);
02324   arrayForEachItem(Ctlsp_Formula_t *, constraintArray, i, formula) {
02325     Ctlsp_Formula_t *finally;
02326     Ctlsp_Formula_t *globally;
02327     finally =  Ctlsp_FormulaCreate(Ctlsp_F_c, formula, NIL(Ctlsp_Formula_t));
02328     globally = Ctlsp_FormulaCreate(Ctlsp_G_c, finally, NIL(Ctlsp_Formula_t));
02329     if (i == 0) {
02330       fairness = globally;
02331     } else {
02332       fairness = Ctlsp_FormulaCreate(Ctlsp_AND_c, fairness, globally);
02333     }
02334   }
02335   /* Empty fairness constraint files are forbidden. */
02336   assert(fairness != NIL(Ctlsp_Formula_t));
02337 
02338   /*
02339    * Add fairness to each given formula: Replace f_i by (fairness -> f_i).
02340    */
02341   arrayForEachItem(Ctlsp_Formula_t *, formulaArray, i, formula) {
02342     Ctlsp_Formula_t *modified;
02343     modified = Ctlsp_FormulaCreate(Ctlsp_THEN_c,
02344                                    Ctlsp_FormulaDup(fairness), formula);
02345     array_insert(Ctlsp_Formula_t *, formulaArray, i, modified);
02346   }
02347   Ctlsp_FormulaFree(fairness);
02348 
02349 } /* Ctlsp_FormulaArrayAddLtlFairnessConstraints */
02350 
02351 
02363 Ctlsp_Formula_t *
02364 Ctlsp_CtlFormulaToCtlsp(Ctlp_Formula_t *F)
02365 {
02366     Ctlsp_Formula_t *Fsp;
02367     Ctlp_FormulaType Ftype;
02368     Ctlsp_FormulaType Fsptype;
02369 
02370     if (F == NIL(Ctlp_Formula_t))
02371         return NIL(Ctlsp_Formula_t);
02372 
02373     Ftype = Ctlp_FormulaReadType(F);
02374     Fsptype = (Ctlsp_FormulaType) Ftype;
02375 
02376     if (Ftype == Ctlp_TRUE_c) {
02377         Fsp = Ctlsp_FormulaCreate(Ctlsp_TRUE_c, NIL(Ctlsp_Formula_t),
02378                                   NIL(Ctlsp_Formula_t));
02379     }else if (Ftype == Ctlp_FALSE_c) {
02380         Fsp = Ctlsp_FormulaCreate(Ctlsp_FALSE_c, NIL(Ctlsp_Formula_t),
02381                                   NIL(Ctlsp_Formula_t));
02382     }else if (Ftype == Ctlp_ID_c) {
02383         char *nameString = Ctlp_FormulaReadVariableName(F);
02384         char *valueString = Ctlp_FormulaReadValueName(F);
02385         Fsp = Ctlsp_FormulaCreate(Ctlsp_ID_c,
02386                                   util_strsav(nameString),
02387                                   util_strsav(valueString));
02388     }else {
02389         Ctlp_Formula_t *Fleft = Ctlp_FormulaReadLeftChild(F);
02390         Ctlp_Formula_t *Fright = Ctlp_FormulaReadRightChild(F);
02391         Ctlsp_Formula_t *Fspleft, *Fspright;
02392         Fspleft = Ctlsp_CtlFormulaToCtlsp(Fleft);
02393         Fspright = Ctlsp_CtlFormulaToCtlsp(Fright);
02394         switch(Ftype) {
02395         case Ctlp_NOT_c:
02396             Fsptype = Ctlsp_NOT_c;
02397             break;
02398         case Ctlp_AND_c:
02399             Fsptype = Ctlsp_AND_c;
02400             break;
02401         case Ctlp_OR_c:
02402             Fsptype = Ctlsp_OR_c;
02403             break;
02404         case Ctlp_THEN_c:
02405             Fsptype = Ctlsp_THEN_c;
02406             break;
02407         case Ctlp_EQ_c:
02408             Fsptype = Ctlsp_EQ_c;
02409             break;
02410         case Ctlp_XOR_c:
02411             Fsptype = Ctlsp_XOR_c;
02412             break;
02413         default:
02414             assert(0);
02415         }
02416         if (Fspleft)
02417             CtlspFormulaIncrementRefCount(Fspleft);
02418         if (Fspright)
02419             CtlspFormulaIncrementRefCount(Fspright);
02420         Fsp = Ctlsp_FormulaCreate(Fsptype, Fspleft, Fspright);
02421     }
02422 
02423     return Fsp;
02424 }
02425 
02426 
02447 Ctlsp_Formula_t *
02448 Ctlsp_LtlFormulaExpandAbbreviation(
02449   Ctlsp_Formula_t *formula)
02450 {
02451   Ctlsp_Formula_t *new_;
02452 
02453   if (formula == NIL(Ctlsp_Formula_t))
02454     return formula;
02455 
02456   switch (formula->type) {
02457   case Ctlsp_THEN_c:
02458     /* a -> b  :: !a + b */
02459     new_ = FormulaCreateWithType(Ctlsp_OR_c);
02460     new_->left = FormulaCreateWithType(Ctlsp_NOT_c);
02461     new_->left->left = Ctlsp_LtlFormulaExpandAbbreviation(formula->left);
02462     new_->right = Ctlsp_LtlFormulaExpandAbbreviation(formula->right);
02463     break;
02464   case Ctlsp_EQ_c:
02465     /* a <-> b  :: a*b + !a*!b */
02466     new_ = FormulaCreateWithType(Ctlsp_OR_c);
02467     new_->left = FormulaCreateWithType(Ctlsp_AND_c);
02468     new_->right= FormulaCreateWithType(Ctlsp_AND_c);
02469     new_->left->left = Ctlsp_LtlFormulaExpandAbbreviation(formula->left);
02470     new_->left->right= Ctlsp_LtlFormulaExpandAbbreviation(formula->right);
02471     new_->right->left = FormulaCreateWithType(Ctlsp_NOT_c);
02472     new_->right->left->left = Ctlsp_LtlFormulaExpandAbbreviation(formula->left);
02473     new_->right->right= FormulaCreateWithType(Ctlsp_NOT_c);
02474     new_->right->right->left = Ctlsp_LtlFormulaExpandAbbreviation(formula->right);
02475     break;
02476   case Ctlsp_XOR_c:
02477     /* a ^ b  :: a*!b + !a*b */
02478     new_ = FormulaCreateWithType(Ctlsp_OR_c);
02479     new_->left = FormulaCreateWithType(Ctlsp_AND_c);
02480     new_->left->left = Ctlsp_LtlFormulaExpandAbbreviation(formula->left);
02481     new_->left->right= FormulaCreateWithType(Ctlsp_NOT_c);
02482     new_->left->right->left = Ctlsp_LtlFormulaExpandAbbreviation(formula->right);
02483     new_->right = FormulaCreateWithType(Ctlsp_AND_c);
02484     new_->right->left= FormulaCreateWithType(Ctlsp_NOT_c);
02485     new_->right->left->left = Ctlsp_LtlFormulaExpandAbbreviation(formula->left);
02486     new_->right->right = Ctlsp_LtlFormulaExpandAbbreviation(formula->right);
02487     break;
02488   case Ctlsp_F_c:
02489     /* F a  :: true U a */
02490     new_ = FormulaCreateWithType(Ctlsp_U_c);
02491     new_->left = FormulaCreateWithType(Ctlsp_TRUE_c);
02492     new_->right= Ctlsp_LtlFormulaExpandAbbreviation(formula->left);
02493     break;
02494   case Ctlsp_G_c:
02495     /* G a  :: false R a */
02496     new_ = FormulaCreateWithType(Ctlsp_R_c);
02497     new_->left = FormulaCreateWithType(Ctlsp_FALSE_c);
02498     new_->right= Ctlsp_LtlFormulaExpandAbbreviation(formula->left);
02499     break;
02500   case Ctlsp_W_c:
02501     /* a W b :: b R (a+b) */
02502     new_ = FormulaCreateWithType(Ctlsp_R_c);
02503     new_->left = Ctlsp_LtlFormulaExpandAbbreviation(formula->right);
02504     new_->right = FormulaCreateWithType(Ctlsp_OR_c);
02505     new_->right->left = Ctlsp_LtlFormulaExpandAbbreviation(formula->right);
02506     new_->right->right = Ctlsp_LtlFormulaExpandAbbreviation(formula->left);
02507     break;
02508   case Ctlsp_ID_c:
02509     /* Make a copy of the name, and create a new formula. */
02510     new_ = FormulaCreateWithType(Ctlsp_ID_c);
02511     new_->left = (Ctlsp_Formula_t *) util_strsav((char *)(formula->left));
02512     new_->right= (Ctlsp_Formula_t *) util_strsav((char *)(formula->right));
02513     break;
02514   case Ctlsp_A_c:
02515     /* Ignore A */
02516     new_ = Ctlsp_LtlFormulaExpandAbbreviation(formula->left);
02517     break;
02518   default:
02519     /* These are already in the correct form.  Just convert subformulas. */
02520     new_ = FormulaCreateWithType(formula->type);
02521     new_->left = Ctlsp_LtlFormulaExpandAbbreviation(formula->left);
02522     new_->right= Ctlsp_LtlFormulaExpandAbbreviation(formula->right);
02523   }
02524 
02525   return new_;
02526 }
02527 
02545 Ctlsp_Formula_t *
02546 Ctlsp_LtlFormulaNegationNormalForm(
02547   Ctlsp_Formula_t *formula)
02548 {
02549   Ctlsp_Formula_t *new_, *left, *right;
02550 #if 0
02551   Ctlsp_Formula_t  *negRight, *negLeft;
02552 #endif
02553   Ctlsp_FormulaType dual;
02554 
02555   if (formula == NIL(Ctlsp_Formula_t))
02556     return formula;
02557 
02558   if (formula->type == Ctlsp_TRUE_c || formula->type == Ctlsp_FALSE_c) {
02559     new_ = FormulaCreateWithType(formula->type);
02560     return new_;
02561   }
02562 
02563   if (formula->type == Ctlsp_ID_c) {
02564     new_ = FormulaCreateWithType(formula->type);
02565     new_->left =(Ctlsp_Formula_t *)util_strsav((char *)(formula->left));
02566     new_->right=(Ctlsp_Formula_t *)util_strsav((char *)(formula->right));
02567     return new_;
02568   }
02569 
02570   if (formula->type != Ctlsp_NOT_c) {
02571     new_ = FormulaCreateWithType(formula->type);
02572     new_->left = Ctlsp_LtlFormulaNegationNormalForm(formula->left);
02573     new_->right= Ctlsp_LtlFormulaNegationNormalForm(formula->right);
02574     return new_;
02575   }
02576 
02577   /* In the following, formula->type == Ctlsp_NOT_c */
02578   if (formula->left->type == Ctlsp_NOT_c)
02579     return Ctlsp_LtlFormulaNegationNormalForm(formula->left->left);
02580 
02581   if (formula->left->type == Ctlsp_ID_c) {
02582     new_ = FormulaCreateWithType(formula->type);
02583     new_->left = Ctlsp_LtlFormulaNegationNormalForm(formula->left);
02584     return new_;
02585   }
02586 #if 0
02587   if (formula->left->type == Ctlsp_THEN_c ) {
02588     left  = Ctlsp_LtlFormulaNegationNormalForm(formula->left->left);
02589     right = Ctlsp_FormulaCreate(Ctlsp_NOT_c, formula->left->right, NIL(Ctlsp_Formula_t));
02590     right = Ctlsp_LtlFormulaNegationNormalForm(right);
02591     new_   = Ctlsp_FormulaCreate(Ctlsp_AND_c, left, right);
02592     return new_;
02593   }
02594   if (formula->left->type == Ctlsp_EQ_c ) {
02595     left  = Ctlsp_LtlFormulaNegationNormalForm(formula->left->left);
02596     right = Ctlsp_LtlFormulaNegationNormalForm(formula->left->right);
02597     negRight = Ctlsp_FormulaCreate(Ctlsp_NOT_c, right, NIL(Ctlsp_Formula_t));
02598     negLeft  = Ctlsp_FormulaCreate(Ctlsp_NOT_c, left, NIL(Ctlsp_Formula_t));
02599     left     = right= Ctlsp_FormulaCreate(Ctlsp_AND_c, left, negRight);
02600     right    = right= Ctlsp_FormulaCreate(Ctlsp_AND_c, negLeft, right);
02601     new_      = Ctlsp_FormulaCreate(Ctlsp_OR_c, left, right);
02602     return Ctlsp_LtlFormulaNegationNormalForm(new_);
02603   }
02604 #endif
02605   /* for TRUE/ FALSE/ AND/ OR/ U/ R/ X/ F/ G */
02606   switch (formula->left->type) {
02607   case Ctlsp_TRUE_c:
02608     dual = Ctlsp_FALSE_c;
02609     break;
02610   case Ctlsp_FALSE_c:
02611     dual = Ctlsp_TRUE_c;
02612     break;
02613   case Ctlsp_AND_c:
02614     dual = Ctlsp_OR_c;
02615     break;
02616   case Ctlsp_OR_c:
02617     dual = Ctlsp_AND_c;
02618     break;
02619   case Ctlsp_U_c:
02620     dual = Ctlsp_R_c;
02621     break;
02622   case Ctlsp_R_c:
02623     dual = Ctlsp_U_c;
02624     break;
02625   case Ctlsp_X_c:
02626     dual = Ctlsp_X_c;
02627     break;
02628   case Ctlsp_F_c:
02629     dual = Ctlsp_G_c;
02630     break;
02631   case Ctlsp_G_c:
02632     dual = Ctlsp_F_c;
02633     break;
02634   default:
02635     fail("Unexpected type");
02636   }
02637 
02638   /* alloc temporary formulae (! left) and (! right) */
02639   left = Ctlsp_FormulaCreate(Ctlsp_NOT_c, formula->left->left, NIL(Ctlsp_Formula_t));
02640   right= Ctlsp_FormulaCreate(Ctlsp_NOT_c, formula->left->right, NIL(Ctlsp_Formula_t));
02641 
02642   /* create the new formula */
02643   new_ = FormulaCreateWithType(dual);
02644   if ((dual == Ctlsp_X_c) ||
02645       (dual == Ctlsp_F_c) ||
02646       (dual == Ctlsp_G_c) ){
02647     new_->left = Ctlsp_LtlFormulaNegationNormalForm(left);
02648   }else if (dual != Ctlsp_TRUE_c && dual != Ctlsp_FALSE_c) {
02649     new_->left = Ctlsp_LtlFormulaNegationNormalForm(left);
02650     new_->right= Ctlsp_LtlFormulaNegationNormalForm(right);
02651   }
02652   FREE(left);
02653   FREE(right);
02654 
02655   return new_;
02656 }
02657 
02671 Ctlsp_Formula_t *
02672 Ctlsp_LtlFormulaHashIntoUniqueTable(
02673   Ctlsp_Formula_t *F,
02674   st_table *uniqueTable)
02675 {
02676   Ctlsp_Formula_t *uniqueFormula;
02677 
02678   uniqueFormula = FormulaHashIntoUniqueTable(F, uniqueTable);
02679 
02680   /* If there is a copy 'uniqueFormula' in the uniqueTable, free F and
02681      increment the refCount of 'uniqueFormula' */
02682   if(uniqueFormula != F) {
02683     CtlspFormulaDecrementRefCount(F);
02684     CtlspFormulaIncrementRefCount(uniqueFormula);
02685   }
02686 
02687   return uniqueFormula;
02688 }
02689 
02701 void
02702 Ctlsp_LtlFormulaClearMarks(
02703   Ctlsp_Formula_t *F)
02704 {
02705   if(F) {
02706     F->marked = 0;
02707     if (F->type != Ctlsp_ID_c) {
02708       Ctlsp_LtlFormulaClearMarks(F->left);
02709       Ctlsp_LtlFormulaClearMarks(F->right);
02710     }
02711   }
02712 }
02713 
02725 int
02726 Ctlsp_LtlFormulaCountNumber(
02727   Ctlsp_Formula_t *F)
02728 {
02729   int result = 1;
02730 
02731   if (!F)
02732     return 0;
02733 
02734   if (F->marked)
02735     return 0;
02736 
02737   F->marked = 1;
02738   if (F->type == Ctlsp_TRUE_c ||
02739       F->type == Ctlsp_FALSE_c ||
02740       F->type == Ctlsp_ID_c)
02741     return 1;
02742 
02743   result += Ctlsp_LtlFormulaCountNumber(F->left);
02744   result += Ctlsp_LtlFormulaCountNumber(F->right);
02745 
02746   return result;
02747 }
02748 
02760 st_table *
02761 Ctlsp_LtlFormulaCreateUniqueTable( void )
02762 {
02763   return st_init_table(FormulaCompare, FormulaHash);
02764 }
02765 
02778 int
02779 Ctlsp_LtlFormulaIsElementary2(
02780   Ctlsp_Formula_t *F)
02781 {
02782   assert(F != 0);
02783 
02784   return (F->type == Ctlsp_X_c || Ctlsp_LtlFormulaIsAtomicPropositional(F) );
02785 }
02786 
02800 int
02801 Ctlsp_LtlFormulaIsElementary(
02802   Ctlsp_Formula_t *F)
02803 {
02804   assert(F != NIL(Ctlsp_Formula_t));
02805 
02806   return (F->type == Ctlsp_X_c || Ctlsp_LtlFormulaIsPropositional(F) );
02807 }
02808 
02826 boolean
02827 Ctlsp_LtlFormulaTestIsBounded(
02828   Ctlsp_Formula_t *formula,
02829   int *depth)
02830 {
02831   Ctlsp_Formula_t *leftChild;
02832   Ctlsp_Formula_t *rightChild;
02833   int leftDepth, rightDepth;
02834 
02835   assert(formula != NIL(Ctlsp_Formula_t));
02836 
02837   switch (Ctlsp_FormulaReadType(formula)) {
02838   case Ctlsp_TRUE_c:
02839   case Ctlsp_FALSE_c:
02840   case Ctlsp_ID_c:
02841     *depth = 0;
02842     return TRUE;
02843   case Ctlsp_AND_c:
02844   case Ctlsp_OR_c:
02845     leftChild = Ctlsp_FormulaReadLeftChild(formula);
02846     if (Ctlsp_LtlFormulaTestIsBounded(leftChild, &leftDepth)) {
02847       rightChild = Ctlsp_FormulaReadRightChild(formula);
02848       if (Ctlsp_LtlFormulaTestIsBounded(rightChild, &rightDepth)) {
02849         *depth = leftDepth > rightDepth ? leftDepth : rightDepth;
02850         return TRUE;
02851       } else {
02852         return FALSE;
02853       }
02854     } else {
02855       return FALSE;
02856     }
02857   case Ctlsp_NOT_c:
02858   case Ctlsp_X_c:
02859     leftChild = Ctlsp_FormulaReadLeftChild(formula);
02860     if (Ctlsp_LtlFormulaTestIsBounded(leftChild, &leftDepth)) {
02861       if (Ctlsp_FormulaReadType(formula) == Ctlsp_X_c) leftDepth++;
02862       *depth = leftDepth;
02863       return TRUE;
02864     } else {
02865       return FALSE;
02866     }
02867   case Ctlsp_U_c:
02868   case Ctlsp_R_c:
02869     return FALSE;
02870   default:
02871     fail("unexpected node type in abbreviation-free formula\n");
02872     return FALSE; /* not reached */
02873   }
02874 } /* Ctlsp_LtlFormulaTestIsBounded */
02875 
02889 int
02890 Ctlsp_LtlFormulaDepth(
02891   Ctlsp_Formula_t *formula)
02892 {
02893   int leftDepth, rightDepth;
02894 
02895   assert(formula != NIL(Ctlsp_Formula_t));
02896 
02897   switch (Ctlsp_FormulaReadType(formula)) {
02898   case Ctlsp_TRUE_c:
02899   case Ctlsp_FALSE_c:
02900   case Ctlsp_ID_c:
02901     return 0;
02902   case Ctlsp_AND_c:
02903   case Ctlsp_OR_c:
02904     leftDepth  = Ctlsp_LtlFormulaDepth(Ctlsp_FormulaReadLeftChild(formula));
02905     rightDepth = Ctlsp_LtlFormulaDepth(Ctlsp_FormulaReadRightChild(formula));
02906     return leftDepth > rightDepth ? leftDepth : rightDepth;
02907   case Ctlsp_NOT_c:
02908     return Ctlsp_LtlFormulaDepth(Ctlsp_FormulaReadLeftChild(formula));
02909   case Ctlsp_X_c:
02910     return 1+Ctlsp_LtlFormulaDepth(Ctlsp_FormulaReadLeftChild(formula));
02911   case Ctlsp_U_c:
02912   case Ctlsp_R_c:
02913     leftDepth  = Ctlsp_LtlFormulaDepth(Ctlsp_FormulaReadLeftChild(formula));
02914     rightDepth = Ctlsp_LtlFormulaDepth(Ctlsp_FormulaReadRightChild(formula));
02915     return 1+(leftDepth > rightDepth ? leftDepth : rightDepth);
02916   default:
02917     fail("unexpected node type in abbreviation-free formula\n");
02918     return 0; /* not reached */
02919   }
02920 } /* Ctlsp_LtlFormulaDepth */
02921 
02939 boolean
02940 Ctlsp_LtlFormulaTestIsSyntacticallyCoSafe(Ctlsp_Formula_t *formula)
02941 {
02942   Ctlsp_Formula_t *leftChild;
02943   Ctlsp_Formula_t *rightChild;
02944 
02945   assert(formula != NIL(Ctlsp_Formula_t));
02946 
02947   /*
02948     Check for unless temporal operator. a W b = (a U b) OR (FALSE R a)
02949                      its negation = (!a R !b) AND (TRUE U !a)
02950    */
02951   if(Ctlsp_FormulaReadType(formula) ==  Ctlsp_AND_c){
02952     leftChild  = Ctlsp_FormulaReadLeftChild(formula);
02953     rightChild = Ctlsp_FormulaReadRightChild(formula);
02954     if((Ctlsp_FormulaReadType(leftChild)  == Ctlsp_R_c) &&
02955        (Ctlsp_FormulaReadType(rightChild) == Ctlsp_U_c)){
02956       if(Ctlsp_FormulaReadLeftChild(leftChild) == Ctlsp_FormulaReadRightChild(rightChild)){
02957         if(Ctlsp_FormulaReadType(Ctlsp_FormulaReadLeftChild(rightChild)) == Ctlsp_TRUE_c){
02958           return Ctlsp_LtlFormulaTestIsSyntacticallyCoSafe(
02959                             Ctlsp_FormulaReadLeftChild(leftChild)) &&
02960                  Ctlsp_LtlFormulaTestIsSyntacticallyCoSafe(
02961                             Ctlsp_FormulaReadRightChild(leftChild));
02962         }
02963       }
02964     }
02965     /*
02966        a W b = (FALSE R a) OR (a U b)
02967        its negation = (TRUE U !a) AND (!a R !b)
02968    */
02969     if((Ctlsp_FormulaReadType(rightChild) == Ctlsp_R_c) &&
02970        (Ctlsp_FormulaReadType(leftChild) == Ctlsp_U_c)){
02971       if(Ctlsp_FormulaReadLeftChild(rightChild) == Ctlsp_FormulaReadRightChild(leftChild)){
02972         if(Ctlsp_FormulaReadType(Ctlsp_FormulaReadLeftChild(leftChild)) == Ctlsp_TRUE_c){
02973           return Ctlsp_LtlFormulaTestIsSyntacticallyCoSafe(
02974             Ctlsp_FormulaReadLeftChild(rightChild)) &&
02975             Ctlsp_LtlFormulaTestIsSyntacticallyCoSafe(
02976               Ctlsp_FormulaReadRightChild(rightChild));
02977         }
02978       }
02979     }
02980   }
02981   switch (Ctlsp_FormulaReadType(formula)) {
02982   case Ctlsp_TRUE_c:
02983   case Ctlsp_FALSE_c:
02984   case Ctlsp_ID_c:
02985     return TRUE;
02986   case Ctlsp_AND_c:
02987   case Ctlsp_OR_c:
02988   case Ctlsp_U_c:
02989     leftChild = Ctlsp_FormulaReadLeftChild(formula);
02990     if (Ctlsp_LtlFormulaTestIsSyntacticallyCoSafe(leftChild)) {
02991       rightChild = Ctlsp_FormulaReadRightChild(formula);
02992       return Ctlsp_LtlFormulaTestIsSyntacticallyCoSafe(rightChild);
02993     } else {
02994       return FALSE;
02995     }
02996   case Ctlsp_NOT_c:
02997     leftChild = Ctlsp_FormulaReadLeftChild(formula);
02998     /* The formula is in negation normal form. */
02999     assert(Ctlsp_FormulaReadType(leftChild) == Ctlsp_ID_c);
03000     return TRUE;
03001   case Ctlsp_X_c:
03002     leftChild = Ctlsp_FormulaReadLeftChild(formula);
03003     return Ctlsp_LtlFormulaTestIsSyntacticallyCoSafe(leftChild);
03004   case Ctlsp_R_c:
03005     return FALSE;
03006   default:
03007     fail("unexpected node type in abbreviation-free formula\n");
03008     return FALSE; /* not reached */
03009   }
03010 } /* Ctlsp_LtlFormulaTestIsSyntacticallyCoSafe */
03011 
03026 int
03027 Ctlsp_LtlFormulaArrayIsPropositional(
03028   array_t * formulaArray)
03029 {
03030   int             i;
03031   Ctlsp_Formula_t *formula;
03032 
03033   for (i = 0; i < array_n(formulaArray); i++) {
03034     formula = array_fetch(Ctlsp_Formula_t *, formulaArray, i);
03035     if(!Ctlsp_isPropositionalFormula(formula)){
03036       /*if(Ctlsp_LtlFormulaIsPropositional(formula) == 0){*/
03037       return 0;
03038     }
03039   }
03040   return 1;
03041 
03042 } /* Ctlsp_LtlFormulaArrayIsPropositional */
03043 
03044 
03060 int
03061 Ctlsp_LtlFormulaIsPropositional(
03062   Ctlsp_Formula_t *F)
03063 {
03064   int result;
03065 
03066   assert(F !=  NIL(Ctlsp_Formula_t));
03067 
03068   switch (F->type) {
03069   case Ctlsp_TRUE_c:
03070   case Ctlsp_FALSE_c:
03071   case Ctlsp_ID_c:
03072     result = 1;
03073     break;
03074   case Ctlsp_NOT_c: /* negation only appears ahead of AP */
03075     if (F->left->type == Ctlsp_ID_c)
03076       result = 1;
03077     else
03078       result = 0;
03079     break;
03080   case Ctlsp_AND_c:
03081   case Ctlsp_OR_c:
03082     result = (Ctlsp_LtlFormulaIsPropositional(F->left) &&
03083               Ctlsp_LtlFormulaIsPropositional(F->right));
03084     break;
03085   default:
03086     result = 0;
03087   }
03088 
03089   return result;
03090 } /* Ctlsp_LtlFormulaIsPropositional() */
03091 
03104 int
03105 Ctlsp_LtlFormulaIsAtomicPropositional(
03106   Ctlsp_Formula_t *F)
03107 {
03108   int result;
03109 
03110   assert(F != 0);
03111 
03112   switch (F->type) {
03113   case Ctlsp_TRUE_c:
03114   case Ctlsp_FALSE_c:
03115   case Ctlsp_ID_c:
03116     result = 1;
03117     break;
03118   case Ctlsp_NOT_c: /* negation only appears ahead of AP */
03119     if (F->left->type == Ctlsp_ID_c)
03120       result = 1;
03121     else
03122       result = 0;
03123     break;
03124   default:
03125     result = 0;
03126   }
03127 
03128   return result;
03129 }
03130 
03142 int
03143 Ctlsp_LtlFormulaIsFG(
03144   Ctlsp_Formula_t *F)
03145 {
03146   int result = 0;
03147 
03148   if (F->type == Ctlsp_U_c) {
03149     if (F->left->type == Ctlsp_TRUE_c && F->right->type == Ctlsp_R_c) {
03150       result = (F->right->left->type == Ctlsp_FALSE_c);
03151     }
03152   }
03153 
03154   return result;
03155 }
03156 
03157 
03169 int
03170 Ctlsp_LtlFormulaIsGF(
03171   Ctlsp_Formula_t *F)
03172 {
03173   int result = 0;
03174 
03175   if (F->type == Ctlsp_R_c) {
03176       if (F->left->type == Ctlsp_FALSE_c && F->right->type == Ctlsp_U_c) {
03177           result = (F->right->left->type == Ctlsp_TRUE_c);
03178       }
03179   }
03180 
03181   return result;
03182 }
03183 
03195 int
03196 Ctlsp_LtlFormulaIsFGorGF(
03197   Ctlsp_Formula_t *F)
03198 {
03199   return (Ctlsp_LtlFormulaIsFG(F) || Ctlsp_LtlFormulaIsGF(F));
03200 }
03201 
03202 
03218 int
03219 Ctlsp_LtlFormulaSimplyImply(
03220   Ctlsp_Formula_t *from,
03221   Ctlsp_Formula_t *to)
03222 {
03223 
03224 #if 0
03225   fprintf(vis_stdout, "\n------------------------\n");
03226   Ctlsp_FormulaPrint(vis_stdout, from);
03227   fprintf(vis_stdout, "\n   ==>\n");
03228   Ctlsp_FormulaPrint(vis_stdout, to);
03229   fprintf(vis_stdout, "\n------------------------\n");
03230 #endif
03231 
03232   /* from -> from   :  1 */
03233   if (from == to)
03234     return 1;
03235 
03236   /* from -> TRUE   :  1 */
03237   if (to->type == Ctlsp_TRUE_c)
03238     return 1;
03239 
03240   /* FALSE -> to    :  1 */
03241   if (from->type == Ctlsp_FALSE_c)
03242     return 1;
03243 
03244 
03245   if (to->type == Ctlsp_U_c) {
03246     /* from -> tL U tR: (from->tR)? */
03247     if (Ctlsp_LtlFormulaSimplyImply(from, to->right))
03248       return 1;
03249 
03250     /* (fL U fR) -> (tl U tR) : (fL->tL)? && (fR->tR)? */
03251     if (from->type == Ctlsp_U_c)
03252       return (Ctlsp_LtlFormulaSimplyImply(from->left, to->left) &&
03253               Ctlsp_LtlFormulaSimplyImply(from->right, to->right));
03254   }
03255 
03256   if (to->type == Ctlsp_R_c) {
03257     /* from -> tL R tR: (from->tL)? && (from->tR)? */
03258     if (Ctlsp_LtlFormulaSimplyImply(from, to->left) &&
03259         Ctlsp_LtlFormulaSimplyImply(from, to->right))
03260       return 1;
03261 
03262     /* (fL R fR) -> (tL R tR) : (fL->tL)? && (fR->tR)? */
03263     if (from->type == Ctlsp_R_c)
03264       return (Ctlsp_LtlFormulaSimplyImply(from->left, to->left) &&
03265               Ctlsp_LtlFormulaSimplyImply(from->right, to->right));
03266   }
03267 
03268   /* (fL U fR) -> to :: (fL->to)? && (fR->to)? */
03269   if (from->type == Ctlsp_U_c) {
03270     if (Ctlsp_LtlFormulaSimplyImply(from->left, to) &&
03271         Ctlsp_LtlFormulaSimplyImply(from->right,to) )
03272       return 1;
03273   }
03274 
03275   /* (fL R fR) -> to :: (fR->to)? */
03276   if (from->type == Ctlsp_R_c) {
03277     if (Ctlsp_LtlFormulaSimplyImply(from->right,to))
03278       return 1;
03279   }
03280 
03281   /*************************************************************************
03282    * (1) If we unwinding every propositional formula, sometimes it will
03283    * become really hard. This is due to the feature of the CTL* parser.
03284    * For example, "state[1024]=0" would be parsed into 1024 subformulae
03285    *
03286    * (2) Without unwinding, some possible simplification cases can not be
03287    * detected. For example, "p + !p", "p * !p" (while p and the left
03288    * subformula in !p are syntatically different.
03289    ************************************************************************/
03290   if (!Ctlsp_LtlFormulaIsPropositional(to)) {
03291 
03292     /* form -> tL*tR  : (from->tL)? && (from->rR)? */
03293     if (to->type == Ctlsp_AND_c)
03294       return (Ctlsp_LtlFormulaSimplyImply(from, to->left) &&
03295               Ctlsp_LtlFormulaSimplyImply(from, to->right));
03296 
03297     /* from -> tL+tR  : (from->tL)? || (from->rR)? */
03298     if (to->type == Ctlsp_OR_c)
03299       return (Ctlsp_LtlFormulaSimplyImply(from, to->left) ||
03300               Ctlsp_LtlFormulaSimplyImply(from, to->right) );
03301   }
03302 
03303   if (!Ctlsp_LtlFormulaIsPropositional(from)) {
03304 
03305     /* (fL * fR) -> to :: (fL->to)? || (fR->to)? */
03306     if (from->type == Ctlsp_AND_c)
03307       return (Ctlsp_LtlFormulaSimplyImply(from->left, to) ||
03308               Ctlsp_LtlFormulaSimplyImply(from->right,to) );
03309 
03310 
03311     /* (fL + fR) -> to :: (fL->to)? && (fR->to)? */
03312     if (from->type == Ctlsp_OR_c)
03313       return (Ctlsp_LtlFormulaSimplyImply(from->left, to) &&
03314               Ctlsp_LtlFormulaSimplyImply(from->right,to) );
03315   }
03316 
03317   return 0;
03318 }
03319 
03320 
03335 array_t *
03336 Ctlsp_LtlTranslateIntoSNF(
03337   Ctlsp_Formula_t *formula)
03338 {
03339   Ctlsp_Formula_t *leftNode;
03340   int             index, i;
03341   array_t         *formulaArray = array_alloc(Ctlsp_Formula_t *, 0);
03342 
03343   /*
03344     rule#1: an LTL formula must hold at an initial state.
03345    */
03346 
03347   leftNode  = Ctlsp_FormulaCreate(Ctlsp_ID_c, (void *)util_strsav(" SNFstart"), (void *)util_strsav("1"));
03348   /*
03349     rightNode = Ctlsp_FormulaCreate(Ctlsp_ID_c, (void *)util_strsav("SNFx_0"),   (void *)util_strsav("1"));
03350     newNode = Ctlsp_FormulaCreate(Ctlsp_THEN_c, leftNode, rightNode);
03351   */
03352 
03353   index = 0;
03354   Ctlsp_LtlTranslateIntoSNFRecursive(leftNode, formula, formulaArray, &index);
03355 
03356   fprintf(vis_stdout, "The SNF rules are:\n");
03357   for (i = 0; i < array_n(formulaArray); i++) {
03358     Ctlsp_Formula_t *ltlFormula     = array_fetch(Ctlsp_Formula_t *, formulaArray, i);
03359 
03360     Ctlsp_FormulaPrint(vis_stdout, ltlFormula);
03361     fprintf(vis_stdout, "\n");
03362   }
03363 
03364   return formulaArray;
03365 }
03366 
03382 void
03383 Ctlsp_LtlTranslateIntoSNFRecursive(
03384   Ctlsp_Formula_t *propNode,
03385   Ctlsp_Formula_t *formula,
03386   array_t         *formulaArray,
03387   int             *index)
03388 {
03389 
03390   Ctlsp_Formula_t *leftNode, *rightNode, *newNode, *result;
03391 
03392   if(formula == NIL(Ctlsp_Formula_t)){
03393     return;
03394   }
03395   if(Ctlsp_LtlFormulaIsPropositional(formula)){
03396     newNode = CtlspFunctionThen(propNode, formula);
03397     CtlspFormulaIncrementRefCount(newNode);
03398     array_insert_last(Ctlsp_Formula_t *, formulaArray, newNode);
03399     return;
03400   }
03401   switch (Ctlsp_FormulaReadType(formula)) {
03402   case Ctlsp_AND_c:
03403     leftNode  = Ctlsp_FormulaReadLeftChild(formula);
03404     rightNode = Ctlsp_FormulaReadRightChild(formula);
03405 
03406     Ctlsp_LtlTranslateIntoSNFRecursive(propNode, leftNode, formulaArray, index);
03407     Ctlsp_LtlTranslateIntoSNFRecursive(propNode, rightNode, formulaArray, index);
03408 
03409     break;
03410   case Ctlsp_OR_c:
03411     leftNode  = createSNFnode(Ctlsp_FormulaReadLeftChild(formula), formulaArray, index);
03412     rightNode = createSNFnode(Ctlsp_FormulaReadRightChild(formula), formulaArray, index);
03413     newNode   = CtlspFunctionOr(leftNode, rightNode);
03414     Ctlsp_LtlTranslateIntoSNFRecursive(propNode, newNode, formulaArray, index);
03415 
03416     break;
03417   case Ctlsp_THEN_c:
03418     leftNode  = createSNFnode(Ctlsp_FormulaReadLeftChild(formula), formulaArray, index);
03419     rightNode = createSNFnode(Ctlsp_FormulaReadRightChild(formula), formulaArray, index);
03420     newNode   = CtlspFunctionOr(
03421       Ctlsp_FormulaCreate(Ctlsp_NOT_c, leftNode, NIL(Ctlsp_Formula_t))
03422       , rightNode);
03423     Ctlsp_LtlTranslateIntoSNFRecursive(propNode, newNode, formulaArray, index);
03424     break;
03425   case Ctlsp_NOT_c:
03426     if (!Ctlsp_isPropositionalFormula(formula)){
03427       fprintf(vis_stderr,"SNF error: the LTL formula is not in NNF\n");
03428     }
03429     break;
03430   case Ctlsp_X_c:
03431     /*
03432       propNode -> X leftNode
03433      */
03434     leftNode = createSNFnode(Ctlsp_FormulaReadLeftChild(formula), formulaArray, index);
03435 
03436     newNode = Ctlsp_FormulaCreate(Ctlsp_X_c, leftNode, NIL(Ctlsp_Formula_t));
03437     newNode = CtlspFunctionThen(propNode, newNode);
03438      CtlspFormulaIncrementRefCount(newNode);
03439     array_insert_last(Ctlsp_Formula_t *, formulaArray, newNode);
03440 
03441     break;
03442   case Ctlsp_F_c:
03443     /*
03444       propNode -> F leftNode
03445      */
03446     leftNode = createSNFnode(Ctlsp_FormulaReadLeftChild(formula), formulaArray, index);
03447 
03448     newNode  = Ctlsp_FormulaCreate(Ctlsp_F_c, leftNode, NIL(Ctlsp_Formula_t));
03449     newNode  = CtlspFunctionThen(propNode, newNode);
03450      CtlspFormulaIncrementRefCount(newNode);
03451     array_insert_last(Ctlsp_Formula_t *, formulaArray, newNode);
03452 
03453     break;
03454   case Ctlsp_G_c:
03455     /*
03456       propNode -> G leftNode
03457     */
03458     leftNode = createSNFnode(Ctlsp_FormulaReadLeftChild(formula), formulaArray, index);
03459 
03460     newNode  = Ctlsp_FormulaCreate(Ctlsp_ID_c, util_strcat3(" SNFx","_", util_inttostr((*index)++)),
03461                                    (void *)util_strsav("1"));
03462 
03463     result  = CtlspFunctionAnd(leftNode, newNode);
03464     Ctlsp_LtlTranslateIntoSNFRecursive(propNode, result, formulaArray, index);
03465     result   = Ctlsp_FormulaCreate(Ctlsp_X_c, result, NIL(Ctlsp_Formula_t));
03466     Ctlsp_LtlTranslateIntoSNFRecursive(newNode, result, formulaArray, index);
03467 
03468     break;
03469   case Ctlsp_U_c:
03470     /*
03471       x --> a U b = x --> b + a*y
03472                     y --> X(b + a*y)
03473                     x --> F(b)
03474     */
03475     newNode = Ctlsp_FormulaCreate(Ctlsp_ID_c, util_strcat3(" SNFx","_", util_inttostr((*index)++)),
03476                                   (void *)util_strsav("1"));
03477 
03478     leftNode  = createSNFnode(Ctlsp_FormulaReadLeftChild(formula), formulaArray, index);
03479     rightNode = createSNFnode(Ctlsp_FormulaReadRightChild(formula), formulaArray, index);
03480 
03481     result  = CtlspFunctionAnd(leftNode, newNode);
03482     result  = CtlspFunctionOr(rightNode, result);
03483 
03484     Ctlsp_LtlTranslateIntoSNFRecursive(propNode, result, formulaArray, index);
03485 
03486     result   = Ctlsp_FormulaCreate(Ctlsp_X_c, result, NIL(Ctlsp_Formula_t));
03487     Ctlsp_LtlTranslateIntoSNFRecursive(newNode, result, formulaArray, index);
03488 
03489     result   = Ctlsp_FormulaCreate(Ctlsp_F_c, rightNode, NIL(Ctlsp_Formula_t));
03490     Ctlsp_LtlTranslateIntoSNFRecursive(propNode, result, formulaArray, index);
03491     break;
03492   case Ctlsp_W_c:
03493     /*
03494       x --> a W b = x --> b + a*y
03495                     y --> X(b + a*y)
03496     */
03497     newNode = Ctlsp_FormulaCreate(Ctlsp_ID_c, util_strcat3(" SNFx","_", util_inttostr((*index)++)),
03498                                   (void *)util_strsav("1"));
03499 
03500     leftNode  = createSNFnode(Ctlsp_FormulaReadLeftChild(formula), formulaArray, index);
03501     rightNode = createSNFnode(Ctlsp_FormulaReadRightChild(formula), formulaArray, index);
03502 
03503     result  = CtlspFunctionAnd(leftNode, newNode);
03504     result  = CtlspFunctionOr(rightNode, result);
03505 
03506     Ctlsp_LtlTranslateIntoSNFRecursive(propNode, result, formulaArray, index);
03507 
03508     result   = Ctlsp_FormulaCreate(Ctlsp_X_c, result, NIL(Ctlsp_Formula_t));
03509     Ctlsp_LtlTranslateIntoSNFRecursive(newNode, result, formulaArray, index);
03510     break;
03511   case Ctlsp_R_c:
03512     /*
03513       x --> left R right = x --> left*right + right*y
03514                            y --> X(left*rigt* + right*y)
03515      */
03516     newNode = Ctlsp_FormulaCreate(Ctlsp_ID_c, util_strcat3(" SNFx","_", util_inttostr((*index)++)),
03517                                   (void *)util_strsav("1"));
03518     leftNode  = createSNFnode(Ctlsp_FormulaReadLeftChild(formula), formulaArray, index);
03519     rightNode = createSNFnode(Ctlsp_FormulaReadRightChild(formula), formulaArray, index);
03520 
03521     leftNode  = CtlspFunctionAnd(leftNode, rightNode);
03522 
03523     result = CtlspFunctionAnd(rightNode, newNode);
03524     result = CtlspFunctionOr(leftNode, result);
03525 
03526     Ctlsp_LtlTranslateIntoSNFRecursive(propNode, result, formulaArray, index);
03527 
03528     result = Ctlsp_FormulaCreate(Ctlsp_X_c, result, NIL(Ctlsp_Formula_t));
03529     Ctlsp_LtlTranslateIntoSNFRecursive(newNode, result, formulaArray, index);
03530 
03531     break;
03532   default:
03533     fail("unexpected node type in abbreviation-free formula\n");
03534     return; /* not reached */
03535   }
03536 }
03537 
03538 
03550 Ctlsp_Formula_t *
03551 Ctlsp_LtlFormulaSimpleRewriting(
03552   Ctlsp_Formula_t *formula)
03553 {
03554   Ctlsp_Formula_t *F, *newF;
03555   st_table *Utable = st_init_table(FormulaCompare, FormulaHash);
03556   st_generator *stGen;
03557   char *key;
03558 
03559   /* copy the input formula (so that they share nothing) */
03560   F = Ctlsp_LtlFormulaNegationNormalForm(formula);
03561 
03562   /* hash into the 'Utable' */
03563   F = Ctlsp_LtlFormulaHashIntoUniqueTable(F, Utable);
03564 
03565   /* simple rewriting */
03566   F = CtlspLtlFormulaSimpleRewriting_Aux(F, Utable);
03567 
03568   /* copy F into 'newF' (they shares nothing) */
03569   newF = Ctlsp_LtlFormulaNegationNormalForm(F);
03570 
03571   /* free formulae in st_table */
03572   st_foreach_item(Utable, stGen, &key, &F) {
03573     if (F->type == Ctlsp_ID_c) {
03574       FREE(F->left);
03575       FREE(F->right);
03576     }
03577     FREE(F);
03578   }
03579   st_free_table(Utable);
03580 
03581   return (newF);
03582 }
03583 
03584 
03585 /*---------------------------------------------------------------------------*/
03586 /* Definition of internal functions                                          */
03587 /*---------------------------------------------------------------------------*/
03588 
03589 
03601 Ctlsp_Formula_t *
03602 CtlspLtlFormulaSimpleRewriting_Aux(
03603   Ctlsp_Formula_t *F,
03604   st_table *Utable)
03605 {
03606   Ctlsp_Formula_t *left, *right;
03607   Ctlsp_Formula_t *tmpf1, *tmpf2;
03608   Ctlsp_Formula_t *True, *False;
03609 
03610   if (F == NIL(Ctlsp_Formula_t))
03611     return F;
03612 
03613   if (F->type == Ctlsp_ID_c || F->type == Ctlsp_TRUE_c ||
03614       F->type == Ctlsp_FALSE_c) {
03615     F = Ctlsp_LtlFormulaHashIntoUniqueTable(F, Utable);
03616     return F;
03617   }
03618 
03619 #if 0
03620   fprintf(vis_stdout, "\nRewriting ...\n");
03621   Ctlsp_FormulaPrint(vis_stdout, F);
03622   fprintf(vis_stdout, "\n");
03623 #endif
03624 
03625   /* First of all, rewrite F->left, F->right */
03626   left = CtlspLtlFormulaSimpleRewriting_Aux(F->left, Utable);
03627 #if 0
03628   fprintf(vis_stdout, "\n... Rewriting(left)\n");
03629   Ctlsp_FormulaPrint(vis_stdout, left);
03630   fprintf(vis_stdout, "\n");
03631 #endif
03632 
03633   right = CtlspLtlFormulaSimpleRewriting_Aux(F->right, Utable);
03634 #if 0
03635   fprintf(vis_stdout, "\n... Rewriting(right)\n");
03636   Ctlsp_FormulaPrint(vis_stdout, right);
03637   fprintf(vis_stdout, "\n");
03638 #endif
03639 
03640   /* in case we want to use TRUE/FALSE */
03641   True = Ctlsp_LtlFormulaHashIntoUniqueTable(FormulaCreateWithType(Ctlsp_TRUE_c), Utable);
03642   False = Ctlsp_LtlFormulaHashIntoUniqueTable(FormulaCreateWithType(Ctlsp_FALSE_c), Utable);
03643 
03644   switch (F->type) {
03645   case Ctlsp_AND_c:
03646 
03647     /* r -> l :  l*r == r */
03648     if (Ctlsp_LtlFormulaSimplyImply(right, left))
03649       return right;
03650 
03651     /* l -> r, l*r == l */
03652     if (Ctlsp_LtlFormulaSimplyImply(left, right))
03653       return left;
03654 
03655     /* r -> !l, l*r == FALSE*/
03656     tmpf1 = FormulaCreateWithType(Ctlsp_NOT_c);
03657     tmpf1->left = left;
03658     tmpf2 = Ctlsp_LtlFormulaNegationNormalForm(tmpf1);
03659     FREE(tmpf1);
03660     tmpf2 = Ctlsp_LtlFormulaHashIntoUniqueTable(tmpf2, Utable);
03661     if (Ctlsp_LtlFormulaSimplyImply(right, tmpf2))
03662       return False;
03663 
03664     /* l -> !r, l*r == FALSE*/
03665     tmpf1 = FormulaCreateWithType(Ctlsp_NOT_c);
03666     tmpf1->left = right;
03667     tmpf2 = Ctlsp_LtlFormulaNegationNormalForm(tmpf1);
03668     FREE(tmpf1);
03669     tmpf2 = Ctlsp_LtlFormulaHashIntoUniqueTable(tmpf2, Utable);
03670     if (Ctlsp_LtlFormulaSimplyImply(left, tmpf2))
03671       return False;
03672 
03673     /* (ll R lr) * (ll R rr) == (ll) R (lr*rr) */
03674     if (left->type == Ctlsp_R_c && right->type == Ctlsp_R_c) {
03675       if (left->left == right->left) {
03676         tmpf1 = FormulaCreateWithType(Ctlsp_AND_c);
03677         tmpf1->left = left->right;
03678         tmpf1->right = right->right;
03679         CtlspFormulaIncrementRefCount(left->right);
03680         CtlspFormulaIncrementRefCount(right->right);
03681         tmpf1 = Ctlsp_LtlFormulaHashIntoUniqueTable(tmpf1, Utable);
03682 
03683         tmpf2 = FormulaCreateWithType(Ctlsp_R_c);
03684         tmpf2->left = left->left;
03685         tmpf2->right = tmpf1;
03686         CtlspFormulaIncrementRefCount(left->left);
03687         CtlspFormulaIncrementRefCount(tmpf1);
03688         tmpf2 = Ctlsp_LtlFormulaHashIntoUniqueTable(tmpf2, Utable);
03689         return tmpf2;
03690       }
03691     }
03692 
03693     /* (ll U lr) * (rl U lr) == (ll * rl) U (lr) */
03694     if (left->type == Ctlsp_U_c && right->type == Ctlsp_U_c) {
03695       if (left->right == right->right) {
03696         tmpf1 = FormulaCreateWithType(Ctlsp_AND_c);
03697         tmpf1->left = left->left;
03698         tmpf1->right = right->left;
03699         CtlspFormulaIncrementRefCount(left->left);
03700         CtlspFormulaIncrementRefCount(right->left);
03701         tmpf1 = Ctlsp_LtlFormulaHashIntoUniqueTable(tmpf1, Utable);
03702 
03703         tmpf2 = FormulaCreateWithType(Ctlsp_U_c);
03704         tmpf2->left = tmpf1;
03705         tmpf2->right = left->right;
03706         CtlspFormulaIncrementRefCount(tmpf1);
03707         CtlspFormulaIncrementRefCount(left->right);
03708         tmpf2 = Ctlsp_LtlFormulaHashIntoUniqueTable(tmpf2, Utable);
03709         return tmpf2;
03710       }
03711     }
03712 
03713     /* (X ll)*(X rl) == X (ll*rl) */
03714     if (left->type == Ctlsp_X_c && right->type == Ctlsp_X_c) {
03715       tmpf1 = FormulaCreateWithType(Ctlsp_AND_c);
03716       tmpf1->left = left->left;
03717       tmpf1->right = right->left;
03718       CtlspFormulaIncrementRefCount(left->left);
03719       CtlspFormulaIncrementRefCount(right->left);
03720       tmpf1 = Ctlsp_LtlFormulaHashIntoUniqueTable(tmpf1, Utable);
03721 
03722       tmpf2 = FormulaCreateWithType(Ctlsp_X_c);
03723       tmpf2->left = tmpf1;
03724       CtlspFormulaIncrementRefCount(tmpf1);
03725       tmpf2 = Ctlsp_LtlFormulaHashIntoUniqueTable(tmpf2, Utable);
03726       return tmpf2;
03727     }
03728 
03729     /* (ll R lr) * (rl U ll)   ==  ( (X lr * rl) U ll) * lr */
03730     if (left->type == Ctlsp_R_c && right->type == Ctlsp_U_c) {
03731       if (left->left == right->right) {
03732         tmpf1 = FormulaCreateWithType(Ctlsp_X_c);
03733         tmpf1->left = left->right;
03734         CtlspFormulaIncrementRefCount(left->right);
03735         tmpf1 = Ctlsp_LtlFormulaHashIntoUniqueTable(tmpf1, Utable);
03736 
03737         if (right->left->type != Ctlsp_TRUE_c) {
03738           tmpf2 = FormulaCreateWithType(Ctlsp_AND_c);
03739           tmpf2->left = tmpf1;
03740           tmpf2->right = right->left;
03741           CtlspFormulaIncrementRefCount(tmpf1);
03742           CtlspFormulaIncrementRefCount(right->left);
03743           tmpf1 = Ctlsp_LtlFormulaHashIntoUniqueTable(tmpf2, Utable);
03744         }
03745 
03746         tmpf2 = FormulaCreateWithType(Ctlsp_U_c);
03747         tmpf2->left = tmpf1;
03748         tmpf2->right = left->left;
03749         CtlspFormulaIncrementRefCount(tmpf1);
03750         CtlspFormulaIncrementRefCount(left->left);
03751         tmpf1 = Ctlsp_LtlFormulaHashIntoUniqueTable(tmpf2, Utable);
03752 
03753         tmpf2 = FormulaCreateWithType(Ctlsp_AND_c);
03754         tmpf2->left = tmpf1;
03755         tmpf2->right = left->right;
03756         CtlspFormulaIncrementRefCount(tmpf1);
03757         CtlspFormulaIncrementRefCount(left->right);
03758         tmpf2 = Ctlsp_LtlFormulaHashIntoUniqueTable(tmpf2, Utable);
03759 
03760         return tmpf2;
03761       }
03762     }
03763     /* (ll U lr) * (lr R rr)   ==  ( (X rr * ll) U rl) * rr */
03764     if (left->type == Ctlsp_U_c && right->type == Ctlsp_R_c) {
03765       if (left->right == right->left) {
03766         tmpf1 = FormulaCreateWithType(Ctlsp_X_c);
03767         tmpf1->left = right->right;
03768         CtlspFormulaIncrementRefCount(right->right);
03769         tmpf1 = Ctlsp_LtlFormulaHashIntoUniqueTable(tmpf1, Utable);
03770 
03771         if (left->left->type != Ctlsp_TRUE_c) {
03772           tmpf2 = FormulaCreateWithType(Ctlsp_AND_c);
03773           tmpf2->left = tmpf1;
03774           tmpf2->right = left->left;
03775           CtlspFormulaIncrementRefCount(tmpf1);
03776           CtlspFormulaIncrementRefCount(left->left);
03777           tmpf1 = Ctlsp_LtlFormulaHashIntoUniqueTable(tmpf2, Utable);
03778         }
03779 
03780         tmpf2 = FormulaCreateWithType(Ctlsp_U_c);
03781         tmpf2->left = tmpf1;
03782         tmpf2->right = right->left;
03783         CtlspFormulaIncrementRefCount(tmpf1);
03784         CtlspFormulaIncrementRefCount(right->left);
03785         tmpf1 = Ctlsp_LtlFormulaHashIntoUniqueTable(tmpf2, Utable);
03786 
03787         tmpf2 = FormulaCreateWithType(Ctlsp_AND_c);
03788         tmpf2->left = tmpf1;
03789         tmpf2->right = right->right;
03790         CtlspFormulaIncrementRefCount(tmpf1);
03791         CtlspFormulaIncrementRefCount(right->right);
03792         tmpf2 = Ctlsp_LtlFormulaHashIntoUniqueTable(tmpf2, Utable);
03793 
03794         return tmpf2;
03795       }
03796     }
03797 
03798     /* (ll R lr) * r, r=>ll  == lr *r */
03799     if (left->type == Ctlsp_R_c &&
03800         Ctlsp_LtlFormulaSimplyImply(right, left->left)) {
03801       tmpf1 = FormulaCreateWithType(Ctlsp_AND_c);
03802       tmpf1->left = left->right;
03803       tmpf1->right = right;
03804       CtlspFormulaIncrementRefCount(left->right);
03805       CtlspFormulaIncrementRefCount(right);
03806       tmpf2 = Ctlsp_LtlFormulaHashIntoUniqueTable(tmpf1, Utable);
03807       return tmpf2;
03808     }
03809     /* l *(rl R rr), l=>rl  == l * rr */
03810     if (right->type == Ctlsp_R_c &&
03811         Ctlsp_LtlFormulaSimplyImply(left, right->left)) {
03812       tmpf1 = FormulaCreateWithType(Ctlsp_AND_c);
03813       tmpf1->left = left;
03814       tmpf1->right = right->right;
03815       CtlspFormulaIncrementRefCount(left);
03816       CtlspFormulaIncrementRefCount(right->right);
03817       tmpf2 = Ctlsp_LtlFormulaHashIntoUniqueTable(tmpf1, Utable);
03818       return tmpf2;
03819     }
03820 
03821     /* (ll U lr) * r, r=>!ll   == lr * r */
03822     if (left->type == Ctlsp_U_c) {
03823       tmpf1 = FormulaCreateWithType(Ctlsp_NOT_c);
03824       tmpf1->left = left->left;
03825       tmpf2 = Ctlsp_LtlFormulaNegationNormalForm(tmpf1);
03826       FREE(tmpf1);
03827       tmpf1 = Ctlsp_LtlFormulaHashIntoUniqueTable(tmpf2, Utable);
03828 
03829       if (Ctlsp_LtlFormulaSimplyImply(right, tmpf1)) {
03830         tmpf1 = FormulaCreateWithType(Ctlsp_AND_c);
03831         tmpf1->left = left->right;
03832         tmpf1->right = right;
03833         CtlspFormulaIncrementRefCount(left->right);
03834         CtlspFormulaIncrementRefCount(right);
03835         tmpf2 = Ctlsp_LtlFormulaHashIntoUniqueTable(tmpf1, Utable);
03836         return tmpf2;
03837       }
03838     }
03839     /* l * (rl U rr), l=>!rl   == l * rr */
03840     if (right->type == Ctlsp_U_c) {
03841       tmpf1 = FormulaCreateWithType(Ctlsp_NOT_c);
03842       tmpf1->left = right->left;
03843       tmpf2 = Ctlsp_LtlFormulaNegationNormalForm(tmpf1);
03844       FREE(tmpf1);
03845       tmpf1 = Ctlsp_LtlFormulaHashIntoUniqueTable(tmpf2, Utable);
03846 
03847       if (Ctlsp_LtlFormulaSimplyImply(left, tmpf1)) {
03848         tmpf1 = FormulaCreateWithType(Ctlsp_AND_c);
03849         tmpf1->left = left;
03850         tmpf1->right = right->right;
03851         CtlspFormulaIncrementRefCount(left);
03852         CtlspFormulaIncrementRefCount(right->right);
03853         tmpf2 = Ctlsp_LtlFormulaHashIntoUniqueTable(tmpf1, Utable);
03854         return tmpf2;
03855       }
03856     }
03857 
03858     /* FG lrr * FG rrr = FG (lrr * rrr) */
03859     if (Ctlsp_LtlFormulaIsFG(left) && Ctlsp_LtlFormulaIsFG(right)) {
03860       tmpf1 = FormulaCreateWithType(Ctlsp_AND_c);
03861       tmpf1->left = left->right->right;
03862       tmpf1->right = right->right->right;
03863       CtlspFormulaIncrementRefCount(left->right->right);
03864       CtlspFormulaIncrementRefCount(right->right->right);
03865       tmpf1 = Ctlsp_LtlFormulaHashIntoUniqueTable(tmpf1, Utable);
03866 
03867       tmpf2 = FormulaCreateWithType(Ctlsp_R_c);
03868       tmpf2->left = False;
03869       tmpf2->right = tmpf1;
03870       CtlspFormulaIncrementRefCount(False);
03871       CtlspFormulaIncrementRefCount(tmpf1);
03872       tmpf1 = Ctlsp_LtlFormulaHashIntoUniqueTable(tmpf2, Utable);
03873 
03874       tmpf2 = FormulaCreateWithType(Ctlsp_U_c);
03875       tmpf2->left = True;
03876       tmpf2->right = tmpf1;
03877       CtlspFormulaIncrementRefCount(True);
03878       CtlspFormulaIncrementRefCount(tmpf1);
03879       tmpf2 = Ctlsp_LtlFormulaHashIntoUniqueTable(tmpf2, Utable);
03880       return tmpf2;
03881     }
03882 
03883     /* return  (l * r) */
03884     tmpf1 = FormulaCreateWithType(Ctlsp_AND_c);
03885     tmpf1->left = left;
03886     tmpf1->right = right;
03887     CtlspFormulaIncrementRefCount(left);
03888     CtlspFormulaIncrementRefCount(right);
03889     tmpf2 = Ctlsp_LtlFormulaHashIntoUniqueTable(tmpf1, Utable);
03890     return tmpf2;
03891 
03892   case Ctlsp_OR_c:
03893 
03894     /* r -> l, l+r == l */
03895     if (Ctlsp_LtlFormulaSimplyImply(right, left))
03896       return left;
03897 
03898     /* l -> r, l+r == r */
03899     if (Ctlsp_LtlFormulaSimplyImply(left, right))
03900       return right;
03901 
03902     /* !r -> l, l+r == TRUE*/
03903     tmpf1 = FormulaCreateWithType(Ctlsp_NOT_c);
03904     tmpf1->left = right;
03905     tmpf2 = Ctlsp_LtlFormulaNegationNormalForm(tmpf1);
03906     FREE(tmpf1);
03907     tmpf2 = Ctlsp_LtlFormulaHashIntoUniqueTable(tmpf2, Utable);
03908     if (Ctlsp_LtlFormulaSimplyImply(tmpf2, left))
03909       return True;
03910 
03911     /* !l -> r, l+r == TRUE*/
03912     tmpf1 = FormulaCreateWithType(Ctlsp_NOT_c);
03913     tmpf1->left = left;
03914     tmpf2 = Ctlsp_LtlFormulaNegationNormalForm(tmpf1);
03915     FREE(tmpf1);
03916     tmpf2 = Ctlsp_LtlFormulaHashIntoUniqueTable(tmpf2, Utable);
03917     if (Ctlsp_LtlFormulaSimplyImply(tmpf2, right))
03918       return True;
03919 
03920     /* (ll U lr) + (ll U rr) == (ll) U (lr+rr) */
03921     if (left->type == Ctlsp_U_c && right->type == Ctlsp_U_c) {
03922       if (left->left == right->left) {
03923         tmpf1 = FormulaCreateWithType(Ctlsp_OR_c);
03924         tmpf1->left = left->right;
03925         tmpf1->right = right->right;
03926         CtlspFormulaIncrementRefCount(left->right);
03927         CtlspFormulaIncrementRefCount(right->right);
03928         tmpf1 = Ctlsp_LtlFormulaHashIntoUniqueTable(tmpf1, Utable);
03929 
03930         tmpf2 = FormulaCreateWithType(Ctlsp_U_c);
03931         tmpf2->left = left->left;
03932         tmpf2->right = tmpf1;
03933         CtlspFormulaIncrementRefCount(left->left);
03934         CtlspFormulaIncrementRefCount(tmpf1);
03935         tmpf2 = Ctlsp_LtlFormulaHashIntoUniqueTable(tmpf2, Utable);
03936         return tmpf2;
03937       }
03938     }
03939 
03940     /* (ll R lr) + (rl R lr) == (ll+rl) R (lr) */
03941     if (left->type == Ctlsp_R_c && right->type == Ctlsp_R_c) {
03942       if (left->right == right->right) {
03943         tmpf1 = FormulaCreateWithType(Ctlsp_OR_c);
03944         tmpf1->left = left->left;
03945         tmpf1->right = right->left;
03946         CtlspFormulaIncrementRefCount(left->left);
03947         CtlspFormulaIncrementRefCount(right->left);
03948         tmpf1 = Ctlsp_LtlFormulaHashIntoUniqueTable(tmpf1, Utable);
03949 
03950         tmpf2 = FormulaCreateWithType(Ctlsp_R_c);
03951         tmpf2->left = tmpf1;
03952         tmpf2->right = left->right;
03953         CtlspFormulaIncrementRefCount(tmpf1);
03954         CtlspFormulaIncrementRefCount(left->right);
03955         tmpf2 = Ctlsp_LtlFormulaHashIntoUniqueTable(tmpf2, Utable);
03956         return tmpf2;
03957       }
03958     }
03959 
03960     /* (X ll) + (X rl) == X (ll+rl) */
03961     if (left->type == Ctlsp_X_c && right->type == Ctlsp_X_c) {
03962       tmpf1 = FormulaCreateWithType(Ctlsp_OR_c);
03963       tmpf1->left = left->left;
03964       tmpf1->right = right->left;
03965       CtlspFormulaIncrementRefCount(left->left);
03966       CtlspFormulaIncrementRefCount(right->left);
03967       tmpf1 = Ctlsp_LtlFormulaHashIntoUniqueTable(tmpf1, Utable);
03968 
03969       tmpf2 = FormulaCreateWithType(Ctlsp_X_c);
03970       tmpf2->left = tmpf1;
03971       CtlspFormulaIncrementRefCount(tmpf1);
03972       tmpf2 = Ctlsp_LtlFormulaHashIntoUniqueTable(tmpf2, Utable);
03973       return tmpf2;
03974     }
03975 
03976     /* ll U lr  + rl R ll  == ((Xlr + rl) R ll) +lr */
03977     if (left->type == Ctlsp_U_c && right->type == Ctlsp_R_c) {
03978       if (left->left == right->right) {
03979         tmpf1 = FormulaCreateWithType(Ctlsp_X_c);
03980         tmpf1->left = left->right;
03981         CtlspFormulaIncrementRefCount(left->right);
03982         tmpf1 = Ctlsp_LtlFormulaHashIntoUniqueTable(tmpf1, Utable);
03983 
03984         if (right->left->type != Ctlsp_FALSE_c) {
03985           tmpf2 = FormulaCreateWithType(Ctlsp_OR_c);
03986           tmpf2->left = tmpf1;
03987           tmpf2->right = right->left;
03988           CtlspFormulaIncrementRefCount(tmpf1);
03989           CtlspFormulaIncrementRefCount(right->left);
03990           tmpf1 = Ctlsp_LtlFormulaHashIntoUniqueTable(tmpf2, Utable);
03991         }
03992 
03993         tmpf2 = FormulaCreateWithType(Ctlsp_R_c);
03994         tmpf2->left = tmpf1;
03995         tmpf2->right = left->left;
03996         CtlspFormulaIncrementRefCount(tmpf1);
03997         CtlspFormulaIncrementRefCount(left->left);
03998         tmpf1 = Ctlsp_LtlFormulaHashIntoUniqueTable(tmpf2, Utable);
03999 
04000         tmpf2 = FormulaCreateWithType(Ctlsp_OR_c);
04001         tmpf2->left = tmpf1;
04002         tmpf2->right = left->right;
04003         CtlspFormulaIncrementRefCount(tmpf1);
04004         CtlspFormulaIncrementRefCount(left->right);
04005         tmpf2 = Ctlsp_LtlFormulaHashIntoUniqueTable(tmpf2, Utable);
04006 
04007         return tmpf2;
04008       }
04009     }
04010 
04011     /* ll R lr  + lr U rr  == ((Xrr + ll) R lr) + rr */
04012     if (left->type == Ctlsp_R_c && right->type == Ctlsp_U_c) {
04013       if (left->right == right->left) {
04014         tmpf1 = FormulaCreateWithType(Ctlsp_X_c);
04015         tmpf1->left = right->right;
04016         CtlspFormulaIncrementRefCount(right->right);
04017         tmpf1 = Ctlsp_LtlFormulaHashIntoUniqueTable(tmpf1, Utable);
04018 
04019         if (left->left->type != Ctlsp_FALSE_c) {
04020           tmpf2 = FormulaCreateWithType(Ctlsp_OR_c);
04021           tmpf2->left = tmpf1;
04022           tmpf2->right = left->left;
04023           CtlspFormulaIncrementRefCount(tmpf1);
04024           CtlspFormulaIncrementRefCount(left->left);
04025           tmpf1 = Ctlsp_LtlFormulaHashIntoUniqueTable(tmpf2, Utable);
04026         }
04027 
04028         tmpf2 = FormulaCreateWithType(Ctlsp_R_c);
04029         tmpf2->left = tmpf1;
04030         tmpf2->right = left->right;
04031         CtlspFormulaIncrementRefCount(tmpf1);
04032         CtlspFormulaIncrementRefCount(left->right);
04033         tmpf1 = Ctlsp_LtlFormulaHashIntoUniqueTable(tmpf2, Utable);
04034 
04035         tmpf2 = FormulaCreateWithType(Ctlsp_OR_c);
04036         tmpf2->left = tmpf1;
04037         tmpf2->right = right->right;
04038         CtlspFormulaIncrementRefCount(tmpf1);
04039         CtlspFormulaIncrementRefCount(right->right);
04040         tmpf2 = Ctlsp_LtlFormulaHashIntoUniqueTable(tmpf2, Utable);
04041 
04042         return tmpf2;
04043       }
04044     }
04045 
04046     /* ll U lr + r , ll =>r  ==  lr + r ??? */
04047     if (left->type == Ctlsp_U_c) {
04048       if (Ctlsp_LtlFormulaSimplyImply(left->left, right)) {
04049         tmpf1 = FormulaCreateWithType(Ctlsp_OR_c);
04050         tmpf1->left = left->right;
04051         tmpf1->right = right;
04052         CtlspFormulaIncrementRefCount(left->right);
04053         CtlspFormulaIncrementRefCount(right);
04054         tmpf2 = Ctlsp_LtlFormulaHashIntoUniqueTable(tmpf1, Utable);
04055         return tmpf2;
04056       }
04057     }
04058 
04059     /* l + rl U rr ,  rl => l   ==  rr + l */
04060     if (right->type == Ctlsp_U_c) {
04061       if (Ctlsp_LtlFormulaSimplyImply(right->left, left)) {
04062         tmpf1 = FormulaCreateWithType(Ctlsp_OR_c);
04063         tmpf1->left = left;
04064         tmpf1->right = right->right;
04065         CtlspFormulaIncrementRefCount(left);
04066         CtlspFormulaIncrementRefCount(right->right);
04067         tmpf2 = Ctlsp_LtlFormulaHashIntoUniqueTable(tmpf1, Utable);
04068         return tmpf2;
04069       }
04070     }
04071 
04072     /* ll R lr + r ,  !ll => r   ==  lr + r */
04073     if (left->type == Ctlsp_R_c) {
04074       tmpf1 = FormulaCreateWithType(Ctlsp_NOT_c);
04075       tmpf1->left = left->left;
04076       tmpf2 = Ctlsp_LtlFormulaNegationNormalForm(tmpf1);
04077       FREE(tmpf1);
04078       tmpf2 = Ctlsp_LtlFormulaHashIntoUniqueTable(tmpf2, Utable);
04079       if (Ctlsp_LtlFormulaSimplyImply(tmpf2, right)) {
04080         tmpf1 = FormulaCreateWithType(Ctlsp_OR_c);
04081         tmpf1->left = left->right;
04082         tmpf1->right = right;
04083         CtlspFormulaIncrementRefCount(left->right);
04084         CtlspFormulaIncrementRefCount(right);
04085         tmpf2 = Ctlsp_LtlFormulaHashIntoUniqueTable(tmpf1, Utable);
04086         return tmpf2;
04087       }
04088     }
04089 
04090     /* l + rl R rr ,  !rl => l   ==  rr + l */
04091     if (right->type == Ctlsp_R_c) {
04092       tmpf1 = FormulaCreateWithType(Ctlsp_NOT_c);
04093       tmpf1->left = right->left;
04094       tmpf2 = Ctlsp_LtlFormulaNegationNormalForm(tmpf1);
04095       FREE(tmpf1);
04096       tmpf2 = Ctlsp_LtlFormulaHashIntoUniqueTable(tmpf2, Utable);
04097       if (Ctlsp_LtlFormulaSimplyImply(tmpf2, left)) {
04098         tmpf1 = FormulaCreateWithType(Ctlsp_OR_c);
04099         tmpf1->left = left;
04100         tmpf1->right = right->right;
04101         CtlspFormulaIncrementRefCount(left);
04102         CtlspFormulaIncrementRefCount(right->right);
04103         tmpf2 = Ctlsp_LtlFormulaHashIntoUniqueTable(tmpf1, Utable);
04104         return tmpf2;
04105       }
04106     }
04107 
04108     /* GF lrr + GF rrr = GF (lrr + rrr) */
04109     if (Ctlsp_LtlFormulaIsGF(left) && Ctlsp_LtlFormulaIsGF(right)) {
04110       tmpf1 = FormulaCreateWithType(Ctlsp_OR_c);
04111       tmpf1->left = left->right->right;
04112       tmpf1->right = right->right->right;
04113       CtlspFormulaIncrementRefCount(left->right->right);
04114       CtlspFormulaIncrementRefCount(right->right->right);
04115       tmpf1 = Ctlsp_LtlFormulaHashIntoUniqueTable(tmpf1, Utable);
04116 
04117       tmpf2 = FormulaCreateWithType(Ctlsp_U_c);
04118       tmpf2->left = True;
04119       tmpf2->right = tmpf1;
04120       CtlspFormulaIncrementRefCount(True);
04121       CtlspFormulaIncrementRefCount(tmpf1);
04122       tmpf1 = Ctlsp_LtlFormulaHashIntoUniqueTable(tmpf2, Utable);
04123 
04124       tmpf2 = FormulaCreateWithType(Ctlsp_R_c);
04125       tmpf2->left = False;
04126       tmpf2->right = tmpf1;
04127       CtlspFormulaIncrementRefCount(False);
04128       CtlspFormulaIncrementRefCount(tmpf1);
04129       tmpf2 = Ctlsp_LtlFormulaHashIntoUniqueTable(tmpf2, Utable);
04130       return tmpf2;
04131     }
04132 
04133     /* return  (l + r) */
04134     tmpf1 = FormulaCreateWithType(Ctlsp_OR_c);
04135     tmpf1->left = left;
04136     tmpf1->right = right;
04137     CtlspFormulaIncrementRefCount(left);
04138     CtlspFormulaIncrementRefCount(right);
04139     tmpf2 = Ctlsp_LtlFormulaHashIntoUniqueTable(tmpf1, Utable);
04140     return tmpf2;
04141 
04142   case Ctlsp_U_c:
04143 
04144     /* l -> r : l U r == r */
04145     if (Ctlsp_LtlFormulaSimplyImply(left, right))
04146       return right;
04147 
04148     /* l U FALSE = FALSE */
04149     if (right->type == Ctlsp_FALSE_c)
04150       return False;
04151 
04152     /* (X ll) U (X rl) == X (ll U rl) */
04153     if (left->type == Ctlsp_X_c && right->type == Ctlsp_X_c) {
04154       tmpf1 = FormulaCreateWithType(Ctlsp_U_c);
04155       tmpf1->left = left->left;
04156       tmpf1->right = right->left;
04157       CtlspFormulaIncrementRefCount(left->left);
04158       CtlspFormulaIncrementRefCount(right->left);
04159       tmpf1 = Ctlsp_LtlFormulaHashIntoUniqueTable(tmpf1, Utable);
04160 
04161       tmpf2 = FormulaCreateWithType(Ctlsp_X_c);
04162       tmpf2->left = tmpf1;
04163       CtlspFormulaIncrementRefCount(tmpf1);
04164       tmpf2 = Ctlsp_LtlFormulaHashIntoUniqueTable(tmpf2, Utable);
04165       return tmpf2;
04166     }
04167 
04168     /* TRUE U (X rl) == X( TRUE U rl ) */
04169     if (left->type == Ctlsp_TRUE_c && right->type == Ctlsp_X_c) {
04170       tmpf1 = FormulaCreateWithType(Ctlsp_U_c);
04171       tmpf1->left = True;
04172       tmpf1->right = right->left;
04173       CtlspFormulaIncrementRefCount(True);
04174       CtlspFormulaIncrementRefCount(right->left);
04175       tmpf1 = Ctlsp_LtlFormulaHashIntoUniqueTable(tmpf1, Utable);
04176 
04177       tmpf2 = FormulaCreateWithType(Ctlsp_X_c);
04178       tmpf2->left = tmpf1;
04179       CtlspFormulaIncrementRefCount(tmpf1);
04180       tmpf2 = Ctlsp_LtlFormulaHashIntoUniqueTable(tmpf2, Utable);
04181       return tmpf2;
04182     }
04183 
04184     /* l->rl : l U (rl U rr) == rl U rr */
04185     if (right->type == Ctlsp_U_c) {
04186       if (Ctlsp_LtlFormulaSimplyImply(left, right->left)) {
04187         return right;
04188       }
04189     }
04190 
04191     /* (TRUE or anything) U (FG rrr) == FG rrr */
04192     /* (TRUE or anything) U (GF rrr) == GF rrr */
04193     if (/*left->type == Ctlsp_TRUE_c &&*/ Ctlsp_LtlFormulaIsFGorGF(right))
04194       return right;
04195 
04196     /* TRUE U (rl * FG rrrr) = F(rl) * FG(rrrr) */
04197     /* TRUE U (rl * GF rrrr) = F(rl) * GF(rrrr) */
04198     if (left->type == Ctlsp_TRUE_c && right->type == Ctlsp_AND_c) {
04199       if (Ctlsp_LtlFormulaIsFGorGF(right->right)) {
04200         tmpf1 = FormulaCreateWithType(Ctlsp_U_c);
04201         tmpf1->left = True;
04202         tmpf1->right = right->left;
04203         CtlspFormulaIncrementRefCount(True);
04204         CtlspFormulaIncrementRefCount(right->left);
04205         tmpf1 = Ctlsp_LtlFormulaHashIntoUniqueTable(tmpf1, Utable);
04206 
04207         tmpf2 = FormulaCreateWithType(Ctlsp_AND_c);
04208         tmpf2->left = tmpf1;
04209         tmpf2->right = right->right;
04210         CtlspFormulaIncrementRefCount(tmpf1);
04211         CtlspFormulaIncrementRefCount(right->right);
04212         tmpf2 = Ctlsp_LtlFormulaHashIntoUniqueTable(tmpf2, Utable);
04213         return tmpf2;
04214       }
04215     }
04216 
04217     /* TRUE U (FG rlrr * rr) == (FG rlrr) * F(rr) */
04218     /* TRUE U (GF rlrr * rr) == (GF rlrr) * F(rr) */
04219     if (left->type == Ctlsp_TRUE_c && right->type == Ctlsp_AND_c) {
04220       if (Ctlsp_LtlFormulaIsFGorGF(right->left)) {
04221         tmpf1 = FormulaCreateWithType(Ctlsp_U_c);
04222         tmpf1->left = True;
04223         tmpf1->right = right->right;
04224         CtlspFormulaIncrementRefCount(True);
04225         CtlspFormulaIncrementRefCount(right->right);
04226         tmpf1 = Ctlsp_LtlFormulaHashIntoUniqueTable(tmpf1, Utable);
04227 
04228         tmpf2 = FormulaCreateWithType(Ctlsp_AND_c);
04229         tmpf2->left = right->left;
04230         tmpf2->right = tmpf1;
04231         CtlspFormulaIncrementRefCount(right->left);
04232         CtlspFormulaIncrementRefCount(tmpf1);
04233         tmpf2 = Ctlsp_LtlFormulaHashIntoUniqueTable(tmpf2, Utable);
04234         return tmpf2;
04235       }
04236     }
04237 
04238     /* !r -> l : (l U r) == TRUE U r */
04239     tmpf1 = FormulaCreateWithType(Ctlsp_NOT_c);
04240     tmpf1->left = right;
04241     tmpf2 = Ctlsp_LtlFormulaNegationNormalForm(tmpf1);
04242     FREE(tmpf1);
04243     tmpf2 = Ctlsp_LtlFormulaHashIntoUniqueTable(tmpf2, Utable);
04244     if (Ctlsp_LtlFormulaSimplyImply(tmpf2, left)) {
04245       tmpf1 = FormulaCreateWithType(Ctlsp_U_c);
04246       tmpf1->left = True;
04247       tmpf1->right = right;
04248       CtlspFormulaIncrementRefCount(True);
04249       CtlspFormulaIncrementRefCount(right);
04250       tmpf2 = Ctlsp_LtlFormulaHashIntoUniqueTable(tmpf1, Utable);
04251       return tmpf2;
04252     }
04253 
04254     /* (ll + lr) U r,  ll => r   == (lr U r) */
04255     if (left->type == Ctlsp_OR_c) {
04256       if (Ctlsp_LtlFormulaSimplyImply(left->left, right)) {
04257         tmpf1 = FormulaCreateWithType(Ctlsp_U_c);
04258         tmpf1->left = left->right;
04259         tmpf1->right = right;
04260         CtlspFormulaIncrementRefCount(left->right);
04261         CtlspFormulaIncrementRefCount(right);
04262         tmpf2 = Ctlsp_LtlFormulaHashIntoUniqueTable(tmpf1, Utable);
04263         return tmpf2;
04264       }
04265     }
04266 
04267     /* (ll + lr) U r,  lr => r   == (ll U r) */
04268     if (left->type == Ctlsp_OR_c) {
04269       if (Ctlsp_LtlFormulaSimplyImply(left->right, right)) {
04270         tmpf1 = FormulaCreateWithType(Ctlsp_U_c);
04271         tmpf1->left = left->left;
04272         tmpf1->right = right;
04273         CtlspFormulaIncrementRefCount(left->left);
04274         CtlspFormulaIncrementRefCount(right);
04275         tmpf2 = Ctlsp_LtlFormulaHashIntoUniqueTable(tmpf1, Utable);
04276         return tmpf2;
04277       }
04278     }
04279 
04280 
04281     /* return  (left U right) */
04282     tmpf1 = FormulaCreateWithType(Ctlsp_U_c);
04283     tmpf1->left = left;
04284     tmpf1->right = right;
04285     CtlspFormulaIncrementRefCount(left);
04286     CtlspFormulaIncrementRefCount(right);
04287     tmpf2 = Ctlsp_LtlFormulaHashIntoUniqueTable(tmpf1, Utable);
04288     return tmpf2;
04289 
04290   case Ctlsp_R_c:
04291 
04292     /* r -> l : l R r == r */
04293     if (Ctlsp_LtlFormulaSimplyImply(right,left))
04294       return right;
04295 
04296     /* l R TRUE == TRUE */
04297     if (right->type == Ctlsp_TRUE_c)
04298       return True;
04299 
04300     /* (X ll) R (X rl) == X (ll R rl) */
04301     if (left->type == Ctlsp_X_c && right->type == Ctlsp_X_c) {
04302       tmpf1 = FormulaCreateWithType(Ctlsp_R_c);
04303       tmpf1->left = left->left;
04304       tmpf1->right = right->left;
04305       CtlspFormulaIncrementRefCount(left->left);
04306       CtlspFormulaIncrementRefCount(right->left);
04307       tmpf1 = Ctlsp_LtlFormulaHashIntoUniqueTable(tmpf1, Utable);
04308 
04309       tmpf2 = FormulaCreateWithType(Ctlsp_X_c);
04310       tmpf2->left = tmpf1;
04311       CtlspFormulaIncrementRefCount(tmpf1);
04312       tmpf2 = Ctlsp_LtlFormulaHashIntoUniqueTable(tmpf2, Utable);
04313       return tmpf2;
04314     }
04315 
04316     /* FALSE R (X rl) == X( FALSE R rl) */
04317     if (left->type == Ctlsp_TRUE_c && right->type == Ctlsp_X_c) {
04318       tmpf1 = FormulaCreateWithType(Ctlsp_R_c);
04319       tmpf1->left = False;
04320       tmpf1->right = right->left;
04321       CtlspFormulaIncrementRefCount(False);
04322       CtlspFormulaIncrementRefCount(right->left);
04323       tmpf1 = Ctlsp_LtlFormulaHashIntoUniqueTable(tmpf1, Utable);
04324 
04325       tmpf2 = FormulaCreateWithType(Ctlsp_X_c);
04326       tmpf2->left = tmpf1;
04327       CtlspFormulaIncrementRefCount(tmpf1);
04328       tmpf2 = Ctlsp_LtlFormulaHashIntoUniqueTable(tmpf2, Utable);
04329       return tmpf2;
04330     }
04331 
04332     /* rl->l :  l R (rl R rr) == (rl R rr) */
04333     if (right->type == Ctlsp_R_c)
04334       if (Ctlsp_LtlFormulaSimplyImply(right->left, left))
04335         return right;
04336 
04337     /* (FALSE or anything) R (FG rrr) == FG rrr */
04338     /* (FALSE or anything) R (GF rrr) == GF rrr */
04339     if (/*left->type == Ctlsp_FALSE_c &&*/ Ctlsp_LtlFormulaIsFGorGF(right))
04340       return right;
04341 
04342     /* FALSE R (rl + FG rrrr) = G(rl) + FG(rrrr) */
04343     /* FALSE R (rl + GF rrrr) = G(rl) + GF(rrrr) */
04344     if (left->type == Ctlsp_FALSE_c && right->type == Ctlsp_OR_c) {
04345       if (Ctlsp_LtlFormulaIsFGorGF(right->right)) {
04346         tmpf1 = FormulaCreateWithType(Ctlsp_R_c);
04347         tmpf1->left = False;
04348         tmpf1->right = right->left;
04349         CtlspFormulaIncrementRefCount(False);
04350         CtlspFormulaIncrementRefCount(right->left);
04351         tmpf1 = Ctlsp_LtlFormulaHashIntoUniqueTable(tmpf1, Utable);
04352 
04353         tmpf2 = FormulaCreateWithType(Ctlsp_OR_c);
04354         tmpf2->left = tmpf1;
04355         tmpf2->right = right->right;
04356         CtlspFormulaIncrementRefCount(tmpf1);
04357         CtlspFormulaIncrementRefCount(right->right);
04358         tmpf2 = Ctlsp_LtlFormulaHashIntoUniqueTable(tmpf2, Utable);
04359         return tmpf2;
04360       }
04361     }
04362 
04363     /* FALSE R (FG rlrr + rr) = FG(rlrr) + G(rr) */
04364     /* FALSE R (GF rlrr + rr) = GF(rlrr) + G(rr) */
04365     if (left->type == Ctlsp_FALSE_c && right->type == Ctlsp_OR_c) {
04366       if (Ctlsp_LtlFormulaIsFGorGF(right->left)) {
04367         tmpf1 = FormulaCreateWithType(Ctlsp_R_c);
04368         tmpf1->left = False;
04369         tmpf1->right = right->right;
04370         CtlspFormulaIncrementRefCount(False);
04371         CtlspFormulaIncrementRefCount(right->right);
04372         tmpf1 = Ctlsp_LtlFormulaHashIntoUniqueTable(tmpf1, Utable);
04373 
04374         tmpf2 = FormulaCreateWithType(Ctlsp_OR_c);
04375         tmpf2->left = tmpf1;
04376         tmpf2->right = right->left;
04377         CtlspFormulaIncrementRefCount(tmpf1);
04378         CtlspFormulaIncrementRefCount(right->left);
04379         tmpf2 = Ctlsp_LtlFormulaHashIntoUniqueTable(tmpf2, Utable);
04380         return tmpf2;
04381       }
04382     }
04383 
04384     /* r -> !l : (l R r) == FALSE R r */
04385     tmpf1 = FormulaCreateWithType(Ctlsp_NOT_c);
04386     tmpf1->left = left;
04387     tmpf2 = Ctlsp_LtlFormulaNegationNormalForm(tmpf1);
04388     FREE(tmpf1);
04389     tmpf2 = Ctlsp_LtlFormulaHashIntoUniqueTable(tmpf2, Utable);
04390     if (Ctlsp_LtlFormulaSimplyImply(right, tmpf2)) {
04391       tmpf1 = FormulaCreateWithType(Ctlsp_R_c);
04392       tmpf1->left = False;
04393       tmpf1->right = right;
04394       CtlspFormulaIncrementRefCount(False);
04395       CtlspFormulaIncrementRefCount(right);
04396       tmpf2 = Ctlsp_LtlFormulaHashIntoUniqueTable(tmpf1, Utable);
04397       return tmpf2;
04398     }
04399 
04400     /* r=>ll : (ll * lr) R r  ==  lr R r */
04401     if (left->type == Ctlsp_AND_c) {
04402       if (Ctlsp_LtlFormulaSimplyImply(right, left->left)) {
04403         tmpf1 = FormulaCreateWithType(Ctlsp_R_c);
04404         tmpf1->left = left->right;
04405         tmpf1->right = right;
04406         CtlspFormulaIncrementRefCount(left->right);
04407         CtlspFormulaIncrementRefCount(right);
04408         tmpf2 = Ctlsp_LtlFormulaHashIntoUniqueTable(tmpf1, Utable);
04409         return tmpf2;
04410       }
04411     }
04412 
04413     /* r=>lr : (ll * lr) R r  ==  ll R r */
04414     if (left->type == Ctlsp_AND_c) {
04415       if (Ctlsp_LtlFormulaSimplyImply(right, left->right)) {
04416         tmpf1 = FormulaCreateWithType(Ctlsp_R_c);
04417         tmpf1->left = left->left;
04418         tmpf1->right = right;
04419         CtlspFormulaIncrementRefCount(left->left);
04420         CtlspFormulaIncrementRefCount(right);
04421         tmpf2 = Ctlsp_LtlFormulaHashIntoUniqueTable(tmpf1, Utable);
04422         return tmpf2;
04423       }
04424     }
04425 
04426 
04427     /* return  (left R right) */
04428     tmpf1 = FormulaCreateWithType(Ctlsp_R_c);
04429     tmpf1->left = left;
04430     tmpf1->right = right;
04431     CtlspFormulaIncrementRefCount(left);
04432     CtlspFormulaIncrementRefCount(right);
04433     tmpf2 = Ctlsp_LtlFormulaHashIntoUniqueTable(tmpf1, Utable);
04434     return tmpf2;
04435 
04436   case Ctlsp_X_c:
04437 
04438     /* X(TRUE) == TRUE */
04439     /* X(FALSE) == FALSE */
04440     if (left->type == Ctlsp_TRUE_c || left->type == Ctlsp_FALSE_c)
04441       return left;
04442 
04443     /* X(FGorGF) == FGorGF */
04444     if (Ctlsp_LtlFormulaIsFGorGF(left))
04445       return left;
04446 
04447     /* X(ll + FGorGF lrrr) == X(ll) + FGorGF lrrr */
04448     /* X(ll * FGorGF lrrr) == X(ll) * FGorGF lrrr */
04449     if (left->type == Ctlsp_AND_c || left->type == Ctlsp_OR_c) {
04450       if (Ctlsp_LtlFormulaIsFGorGF(left->right)) {
04451         tmpf1 = FormulaCreateWithType(Ctlsp_X_c);
04452         tmpf1->left = left->left;
04453         CtlspFormulaIncrementRefCount(left->left);
04454         tmpf1 = Ctlsp_LtlFormulaHashIntoUniqueTable(tmpf1, Utable);
04455 
04456         tmpf2 = FormulaCreateWithType(left->type);
04457         tmpf2->left = tmpf1;
04458         tmpf2->right = left->right;
04459         CtlspFormulaIncrementRefCount(tmpf1);
04460         CtlspFormulaIncrementRefCount(left->right);
04461         tmpf2 = Ctlsp_LtlFormulaHashIntoUniqueTable(tmpf2, Utable);
04462         return tmpf2;
04463       }
04464     }
04465 
04466     /* X(FGorGF llrr + lr) ==  FGorGF llrr + X(lr) */
04467     /* X(FGorGF llrr * lr) ==  FGorGF llrr * X(lr) */
04468     if (left->type == Ctlsp_AND_c || left->type == Ctlsp_OR_c) {
04469       if (Ctlsp_LtlFormulaIsFGorGF(left->left)) {
04470         tmpf1 = FormulaCreateWithType(Ctlsp_X_c);
04471         tmpf1->left = left->right;
04472         CtlspFormulaIncrementRefCount(left->right);
04473         tmpf1 = Ctlsp_LtlFormulaHashIntoUniqueTable(tmpf1, Utable);
04474 
04475         tmpf2 = FormulaCreateWithType(left->type);
04476         tmpf2->left = left->left;
04477         tmpf2->right = tmpf1;
04478         CtlspFormulaIncrementRefCount(left->left);
04479         CtlspFormulaIncrementRefCount(tmpf1);
04480         tmpf2 = Ctlsp_LtlFormulaHashIntoUniqueTable(tmpf2, Utable);
04481         return tmpf2;
04482       }
04483     }
04484 
04485     /* return X(left) */
04486     tmpf1 = FormulaCreateWithType(Ctlsp_X_c);
04487     tmpf1->left = left;
04488     CtlspFormulaIncrementRefCount(left);
04489     tmpf2 = Ctlsp_LtlFormulaHashIntoUniqueTable(tmpf1, Utable);
04490     return tmpf2;
04491 
04492   case Ctlsp_NOT_c:
04493 
04494     /* return !(left) */
04495     tmpf1 = FormulaCreateWithType(Ctlsp_NOT_c);
04496     tmpf1->left = left;
04497     CtlspFormulaIncrementRefCount(left);
04498     tmpf2 = Ctlsp_LtlFormulaHashIntoUniqueTable(tmpf1, Utable);
04499     return tmpf2;
04500 
04501   default:
04502     assert(0);
04503   }
04504   return NIL(Ctlsp_Formula_t);
04505 }
04506 
04519 void
04520 CtlspFormulaIncrementRefCount(
04521   Ctlsp_Formula_t *formula)
04522 {
04523   if(formula!=NIL(Ctlsp_Formula_t)) {
04524     ++(formula->refCount);
04525   }
04526 }
04527 
04542 void
04543 CtlspFormulaDecrementRefCount(
04544   Ctlsp_Formula_t *formula)
04545 {
04546   if(formula!=NIL(Ctlsp_Formula_t)) {
04547     assert(formula->refCount>0);
04548     if(--(formula->refCount) == 0)
04549       CtlspFormulaFree(formula);
04550   }
04551 }
04561 void
04562 CtlspFormulaAddToGlobalArray(
04563   Ctlsp_Formula_t * formula)
04564 {
04565   array_insert_last(Ctlsp_Formula_t *, globalFormulaArray, formula);
04566 }
04567 
04582 void
04583 CtlspFormulaFree(
04584   Ctlsp_Formula_t * formula)
04585 {
04586   if (formula != NIL(Ctlsp_Formula_t)) {
04587 
04588     /*
04589      * Free any fields that are not NULL.
04590      */
04591 
04592     if (formula->type == Ctlsp_ID_c){
04593       FREE(formula->left);
04594       FREE(formula->right);
04595     }
04596     else {
04597       if (formula->left  != NIL(Ctlsp_Formula_t)) {
04598         CtlspFormulaDecrementRefCount(formula->left);
04599       }
04600       if (formula->right != NIL(Ctlsp_Formula_t)) {
04601         CtlspFormulaDecrementRefCount(formula->right);
04602       }
04603     }
04604 
04605     if (formula->states != NIL(mdd_t))
04606       mdd_free(formula->states);
04607     if (formula->underapprox != NIL(mdd_t))
04608       mdd_free(formula->underapprox);
04609     if (formula->overapprox != NIL(mdd_t))
04610       mdd_free(formula->overapprox);
04611 
04612     if (formula->dbgInfo.data != NIL(void)){
04613       (*formula->dbgInfo.freeFn)(formula);
04614     }
04615 
04616     FREE(formula);
04617   }
04618 }
04619 
04620 
04636 int
04637 CtlspStringChangeValueStrToBinString(
04638   char *value,
04639   char *binValueStr,
04640   int  interval)
04641 {
04642   int i;
04643   long int num, mask;
04644   double maxNum;
04645   char *ptr;
04646 
04647   mask = 1;
04648   maxNum = pow(2.0,(double)interval);
04649   errno = 0;
04650 
04651   if(value[0] == 'b'){
04652     if ((int)strlen(value)-1 == interval){
04653                         for(i=1;i<=interval;i++){
04654         if (value[i] == '0' || value[i] == '1'){
04655           binValueStr[i-1] =  value[i];
04656         }else{
04657           return 0;
04658         }
04659       }
04660       binValueStr[interval] = '\0';
04661     }else{
04662       return 0;
04663     }
04664   }else if (value[0] == 'x'){
04665     for(i=1; i < (int)strlen(value); i++){
04666       if (!isxdigit((int)value[i])){
04667         return 0;
04668       }
04669     }
04670     num = strtol(++value,&ptr,16);
04671     if (errno) return 0;
04672     if (num >= maxNum) return 0;
04673     for(i=0;i<interval;i++){
04674       if(num & (mask<<i)) binValueStr[interval-i-1] = '1';
04675       else binValueStr[interval-i-1] = '0';
04676     }
04677     binValueStr[interval] = '\0';
04678   }else{
04679     for(i=0;i<(int)strlen(value);i++){
04680       if (!isdigit((int)value[i])){
04681         return 0;
04682       }
04683     }
04684     num = strtol(value,&ptr,0);
04685     if (errno) return 0;
04686     if (num >= maxNum) return 0;
04687     mask = 1;
04688     for(i=0;i<interval;i++){
04689       if(num & (mask<<i)) binValueStr[interval-i-1] = '1';
04690       else binValueStr[interval-i-1] = '0';
04691     }
04692     binValueStr[interval] = '\0';
04693   }
04694 
04695   return(1);
04696 }
04697 
04698 
04711 void
04712 CtlspChangeBracket(
04713   char *inStr)
04714 {
04715   int i, j;
04716   char *str;
04717 
04718   j = 0;
04719   for (i=0;i<(int)strlen(inStr)+1;i++){
04720     if (inStr[i] != ' '){
04721       inStr[i-j] = inStr[i];
04722     }else{
04723       j++;
04724     }
04725   }
04726 
04727   if (changeBracket == 0)
04728     return;
04729 
04730   str = strchr(inStr,'[');
04731   if (str == NULL) return;
04732 
04733   *str = '<';
04734   str = strchr(inStr,']');
04735   *str = '>';
04736 }
04737 
04738 
04752 char *
04753 CtlspGetVectorInfoFromStr(
04754   char *str,
04755   int  *start,
04756   int  *end,
04757   int  *interval,
04758   int  *inc)
04759 {
04760   char *str1, *str2, *str3;
04761   char *startStr, *endStr;
04762   char *name, *ptr;
04763 
04764   str1 = strchr(str,'[');
04765   str2 = strchr(str,':');
04766   str3 = strchr(str,']');
04767   startStr = ALLOC(char, str2-str1);
04768   endStr = ALLOC(char, str3-str2);
04769   name = ALLOC(char, str1-str+1);
04770 
04771   (void) strncpy(name, str, str1-str);
04772   (void) strncpy(startStr, str1+1, str2-str1-1);
04773   (void) strncpy(endStr, str2+1, str3-str2-1);
04774 
04775   startStr[str2-str1-1] = '\0';
04776   endStr[str3-str2-1] = '\0';
04777   name[str1-str] = '\0';
04778   *start = strtol(startStr,&ptr,0);
04779   *end = strtol(endStr,&ptr,0);
04780   if(*start > *end){
04781       *inc = -1;
04782       *interval = *start - *end + 1;
04783   } else {
04784       *inc = 1;
04785       *interval = *end - *start + 1;
04786   }
04787   FREE(startStr);
04788   FREE(endStr);
04789   return name;
04790 }
04791 
04804 int
04805 CtlspFormulaAddToTable(
04806   char *name,
04807   Ctlsp_Formula_t *formula,
04808   st_table *macroTable)
04809 {
04810   if(macroTable == NIL(st_table)){
04811     macroTable = st_init_table(strcmp, st_strhash);
04812   }
04813   if(st_is_member(macroTable, name)){
04814     return 0;
04815   }
04816   st_insert(macroTable, name, (char *)formula);
04817   return 1;
04818 }
04819 
04820 
04832 Ctlsp_Formula_t *
04833 CtlspFormulaFindInTable(
04834   char *name,
04835   st_table *macroTable)
04836 {
04837   Ctlsp_Formula_t *formula;
04838   if (st_lookup(macroTable, name, &formula)){
04839     return (Ctlsp_FormulaDup(formula));
04840   }else{
04841     return NIL(Ctlsp_Formula_t);
04842   }
04843 }
04844 
04856 Ctlsp_FormulaClass
04857 CtlspCheckClassOfExistentialFormulaRecur(
04858   Ctlsp_Formula_t *formula,
04859   boolean parity)
04860 {
04861   Ctlsp_FormulaClass result;
04862 
04863   Ctlsp_FormulaType formulaType = Ctlsp_FormulaReadType(formula);
04864   Ctlsp_Formula_t *rightFormula, *leftFormula;
04865   Ctlsp_FormulaClass resultLeft, resultRight, tempResult, currentClass;
04866 
04867   /* Depending on the formula type, create result or recur */
04868   switch (formulaType) {
04869   case Ctlsp_E_c:
04870     leftFormula = Ctlsp_FormulaReadLeftChild(formula);
04871     resultLeft = CtlspCheckClassOfExistentialFormulaRecur(leftFormula, parity);
04872       resultRight = Ctlsp_QuantifierFree_c;
04873     tempResult = CtlspResolveClass(resultLeft, resultRight);
04874     if (!parity){
04875       currentClass = Ctlsp_ECTL_c;
04876     }else{
04877       currentClass = Ctlsp_ACTL_c;
04878     }
04879     result = CtlspResolveClass(currentClass, tempResult);
04880     break;
04881   case Ctlsp_A_c:
04882     /* The formula is supposed to be only existential */
04883     error_append("Inconsistency detected in function ");
04884     error_append("FormulaTestIsForallQuantifier\n");
04885     result = Ctlsp_invalid_c;
04886     break;
04887   case Ctlsp_OR_c:
04888   case Ctlsp_AND_c:
04889     rightFormula = Ctlsp_FormulaReadRightChild(formula);
04890     leftFormula = Ctlsp_FormulaReadLeftChild(formula);
04891     resultLeft = CtlspCheckClassOfExistentialFormulaRecur(leftFormula, parity);
04892     resultRight = CtlspCheckClassOfExistentialFormulaRecur(rightFormula, parity);
04893     result = CtlspResolveClass(resultLeft, resultRight);
04894     break;
04895   case Ctlsp_NOT_c:
04896     parity = !parity;
04897     leftFormula = Ctlsp_FormulaReadLeftChild(formula);
04898     result = CtlspCheckClassOfExistentialFormulaRecur(leftFormula, parity);
04899     break;
04900   case Ctlsp_ID_c:
04901   case Ctlsp_TRUE_c:
04902   case Ctlsp_FALSE_c:
04903      result = Ctlsp_QuantifierFree_c;
04904      break;
04905   case Ctlsp_Cmp_c:
04906     result = Ctlsp_Mixed_c;
04907     break;
04908   default:
04909     error_append("Unexpected operator detected.");
04910     result = Ctlsp_invalid_c;
04911     break;
04912   }
04913 
04914   return result;
04915 
04916 } /* End of FormulaTestIsForallQuantifier */
04917 
04929 Ctlsp_FormulaClass
04930 CtlspResolveClass(
04931   Ctlsp_FormulaClass class1,
04932   Ctlsp_FormulaClass class2)
04933 {
04934   Ctlsp_FormulaClass result;
04935 
04936   if ((class1 == Ctlsp_Mixed_c) || (class2 == Ctlsp_Mixed_c)){
04937     result = Ctlsp_Mixed_c;
04938   }else if (class1 == Ctlsp_QuantifierFree_c){
04939     result = class2;
04940   }else if (class2 == Ctlsp_QuantifierFree_c){
04941     result = class1;
04942   }else if (class1 == class2){
04943     result = class1;
04944   }else{
04945     result = Ctlsp_Mixed_c;
04946   }
04947   return result;
04948 }
04949 
04963 Ctlp_Formula_t *
04964 CtlspFormulaConvertToCTL(
04965   Ctlsp_Formula_t *formula)
04966 {
04967   Ctlp_Formula_t *newNode, *leftNode, *rightNode;
04968   Ctlsp_Formula_t *childNode;
04969   char *variableNameCopy, *valueNameCopy;
04970 
04971   if (formula == NIL(Ctlsp_Formula_t)) {
04972     return NIL(Ctlp_Formula_t);
04973   }
04974   /*
04975    * Recursively convert each subformula.
04976    */
04977   switch(formula->type) {
04978   case Ctlsp_E_c:
04979     childNode = formula->left;
04980     switch(childNode->type) {
04981     case Ctlsp_X_c:
04982       newNode = Ctlp_FormulaCreate(Ctlp_EX_c,
04983                                    CtlspFormulaConvertToCTL(childNode->left),
04984                                    NIL(Ctlsp_Formula_t));
04985       break;
04986     case Ctlsp_F_c:
04987       newNode = Ctlp_FormulaCreate(Ctlp_EF_c,
04988                                    CtlspFormulaConvertToCTL(childNode->left),
04989                                    NIL(Ctlsp_Formula_t));
04990       break;
04991     case Ctlsp_U_c:
04992       newNode = Ctlp_FormulaCreate(Ctlp_EU_c,
04993                                    CtlspFormulaConvertToCTL(childNode->left),
04994                                    CtlspFormulaConvertToCTL(childNode->right));
04995       break;
04996     case Ctlsp_R_c:
04997       /* E(f R g) => !A( !f U !g) */
04998 
04999       leftNode  =  Ctlp_FormulaCreate(Ctlp_NOT_c,
05000                    CtlspFormulaConvertToCTL(childNode->left),
05001                    NIL(Ctlsp_Formula_t));
05002       rightNode =  Ctlp_FormulaCreate(Ctlp_NOT_c,
05003                    CtlspFormulaConvertToCTL(childNode->right),
05004                    NIL(Ctlsp_Formula_t));
05005 
05006       newNode = Ctlp_FormulaCreate(Ctlp_AU_c, leftNode, rightNode);
05007       newNode = Ctlp_FormulaCreate(Ctlp_NOT_c, newNode, NIL(Ctlsp_Formula_t));
05008 
05009       break;
05010     case Ctlsp_W_c:
05011       /* E(f W g) => !A(!g U !(f + g)) */
05012 
05013       leftNode  =  Ctlp_FormulaCreate(Ctlp_NOT_c,
05014                    CtlspFormulaConvertToCTL(childNode->right),
05015                    NIL(Ctlsp_Formula_t));
05016       rightNode =  Ctlp_FormulaCreate(Ctlp_OR_c,
05017                    CtlspFormulaConvertToCTL(childNode->left),
05018                    CtlspFormulaConvertToCTL(childNode->right));
05019       rightNode =  Ctlp_FormulaCreate(Ctlp_NOT_c, rightNode,
05020                    NIL(Ctlsp_Formula_t));
05021 
05022       newNode = Ctlp_FormulaCreate(Ctlp_AU_c, leftNode, rightNode);
05023       newNode = Ctlp_FormulaCreate(Ctlp_NOT_c, newNode, NIL(Ctlsp_Formula_t));
05024 
05025       break;
05026     case Ctlsp_G_c:
05027       newNode = Ctlp_FormulaCreate(Ctlp_EG_c,
05028                                    CtlspFormulaConvertToCTL(childNode->left),
05029                                    NIL(Ctlsp_Formula_t));
05030       break;
05031     default:
05032       fail("Unexpected type");
05033     } /* switch: childNode->type */
05034     break;
05035   case Ctlsp_A_c:
05036     childNode = formula->left;
05037     switch(childNode->type) {
05038     case Ctlsp_X_c:
05039       newNode = Ctlp_FormulaCreate(Ctlp_AX_c,
05040                                    CtlspFormulaConvertToCTL(childNode->left),
05041                                    NIL(Ctlsp_Formula_t));
05042       break;
05043     case Ctlsp_F_c:
05044       newNode = Ctlp_FormulaCreate(Ctlp_AF_c,
05045                                    CtlspFormulaConvertToCTL(childNode->left),
05046                                    NIL(Ctlsp_Formula_t));
05047       break;
05048     case Ctlsp_U_c:
05049       newNode = Ctlp_FormulaCreate(Ctlp_AU_c,
05050                                    CtlspFormulaConvertToCTL(childNode->left),
05051                                    CtlspFormulaConvertToCTL(childNode->right));
05052       break;
05053     case Ctlsp_R_c:
05054       /* A(f R g) => !E( !f U !g) */
05055 
05056       leftNode  =  Ctlp_FormulaCreate(Ctlp_NOT_c,
05057                    CtlspFormulaConvertToCTL(childNode->left),
05058                    NIL(Ctlsp_Formula_t));
05059       rightNode =  Ctlp_FormulaCreate(Ctlp_NOT_c,
05060                    CtlspFormulaConvertToCTL(childNode->right),
05061                    NIL(Ctlsp_Formula_t));
05062 
05063       newNode = Ctlp_FormulaCreate(Ctlp_EU_c, leftNode, rightNode);
05064       newNode = Ctlp_FormulaCreate(Ctlp_NOT_c, newNode, NIL(Ctlsp_Formula_t));
05065 
05066       break;
05067     case Ctlsp_W_c:
05068       /* A(f W g) => !E(!g U !(f + g)) */
05069 
05070       leftNode  =  Ctlp_FormulaCreate(Ctlp_NOT_c,
05071                    CtlspFormulaConvertToCTL(childNode->right),
05072                    NIL(Ctlsp_Formula_t));
05073       rightNode =  Ctlp_FormulaCreate(Ctlp_OR_c,
05074                    CtlspFormulaConvertToCTL(childNode->left),
05075                    CtlspFormulaConvertToCTL(childNode->right));
05076       rightNode =  Ctlp_FormulaCreate(Ctlp_NOT_c, rightNode,
05077                    NIL(Ctlsp_Formula_t));
05078 
05079       newNode = Ctlp_FormulaCreate(Ctlp_EU_c, leftNode, rightNode);
05080       newNode = Ctlp_FormulaCreate(Ctlp_NOT_c, newNode, NIL(Ctlsp_Formula_t));
05081 
05082       break;
05083     case Ctlsp_G_c:
05084       newNode = Ctlp_FormulaCreate(Ctlp_AG_c,
05085                                    CtlspFormulaConvertToCTL(childNode->left),
05086                                    NIL(Ctlsp_Formula_t));
05087       break;
05088     default:
05089       fail("Unexpected type");
05090     } /* switch: childNode->type */
05091     break;
05092 
05093   case Ctlsp_ID_c:
05094     /* Make a copy of the name, and create a new formula. */
05095     variableNameCopy = util_strsav((char *)(formula->left));
05096     valueNameCopy = util_strsav((char *)(formula->right));
05097     newNode = Ctlp_FormulaCreate(Ctlp_ID_c, variableNameCopy, valueNameCopy);
05098     break;
05099 
05100   case Ctlsp_THEN_c:
05101     newNode = Ctlp_FormulaCreate(Ctlp_THEN_c,
05102                                  CtlspFormulaConvertToCTL(formula->left) ,
05103                                  CtlspFormulaConvertToCTL(formula->right) );
05104     break;
05105   case Ctlsp_OR_c:
05106     newNode = Ctlp_FormulaCreate(Ctlp_OR_c,
05107                                  CtlspFormulaConvertToCTL(formula->left) ,
05108                                  CtlspFormulaConvertToCTL(formula->right) );
05109     break;
05110   case Ctlsp_AND_c:
05111     newNode = Ctlp_FormulaCreate(Ctlp_AND_c,
05112                                  CtlspFormulaConvertToCTL(formula->left) ,
05113                                  CtlspFormulaConvertToCTL(formula->right) );
05114     break;
05115   case Ctlsp_NOT_c:
05116     newNode = Ctlp_FormulaCreate(Ctlp_NOT_c,
05117                                  CtlspFormulaConvertToCTL(formula->left) ,
05118                                  CtlspFormulaConvertToCTL(formula->right) );
05119     break;
05120   case Ctlsp_XOR_c:
05121     newNode = Ctlp_FormulaCreate(Ctlp_XOR_c,
05122                                  CtlspFormulaConvertToCTL(formula->left) ,
05123                                  CtlspFormulaConvertToCTL(formula->right) );
05124     break;
05125   case Ctlsp_EQ_c:
05126     newNode = Ctlp_FormulaCreate(Ctlp_EQ_c,
05127                                  CtlspFormulaConvertToCTL(formula->left) ,
05128                                  CtlspFormulaConvertToCTL(formula->right) );
05129     break;
05130   case Ctlsp_TRUE_c:
05131     newNode = Ctlp_FormulaCreate(Ctlp_TRUE_c,
05132                                  CtlspFormulaConvertToCTL(formula->left) ,
05133                                  CtlspFormulaConvertToCTL(formula->right) );
05134     break;
05135   case Ctlsp_FALSE_c:
05136     newNode = Ctlp_FormulaCreate(Ctlp_FALSE_c,
05137                                  CtlspFormulaConvertToCTL(formula->left) ,
05138                                  CtlspFormulaConvertToCTL(formula->right) );
05139     break;
05140   default:
05141     fail("Unexpected type");
05142   }
05143 
05144   return newNode;
05145 } /* CtlspFormulaConvertToCTL() */
05146 
05147 
05159 Ctlsp_Formula_t *
05160 CtlspFunctionOr(
05161   Ctlsp_Formula_t *left,
05162   Ctlsp_Formula_t *right)
05163 {
05164   Ctlsp_Formula_t *result;
05165 
05166   if((Ctlsp_FormulaReadType(left)  == Ctlsp_TRUE_c) ||
05167      (Ctlsp_FormulaReadType(right) == Ctlsp_TRUE_c)){
05168     result = Ctlsp_FormulaCreate(Ctlsp_TRUE_c, NIL(Ctlsp_Formula_t),
05169                                  NIL(Ctlsp_Formula_t));;
05170   } else
05171     if(Ctlsp_FormulaReadType(left) == Ctlsp_FALSE_c){
05172       result = right;
05173     } else
05174       if(Ctlsp_FormulaReadType(right) == Ctlsp_FALSE_c){
05175         result = left;
05176       } else
05177         result = Ctlsp_FormulaCreate(Ctlsp_OR_c, left, right);
05178 
05179   return result;
05180 }
05181 
05193 Ctlsp_Formula_t *
05194 CtlspFunctionAnd(
05195   Ctlsp_Formula_t *left,
05196   Ctlsp_Formula_t *right)
05197 {
05198   Ctlsp_Formula_t *result;
05199 
05200   if((Ctlsp_FormulaReadType(left)  == Ctlsp_FALSE_c) ||
05201      (Ctlsp_FormulaReadType(right) == Ctlsp_FALSE_c)){
05202     result = Ctlsp_FormulaCreate(Ctlsp_FALSE_c, NIL(Ctlsp_Formula_t),
05203                                  NIL(Ctlsp_Formula_t));;
05204   } else
05205     if(Ctlsp_FormulaReadType(left) == Ctlsp_TRUE_c){
05206       result = right;
05207     } else
05208       if(Ctlsp_FormulaReadType(right) == Ctlsp_TRUE_c){
05209         result = left;
05210       } else
05211         result = Ctlsp_FormulaCreate(Ctlsp_AND_c, left, right);
05212 
05213   return result;
05214 }
05215 
05227 Ctlsp_Formula_t *
05228 CtlspFunctionThen(
05229   Ctlsp_Formula_t *left,
05230   Ctlsp_Formula_t *right)
05231 {
05232   Ctlsp_Formula_t *result;
05233 
05234   if((Ctlsp_FormulaReadType(left)  == Ctlsp_TRUE_c) &&
05235      (Ctlsp_FormulaReadType(right) == Ctlsp_FALSE_c)){
05236     result = Ctlsp_FormulaCreate(Ctlsp_FALSE_c, NIL(Ctlsp_Formula_t),
05237                                  NIL(Ctlsp_Formula_t));
05238   } else
05239     if(Ctlsp_FormulaReadType(left) == Ctlsp_FALSE_c){
05240       result = Ctlsp_FormulaCreate(Ctlsp_TRUE_c, NIL(Ctlsp_Formula_t),
05241                                    NIL(Ctlsp_Formula_t));
05242     } else
05243       if((Ctlsp_FormulaReadType(left)  == Ctlsp_TRUE_c) &&
05244          (Ctlsp_FormulaReadType(right) == Ctlsp_TRUE_c)){
05245         result = Ctlsp_FormulaCreate(Ctlsp_TRUE_c, NIL(Ctlsp_Formula_t),
05246                                      NIL(Ctlsp_Formula_t));
05247       } else
05248         result = Ctlsp_FormulaCreate(Ctlsp_THEN_c, left, right);
05249 
05250   return result;
05251 }
05252 
05253 /*---------------------------------------------------------------------------*/
05254 /* Definition of static functions                                            */
05255 /*---------------------------------------------------------------------------*/
05256 
05268 static Ctlsp_Formula_t *
05269 FormulaCreateWithType(
05270   Ctlsp_FormulaType type)
05271 {
05272   return (Ctlsp_FormulaCreate(type, NIL(Ctlsp_Formula_t), NIL(Ctlsp_Formula_t)));
05273 }
05274 
05275 
05289 static int
05290 FormulaCompare(
05291   const char *key1,
05292   const char *key2)
05293 {
05294   Ctlsp_Formula_t *formula1 = (Ctlsp_Formula_t *) key1;
05295   Ctlsp_Formula_t *formula2 = (Ctlsp_Formula_t *) key2;
05296 
05297   assert(key1 != NIL(char));
05298   assert(key2 != NIL(char));
05299 
05300 
05301   if(formula1->type != formula2->type) {
05302     return -1;
05303   }
05304   if(formula1->type == Ctlsp_ID_c) {
05305     if(strcmp((char *) (formula1->left), (char *) (formula2->left)) ||
05306        strcmp((char *) (formula1->right), (char *) (formula2->right))) {
05307       return -1;
05308     } else
05309       return 0;
05310   } else {
05311     if(formula1->left != formula2->left)
05312       return -1;
05313     if(formula1->right != formula2->right)
05314       return -1;
05315     if (formula1->type == Ctlsp_Cmp_c &&
05316         formula1->compareValue != formula2->compareValue) {
05317       return -1;
05318     }
05319     return 0;
05320   }
05321 }
05322 
05337 static int
05338 FormulaHash(
05339   char *key,
05340   int modulus)
05341 {
05342   char *hashString;
05343   int hashValue;
05344   Ctlsp_Formula_t *formula = (Ctlsp_Formula_t *) key;
05345 
05346   if(formula->type==Ctlsp_ID_c) {
05347     hashString = util_strcat3((char *) (formula->left), (char *)
05348                               (formula->right), "");
05349     hashValue = st_strhash(hashString, modulus);
05350     FREE(hashString);
05351     return hashValue;
05352   }
05353   return (int) ((((unsigned long) formula->left >>2) +
05354                  ((unsigned long) formula->right >>2)) % modulus);
05355 }
05356 
05374 static Ctlsp_Formula_t *
05375 FormulaHashIntoUniqueTable(
05376   Ctlsp_Formula_t *formula,
05377   st_table *uniqueTable)
05378 {
05379   Ctlsp_Formula_t *uniqueFormula, *uniqueLeft, *uniqueRight;
05380 
05381   if(formula == NIL(Ctlsp_Formula_t))
05382     return NIL(Ctlsp_Formula_t);
05383   if(st_lookup(uniqueTable, formula, &uniqueFormula)) {
05384     return uniqueFormula;
05385   }
05386   else {
05387     if(formula->type == Ctlsp_ID_c) {
05388       st_insert(uniqueTable, (char *) formula, (char *) formula);
05389       return formula;
05390     }
05391     else {
05392       uniqueLeft = FormulaHashIntoUniqueTable(formula->left, uniqueTable);
05393       if(uniqueLeft != NIL(Ctlsp_Formula_t))
05394         if(uniqueLeft != formula->left) {
05395           CtlspFormulaDecrementRefCount(formula->left);
05396           formula->left = uniqueLeft;
05397           CtlspFormulaIncrementRefCount(formula->left);
05398         }
05399       uniqueRight = FormulaHashIntoUniqueTable(formula->right, uniqueTable);
05400       if(uniqueRight != NIL(Ctlsp_Formula_t))
05401         if(uniqueRight != formula->right) {
05402           CtlspFormulaDecrementRefCount(formula->right);
05403           formula->right = uniqueRight;
05404           CtlspFormulaIncrementRefCount(formula->right);
05405         }
05406       if(st_lookup(uniqueTable, formula, &uniqueFormula)) {
05407         return uniqueFormula;
05408       }
05409       else {
05410         st_insert(uniqueTable, (char *) formula, (char *) formula);
05411         return formula;
05412       }
05413     }
05414   }
05415 }
05416 
05430 static Ctlsp_Formula_t *
05431 createSNFnode(
05432   Ctlsp_Formula_t *formula,
05433   array_t         *formulaArray,
05434   int             *index)
05435 {
05436   Ctlsp_Formula_t *newNode;
05437 
05438   if(!Ctlsp_LtlFormulaIsPropositional(formula)){
05439     newNode  = Ctlsp_FormulaCreate(Ctlsp_ID_c, util_strcat3(" SNFx","_", util_inttostr((*index)++)),
05440                                    (void *)util_strsav("1"));
05441     Ctlsp_LtlTranslateIntoSNFRecursive(newNode, formula, formulaArray, index);
05442     return newNode;
05443   } else {
05444     return Ctlsp_FormulaDup(formula);
05445   }
05446 
05447 }