146 lines
5.9 KiB
C
146 lines
5.9 KiB
C
/************************/
|
|
/* 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;
|
|
}
|