Automate * creer_automate_des_facteurs( const Automate* automate ){ Automate * facteur = copier_automate(automate); Ensemble * finaux = facteur->finaux; Ensemble_iterateur it1, it2; int etat_actuel, est_ok; est_ok = 0; for (it1 = premier_iterateur_ensemble(get_etats(facteur)); ! iterateur_ensemble_est_vide(it1); it1 = iterateur_suivant_ensemble(it1)){ etat_actuel = get_element(it1); for (it2 = premier_iterateur_ensemble(finaux); !iterateur_ensemble_est_vide(it2) && !est_ok; it2 = iterateur_suivant_ensemble(it2)){ if (est_dans_l_ensemble(etats_accessibles(facteur, etat_actuel), get_element(it2))) { est_ok = 1; ajouter_etat_initial(facteur, etat_actuel); ajouter_etat_final(facteur, etat_actuel); } } est_ok = 0; } return facteur; }
Automate* copier_automate( const Automate* automate ){ Automate * res = creer_automate(); Ensemble_iterateur it1; // On ajoute les états de l'automate for( it1 = premier_iterateur_ensemble( get_etats( automate ) ); ! iterateur_ensemble_est_vide( it1 ); it1 = iterateur_suivant_ensemble( it1 ) ){ ajouter_etat( res, get_element( it1 ) ); } // On ajoute les états initiaux for( it1 = premier_iterateur_ensemble( get_initiaux( automate ) ); ! iterateur_ensemble_est_vide( it1 ); it1 = iterateur_suivant_ensemble( it1 ) ){ ajouter_etat_initial( res, get_element( it1 ) ); } // On ajoute les états finaux for( it1 = premier_iterateur_ensemble( get_finaux( automate ) ); ! iterateur_ensemble_est_vide( it1 ); it1 = iterateur_suivant_ensemble( it1 ) ){ ajouter_etat_final( res, get_element( it1 ) ); } // On ajoute les lettres for( it1 = premier_iterateur_ensemble( get_alphabet( automate ) ); ! iterateur_ensemble_est_vide( it1 ); it1 = iterateur_suivant_ensemble( it1 ) ){ ajouter_lettre( res, (char) get_element( it1 ) ); } // On ajoute les transitions Table_iterateur it2; for( it2 = premier_iterateur_table( automate->transitions ); ! iterateur_ensemble_est_vide( it2 ); it2 = iterateur_suivant_ensemble( it2 ) ){ Cle * cle = (Cle*) get_cle( it2 ); Ensemble * fins = (Ensemble*) get_valeur( it2 ); for( it1 = premier_iterateur_ensemble( fins ); ! iterateur_ensemble_est_vide( it1 ); it1 = iterateur_suivant_ensemble( it1 ) ){ int fin = get_element( it1 ); ajouter_transition( res, cle->origine, cle->lettre, fin ); } }; return res; }
/** * \par Implémentation * La fonction ne fait qu'ajouter des transitions à un automate vide. </br> * \par * Pour chaque lettre du mot, on part de l'état <em>[position de la lettre]+1</em>, on * passe par la lettre sélectionnée et on fini dans l'état * <em>[position de la lettre]+2</em> * @param mot * @return */ Automate * mot_to_automate(const char * mot){ Automate* res = creer_automate(); int length = sizeof(mot) / sizeof(char); int i; ajouter_etat_initial(res, 1); for (i = 0; i < length; ++i) { ajouter_transition(res, i+1, mot[i], i+2); } ajouter_etat_final(res, i+1); return res; }
// abac est un sur-mot de aa Automate * creer_automate_des_sur_mot( const Automate* automate, Ensemble * alphabet ){ Automate* surmots = creer_automate(); Ensemble_iterateur it_al; Table_iterateur it_trans; int etat_act = get_max_etat(automate) + 1; int etat_init = get_min_etat(automate) - 1; liberer_ensemble(surmots->alphabet); surmots->alphabet = (alphabet != NULL)? creer_union_ensemble(automate->alphabet, alphabet):copier_ensemble(automate->alphabet); // Pour chaques transition, on ajoute un état intermédiaire qui boucle sur lui même avec tout l'alphabet. En epsilon transition il passe à l'état suivant. for (it_trans = premier_iterateur_table(automate->transitions); !iterateur_est_vide(it_trans); it_trans = iterateur_suivant_table(it_trans)) { Cle * cle = (Cle*) get_cle(it_trans); Ensemble * fins = (Ensemble*) get_valeur(it_trans); ajouter_transition(surmots, cle->origine, cle->lettre, etat_act); for (it_al = premier_iterateur_ensemble(surmots->alphabet); !iterateur_ensemble_est_vide(it_al); it_al = iterateur_suivant_ensemble(it_al)) ajouter_transition(surmots, etat_act, get_element(it_al), etat_act); for (it_al = premier_iterateur_ensemble(fins); !iterateur_ensemble_est_vide(it_al); it_al = iterateur_suivant_ensemble(it_al)) ajouter_epsilon_transition(surmots, etat_act, get_element(it_al)); etat_act++; } // On ajoute un état initial, et un état final qui bouclent sur eux-même avec l'alphabet. ajouter_etat_final(surmots, etat_act); ajouter_etat_initial(surmots, etat_init); for (it_al = premier_iterateur_ensemble(surmots->alphabet); !iterateur_ensemble_est_vide(it_al); it_al = iterateur_suivant_ensemble(it_al)) { ajouter_transition(surmots, etat_act, get_element(it_al), etat_act); ajouter_transition(surmots, etat_init, get_element(it_al), etat_init); } // Les anciens états initiaux/finaux viennent/vont sur les nouvaux. for (it_al = premier_iterateur_ensemble(automate->initiaux); !iterateur_ensemble_est_vide(it_al); it_al = iterateur_suivant_ensemble(it_al)) ajouter_epsilon_transition(surmots, etat_init, get_element(it_al)); for (it_al = premier_iterateur_ensemble(automate->finaux); !iterateur_ensemble_est_vide(it_al); it_al = iterateur_suivant_ensemble(it_al)) ajouter_epsilon_transition(surmots, get_element(it_al), etat_act);; return surmots; }
int test_mot_accepte(){ BEGIN_TEST; int result = 1; Automate * automate = creer_automate(); ajouter_transition( automate, 1, 'a', 1 ); ajouter_transition( automate, 1, 'b', 2 ); ajouter_etat_final( automate, 2 ); ajouter_etat_initial( automate, 1 ); TEST( le_mot_est_reconnu( automate, "b" ), result ); TEST( le_mot_est_reconnu( automate, "ab" ), result ); TEST( le_mot_est_reconnu( automate, "aab" ), result ); TEST( ! le_mot_est_reconnu( automate, "aba" ), result ); liberer_automate( automate ); return result; }
// aa est un sous-mot de abac // Donc si abac est reconnu par automate on doit pouvoir reconnaitre a, b, c, ab, aa, ac, ba, bc, aba, abc, aac, bac, abac // Autrement dit, on doit pouvoir aller depuis un état à n'importe quel autre état en _avant_, tout en pouvant commencer partout. // C'est donc l'automate des facteurs avec des epsilons transition en plus. Automate * creer_automate_des_sous_mots( const Automate* automate ){ Automate * sous_mots = copier_automate(automate); Ensemble * finaux = sous_mots->finaux; Ensemble_iterateur it1, it2; int etat_actuel, etat_cible; for (it1 = premier_iterateur_ensemble(get_etats(sous_mots)); ! iterateur_ensemble_est_vide(it1); it1 = iterateur_suivant_ensemble(it1)){ etat_actuel = get_element(it1); for (it2 = premier_iterateur_ensemble(etats_accessibles(sous_mots, etat_actuel)); !iterateur_ensemble_est_vide(it2); it2 = iterateur_suivant_ensemble(it2)){ etat_cible = get_element(it2); ajouter_epsilon_transition(sous_mots, etat_actuel, etat_cible); if (est_dans_l_ensemble(finaux, etat_cible)) { ajouter_etat_initial(sous_mots, etat_actuel); ajouter_etat_final(sous_mots, etat_actuel); } } } return sous_mots; }
int test_automate_du_melange(){ int result = 1; { Automate * aut1 = mot_to_automate("a"); Automate * aut2 = mot_to_automate("b"); Automate * mela = creer_automate_du_melange( aut1, aut2 ); print_automate(mela); TEST( 1 && mela && le_mot_est_reconnu( mela, "ab" ) && le_mot_est_reconnu( mela, "ba" ) && ! le_mot_est_reconnu( mela, "" ) && ! le_mot_est_reconnu( mela, "a" ) && ! le_mot_est_reconnu( mela, "b" ) && ! le_mot_est_reconnu( mela, "aa" ) && ! le_mot_est_reconnu( mela, "bb" ) && ! le_mot_est_reconnu( mela, "aaa" ) && ! le_mot_est_reconnu( mela, "aab" ) && ! le_mot_est_reconnu( mela, "aba" ) && ! le_mot_est_reconnu( mela, "abb" ) && ! le_mot_est_reconnu( mela, "baa" ) && ! le_mot_est_reconnu( mela, "bab" ) && ! le_mot_est_reconnu( mela, "bba" ) && ! le_mot_est_reconnu( mela, "bbb" ) , result ); wrap_liberer_automate( aut1 ); wrap_liberer_automate( aut2 ); wrap_liberer_automate( mela ); } { Automate * aut1 = creer_automate(); ajouter_transition( aut1, 0, 'a', 1 ); ajouter_transition( aut1, 1, 'b', 2 ); ajouter_transition( aut1, 2, 'a', 2 ); ajouter_transition( aut1, 2, 'b', 1 ); ajouter_etat_initial( aut1, 0 ); ajouter_etat_final( aut1, 1 ); Automate * aut2 = creer_automate(); ajouter_transition( aut2, 0, 'c', 1 ); ajouter_transition( aut2, 1, 'd', 1 ); ajouter_transition( aut2, 0, 'd', 0 ); ajouter_transition( aut2, 1, 'e', 0 ); ajouter_etat_initial( aut2, 0 ); ajouter_etat_final( aut2, 1 ); Automate * mela = creer_automate_du_melange( aut1, aut2 ); print_automate(mela); TEST( 1 && mela && ! le_mot_est_reconnu( mela, "" ) && ! le_mot_est_reconnu( mela, "a" ) && ! le_mot_est_reconnu( mela, "b" ) && ! le_mot_est_reconnu( mela, "c" ) && ! le_mot_est_reconnu( mela, "d" ) && ! le_mot_est_reconnu( mela, "e" ) && le_mot_est_reconnu( mela, "ca" ) && le_mot_est_reconnu( mela, "ac" ) && ! le_mot_est_reconnu( mela, "aa" ) && ! le_mot_est_reconnu( mela, "cc" ) && le_mot_est_reconnu( mela, "cabb" ) && le_mot_est_reconnu( mela, "acbb" ) && le_mot_est_reconnu( mela, "abcb" ) && le_mot_est_reconnu( mela, "abbc" ) && le_mot_est_reconnu( mela, "cda" ) && le_mot_est_reconnu( mela, "cad" ) && le_mot_est_reconnu( mela, "acd" ) && le_mot_est_reconnu( mela, "cdeca" ) && le_mot_est_reconnu( mela, "cdeac" ) && le_mot_est_reconnu( mela, "cdaec" ) && le_mot_est_reconnu( mela, "cadec" ) && le_mot_est_reconnu( mela, "acdec" ) && le_mot_est_reconnu( mela, "cdabb" ) && le_mot_est_reconnu( mela, "cadbb" ) && le_mot_est_reconnu( mela, "cabdb" ) && le_mot_est_reconnu( mela, "cabbd" ) && le_mot_est_reconnu( mela, "acdbb" ) && le_mot_est_reconnu( mela, "acbdb" ) && le_mot_est_reconnu( mela, "acbbd" ) && le_mot_est_reconnu( mela, "abcdb" ) && le_mot_est_reconnu( mela, "abcbd" ) && le_mot_est_reconnu( mela, "abbcd" ) , result ); wrap_liberer_automate( aut1 ); wrap_liberer_automate( aut2 ); wrap_liberer_automate( mela ); } return result; }
int test_execute_fonctions(){ BEGIN_TEST int res = 1; Automate * automate2; Automate * automate; Automate * result = NULL; Ensemble * ens = NULL; Ensemble * ens1 = NULL; automate = creer_automate(); result = NULL; ajouter_lettre( automate, 'a' ); if( result ) liberer_automate( result ); liberer_automate( automate ); automate = creer_automate(); result = NULL; ajouter_etat_final( automate, 1 ); if( result ) liberer_automate( result ); liberer_automate( automate ); automate = creer_automate(); result = NULL; ajouter_etat_initial( automate, 1 ); if( result ) liberer_automate( result ); liberer_automate( automate ); automate = creer_automate(); get_initiaux( automate ); liberer_automate( automate ); automate = creer_automate(); get_finaux( automate ); liberer_automate( automate ); automate = creer_automate(); get_alphabet( automate ); liberer_automate( automate ); automate = creer_automate(); result = NULL; est_un_etat_initial_de_l_automate( automate, 1 ); if( result ) liberer_automate( result ); liberer_automate( automate ); automate = creer_automate(); result = NULL; est_un_etat_final_de_l_automate( automate, 1 ); if( result ) liberer_automate( result ); liberer_automate( automate ); automate = creer_automate(); result = NULL; est_une_lettre_de_l_automate( automate, 'a' ); if( result ) liberer_automate( result ); liberer_automate( automate ); automate = creer_automate(); ens = NULL; ens1 = creer_ensemble( NULL, NULL, NULL ); ens = delta_star( automate, ens1, "aba" ); if( ens ) liberer_ensemble( ens ); liberer_ensemble( ens1 ); liberer_automate( automate ); automate = creer_automate(); result = NULL; le_mot_est_reconnu( automate, "abaa" ); if( result ) liberer_automate( result ); liberer_automate( automate ); automate = creer_automate(); result = NULL; result = mot_to_automate( "abbaa" ); if( result ) liberer_automate( result ); liberer_automate( automate ); automate = creer_automate(); ens = NULL; ens = etats_accessibles( automate, 0 ); if( ens ) liberer_ensemble( ens ); liberer_automate( automate ); automate = creer_automate(); result = NULL; result = automate_accessible( automate ); if( result ) liberer_automate( result ); liberer_automate( automate ); automate = creer_automate(); result = NULL; result = miroir( automate ); if( result ) liberer_automate( result ); liberer_automate( automate ); automate = creer_automate(); result = NULL; result = automate_co_accessible(automate ); if( result ) liberer_automate( result ); liberer_automate( automate ); automate = creer_automate(); result = NULL; result = creer_automate_des_prefixes( automate ); if( result ) liberer_automate( result ); liberer_automate( automate ); automate = creer_automate(); result = NULL; result = creer_automate_des_suffixes( automate ); if( result ) liberer_automate( result ); liberer_automate( automate ); automate = creer_automate(); result = NULL; result = creer_automate_des_facteurs( automate ); if( result ) liberer_automate( result ); liberer_automate( automate ); automate = creer_automate(); result = NULL; ens = creer_ensemble( NULL, NULL, NULL ); result = creer_automate_des_sur_mot( automate, ens ); if( result ) liberer_automate( result ); liberer_automate( automate ); liberer_ensemble( ens ); automate = creer_automate(); automate2 = creer_automate(); result = NULL; result = creer_automate_de_concatenation( automate, automate2 ); if( result ) liberer_automate( result ); liberer_automate( automate ); liberer_automate( automate2 ); automate = creer_automate(); result = NULL; result = creer_automate_des_sous_mots( automate ); if( result ) liberer_automate( result ); liberer_automate( automate ); return res; }
int test_delta_delta_star(){ BEGIN_TEST; int result = 1; Automate* automate = creer_automate(); ajouter_etat( automate, 3 ); ajouter_etat( automate, 5 ); ajouter_transition( automate, 3, 'a', 5 ); ajouter_transition( automate, 5, 'b', 3 ); ajouter_transition( automate, 5, 'a', 5 ); ajouter_transition( automate, 5, 'c', 6 ); ajouter_etat_initial( automate, 3 ); ajouter_etat_final( automate, 6 ); TEST( 1 && est_un_etat_de_l_automate( automate, 3 ) && est_un_etat_de_l_automate( automate, 5 ) && est_un_etat_de_l_automate( automate, 6 ) && est_un_etat_initial_de_l_automate( automate, 3 ) && ! est_un_etat_initial_de_l_automate( automate, 5 ) && ! est_un_etat_initial_de_l_automate( automate, 6 ) && ! est_un_etat_final_de_l_automate( automate, 3 ) && ! est_un_etat_final_de_l_automate( automate, 5 ) && est_un_etat_final_de_l_automate( automate, 6 ) && est_une_lettre_de_l_automate( automate, 'a' ) && est_une_lettre_de_l_automate( automate, 'b' ) && est_une_lettre_de_l_automate( automate, 'c' ) && ! est_une_lettre_de_l_automate( automate, 'd' ) && est_une_transition_de_l_automate( automate, 3, 'a', 5 ) && est_une_transition_de_l_automate( automate, 5, 'b', 3 ) && est_une_transition_de_l_automate( automate, 5, 'a', 5 ) && est_une_transition_de_l_automate( automate, 5, 'c', 6 ) && ! est_une_transition_de_l_automate( automate, 3, 'b', 5 ) && ! est_une_transition_de_l_automate( automate, 1, 'b', 5 ) && ! est_une_transition_de_l_automate( automate, 3, 'a', 1 ) , result ); Ensemble * etat_courant = creer_ensemble( NULL, NULL, NULL ); ajouter_element( etat_courant, 3 ); deplacer_ensemble( etat_courant, delta( automate, etat_courant, 'a' ) ); TEST( 1 && est_dans_l_ensemble( etat_courant, 5 ) && taille_ensemble( etat_courant ) ==1 , result ); deplacer_ensemble( etat_courant, delta_star( automate, etat_courant, "ab" ) ); TEST( 1 && est_dans_l_ensemble( etat_courant, 3 ) && taille_ensemble( etat_courant ) ==1 , result ); deplacer_ensemble( etat_courant, delta_star( automate, etat_courant, "ac" ) ); TEST( 1 && est_dans_l_ensemble( etat_courant, 6 ) && taille_ensemble( etat_courant ) ==1 , result ); deplacer_ensemble( etat_courant, delta_star( automate, etat_courant, "" ) ); TEST( 1 && est_dans_l_ensemble( etat_courant, 6 ) && taille_ensemble( etat_courant ) ==1 , result ); deplacer_ensemble( etat_courant, delta_star( automate, etat_courant, "c" ) ); TEST( 1 && taille_ensemble( etat_courant ) == 0 , result ); liberer_ensemble( etat_courant ); liberer_automate( automate ); return result; }
int test_creer_automate(){ BEGIN_TEST; int result = 1; Automate * automate = creer_automate(); ajouter_lettre( automate, 'a' ); ajouter_lettre( automate, 'd' ); ajouter_etat( automate, 3 ); ajouter_etat_final( automate, 6 ); ajouter_transition( automate, 3, 'a', 5 ); ajouter_transition( automate, 3, 'b', 3 ); ajouter_etat_final( automate, 5 ); ajouter_etat_initial( automate, 3 ); TEST( 1 && est_un_etat_de_l_automate( automate, 3) && est_un_etat_de_l_automate( automate, 5) && est_un_etat_de_l_automate( automate, 6) , result ); TEST( 1 && ! est_un_etat_final_de_l_automate( automate, 3) && est_un_etat_final_de_l_automate( automate, 5) && est_un_etat_final_de_l_automate( automate, 6) , result ); TEST( 1 && est_un_etat_initial_de_l_automate( automate, 3) && ! est_un_etat_initial_de_l_automate( automate, 5) , result ); TEST( 1 && est_une_lettre_de_l_automate( automate, 'a') && est_une_lettre_de_l_automate( automate, 'b') && est_une_lettre_de_l_automate( automate, 'd') && ! est_une_lettre_de_l_automate( automate, 'c') , result ); TEST( 1 && est_une_transition_de_l_automate( automate, 3, 'a', 5 ) && est_une_transition_de_l_automate( automate, 3, 'b', 3 ) && ! est_une_transition_de_l_automate( automate, 3, 'b', 5 ) && ! est_une_transition_de_l_automate( automate, 3, 'a', 3 ) && ! est_une_transition_de_l_automate( automate, 5, 'a', 3 ) && ! est_une_transition_de_l_automate( automate, 5, 'b', 3 ) && ! est_une_transition_de_l_automate( automate, 5, 'a', 5 ) && ! est_une_transition_de_l_automate( automate, 5, 'b', 5 ) , result ); const Ensemble* ens = get_initiaux( automate ); TEST( 1 && ens && est_dans_l_ensemble( ens, 3 ) && ! est_dans_l_ensemble( ens, 5 ) && ! est_dans_l_ensemble( ens, 6 ) , result ); ens = get_finaux( automate ); TEST( 1 && ens && ! est_dans_l_ensemble( ens, 3 ) && est_dans_l_ensemble( ens, 5 ) && est_dans_l_ensemble( ens, 6 ) , result ); ens = get_alphabet( automate ); TEST( 1 && ens && est_dans_l_ensemble( ens, 'a') && est_dans_l_ensemble( ens, 'b') && ! est_dans_l_ensemble( ens, 'c') && est_dans_l_ensemble( ens, 'd') , result ); liberer_automate( automate ); return result; }
int main(){ Automate * a = creer_automate(); /* Automate * a2 = creer_automate(); */ /* printf("\n==========automate(a)==============\n"); */ /* ajouter_transition(a, 1, 'a', 1, 1); */ /* ajouter_transition(a, 2, 'a', 1, 1); */ /* ajouter_transition(a, 1, 'a', 1, 2); */ /* ajouter_transition(a, 2, 'a', 0, 2); */ /* ajouter_transition(a, 3, 'a', 3, 3); */ /* ajouter_transition(a, 1, 'b', 1, 1); */ /* ajouter_transition(a, 1, 'b', 1, 3); */ /* ajouter_transition(a, 3, 'b', 1, 1); */ /* ajouter_transition(a, 3, 'b', 0, 3); */ /* ajouter_etat_initial(a, 1); */ /* ajouter_etat_final(a, 1); */ printf("\n==========automate(a)==============\n"); ajouter_transition(a, 0, 'a', 0, 0); ajouter_transition(a, 0, 'b', 0, 0); ajouter_transition(a, 0, 'b', 0, 1); ajouter_transition(a, 1, 'a', 1, 1); ajouter_transition(a, 1, 'b', 0, 2); ajouter_transition(a, 2, 'a', 0, 2); ajouter_transition(a, 2, 'b', 0, 2); ajouter_transition(a, 3, 'a', 0, 3); ajouter_transition(a, 3, 'b', 1, 3); ajouter_etat_initial(a, 0); ajouter_etat_initial(a, 1); ajouter_etat_initial(a, 3); ajouter_etat_final(a, 1); ajouter_etat_final(a, 2); ajouter_etat_final(a, 3); print_automate(a); printf("Voulez vous voir le graphe de cet automate? (y/n) *Graphviz nécessaire*\n"); char entree; scanf("%c", &entree); if(entree == 'y'){ creergraphe(a); system("dot -Tpng auto.gv -o auto.png"); system("xdg-open auto.png &"); //open avec le logiciel par default /* system("firefox auto.png >/dev/null 2>&1 &"); */ //open avec firefox } printf("\n"); printf("\n==========L'automate a est-il limité ?==============\n"); printf("Calcul de l'automate des matrices...\n"); clock_t time = clock(); Mautomate * maut = creer_mautomate(a); time= clock(); printf("Temps de calcul : %.3f seconde\n", (double)time/CLOCKS_PER_SEC); printf("Calcul des limites...\n"); Matrice res = (Matrice)est_limite(a, maut); if(res==NULL) printf("L'automate est limité.\n"); else{ printf("L'automate n'est pas limité, voici la premiere matrice qui cause le cout infini :\n"); print_matrice_in_R(res); } print_mautomate(maut); liberer_mautomate(maut); liberer_automate(a);//c'est bon return 0; }
// À chaque itération de l'algo, on prend une lettre du premier ou du second automate, jusqu'à ce qu'on arrive à la dernière lettre. // Produit cartésien des états. // Exemple : mot 1 : aaaa, mot 2 : bbbb // Quelques résulats possibles : aabbaabb; aaaabbbb: bbbbaaaa; aaababbb: baababba Automate * creer_automate_du_melange( const Automate* automate1, const Automate* automate2 ){ int i, j, k, nbelau1, nbelau2, etat_act, et1, et2; int ** nouveaux_etats = NULL; Automate * melange = creer_automate(); Ensemble_iterateur it1, it2; Table_iterateur it_transition; Table *cle1 = creer_table( ( int(*)(const intptr_t, const intptr_t) ) comparer_int , ( intptr_t (*)( const intptr_t ) ) copier_int, ( void(*)(intptr_t) ) supprimer_int ); Table *cle2 = creer_table( ( int(*)(const intptr_t, const intptr_t) ) comparer_int , ( intptr_t (*)( const intptr_t ) ) copier_int, ( void(*)(intptr_t) ) supprimer_int ); const Ensemble * finaux1 = get_finaux(automate1); const Ensemble * finaux2 = get_finaux(automate2); const Ensemble * initiaux1 = get_initiaux(automate1); const Ensemble * initiaux2 = get_initiaux(automate2); nbelau1 = taille_ensemble(automate1->etats); nbelau2 = taille_ensemble(automate2->etats); nouveaux_etats = malloc(nbelau1 * sizeof(int *)); for(i=0; i<nbelau1; i++) nouveaux_etats[i]=malloc(nbelau2 * sizeof(int)); k = 0; // Création des états, états initiaux, états finaux de l'automate. for (it1 = premier_iterateur_ensemble(automate1->etats), i=0; ! iterateur_ensemble_est_vide(it1); it1 = iterateur_suivant_ensemble(it1), i++){ et1 = get_element(it1); add_table(cle1, et1, i); for (it2 = premier_iterateur_ensemble(automate2->etats), j=0; ! iterateur_ensemble_est_vide(it2); it2 = iterateur_suivant_ensemble(it2), j++){ et2 = get_element(it2); ajouter_etat(melange, k); add_table(cle2, et2, j); if (est_dans_l_ensemble(finaux1, et1) && est_dans_l_ensemble(finaux2, et2)) ajouter_etat_final(melange, k); if (est_dans_l_ensemble(initiaux1, et1) && est_dans_l_ensemble(initiaux2, et2)) ajouter_etat_initial(melange, k); nouveaux_etats[i][j] = k; k++; } } // Les transitions sont ensuite crées // D'abord celles de l'ancien automate 1 for (it_transition = premier_iterateur_table(automate1->transitions); !iterateur_est_vide(it_transition); it_transition = iterateur_suivant_table(it_transition)) { Cle * cle = (Cle*) get_cle(it_transition); Ensemble * fins = (Ensemble*) get_valeur(it_transition); for (it1 = premier_iterateur_ensemble(fins), i=0; ! iterateur_ensemble_est_vide(it1); it1 = iterateur_suivant_ensemble(it1), i++){ etat_act = get_element(it1); for(i = 0; i < nbelau2; i++) { ajouter_transition(melange, nouveaux_etats[(int)get_valeur(trouver_table(cle1, cle->origine))][i], cle->lettre, nouveaux_etats[(int)get_valeur(trouver_table(cle1, etat_act))][i]); } } } // Puis celles de l'ancien automate 2 for (it_transition = premier_iterateur_table(automate2->transitions); !iterateur_est_vide(it_transition); it_transition = iterateur_suivant_table(it_transition)) { Cle * cle = (Cle*) get_cle(it_transition); Ensemble * fins = (Ensemble*) get_valeur(it_transition); for (it1 = premier_iterateur_ensemble(fins), i=0; ! iterateur_ensemble_est_vide(it1); it1 = iterateur_suivant_ensemble(it1), i++){ etat_act = get_element(it1); for(i = 0; i < nbelau1; i++) { ajouter_transition(melange, nouveaux_etats[i][(int)get_valeur(trouver_table(cle2, cle->origine))], cle->lettre, nouveaux_etats[i][(int)get_valeur(trouver_table(cle2, etat_act))]); } } } liberer_table(cle1); liberer_table(cle2); return melange; }
void incrementer_finaux(const intptr_t element, void* data){ AutomateInt* donnee = (AutomateInt*) data; ajouter_etat_final(donnee->automate, element + donnee->valeur); }
int test_automate_union(){ int result = 1; { Automate * aut1 = mot_to_automate("ab"); Automate * aut2 = mot_to_automate("ba"); Automate * mela = creer_union_des_automates( aut1, aut2 ); TEST( 1 && mela && le_mot_est_reconnu( mela, "ab" ) && le_mot_est_reconnu( mela, "ba" ) && ! le_mot_est_reconnu( mela, "" ) && ! le_mot_est_reconnu( mela, "a" ) && ! le_mot_est_reconnu( mela, "b" ) && ! le_mot_est_reconnu( mela, "aa" ) && ! le_mot_est_reconnu( mela, "bb" ) && ! le_mot_est_reconnu( mela, "aaa" ) && ! le_mot_est_reconnu( mela, "aab" ) && ! le_mot_est_reconnu( mela, "aba" ) && ! le_mot_est_reconnu( mela, "abb" ) && ! le_mot_est_reconnu( mela, "baa" ) && ! le_mot_est_reconnu( mela, "bab" ) && ! le_mot_est_reconnu( mela, "bba" ) && ! le_mot_est_reconnu( mela, "bbb" ) , result ); wrap_liberer_automate( aut1 ); wrap_liberer_automate( aut2 ); wrap_liberer_automate( mela ); } { Automate * aut1 = creer_automate(); ajouter_transition( aut1, 0, 'a', 1 ); ajouter_transition( aut1, 1, 'b', 2 ); ajouter_transition( aut1, 2, 'a', 2 ); ajouter_transition( aut1, 2, 'b', 1 ); ajouter_etat_initial( aut1, 0 ); ajouter_etat_final( aut1, 1 ); Automate * aut2 = creer_automate(); ajouter_transition( aut2, 0, 'c', 1 ); ajouter_transition( aut2, 1, 'd', 1 ); ajouter_transition( aut2, 0, 'd', 0 ); ajouter_transition( aut2, 1, 'e', 0 ); ajouter_etat_initial( aut2, 0 ); ajouter_etat_final( aut2, 1 ); Automate * mela = creer_union_des_automates( aut1, aut2 ); TEST( 1 && mela && le_mot_est_reconnu( mela, "a" ) && le_mot_est_reconnu( mela, "c" ) && ! le_mot_est_reconnu( mela, "" ) && ! le_mot_est_reconnu( mela, "b" ) && ! le_mot_est_reconnu( mela, "d" ) && ! le_mot_est_reconnu( mela, "e" ) && le_mot_est_reconnu ( mela, "dc") && le_mot_est_reconnu ( mela, "cec") && le_mot_est_reconnu ( mela, "abb") && !le_mot_est_reconnu( mela, "da") , result ); wrap_liberer_automate( aut1 ); wrap_liberer_automate( aut2 ); wrap_liberer_automate( mela ); } return result; }