Está en la página 1de 20

Maquina de Turing

Lenguajes Automatas
Armando Ramos Barajas

IVAN MONTES MONTES


PEDRO FRANCISCO ESCALANTE DELGADO

1
Índice

1 INTRODUCCION. .................................................................................................................................... 3
2 OBJETIVO PARTICULAR. ......................................................................................................................... 4
2.1 Objetivos general. ......................................................................................................................... 4
3 MARCO TEORICO. .................................................................................................................................. 4
4 DIAGRAMA DE ESTADOS. ...................................................................................................................... 8
4.1 Máquina Turing (diagrama JFLAP). ................................................................................................ 8
5 DESARROLLO. ........................................................................................................................................ 9
5.1 Código............................................................................................................................................ 9
6 Caja Blanca. ......................................................................................................................................... 18
7 Caja Negra. .......................................................................................................................................... 20
8 Bibliografías. ........................................................................................................................................ 20

2
1 INTRODUCCION.

Una máquina de Turing es un dispositivo de cálculo lógico que utiliza un input en una o
varias cintas que se van moviendo en función de la instrucción que tenga el estado de
un autómata, para finalmente obtener un output mediante la reescritura de los datos en
la misma cinta. La máquina tiene un cabezal de lectura y este lee el dato que se
encuentra en la posición de la cinta. Por buscar una similitud lo más parecido sería un
casette de música, que se rebobina o se adelanta según la canción que nos interese,
en la cual podremos borrar o grabar otra canción donde queramos. En el caso de una
máquina de Turing de una cinta se define dicha máquina como una 7-tupla de la
siguiente manera:

donde:

Símbolo Descripción

Conjunto finito de símbolos que pueden aparecer en la


cinta.

Alfabeto de entrada a la máquina un conjunto finito de


símbolos (menos el espacio en blanco).

Conjunto finito de estados.

Estado inicial en el que empieza la máquina.

Símbolo denominado blanco y es el único símbolo que se


puede repetir un número infinito de veces. Es muy
habitual que el símbolo para referirse al blanco sea ' ' '
'o' '.

Conjunto de estados finales de aceptación.

Función de transición donde es un movimiento a la


izquierda y es el movimiento a la derecha.

Cada función de transición se escribe así:

3
Y se interpreta de la siguiente manera:

1 La máquina se encuentra en el estado

2 Lee un

3 Sobrescribe el con una


4 El cabezal se mueve en la cinta una posición a la derecha (Right)

5 Finalmente se cambia al estado


Teniendo claros los conceptos mínimos de los que se compone una máquina de Turing
se puede diseñar una para saber si una cadena de entrada cumple una expresión
lógico-matemática determinada. A continuación, algunos ejemplos.

2 OBJETIVO PARTICULAR.

Construir autómatas con pila que reconozcan un lenguaje que pueda ser generado a
partir de una gramática independiente del contexto y viceversa. Construir Máquinas de
Turing reconocedores de lenguajes. Reconocer el alcance de las funciones recursivas.
Resolver aplicaciones prácticas y ejercicios con los modelos teóricos anteriores.

2.1 Objetivos general.

Reconocer la importancia y el poder computacional de las Maquinas de Turing en el


contexto de la solución de problemas computacionales de reconocimiento de los
Lenguajes.

3 MARCO TEORICO.

Alan Mathison Turing nació el 23 de junio de 1912 en Paddington (Londres). Su padre,


Julius Mathison, era funcionario del Servicio Civil Indio (cuerpo de funcionarios británicos
en la India), y su madre, Ethel Sara Turing, era hija del Ingeniero Jefe de los Ferrocarriles
de Madrás. Dio muestras de su ingenio y de su capacidad desde una edad muy temprana
(de hecho se cuenta que aprendió a leer por sí sólo en tres semanas), interesándose por
la ciencia en general y por la resolución de enigmas y rompecabezas en particular.

4
Según parece, el temprano interés por la ciencia que demostró no tenía ninguna raíz en
su familia, sino que se trató de un caso de “generación espontánea”. De hecho se afirma
que este interés preocupaba a su madre, que veía peligrar su entrada en la Escuela
Pública Inglesa, poco interesada en fomentar la expresividad, originalidad y el
descubrimiento. Aún así consiguió ingresar en el internado de Sherborne, en Dorset
(cerca de Southampton).

Durante su estancia en esta escuela Alan Turing siguió demostrando su excepcional


capacidad para la ciencia. Con dieciséis años leyó los trabajos de Einstein y, según se
desprende de sus notas personales, no sólo los comprendió, sino que infirió las relaciones
entre éstos y la física Newtoniana de unos textos en los que dichas relaciones no se
encontraban descritas. Es en esta época cuando conoce a Christopher Morcom, un joven
prometedor y brillante con quién mantendrá una intensa relación. Las inquietudes
intelectuales de Christopher se centraban en descubrir las relaciones entre la mente
humana y su “continente” físico, lo que influyó de forma decisiva en el punto de vista tan
particular que tenía Turing acerca de la relación entre lo físico o real y los conceptos
abstractos de matemática pura. La temprana muerte de su amigo marcó profundamente
a Turing e influyó de forma decisiva en su determinación de continuar lo que Cristopher
apenas había podido comenzar.

En 1931 ingresó en el King’s College de Cambridge, consiguiendo un “distinguished


degree”, la mayor calificación posible en los estudios universitarios. En 1935 consiguió
una beca del mismo King’s College y en 1936 un Premio Smith por su trabajo en la teoría
de la probabilidad. En ese momento la carrera de Alan Turing parecía encaminarse hacia
las matemáticas puras tradicionales, pero su singular forma de pensar le condujo en una
dirección completamente inesperada.

Desde 1933 se había interesado por las teorías de Russell, Whitehead y Gödel acerca
de la formalización de las matemáticas en términos de la lógica de proposiciones. Este
interés fue el que llevó a Turing a dar con el conocido como Problema de la
decisión o Entscheidungsproblem, planteado por David Hilbert y Wilhem Ackermann en
1928, y para el que aún no se había encontrado respuesta: ¿Podría existir, al menos en

5
principio, un método definido o proceso a través del cual pudiera decidirse si una
afirmación matemática es demostrable? o dicho de otro modo, ¿es posible encontrar una
forma de saber a ciencia cierta si una afirmación determinada, dentro del contexto de las
matemáticas, es cierta o falsa, o por el contrario existen afirmaciones cuya naturaleza no
podemos determinar?

El logro de Turing fue no sólo el dar respuesta a esa pregunta, sino también la precisa y
contundente definición de método que se vio obligado a construir para ello. Utilizando su
revolucionaria capacidad para mezclar lo físico con la formalidad y el rigor matemático,
Turing ideó una máquina teórica que se ajustaba perfectamente a esta definición: la
Máquina de Turing, y demostró que dicha máquina era capaz de implementar (leer y
ejecutar) cualquier problema matemático que pudiera representarse por medio de un
algoritmo, es decir, que pudiera describirse en un número determinado de pasos
concretos. Turing había descubierto el métodocapaz de procesar cualquier afirmación
matemática, y por tanto le bastó con comprobar que existen problemas que se podían
implementar, pero para los que no se podía saber si la máquina llegaría a una solución o
no, para demostrar, en su memorable estudio de 1936 “Sobre los números computables
con una aplicación al Entscheidungsproblem”, que la respuesta al Problema de la
decisión es no. Todo esto, que puede parecer un simple entretenimiento de científicos
locos, constituye el fundamento teórico sobre el cual se basa la Computación, base
teórica de la Informática, y es que una máquina de Turing no es más que una
computadora expresada de la forma más sencilla posible.

Durante los años siguientes Alan Turing desarrolló sus trabajos sobre computación en la
universidad norteamericana de Princeton, donde se encontraba uno de los más
importantes centros de estudio de lógica formal del mundo, bajo la dirección de Alonzo
Church, quien había sido capaz de llegar a las mismas conclusiones de Turing pero
utilizando métodos más formales desde el punto de vista del rigor matemático. Aunque
Church publicó antes que Turing su descubrimiento, la explicación de Turing ha tenido
mayor transcendencia debido en gran medida a la conexión que encontró entre lo
real y lo formal por medio de una máquina que, aunque con limitaciones, puede
construirse y funcionar fuera de la mente de un matemático.
6
En 1939 retornó a Inglaterra y se involucró en una tarea que iba a ser clave para el
desarrollo de la recién comenzada IIª Guerra Mundial: el descubrimiento del código de la
máquina Enigma, utililizada por el ejército alemán para codificar mensajes. La
descodificación de la Enigma, además de ser cosiderada una verdadera hazaña desde
el punto de vista científico, aportó al bando aliado importantes ventajas estratégicas,
principalmente la posibilidad de que los convoyes que abastecían a las islas británicas
evitaran las emboscadas de los submarinos alemanes. Es una idea comunmente
aceptada que en este incomesurable esfuerzo estuvo una de las claves de la derrota
alemana.

A partir de 1945, una vez terminada la guerra, dedicó sus esfuerzos en el desarrollo de
los primeros computadores en la Universidad de Manchester y en el estudio, más teórico,
de la Inteligencia Artificial. Fue en 1950 cuando desarrolló su famoso “Test de Turing”,
una prueba destinada corroborar la existencia de inteligencia en una máquina. Turing
defendía la viabilidad de construir una máquina con una capacidad de razonamiento tal
que su propio test no fuera capaz de distinguirla de un ser humano, postulado que es el
centro de uno de los debates científicos y filosóficos más interesantes de la actualidad y
que tiene como uno de sus principales detractores al Premio Nobel de Física Roger
Penrose. Como curiosidad, el Test Voight-Kampf que se utiliza para identificar replicantes
en la película Blade Runner es una versión ficticia del test de Turing.

En 1952 vuelve a dar un giro a su carrera y comienza a trabajar en los patrones


matemáticos que hay detrás de muchos procesos biológicos. Si embargo, ese mismo año
Turing recibe un serio revés cuando es procesado por su homosexualidad. La desmedida
persecución pública a la que se vio sometido, sumada al tratamiento hormonal que tuvo
que aceptar como medida alternativa a la prisión y que le produjo importantes
alteraciones físicas, provocaron en Turing una profunda crisis personal de la que no se
recuperó.

Alan Turing apareció muerto en su cama el 7 de junio de 1954 en su casa de Wimslow,


Chesire, cerca de Manchester, con media manzana impregnada de cianuro a su lado. La
causa oficial de su muerte fue el suicidio, y aunque todo apunta que esta es la explicación

7
más probable, no faltaron las especulaciones ni las teorías conspiratorias al respecto. Así
acabó, prematura y trágicamente, la vida de uno de los científicos más importantes del
siglo XX, cuyas ideas fueron transcendentales para la revolución tecnológica que
sobrevino años después, y que aún hoy alimentan debates de gran impotancia para
nuestro futuro.

Afortunadamente en la actualidad la figura de Alan Turing está rehabilitada y ha recibido


su merecido reconocimiento, hasta el punto de que el premio que da la Assosiation for
Computing Machinery a las personas que contribuyen de forma destacada al mundo de
la computación, y que se considera su Nobel, recibe el nombre de Premio Turing. El 10
de septiembre de 2009 el primer ministro del Reino Unido, Gordon Brown, pidió disculpas
en nombre del gobierno por el trato que recibió durante sus últimos años de vida,
restituyendo así oficialmente el honor de Alan Turing quien fue, sin duda, una
auténtica máquina.

4 DIAGRAMA DE ESTADOS.

4.1 Máquina Turing (diagrama JFLAP).


Nuestro trabajo se realizó con 22 estados para poder realizar la siguiente máquina de Turing que se
muestra mas adelante.

8
5 DESARROLLO.

5.1 Código.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>

/* Longitud maxima + 1. */
#define MAX_LONG 256

/* Declaracion de variables globales. */


char *estadoActual;
char *funcion = "Cadena invalida!!";
int i, longitudW;

void estado_q0(char*, int);


void estado_q1(char*, int);
void estado_q2(char*, int);
void estado_q3(char*, int);
void estado_q4(char*, int);
void estado_q5(char*, int);
void estado_q6(char*, int);
void estado_q7(char*, int);
void estado_q8(char*, int);
void estado_q9(char*, int);
void estado_q10(char*, int);
void estado_q11(char*, int);
void estado_q12(char*, int);
void estado_q13(char*, int);
void estado_q14(char*, int);
void estado_q15(char*, int);
void estado_q16(char*, int);
void estado_q17(char*, int);
void estado_q18(char*, int);
void estado_q19(char*, int);
void estado_q20(char*, int);
void estado_q21(char*, int);
void estado_q22(char*, int);
void stop(bool);

void addBlankL(char *w) {


/* Recorro el array de derecha a izquierda y desplazo
* los caracteres una posicion a la derecha */
for (i = strlen(w); i > 0; i--) {
w[i] = w[i - 1];
}

9
/* Concateno la cadena w con un blanco por la izquierda. */
w[i] = '_';
}

void addBlankR(char *w) {


/* Concateno la cadena w con un blanco por la derecha. */
strcat(w, "_");
}

void salidaTrue() {
printf("\n\nCadena aceptada!!");
}

void salidaFalse() {
printf("\n\nError... %s\n\n", funcion);
}

void printLog(char *w, char *ea, int i, char x, char m, char *e) {
printf(
"\nLa cadena es: \"%s\". ( %s,\"%c\") --> ( \"%c\", %c ,
%s).",
w, ea, w[i], x, m, e);
}

void stop(bool resultado) {


if (resultado) {
salidaTrue();
} else {
salidaFalse();
}
}

void estado_q0(char *w, int i) {


estadoActual = "q0";

// Si leo 0
if (w[i] == '0') {

printLog(w, estadoActual, i, 'X', 'R', "q10");

// lo cambio por X
w[i] = 'X';

// me muevo a la derecha (R) y me voy al estado q1.


estado_q10(w, i += 1);

// Si leo 1, X o un blanco (_)


} else if (w[i] == '1' || w[i] == 'X' || w[i] == '_') {

// se para la maquina de Turing con un resultado false.


stop(false);

// Si leo Y
} else if (w[i] == 'Y') {

printLog(w, estadoActual, i, 'Y', 'R', "q12");

10
// dejo Y sin cambiar, me muevo a la derecha (R) y me voy al
estado q3.
estado_q12(w, i += 1);

}else if(w[i] == 'S') {

printLog(w, estadoActual, i, '_', 'R', "q1");


w[i] = '_';
estado_q1(w, i += 1);
}else if(w[i] == 'I') {

printLog(w, estadoActual, i, '0', 'R', "q9");


w[i] = '0';
estado_q9(w, i += 1);
}
}
void estado_q1(char *w, int i) {
estadoActual = "q1";
if (w[i] == '_') {
printLog(w, estadoActual, i, '_', 'L', "q2");
estado_q2(w, i -= 1);

}else if (w[i] == '0') {

printLog(w, estadoActual, i, '0', 'R', "q1");


estado_q1(w, i += 1);

}else if (w[i] == '1') {

printLog(w, estadoActual, i, '1', 'R', "q1");


estado_q1(w, i += 1);
}
}

void estado_q2(char *w, int i) {


estadoActual = "q2";

if (w[i] == '_') {
printLog(w, estadoActual, i, '_', 'R', "q5");
estado_q5(w, i += 1);

}else if (w[i] == '1') {

printLog(w, estadoActual, i, '0', 'L', "q3");


w[i] = '0';
estado_q3(w, i -= 1);

}
}

void estado_q3(char *w, int i) {


estadoActual = "q3";

if (w[i] == '_') {
printLog(w, estadoActual, i, '1', 'L', "q4");
w[i] = '1';
estado_q4(w, i -= 1);

11
}else if (w[i] == '1') {

printLog(w, estadoActual, i, '1', 'L', "q3");


estado_q3(w, i -= 1);

}
}

void estado_q4(char *w, int i) {


estadoActual = "q4";

if (w[i] == '_') {
printLog(w, estadoActual, i, '_', 'R', "q5");
estado_q5(w, i += 1);

}
}

void estado_q5(char *w, int i) {


estadoActual = "q5";

if (w[i] == '_') {
printLog(w, estadoActual, i, '_', 'L', "q6");
estado_q6(w, i -= 1);

}else if (w[i] == '0') {

printLog(w, estadoActual, i, '0', 'R', "q5");


estado_q5(w, i += 1);

}else if (w[i] == '1') {

printLog(w, estadoActual, i, '1', 'R', "q5");


estado_q5(w, i += 1);
}
}

void estado_q6(char *w, int i) {


estadoActual = "q6";

if (w[i] == '0') {
printLog(w, estadoActual, i, '1', 'L', "q7");
w[i] = '1';
estado_q7(w, i -= 1);

}else if (w[i] == '1') {

printLog(w, estadoActual, i, '0', 'L', "q3");


w[i] = '0';
estado_q3(w, i -= 1);

}
}

void estado_q7(char *w, int i) {


estadoActual = "q7";

12
if (w[i] == '_') {
printLog(w, estadoActual, i, '_', 'R', "STOP");
stop(true);
printf("\n\nFuncion 2x + 1\n\n");

}else if (w[i] == '0') {

printLog(w, estadoActual, i, '0', 'L', "q7");


estado_q7(w, i -= 1);

}else if (w[i] == '1') {

printLog(w, estadoActual, i, '1', 'L', "q7");


estado_q7(w, i -= 1);
}
}

void estado_q8(char *w, int i) {


estadoActual = "q8";

if (w[i] == '1') {
printLog(w, estadoActual, i, '0', 'L', "q8");
w[i] = '0';
estado_q8(w, i -= 1);

}
}

void estado_q9(char *w, int i) {


estadoActual = "q9";

if(w[i] == 'V') {

printLog(w, estadoActual, i, '1', 'R', "q14");


w[i] = '1';
estado_q14(w, i += 1);
}
}

void estado_q10(char *w, int i) {


estadoActual = "q10";

// Si leo 0
if (w[i] == '0') {

printLog(w, estadoActual, i, '0', 'R', "q10");

// dejo 0 sin cambiar, me muevo a la derecha (R) y sigo en el


estado q1.
estado_q10(w, i += 1);

// Si leo 1
} else if (w[i] == '1') {

printLog(w, estadoActual, i, 'Y', 'L', "q11");

13
// lo cambio por Y
w[i] = 'Y';

// me muevo a la izquierda (L) y me voy al estado q2.


estado_q11(w, i -= 1);

// Si leo X o un blanco (_)


} else if (w[i] == 'X' || w[i] == '_') {

// se para la maquina de Turing con un resultado false.


stop(false);

// Si leo Y
} else if (w[i] == 'Y') {

printLog(w, estadoActual, i, 'Y', 'R', "q10");

// dejo Y sin cambiar, me muevo a la derecha (R) y me voy al


estado q1.
estado_q10(w, i += 1);
}
}

void estado_q11(char *w, int i) {


estadoActual = "q11";

// Si leo 0
if (w[i] == '0') {

printLog(w, estadoActual, i, '0', 'L', "q11");

// dejo 0 sin cambiar, me muevo a la izquierda (L) y sigo en el


estado q2.
estado_q11(w, i -= 1);

// Si leo 1 o un blanco (_)


} else if (w[i] == '1' || w[i] == '_') {

// se para la maquina de Turing con un resultado false.


stop(false);

// Si leo X
} else if (w[i] == 'X') {

printLog(w, estadoActual, i, 'X', 'R', "q0");

// dejo X sin cambiar, me muevo a la derecha (R) y me voy al


estado q0.
estado_q0(w, i += 1);

// Si leo Y
} else if (w[i] == 'Y') {

printLog(w, estadoActual, i, 'Y', 'L', "q11");

// dejo Y sin cambiar, me muevo a la izquierda (L) y me voy al


estado q2.

14
estado_q11(w, i -= 1);
}
}

void estado_q12(char *w, int i) {


estadoActual = "q12";

// Si leo 0, 1 o X
if (w[i] == '0' || w[i] == '1' || w[i] == 'X') {

// se para la maquina de Turing con un resultado false.


stop(false);

// Si leo Y
} else if (w[i] == 'Y') {

printLog(w, estadoActual, i, 'Y', 'R', "q12");

// dejo Y sin cambiar, me muevo a la derecha (R) y sigo en el


estado q3.
estado_q12(w, i += 1);

}else if (w[i] == '_') {


printLog(w, estadoActual, i, '_', 'R', "STOP");
stop(true);
printf("\n\nCumple x^{n}y^{n} | n >= 0\n\n");

void estado_q14(char *w, int i) {


estadoActual = "q14";

if(w[i] == 'A') {

printLog(w, estadoActual, i, '2', 'R', "q15");


w[i] = '2';
estado_q15(w, i += 1);
}
}

void estado_q15(char *w, int i) {


estadoActual = "q15";

if(w[i] == 'N') {

printLog(w, estadoActual, i, '3', 'R', "q16");


w[i] = '3';
estado_q16(w, i += 1);
}
}

void estado_q16(char *w, int i) {


estadoActual = "q16";

15
if(w[i] == 'M') {

printLog(w, estadoActual, i, '4', 'R', "q17");


w[i] = '4';
estado_q17(w, i += 1);
}
}

void estado_q17(char *w, int i) {


estadoActual = "q17";

if(w[i] == 'O') {

printLog(w, estadoActual, i, '5', 'R', "q18");


w[i] = '5';
estado_q18(w, i += 1);
}
}

void estado_q18(char *w, int i) {


estadoActual = "q18";

if(w[i] == 'N') {

printLog(w, estadoActual, i, '6', 'R', "q19");


w[i] = '6';
estado_q19(w, i += 1);
}
}

void estado_q19(char *w, int i) {


estadoActual = "q19";

if(w[i] == 'T') {

printLog(w, estadoActual, i, '7', 'R', "q20");


w[i] = '7';
estado_q20(w, i += 1);
}
}

void estado_q20(char *w, int i) {


estadoActual = "q20";

if(w[i] == 'E') {

printLog(w, estadoActual, i, '8', 'R', "q21");


w[i] = '8';
estado_q21(w, i += 1);
}
}

void estado_q21(char *w, int i) {


estadoActual = "q21";

if(w[i] == 'S') {

16
printLog(w, estadoActual, i, '9', 'R', "q22");
w[i] = '9';
estado_q22(w, i += 1);
}
}

void estado_q22(char *w, int i) {


estadoActual = "q22";

if (w[i] == '_') {
printLog(w, estadoActual, i, '_', 'R', "STOP");
stop(true);
printf("\n\nCumple lectura de cadena!!\n\n");
}
}

int linea(int s) {
fprintf(stdout,"+");
for (i = 0; i <= s; i++) {
fprintf(stdout,"-");
}
fprintf(stdout,"+\n");
return 0;
}

int main(int argc, char *argv[]) {

/* Se asigna memoria para la cadena w. */


char *w = malloc(MAX_LONG);

printf("Introduce una cadena: ");

/* Guarda la cadena w, con limite de longitud. */


fgets(w, MAX_LONG, stdin);

/* Se obtiene la logitud de la cadena de entrada,


* sin tener en cuanta el salto de linea. */
longitudW = strlen(w) - 1;

/* Elimina salto de linea del final, si existiera. */


if ((longitudW + 1 > 0) && (w[longitudW] == '\n')) {
w[longitudW] = '\0';
}

/* Primera condicion es que la cadena debe ser par */


if (strlen(w) % 2 != 0 ) {
salidaFalse();
} else {
//printTablaMT();

/* Se incorpora un blanco por la izquierda


* y otro por la derecha de la cadena w. */
addBlankL(w);
addBlankR(w);

/* Le digo a la maquina de Turing que empiece

17
* por el caracter w[1] en el estado q0 */
estado_q0(w, 1);

/* Se libera la memoria reservada para la daena w. */


free(w);

return 0;
}

6 Caja Blanca.

Se hizo la compilación introduciendo las cadenas correspondientes que le dimos al diagrama de estado
para que las acepte como se muestran en las siguientes imágenes.

18
19
7 Caja Negra.

Se muestra en las siguientes imágenes que no acepta la cadena porque es incorrecta y porque no la
declaramos en el diagrama de estados.

8 Bibliografías.
https://elmaquinadeturing.wordpress.com/alan-turing/

20

También podría gustarte