int test_accessible(){ int result = 1; Automate* aut1 = mot_to_automate("abcde"); ajouter_transition( aut1, 3, 'a', 3); ajouter_transition( aut1, 3, 'b', 2); ajouter_transition( aut1, 3, 'c', 1); ajouter_transition( aut1, 1, 'e', 3); ajouter_etat( aut1, 6); ajouter_etat( aut1, 7); ajouter_transition( aut1, 6, 'a', 7); ajouter_transition( aut1, 7, 'e', 6); printf("Automate 1: \n"); print_automate(aut1); printf("\n"); Automate* aut2 = automate_accessible(aut1); printf("Resultat: \n"); print_automate(aut2); printf("\n"); liberer_automate(aut1); return result; }
Automate * translater_etat( const Automate* automate, int n ){ Automate * res = creer_automate(); Ensemble_iterateur it; for( it = premier_iterateur_ensemble( get_etats( automate ) ); ! iterateur_ensemble_est_vide( it ); it = iterateur_suivant_ensemble( it ) ){ ajouter_etat( res, get_element( it ) + n ); } Table_iterateur it1; Ensemble_iterateur it2; for( it1 = premier_iterateur_table( automate->transitions ); ! iterateur_ensemble_est_vide( it1 ); it1 = iterateur_suivant_ensemble( it1 ) ){ Cle * cle = (Cle*) get_cle( it1 ); Ensemble * fins = (Ensemble*) get_valeur( it1 ); for( it2 = premier_iterateur_ensemble( fins ); ! iterateur_ensemble_est_vide( it2 ); it2 = iterateur_suivant_ensemble( it2 ) ){ int fin = get_valeur( it2 ); ajouter_transition( res, cle->origine + n, cle->lettre, fin + n ); } }; return res; }
void ajouter_transition( Automate * automate, int origine, char lettre, int fin ){ ajouter_etat( automate, origine ); ajouter_etat( automate, fin ); ajouter_lettre( automate, lettre ); Cle cle; initialiser_cle( &cle, origine, lettre ); Table_iterateur it = trouver_table( automate->transitions, (intptr_t) &cle ); Ensemble * ens; if( iterateur_est_vide( it ) ){ ens = creer_ensemble( NULL, NULL, NULL ); add_table( automate->transitions, (intptr_t) &cle, (intptr_t) ens ); }else{ ens = (Ensemble*) get_valeur( it ); } ajouter_element( ens, fin ); }
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; }
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; }
// À 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_etat(const intptr_t element, void* data){ AutomateInt* donnee = (AutomateInt*) data; ajouter_etat(donnee->automate, element + donnee->valeur); }
void ajouter_etat_initial( Automate * automate, int etat_initial ){ ajouter_element(automate->initiaux, etat_initial); ajouter_etat(automate, etat_initial); }
void ajouter_etat_final( Automate * automate, int etat_final ){ ajouter_element(automate->finaux, etat_final); ajouter_etat(automate, etat_final); }