VIS
|
00001 00037 #include "fsmInt.h" 00038 00039 static char rcsid[] UNUSED = "$Id: fsmFair.c,v 1.28 2003/01/22 18:44:20 jinh Exp $"; 00040 00041 /*---------------------------------------------------------------------------*/ 00042 /* Constant declarations */ 00043 /*---------------------------------------------------------------------------*/ 00044 00045 00046 /*---------------------------------------------------------------------------*/ 00047 /* Type declarations */ 00048 /*---------------------------------------------------------------------------*/ 00049 00050 00051 /*---------------------------------------------------------------------------*/ 00052 /* Structure declarations */ 00053 /*---------------------------------------------------------------------------*/ 00054 00062 typedef struct FairnessConjunctStruct { 00063 Ctlp_Formula_t *finallyInf; /* states to visit infinitely often */ 00064 Ctlp_Formula_t *globallyInf; /* states to visit almost always */ 00065 } FairnessConjunct_t; 00066 00067 00068 /*---------------------------------------------------------------------------*/ 00069 /* Variable declarations */ 00070 /*---------------------------------------------------------------------------*/ 00071 00072 00073 /*---------------------------------------------------------------------------*/ 00074 /* Macro declarations */ 00075 /*---------------------------------------------------------------------------*/ 00076 00077 00080 /*---------------------------------------------------------------------------*/ 00081 /* Static function prototypes */ 00082 /*---------------------------------------------------------------------------*/ 00083 00084 static FairnessConjunct_t * FairnessReadConjunct(Fsm_Fairness_t *fairness, int i, int j); 00085 static mdd_t * FsmObtainStatesSatisfyingFormula(Fsm_Fsm_t *fsm, Ctlp_Formula_t *formula, array_t *careSetArray, Mc_VerbosityLevel verbosity, Mc_DcLevel dcLevel); 00086 00090 /*---------------------------------------------------------------------------*/ 00091 /* Definition of exported functions */ 00092 /*---------------------------------------------------------------------------*/ 00093 00118 Fsm_Fairness_t * 00119 Fsm_FsmReadFairnessConstraint( 00120 Fsm_Fsm_t *fsm) 00121 { 00122 return (fsm->fairnessInfo.constraint); 00123 } 00124 00125 mdd_t * 00126 Fsm_FsmReadFairnessStates(Fsm_Fsm_t *fsm) 00127 { 00128 return(fsm->fairnessInfo.states); 00129 } 00130 00131 00158 mdd_t * 00159 Fsm_FsmComputeFairStates( 00160 Fsm_Fsm_t *fsm, 00161 array_t *careSetArray, 00162 int verbosity, 00163 int dcLevel, 00164 Mc_GSHScheduleType schedule, 00165 Mc_FwdBwdAnalysis direction, 00166 boolean useEarlyTermination) 00167 { 00168 mdd_manager *mddManager = Fsm_FsmReadMddManager(fsm); 00169 Fsm_Fairness_t *constraint = Fsm_FsmReadFairnessConstraint(fsm); 00170 00171 assert(constraint != NIL(Fsm_Fairness_t)); 00172 00173 if (fsm->fairnessInfo.states != NIL(mdd_t)) { 00174 /* Already computed. */ 00175 return mdd_dup(fsm->fairnessInfo.states); 00176 } else { 00177 /* Compute from scratch. */ 00178 mdd_t *fairStates; 00179 array_t *dbgArray = array_alloc(array_t *, 0); 00180 00181 /* No or trivial fairness constraint */ 00182 if (FsmFairnessConstraintIsDefault(constraint)) { 00183 array_t *onionRings; 00184 00185 fairStates = mdd_one(mddManager); 00186 00187 onionRings = array_alloc(mdd_t *, 1); 00188 array_insert_last(mdd_t *, onionRings, mdd_one(mddManager)); 00189 array_insert_last(array_t *, dbgArray, onionRings); 00190 00191 fsm->fairnessInfo.states = mdd_dup(fairStates); 00192 fsm->fairnessInfo.dbgArray = dbgArray; 00193 } else { 00194 mdd_t *oneMdd = mdd_one(mddManager); 00195 array_t *tmpCareSetArray; 00196 00197 if (careSetArray) { 00198 tmpCareSetArray = careSetArray; 00199 } else { 00200 /* oneMdd is default */ 00201 tmpCareSetArray = array_alloc(mdd_t *, 0); 00202 array_insert_last(mdd_t *, tmpCareSetArray, oneMdd); 00203 } 00204 00205 if (direction == McBwd_c) { 00206 mdd_t *initialStates; 00207 Mc_EarlyTermination_t *earlyTermination; 00208 int fixpoint = 1; 00209 00210 if (useEarlyTermination == TRUE) { 00211 initialStates = Fsm_FsmComputeInitialStates(fsm); 00212 earlyTermination = Mc_EarlyTerminationAlloc(McSome_c, initialStates); 00213 } else { 00214 initialStates = NIL(mdd_t); 00215 earlyTermination = MC_NO_EARLY_TERMINATION; 00216 } 00217 00218 fairStates = 00219 Mc_FsmEvaluateEGFormula(fsm, 00220 oneMdd, NIL(mdd_t), oneMdd, 00221 constraint, tmpCareSetArray, 00222 earlyTermination, NIL(array_t), 00223 Mc_None_c, &dbgArray, 00224 (Mc_VerbosityLevel) verbosity, 00225 (Mc_DcLevel) dcLevel, 00226 &fixpoint, schedule); 00227 if (useEarlyTermination == TRUE) { 00228 Mc_EarlyTerminationFree(earlyTermination); 00229 mdd_free(initialStates); 00230 } 00231 if (!fixpoint) { 00232 int i; 00233 array_t *mddArray; 00234 arrayForEachItem(array_t *, dbgArray, i, mddArray) { 00235 mdd_array_free(mddArray); 00236 } 00237 array_free(dbgArray); 00238 } else { 00239 fsm->fairnessInfo.states = mdd_dup(fairStates); 00240 fsm->fairnessInfo.dbgArray = dbgArray; 00241 } 00242 } else { 00243 fairStates = 00244 Mc_FsmEvaluateEHFormula(fsm, 00245 oneMdd, NIL(mdd_t), oneMdd, 00246 constraint, tmpCareSetArray, 00247 MC_NO_EARLY_TERMINATION, NIL(array_t), 00248 Mc_None_c, NIL(array_t *), 00249 (Mc_VerbosityLevel) verbosity, 00250 (Mc_DcLevel) dcLevel, 00251 NIL(boolean), schedule); 00252 array_free(dbgArray); 00253 } 00254 if (tmpCareSetArray != careSetArray) 00255 array_free(tmpCareSetArray); 00256 mdd_free(oneMdd); 00257 } 00258 00259 return fairStates; 00260 }/* compute from scratch*/ 00261 } 00262 00263 00282 Ctlp_Formula_t * 00283 Fsm_FairnessReadFinallyInfFormula( 00284 Fsm_Fairness_t *fairness, 00285 int i, 00286 int j) 00287 { 00288 FairnessConjunct_t *conjunct = FairnessReadConjunct(fairness, i, j); 00289 return (conjunct->finallyInf); 00290 } 00291 00292 00311 Ctlp_Formula_t * 00312 Fsm_FairnessReadGloballyInfFormula( 00313 Fsm_Fairness_t *fairness, 00314 int i, 00315 int j) 00316 { 00317 FairnessConjunct_t *conjunct = FairnessReadConjunct(fairness, i, j); 00318 return (conjunct->globallyInf); 00319 } 00320 00344 mdd_t * 00345 Fsm_FairnessObtainFinallyInfMdd( 00346 Fsm_Fairness_t *fairness, 00347 int i, 00348 int j, 00349 array_t *careSetArray, 00350 Mc_DcLevel dcLevel) 00351 { 00352 Ctlp_Formula_t *formula = Fsm_FairnessReadFinallyInfFormula(fairness, i, j); 00353 /* hard code verbosity to Mc_VerbosityNone */ 00354 return(FsmObtainStatesSatisfyingFormula(fairness->fsm, formula, careSetArray, 00355 McVerbosityNone_c, dcLevel)); 00356 } 00357 00358 00382 mdd_t * 00383 Fsm_FairnessObtainGloballyInfMdd( 00384 Fsm_Fairness_t *fairness, 00385 int i, 00386 int j, 00387 array_t *careSetArray, 00388 Mc_DcLevel dcLevel) 00389 { 00390 Ctlp_Formula_t *formula = Fsm_FairnessReadGloballyInfFormula(fairness, i, j); 00391 /* hard code verbosity to Mc_VerbosityNone */ 00392 return(FsmObtainStatesSatisfyingFormula(fairness->fsm, formula, careSetArray, 00393 McVerbosityNone_c, dcLevel)); 00394 00395 } 00396 00397 00411 boolean 00412 Fsm_FairnessTestIsStreett( 00413 Fsm_Fairness_t *fairness) 00414 { 00415 return (array_n(fairness->disjunctArray) == 1); 00416 } 00417 00418 00433 boolean 00434 Fsm_FairnessTestIsBuchi( 00435 Fsm_Fairness_t *fairness) 00436 { 00437 if (array_n(fairness->disjunctArray) != 1) { 00438 return (FALSE); 00439 } 00440 else { 00441 int j; 00442 array_t *disjunct = array_fetch(array_t *, fairness->disjunctArray, 0); 00443 00444 for (j = 0; j < array_n(disjunct); j++) { 00445 FairnessConjunct_t *conjunct = array_fetch(FairnessConjunct_t *, 00446 disjunct, j); 00447 if (conjunct->globallyInf != NIL(Ctlp_Formula_t)) { 00448 return (FALSE); 00449 } 00450 } 00451 return (TRUE); 00452 } 00453 } 00454 00455 00467 int 00468 Fsm_FairnessReadNumDisjuncts( 00469 Fsm_Fairness_t *fairness) 00470 { 00471 return (array_n(fairness->disjunctArray)); 00472 } 00473 00474 00485 int 00486 Fsm_FairnessReadNumConjunctsOfDisjunct( 00487 Fsm_Fairness_t *fairness, 00488 int i) 00489 { 00490 array_t *disjunct = array_fetch(array_t *, fairness->disjunctArray, i); 00491 00492 return (array_n(disjunct)); 00493 } 00494 00495 00514 array_t * 00515 Fsm_FsmReadDebugArray(Fsm_Fsm_t *fsm) 00516 { 00517 return (fsm->fairnessInfo.dbgArray); 00518 } 00519 00520 00533 void 00534 Fsm_FsmFairnessUpdate( 00535 Fsm_Fsm_t *fsm, 00536 array_t *formulaArray) 00537 { 00538 Fsm_Fairness_t *fairness = FsmFairnessAlloc(fsm); 00539 int j; 00540 /* 00541 * Interpret the array of CTL formulas as a set of Buchi conditions. 00542 * Hence, create a single disjunct, consisting of k conjuncts, where k is 00543 * the number of CTL formulas read in. The jth conjunct has the jth 00544 * formula as its finallyInf component, and NULL as its globallyInf 00545 * component. 00546 */ 00547 00548 for (j = 0; j < array_n(formulaArray); j++) { 00549 Ctlp_Formula_t *formula = array_fetch(Ctlp_Formula_t *, formulaArray, j); 00550 00551 FsmFairnessAddConjunct(fairness, formula, NIL(Ctlp_Formula_t), 0, j); 00552 } 00553 00554 /* 00555 * Remove any existing fairnessInfo associated with the FSM, and update 00556 * the fairnessInfo.constraint with the new fairness just read. 00557 */ 00558 FsmFsmFairnessInfoUpdate(fsm, NIL(mdd_t), fairness, NIL(array_t)); 00559 } 00560 00561 00562 /*---------------------------------------------------------------------------*/ 00563 /* Definition of internal functions */ 00564 /*---------------------------------------------------------------------------*/ 00565 00578 Fsm_Fairness_t * 00579 FsmFsmCreateDefaultFairnessConstraint( 00580 Fsm_Fsm_t *fsm) 00581 { 00582 Fsm_Fairness_t *fairness = FsmFairnessAlloc(fsm); 00583 Ctlp_Formula_t *trueFormula = Ctlp_FormulaCreate(Ctlp_TRUE_c, 00584 NIL(Ctlp_Formula_t), 00585 NIL(Ctlp_Formula_t)); 00586 00587 FsmFairnessAddConjunct(fairness, trueFormula, NIL(Ctlp_Formula_t), 0, 0); 00588 return fairness; 00589 } 00590 00591 00604 boolean 00605 FsmFairnessConstraintIsDefault( 00606 Fsm_Fairness_t *fairness) 00607 { 00608 array_t *disjuncts; 00609 array_t *conjuncts; 00610 FairnessConjunct_t *leaf; 00611 Ctlp_Formula_t *tautology; 00612 boolean result; 00613 00614 /* one disjunct */ 00615 disjuncts = fairness->disjunctArray; 00616 if(array_n(disjuncts) != 1) 00617 return FALSE; 00618 00619 /* one conjunct */ 00620 conjuncts = array_fetch(array_t *, disjuncts, 0); 00621 if(array_n(conjuncts) != 1) 00622 return FALSE; 00623 00624 /* set to (GF TRUE * FG NULL) */ 00625 leaf = array_fetch(FairnessConjunct_t *, conjuncts, 0); 00626 if(leaf->globallyInf != NIL(Ctlp_Formula_t)) 00627 return FALSE; 00628 00629 tautology = Ctlp_FormulaCreate(Ctlp_TRUE_c, NIL(Ctlp_Formula_t), 00630 NIL(Ctlp_Formula_t)); 00631 result = Ctlp_FormulaIdentical(tautology, leaf->finallyInf); 00632 Ctlp_FormulaFree(tautology); 00633 00634 return result; 00635 } 00636 00637 00650 void 00651 FsmFairnessFree( 00652 Fsm_Fairness_t *fairness) 00653 { 00654 int i; 00655 00656 for (i = 0; i < array_n(fairness->disjunctArray); i++) { 00657 int j; 00658 array_t *disjunct = array_fetch(array_t *, fairness->disjunctArray, i); 00659 00660 for (j = 0; j < array_n(disjunct); j++) { 00661 FairnessConjunct_t *conjunct = array_fetch(FairnessConjunct_t *, 00662 disjunct, j); 00663 Ctlp_FormulaFree(conjunct->finallyInf); 00664 Ctlp_FormulaFree(conjunct->globallyInf); 00665 FREE(conjunct); 00666 } 00667 array_free(disjunct); 00668 } 00669 array_free(fairness->disjunctArray); 00670 FREE(fairness); 00671 } 00672 00673 00686 Fsm_Fairness_t * 00687 FsmFairnessAlloc(Fsm_Fsm_t *fsm) 00688 { 00689 Fsm_Fairness_t *fairness = ALLOC(Fsm_Fairness_t, 1); 00690 00691 fairness->fsm = fsm; 00692 fairness->disjunctArray = array_alloc(array_t *, 0); 00693 00694 return fairness; 00695 } 00696 00697 00713 void 00714 FsmFairnessAddConjunct( 00715 Fsm_Fairness_t *fairness, 00716 Ctlp_Formula_t *finallyInf, 00717 Ctlp_Formula_t *globallyInf, 00718 int i, 00719 int j) 00720 { 00721 int k; 00722 array_t *disjunct; 00723 int numConjuncts; 00724 int numDisjuncts = array_n(fairness->disjunctArray); 00725 FairnessConjunct_t *conjunct = ALLOC(FairnessConjunct_t, 1); 00726 00727 assert((i >= 0) && (j >= 0)); 00728 00729 /* Get the array for row i. */ 00730 if (i >= numDisjuncts) { 00731 /* 00732 * i is out of range. Create a new disjunct, add it to the array, and 00733 * zero out the intervening entries. 00734 */ 00735 disjunct = array_alloc(FairnessConjunct_t *, 0); 00736 00737 /* Note that the array is dynamically extended. */ 00738 array_insert(array_t *, fairness->disjunctArray, i, disjunct); 00739 00740 /* Zero out the holes just created (if any). */ 00741 for (k = numDisjuncts; k < i; k++) { 00742 array_insert(array_t *, fairness->disjunctArray, k, NIL(array_t)); 00743 } 00744 } 00745 else { 00746 /* 00747 * i is in range. However, there may not be a non-NIL array at entry i 00748 * yet. 00749 */ 00750 disjunct = array_fetch(array_t *, fairness->disjunctArray, i); 00751 if (disjunct == NIL(array_t)) { 00752 disjunct = array_alloc(FairnessConjunct_t *, 0); 00753 array_insert(array_t *, fairness->disjunctArray, i, disjunct); 00754 } 00755 } 00756 00757 /* 00758 * Fill in the conjunct, and add it to the jth position of the ith row. If 00759 * holes are created, then zero them out. 00760 */ 00761 conjunct->finallyInf = finallyInf; 00762 conjunct->globallyInf = globallyInf; 00763 00764 array_insert(FairnessConjunct_t *, disjunct, j, conjunct); 00765 numConjuncts = array_n(disjunct); 00766 for (k = numConjuncts; k < j; k++) { 00767 array_insert(FairnessConjunct_t *, disjunct, k, NIL(FairnessConjunct_t)); 00768 } 00769 } 00770 00771 00783 void 00784 FsmFsmFairnessInfoUpdate( 00785 Fsm_Fsm_t *fsm, 00786 mdd_t *states, 00787 Fsm_Fairness_t *constraint, 00788 array_t *dbgArray) 00789 { 00790 array_t *oldDbgArray = fsm->fairnessInfo.dbgArray; 00791 00792 if (fsm->fairnessInfo.states != NIL(mdd_t)){ 00793 mdd_free(fsm->fairnessInfo.states); 00794 } 00795 fsm->fairnessInfo.states = states; 00796 00797 if (fsm->fairnessInfo.constraint != NIL(Fsm_Fairness_t)) { 00798 FsmFairnessFree(fsm->fairnessInfo.constraint); 00799 } 00800 fsm->fairnessInfo.constraint = constraint; 00801 00802 if (oldDbgArray != NIL(array_t)) { 00803 int i; 00804 for (i = 0; i < array_n(oldDbgArray); i++) { 00805 array_t *mddArray = array_fetch(array_t *, oldDbgArray, i); 00806 mdd_array_free(mddArray); 00807 } 00808 array_free(oldDbgArray); 00809 } 00810 fsm->fairnessInfo.dbgArray = dbgArray; 00811 } 00812 00813 00814 00815 /*---------------------------------------------------------------------------*/ 00816 /* Definition of static functions */ 00817 /*---------------------------------------------------------------------------*/ 00818 00832 static FairnessConjunct_t * 00833 FairnessReadConjunct( 00834 Fsm_Fairness_t *fairness, 00835 int i, 00836 int j) 00837 { 00838 array_t *disjunct; 00839 FairnessConjunct_t *conjunct; 00840 00841 assert((i >= 0) && (i < array_n(fairness->disjunctArray))); 00842 disjunct = array_fetch(array_t *, fairness->disjunctArray, i); 00843 00844 assert((j >= 0) && (j < array_n(disjunct))); 00845 conjunct = array_fetch(FairnessConjunct_t *, disjunct, j); 00846 00847 return conjunct; 00848 } 00849 00850 00867 static mdd_t * 00868 FsmObtainStatesSatisfyingFormula( 00869 Fsm_Fsm_t *fsm, 00870 Ctlp_Formula_t *formula, 00871 array_t *careSetArray, 00872 Mc_VerbosityLevel verbosity, 00873 Mc_DcLevel dcLevel) 00874 { 00875 if (formula == NIL(Ctlp_Formula_t)) { 00876 return (NIL(mdd_t)); 00877 } 00878 else { 00879 mdd_t *stateSet = Ctlp_FormulaObtainStates(formula); 00880 00881 if (stateSet != NIL(mdd_t)) { 00882 return stateSet; 00883 } 00884 else { 00885 mdd_t *result; 00886 mdd_manager *mddManager = Fsm_FsmReadMddManager(fsm); 00887 mdd_t *oneMdd = mdd_one(mddManager); 00888 Ctlp_Formula_t *convFormula = 00889 Ctlp_FormulaConvertToExistentialForm(formula); 00890 00891 /* Note that Mc_FsmEvaluateFormula returns a copy of the MDD. */ 00892 result = Mc_FsmEvaluateFormula(fsm, convFormula, oneMdd, 00893 NIL(Fsm_Fairness_t), 00894 careSetArray, 00895 MC_NO_EARLY_TERMINATION, 00896 NIL(Fsm_HintsArray_t), 00897 Mc_None_c, verbosity, dcLevel, 0, 00898 McGSH_EL_c); 00899 mdd_free(oneMdd); 00900 00901 /* 00902 * We must make a copy of the MDD for the return value. 00903 */ 00904 Ctlp_FormulaSetStates(formula, result); 00905 stateSet = mdd_dup(result); 00906 00907 Ctlp_FormulaFree(convFormula); 00908 00909 return stateSet; 00910 } 00911 } 00912 }