Programa para implementar NFA con paso de épsilon a DFA Conversion

Autómatas finitos no deterministas (NFA): NFA es un autómata finito en el que, en algunos casos, cuando se proporciona una sola entrada a un solo estado, la máquina pasa a más de 1 estado, es decir, algunos de los movimientos no pueden determinarse de forma única por el presente. estado y el símbolo de entrada actual.

An NFA can be represented as M = { Q, ∑, ∂, q0, F}

Q → Conjunto de estados finito no vacío. ∑ → Conjunto finito no vacío de símbolos de entrada. ∂ → Función de Transición. q0 → Estado inicial. F → Estado final

NFA con (nulo) o ∈ movimiento: si cualquier autómata finito contiene ε (nulo) movimiento o transacción, entonces ese autómata finito se llama NFA con ∈ movimientos

Ejemplo: Considere la siguiente figura de NFA con movimiento ∈: Tabla de estado de transición para el NFA anterior 

ESTADOS 0 1 épsilon
A ANTES DE CRISTO A B
B B C
C C C

Epsilon (∈) – cierre: el cierre de Epsilon para un estado X dado es un conjunto de estados que se pueden alcanzar desde los estados X con solo (nulo) o ε movimientos, incluido el propio estado X. En otras palabras, el cierre ε para un estado se puede obtener mediante la operación de unión del cierre ε de los estados que se pueden alcanzar desde X con un solo movimiento ε de manera recursiva. Para el ejemplo anterior, los ∈ cierres son los siguientes:

∈ closure(A) : {A, B, C}
∈ closure(B) : {B, C}
∈ closure(C) : {C}

  Autómatas finitos deterministas (DFA): DFA es un autómata finito en el que, en todos los casos, cuando se proporciona una sola entrada a un solo estado, la máquina pasa a un solo estado, es decir, todos los movimientos de la máquina pueden determinarse de forma única mediante el estado actual y el símbolo de entrada actual.

Pasos para convertir NFA con ε-move a DFA:

Paso 1: Tome el cierre ∈ para el estado inicial de NFA como estado inicial de DFA. Paso 2: encuentre los estados que se pueden atravesar desde el presente para cada símbolo de entrada (unión del valor de transición y sus cierres para cada estado de NFA presente en el estado actual de DFA). Paso 3: si se encuentra algún estado nuevo, tómelo como estado actual y repita el paso 2. Paso 4: repita los pasos 2 y 3 hasta que no haya ningún estado nuevo presente en la tabla de transición de DFA. Paso 5: marque los estados de DFA que contienen el estado final de NFA como estados finales de DFA.

Tabla de estado de transición para DFA correspondiente a NFA anterior

ESTADOS 0 1
A B C ANTES DE CRISTO A B C
ANTES DE CRISTO C ANTES DE CRISTO
C C C

DIAGRAMA DE ESTADO DE DFA Ejemplos:

Input : 6
        2
        FC - BF
        - C -
        - - D
        E A -
        A - BF
        - - -


Output :
 STATES OF NFA :        A, B, C, D, E, F,

 GIVEN SYMBOLS FOR NFA:     0, 1, eps


 NFA STATE TRANSITION TABLE 


STATES    |0    |1    eps
--------+------------------------------------
A    |FC     |-     |BF     
B    |-     |C     |-     
C    |-     |-     |D     
D    |E     |A     |-     
E    |A     |-     |BF     
F    |-     |-     |-     

 e-Closure (A) :    ABF

 e-Closure (B) :    B

 e-Closure (C) :    CD

 e-Closure (D) :    D

 e-Closure (E) :    BEF

 e-Closure (F) :    F


********************************************************

         DFA TRANSITION STATE TABLE          


 STATES OF DFA :        ABF, CDF, CD, BEF,

 GIVEN SYMBOLS FOR DFA:     0, 1,

STATES    |0    |1    
--------+-----------------------
ABF    |CDF     |CD     
CDF    |BEF     |ABF     
CD    |BEF     |ABF     
BEF    |ABF     |CD     



Input :
9
2
- - BH
- - CE
D - -
- - G
- F -
- - G
- - BH
I - -
- -  -


Output :

STATES OF NFA :        A, B, C, D, E, F, G, H, I,

 GIVEN SYMBOLS FOR NFA:     0, 1, eps


 NFA STATE TRANSITION TABLE 


STATES    |0    |1    eps
--------+------------------------------------
A    |-     |-     |BH     
B    |-     |-     |CE     
C    |D     |-     |-     
D    |-     |-     |G     
E    |-     |F     |-     
F    |-     |-     |G     
G    |-     |-     |BH     
H    |I     |-     |-     
I    |-     |-     |-     

 e-Closure (A) :    ABCEH

 e-Closure (B) :    BCE

 e-Closure (C) :    C

 e-Closure (D) :    BCDEGH

 e-Closure (E) :    E

 e-Closure (F) :    BCEFGH

 e-Closure (G) :    BCEGH

 e-Closure (H) :    H

 e-Closure (I) :    I


********************************************************

         DFA TRANSITION STATE TABLE          


 STATES OF DFA :        ABCEH, BCDEGHI, BCEFGH,

 GIVEN SYMBOLS FOR DFA:     0, 1,

STATES    |0    |1    
--------+-----------------------
ABCEH    |BCDEGHI     |BCEFGH     
BCDEGHI    |BCDEGHI     |BCEFGH     
BCEFGH    |BCDEGHI     |BCEFGH     

Explicación: la primera línea de la entrada contiene el número de estados ( N ) de NFA. La segunda línea de la entrada dice el número de símbolos de entrada ( S ). En el ejemplo 1, el número de estados de NFA es 6, es decir ( A, B, C, D, E, F ) y 2 símbolos de entrada, es decir ( 0, 1 ). Dado que estamos trabajando en NFA con ∈ move, se agregará como un símbolo de entrada adicional. Las siguientes N líneas contienen los valores de transición para cada estado de NFA. El valor de la i-ésima fila, j-ésima columna indica el valor de transición para el i-ésimo estado en el j-ésimo símbolo de entrada. Aquí en la transición del ejemplo 1 (A, 0): FC. La salida contiene el NFA, ∈ cierre para cada estado del NFA y DFA correspondiente obtenido al convertir el NFA de entrada. También se especifican los estados y los símbolos de entrada del DFA. A continuación se muestra la implementación del enfoque anterior: 

C

// C Program to illustrate how to convert e-nfa to DFA
 
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_LEN 100
 
char NFA_FILE[MAX_LEN];
char buffer[MAX_LEN];
int zz = 0;
 
// Structure to store DFA states and their
// status ( i.e new entry or already present)
struct DFA {
  char *states;
  int count;
} dfa;
 
int last_index = 0;
FILE *fp;
int symbols;
 
/* reset the hash map*/
void reset(int ar[], int size) {
  int i;
 
  // reset all the values of
  // the mapping array to zero
  for (i = 0; i < size; i++) {
    ar[i] = 0;
  }
}
 
// Check which States are present in the e-closure
 
/* map the states of NFA to a hash set*/
void check(int ar[], char S[]) {
  int i, j;
 
  // To parse the individual states of NFA
  int len = strlen(S);
  for (i = 0; i < len; i++) {
 
    // Set hash map for the position
    // of the states which is found
    j = ((int)(S[i]) - 65);
    ar[j]++;
  }
}
 
// To find new Closure States
void state(int ar[], int size, char S[]) {
  int j, k = 0;
 
  // Combine multiple states of NFA
  // to create new states of DFA
  for (j = 0; j < size; j++) {
    if (ar[j] != 0)
      S[k++] = (char)(65 + j);
  }
 
  // mark the end of the state
  S[k] = '\0';
}
 
// To pick the next closure from closure set
int closure(int ar[], int size) {
  int i;
 
  // check new closure is present or not
  for (i = 0; i < size; i++) {
    if (ar[i] == 1)
      return i;
  }
  return (100);
}
 
// Check new DFA states can be
// entered in DFA table or not
int indexing(struct DFA *dfa) {
  int i;
 
  for (i = 0; i < last_index; i++) {
    if (dfa[i].count == 0)
      return 1;
  }
  return -1;
}
 
/* To Display epsilon closure*/
void Display_closure(int states, int closure_ar[],
                     char *closure_table[],
                     char *NFA_TABLE[][symbols + 1],
                     char *DFA_TABLE[][symbols]) {
  int i;
  for (i = 0; i < states; i++) {
    reset(closure_ar, states);
    closure_ar[i] = 2;
 
    // to neglect blank entry
    if (strcmp(&NFA_TABLE[i][symbols], "-") != 0) {
 
      // copy the NFA transition state to buffer
      strcpy(buffer, &NFA_TABLE[i][symbols]);
      check(closure_ar, buffer);
      int z = closure(closure_ar, states);
 
      // till closure get completely saturated
      while (z != 100)
      {
        if (strcmp(&NFA_TABLE[z][symbols], "-") != 0) {
          strcpy(buffer, &NFA_TABLE[z][symbols]);
 
          // call the check function
          check(closure_ar, buffer);
        }
        closure_ar[z]++;
        z = closure(closure_ar, states);
      }
    }
 
    // print the e closure for every states of NFA
    printf("\n e-Closure (%c) :\t", (char)(65 + i));
 
    bzero((void *)buffer, MAX_LEN);
    state(closure_ar, states, buffer);
    strcpy(&closure_table[i], buffer);
    printf("%s\n", &closure_table[i]);
  }
}
 
/* To check New States in DFA */
int new_states(struct DFA *dfa, char S[]) {
 
  int i;
 
  // To check the current state is already
  // being used as a DFA state or not in
  // DFA transition table
  for (i = 0; i < last_index; i++) {
    if (strcmp(&dfa[i].states, S) == 0)
      return 0;
  }
 
  // push the new
  strcpy(&dfa[last_index++].states, S);
 
  // set the count for new states entered
  // to zero
  dfa[last_index - 1].count = 0;
  return 1;
}
 
// Transition function from NFA to DFA
// (generally union of closure operation )
void trans(char S[], int M, char *clsr_t[], int st,
               char *NFT[][symbols + 1], char TB[]) {
  int len = strlen(S);
  int i, j, k, g;
  int arr[st];
  int sz;
  reset(arr, st);
  char temp[MAX_LEN], temp2[MAX_LEN];
  char *buff;
 
  // Transition function from NFA to DFA
  for (i = 0; i < len; i++) {
 
    j = ((int)(S[i] - 65));
    strcpy(temp, &NFT[j][M]);
 
    if (strcmp(temp, "-") != 0) {
      sz = strlen(temp);
      g = 0;
 
      while (g < sz) {
        k = ((int)(temp[g] - 65));
        strcpy(temp2, &clsr_t[k]);
        check(arr, temp2);
        g++;
      }
    }
  }
 
  bzero((void *)temp, MAX_LEN);
  state(arr, st, temp);
  if (temp[0] != '\0') {
    strcpy(TB, temp);
  } else
    strcpy(TB, "-");
}
 
/* Display DFA transition state table*/
void Display_DFA(int last_index, struct DFA *dfa_states,
                 char *DFA_TABLE[][symbols]) {
  int i, j;
  printf("\n\n********************************************************\n\n");
  printf("\t\t DFA TRANSITION STATE TABLE \t\t \n\n");
  printf("\n STATES OF DFA :\t\t");
 
  for (i = 1; i < last_index; i++)
    printf("%s, ", &dfa_states[i].states);
  printf("\n");
  printf("\n GIVEN SYMBOLS FOR DFA: \t");
 
  for (i = 0; i < symbols; i++)
    printf("%d, ", i);
  printf("\n\n");
  printf("STATES\t");
 
  for (i = 0; i < symbols; i++)
    printf("|%d\t", i);
  printf("\n");
 
  // display the DFA transition state table
  printf("--------+-----------------------\n");
  for (i = 0; i < zz; i++) {
    printf("%s\t", &dfa_states[i + 1].states);
    for (j = 0; j < symbols; j++) {
      printf("|%s \t", &DFA_TABLE[i][j]);
    }
    printf("\n");
  }
}
 
// Driver Code
int main() {
  int i, j, states;
  char T_buf[MAX_LEN];
 
  // creating an array dfa structures
  struct DFA *dfa_states = malloc(MAX_LEN * (sizeof(dfa)));
  states = 6, symbols = 2;
 
  printf("\n STATES OF NFA :\t\t");
  for (i = 0; i < states; i++)
 
    printf("%c, ", (char)(65 + i));
  printf("\n");
  printf("\n GIVEN SYMBOLS FOR NFA: \t");
 
  for (i = 0; i < symbols; i++)
 
    printf("%d, ", i);
  printf("eps");
  printf("\n\n");
  char *NFA_TABLE[states][symbols + 1];
 
  // Hard coded input for NFA table
  char *DFA_TABLE[MAX_LEN][symbols];
  strcpy(&NFA_TABLE[0][0], "FC");
  strcpy(&NFA_TABLE[0][1], "-");
  strcpy(&NFA_TABLE[0][2], "BF");
  strcpy(&NFA_TABLE[1][0], "-");
  strcpy(&NFA_TABLE[1][1], "C");
  strcpy(&NFA_TABLE[1][2], "-");
  strcpy(&NFA_TABLE[2][0], "-");
  strcpy(&NFA_TABLE[2][1], "-");
  strcpy(&NFA_TABLE[2][2], "D");
  strcpy(&NFA_TABLE[3][0], "E");
  strcpy(&NFA_TABLE[3][1], "A");
  strcpy(&NFA_TABLE[3][2], "-");
  strcpy(&NFA_TABLE[4][0], "A");
  strcpy(&NFA_TABLE[4][1], "-");
  strcpy(&NFA_TABLE[4][2], "BF");
  strcpy(&NFA_TABLE[5][0], "-");
  strcpy(&NFA_TABLE[5][1], "-");
  strcpy(&NFA_TABLE[5][2], "-");
  printf("\n NFA STATE TRANSITION TABLE \n\n\n");
  printf("STATES\t");
 
  for (i = 0; i < symbols; i++)
    printf("|%d\t", i);
  printf("eps\n");
 
  // Displaying the matrix of NFA transition table
  printf("--------+------------------------------------\n");
  for (i = 0; i < states; i++) {
    printf("%c\t", (char)(65 + i));
 
    for (j = 0; j <= symbols; j++) {
      printf("|%s \t", &NFA_TABLE[i][j]);
    }
    printf("\n");
  }
  int closure_ar[states];
  char *closure_table[states];
 
  Display_closure(states, closure_ar, closure_table, NFA_TABLE, DFA_TABLE);
  strcpy(&dfa_states[last_index++].states, "-");
 
  dfa_states[last_index - 1].count = 1;
  bzero((void *)buffer, MAX_LEN);
 
  strcpy(buffer, &closure_table[0]);
  strcpy(&dfa_states[last_index++].states, buffer);
 
  int Sm = 1, ind = 1;
  int start_index = 1;
 
  // Filling up the DFA table with transition values
  // Till new states can be entered in DFA table
  while (ind != -1) {
    dfa_states[start_index].count = 1;
    Sm = 0;
    for (i = 0; i < symbols; i++) {
 
      trans(buffer, i, closure_table, states, NFA_TABLE, T_buf);
 
      // storing the new DFA state in buffer
      strcpy(&DFA_TABLE[zz][i], T_buf);
 
      // parameter to control new states
      Sm = Sm + new_states(dfa_states, T_buf);
    }
    ind = indexing(dfa_states);
    if (ind != -1)
      strcpy(buffer, &dfa_states[++start_index].states);
    zz++;
  }
  // display the DFA TABLE
  Display_DFA(last_index, dfa_states, DFA_TABLE);
 
  return 0;
}

Uso de NFA con ∈ move: si queremos construir un FA que acepte un idioma, a veces se vuelve muy difícil o parece imposible construir un NFA o DFA directo. Pero si se usa NFA con ∈ movimientos, entonces el diagrama de transición se puede construir y describir fácilmente.

Publicación traducida automáticamente

Artículo escrito por Agnibha_Chandra y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *