/************************/ /* Intersection of NFAs */ /************************/ #include "nfa_intersec.h" /************************************************************************************************/ /* Construction classique: calcul de l'automate produit en ne gardant que les * états accessibles */ /************************************************************************************************/ // Intersection nfa *nfa_intersect(nfa *nfa1, nfa *nfa2, bool nom) { printf("Intersection de l'automate\n"); fflush(stdout); // Vérifier que les alphabets des deux automates sont identiques if (nfa1->trans->size_alpha != nfa2->trans->size_alpha) { fprintf(stderr, "Les alphabets des deux automates doivent être identiques.\n"); return NULL; } // Créer un nouveau NFA pour l'automate produit nfa *result = (nfa *)malloc(sizeof(nfa)); if (!result) { perror("Erreur d'allocation de mémoire pour l'automate produit"); return NULL; } // Initialiser les champs de l'automate produit result->trans = create_lgraph_noedges(nfa1->trans->size_graph * nfa2->trans->size_graph, nfa1->trans->size_alpha); result->initials = create_dequeue(); result->finals = create_dequeue(); result->alpha_names = nfa_copy_alpha(nfa1); result->state_names = nom ? (char **)malloc(result->trans->size_graph * sizeof(char *)) : NULL; // Ajouter les états initiaux for (uint i = 0; i < size_dequeue(nfa1->initials); i++) { for (uint j = 0; j < size_dequeue(nfa2->initials); j++) { // Récupérer les états initiaux des deux automates uint state1 = lefread_dequeue(nfa1->initials, i); uint state2 = lefread_dequeue(nfa2->initials, j); // Calcule de l'indice du nouvel état initial dans l'automate produit uint new_state = state1 * nfa2->trans->size_graph + state2; // Ajouter le nouvel état initial à la liste des états initiaux de // l'automate produit insert_dequeue(result->initials, new_state); } } printf("Intersection de l'automate1\n"); fflush(stdout); // Ajouter les états finaux for (uint i = 0; i < size_dequeue(nfa1->finals); i++) { for (uint j = 0; j < size_dequeue(nfa2->finals); j++) { // Récupérer les états finaux des deux automates uint state1 = lefread_dequeue(nfa1->finals, i); uint state2 = lefread_dequeue(nfa2->finals, j); // Calcule de l'indice du nouvel état final dans l'automate produit uint new_state = state1 * nfa2->trans->size_graph + state2; // Ajouter le nouvel état final à la liste des états finaux de l'automate // produit insert_dequeue(result->finals, new_state); } } printf("Intersection de l'automate2\n"); fflush(stdout); // Ajouter les transitions for (uint state1 = 0; state1 < nfa1->trans->size_graph; state1++) { for (uint state2 = 0; state2 < nfa2->trans->size_graph; state2++) { // Calcule de l'indice du nouvel dans l'automate produit uint new_state = state1 * nfa2->trans->size_graph + state2; for (uint letter = 0; letter < nfa1->trans->size_alpha; letter++) { // Récupérer les états atteignables depuis state1 et state2 avec la // lettre courante // tuyau de tout les états atteignables depuis state1 avec la lettre dequeue *reachable1 = nfa1->trans->edges[state1][letter]; // tuyau de tout les états atteignables depuis state2 avec la lettre dequeue *reachable2 = nfa2->trans->edges[state2][letter]; // pour toute les combinaisons d'états atteignables depuis state1 et // state2 avec la lettre for (uint i = 0; i < size_dequeue(reachable1); i++) { for (uint j = 0; j < size_dequeue(reachable2); j++) { // Récupérer les états atteignables uint next_state1 = lefread_dequeue(reachable1, i); uint next_state2 = lefread_dequeue(reachable2, j); // Calculer le nouvel état atteignable dans l'automate produit uint new_next_state = next_state1 * nfa2->trans->size_graph + next_state2; // Ajouter la transition dans l'automate produit rigins_dequeue(new_next_state, result->trans->edges[new_state][letter]); } } } } } printf("Intersection de l'automate3\n"); fflush(stdout); // Enregistrer les noms des états si nécessaire if (nom) { for (uint state1 = 0; state1 < nfa1->trans->size_graph; state1++) { for (uint state2 = 0; state2 < nfa2->trans->size_graph; state2++) { // Calculer le nouvel état dans l'automate produit uint new_state = state1 * nfa2->trans->size_graph + state2; // Récupérer les noms des états des deux automates printf("c'est pas ici\n"); fflush(stdout); char *name1 = nfa_copy_one_name(nfa1, state1); char *name2 = nfa_copy_one_name(nfa2, state2); // Calculer la longueur des noms printf("vincent c'est un genie\n"); fflush(stdout); size_t len1 = name1 ? strlen(name1) : 0; size_t len2 = name2 ? strlen(name2) : 0; // Allouer de la mémoire pour le nom du nouvel état result->state_names[new_state] = (char *)malloc((len1 + len2 + 4) * sizeof(char)); printf("blem de malloc\n"); fflush(stdout); // Copier le nom du premier état if (name1) { strcpy(result->state_names[new_state], name1); free(name1); } printf("truc bizzar de copilot\n"); fflush(stdout); // Ajouter une virgule pour séparer les noms strcat(result->state_names[new_state], ","); // Copier le nom du second état if (name2) { strcat(result->state_names[new_state], name2); free(name2); } } } } printf("fin Intersection de l'automate\n"); fflush(stdout); // Retourner l'automate produit return result; }