/* afne-afd.cpp Ing.Rosa Imelda Garc¡a Chi Programa que convierte un automata finito no determinista de movimientos vacios en un automata finito determinista con un numero maximo de 10 estados y 2 simbolos. */ #define MAXEST 10 #define MAXSIM 3 #define NULO -1 #define VACIO -2
// Dos simbolos + el estado vacio.
#include <stdio.h> #include <stdlib.h> #include <iostream.h> #include <conio.h> #include <dos.h> void pantalla(); void mensaje(int); void Beep(); void copia(int, int, int, int); int agregacad(int, int, int); void transicion(int, int, int); int igual(int, int, int, int); struct {
int est[MAXEST]; } funtra[MAXSIM][MAXEST]; struct { int est[MAXEST]; } nuefuntra[MAXSIM][MAXEST]; struct { int est[MAXEST]; } cer[MAXEST]; int main () { int int char /* ** */
est[MAXEST], sim[MAXSIM], estini, estfin[MAXEST]; i, j, k, l, lin, col, ren, maxlin, maxcol, est1, est2, pos, pos1, pos2; c;
pantalla(); Inicializacion de variables.
i= j= k= 0; while (i < MAXSIM) { // Funcion de transicion. while (j < MAXEST) { while (k < MAXEST) { funtra[i][j].est[k]= NULO; k++; } k= 0; j++; } j= 0; i++; } i= j= k= 0; while (i < MAXSIM) { // Nueva funcion de transicion. while (j < MAXEST) { while (k < MAXEST) { nuefuntra[i][j].est[k]= NULO; k++; } k= 0; j++; } j= 0; i++; } i= 0; while (i < MAXSIM) { // Simbolos. sim[i]= NULO; i++; } i= 0; while (i < MAXEST) { est[i]= NULO; i++; }
// Estados.
i= j= 0; while (i < MAXEST) { // Cerradura de los estados. while (j < MAXEST) { cer[i].est[j]= NULO; j++; } j= 0; i++;
/* ** */
/* ** */
/* ** */
} Introduce los valores de los estados. mensaje(0); col= 9; lin= 7; gotoxy(col,lin); for (i=0; i < MAXEST && (c=getche()) != 13; ++i) { if (c >= 48 && c <= 57 && (c==48+i)) { est[i]= c-48; col= col+4; mensaje(i+1); gotoxy(col,lin); } else { Beep(); gotoxy(col,lin); cout << " "; gotoxy(col,lin); --i; } }
// Sale cuando oprime <Enter> // Si esta en el rango 0-9
Introduce los valores de los simbolos. mensaje(0); col= 8; lin= 8; gotoxy(col,lin); for (i=0; i < MAXSIM-1 && (c=getche()) != 13; ++i) { if (c >= 48 && c <=57 && (c==48+i)) { sim[i]= c-48; col= col+2; mensaje(i+1); gotoxy(col,lin); } else { Beep(); gotoxy(col,lin); cout << " "; gotoxy(col,lin); --i; } } Introduce el valor del estado inicial.
// Sale cuando oprime <Enter> // Si esta en el rango 0-9
/* ** */
col= 9; lin= 9; mensaje(10); gotoxy(col,lin); i=1; c= getche(); while (i) { if (c >= 48 && c <=57) { // Si esta en el rango 0-9 estini= c-48; i= 0; } else { Beep(); gotoxy(col,lin); cout << " "; gotoxy(col,lin); c= getche(); } } Introduce los valores de los estados finales. col= 9; lin= 10; mensaje(10); gotoxy(col,lin); for (i=0; i < MAXEST && (c=getche()) != 13; ++i) { if (c >= 48 && c <=57) { // Si esta en el rango 0-9 estfin[i]= c-48; col= col+4; gotoxy(col,lin); } else { Beep(); gotoxy(col,lin); cout << " "; gotoxy(col,lin); --i; } }
/* ** */
Despliega los simbolos. i= 0; col= 1; lin= 12; gotoxy(col,lin); cout << "ë"; // ë - Alt+235
/* ** */
col= col+4; while (i < MAXSIM && sim[i] != NULO) { gotoxy(col,lin); cout << sim[i]; col= col+30; i++; } gotoxy(col,lin); cout << "î"; // î - Alt+238 i++; maxcol= i; // Maximo de columna por avanzar. Despliega los estados. i= 0; col= 1; lin= 13; while (i < MAXEST && est[i] != NULO) { gotoxy(col,lin); cout << "q" << est[i]; lin++; i++; } maxlin= i; // Maximo de linea por avanzar.
/* ** */
Introduce los valores de la funcion de transicion.
i= j= 0; col= 4; lin= 13; while (i < maxlin) { while (j < maxcol) { gotoxy(col-1,lin); cout << "{"; gotoxy(col,lin); cout << "q"; for (k=0; k < MAXEST && (c=getche()) != 13; ++k) { if ((c >= 48 && c <=57) || (c == 'f' || c == 'F')) { // Si esta en el rango 0-9 if (c >= 48 && c <=57) // o es vacio (í) la letra f. funtra[j][i].est[k]= c-48; else { funtra[j][i].est[k]= VACIO; col= col+3; break; } col= col+3;
gotoxy(col,lin); cout << "q"; } else {
} j= 0; col= 4; lin++; i++; /* ** */
} } j++; gotoxy(col,lin); cout << "}"; if (j == 1) col= 34; else col= 64;
Beep(); gotoxy(col+1,lin); cout << " "; gotoxy(col+1,lin); --k;
} Construye la cerradura de los estados.
est1= pos1= 0; while (est1 < maxlin) { cer[est1].est[pos1]= est1; pos2= pos= 0; while (cer[est1].est[pos1] != NULO) { est2= cer[est1].est[pos1]; while (funtra[maxcol-1][est2].est[pos2] != NULO) { while (cer[est1].est[pos] != NULO) if (cer[est1].est[pos] == funtra[maxcol-1][est2].est[pos2]) pos2++; else pos++; if (funtra[maxcol-1][est2].est[pos2] != VACIO) { cer[est1].est[pos]= funtra[maxcol-1][est2].est[pos2]; pos++; } pos2++; pos= 0; } pos1++; pos2= 0; } // Ordena la cadena de estados (Metodo de la Burbuja).
NULO)) {
i= 0; while (i < pos1-1) { j= 0; while(j < pos1-i) { if ((cer[est1].est[j] > cer[est1].est[j+1]) && (cer[est1].est[j+1] !=
} i++;
} j++;
k= cer[est1].est[j]; cer[est1].est[j]= cer[est1].est[j+1]; cer[est1].est[j+1] = k;
} est1++; pos1= 0;
} // Despliega la cerradura de los estados. pos1= est1= 0; cout << '\n'; while (est1 < maxlin) { cout << "Cî(q" << est1 << ")={"; while (cer[est1].est[pos1] != NULO) { cout << "q" << cer[est1].est[pos1]; pos1++; if (cer[est1].est[pos1] != NULO) cout << ","; } cout << "}" << " "; pos1= 0; est1++; } /* ** Construye los renglones de la nueva funcion de transicion. */ // En la primer columna se colocan las cerraduras de los estados (q0 = Cî(q0)) ren= maxlin; i= j= 0; while (i < ren) { while (cer[i].est[j] != NULO) { nuefuntra[0][i].est[j]= cer[i].est[j]; j++; } j= 0; i++; } i= 0;
while (i <= ren) { j= 0; while (j < maxcol) { transicion(j+1, i, 1); j++; } i++; } /* ** ** ** */
// Realiza la union entre Simbolo-j Estado-i.
Copia en la funcion de transicion (funtra) los datos de la nueva funcion de transicion (nuefuntra); esto es los datos de funtra del afne por los datos de nuefuntra del afn e inicializa nuefuntra. i= 0; col= 5; lin++; gotoxy(col,lin); cout << "ë''"; // ë - Alt+235 col= col+4; while (i < MAXSIM && sim[i] != NULO) { gotoxy(col,lin); cout << sim[i]; col= col+30; i++; } maxcol= i; col= 5; l= lin++; pos1= est1= 0; pos= 1; while (est1 < maxlin) { gotoxy(col,lin); cout << "q" << est1; col= col+4; while (pos < maxcol+1) { gotoxy(col,lin); cout << "{"; while (nuefuntra[pos][est1].est[pos1] != NULO) { if (nuefuntra[pos][est1].est[pos1] != VACIO) { cout << "q"; cout << nuefuntra[pos][est1].est[pos1]; } else cout << "í"; pos1++; if (nuefuntra[pos][est1].est[pos1] != NULO) cout << ","; } cout << "}";
} est1++; pos= 1; lin++; col= 5;
col= col+30; pos++; pos1= 0;
} i= j= k= 0; while (i < MAXSIM-1) { // Funcion de transicion con datos del afn. while (j < MAXEST) { while (k < MAXEST) { funtra[i][j].est[k]= nuefuntra[i+1][j].est[k]; k++; } k= 0; j++; } j= 0; i++; } i= j= k= 0; while (i < MAXSIM) { // Nueva funcion de transicion. while (j < MAXEST) { while (k < MAXEST) { nuefuntra[i][j].est[k]= NULO; k++; } k= 0; j++; } j= 0; i++; } /* ** */
Construye la nueva funcion de transicion (primer renglon). i= j= k= 0; while (i < 1) { // Se copian el primer renglon de la funcion de transicion while (j < MAXSIM+1) { // en la nueva funcion de transicion. while (k < MAXEST) { if (j==0) { nuefuntra[j][i].est[k]= 0; break; } else {
nuefuntra[j][i].est[k]= funtra[j-1][i].est[k]; k++; } k= 0; j++;
}
} j= 0; i++;
/* ** */
} ren= 0; ren= agregacad(0+1, 0, ren); ren= agregacad(1+1, 0, ren);
// Agrega en la nueva funcion Simbolo-0 Estado-0. // Agrega en la nueva funcion Simbolo-1 Estado-0.
Construye los siguientes renglones de la nueva funcion de transicion.
i= 1; while (i <= ren) { j= 0; while (j < maxcol) { transicion(j+1, i, 0); Estado-i. ren= agregacad(j+1, i, ren); Estado-i. j++; } i++; } /* ** Despliega la nueva funcion de transicion. */ i= 0; col= 55; lin= l; gotoxy(col,lin); cout << "ë'"; // ë - Alt+235 col= col+4; while (i < MAXSIM && sim[i] != NULO) { gotoxy(col,lin); cout << sim[i]; col= col+4; i++; } maxcol= i; l= 0; col= 55; lin++;
// Realiza la union entre Simbolo-j // Agrega en la nueva funcion Simbolo-j
}
while (l <= ren) { gotoxy (col,lin); cout << "r" << l; col= col+4; i= 0; while ( i < maxcol) { j= 0; while (j <= ren) { k= igual(0, j, i+1, l); if ( k != -1) { gotoxy(col,lin); cout << "r" << k; col= col+4; break; } else j++; } i++; } l++; col= 55; lin++; }
void pantalla() { clrscr(); gotoxy(5,1); cout << "AUTOMATA FINITO NO DETERMINISTA DE MOVIMIENTOS VACIOS"; gotoxy(5,3); cout << "En donde:"; gotoxy(5,5); cout << "Q=Estados ä=Simbolos q0=Estado Inicial F=Estados Finales"; gotoxy(5,7); cout << "Q={q , q , q , q , q , q , q , q , q , q }"; gotoxy(5,8); cout << "ä={ , }"; // ä - Alt+228 gotoxy(5,9); cout << "q0=q "; gotoxy(5,10); cout << "F={q , q , q , q , q , q , q , q , q , q }"; gotoxy(5,23); cout << "Utilice la letra f para indicar vacio (í)"; // í - Alt+237 } void mensaje(int i) { gotoxy(5,24); clreol();
}
if (i==10) cout << "Escriba digitos del 0 al 9. Si desea avanzar de linea presione <Enter>"; else if (i==11) cout << "Escriba digitos del 0 al 1. Si desea avanzar de linea presione <Enter>"; else cout << "Escriba el digitos " << i << ". Si desea avanzar de linea presione <Enter>";
void Beep() { cout << '\a'; gotoxy(5,23); cerr << "Error. Caracter fuera de rango."; sleep(2); gotoxy(5,23); clreol(); } void copia(int sim, int est, int sim1, int est1) { int i; i= 0; while (i < MAXEST) { nuefuntra[sim][est].est[i]= nuefuntra[sim1][est1].est[i]; i++; } } int agregacad(int sim, int est, int ren) { int i, est1, ban; i= est1= 0; ban= 1; while (est1 <= ren) { while (nuefuntra[0][est1].est[i] != NULO && ban) { if (nuefuntra[0][est1].est[i] == nuefuntra[sim][est].est[i]) i++; else ban= 0; } if (ban && nuefuntra[0][est1].est[i] == nuefuntra[sim][est].est[i]) { iguales
return ren; } else {
}
// Son diferentes est1++; i= 0; ban= 1;
} copia(0, est1, sim, est);
// Son
}
return est1;
void transicion(int sim, int est, int cerradura) { int i, j, k, aux, ban, temp[MAXEST]; i= j= aux= 0; ban= 1; if (nuefuntra[0][est].est[i] == VACIO) { nuefuntra[0+1][est].est[i] = VACIO; nuefuntra[1+1][est].est[i] = VACIO; } else { while (nuefuntra[0][est].est[i] != NULO) { while (funtra[sim-1][nuefuntra[0][est].est[i]].est[j] != NULO) { if (ban) { // La primera vez acepta el primer estado. nuefuntra[sim][est].est[j]= funtra[sim-1][nuefuntra[0] [est].est[i]].est[j]; aux++; ban= 0; } else if (funtra[sim-1][nuefuntra[0][est].est[i]].est[j] != VACIO) { // Si se lee un estado vacio, no se agrega. k= 0; if (nuefuntra[sim][est].est[k] == VACIO) // Si en la primera vez se agrego un estado vacio, se sustituye cuando se lee el siguiente. nuefuntra[sim][est].est[k]= funtra[sim-1] [nuefuntra[0][est].est[i]].est[j]; else { while (k < aux) // Valida que exista el estado solo una vez. if ((nuefuntra[sim][est].est[k] != funtra[sim-1][nuefuntra[0][est].est[i]].est[j]) && (nuefuntra[sim][est].est[k] != NULO)) k++; else break; if (nuefuntra[sim][est].est[k] == NULO) { // Si no existe el estado lo agrega. nuefuntra[sim][est].est[k]= funtra[sim-1] [nuefuntra[0][est].est[i]].est[j]; aux++; } } } j++; } j= 0; i++; }
//
Realiza la union de las cerraduras (si la bandera cerradura esta encendida). if (cerradura == 1) { i= 0; while (i < MAXEST) { temp[i]= nuefuntra[sim][est].est[i]; if (nuefuntra[sim][est].est[i] != VACIO ) nuefuntra[sim][est].est[i]= NULO; i++; } i= 0; while (temp[i] != NULO && temp[i] != VACIO) { if (i == 0) { // La primera vez copia cada uno de los estados. j= 0; while (nuefuntra[0][temp[i]].est[j] != NULO) { if (i == 0) nuefuntra[sim][est].est[j]= nuefuntra[0] [temp[i]].est[j]; else if (nuefuntra[0][temp[i]].est[j] != VACIO) nuefuntra[sim][est].est[j]= nuefuntra[0] [temp[i]].est[j]; j++; } } else { j= k= 0; while (nuefuntra[0][temp[i]].est[j] != NULO) { while (nuefuntra[0][temp[i]].est[j] != nuefuntra[sim] [est].est[k] && nuefuntra[sim][est].est[k] != NULO) k++; if (nuefuntra[sim][est].est[k] == NULO) nuefuntra[sim][est].est[k]= nuefuntra[0] [temp[i]].est[j]; k= 0; j++; } } i++; } } // Ordena la cadena de estados (Metodo de la Burbuja). i= 0; while (i < aux-1) { j= 0; while(j < aux-i) { if ((nuefuntra[sim][est].est[j] > nuefuntra[sim][est].est[i+1]) && (nuefuntra[sim][est].est[j+1] != NULO)) { k= nuefuntra[sim][est].est[j]; nuefuntra[sim][est].est[j]= nuefuntra[sim][est].est[j+1];
} }
} i++;
} j++;
nuefuntra[sim][est].est[j+1] = k;
}
int igual (int sim, int est, int sim1, int est1) { int i;
}
i= 0; while (nuefuntra[sim][est].est[i] != NULO) { if (nuefuntra[sim][est].est[i] == nuefuntra[sim1][est1].est[i]) i++; else return -1; } if (nuefuntra[sim][est].est[i] == nuefuntra[sim1][est1].est[i]) return est; else return -1;