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 * 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; }
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; }
Automate *automate_accessible( const Automate * automate){ Automate* clone = copier_automate(automate); Ensemble* etats = creer_ensemble(NULL, NULL, NULL); Ensemble_iterateur it_etat; Ensemble_iterateur it_lettre; // On calcule l'ensemble des états accessibles for(it_etat = premier_iterateur_ensemble(get_initiaux(automate)); ! iterateur_ensemble_est_vide( it_etat ); it_etat = iterateur_suivant_ensemble( it_etat )){ ajouter_elements(etats, etats_accessibles(automate, get_element(it_etat))); ajouter_element(etats, get_element(it_etat)); } // On détermine les états qui ne sont pas accessibles => ceux qui sont dans get_etats mais pas dans etats Ensemble* non_accessible = creer_difference_ensemble(get_etats(automate), etats); // On parcourt l'ensemble obtenu for(it_etat = premier_iterateur_ensemble(non_accessible); ! iterateur_ensemble_est_vide( it_etat ); it_etat = iterateur_suivant_ensemble( it_etat )){ const intptr_t etat_courant = get_element(it_etat); // On cherche toutes les transitions partant d'un état for(it_lettre = premier_iterateur_ensemble(get_alphabet(automate)); ! iterateur_ensemble_est_vide( it_lettre ); it_lettre = iterateur_suivant_ensemble( it_lettre )){ Cle cle; initialiser_cle( &cle, etat_courant, get_element(it_lettre)); Table_iterateur it = trouver_table( clone->transitions, (intptr_t) &cle ); // Si on trouve une transition partant d'un état non accessible if( !iterateur_est_vide( it ) ){ delete_table( clone->transitions, (intptr_t) &cle); // on la supprime } } // si c'est un état final, on pense à le supprimer if (est_un_etat_final_de_l_automate(automate, etat_courant)) { retirer_element(clone->finaux, etat_courant); } // si c'est un état initial, on pense à le supprimer if (est_un_etat_initial_de_l_automate(automate, etat_courant)) { retirer_element(clone->initiaux, etat_courant); } } // On supprime tous les états non accessibles de l'automate deplacer_ensemble(clone->etats, etats); return clone; }
void print_automate( const Automate * automate ){ printf("- Etats : "); print_ensemble( get_etats( automate ), NULL ); printf("\n- Initiaux : "); print_ensemble( get_initiaux( automate ), NULL ); printf("\n- Finaux : "); print_ensemble( get_finaux( automate ), NULL ); printf("\n- Alphabet : "); print_ensemble( get_alphabet( automate ), print_lettre ); printf("\n- Transitions : "); print_table( automate->transitions, ( void (*)( const intptr_t ) ) print_cle, ( void (*)( const intptr_t ) ) print_ensemble_2, "" ); printf("\n"); }
Matrice creer_matrice_transistions(Automate* a, char c){ Automate * abis = creer_automate_etats_0_n(a); int n = taille_ensemble(get_etats(abis)); Matrice m = creer_matrice(n); tree t=tree_creat(); tree_set(t, c); m->mot = t; int i, j; for(i = 0; i < m->taille; i++){ for(j = 0; j< m->taille; j++){ m->tab[i][j] = INFINI; } } Table_iterateur it1; Ensemble_iterateur it2; for ( it1 = premier_iterateur_table(get_transitions(abis)); ! iterateur_ensemble_est_vide(it1); it1 = iterateur_suivant_ensemble(it1) ){ Cle * cle = (Cle*) get_cle(it1); Ensemble * fins = (Ensemble*) get_valeur(it1); int tmp = get_lettre_cle(cle); if(tmp == (int)c){ for( it2 = premier_iterateur_ensemble(fins); ! iterateur_ensemble_est_vide(it2); it2 = iterateur_suivant_ensemble(it2) ){ int f = get_element(it2); int cout = get_cout_cle(cle)==0 ? 0: 1; m->tab[get_origine_cle(cle)][f] = cout; } } } liberer_automate(abis); return m; }
// 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 est_un_etat_de_l_automate( const Automate* automate, int etat ){ return est_dans_l_ensemble( get_etats( automate ), etat ); }