void get_network() { char line[140]; int i, k, j = ptdn-1, nsti = 0, ok = FALSE; /* checking the network: initial, internal and final layers */ for (i = tdn[j].belem; i <= tdn[j].eelem; i++) { switch (tdl[i].type) { case FO: { if ((tdl[i].nsucc == 0) && (tdl[i].nprev > 0)) ok = TRUE; else yyerror("Error in the accessibility of final layer"); break; } case FI: case CI: { if ((tdl[i].nsucc > 0) && (tdl[i].nprev == 0)) { tdn[j].start = i; nsti++; ok= TRUE; } else yyerror("Error in the accessibility of initial layer"); break; } case C: case MP: { if ((tdl[i].nsucc > 0) && (tdl[i].nprev == 1)) ok = TRUE; else yyerror("Error in the accessibility of internal layer1"); break; } case CA: case F: case R: { if ((tdl[i].nsucc > 0) && (tdl[i].nprev > 0)) ok = TRUE; else yyerror("Error in the accessibility of internal layer2"); break; } } } if (nsti > 1) yyerror("Error: there can be only an initial layer"); else if (nsti == 0) yyerror("Error: a network must have an initial layer"); else if (ok == TRUE) { sprintf(line,"Network %s",tdn[j].name); emit(line); /* getting data files of network */ get_net_data(j); /* getting layers of network */ if (is_acyclic() == FALSE) yyerror("Error, possible loop in the network"); get_net_layers(j); /* getting links of network */ get_net_links(j, tdn[j].start); } }
/** * Returns 1 if the given sentence automaton is acylic; 0 otherwise. */ static int is_acyclic(Fst2* fst2,int graph_number) { if (graph_number<1 || graph_number>fst2->number_of_graphs) { fatal_error("Invalid graph number in is_acyclic\n"); } int N=fst2->number_of_states_per_graphs[graph_number]; #ifdef NO_C99_VARIABLE_LENGTH_ARRAY char *mark=(char*)malloc(sizeof(char)*N); #else char mark[N]; #endif for (int i=0;i<N;i++) { mark[i]=NOT_SEEN_YET; } #ifdef NO_C99_VARIABLE_LENGTH_ARRAY free(mark); #endif return is_acyclic(fst2,mark,fst2->initial_states[graph_number],fst2->initial_states[graph_number]); }
/** * Returns 1 if the given .fst2 corresponds to a valid sentence automaton; 0 * otherwise. Following conditions must be true: * * 1) there must be only one graph * 2) it must be acyclic * 3) there must not be any <E> transition with an ouput * 4) <E> must the only tag without output * 5) all other tags must have an ouput of the form w x y z f g, with * w and y being integers >=0, and x, z, f and g being integers >=-1 */ int valid_sentence_automaton_write_error(const VersatileEncodingConfig* vec,const char* name,U_FILE*) { struct FST2_free_info fst2_free; Fst2* fst2=load_abstract_fst2(vec,name,0,&fst2_free); if (fst2==NULL) return 0; /* Condition 1 */ if (fst2->number_of_graphs!=1) { free_abstract_Fst2(fst2,&fst2_free); return 0; } /* Condition 2 */ if (!is_acyclic(fst2,1)) { free_abstract_Fst2(fst2,&fst2_free); return 0; } /* Conditions 3, 4 & 5 */ if (!valid_outputs(fst2)) { free_abstract_Fst2(fst2,&fst2_free); return 0; } /* Victory! */ return 1; }
/** * Returns 1 if the exploration of the current state leads to the conclusion that * the automaton is acyclic; 0 otherwise. */ static int is_acyclic(Fst2* fst2,char* mark,int current_state_index,int shift) { if (mark[current_state_index-shift]==BEING_EXPLORED) { /* If we find a state that is currently being explored, then we found * a cycle */ return 0; } if (mark[current_state_index-shift]==SEEN) { return 1; } /* If the state is unseen, we mark it as being explored */ mark[current_state_index-shift]=BEING_EXPLORED; Fst2State state=fst2->states[current_state_index]; Transition* t=state->transitions; while (t!=NULL) { if (!is_acyclic(fst2,mark,t->state_number,shift)) { return 0; } t=t->next; } /* Finally, we mark the state as seen, and we return the success value */ mark[current_state_index-shift]=SEEN; return 1; }