VIS
|
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 }