/**
 * 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);
      }
   }
}
}
Exemple #2
0
/**
 * This function concatenates B at the end of A. A is modified.
 */
void elag_concat(language_t* language,SingleGraph A,SingleGraph B) {
int oldnb=A->number_of_states;
int* renumber=(int*)malloc(B->number_of_states*sizeof(int));
if (renumber==NULL) {
   fatal_alloc_error("elag_concat");
}
int q;
/* We copy the states of B into A */
for (q=0;q<B->number_of_states;q++) {
   renumber[q]=A->number_of_states;
   add_state(A);
}
for (q=0;q<B->number_of_states;q++) {
   A->states[renumber[q]]->outgoing_transitions=clone_transition_list(B->states[q]->outgoing_transitions,renumber,dup_symbol);
   A->states[renumber[q]]->default_state=(B->states[q]->default_state!=-1)?renumber[B->states[q]->default_state]:-1;
   if (is_final_state(B->states[q])) {
      set_final_state(A->states[renumber[q]]);
   }
}
/* Then, we concatenate A and B.
 * 1) We replace default transitions that outgo from B's initial states
 *    by explicit transitions */
struct list_int* initials=get_initial_states(B);
for (struct list_int* tmp=initials;tmp!=NULL;tmp=tmp->next) {
   explicit_default_transition(language,A,renumber[tmp->n]);
}
for (q=0;q<oldnb;q++) {
   if (is_final_state(A->states[q])) {
      /* Each final state of A becomes non final. Moreover, we have
       * to explicit its default transition, because if not, the concatenation
       * algorithm will modify the recognized language. */
      unset_final_state(A->states[q]);
      explicit_default_transition(language,A,q);
      for (struct list_int* tmp=initials;tmp!=NULL;tmp=tmp->next) {
         concat(&(A->states[q]->outgoing_transitions),clone_transition_list(A->states[renumber[tmp->n]]->outgoing_transitions,NULL,dup_symbol));
         if (is_final_state(A->states[renumber[tmp->n]])) {
            set_final_state(A->states[q]);
         }
      }
   }
}
free(renumber);
free_list_int(initials);
}