/***** ltl3ba : trans.c *****/ /* Written by Denis Oddoux, LIAFA, France */ /* Copyright (c) 2001 Denis Oddoux */ /* Modified by Paul Gastin, LSV, France */ /* Copyright (c) 2007 Paul Gastin */ /* Modified by Tomas Babiak, FI MU, Brno, Czech Republic */ /* Copyright (c) 2012 Tomas Babiak */ /* */ /* This program is free software; you can redistribute it and/or modify */ /* it under the terms of the GNU General Public License as published by */ /* the Free Software Foundation; either version 2 of the License, or */ /* (at your option) any later version. */ /* */ /* This program is distributed in the hope that it will be useful, */ /* but WITHOUT ANY WARRANTY; without even the implied warranty of */ /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */ /* GNU General Public License for more details. */ /* */ /* You should have received a copy of the GNU General Public License */ /* along with this program; if not, write to the Free Software */ /* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA*/ /* */ /* Based on the translation algorithm by Gastin and Oddoux, */ /* presented at the 13th International Conference on Computer Aided */ /* Verification, CAV 2001, Paris, France. */ /* Proceedings - LNCS 2102, pp. 53-65 */ /* */ /* Modifications based on paper by */ /* T. Babiak, M. Kretinsky, V. Rehak, and J. Strejcek, */ /* LTL to Buchi Automata Translation: Fast and More Deterministic */ /* presented at the 18th International Conference on Tools and */ /* Algorithms for the Construction and Analysis of Systems (TACAS 2012) */ /* */ #include "ltl3ba.h" #include extern int tl_verbose, tl_terse, tl_errs; extern FILE *tl_out; int Stack_mx=0, Max_Red=0, Total=0; static char dumpbuf[2048]; void reinitTrans() { Stack_mx=0, Max_Red=0, Total=0; memset( dumpbuf, 0, 2048 ); } #ifdef NXT int only_nxt(Node *n) { switch (n->ntyp) { case NEXT: return 1; case OR: case AND: return only_nxt(n->rgt) && only_nxt(n->lft); default: return 0; } } #endif int dump_cond(Node *pp, Node *r, int first) { Node *q; int frst = first; if (!pp) return frst; q = dupnode(pp); q = rewrite(q); if (q->ntyp == PREDICATE || q->ntyp == NOT #ifndef NXT || q->ntyp == OR #endif || q->ntyp == FALSE) { if (!frst) fprintf(tl_out, " && "); dump(q); frst = 0; #ifdef NXT } else if (q->ntyp == OR) { if (!frst) fprintf(tl_out, " && "); fprintf(tl_out, "(("); frst = dump_cond(q->lft, r, 1); if (!frst) fprintf(tl_out, ") || ("); else { if (only_nxt(q->lft)) { fprintf(tl_out, "1))"); return 0; } } frst = dump_cond(q->rgt, r, 1); if (frst) { if (only_nxt(q->rgt)) fprintf(tl_out, "1"); else fprintf(tl_out, "0"); frst = 0; } fprintf(tl_out, "))"); #endif } else if (q->ntyp == V_OPER && !anywhere(AND, q->rgt, r)) { frst = dump_cond(q->rgt, r, frst); } else if (q->ntyp == AND) { frst = dump_cond(q->lft, r, frst); frst = dump_cond(q->rgt, r, frst); } return frst; } static void sdump(Node *n) { switch (n->ntyp) { case PREDICATE: strcat(dumpbuf, n->sym->name); break; case U_OPER: strcat(dumpbuf, "U"); goto common2; case V_OPER: strcat(dumpbuf, "V"); goto common2; case OR: strcat(dumpbuf, "|"); goto common2; case AND: strcat(dumpbuf, "&"); common2: sdump(n->rgt); common1: sdump(n->lft); break; #ifdef NXT case NEXT: strcat(dumpbuf, "X"); goto common1; #endif case NOT: strcat(dumpbuf, "!"); goto common1; case TRUE: strcat(dumpbuf, "T"); break; case FALSE: strcat(dumpbuf, "F"); break; default: strcat(dumpbuf, "?"); break; } } Symbol * DoDump(Node *n) { if (!n) return ZS; if (n->ntyp == PREDICATE) return n->sym; dumpbuf[0] = '\0'; sdump(n); return tl_lookup(dumpbuf); } void trans(Node *p) { if (!p || tl_errs) return; if (tl_verbose || tl_terse) { fprintf(tl_out, "\t/* Normlzd: "); dump(p); fprintf(tl_out, " */\n"); } if (tl_terse) return; mk_alternating(p); mk_generalized(); mk_buchi(); }