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