Exemplo n.º 1
0
struct fsm* ConditionMerger::union_trees(struct fsm* fst1, struct fsm* fst2) {
  struct fsm* ret = fsm_topsort(
                      fsm_minimize(
                        fsm_determinize(
                          fsm_union(
                            fsm_copy(fst1),
                            fsm_copy(fst2)))));
  fsm_sort_arcs(ret, 1);
  return ret;
}
Exemplo n.º 2
0
struct fsm *flag_eliminate(struct fsm *net, char *name) {

    struct flags *flags, *f, *ff;
    struct fsm *filter, *succeed_flags, *fail_flags, *self, *newfilter, *newnet;
    int flag, fstatus, found;

    filter = NULL;

    flags = flag_extract(net);
    /* Check that flag actually exists in net */
    if (name != NULL) { 
        for (found = 0, f = flags; f != NULL; f = f->next) {
            if (strcmp(name,f->name) == 0)
                found = 1;
        }
        if (found == 0) {
#ifdef ORIGINAL
	    fprintf(stderr,"Flag attribute '%s' does not occur in the network.\n",name);
#else
            // TODO: Handle this in some other way.
#endif
            return(net);
        }
    }

    flag = 0;

    for (f = flags; f != NULL; f = f->next) {

        if ((name == NULL || strcmp(f->name,name) == 0) &&
            (f->type | FLAG_UNIFY | FLAG_REQUIRE | FLAG_DISALLOW | FLAG_EQUAL)) {
            
            succeed_flags = fsm_empty_set();
            fail_flags = fsm_empty_set();
            self = flag_create_symbol(f->type, f->name, f->value);
            
            for (ff = flags, flag = 0; ff != NULL; ff = ff->next) {
                fstatus = flag_build(f->type, f->name, f->value, ff->type, ff->name, ff->value);
                if (fstatus == FAIL) {
                    fail_flags = fsm_minimize(fsm_union(fail_flags, flag_create_symbol(ff->type, ff->name, ff->value)));
                    flag = 1;
                }
                if (fstatus == SUCCEED) {
                    succeed_flags = fsm_minimize(fsm_union(succeed_flags, flag_create_symbol(ff->type, ff->name, ff->value)));
                    flag = 1;
                }
            }
        }

        if (flag) {
            if (f->type == FLAG_REQUIRE) {
                newfilter = fsm_complement(fsm_concat(fsm_optionality(fsm_concat(fsm_universal(), fail_flags)), fsm_concat(fsm_complement(fsm_contains(succeed_flags)), fsm_concat(self, fsm_universal()))));
                
            } else {
                newfilter = fsm_complement(fsm_contains(fsm_concat(fail_flags,fsm_concat(fsm_complement(fsm_contains(succeed_flags)),self))));
            }

            filter = (filter == NULL) ? newfilter : fsm_intersect(filter, newfilter);
        }
        flag = 0;
    }
    if (filter != NULL) {
        extern int g_flag_is_epsilon;
        int old_g_flag_is_epsilon;
        old_g_flag_is_epsilon = g_flag_is_epsilon;
        g_flag_is_epsilon = 0;
        newnet = fsm_compose(fsm_copy(filter),fsm_compose(net,fsm_copy(filter)));
        g_flag_is_epsilon = old_g_flag_is_epsilon;
    } else {
        newnet = net;
    }
    flag_purge(newnet, name);
    newnet = fsm_minimize(newnet);
    sigma_cleanup(newnet,0);
    xxfree(flags);
    return(fsm_topsort(newnet));
}
Exemplo n.º 3
0
struct fsm *flag_twosided(struct fsm *net) {
  struct fsm_state *fsm;
  struct sigma *sigma;
  int i, j, tail, *isflag, maxsigma, maxstate, newarcs, change;
 
  /* Enforces twosided flag diacritics */
  
  /* Mark flag symbols */
  maxsigma = sigma_max(net->sigma);
  isflag = xxcalloc(maxsigma+1, sizeof(int));
  fsm = net->states;
  for (sigma = net->sigma ; sigma != NULL; sigma = sigma->next) {
    if (flag_check(sigma->symbol)) {
      *(isflag+sigma->number) = 1;
    } else {
      *(isflag+sigma->number) = 0;
    }
  }
  maxstate = 0;
  change = 0;
  for (i = 0, newarcs = 0; (fsm+i)->state_no != -1 ; i++) {
    maxstate = (fsm+i)->state_no > maxstate ? (fsm+i)->state_no : maxstate;
    if ((fsm+i)->target == -1)
      continue;
    if (*(isflag+(fsm+i)->in) && (fsm+i)->out == EPSILON) {
      change = 1;
      (fsm+i)->out = (fsm+i)->in;
    }
    else if (*(isflag+(fsm+i)->out) && (fsm+i)->in == EPSILON) {
      change = 1;
      (fsm+i)->in = (fsm+i)->out;
    }
    if ((*(isflag+(fsm+i)->in) || *(isflag+(fsm+i)->out)) && (fsm+i)->in != (fsm+i)->out) {
      newarcs++;
    }
  }

  if (newarcs == 0) {
    if (change == 1) {
      net->is_deterministic = UNK;
      net->is_minimized = UNK;
      net->is_pruned = UNK;
      return fsm_topsort(fsm_minimize(net));
    }
    return net;
  }
  net->states = xxrealloc(net->states, sizeof(struct fsm)*(i+newarcs));
  fsm = net->states;
  tail = j = i;
  maxstate++;
  for (i = 0; i < tail; i++) {

    if ((fsm+i)->target == -1) 
      continue;
    if ((*(isflag+(fsm+i)->in) || *(isflag+(fsm+i)->out)) && (fsm+i)->in != (fsm+i)->out) {
      if (*(isflag+(fsm+i)->in) && !*(isflag+(fsm+i)->out)) {
	j = add_fsm_arc(fsm, j, maxstate, EPSILON, (fsm+i)->out, (fsm+i)->target, 0, 0);
	(fsm+i)->out = (fsm+i)->in;
	(fsm+i)->target = maxstate;
	maxstate++;
      }
      else if (*(isflag+(fsm+i)->out) && !*(isflag+(fsm+i)->in)) {
	j = add_fsm_arc(fsm, j, maxstate, (fsm+i)->out, (fsm+i)->out, (fsm+i)->target, 0, 0);
	(fsm+i)->out = EPSILON;
	(fsm+i)->target = maxstate;
	maxstate++;
      }
      else if (*(isflag+(fsm+i)->in) && *(isflag+(fsm+i)->out)) {
	j = add_fsm_arc(fsm, j, maxstate, (fsm+i)->out, (fsm+i)->out, (fsm+i)->target, 0, 0);
	(fsm+i)->out = (fsm+i)->in;
	(fsm+i)->target = maxstate;
	maxstate++;
      }
    }
  }
  /* Add sentinel */
  add_fsm_arc(fsm, j, -1, -1, -1, -1, -1, -1);
  net->is_deterministic = UNK;
  net->is_minimized = UNK;
  return fsm_topsort(fsm_minimize(net));
}