VIS
|
00001 00017 #include "ltlInt.h" 00018 00019 static char rcsid[] UNUSED = "$Id: ltlCompose.c,v 1.30 2005/04/28 08:51:19 bli Exp $"; 00020 00021 /*---------------------------------------------------------------------------*/ 00022 /* Constant declarations */ 00023 /*---------------------------------------------------------------------------*/ 00024 00025 /*---------------------------------------------------------------------------*/ 00026 /* Structure declarations */ 00027 /*---------------------------------------------------------------------------*/ 00028 00029 /*---------------------------------------------------------------------------*/ 00030 /* Type declarations */ 00031 /*---------------------------------------------------------------------------*/ 00032 00033 /*---------------------------------------------------------------------------*/ 00034 /* Variable declarations */ 00035 /*---------------------------------------------------------------------------*/ 00036 00037 /*---------------------------------------------------------------------------*/ 00038 /* Macro declarations */ 00039 /*---------------------------------------------------------------------------*/ 00040 00043 /*---------------------------------------------------------------------------*/ 00044 /* Static function prototypes */ 00045 /*---------------------------------------------------------------------------*/ 00046 00047 static void AutomatonGetInputNames(Ltl_Automaton_t *A, array_t *InputNames, array_t *Name2LabelIdx); 00048 static int AutomatonCountSelector(Ltl_Automaton_t *A); 00049 static int AutomatonComputeInitState(Ltl_Automaton_t *A); 00050 /*static lsList AutomatonLabelGetCubes(Ltl_Automaton_t *A, LtlSet_t *compositeLabel, Ntk_Network_t *network);*/ 00051 static lsList GetCubes_Aux(Ltl_Automaton_t *A, int index); 00052 static char * StringNormalize(char *inputString); 00053 static void AutomatonVtxLabelToBlifMv(FILE *fp, Ltl_Automaton_t *A, vertex_t *vtx); 00054 static void VtxLabelToBlifMv_Aux(FILE *fp, Ltl_Automaton_t *A, int node_idx, int index, st_table *CreatedSignals); 00055 00058 /*---------------------------------------------------------------------------*/ 00059 /* Definition of exported functions */ 00060 /*---------------------------------------------------------------------------*/ 00061 00073 void 00074 Ltl_AutomatonToDot( 00075 FILE *fp, 00076 Ltl_Automaton_t *aut, 00077 int level) 00078 { 00079 edge_t *edge; 00080 vertex_t *vtx1, *vtx2; 00081 Ltl_AutomatonNode_t *node, *node2; 00082 lsGen lsgen, lsgen2; 00083 st_table *FairSet; 00084 st_generator *stgen; 00085 Ctlsp_Formula_t *F; 00086 char *tmpString; 00087 int fairindex, first, i, n; 00088 00089 /*------------------------------------------------- 00090 * digraph "G(F(p=1))" { 00091 * node [shape=ellipse]; 00092 * size = "7.5,10" 00093 * center = true; 00094 * "title" [label="G(F(p=1))", shape=plaintext]; 00095 *------------------------------------------------- 00096 */ 00097 if (aut->name) 00098 tmpString = aut->name; 00099 else 00100 tmpString = ""; 00101 00102 fprintf(fp, "\ndigraph \"%s\" {\nnode [shape=ellipse];\nsize = \"7.5,10\"\ncenter = true;\n\"title\" [label=\"%s\",shape=plaintext];", tmpString, tmpString); 00103 00104 /*------------------------------------------------- 00105 * "n1" [label="n1\n{p=1}\n(1)"]; 00106 *------------------------------------------------- 00107 */ 00108 foreach_vertex( aut->G, lsgen, vtx1) { 00109 node = (Ltl_AutomatonNode_t *)vtx1->user_data; 00110 fprintf(fp,"\n\"n%d\" [label=\"n%d\\n{", node->index, node->index); 00111 if (node->Labels) { 00112 first = 1; n = array_n(aut->labelTable); 00113 for (i=0; i<n; i++) { 00114 if (LtlSetGetElt(node->Labels, i)) { 00115 if (!first) fprintf(fp, ","); 00116 else first = 0; 00117 F = array_fetch(Ctlsp_Formula_t *, aut->labelTable, i); 00118 Ctlsp_FormulaPrint(fp, F); 00119 } 00120 } 00121 } 00122 fprintf(fp, "}\\n("); 00123 fairindex = 1; 00124 lsForEachItem(aut->Fair, lsgen2, FairSet) { 00125 if (st_is_member(FairSet, vtx1)) 00126 fprintf(fp, " %d ", fairindex); 00127 fairindex++; 00128 } 00129 fprintf(fp, ")\"];"); 00130 } 00131 00132 /*------------------------------------------------- 00133 * "init-n2" [style=invis] 00134 * "init-n2" -> "n2"; 00135 *------------------------------------------------- 00136 */ 00137 st_foreach_item(aut->Init, stgen, &vtx1, NIL(char *)) { 00138 node = (Ltl_AutomatonNode_t *) vtx1->user_data; 00139 fprintf(fp, "\n\"init-n%d\" [style=invis]", node->index); 00140 fprintf(fp, "\n\"init-n%d\" -> \"n%d\";", node->index, node->index); 00141 } 00142 00143 00144 /*------------------------------------------------- 00145 * "n1" -> "n1"; 00146 *------------------------------------------------- 00147 */ 00148 foreach_edge(aut->G, lsgen, edge) { 00149 vtx1 = g_e_source(edge); 00150 vtx2 = g_e_dest(edge); 00151 node = (Ltl_AutomatonNode_t *) vtx1->user_data; 00152 node2 = (Ltl_AutomatonNode_t *) vtx2->user_data; 00153 fprintf(fp, "\n\"n%d\" -> \"n%d\";", node->index, node2->index); 00154 } 00155 fprintf(fp, "\n}\n"); 00156 } 00157 00158 00174 int 00175 Ltl_AutomatonToBlifMv( 00176 FILE *fp, 00177 Ntk_Network_t *network, 00178 Ltl_Automaton_t *A) 00179 { 00180 Var_Variable_t *inputVar; 00181 array_t *InputNames = array_alloc(char *, 0); 00182 array_t *Name2LabelIdx = array_alloc(st_table *, 0); 00183 Ntk_Node_t *ntknode; 00184 char *inputName; 00185 st_generator *stgen; 00186 lsGen lsgen, lsgen2; 00187 int i, j, is_enum, range; 00188 int sel_num, sel_cnt; 00189 edge_t *edge; 00190 vertex_t *vtx, *vtx2; 00191 st_table *FairSet, *tmptbl; 00192 int InitIdx = AutomatonComputeInitState(A); 00193 char InitStr[10]; 00194 int result = 1; 00195 array_t *labelArray; 00196 00197 /* The initState of the automaton */ 00198 if (InitIdx == -1) 00199 sprintf(InitStr, "Init"); 00200 else 00201 sprintf(InitStr, "n%d", InitIdx); 00202 00203 if (network == NIL(Ntk_Network_t)) { 00204 result = 0; 00205 fprintf(vis_stderr, "Warning: the BlifMv output is incomplete. (The current node is empty. Read in design.)\n"); 00206 } 00207 00208 /* Retrieve all the input names on the labels; For each input, create a 00209 * hash table and add all the label subformulae contains that input; 00210 * Finally, calculate the size of the "selector" 00211 */ 00212 AutomatonGetInputNames(A, InputNames, Name2LabelIdx); 00213 sel_num = AutomatonCountSelector(A); 00214 fprintf(fp, "\n# Buechi automaton: %s\n\n", A->name); 00215 00216 /*------------------------------------------------------- 00217 * .model Buechi$AUT 00218 * .root Buechi$AUT 00219 *------------------------------------------------------- 00220 */ 00221 fprintf(fp, ".model Buechi$AUT\n.root Buechi$AUT"); 00222 00223 /*------------------------------------------------------- 00224 * .inputs in1 in2 in3 ... inN 00225 *------------------------------------------------------- 00226 */ 00227 fprintf(fp, "\n.inputs "); 00228 for (i=0; i<array_n(InputNames); i++) { 00229 inputName = array_fetch(char *, InputNames, i); 00230 fprintf(fp, "%s ", inputName); 00231 } 00232 00233 /*------------------------------------------------------- 00234 * .outputs fair1 fair2 fair3... fairN 00235 *------------------------------------------------------- 00236 */ 00237 fprintf(fp, "\n.outputs "); 00238 if ( lsLength(A->Fair) != 0) { 00239 for (i=0; i<lsLength(A->Fair); i++) { 00240 fprintf(fp, "fair%d$AUT ", i+1); 00241 } 00242 }else 00243 fprintf(fp, "fair1$AUT"); 00244 00245 /*------------------------------------------------------- 00246 * .mv in1 3 RED GREEN YELLOW 00247 *------------------------------------------------------- 00248 */ 00249 if (network != NIL(Ntk_Network_t)) { 00250 for (i=0; i<array_n(InputNames); i++) { 00251 inputName = array_fetch(char *, InputNames, i); 00252 ntknode = Ntk_NetworkFindNodeByName(network, inputName); 00253 assert(ntknode != NIL(Ntk_Node_t)); 00254 inputVar = Ntk_NodeReadVariable(ntknode); 00255 is_enum = Var_VariableTestIsEnumerative(inputVar); 00256 range = Var_VariableReadNumValues(inputVar); 00257 if (is_enum) { 00258 if (range != 2) 00259 fprintf(fp, "\n.mv %s %d\n", inputName, range); 00260 }else { 00261 fprintf(fp, "\n.mv %s %d ", inputName, range); 00262 for (j=0; j<range; j++) { 00263 fprintf(fp, "%s ", 00264 Var_VariableReadSymbolicValueFromIndex(inputVar,j)); 00265 } 00266 } 00267 } 00268 } 00269 00270 /*------------------------------------------------------- 00271 * .mv stateD$AUT N Init n1 n2 n3 ... nN 00272 * .mv state$AUT N Init n1 n2 n3 ... nN 00273 *------------------------------------------------------- 00274 */ 00275 if (InitIdx == -1) 00276 fprintf(fp, "\n.mv stateD$AUT %d Init Trap ", 00277 lsLength(g_get_vertices(A->G)) + 2); 00278 else 00279 fprintf(fp, "\n.mv stateD$AUT %d Trap ", 00280 lsLength(g_get_vertices(A->G)) + 1); 00281 foreach_vertex(A->G, lsgen, vtx) { 00282 fprintf(fp, "n%d ", Ltl_AutomatonVtxGetNodeIdx(vtx)); 00283 } 00284 if (InitIdx == -1) 00285 fprintf(fp, "\n.mv state$AUT %d Init Trap ", 00286 lsLength(g_get_vertices(A->G)) + 2); 00287 else 00288 fprintf(fp, "\n.mv state$AUT %d Trap ", 00289 lsLength(g_get_vertices(A->G)) + 1); 00290 foreach_vertex(A->G, lsgen, vtx) { 00291 fprintf(fp, "n%d ", Ltl_AutomatonVtxGetNodeIdx(vtx)); 00292 } 00293 00294 /*------------------------------------------------------- 00295 * .mv selector n 00296 * .table selector 00297 * - 00298 *------------------------------------------------------- 00299 */ 00300 if (sel_num > 1) 00301 fprintf(fp, "\n.mv selector$AUT %d\n.table selector$AUT\n-", sel_num); 00302 00303 /*------------------------------------------------------- 00304 * for each state label, create a signal n1_##_label$AUT (recursively) 00305 *------------------------------------------------------- 00306 */ 00307 labelArray = array_alloc(vertex_t *, 0); 00308 foreach_vertex(A->G, lsgen, vtx) { 00309 AutomatonVtxLabelToBlifMv(fp, A, vtx); 00310 array_insert_last(vertex_t *, labelArray, vtx); 00311 } 00312 00313 /*------------------------------------------------------- 00314 * .latch stateD$AUT state$AUT 00315 * .reset state$AUT 00316 * Init (or ns) 00317 *------------------------------------------------------- 00318 */ 00319 fprintf(fp, "\n.latch stateD$AUT state$AUT\n.reset -> state$AUT\n%s", 00320 InitStr); 00321 00322 00323 /*------------------------------------------------------ 00324 * .table selector$AUT state$AUT n1_label$AUT n2_label... -> stateD$AUT 00325 * .default Trap 00326 * 0 1 0 0 ... n1 00327 * 1 0 1 n2 00328 * ... 00329 *------------------------------------------------------ 00330 */ 00331 if (sel_num >1) 00332 fprintf(fp, "\n.table selector$AUT state$AUT "); 00333 else 00334 fprintf(fp, "\n.table state$AUT "); 00335 00336 arrayForEachItem(vertex_t *, labelArray, i, vtx) { 00337 fprintf(fp, "n%d_label$AUT ", Ltl_AutomatonVtxGetNodeIdx(vtx)); 00338 } 00339 fprintf(fp, " -> stateD$AUT\n.default Trap"); 00340 00341 if (InitIdx == -1) { 00342 sel_cnt = 0; 00343 arrayForEachItem(vertex_t *, labelArray, i, vtx) { 00344 if (!st_is_member(A->Init, vtx)) 00345 continue; 00346 if (sel_num > 1) { 00347 if (st_count(A->Init) == 1) 00348 fprintf(fp, "\n- Init "); 00349 else 00350 fprintf(fp, "\n%d Init ", sel_cnt); 00351 }else 00352 fprintf(fp, "\nInit "); 00353 00354 for(j=0; j<array_n(labelArray); j++) 00355 fprintf(fp, "%s ", ((i==j)?"1":"-")); 00356 00357 fprintf(fp, " n%d", Ltl_AutomatonVtxGetNodeIdx(vtx)); 00358 00359 if (sel_num > 1) 00360 sel_cnt++; 00361 } 00362 } 00363 00364 /* for each edge (n1, n2) with n2 labeled n2_label$AUT, add entry: 00365 *------------------------------------------------------- 00366 * selector 1 0 0 ... n1 00367 * selector 0 1 0 ... n2 00368 * ... 00369 *------------------------------------------------------- 00370 */ 00371 foreach_vertex(A->G, lsgen, vtx) { 00372 int n1 = Ltl_AutomatonVtxGetNodeIdx(vtx); 00373 int outDegree = lsLength(g_get_out_edges(vtx)); 00374 sel_cnt = 0; 00375 foreach_out_edge(vtx, lsgen2, edge) { 00376 int n2 = Ltl_AutomatonVtxGetNodeIdx(g_e_dest(edge)); 00377 00378 if (sel_num > 1) { 00379 if (outDegree == 1) 00380 fprintf(fp, "\n- n%d ", n1); 00381 else 00382 fprintf(fp, "\n%d n%d ", sel_cnt, n1); 00383 }else { 00384 fprintf(fp, "\nn%d ", n1); 00385 } 00386 00387 arrayForEachItem(vertex_t *, labelArray, i, vtx2) { 00388 fprintf(fp, "%s ", ((vtx2 == g_e_dest(edge))?"1":"-")); 00389 } 00390 fprintf(fp, " n%d", n2); 00391 00392 if (sel_num > 1) 00393 sel_cnt++; 00394 } 00395 } 00396 array_free(labelArray); 00397 00398 /*------------------------------------------------------- 00399 * .table state -> fair1 00400 * .default 0 00401 * ------------------------------------------------------ 00402 */ 00403 if (lsLength(A->Fair) != 0) { 00404 i = 1; 00405 lsForEachItem(A->Fair, lsgen, FairSet) { 00406 int isFirst = 1; 00407 fprintf(fp, "\n.table state$AUT -> fair%d$AUT ", i++); 00408 fprintf(fp, "\n.default 0\n("); 00409 st_foreach_item(FairSet, stgen, &vtx, NIL(char *)) { 00410 if (isFirst) 00411 isFirst = 0; 00412 else 00413 fprintf(fp, ","); 00414 fprintf(fp, "n%d", Ltl_AutomatonVtxGetNodeIdx(vtx)); 00415 } 00416 fprintf(fp, ") 1"); 00417 } 00418 }else { 00419 fprintf(fp, "\n.table state$AUT -> fair1$AUT "); 00420 if (InitIdx == -1) 00421 fprintf(fp, "\n.default 0\n!(Trap,Init) 1"); 00422 else 00423 fprintf(fp, "\n.default 0\n!(Trap) 1"); 00424 } 00425 00426 /*------------------------------------------------------- 00427 * .end 00428 * ------------------------------------------------------ 00429 */ 00430 fprintf(fp, "\n.end\n"); 00431 00432 /* free the name array 00433 */ 00434 array_free(InputNames); 00435 arrayForEachItem(st_table *, Name2LabelIdx, i, tmptbl) { 00436 st_free_table(tmptbl); 00437 } 00438 array_free(Name2LabelIdx); 00439 00440 return result; 00441 } 00442 00443 #if 0 00444 int 00445 Ltl_AutomatonToBlifMv_Old( 00446 FILE *fp, 00447 Ntk_Network_t *network, 00448 Ltl_Automaton_t *A) 00449 { 00450 Var_Variable_t *inputVar; 00451 array_t *InputNames = array_alloc(char *, 0); 00452 array_t *Name2LabelIdx = array_alloc(st_table *, 0); 00453 Ntk_Node_t *ntknode; 00454 char *inputName; 00455 st_generator *stgen, *stgen2; 00456 lsGen lsgen, lsgen2, lsgen3; 00457 int i, j, is_enum, range; 00458 long index; 00459 int sel_num, sel_cnt; 00460 edge_t *edge; 00461 vertex_t *vtx; 00462 st_table *FairSet, *tmptbl; 00463 LtlSet_t *label; 00464 int InitIdx = AutomatonComputeInitState(A); 00465 char InitStr[10]; 00466 int result = 1; 00467 00468 /* The initState of the automaton */ 00469 if (InitIdx == -1) 00470 sprintf(InitStr, "Init"); 00471 else 00472 sprintf(InitStr, "n%d", InitIdx); 00473 00474 if (network == NIL(Ntk_Network_t)) { 00475 result = 0; 00476 fprintf(vis_stderr, "Warning: the BlifMv output is incomplete. (The current node is empty. Read in design.)\n"); 00477 } 00478 00479 /* Retrieve all the input names on the labels; For each input, create a 00480 * hash table and add all the label subformulae contains that input; 00481 * Finally, calculate the size of the "selector" 00482 */ 00483 AutomatonGetInputNames(A, InputNames, Name2LabelIdx); 00484 sel_num = AutomatonCountSelector(A); 00485 fprintf(fp, "\n# Buechi automaton: %s\n\n", A->name); 00486 00487 /*------------------------------------------------------- 00488 * .model Buechi$AUT 00489 * .root Buechi$AUT 00490 *------------------------------------------------------- 00491 */ 00492 fprintf(fp, ".model Buechi$AUT\n.root Buechi$AUT"); 00493 00494 /*------------------------------------------------------- 00495 * .inputs in1 in2 in3 ... inN 00496 *------------------------------------------------------- 00497 */ 00498 fprintf(fp, "\n.inputs "); 00499 for (i=0; i<array_n(InputNames); i++) { 00500 inputName = array_fetch(char *, InputNames, i); 00501 fprintf(fp, "%s ", inputName); 00502 } 00503 00504 /*------------------------------------------------------- 00505 * .outputs fair1 fair2 fair3... fairN 00506 *------------------------------------------------------- 00507 */ 00508 fprintf(fp, "\n.outputs "); 00509 if ( lsLength(A->Fair) != 0) { 00510 for (i=0; i<lsLength(A->Fair); i++) { 00511 fprintf(fp, "fair%d$AUT ", i+1); 00512 } 00513 }else 00514 fprintf(fp, "fair1$AUT"); 00515 00516 /*------------------------------------------------------- 00517 * .mv in1 3 RED GREEN YELLOW 00518 *------------------------------------------------------- 00519 */ 00520 if (network != NIL(Ntk_Network_t)) { 00521 for (i=0; i<array_n(InputNames); i++) { 00522 inputName = array_fetch(char *, InputNames, i); 00523 ntknode = Ntk_NetworkFindNodeByName(network, inputName); 00524 assert(ntknode != NIL(Ntk_Node_t)); 00525 inputVar = Ntk_NodeReadVariable(ntknode); 00526 is_enum = Var_VariableTestIsEnumerative(inputVar); 00527 range = Var_VariableReadNumValues(inputVar); 00528 if (is_enum) { 00529 if (range != 2) 00530 fprintf(fp, "\n.mv %s %d\n", inputName, range); 00531 }else { 00532 fprintf(fp, "\n.mv %s %d ", inputName, range); 00533 for (j=0; j<range; j++) { 00534 fprintf(fp, "%s ", 00535 Var_VariableReadSymbolicValueFromIndex(inputVar,j)); 00536 } 00537 } 00538 } 00539 } 00540 00541 /*------------------------------------------------------- 00542 * .mv stateD$AUT N Init n1 n2 n3 ... nN 00543 * .mv state$AUT N Init n1 n2 n3 ... nN 00544 *------------------------------------------------------- 00545 */ 00546 if (InitIdx == -1) 00547 fprintf(fp, "\n.mv stateD$AUT %d Init Trap ", 00548 lsLength(g_get_vertices(A->G)) + 2); 00549 else 00550 fprintf(fp, "\n.mv stateD$AUT %d Trap ", 00551 lsLength(g_get_vertices(A->G)) + 1); 00552 foreach_vertex(A->G, lsgen, vtx) { 00553 fprintf(fp, "n%d ", Ltl_AutomatonVtxGetNodeIdx(vtx)); 00554 } 00555 if (InitIdx == -1) 00556 fprintf(fp, "\n.mv state$AUT %d Init Trap ", 00557 lsLength(g_get_vertices(A->G)) + 2); 00558 else 00559 fprintf(fp, "\n.mv state$AUT %d Trap ", 00560 lsLength(g_get_vertices(A->G)) + 1); 00561 foreach_vertex(A->G, lsgen, vtx) { 00562 fprintf(fp, "n%d ", Ltl_AutomatonVtxGetNodeIdx(vtx)); 00563 } 00564 00565 /*------------------------------------------------------- 00566 * .mv selector n 00567 * .table selector 00568 * - 00569 *------------------------------------------------------- 00570 */ 00571 if (sel_num > 1) 00572 fprintf(fp, "\n.mv selector$AUT %d\n.table selector$AUT\n-", sel_num); 00573 00574 /*------------------------------------------------------- 00575 * .latch stateD$AUT state$AUT 00576 * .reset state$AUT 00577 * Init (or ns) 00578 *------------------------------------------------------- 00579 */ 00580 fprintf(fp, "\n.latch stateD$AUT state$AUT\n.reset -> state$AUT\n%s", 00581 InitStr); 00582 00583 /*------------------------------------------------------ 00584 * .table selector$AUT state$AUT in1 in2 ... inN -> stateD$AUT 00585 * .default Trap 00586 *------------------------------------------------------ 00587 */ 00588 if (sel_num >1) 00589 fprintf(fp, "\n.table selector$AUT state$AUT "); 00590 else 00591 fprintf(fp, "\n.table state$AUT "); 00592 00593 for (i=0; i<array_n(InputNames); i++) { 00594 inputName = array_fetch(char *, InputNames, i); 00595 fprintf(fp, "%s ", inputName); 00596 } 00597 fprintf(fp, " -> stateD$AUT\n.default Trap"); 00598 00599 00600 /* for each initial state n2 with label "in1=p !in3=q...", add entry: 00601 *------------------------------------------------------- 00602 * selector Init (p) - (!(q)) .. n2 00603 *------------------------------------------------------- 00604 */ 00605 if (InitIdx == -1) { 00606 sel_cnt = 0; 00607 st_foreach_item(A->Init, stgen, &vtx, NIL(char *)) { 00608 int n2 = Ltl_AutomatonVtxGetNodeIdx(vtx); 00609 /* each 'compLabel' is a set of "propositional formulae" */ 00610 LtlSet_t *compLabel = LtlAutomatonVertexGetLabels(vtx); 00611 /* each item in labelList is a set of "atomic proposition" */ 00612 lsList labelList = AutomatonLabelGetCubes(A, compLabel, network); 00613 lsForEachItem(labelList, lsgen, label) { 00614 if (sel_num > 1) { 00615 if (st_count(A->Init) == 1) 00616 fprintf(fp, "\n- Init "); 00617 else 00618 fprintf(fp, "\n%d Init ", sel_cnt); 00619 }else 00620 fprintf(fp, "\nInit "); 00621 arrayForEachItem(st_table *, Name2LabelIdx, i, tmptbl) { 00622 int isFirst = 1; 00623 int is_universe = 1; 00624 /* The value is the universe '-' iff it is not in the label */ 00625 if (!LtlSetIsEmpty(label)) { 00626 st_foreach_item(tmptbl, stgen2, &index, NIL(char *)) { 00627 if (LtlSetGetElt(label, (int) index)) { 00628 is_universe = 0; 00629 st_free_gen(stgen2); 00630 break; 00631 } 00632 } 00633 } 00634 if (is_universe) { 00635 fprintf(fp, "- "); 00636 continue; 00637 } 00638 /* Otherwise, write the value. Note that the value should be 00639 * the conjunction of the values of the atomic propositions. 00640 * A * B * C = !(!A + !B +!C) 00641 */ 00642 fprintf(fp, "!("); 00643 st_foreach_item(tmptbl, stgen2, &index, NIL(char *)) { 00644 if (LtlSetGetElt(label, (int) index)) { 00645 Ctlsp_Formula_t *F = array_fetch(Ctlsp_Formula_t *, 00646 A->labelTable, 00647 (int) index); 00648 if (isFirst) 00649 isFirst = 0; 00650 else 00651 fprintf(fp, ","); 00652 if (Ctlsp_FormulaReadType(F) == Ctlsp_NOT_c) { 00653 F = Ctlsp_FormulaReadLeftChild(F); 00654 }else { 00655 fprintf(fp, "!"); 00656 } 00657 00658 fprintf(fp, "(%s)", Ctlsp_FormulaReadValueName(F)); 00659 } 00660 } 00661 fprintf(fp, ") "); 00662 } 00663 fprintf(fp, " n%d", n2); 00664 } 00665 lsDestroy(labelList, (void (*)(lsGeneric))LtlSetFree); 00666 00667 if (sel_num > 1) 00668 sel_cnt++; 00669 } 00670 } 00671 00672 /* for each edge (n1, n2) with n2 labelled "in1=p !in3=q...", add entry: 00673 *------------------------------------------------------- 00674 * selector n1 (p) - (!(q)) ... n2 00675 *------------------------------------------------------- 00676 */ 00677 foreach_vertex(A->G, lsgen, vtx) { 00678 int n1 = Ltl_AutomatonVtxGetNodeIdx(vtx); 00679 int outDegree = lsLength(g_get_out_edges(vtx)); 00680 sel_cnt = 0; 00681 foreach_out_edge(vtx, lsgen2, edge) { 00682 int n2 = Ltl_AutomatonVtxGetNodeIdx(g_e_dest(edge)); 00683 /* 'compLabel' contains a set of "propositional formulae" */ 00684 LtlSet_t *compLabel = LtlAutomatonVertexGetLabels(g_e_dest(edge)); 00685 /* each item in 'labelList' is a set of "atomic propositions" */ 00686 lsList labelList = AutomatonLabelGetCubes(A, compLabel, network); 00687 lsForEachItem(labelList, lsgen3, label) { 00688 if (sel_num > 1) { 00689 if (outDegree == 1) 00690 fprintf(fp, "\n- n%d ", n1); 00691 else 00692 fprintf(fp, "\n%d n%d ", sel_cnt, n1); 00693 }else { 00694 fprintf(fp, "\nn%d ", n1); 00695 } 00696 arrayForEachItem(st_table *, Name2LabelIdx, i, tmptbl) { 00697 int isFirst = 1; 00698 int is_universe = 1; 00699 /* the value is universe '-' iff it is not in the label */ 00700 if (!LtlSetIsEmpty(label)) { 00701 st_foreach_item(tmptbl,stgen2,&index, NIL(char *)){ 00702 if (LtlSetGetElt(label, (int) index)) { 00703 is_universe = 0; 00704 st_free_gen(stgen2); 00705 break; 00706 } 00707 } 00708 } 00709 if (is_universe) { 00710 fprintf(fp, "- "); 00711 continue; 00712 } 00713 /* write the value as the conjunction of the values in the 00714 * atomic proposition. for example, if the state is labeled 00715 * 'in1={R,G,B}' and 'in1={G}', we should write as 00716 * !( !(R,G,B), !(G) ) 00717 * Note that it's the same as {R,G,B}^{G}={G} 00718 */ 00719 fprintf(fp, "!("); 00720 st_foreach_item(tmptbl, stgen, &index, NIL(char *)) { 00721 if (LtlSetGetElt(label, (int) index)) { 00722 Ctlsp_Formula_t *F = array_fetch(Ctlsp_Formula_t *, 00723 A->labelTable, 00724 (int) index); 00725 if (isFirst) 00726 isFirst = 0; 00727 else 00728 fprintf(fp, ","); 00729 if (Ctlsp_FormulaReadType(F) == Ctlsp_NOT_c) 00730 F = Ctlsp_FormulaReadLeftChild(F); 00731 else 00732 fprintf(fp, "!"); 00733 fprintf(fp, "(%s)", Ctlsp_FormulaReadValueName(F)); 00734 } 00735 } 00736 fprintf(fp, ") "); 00737 } 00738 fprintf(fp, " n%d", n2); 00739 } 00740 lsDestroy(labelList, (void (*)(lsGeneric))LtlSetFree); 00741 00742 if (sel_num > 1) 00743 sel_cnt++; 00744 } 00745 } 00746 00747 00748 /*------------------------------------------------------- 00749 * .table state -> fair1 00750 * .default 0 00751 * ------------------------------------------------------ 00752 */ 00753 if (lsLength(A->Fair) != 0) { 00754 i = 1; 00755 lsForEachItem(A->Fair, lsgen, FairSet) { 00756 int isFirst = 1; 00757 fprintf(fp, "\n.table state$AUT -> fair%d$AUT ", i++); 00758 fprintf(fp, "\n.default 0\n("); 00759 st_foreach_item(FairSet, stgen, &vtx, NIL(char *)) { 00760 if (isFirst) 00761 isFirst = 0; 00762 else 00763 fprintf(fp, ","); 00764 fprintf(fp, "n%d", Ltl_AutomatonVtxGetNodeIdx(vtx)); 00765 } 00766 fprintf(fp, ") 1"); 00767 } 00768 }else { 00769 fprintf(fp, "\n.table state$AUT -> fair1$AUT "); 00770 if (InitIdx == -1) 00771 fprintf(fp, "\n.default 0\n!(Trap,Init) 1"); 00772 else 00773 fprintf(fp, "\n.default 0\n!(Trap) 1"); 00774 } 00775 00776 /*------------------------------------------------------- 00777 * .end 00778 * ------------------------------------------------------ 00779 */ 00780 fprintf(fp, "\n.end\n"); 00781 00782 /* free the name array 00783 */ 00784 array_free(InputNames); 00785 arrayForEachItem(st_table *, Name2LabelIdx, i, tmptbl) { 00786 st_free_table(tmptbl); 00787 } 00788 array_free(Name2LabelIdx); 00789 00790 return result; 00791 } 00792 #endif 00793 00794 00807 int 00808 Ltl_AutomatonToVerilog( 00809 FILE *fp, 00810 Ntk_Network_t *network, 00811 Ltl_Automaton_t *A) 00812 { 00813 Var_Variable_t *inputVar; 00814 array_t *InputNames = array_alloc(char *, 0); 00815 array_t *Name2LabelIdx = array_alloc(st_table *, 0); 00816 Ntk_Node_t *ntknode; 00817 char *inputName, *formulaString, *normalString; 00818 st_generator *stgen; 00819 lsGen lsgen, lsgen2; 00820 int i, j, is_enum, range, isFirst; 00821 int sel_num, sel_cnt; 00822 edge_t *edge; 00823 vertex_t *vtx; 00824 st_table *FairSet; 00825 int InitIdx = AutomatonComputeInitState(A); 00826 char InitStr[10]; 00827 int result = 1; 00828 00829 /* The initState of the automaton */ 00830 if (InitIdx == -1) 00831 sprintf(InitStr, "Init"); 00832 else 00833 sprintf(InitStr, "n%d", InitIdx); 00834 00835 if (network == NIL(Ntk_Network_t)) { 00836 result = 0; 00837 fprintf(vis_stderr, "Warning: the Verilog output is incomplete. (The current node is empty. Read in design.)\n"); 00838 } 00839 00840 /* Retrieve all the input names of the automaton into 'InputNames', And for 00841 * each name, put into a hash table all the subformulae contains it 00842 */ 00843 AutomatonGetInputNames(A, InputNames, Name2LabelIdx); 00844 sel_num = AutomatonCountSelector(A); 00845 fprintf(fp, "\n// Buechi automaton: %s", A->name); 00846 00847 /*------------------------------------------------------- 00848 * typedef enum {Init, trap, n1, n2, ... nN} states; 00849 * typedef enum {READ, GREEN, YELLOW} type_in1; 00850 *------------------------------------------------------- 00851 */ 00852 if (InitIdx == -1) 00853 fprintf(fp, "\ntypedef enum {Init,Trap"); 00854 else 00855 fprintf(fp, "\ntypedef enum {Trap"); 00856 foreach_vertex(A->G, lsgen, vtx) { 00857 fprintf(fp, ",n%d", Ltl_AutomatonVtxGetNodeIdx(vtx)); 00858 } 00859 fprintf(fp, "} type_states;"); 00860 00861 if (network != NIL(Ntk_Network_t)) { 00862 arrayForEachItem(char *, InputNames, i, inputName) { 00863 /* replace illegal characters in the input name string */ 00864 normalString = StringNormalize(inputName); 00865 fprintf(fp, "\n//Input name mapping:\t %s => %s;", inputName, 00866 normalString); 00867 00868 ntknode = Ntk_NetworkFindNodeByName(network, inputName); 00869 assert(ntknode != NIL(Ntk_Node_t)); 00870 inputVar = Ntk_NodeReadVariable(ntknode); 00871 00872 is_enum = Var_VariableTestIsEnumerative(inputVar); 00873 range = Var_VariableReadNumValues(inputVar); 00874 if (is_enum) { 00875 if (range>2) 00876 fprintf(fp, "\ntypedef enum {0-%d} type_%s;", 00877 range-1, normalString); 00878 }else { 00879 fprintf(fp, "\ntypedef enum {"); 00880 isFirst = 1; 00881 for (j=0; j<range; j++) { 00882 char *vstr = 00883 Var_VariableReadSymbolicValueFromIndex(inputVar,j); 00884 if (isFirst) { 00885 fprintf(fp, "%s ", vstr); 00886 isFirst = 0; 00887 } else 00888 fprintf(fp, ",%s ", vstr); 00889 } 00890 fprintf(fp, "} type_%s;", normalString); 00891 } 00892 00893 FREE(normalString); 00894 } 00895 } 00896 00897 /*------------------------------------------------------- 00898 * module Buechi (clock, in1, in2 ... inN, fair1, ...); 00899 *------------------------------------------------------- 00900 */ 00901 fprintf(fp, "\n//Buechi Buechi (clock"); 00902 for (i=0; i<array_n(InputNames); i++) { 00903 inputName = array_fetch(char *, InputNames, i); 00904 fprintf(fp, ",%s", inputName); 00905 } 00906 for (i=0; i<lsLength(A->Fair); i++) { 00907 fprintf(fp, ",fair%d", i+1); 00908 } 00909 fprintf(fp, ");"); 00910 00911 fprintf(fp, "\nmodule Buechi (clock"); 00912 for (i=0; i<array_n(InputNames); i++) { 00913 inputName = array_fetch(char *, InputNames, i); 00914 normalString = StringNormalize(inputName); 00915 fprintf(fp, ",%s", normalString); 00916 FREE(normalString); 00917 } 00918 for (i=0; i<lsLength(A->Fair); i++) { 00919 fprintf(fp, ",fair%d", i+1); 00920 } 00921 fprintf(fp, ");"); 00922 00923 00924 /*------------------------------------------------------- 00925 * input clock, in1, in2 ... inN ; 00926 * output fair1, fair2 ... fairN ; 00927 *------------------------------------------------------- 00928 */ 00929 fprintf(fp, "\n\tinput clock"); 00930 for (i=0; i<array_n(InputNames); i++) { 00931 inputName = array_fetch(char *, InputNames, i); 00932 normalString = StringNormalize(inputName); 00933 fprintf(fp, ", %s", normalString); 00934 FREE(normalString); 00935 } 00936 if (lsLength(A->Fair)>0) { 00937 fprintf(fp, ";\n\toutput "); 00938 isFirst = 1; 00939 for (i=0; i<lsLength(A->Fair); i++) { 00940 if (isFirst) { 00941 fprintf(fp, "fair%d", i+1); 00942 isFirst = 0; 00943 } else { 00944 fprintf(fp, ",fair%d", i+1); 00945 } 00946 } 00947 } 00948 fprintf(fp, ";"); 00949 00950 00951 /*------------------------------------------------------- 00952 * type_in1 wire in1; 00953 * type_in2 wire in2; 00954 * ... 00955 * type_states reg state; 00956 * wire[0:logN] sel; 00957 *------------------------------------------------------- 00958 */ 00959 if (network != NIL(Ntk_Network_t)) { 00960 arrayForEachItem(char *, InputNames, i, inputName) { 00961 normalString = StringNormalize(inputName); 00962 00963 ntknode = Ntk_NetworkFindNodeByName(network, inputName); 00964 assert(ntknode != NIL(Ntk_Node_t)); 00965 inputVar = Ntk_NodeReadVariable(ntknode); 00966 00967 is_enum = Var_VariableTestIsEnumerative(inputVar); 00968 range = Var_VariableReadNumValues(inputVar); 00969 00970 if (!is_enum || range > 2) 00971 fprintf(fp, "\n\ttype_%s wire %s;", normalString,normalString); 00972 FREE(normalString); 00973 } 00974 } 00975 fprintf(fp, "\n\ttype_states reg state;"); 00976 if (sel_num >1) { 00977 if (sel_num == 2) 00978 fprintf(fp, "\n\twire sel;"); 00979 else 00980 fprintf(fp, "\n\twire [0:%d] sel;", (int)(ceil(log(sel_num)))-1); 00981 } 00982 00983 /*------------------------------------------------------- 00984 * assign sel = $ND( {0-N} ); 00985 * assign fair = (state==n1 || state==n2 || ... ); 00986 *------------------------------------------------------- 00987 */ 00988 fprintf(fp, "\n\tassign sel = $ND( {0-%d} );", sel_num-1 ); 00989 i = 1; 00990 lsForEachItem(A->Fair, lsgen, FairSet) { 00991 int isFirst = 1; 00992 fprintf(fp, "\n\tassign fair%d = (state==", i++); 00993 st_foreach_item(FairSet, stgen, &vtx, NIL(char *)) { 00994 if (isFirst) 00995 isFirst = 0; 00996 else 00997 fprintf(fp, "|| state=="); 00998 fprintf(fp, "n%d", Ltl_AutomatonVtxGetNodeIdx(vtx)); 00999 } 01000 fprintf(fp, ");"); 01001 } 01002 01003 /*------------------------------------------------------- 01004 * initial state = Init; 01005 *------------------------------------------------------- 01006 */ 01007 fprintf(fp, "\n\tinitial state = %s;", InitStr); 01008 01009 /*------------------------------------------------------- 01010 * always @ (posedge clock) begin 01011 * case (state) 01012 *------------------------------------------------------- 01013 */ 01014 fprintf(fp, "\n\talways @ (posedge clock) begin"); 01015 fprintf(fp, "\n\t\tcase (state)"); 01016 01017 /* for each initial state n2 with label "in1=p !in3=q...", add entry: 01018 *------------------------------------------------------- 01019 * Init: 01020 * if( sel==0 && in1==p && !in3=q ... ) 01021 * state = n2; 01022 * else if( sel==1 && ...) 01023 * state = n3; 01024 * else 01025 * state = Trap; 01026 *------------------------------------------------------ 01027 */ 01028 if (InitIdx == -1) { 01029 fprintf(fp, "\n\t\tInit:"); 01030 sel_cnt = 0; 01031 st_foreach_item(A->Init, stgen, &vtx, NIL(char *)) { 01032 int n2 = Ltl_AutomatonVtxGetNodeIdx(vtx); 01033 LtlSet_t *label = LtlAutomatonVertexGetLabels(vtx); 01034 01035 /* universal label (no label) on n2 */ 01036 if (LtlSetIsEmpty(label)) { 01037 if (st_count(A->Init) == 1 || sel_num == 0) 01038 fprintf(fp,"\n\t\t\tif(1) \n\t\t\t\tstate = n%d;", n2); 01039 else if (sel_cnt == 0) 01040 fprintf(fp,"\n\t\t\tif(sel==%d)\n\t\t\t\tstate = n%d;", 01041 sel_cnt++, n2); 01042 else 01043 fprintf(fp, "\n\t\t\telse if(sel==%d)\n\t\t\t\tstate = n%d;", 01044 sel_cnt++, n2); 01045 }else { 01046 /* there is at least one label on n2 */ 01047 if (st_count(A->Init) == 1 || sel_num == 0) 01048 fprintf(fp, "\n\t\t\tif("); 01049 else if (sel_cnt==0) 01050 fprintf(fp, "\n\t\t\tif(sel==%d && ", sel_cnt++); 01051 else 01052 fprintf(fp, "\n\t\t\telse if(sel==%d && ", sel_cnt++); 01053 01054 isFirst = 1; 01055 for (i=0; i<array_n(A->labelTable); i++) { 01056 if (LtlSetGetElt(label, i)) { 01057 Ctlsp_Formula_t *F = array_fetch(Ctlsp_Formula_t *, 01058 A->labelTable, i); 01059 formulaString = Ctlsp_FormulaConvertToString(F); 01060 normalString = StringNormalize(formulaString); 01061 FREE(formulaString); 01062 01063 if (isFirst) 01064 isFirst = 0; 01065 else 01066 fprintf(fp, " && "); 01067 01068 fprintf(fp, "%s", normalString); 01069 FREE(normalString); 01070 } 01071 } 01072 fprintf(fp, ")\n\t\t\t\tstate = n%d;", n2); 01073 } 01074 } 01075 fprintf(fp, "\n\t\t\telse\n\t\t\t\tstate = Trap;"); 01076 } 01077 01078 /* for each edge (n1, n2) with n2 labelled "in1=p !in3=q...", add entry: 01079 *------------------------------------------------------- 01080 * n1: 01081 * if( sel==0 && in1==p && !in3=q ... ) 01082 * state = n2; 01083 * else if( sel==1 && ...) 01084 * state = n3; 01085 * else 01086 * state = Trap; 01087 *------------------------------------------------------- 01088 */ 01089 foreach_vertex(A->G, lsgen, vtx) { 01090 int n1 = Ltl_AutomatonVtxGetNodeIdx(vtx); 01091 int outDegree = lsLength(g_get_out_edges(vtx)); 01092 fprintf(fp, "\n\t\tn%d:", n1); 01093 sel_cnt = 0; 01094 foreach_out_edge(vtx, lsgen2, edge) { 01095 int n2 = Ltl_AutomatonVtxGetNodeIdx(g_e_dest(edge)); 01096 LtlSet_t *label = LtlAutomatonVertexGetLabels(g_e_dest(edge)); 01097 01098 /* universal label (no label) on n2 */ 01099 if (LtlSetIsEmpty(label)) { 01100 if (outDegree == 1 || sel_num == 0) 01101 fprintf(fp, "\n\t\t\tif(1) \n\t\t\t\tstate = n%d;", n2); 01102 else if (sel_cnt == 0) 01103 fprintf(fp, "\n\t\t\tif(sel==%d) \n\t\t\t\tstate = n%d;", 01104 sel_cnt++, n2); 01105 else 01106 fprintf(fp, "\n\t\t\telse if(sel==%d)\n\t\t\t\tstate = n%d;", 01107 sel_cnt++, n2); 01108 }else { 01109 /* at least 1 label on n2 */ 01110 if (outDegree == 1 || sel_num == 0) 01111 fprintf(fp, "\n\t\t\tif("); 01112 else if (sel_cnt==0) 01113 fprintf(fp, "\n\t\t\tif(sel==%d && ", sel_cnt++); 01114 else 01115 fprintf(fp, "\n\t\t\telse if(sel==%d && ", sel_cnt++); 01116 01117 isFirst = 1; 01118 for (i=0; i<array_n(A->labelTableNegate); i++) { 01119 if (LtlSetGetElt(label, i)) { 01120 Ctlsp_Formula_t *F = array_fetch(Ctlsp_Formula_t *, 01121 A->labelTable, i); 01122 formulaString = Ctlsp_FormulaConvertToString(F); 01123 normalString = StringNormalize(formulaString); 01124 FREE(formulaString); 01125 01126 if (isFirst) isFirst = 0; 01127 else fprintf(fp, " && "); 01128 01129 fprintf(fp, "%s", normalString); 01130 FREE(normalString); 01131 } 01132 } 01133 fprintf(fp, ")\n\t\t\t\tstate = n%d;", n2); 01134 } 01135 } 01136 fprintf(fp, "\n\t\t\telse\n\t\t\t\tstate = Trap;"); 01137 } 01138 01139 /*------------------------------------------------------- 01140 * default: state = Trap; 01141 * endcase 01142 * end 01143 * endmodule 01144 *------------------------------------------------------- 01145 */ 01146 fprintf(fp, "\n\t\tdefault: state = Trap;\n\t\tendcase\n\tend\nendmodule\n"); 01147 01148 /* free the name array */ 01149 array_free(InputNames); 01150 for(i=0; i<array_n(Name2LabelIdx); i++) { 01151 st_table *tmptbl = array_fetch(st_table *, Name2LabelIdx, i); 01152 st_free_table(tmptbl); 01153 } 01154 array_free(Name2LabelIdx); 01155 01156 return result; 01157 } 01158 01159 01172 int 01173 Ltl_AutomatonToSmv( 01174 FILE *fp, 01175 Ntk_Network_t *network, 01176 Ltl_Automaton_t *A) 01177 { 01178 return 1; 01179 } 01180 01181 /*---------------------------------------------------------------------------*/ 01182 /* Definition of static functions */ 01183 /*---------------------------------------------------------------------------*/ 01184 01185 01198 static void 01199 AutomatonGetInputNames( 01200 Ltl_Automaton_t *A, 01201 array_t *InputNames, 01202 array_t *Name2LabelIdx) 01203 { 01204 st_table *Visited = st_init_table(strcmp, st_strhash); 01205 Ctlsp_Formula_t *F; 01206 Ctlsp_FormulaType F_type; 01207 long i, index, counter; 01208 01209 counter = 0; 01210 for (i=0; i<array_n(A->labelTable); i++) { 01211 /* get the positive formula string */ 01212 F = array_fetch(Ctlsp_Formula_t *, A->labelTable, i); 01213 F_type = Ctlsp_FormulaReadType(F); 01214 /* if it's not an AP (just a propositional formula), skip ... */ 01215 if (F_type != Ctlsp_NOT_c && F_type != Ctlsp_ID_c) 01216 continue; 01217 if (F_type == Ctlsp_NOT_c) 01218 F = Ctlsp_FormulaReadLeftChild(F); 01219 /* put into the InputNames array */ 01220 if (!st_lookup(Visited, Ctlsp_FormulaReadVariableName(F),&index)){ 01221 st_table *tmptbl = st_init_table(st_numcmp, st_numhash); 01222 st_insert(tmptbl, (char *) i, (char *)i); 01223 01224 array_insert(st_table *, Name2LabelIdx, counter, tmptbl); 01225 array_insert(char *, InputNames, counter, 01226 Ctlsp_FormulaReadVariableName(F)); 01227 01228 st_insert(Visited, Ctlsp_FormulaReadVariableName(F), (char *)counter++); 01229 }else { 01230 st_table *tmptbl = array_fetch(st_table *, Name2LabelIdx, index); 01231 st_insert(tmptbl, (char *)i, (char *)i); 01232 } 01233 } 01234 01235 st_free_table(Visited); 01236 } 01237 01251 static int 01252 AutomatonCountSelector( 01253 Ltl_Automaton_t *A) 01254 { 01255 int sel_num = st_count(A->Init); 01256 int local_num; 01257 lsGen lsgen; 01258 vertex_t *vtx; 01259 01260 foreach_vertex(A->G, lsgen, vtx) { 01261 local_num = lsLength(g_get_out_edges(vtx)); 01262 if (sel_num < local_num) 01263 sel_num = local_num; 01264 } 01265 01266 return sel_num; 01267 } 01268 01269 01285 static int 01286 AutomatonComputeInitState( 01287 Ltl_Automaton_t *A) 01288 { 01289 int initIdx = -1; 01290 vertex_t *vtx, *vtx2, *s; 01291 edge_t *e; 01292 st_generator *stgen, *stgen2; 01293 lsGen lsgen; 01294 01295 st_foreach_item(A->Init, stgen, &vtx, NIL(char *)) { 01296 int isInit = 1; 01297 /* first, compute the set of sucessors of 'vtx' */ 01298 lsList Img = g_get_out_edges(vtx); 01299 st_table *uTable = st_init_table(st_ptrcmp, st_ptrhash); 01300 lsForEachItem(Img, lsgen, e) { 01301 s = g_e_dest(e); 01302 st_insert(uTable, s, s); 01303 } 01304 /* then, test if it is equivalent to 'A->Init': No more, No less */ 01305 st_foreach_item(A->Init, stgen2, &vtx2, NIL(char *)) { 01306 if (!st_is_member(uTable, vtx2)) { 01307 isInit = 0; 01308 st_free_gen(stgen2); 01309 break; 01310 } 01311 } 01312 if (isInit) { 01313 st_foreach_item(uTable, stgen2, &vtx2, NIL(char *)) { 01314 if (!st_is_member(A->Init, vtx2)) { 01315 isInit = 0; 01316 st_free_gen(stgen2); 01317 break; 01318 } 01319 } 01320 } 01321 st_free_table(uTable); 01322 01323 if (isInit == 1) { 01324 initIdx = ((Ltl_AutomatonNode_t *)vtx->user_data)->index; 01325 st_free_gen(stgen); 01326 break; 01327 } 01328 } 01329 01330 return initIdx; 01331 } 01332 01343 /*static lsList 01344 AutomatonLabelGetCubes( 01345 Ltl_Automaton_t *A, 01346 LtlSet_t *compositeLabel, 01347 Ntk_Network_t *network) 01348 { 01349 LtlTableau_t *tableau = A->tableau; 01350 int size = tableau->labelIndex; 01351 LtlSet_t *tempSet, *tempSet2, *tempSet3; 01352 lsList conjunctList; 01353 lsList disjunctList; 01354 lsList tempList, tempList2, tempList3; 01355 lsGen lsgen, lsgen2; 01356 int i; 01357 01358 if (LtlSetIsEmpty(compositeLabel)) { 01359 tempList = lsCreate(); 01360 lsNewEnd(tempList, (lsGeneric)LtlSetNew(size), (lsHandle *)0); 01361 return tempList; 01362 } 01363 01364 first, get a list of disjunctLists (which should be conjoin together 01365 to form a cartesian product 01366 01367 conjunctList = lsCreate(); 01368 tempSet = LtlSetNew(size); 01369 for (i=0; i<size; i++) { 01370 if (LtlSetGetElt(compositeLabel, i)) { 01371 if (Ctlsp_LtlFormulaIsAtomicPropositional(tableau->labelTable[i])) 01372 LtlSetSetElt(tempSet, i); 01373 else { 01374 disjunctList = GetCubes_Aux(A, i); 01375 lsNewEnd(conjunctList, (lsGeneric)disjunctList, (lsHandle *)0); 01376 } 01377 } 01378 } 01379 if (LtlSetIsEmpty(tempSet)) 01380 LtlSetFree(tempSet); 01381 else { 01382 disjunctList = lsCreate(); 01383 lsNewEnd(disjunctList, (lsGeneric)tempSet, (lsHandle *)0); 01384 lsNewBegin(conjunctList, (lsGeneric)disjunctList, (lsHandle *)0); 01385 } 01386 01387 01388 compute the cartesian product of the conjuncts 01389 while(lsLength(conjunctList)>1) { 01390 lsList thisList; 01391 lsList leftList; 01392 lsList rightList; 01393 01394 lsDelBegin(conjunctList, (lsGeneric *)&leftList); 01395 lsDelBegin(conjunctList, (lsGeneric *)&rightList); 01396 form the cartesian product of the two lists 01397 thisList = lsCreate(); 01398 lsForEachItem(leftList, lsgen, tempSet) { 01399 lsForEachItem(rightList, lsgen2, tempSet2) { 01400 tempSet3 = LtlSetNew(size); 01401 LtlSetOR(tempSet3, tempSet, tempSet2); 01402 01403 if (0) 01404 fprintf(vis_stdout, 01405 "tempSet = %d tempSet2 = %d tempSet3 = %d\n", 01406 LtlSetIsEmpty(tempSet), 01407 LtlSetIsEmpty(tempSet2), 01408 LtlSetIsEmpty(tempSet3)); 01409 01410 if no contradictory, retain it 01411 if (LtlSetIsContradictory(tempSet3,tableau->labelTableNegate)) 01412 LtlSetFree(tempSet3); 01413 else 01414 lsNewEnd(thisList, (lsGeneric)tempSet3, (lsHandle *)0); 01415 } 01416 } 01417 lsDestroy(leftList, (void (*)(lsGeneric))LtlSetFree); 01418 lsDestroy(rightList, (void (*)(lsGeneric))LtlSetFree); 01419 01420 lsNewBegin(conjunctList, (lsGeneric)thisList, (lsHandle *)0); 01421 } 01422 01423 lsDelBegin(conjunctList, (lsGeneric *)&tempList); 01424 lsDestroy(conjunctList, (void(*)(lsGeneric))0); 01425 01426 remove redundant minterms from 'tempList' 01427 tempList3 = lsCreate(); 01428 tempList2 = lsCopy(tempList, (lsGeneric(*)(lsGeneric))0); 01429 lsForEachItem(tempList, lsgen, tempSet) { 01430 If tempSet is a superset of other cubes, discard it 01431 int flag = 1; 01432 lsForEachItem(tempList2, lsgen2, tempSet2) { 01433 if (tempSet != tempSet2 && LtlSetInclude(tempSet, tempSet2)) { 01434 flag = 0; 01435 lsFinish(lsgen2); 01436 break; 01437 } 01438 } 01439 if (!flag) continue; 01440 If tempSet is an "emptyset" (for example, comtains both 01441 signal=0 and signal=1, where signal has only these two 01442 values), discard it 01443 01444 flag = 1; 01445 if (network != NIL(Ntk_Network_t)) { 01446 Fsm_Fsm_t *fsm = Fsm_NetworkReadOrCreateFsm(network); 01447 if (fsm != NIL(Fsm_Fsm_t)) { 01448 mdd_t *minterm = LtlSetModelCheckFormulae(tempSet, 01449 A->labelTable, 01450 fsm); 01451 flag = !(mdd_is_tautology(minterm, 0)); 01452 mdd_free(minterm); 01453 } 01454 } 01455 if (!flag) continue; 01456 otherwise, save a copy into tempList3 01457 lsNewBegin(tempList3, (lsGeneric)LtlSetCopy(tempSet), (lsHandle *)0); 01458 } 01459 lsDestroy(tempList2, (void(*)(lsGeneric))0); 01460 lsDestroy(tempList, (void (*)(lsGeneric))LtlSetFree); 01461 tempList = tempList3; 01462 01463 return tempList; 01464 } 01465 */ 01466 01478 static lsList 01479 GetCubes_Aux( 01480 Ltl_Automaton_t *A, 01481 int index) 01482 { 01483 Ctlsp_Formula_t *F = A->tableau->labelTable[index]; 01484 int size = A->tableau->labelIndex; 01485 lsList leftList; 01486 lsList rightList; 01487 lsList thisList =(lsList)0; 01488 lsGen lsgen, lsgen2; 01489 LtlSet_t *tempSet, *tempSet2, *tempSet3; 01490 01491 if (Ctlsp_LtlFormulaIsAtomicPropositional(F)) { 01492 thisList = lsCreate(); 01493 tempSet = LtlSetNew(size); 01494 LtlSetSetElt(tempSet, Ctlsp_FormulaReadLabelIndex(F)); 01495 lsNewEnd(thisList, (lsGeneric)tempSet, (lsHandle *)0); 01496 }else { 01497 Ctlsp_Formula_t *F_left = Ctlsp_FormulaReadLeftChild(F); 01498 Ctlsp_Formula_t *F_right = Ctlsp_FormulaReadRightChild(F); 01499 01500 switch(Ctlsp_FormulaReadType(F)) { 01501 case Ctlsp_OR_c: 01502 leftList = GetCubes_Aux(A, Ctlsp_FormulaReadLabelIndex(F_left)); 01503 rightList = GetCubes_Aux(A, Ctlsp_FormulaReadLabelIndex(F_right)); 01504 /* merge two list together */ 01505 thisList = leftList; 01506 lsForEachItem(rightList, lsgen, tempSet) { 01507 lsNewEnd(thisList, (lsGeneric)tempSet, (lsHandle *)0); 01508 } 01509 lsDestroy(rightList, (void (*)(lsGeneric))0); 01510 break; 01511 case Ctlsp_AND_c: 01512 leftList = GetCubes_Aux(A, Ctlsp_FormulaReadLabelIndex(F_left)); 01513 rightList = GetCubes_Aux(A, Ctlsp_FormulaReadLabelIndex(F_right)); 01514 /* generate the cartesian product of the two lists */ 01515 thisList = lsCreate(); 01516 lsForEachItem(leftList, lsgen, tempSet) { 01517 lsForEachItem(rightList, lsgen2, tempSet2) { 01518 tempSet3 = LtlSetNew(size); 01519 LtlSetOR(tempSet3, tempSet, tempSet2); 01520 lsNewEnd(thisList, (lsGeneric)tempSet3, (lsHandle *)0); 01521 } 01522 } 01523 lsDestroy(leftList, (void (*)(lsGeneric))LtlSetFree); 01524 lsDestroy(rightList, (void (*)(lsGeneric))LtlSetFree); 01525 break; 01526 default: 01527 assert(0); 01528 break; 01529 } 01530 } 01531 01532 return thisList; 01533 } 01534 01535 01551 static char * 01552 StringNormalize( 01553 char *inputString) 01554 { 01555 char *normalString = ALLOC(char, strlen(inputString)*2); 01556 char *from = inputString; 01557 char *to = normalString; 01558 01559 while( *from ) { 01560 switch(*from) { 01561 case '=': 01562 *(to++) = '='; 01563 *(to) = '='; 01564 break; 01565 case '+': 01566 *(to++) = '|'; 01567 *(to) = '|'; 01568 break; 01569 case '*': 01570 *(to++) = '&'; 01571 *(to) = '&'; 01572 break; 01573 case '.': 01574 case '<': 01575 case '>': 01576 *(to) = '_'; 01577 break; 01578 default: 01579 *(to) = *from; 01580 } 01581 from++; 01582 to++; 01583 } 01584 *to = '\0'; 01585 01586 return normalString; 01587 } 01588 01610 static void 01611 AutomatonVtxLabelToBlifMv( 01612 FILE *fp, 01613 Ltl_Automaton_t *A, 01614 vertex_t *vtx) 01615 { 01616 /* each 'compLabel' is a "propositional formulae" */ 01617 LtlSet_t *compositeLabel = LtlAutomatonVertexGetLabels(vtx); 01618 int idx = Ltl_AutomatonVtxGetNodeIdx(vtx); 01619 int size = A->tableau->labelIndex; 01620 int i; 01621 st_table *CreatedSignals; 01622 01623 if (LtlSetIsEmpty(compositeLabel)) { 01624 fprintf(fp, "\n.table n%d_label$AUT\n1\n", idx); 01625 return; 01626 } 01627 01628 /* first, we should create the signals for each subformula */ 01629 CreatedSignals = st_init_table(st_ptrcmp, st_ptrhash); 01630 for (i=0; i<size; i++) { 01631 if (LtlSetGetElt(compositeLabel, i)) 01632 VtxLabelToBlifMv_Aux(fp, A, idx, i, CreatedSignals); 01633 } 01634 st_free_table(CreatedSignals); 01635 01636 /* the label signal is the AND or all the conjuncts */ 01637 fprintf(fp, "\n.table "); 01638 for (i=0; i<size; i++) { 01639 if (LtlSetGetElt(compositeLabel, i)) 01640 fprintf(fp, "n%d_%d_label$AUT ", idx, i); 01641 } 01642 fprintf(fp, " -> n%d_label$AUT\n.default 0\n", idx); 01643 for (i=0; i<size; i++) { 01644 if (LtlSetGetElt(compositeLabel, i)) 01645 fprintf(fp, "1 "); 01646 } 01647 fprintf(fp, "1\n"); 01648 01649 } 01650 01660 static void 01661 VtxLabelToBlifMv_Aux( 01662 FILE *fp, 01663 Ltl_Automaton_t *A, 01664 int node_idx, 01665 int index, 01666 st_table *CreatedSignals) 01667 { 01668 Ctlsp_Formula_t *F = A->tableau->labelTable[index]; 01669 Ctlsp_Formula_t *F_left, *F_right; 01670 int l_index, r_index; 01671 01672 if (st_is_member(CreatedSignals, F)) 01673 return; 01674 else 01675 st_insert(CreatedSignals, F, (char *)0); 01676 01677 switch(Ctlsp_FormulaReadType(F)) { 01678 case Ctlsp_ID_c: 01679 fprintf(fp, "\n.table %s -> n%d_%d_label$AUT\n.default 0\n%s 1", 01680 (char *)Ctlsp_FormulaReadVariableName(F), 01681 node_idx, index, 01682 (char *)Ctlsp_FormulaReadValueName(F)); 01683 break; 01684 case Ctlsp_NOT_c: 01685 F_left = Ctlsp_FormulaReadLeftChild(F); 01686 fprintf(fp, "\n.table %s -> n%d_%d_label$AUT\n.default 1\n%s 0", 01687 (char *)Ctlsp_FormulaReadVariableName(F_left), 01688 node_idx, index, 01689 (char *)Ctlsp_FormulaReadValueName(F_left)); 01690 break; 01691 case Ctlsp_AND_c: 01692 F_left = Ctlsp_FormulaReadLeftChild(F); 01693 F_right = Ctlsp_FormulaReadRightChild(F); 01694 l_index = Ctlsp_FormulaReadLabelIndex(F_left); 01695 r_index = Ctlsp_FormulaReadLabelIndex(F_right); 01696 VtxLabelToBlifMv_Aux(fp, A, node_idx, l_index, CreatedSignals); 01697 VtxLabelToBlifMv_Aux(fp, A, node_idx, r_index, CreatedSignals); 01698 fprintf(fp,"\n.table n%d_%d_label$AUT n%d_%d_label$AUT -> n%d_%d_label$AUT\n.default 0\n1 1 1", 01699 node_idx, l_index, 01700 node_idx, r_index, 01701 node_idx, index); 01702 break; 01703 case Ctlsp_OR_c: 01704 F_left = Ctlsp_FormulaReadLeftChild(F); 01705 F_right = Ctlsp_FormulaReadRightChild(F); 01706 l_index = Ctlsp_FormulaReadLabelIndex(F_left); 01707 r_index = Ctlsp_FormulaReadLabelIndex(F_right); 01708 VtxLabelToBlifMv_Aux(fp, A, node_idx, l_index, CreatedSignals); 01709 VtxLabelToBlifMv_Aux(fp, A, node_idx, r_index, CreatedSignals); 01710 fprintf(fp, 01711 "\n.table n%d_%d_label$AUT n%d_%d_label$AUT -> n%d_%d_label$AUT\n.default 0\n1 - 1\n- 1 1", 01712 node_idx, l_index, 01713 node_idx, r_index, 01714 node_idx, index); 01715 break; 01716 default: 01717 fail("unkown formula type"); 01718 } 01719 } 01720 01721 01722