VIS
|
00001 00017 #include "ltlInt.h" 00018 00019 static char rcsid[] UNUSED = "$Id: ltlSet.c,v 1.25 2005/04/28 08:45:27 bli Exp $"; 00020 00021 /* Set manipulation functions. 00022 * 00023 * Set is a term -- the conjunction of literals. In the Ltl->Aut process, a 00024 * literal can be an propositional formula, a X-formula and its negation. 00025 * In order to interpret a Set, we need to corresponding arrays: Table and 00026 * Negate. An '1' in the i-th position of the Set means "Table[i] is contained 00027 * in the Set", and the negation of "Table[i]" is "Negate[i]". 00028 * 00029 * Cover is a lsList of terms -- the "union" of all the items (product terms). 00030 * 00031 * Pair is a data structure to hold a 'ordered pair of items': (First, Second). 00032 */ 00033 00034 /*---------------------------------------------------------------------------*/ 00035 /* Constant declarations */ 00036 /*---------------------------------------------------------------------------*/ 00037 00038 /*---------------------------------------------------------------------------*/ 00039 /* Structure declarations */ 00040 /*---------------------------------------------------------------------------*/ 00041 00042 /*---------------------------------------------------------------------------*/ 00043 /* Type declarations */ 00044 /*---------------------------------------------------------------------------*/ 00045 00046 /*---------------------------------------------------------------------------*/ 00047 /* Variable declarations */ 00048 /*---------------------------------------------------------------------------*/ 00049 00050 /*---------------------------------------------------------------------------*/ 00051 /* Macro declarations */ 00052 /*---------------------------------------------------------------------------*/ 00053 00056 /*---------------------------------------------------------------------------*/ 00057 /* Static function prototypes */ 00058 /*---------------------------------------------------------------------------*/ 00059 00060 00064 /*---------------------------------------------------------------------------*/ 00065 /* Definition of exported functions */ 00066 /*---------------------------------------------------------------------------*/ 00067 00077 LtlSet_t * 00078 LtlSetNew( 00079 int size) 00080 { 00081 LtlSet_t *set = ALLOC(LtlSet_t, 1); 00082 00083 set->e = var_set_new(size); 00084 00085 return set; 00086 } 00087 00097 void 00098 LtlSetFree( 00099 LtlSet_t *set) 00100 { 00101 var_set_free(set->e); 00102 FREE(set); 00103 } 00104 00114 LtlSet_t * 00115 LtlSetCopy( 00116 LtlSet_t *from) 00117 { 00118 LtlSet_t *set = ALLOC(LtlSet_t, 1); 00119 00120 set->e = var_set_copy(from->e); 00121 00122 return set; 00123 } 00124 00134 void 00135 LtlSetAssign( 00136 LtlSet_t *to, 00137 LtlSet_t *from) 00138 { 00139 var_set_assign(to->e, from->e); 00140 } 00141 00151 int 00152 LtlSetEqual( 00153 LtlSet_t *s1, 00154 LtlSet_t *s2) 00155 { 00156 return var_set_equal(s1->e, s2->e); 00157 } 00158 00159 00169 int 00170 LtlSetCardinality( 00171 LtlSet_t *set) 00172 { 00173 return (var_set_n_elts(set->e)); 00174 } 00175 00186 int 00187 LtlSetCompareCardinality( 00188 const void *p1, 00189 const void *p2) 00190 { 00191 LtlSet_t **s1 = (LtlSet_t **) p1; 00192 LtlSet_t **s2 = (LtlSet_t **) p2; 00193 int c1; 00194 int c2; 00195 00196 c1 = LtlSetCardinality(*s1); 00197 c2 = LtlSetCardinality(*s2); 00198 00199 if (c1 < c2) 00200 return -1; 00201 else if (c1 == c2) 00202 return 0; 00203 else 00204 return +1; 00205 } 00206 00216 int 00217 LtlSetIsContradictory( 00218 LtlSet_t *set, 00219 array_t *Negate) 00220 { 00221 int i, negi; 00222 int flag = 0; 00223 00224 for (i=0; i<array_n(Negate); i++) { 00225 if (LtlSetGetElt(set, i)) { 00226 negi = array_fetch(int, Negate, i); 00227 if (LtlSetGetElt(set, negi)) { 00228 flag = 1; 00229 break; 00230 } 00231 } 00232 } 00233 00234 return flag; 00235 } 00236 00246 int 00247 LtlSetInclude( 00248 LtlSet_t *large, 00249 LtlSet_t *small) 00250 { 00251 var_set_t *neg_large = var_set_not(var_set_copy(large->e),large->e); 00252 int result = ! var_set_intersect(small->e, neg_large); 00253 var_set_free(neg_large); 00254 00255 return result; 00256 } 00257 00267 void 00268 LtlSetOR( 00269 LtlSet_t *to, 00270 LtlSet_t *from1, 00271 LtlSet_t *from2) 00272 { 00273 var_set_or(to->e, from1->e, from2->e); 00274 } 00275 00285 void 00286 LtlSetClear( 00287 LtlSet_t *set) 00288 { 00289 var_set_clear(set->e); 00290 } 00291 00301 void 00302 LtlSetSetElt( 00303 LtlSet_t *set, 00304 int index) 00305 { 00306 var_set_set_elt(set->e, index); 00307 } 00308 00318 void 00319 LtlSetClearElt( 00320 LtlSet_t *set, 00321 int index) 00322 { 00323 var_set_clear_elt(set->e, index); 00324 } 00325 00335 int 00336 LtlSetGetElt( 00337 LtlSet_t *set, 00338 int index) 00339 { 00340 return var_set_get_elt(set->e,index); 00341 } 00342 00352 int 00353 LtlSetIsEmpty( 00354 LtlSet_t *set) 00355 { 00356 return var_set_is_empty(set->e); 00357 } 00358 00368 LtlSet_t * 00369 LtlSetIsInList( 00370 LtlSet_t *set, 00371 lsList list) 00372 { 00373 lsGen gen; 00374 lsGeneric data; 00375 LtlSet_t *s = NIL(LtlSet_t); 00376 int flag = 0; 00377 00378 lsForEachItem(list, gen, data) { 00379 s = (LtlSet_t *) data; 00380 if ( var_set_equal(s->e, set->e) ) { 00381 flag = 1; 00382 lsFinish(gen); 00383 break; 00384 } 00385 } 00386 00387 return flag? s: NIL(LtlSet_t); 00388 } 00389 00407 LtlSet_t * 00408 LtlSetToLabelSet( 00409 LtlTableau_t *tableau, 00410 LtlSet_t *set) 00411 { 00412 int i; 00413 LtlSet_t *vset = LtlSetNew(tableau->labelIndex); 00414 Ctlsp_Formula_t *F; 00415 00416 for (i=0; i<tableau->abIndex; i++) { 00417 if (var_set_get_elt(set->e, i)) { 00418 F = tableau->abTable[i].F; 00419 if (Ctlsp_LtlFormulaIsPropositional(F)&& 00420 Ctlsp_FormulaReadType(F) != Ctlsp_TRUE_c && 00421 Ctlsp_FormulaReadType(F) != Ctlsp_FALSE_c) 00422 var_set_set_elt(vset->e, 00423 Ctlsp_FormulaReadLabelIndex(tableau->abTable[i].F)); 00424 } 00425 } 00426 00427 return vset; 00428 } 00429 00439 void 00440 LtlSetPrint( 00441 LtlTableau_t *tableau, 00442 LtlSet_t *set) 00443 { 00444 int i; 00445 00446 fprintf(vis_stdout, "{ "); 00447 for (i=0; i<tableau->abIndex; i++) { 00448 if (LtlSetGetElt(set, i)) { 00449 Ctlsp_FormulaPrint(vis_stdout, tableau->abTable[i].F); 00450 fprintf(vis_stdout, "; "); 00451 } 00452 } 00453 fprintf(vis_stdout, " }"); 00454 } 00455 00465 void 00466 LtlSetPrintIndex( 00467 int length, 00468 LtlSet_t *set) 00469 { 00470 int i; 00471 00472 fprintf(vis_stdout, "{ "); 00473 for (i=0; i<length; i++) { 00474 if (LtlSetGetElt(set, i)) { 00475 fprintf(vis_stdout, " %d ", i); 00476 } 00477 } 00478 fprintf(vis_stdout, " }\n"); 00479 } 00480 00481 00491 LtlPair_t * 00492 LtlPairNew( 00493 char *First, 00494 char *Second) 00495 { 00496 LtlPair_t *pair = ALLOC(LtlPair_t, 1); 00497 00498 pair->First = First; 00499 pair->Second= Second; 00500 return pair; 00501 } 00502 00512 void 00513 LtlPairFree( 00514 LtlPair_t *pair) 00515 { 00516 FREE(pair); 00517 } 00518 00529 int 00530 LtlPairHash( 00531 char *key, 00532 int modulus) 00533 { 00534 LtlPair_t *pair = (LtlPair_t *) key; 00535 00536 return (int) ((((unsigned long) pair->First >>2) + 00537 ((unsigned long) pair->Second>>4)) % modulus); 00538 } 00539 00549 int 00550 LtlPairCompare( 00551 const char *key1, 00552 const char *key2) 00553 { 00554 LtlPair_t *pair1 = (LtlPair_t *) key1; 00555 LtlPair_t *pair2 = (LtlPair_t *) key2; 00556 00557 assert(key1 != NIL(char)); 00558 assert(key2 != NIL(char)); 00559 00560 if ((pair1->First == pair2->First) && (pair1->Second == pair2->Second)) 00561 return 0; 00562 else if (pair1->First >= pair2->First && pair1->Second >= pair2->Second) 00563 return 1; 00564 else 00565 return -1; 00566 } 00567 00577 void 00578 LtlPairPrint( 00579 LtlPair_t *pair) 00580 { 00581 vertex_t *first = (vertex_t *) pair->First; 00582 vertex_t *second= (vertex_t *) pair->Second; 00583 Ltl_AutomatonNode_t *node1 = (Ltl_AutomatonNode_t *) first->user_data; 00584 Ltl_AutomatonNode_t *node2 = (Ltl_AutomatonNode_t *) second->user_data; 00585 00586 fprintf(vis_stdout, " (n%d, n%d) ", node1->index, node2->index); 00587 } 00588 00598 void 00599 LtlCoverPrintIndex( 00600 int length, 00601 lsList cover) 00602 { 00603 int first = 1; 00604 lsGen gen; 00605 LtlSet_t *set; 00606 00607 fprintf(vis_stdout, "{ "); 00608 lsForEachItem(cover, gen, set) { 00609 if (first) first = 0; 00610 else fprintf(vis_stdout, " + "); 00611 LtlSetPrintIndex(length, set); 00612 } 00613 fprintf(vis_stdout, " }"); 00614 } 00615 00616 00627 lsList 00628 LtlCoverCompleteSum( 00629 lsList Cover, 00630 array_t *Negate) 00631 { 00632 lsList cs = lsCreate(); 00633 lsGen lsgen; 00634 array_t *products = array_alloc(LtlSet_t *, 0); 00635 LtlSet_t *term, *term1, *term2, *consensus; 00636 long i, j, k, flag; 00637 st_table *removed, *consList; /* removed, and consensus generated */ 00638 00639 /* Check and remove contraditory terms -- containing both F and !F */ 00640 lsForEachItem(Cover, lsgen, term) { 00641 if (!LtlSetIsContradictory(term, Negate)) 00642 array_insert_last(LtlSet_t *, products, term); 00643 } 00644 00645 /* Sort terms by increasing number of literals */ 00646 array_sort(products, LtlSetCompareCardinality); 00647 00648 /* Check tautologous term */ 00649 term = array_fetch(LtlSet_t *, products, 0); 00650 if (LtlSetCardinality(term) == 0) { 00651 lsNewEnd(cs, (lsGeneric) LtlSetCopy(term), (lsHandle *)0); 00652 array_free(products); 00653 return cs; 00654 } 00655 00656 /* In the following, we won't change 'products'. Instead, if a term need to 00657 * be removed, we will store it (its index number) in the hash table 00658 */ 00659 removed = st_init_table(st_ptrcmp, st_ptrhash); 00660 /* In the following, we might generate some new consensus terms, and we will 00661 * store them (LtlSet_t) in the list 00662 */ 00663 consList = st_init_table(st_ptrcmp, st_ptrhash); 00664 00665 /* Check terms for single-cube containment. Rely on ordering for efficiency. 00666 * A term can only be contained by another term with fewer literals 00667 */ 00668 for (i=array_n(products)-1; i>0; i--) { 00669 term = array_fetch(LtlSet_t *, products, i); 00670 for (j=0; j<i; j++) { 00671 term1 = array_fetch(LtlSet_t *, products, j); 00672 if (LtlSetCardinality(term1) == LtlSetCardinality(term)) break; 00673 if (LtlSetInclude(term, term1)) { 00674 /* remember the removed term */ 00675 st_insert(removed, (char *)i, (char *)i); 00676 break; 00677 } 00678 } 00679 } 00680 00681 /* Now do iterated consensus */ 00682 for (i=1; i<array_n(products); i++) { 00683 if (st_is_member(removed, (char *)i)) continue; 00684 term = array_fetch(LtlSet_t *, products, i); 00685 00686 for (j=0; j<i; j++) { 00687 if (st_is_member(removed, (char *)j)) continue; 00688 term1 = array_fetch(LtlSet_t *, products, j); 00689 00690 consensus = LtlSetConsensus(term, term1, Negate); 00691 00692 if (consensus) { 00693 /* should store consensus ? */ 00694 flag = 1; 00695 for(k=0; k<array_n(products); k++) { 00696 if (st_is_member(removed, (char *)k)) continue; 00697 term2 = array_fetch(LtlSet_t *, products, k); 00698 00699 if (LtlSetInclude(consensus, term2)) { 00700 /* redudant new term */ 00701 flag = 0; 00702 break; 00703 } 00704 if (LtlSetInclude(term2, consensus)) { 00705 /* remember the removed term2 (k) */ 00706 st_insert(removed, (char *)k, (char *)k); 00707 } 00708 } 00709 if (flag) { 00710 array_insert_last(LtlSet_t *, products, consensus); 00711 st_insert(consList, consensus, (char *)0); 00712 }else 00713 LtlSetFree(consensus); 00714 } 00715 } 00716 } 00717 00718 #if 0 00719 if (0) { 00720 fprintf(vis_stdout, "\nLtlCompleteSum: products = { "); 00721 for(i=0; i<array_n(products); i++) { 00722 term = array_fetch(LtlSet_t *, products, i); 00723 LtlSetPrintIndex(array_n(Negate), term); 00724 } 00725 fprintf(vis_stdout, "}\nLtlCompleteSum: removed = { "); 00726 st_foreach_item(removed, stgen, &i, NIL(char *)) { 00727 term = array_fetch(LtlSet_t *, products, i); 00728 LtlSetPrintIndex(array_n(Negate), term); 00729 } 00730 fprintf(vis_stdout, "}\nLtlCompleteSum: consList = { "); 00731 st_foreach_item(consList, stgen, &term, NIL(char *)) { 00732 LtlSetPrintIndex(array_n(Negate), term); 00733 } 00734 fprintf(vis_stdout, "}\n"); 00735 00736 fflush(vis_stdout); 00737 } 00738 #endif 00739 00740 arrayForEachItem(LtlSet_t *, products, i, term) { 00741 if (!st_is_member(removed, (char *)i)) { 00742 /* put it into the complete sum list */ 00743 if (!st_is_member(consList, term)) 00744 term1 = LtlSetCopy(term); 00745 else 00746 term1 = term; 00747 lsNewEnd(cs, (lsGeneric) term1, NIL(lsHandle)); 00748 }else { 00749 /* it has been removed. If it was allocated locally, free it */ 00750 if (st_is_member(consList, term)) 00751 LtlSetFree(term); 00752 } 00753 } 00754 00755 array_free(products); 00756 st_free_table(removed); 00757 st_free_table(consList); 00758 00759 return cs; 00760 } 00761 00762 00772 LtlSet_t * 00773 LtlSetConsensus( 00774 LtlSet_t *first, 00775 LtlSet_t *second, 00776 array_t *Negate) 00777 { 00778 LtlSet_t *consensus = LtlSetNew(array_n(Negate)); 00779 int pivot = -1; 00780 int literal, complement; 00781 00782 for (literal=0; literal<array_n(Negate); literal++) { 00783 if (LtlSetGetElt(first, literal)) { 00784 complement = array_fetch(int, Negate, literal); 00785 if (LtlSetGetElt(second, complement)) { 00786 if (pivot != -1) { 00787 LtlSetFree(consensus); 00788 return NIL(LtlSet_t); 00789 }else { 00790 pivot = complement; 00791 } 00792 }else { 00793 LtlSetSetElt(consensus, literal); 00794 } 00795 } 00796 } 00797 /* if pivot has never been defined, return NIL */ 00798 if (pivot == -1) { 00799 LtlSetFree(consensus); 00800 return NIL(LtlSet_t); 00801 } 00802 00803 for (literal=0; literal<array_n(Negate); literal++) { 00804 if (LtlSetGetElt(second, literal)) { 00805 if (literal != pivot) 00806 LtlSetSetElt(consensus, literal); 00807 } 00808 } 00809 00810 return consensus; 00811 } 00812 00823 lsList 00824 LtlCoverCofactor( 00825 lsList Cover, 00826 LtlSet_t *c, 00827 array_t *Negate) 00828 { 00829 lsList cofactor = lsCopy(Cover, (lsGeneric (*)(lsGeneric))LtlSetCopy); 00830 lsList list; 00831 lsGen lsgen; 00832 st_table *removed = st_init_table(st_ptrcmp, st_ptrhash); 00833 int literal, complement; 00834 LtlSet_t *term; 00835 00836 for (literal=0; literal<array_n(Negate); literal++) { 00837 if (!LtlSetGetElt(c, literal)) continue; 00838 complement = array_fetch(int, Negate, literal); 00839 lsForEachItem(cofactor, lsgen, term) { 00840 if (st_is_member(removed, term)) continue; 00841 if (LtlSetGetElt(term, complement)) 00842 st_insert(removed, term, term); 00843 else if (LtlSetGetElt(term, literal)) 00844 LtlSetClearElt(term, literal); 00845 } 00846 } 00847 00848 list = cofactor; 00849 cofactor = lsCreate(); 00850 lsForEachItem(list, lsgen, term) { 00851 if (st_is_member(removed, term)) 00852 LtlSetFree(term); 00853 else 00854 lsNewEnd(cofactor, (lsGeneric) term, (lsHandle *) 0); 00855 } 00856 lsDestroy(list, (void (*)(lsGeneric))0); 00857 00858 st_free_table(removed); 00859 00860 return cofactor; 00861 } 00862 00873 int 00874 LtlCoverIsTautology( 00875 lsList Cover, 00876 array_t *Negate) 00877 { 00878 lsList complete = LtlCoverCompleteSum(Cover, Negate); 00879 LtlSet_t *term; 00880 int result; 00881 00882 if (lsLength(complete) !=1) 00883 result = 0; 00884 else { 00885 lsFirstItem(complete, &term, (lsHandle *)0); 00886 result = (LtlSetCardinality(term) == 0); 00887 } 00888 00889 lsDestroy(complete, (void (*)(lsGeneric))LtlSetFree); 00890 return result; 00891 } 00892 00902 int 00903 LtlCoverIsImpliedBy( 00904 lsList Cover, 00905 LtlSet_t *term, 00906 array_t *Negate) 00907 { 00908 lsList cofactor = LtlCoverCofactor(Cover, term, Negate); 00909 int result = LtlCoverIsTautology(Cover, Negate); 00910 lsDestroy(cofactor, (void (*)(lsGeneric))LtlSetFree); 00911 00912 return result; 00913 } 00914 00915 00930 lsList 00931 LtlCoverPrimeAndIrredundant( 00932 LtlTableau_t *tableau, 00933 lsList Cover, 00934 array_t *Negate) 00935 { 00936 lsList pai = LtlCoverCompleteSum(Cover, Negate); 00937 int totalnum; /* total num of terms in current lsList pai */ 00938 int procnum; /* how many are already processed so far ? */ 00939 LtlSet_t *term; 00940 00941 totalnum = lsLength(pai); 00942 procnum = 0; 00943 /* Try to drop each term in turn */ 00944 while(lsDelBegin(pai, &term) != LS_NOMORE) { 00945 if ( (lsLength(pai) != 0) && 00946 /* !LtlAutomatonSetIsFair(tableau, term) && */ 00947 LtlCoverIsImpliedBy(pai, term, Negate) ) { 00948 LtlSetFree(term); 00949 totalnum--; 00950 }else 00951 lsNewEnd(pai, (lsGeneric) term, (lsHandle *)0); 00952 00953 procnum++; 00954 if (procnum >= totalnum) 00955 break; 00956 } 00957 00958 return pai; 00959 } 00960 00961 00971 LtlSet_t * 00972 LtlCoverGetSuperCube( 00973 lsList Cover, 00974 array_t *Negate) 00975 { 00976 LtlSet_t *unate = LtlSetNew(array_n(Negate)); 00977 LtlSet_t *binate = LtlSetNew(array_n(Negate)); 00978 lsGen lsgen; 00979 LtlSet_t *term; 00980 int literal, neg; 00981 00982 lsForEachItem( Cover, lsgen, term ) { 00983 for (literal=0; literal<array_n(Negate); literal++) { 00984 if (!LtlSetGetElt(term, literal)) continue; 00985 if (LtlSetGetElt(binate, literal) || LtlSetGetElt(unate, literal)) 00986 continue; 00987 neg = array_fetch(int, Negate, literal); 00988 if (LtlSetGetElt(unate, neg)) { 00989 LtlSetClearElt(unate, neg); 00990 LtlSetSetElt(binate, literal); 00991 LtlSetSetElt(binate, neg); 00992 }else 00993 LtlSetSetElt(unate, literal); 00994 } 00995 } 00996 00997 LtlSetFree(binate); 00998 00999 return unate; 01000 } 01001 01002 01003 01013 mdd_t * 01014 LtlSetModelCheckFormulae( 01015 LtlSet_t *set, 01016 array_t *labelTable, 01017 Fsm_Fsm_t *fsm) 01018 { 01019 mdd_t *minterm, *mdd1, *mdd2; 01020 mdd_manager *mddManager = Fsm_FsmReadMddManager(fsm); 01021 mdd_t *mddOne = mdd_one(mddManager); 01022 array_t *careStatesArray = array_alloc(mdd_t *, 0); 01023 int i; 01024 01025 array_insert(mdd_t *, careStatesArray, 0, mddOne); 01026 01027 minterm = mdd_dup(mddOne); 01028 for (i=0; i<array_n(labelTable); i++) { 01029 if (LtlSetGetElt(set, i)) { 01030 Ctlsp_Formula_t *F = array_fetch(Ctlsp_Formula_t *, labelTable, i); 01031 Ctlp_Formula_t *ctlF = Ctlsp_PropositionalFormulaToCTL(F); 01032 mdd1 = Mc_FsmEvaluateFormula(fsm, ctlF, mddOne, 01033 NIL(Fsm_Fairness_t), 01034 careStatesArray, 01035 MC_NO_EARLY_TERMINATION, 01036 NIL(Fsm_HintsArray_t), Mc_None_c, 01037 McVerbosityNone_c, McDcLevelNone_c, 0, 01038 McGSH_EL_c); 01039 mdd2 = minterm; 01040 minterm = mdd_and(minterm, mdd1, 1, 1); 01041 mdd_free(mdd2); 01042 mdd_free(mdd1); 01043 Ctlp_FormulaFree(ctlF); 01044 } 01045 } 01046 01047 mdd_array_free(careStatesArray); 01048 01049 return minterm; 01050 }