/**
 * Replaces the given automaton by its complement one.
 */
void elag_complementation(language_t* language,SingleGraph A) {
int sink_state_index=A->number_of_states;
SingleGraphState sink_state=add_state(A);
/* The sink state is not final (because finalities will be reversed
 * below), and its default transition loops back on itself */
sink_state->default_state=sink_state_index;
for (int q=0;q<A->number_of_states;q++) {
   /* We reverse the finality of each state */
   if (is_final_state(A->states[q])) {
      unset_final_state(A->states[q]);
   } else {
      set_final_state(A->states[q]);
   }
   if (A->states[q]->default_state==-1) {
      /* If there is no default transition, we create one that is
       * tagged by anything but the non default ones */
      symbol_t* s=LEXIC_minus_transitions(language,A->states[q]->outgoing_transitions);
      if (s!=NULL) {
         add_all_outgoing_transitions(A->states[q],s,sink_state_index);
         /* We have added a single transition tagged by a symbol list. Now
          * we replace it by a list of transitions, each one of them
          * tagged with a single symbol */
         flatten_transition(A->states[q]->outgoing_transitions);
         /* Important to use free_symbols and not free_symbol, because
          * s represents a symbol list */
         free_symbols(s);
      }
   }
}
}
示例#2
0
文件: AutConcat.cpp 项目: adri87/Q-A
/**
 * If the state #q of the automaton A has a default transition, this function
 * adds all the explicit transitions that are equivalent to the default one.
 */
void explicit_default_transition(language_t* language,SingleGraph A,int q) {
if (A->states[q]->default_state==-1) {
   /* Nothing to do if there is no default transition */
   return;
}
/* We compute the set of symbols tagging transitions that outgo from q */
symbol_t* s=symbols_from_transs(A->states[q]->outgoing_transitions);
/* and we take the complementary set */
symbol_t* all_but_s=minus_symbols(language,s);
add_all_outgoing_transitions(A->states[q],all_but_s,A->states[q]->default_state);
free_symbols(s);
free_symbols(all_but_s);
}
/**
 * Loads and returns an automaton from the given .fst2.
 * Returns NULL if there is no more automaton to load.
 */
Fst2Automaton* load_automaton(Elag_fst_file_in* fstf) {
if (fstf->pos>=fstf->nb_automata) {
   return NULL;
}
Ustring* ustr=new_Ustring();
readline(ustr,fstf->f);
const unichar* p=ustr->str;
if (p[0]!='-') {
   fatal_error("load_automaton: %s: bad file format\n",fstf->name);
}
p++;
int i=u_parse_int(p,&p);
if (i!=fstf->pos+1) {
   /* We make sure that the automaton number is what it should be */
   fatal_error("load_automaton: %s: parsing error with line '%S' ('-%d ...' expected)\n",fstf->name,ustr->str,fstf->pos+1);
}
/* Now p points on the automaton name */
p++;
Fst2Automaton* A=new_Fst2Automaton(p);
while (readline(ustr,fstf->f) && ustr->str[0]!='f') {
   /* If there is a state to read */
   p=ustr->str;
   SingleGraphState state=add_state(A->automaton);
   if (*p=='t') {
      /* If necessary, we set the state final */
      set_final_state(state);
   }
   /* We puts p on the first digit */
   while (*p!='\0' && !u_is_digit(*p)) {
      p++;
   }
   while (*p!='\0') {
      /* If there is a transition to read */
      int tag_number=u_parse_int(p,&p);
      if (fstf->renumber!=NULL) {
         tag_number=fstf->renumber[tag_number];
      }
      while (*p==' ') {
         p++;
      }
      if (!u_is_digit(*p)) {
         fatal_error("load_automaton: %s: bad file format (line='%S')\n",fstf->name,ustr->str);
      }
      int state_number=u_parse_int(p,&p);
      symbol_t* tmp=(symbol_t*)fstf->symbols->value[tag_number];
      if (tmp!=NULL) {
         /* If it is a good symbol (successfully loaded), we add transition(s) */
         if (fstf->type!=FST_TEXT) {
            add_all_outgoing_transitions(state,tmp,state_number);
         } else {
            /* In a text automaton, we add one transition per element of
             * the symbol list. For instance, if we have:
             *
             * tmp = "{domestique,.N:fs}" => "{domestique,.N:ms}" => NULL
             *
             * then we add two transitions. */
            add_all_outgoing_transitions(state,tmp,state_number);
         }
      }
      while (*p==' ') {
         p++;
      }
   }
}
if (*ustr->str=='\0') {
   fatal_error("load_automaton: unexpected end of file\n");
}
if (A->automaton->number_of_states==0) {
   error("load_automaton: automaton with no state\n");
} else {
   set_initial_state(A->automaton->states[0]);
}
fstf->pos++;
free_Ustring(ustr);
return A;
}