ATrans *boolean(tl_Node *p) /* computes the transitions to boolean nodes -> next & init */ { ATrans *t1, *t2, *lft, *rgt, *result = (ATrans *)0; int id; switch (p->ntyp) { case TRUE: result = emalloc_atrans(); clear_set(result->to, 0); clear_set(result->pos, 1); clear_set(result->neg, 1); case FALSE: break; case AND: lft = boolean(p->lft); rgt = boolean(p->rgt); for (t1 = lft; t1; t1 = t1->nxt) { for (t2 = rgt; t2; t2 = t2->nxt) { ATrans *tmp = merge_trans(t1, t2); if (tmp) { tmp->nxt = result; result = tmp; } } } free_atrans(lft, 1); free_atrans(rgt, 1); break; case OR: lft = boolean(p->lft); for (t1 = lft; t1; t1 = t1->nxt) { ATrans *tmp = dup_trans(t1); tmp->nxt = result; result = tmp; } free_atrans(lft, 1); rgt = boolean(p->rgt); for (t1 = rgt; t1; t1 = t1->nxt) { ATrans *tmp = dup_trans(t1); tmp->nxt = result; result = tmp; } free_atrans(rgt, 1); break; default: build_alternating(p); result = emalloc_atrans(); clear_set(result->to, 0); clear_set(result->pos, 1); clear_set(result->neg, 1); add_set(result->to, already_done(p)); } return result; }
ATrans *build_alternating(Node *p) /* builds an alternating automaton for p */ { ATrans *t1, *t2, *t = (ATrans *)0; int node = already_done(p); if(node >= 0) return transition[node]; switch (p->ntyp) { case TRUE: t = emalloc_atrans(); clear_set(t->to, 0); clear_set(t->pos, 1); clear_set(t->neg, 1); case FALSE: break; case PREDICATE: t = emalloc_atrans(); clear_set(t->to, 0); clear_set(t->pos, 1); clear_set(t->neg, 1); add_set(t->pos, get_sym_id(p->sym->name)); break; case NOT: t = emalloc_atrans(); clear_set(t->to, 0); clear_set(t->pos, 1); clear_set(t->neg, 1); add_set(t->neg, get_sym_id(p->lft->sym->name)); break; #ifdef NXT case NEXT: t = boolean(p->lft); break; #endif case U_OPER: /* p U q <-> q || (p && X (p U q)) */ for(t2 = build_alternating(p->rgt); t2; t2 = t2->nxt) { ATrans *tmp = dup_trans(t2); /* q */ tmp->nxt = t; t = tmp; } for(t1 = build_alternating(p->lft); t1; t1 = t1->nxt) { ATrans *tmp = dup_trans(t1); /* p */ add_set(tmp->to, node_id); /* X (p U q) */ tmp->nxt = t; t = tmp; } add_set(final_set, node_id); break; case V_OPER: /* p V q <-> (p && q) || (p && X (p V q)) */ for(t1 = build_alternating(p->rgt); t1; t1 = t1->nxt) { ATrans *tmp; for(t2 = build_alternating(p->lft); t2; t2 = t2->nxt) { tmp = merge_trans(t1, t2); /* p && q */ if(tmp) { tmp->nxt = t; t = tmp; } } tmp = dup_trans(t1); /* p */ add_set(tmp->to, node_id); /* X (p V q) */ tmp->nxt = t; t = tmp; } break; case AND: t = (ATrans *)0; for(t1 = build_alternating(p->lft); t1; t1 = t1->nxt) { for(t2 = build_alternating(p->rgt); t2; t2 = t2->nxt) { ATrans *tmp = merge_trans(t1, t2); if(tmp) { tmp->nxt = t; t = tmp; } } } break; case OR: t = (ATrans *)0; for(t1 = build_alternating(p->lft); t1; t1 = t1->nxt) { ATrans *tmp = dup_trans(t1); tmp->nxt = t; t = tmp; } for(t1 = build_alternating(p->rgt); t1; t1 = t1->nxt) { ATrans *tmp = dup_trans(t1); tmp->nxt = t; t = tmp; } break; default: break; } transition[node_id] = t; label[node_id++] = p; return(t); }