You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

653 lines
20 KiB

  1. /***** ltl2ba : generalized.c *****/
  2. /* Written by Denis Oddoux, LIAFA, France */
  3. /* Copyright (c) 2001 Denis Oddoux */
  4. /* Modified by Paul Gastin, LSV, France */
  5. /* Copyright (c) 2007 Paul Gastin */
  6. /* */
  7. /* This program is free software; you can redistribute it and/or modify */
  8. /* it under the terms of the GNU General Public License as published by */
  9. /* the Free Software Foundation; either version 2 of the License, or */
  10. /* (at your option) any later version. */
  11. /* */
  12. /* This program is distributed in the hope that it will be useful, */
  13. /* but WITHOUT ANY WARRANTY; without even the implied warranty of */
  14. /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
  15. /* GNU General Public License for more details. */
  16. /* */
  17. /* You should have received a copy of the GNU General Public License */
  18. /* along with this program; if not, write to the Free Software */
  19. /* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA*/
  20. /* */
  21. /* Based on the translation algorithm by Gastin and Oddoux, */
  22. /* presented at the 13th International Conference on Computer Aided */
  23. /* Verification, CAV 2001, Paris, France. */
  24. /* Proceedings - LNCS 2102, pp. 53-65 */
  25. /* */
  26. /* Send bug-reports and/or questions to Paul Gastin */
  27. /* http://www.lsv.ens-cachan.fr/~gastin */
  28. #include "ltl2ba.h"
  29. /********************************************************************\
  30. |* Structures and shared variables *|
  31. \********************************************************************/
  32. extern FILE *tl_out;
  33. extern ATrans **transition;
  34. extern struct rusage tr_debut, tr_fin;
  35. extern struct timeval t_diff;
  36. extern int tl_verbose, tl_stats, tl_simp_diff, tl_simp_fly, tl_fjtofj,
  37. tl_simp_scc, *final_set, node_id;
  38. extern char **sym_table;
  39. GState *gstack, *gremoved, *gstates, **init;
  40. GScc *scc_stack;
  41. int init_size = 0, gstate_id = 1, gstate_count = 0, gtrans_count = 0;
  42. int *fin, *final, rank, scc_id, scc_size, *bad_scc;
  43. void print_generalized();
  44. /********************************************************************\
  45. |* Simplification of the generalized Buchi automaton *|
  46. \********************************************************************/
  47. void free_gstate(GState *s) /* frees a state and its transitions */
  48. {
  49. free_gtrans(s->trans->nxt, s->trans, 1);
  50. tfree(s->nodes_set);
  51. tfree(s);
  52. }
  53. GState *remove_gstate(GState *s, GState *s1) /* removes a state */
  54. {
  55. GState *prv = s->prv;
  56. s->prv->nxt = s->nxt;
  57. s->nxt->prv = s->prv;
  58. free_gtrans(s->trans->nxt, s->trans, 0);
  59. s->trans = (GTrans *)0;
  60. tfree(s->nodes_set);
  61. s->nodes_set = 0;
  62. s->nxt = gremoved->nxt;
  63. gremoved->nxt = s;
  64. s->prv = s1;
  65. for(s1 = gremoved->nxt; s1 != gremoved; s1 = s1->nxt)
  66. if(s1->prv == s)
  67. s1->prv = s->prv;
  68. return prv;
  69. }
  70. void copy_gtrans(GTrans *from, GTrans *to) /* copies a transition */
  71. {
  72. to->to = from->to;
  73. copy_set(from->pos, to->pos, 1);
  74. copy_set(from->neg, to->neg, 1);
  75. copy_set(from->final, to->final, 0);
  76. }
  77. int same_gtrans(GState *a, GTrans *s, GState *b, GTrans *t, int use_scc)
  78. { /* returns 1 if the transitions are identical */
  79. if((s->to != t->to) ||
  80. ! same_sets(s->pos, t->pos, 1) ||
  81. ! same_sets(s->neg, t->neg, 1))
  82. return 0; /* transitions differ */
  83. if(same_sets(s->final, t->final, 0))
  84. return 1; /* same transitions exactly */
  85. /* next we check whether acceptance conditions may be ignored */
  86. if( use_scc &&
  87. ( in_set(bad_scc, a->incoming) ||
  88. in_set(bad_scc, b->incoming) ||
  89. (a->incoming != s->to->incoming) ||
  90. (b->incoming != t->to->incoming) ) )
  91. return 1;
  92. return 0;
  93. /* below is the old test to check whether acceptance conditions may be ignored */
  94. if(!use_scc)
  95. return 0; /* transitions differ */
  96. if( (a->incoming == b->incoming) && (a->incoming == s->to->incoming) )
  97. return 0; /* same scc: acceptance conditions must be taken into account */
  98. /* if scc(a)=scc(b)>scc(s->to) then acceptance conditions need not be taken into account */
  99. /* if scc(a)>scc(b) and scc(a) is non-trivial then all_gtrans_match(a,b,use_scc) will fail */
  100. /* if scc(a) is trivial then acceptance conditions of transitions from a need not be taken into account */
  101. return 1; /* same transitions up to acceptance conditions */
  102. }
  103. int simplify_gtrans() /* simplifies the transitions */
  104. {
  105. int changed = 0;
  106. GState *s;
  107. GTrans *t, *t1;
  108. if(tl_stats) getrusage(RUSAGE_SELF, &tr_debut);
  109. for(s = gstates->nxt; s != gstates; s = s->nxt) {
  110. t = s->trans->nxt;
  111. while(t != s->trans) { /* tries to remove t */
  112. copy_gtrans(t, s->trans);
  113. t1 = s->trans->nxt;
  114. while ( !((t != t1)
  115. && (t1->to == t->to)
  116. && included_set(t1->pos, t->pos, 1)
  117. && included_set(t1->neg, t->neg, 1)
  118. && (included_set(t->final, t1->final, 0) /* acceptance conditions of t are also in t1 or may be ignored */
  119. || (tl_simp_scc && ((s->incoming != t->to->incoming) || in_set(bad_scc, s->incoming))))) )
  120. t1 = t1->nxt;
  121. if(t1 != s->trans) { /* remove transition t */
  122. GTrans *free = t->nxt;
  123. t->to = free->to;
  124. copy_set(free->pos, t->pos, 1);
  125. copy_set(free->neg, t->neg, 1);
  126. copy_set(free->final, t->final, 0);
  127. t->nxt = free->nxt;
  128. if(free == s->trans) s->trans = t;
  129. free_gtrans(free, 0, 0);
  130. changed++;
  131. }
  132. else
  133. t = t->nxt;
  134. }
  135. }
  136. if(tl_stats) {
  137. getrusage(RUSAGE_SELF, &tr_fin);
  138. timeval_subtract (&t_diff, &tr_fin.ru_utime, &tr_debut.ru_utime);
  139. fprintf(tl_out, "\nSimplification of the generalized Buchi automaton - transitions: %i.%06is",
  140. t_diff.tv_sec, t_diff.tv_usec);
  141. fprintf(tl_out, "\n%i transitions removed\n", changed);
  142. }
  143. return changed;
  144. }
  145. void retarget_all_gtrans()
  146. { /* redirects transitions before removing a state from the automaton */
  147. GState *s;
  148. GTrans *t;
  149. int i;
  150. for (i = 0; i < init_size; i++)
  151. if (init[i] && !init[i]->trans) /* init[i] has been removed */
  152. init[i] = init[i]->prv;
  153. for (s = gstates->nxt; s != gstates; s = s->nxt)
  154. for (t = s->trans->nxt; t != s->trans; )
  155. if (!t->to->trans) { /* t->to has been removed */
  156. t->to = t->to->prv;
  157. if(!t->to) { /* t->to has no transitions */
  158. GTrans *free = t->nxt;
  159. t->to = free->to;
  160. copy_set(free->pos, t->pos, 1);
  161. copy_set(free->neg, t->neg, 1);
  162. copy_set(free->final, t->final, 0);
  163. t->nxt = free->nxt;
  164. if(free == s->trans) s->trans = t;
  165. free_gtrans(free, 0, 0);
  166. }
  167. else
  168. t = t->nxt;
  169. }
  170. else
  171. t = t->nxt;
  172. while(gremoved->nxt != gremoved) { /* clean the 'removed' list */
  173. s = gremoved->nxt;
  174. gremoved->nxt = gremoved->nxt->nxt;
  175. if(s->nodes_set) tfree(s->nodes_set);
  176. tfree(s);
  177. }
  178. }
  179. int all_gtrans_match(GState *a, GState *b, int use_scc)
  180. { /* decides if the states are equivalent */
  181. GTrans *s, *t;
  182. for (s = a->trans->nxt; s != a->trans; s = s->nxt) {
  183. /* all transitions from a appear in b */
  184. copy_gtrans(s, b->trans);
  185. t = b->trans->nxt;
  186. while(!same_gtrans(a, s, b, t, use_scc)) t = t->nxt;
  187. if(t == b->trans) return 0;
  188. }
  189. for (t = b->trans->nxt; t != b->trans; t = t->nxt) {
  190. /* all transitions from b appear in a */
  191. copy_gtrans(t, a->trans);
  192. s = a->trans->nxt;
  193. while(!same_gtrans(a, s, b, t, use_scc)) s = s->nxt;
  194. if(s == a->trans) return 0;
  195. }
  196. return 1;
  197. }
  198. int simplify_gstates() /* eliminates redundant states */
  199. {
  200. int changed = 0;
  201. GState *a, *b;
  202. if(tl_stats) getrusage(RUSAGE_SELF, &tr_debut);
  203. for(a = gstates->nxt; a != gstates; a = a->nxt) {
  204. if(a->trans == a->trans->nxt) { /* a has no transitions */
  205. a = remove_gstate(a, (GState *)0);
  206. changed++;
  207. continue;
  208. }
  209. gstates->trans = a->trans;
  210. b = a->nxt;
  211. while(!all_gtrans_match(a, b, tl_simp_scc)) b = b->nxt;
  212. if(b != gstates) { /* a and b are equivalent */
  213. /* if scc(a)>scc(b) and scc(a) is non-trivial then all_gtrans_match(a,b,use_scc) must fail */
  214. if(a->incoming > b->incoming) /* scc(a) is trivial */
  215. a = remove_gstate(a, b);
  216. else /* either scc(a)=scc(b) or scc(b) is trivial */
  217. remove_gstate(b, a);
  218. changed++;
  219. }
  220. }
  221. retarget_all_gtrans();
  222. if(tl_stats) {
  223. getrusage(RUSAGE_SELF, &tr_fin);
  224. timeval_subtract (&t_diff, &tr_fin.ru_utime, &tr_debut.ru_utime);
  225. fprintf(tl_out, "\nSimplification of the generalized Buchi automaton - states: %i.%06is",
  226. t_diff.tv_sec, t_diff.tv_usec);
  227. fprintf(tl_out, "\n%i states removed\n", changed);
  228. }
  229. return changed;
  230. }
  231. int gdfs(GState *s) {
  232. GTrans *t;
  233. GScc *c;
  234. GScc *scc = (GScc *)tl_emalloc(sizeof(GScc));
  235. scc->gstate = s;
  236. scc->rank = rank;
  237. scc->theta = rank++;
  238. scc->nxt = scc_stack;
  239. scc_stack = scc;
  240. s->incoming = 1;
  241. for (t = s->trans->nxt; t != s->trans; t = t->nxt) {
  242. if (t->to->incoming == 0) {
  243. int result = gdfs(t->to);
  244. scc->theta = min(scc->theta, result);
  245. }
  246. else {
  247. for(c = scc_stack->nxt; c != 0; c = c->nxt)
  248. if(c->gstate == t->to) {
  249. scc->theta = min(scc->theta, c->rank);
  250. break;
  251. }
  252. }
  253. }
  254. if(scc->rank == scc->theta) {
  255. while(scc_stack != scc) {
  256. scc_stack->gstate->incoming = scc_id;
  257. scc_stack = scc_stack->nxt;
  258. }
  259. scc->gstate->incoming = scc_id++;
  260. scc_stack = scc->nxt;
  261. }
  262. return scc->theta;
  263. }
  264. void simplify_gscc() {
  265. GState *s;
  266. GTrans *t;
  267. int i, **scc_final;
  268. rank = 1;
  269. scc_stack = 0;
  270. scc_id = 1;
  271. if(gstates == gstates->nxt) return;
  272. for(s = gstates->nxt; s != gstates; s = s->nxt)
  273. s->incoming = 0; /* state color = white */
  274. for(i = 0; i < init_size; i++)
  275. if(init[i] && init[i]->incoming == 0)
  276. gdfs(init[i]);
  277. scc_final = (int **)tl_emalloc(scc_id * sizeof(int *));
  278. for(i = 0; i < scc_id; i++)
  279. scc_final[i] = make_set(-1,0);
  280. for(s = gstates->nxt; s != gstates; s = s->nxt)
  281. if(s->incoming == 0)
  282. s = remove_gstate(s, 0);
  283. else
  284. for (t = s->trans->nxt; t != s->trans; t = t->nxt)
  285. if(t->to->incoming == s->incoming)
  286. merge_sets(scc_final[s->incoming], t->final, 0);
  287. scc_size = (scc_id + 1) / (8 * sizeof(int)) + 1;
  288. bad_scc=make_set(-1,2);
  289. for(i = 0; i < scc_id; i++)
  290. if(!included_set(final_set, scc_final[i], 0))
  291. add_set(bad_scc, i);
  292. for(i = 0; i < scc_id; i++)
  293. tfree(scc_final[i]);
  294. tfree(scc_final);
  295. }
  296. /********************************************************************\
  297. |* Generation of the generalized Buchi automaton *|
  298. \********************************************************************/
  299. int is_final(int *from, ATrans *at, int i) /*is the transition final for i ?*/
  300. {
  301. ATrans *t;
  302. int in_to;
  303. if((tl_fjtofj && !in_set(at->to, i)) ||
  304. (!tl_fjtofj && !in_set(from, i))) return 1;
  305. in_to = in_set(at->to, i);
  306. rem_set(at->to, i);
  307. for(t = transition[i]; t; t = t->nxt)
  308. if(included_set(t->to, at->to, 0) &&
  309. included_set(t->pos, at->pos, 1) &&
  310. included_set(t->neg, at->neg, 1)) {
  311. if(in_to) add_set(at->to, i);
  312. return 1;
  313. }
  314. if(in_to) add_set(at->to, i);
  315. return 0;
  316. }
  317. GState *find_gstate(int *set, GState *s)
  318. { /* finds the corresponding state, or creates it */
  319. if(same_sets(set, s->nodes_set, 0)) return s; /* same state */
  320. s = gstack->nxt; /* in the stack */
  321. gstack->nodes_set = set;
  322. while(!same_sets(set, s->nodes_set, 0))
  323. s = s->nxt;
  324. if(s != gstack) return s;
  325. s = gstates->nxt; /* in the solved states */
  326. gstates->nodes_set = set;
  327. while(!same_sets(set, s->nodes_set, 0))
  328. s = s->nxt;
  329. if(s != gstates) return s;
  330. s = gremoved->nxt; /* in the removed states */
  331. gremoved->nodes_set = set;
  332. while(!same_sets(set, s->nodes_set, 0))
  333. s = s->nxt;
  334. if(s != gremoved) return s;
  335. s = (GState *)tl_emalloc(sizeof(GState)); /* creates a new state */
  336. s->id = (empty_set(set, 0)) ? 0 : gstate_id++;
  337. s->incoming = 0;
  338. s->nodes_set = dup_set(set, 0);
  339. s->trans = emalloc_gtrans(); /* sentinel */
  340. s->trans->nxt = s->trans;
  341. s->nxt = gstack->nxt;
  342. gstack->nxt = s;
  343. return s;
  344. }
  345. void make_gtrans(GState *s) { /* creates all the transitions from a state */
  346. int i, *list, state_trans = 0, trans_exist = 1;
  347. GState *s1;
  348. GTrans *t;
  349. ATrans *t1, *free;
  350. AProd *prod = (AProd *)tl_emalloc(sizeof(AProd)); /* initialization */
  351. prod->nxt = prod;
  352. prod->prv = prod;
  353. prod->prod = emalloc_atrans();
  354. clear_set(prod->prod->to, 0);
  355. clear_set(prod->prod->pos, 1);
  356. clear_set(prod->prod->neg, 1);
  357. prod->trans = prod->prod;
  358. prod->trans->nxt = prod->prod;
  359. list = list_set(s->nodes_set, 0);
  360. for(i = 1; i < list[0]; i++) {
  361. AProd *p = (AProd *)tl_emalloc(sizeof(AProd));
  362. p->astate = list[i];
  363. p->trans = transition[list[i]];
  364. if(!p->trans) trans_exist = 0;
  365. p->prod = merge_trans(prod->nxt->prod, p->trans);
  366. p->nxt = prod->nxt;
  367. p->prv = prod;
  368. p->nxt->prv = p;
  369. p->prv->nxt = p;
  370. }
  371. while(trans_exist) { /* calculates all the transitions */
  372. AProd *p = prod->nxt;
  373. t1 = p->prod;
  374. if(t1) { /* solves the current transition */
  375. GTrans *trans, *t2;
  376. clear_set(fin, 0);
  377. for(i = 1; i < final[0]; i++)
  378. if(is_final(s->nodes_set, t1, final[i]))
  379. add_set(fin, final[i]);
  380. for(t2 = s->trans->nxt; t2 != s->trans;) {
  381. if(tl_simp_fly &&
  382. included_set(t1->to, t2->to->nodes_set, 0) &&
  383. included_set(t1->pos, t2->pos, 1) &&
  384. included_set(t1->neg, t2->neg, 1) &&
  385. same_sets(fin, t2->final, 0)) { /* t2 is redondant */
  386. GTrans *free = t2->nxt;
  387. t2->to->incoming--;
  388. t2->to = free->to;
  389. copy_set(free->pos, t2->pos, 1);
  390. copy_set(free->neg, t2->neg, 1);
  391. copy_set(free->final, t2->final, 0);
  392. t2->nxt = free->nxt;
  393. if(free == s->trans) s->trans = t2;
  394. free_gtrans(free, 0, 0);
  395. state_trans--;
  396. }
  397. else if(tl_simp_fly &&
  398. included_set(t2->to->nodes_set, t1->to, 0) &&
  399. included_set(t2->pos, t1->pos, 1) &&
  400. included_set(t2->neg, t1->neg, 1) &&
  401. same_sets(t2->final, fin, 0)) {/* t1 is redondant */
  402. break;
  403. }
  404. else {
  405. t2 = t2->nxt;
  406. }
  407. }
  408. if(t2 == s->trans) { /* adds the transition */
  409. trans = emalloc_gtrans();
  410. trans->to = find_gstate(t1->to, s);
  411. trans->to->incoming++;
  412. copy_set(t1->pos, trans->pos, 1);
  413. copy_set(t1->neg, trans->neg, 1);
  414. copy_set(fin, trans->final, 0);
  415. trans->nxt = s->trans->nxt;
  416. s->trans->nxt = trans;
  417. state_trans++;
  418. }
  419. }
  420. if(!p->trans)
  421. break;
  422. while(!p->trans->nxt) /* calculates the next transition */
  423. p = p->nxt;
  424. if(p == prod)
  425. break;
  426. p->trans = p->trans->nxt;
  427. do_merge_trans(&(p->prod), p->nxt->prod, p->trans);
  428. p = p->prv;
  429. while(p != prod) {
  430. p->trans = transition[p->astate];
  431. do_merge_trans(&(p->prod), p->nxt->prod, p->trans);
  432. p = p->prv;
  433. }
  434. }
  435. tfree(list); /* free memory */
  436. while(prod->nxt != prod) {
  437. AProd *p = prod->nxt;
  438. prod->nxt = p->nxt;
  439. free_atrans(p->prod, 0);
  440. tfree(p);
  441. }
  442. free_atrans(prod->prod, 0);
  443. tfree(prod);
  444. if(tl_simp_fly) {
  445. if(s->trans == s->trans->nxt) { /* s has no transitions */
  446. free_gtrans(s->trans->nxt, s->trans, 1);
  447. s->trans = (GTrans *)0;
  448. s->prv = (GState *)0;
  449. s->nxt = gremoved->nxt;
  450. gremoved->nxt = s;
  451. for(s1 = gremoved->nxt; s1 != gremoved; s1 = s1->nxt)
  452. if(s1->prv == s)
  453. s1->prv = (GState *)0;
  454. return;
  455. }
  456. gstates->trans = s->trans;
  457. s1 = gstates->nxt;
  458. while(!all_gtrans_match(s, s1, 0))
  459. s1 = s1->nxt;
  460. if(s1 != gstates) { /* s and s1 are equivalent */
  461. free_gtrans(s->trans->nxt, s->trans, 1);
  462. s->trans = (GTrans *)0;
  463. s->prv = s1;
  464. s->nxt = gremoved->nxt;
  465. gremoved->nxt = s;
  466. for(s1 = gremoved->nxt; s1 != gremoved; s1 = s1->nxt)
  467. if(s1->prv == s)
  468. s1->prv = s->prv;
  469. return;
  470. }
  471. }
  472. s->nxt = gstates->nxt; /* adds the current state to 'gstates' */
  473. s->prv = gstates;
  474. s->nxt->prv = s;
  475. gstates->nxt = s;
  476. gtrans_count += state_trans;
  477. gstate_count++;
  478. }
  479. /********************************************************************\
  480. |* Display of the generalized Buchi automaton *|
  481. \********************************************************************/
  482. void reverse_print_generalized(GState *s) /* dumps the generalized Buchi automaton */
  483. {
  484. GTrans *t;
  485. if(s == gstates) return;
  486. reverse_print_generalized(s->nxt); /* begins with the last state */
  487. fprintf(tl_out, "state %i (", s->id);
  488. print_set(s->nodes_set, 0);
  489. fprintf(tl_out, ") : %i\n", s->incoming);
  490. for(t = s->trans->nxt; t != s->trans; t = t->nxt) {
  491. if (empty_set(t->pos, 1) && empty_set(t->neg, 1))
  492. fprintf(tl_out, "1");
  493. print_set(t->pos, 1);
  494. if (!empty_set(t->pos, 1) && !empty_set(t->neg, 1)) fprintf(tl_out, " & ");
  495. print_set(t->neg, 1);
  496. fprintf(tl_out, " -> %i : ", t->to->id);
  497. print_set(t->final, 0);
  498. fprintf(tl_out, "\n");
  499. }
  500. }
  501. void print_generalized() { /* prints intial states and calls 'reverse_print' */
  502. int i;
  503. fprintf(tl_out, "init :\n");
  504. for(i = 0; i < init_size; i++)
  505. if(init[i])
  506. fprintf(tl_out, "%i\n", init[i]->id);
  507. reverse_print_generalized(gstates->nxt);
  508. }
  509. /********************************************************************\
  510. |* Main method *|
  511. \********************************************************************/
  512. void mk_generalized()
  513. { /* generates a generalized Buchi automaton from the alternating automaton */
  514. ATrans *t;
  515. GState *s;
  516. int i;
  517. if(tl_stats) getrusage(RUSAGE_SELF, &tr_debut);
  518. fin = new_set(0);
  519. bad_scc = 0; /* will be initialized in simplify_gscc */
  520. final = list_set(final_set, 0);
  521. gstack = (GState *)tl_emalloc(sizeof(GState)); /* sentinel */
  522. gstack->nxt = gstack;
  523. gremoved = (GState *)tl_emalloc(sizeof(GState)); /* sentinel */
  524. gremoved->nxt = gremoved;
  525. gstates = (GState *)tl_emalloc(sizeof(GState)); /* sentinel */
  526. gstates->nxt = gstates;
  527. gstates->prv = gstates;
  528. for(t = transition[0]; t; t = t->nxt) { /* puts initial states in the stack */
  529. s = (GState *)tl_emalloc(sizeof(GState));
  530. s->id = (empty_set(t->to, 0)) ? 0 : gstate_id++;
  531. s->incoming = 1;
  532. s->nodes_set = dup_set(t->to, 0);
  533. s->trans = emalloc_gtrans(); /* sentinel */
  534. s->trans->nxt = s->trans;
  535. s->nxt = gstack->nxt;
  536. gstack->nxt = s;
  537. init_size++;
  538. }
  539. if(init_size) init = (GState **)tl_emalloc(init_size * sizeof(GState *));
  540. init_size = 0;
  541. for(s = gstack->nxt; s != gstack; s = s->nxt)
  542. init[init_size++] = s;
  543. while(gstack->nxt != gstack) { /* solves all states in the stack until it is empty */
  544. s = gstack->nxt;
  545. gstack->nxt = gstack->nxt->nxt;
  546. if(!s->incoming) {
  547. free_gstate(s);
  548. continue;
  549. }
  550. make_gtrans(s);
  551. }
  552. retarget_all_gtrans();
  553. if(tl_stats) {
  554. getrusage(RUSAGE_SELF, &tr_fin);
  555. timeval_subtract (&t_diff, &tr_fin.ru_utime, &tr_debut.ru_utime);
  556. fprintf(tl_out, "\nBuilding the generalized Buchi automaton : %i.%06is",
  557. t_diff.tv_sec, t_diff.tv_usec);
  558. fprintf(tl_out, "\n%i states, %i transitions\n", gstate_count, gtrans_count);
  559. }
  560. tfree(gstack);
  561. /*for(i = 0; i < node_id; i++) /* frees the data from the alternating automaton */
  562. /*free_atrans(transition[i], 1);*/
  563. free_all_atrans();
  564. tfree(transition);
  565. if(tl_verbose) {
  566. fprintf(tl_out, "\nGeneralized Buchi automaton before simplification\n");
  567. print_generalized();
  568. }
  569. if(tl_simp_diff) {
  570. if (tl_simp_scc) simplify_gscc();
  571. simplify_gtrans();
  572. if (tl_simp_scc) simplify_gscc();
  573. while(simplify_gstates()) { /* simplifies as much as possible */
  574. if (tl_simp_scc) simplify_gscc();
  575. simplify_gtrans();
  576. if (tl_simp_scc) simplify_gscc();
  577. }
  578. if(tl_verbose) {
  579. fprintf(tl_out, "\nGeneralized Buchi automaton after simplification\n");
  580. print_generalized();
  581. }
  582. }
  583. }