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;
}
Пример #2
0
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);
}