Automate *miroir( const Automate * automate){ Automate* clone = creer_automate(); ajouter_elements(clone->initiaux, automate->finaux); ajouter_elements(clone->finaux, automate->initiaux); pour_toute_transition(automate, reverse_transition, clone); return clone; }
int test_transitions_automate( int nb_transitions, const Automate* aut, ... ){ va_list pile; int i; int nb = 0; pour_toute_transition( aut, action_test_transitions_automate, &nb ); if( nb_transitions != nb ){ return 0; } va_start(pile,aut); for (i=0;i<nb_transitions;i++){ int origine = va_arg(pile,int); char lettre = (char) va_arg(pile,int); int fin = va_arg(pile,int); if( ! est_une_transition_de_l_automate( aut, origine, lettre, fin ) ){ return 0; } } va_end(pile); return 1; }
Automate * creer_automate_de_concatenation( const Automate* automate1, const Automate* automate2 ){ /** * \par Implémentation * * On créé un automate, copie de automate1 avec comme états finaux ceux de automate2 */ Automate* concat = copier_automate(automate1); deplacer_ensemble(concat->finaux, automate2->finaux); /** * Puis on créé un modificateur qui nous permet de passer en paramètres de fonction * l'automate de destination et une valeur de décalage des états. * Cette valeur permet de ne pas avoir deux états avec la même valeur. */ int decalage = get_max_etat(automate1); AutomateInt* modificateur = creer_automate_int(); modificateur->automate = concat; modificateur->valeur = decalage; /** * On ajoute les transitions de l'automate 2 avec les états décalés. */ pour_toute_transition(automate2, incrementer_etats_transition, modificateur); liberer_automate_int(modificateur); /** * Pour chaque état initial du second automate */ Ensemble_iterateur initial2; for( initial2 = premier_iterateur_ensemble(get_initiaux(automate2)); ! iterateur_ensemble_est_vide( initial2 ); initial2 = iterateur_suivant_ensemble( initial2 )){ /** * Pour chaque lettre de son alphabet */ Ensemble_iterateur lettre; for( lettre = premier_iterateur_ensemble(get_alphabet(automate2)); ! iterateur_ensemble_est_vide(lettre); lettre = iterateur_suivant_ensemble(lettre)){ Cle cle; printf("initial2 : %d\n", (int) get_element(initial2)); printf("lettre : %c\n", (char) get_element(lettre)); initialiser_cle(&cle, (int) get_element(initial2), (char) get_element(lettre)); Table_iterateur destination = trouver_table(automate2->transitions, (intptr_t) &cle); printf("avant clé\n"); print_cle(&cle); printf("après clé\n"); if (!iterateur_est_vide(destination)){ AutomateTransition* modif_trans = creer_automate_transition(); modif_trans->automate = concat; modif_trans->lettre = get_element(lettre); Ensemble* destinations = (Ensemble*) get_valeur(destination); Ensemble_iterateur etat_dest; /** * Pour chaque transition de la forme (i2, a2, q2), avec i2 intial, a2 lettre de l'alphabet * et q2 état de l'automate2 */ for( etat_dest = premier_iterateur_ensemble(destinations); ! iterateur_ensemble_est_vide(etat_dest); etat_dest = iterateur_suivant_ensemble(etat_dest)){ modif_trans->destination = get_element(etat_dest)+decalage; /** * On ajoute une transition dans l'automate de concaténation ayant pour origine * un état initial, la lettre a2 et l'état q2 */ pour_tout_element(get_finaux(automate1), simuler_epsilon_transition, modif_trans); } initialiser_cle(&cle, (int) get_element(initial2) + decalage, get_element(lettre)); delete_table(concat->transitions, (intptr_t) &cle); liberer_automate_transition(modif_trans); } } } return concat; }