Máquinas de Turing
Aumentando el poder Hasta aquí: Autómatas finitos ( lenguajes regulares), el poder de cómputo de los sistemas con memoria finita. Bastante limitados: pueden describir patrones “simples” en texto. Autómatas de pila ( lenguajes de libre contexto), memoria no acotada pero de acceso limitado. Pueden describir lenguajes de programación, humanos... Pero ciertamente un computador puede hacer más. Como reconocer {w=a n b n c n }, o {w=uu}
Aumentando el poder lenguajes regulares lenguajes de libre contexto ? ?
Memoria más accesible Ahora agregaremos la posibilidad de moverse con libertad por la memoria (sin ir borrando lo que se lee, como en el PDA). La memoria será una cinta potencialmente infinita, en la que podemos escribir y leer símbolos. Movemos la cinta una posición a la izquierda o a la derecha, para acceder a otras posiciones de memoria. Alternativamente, podemos pensarlo como que estamos moviendo un “cabezal” sobre la cinta.
Memoria y unidad de control Cinta Cabezal para leer y escribir Al igual que antes, la máquina tiene una cantidad finita de estados, que representamos con un grafo de transiciones. “Unidad de control”
Memoria y unidad de control Este esquema de “unidad de control” interactuando con una memoria de acceso “libre” suena familiar para un informático, y no es casualidad. Pero notemos que es una extensión de los modelos de cómputo anteriores: En los AF, no había memoria externa. En los PDA, estaba restringida a una pila. ……
Input en cinta; posición inicial Hasta ahora el input lo hemos estado leyendo de una “cinta” aparte. Ahora no será necesario: podemos asumir que viene escrito en la cinta. input posición inicial del cabezal En cada paso, la máquina Lee un símbolo de la cinta Escribe un símbolo en la cinta Mueve el cabezal a izquierda o derecha Actualiza su estado interno w0w0 w1w1 w2w2 wnwn... casillas en blanco
Representando transiciones Nota: también se usa la notación (a,b,L), en lugar de a b,L. lo que leo lo que escribo el movimiento del cabezal (L:left, R:right) el cambio de estado de la máquina
Representando transiciones Aparte del contenido de la cinta, lo único que necesitamos para conocer el estado del sistema es la ubicación del cabezal y el estado de la máquina. Por eso se suelen anotar juntos:
Representando transiciones Si la descripción de la máquina incluye un transición lo que ocurrirá será Tiempo k Tiempo k+1
Representando transiciones Otro ejemplo, aplicando......
DeterminismoDeterminismo Hasta que indiquemos lo contrario, las máquinas de Turing serán deterministas: Para un mismo estado y símbolo en la cinta, sólo hay una transición posible. Nada de transiciones .
Función parcial Pero a diferencia de los AFD, no exigiremos que todos los casos estén cubiertos. Por lo tanto, puede ser que para un cierto símbolo leído, y cierto estado, no haya ninguna transición. Si eso ocurre, la máquina se detiene. En particular, los estados de aceptación no tienen transiciones de salida. Por lo tanto, son estados finales: la máquina acepta y se detiene.
Rechazo o aceptación Cuando la máquina se ejecuta partiendo con una palabra w en la cinta, decimos que la máquina Acepta w: si se detiene en algún momento en un estado de aceptación Rechaza w: Cuando no acepta. Esto puede ocurrir: si se detiene en algún momento en un estado que no es de aceptación...o si nunca se detiene
T=4 Un ejemplo Consideremos la máquina de la arriba, y hagámosla correr sobre el input aaa. T=0 T=1 T=2 T=3 Stop y acepta
Un ejemplo de rechazo T=0 Stop y rechaza T=1 La misma máquina pero con input aba, rechaza.
Otro tipo de rechazo T=0 T=1 Para ver un caso de rechazo por loop infinito, modificamos un poco la máquina. T=2T=4...etc
FormalmenteFormalmente Una máquina de Turing queda definida por M = ( Q, , , , q 0, F, ) donde Q es un conjunto finito de estados es el alfabeto de la cinta es el alfabeto leído por la máquina \ es el carácter “blanco” de la cinta (también se usa B, o ) q 0 Q es el estado inicial F son los estados de aceptación
FormalmenteFormalmente Una máquina de Turing queda definida por M = ( Q, , , , q 0, F, ) donde : Q Q {L,R} es la función de transición Como dijimos antes, se permite que para algunos pares (q,a) el valor de (q,a) no esté definido. Lo podemos interpretar como que en esos casos (q,a) vale “stop” (y algunos libros lo tratan así).
Descripción instantanea El sistema se echa a andar con el input w * escrito en la cinta el resto de la cinta en blanco la máquina en estado q 0 el cabezal apuntando al comienzo de w Por lo tanto, en cualquier momento T la máquina no habrá visitado aún las casillas que estén a distancia mayor que T respecto a la posición inicial. En todo instante el tramo de la cinta que no está en blanco es finito.
Descripción instantanea Eso permite dar una descripción finita del estado del sistema en un momento dado: Sea v el contenido de la cinta desde la posición del cabezal hasta el último símbolo no blanco. Sea u el contenido de la cinta desde el primer símbolo no blanco hasta la casilla anterior a la del cabezal. Sea q el estado interno de la máquina. Entonces anotamos la descripción instantánea o configuración como uqv. Si hay que evitar alguna confusión, escribimos [u,q,v]. uv
Descripción instantanea Como antes, escribimos u q v u’ p v’ si lleva el sistema de uqv a u’pv’ Usamos la misma “ ” para denotar su clausura transitiva (aplicación reiterada de ). Podemos entonces definir el lenguaje aceptado por M como L(M) = { w * : q 0 w uqv, q F }
Una convención práctica Llamémosle "área de trabajo" a la zona de la cinta que no está en blanco. Es recomendable no usar el símbolo dentro del área de trabajo; así siempre podemos usarlo para identificar los bordes. Seguiremos ese consejo. El área de trabajo puede crecer y crecer, pero en cualquier momento dado será finita (pues partió siendo finita). La descripción instantanea uqv da el contenido del área de trabajo (uv), el estado interno de la máquina (q) y su ubicación (entre u y v, apuntando al comienzo de u). área de trabajo...
Volvamos al ejemplo: una observación Claramente, el lenguaje aceptado por el ejemplo que vimos es a * Ese es un lenguaje regular. Nótese además que esta MT no escribe. No es casualidad: no es dificil ver que cualquier lenguaje regular puede ser aceptado por una MT que no altera su cinta.
MT para lenguajes regulares Idea: La MT simplemente lee la palabra como lo haría el AFD, avanzando siempre hacia la derecha. Sus estados corresponden a los del AFD. Se agrega un estado extra para la aceptación (pues los del AFD no eran de detención; pierden su condición de estado de aceptación al pasar a la MT), y para llegar a él se chequea el fin del input.. Detalles: ejercicio. De hecho es un ssi: Si a la MT le prohibimos escribir, sólo puede aceptar lenguajes regulares.
Otro ejemplo Veamos un MT para el lenguaje {a n b n }
T= 0
T= 1
T= 2
T= 3
T= 4
T= 5
T= 6
T= 7
T= 8
T= 9
T= 10
T= 11
T= 12
Para & acepta T= 13
El segundo ejemplo Podemos resumir el funcionamiento de esa máquina de Turing mediante pseudocódigo: While veo a a x Avanzar (R) saltando {a,y}, hasta ver b b y Avanzar (L) saltando {a,y}, hasta ver x Avanzar (R) Avanzar (R) saltando {y} hasta ver Aceptar La gracia: nada nos impide extender la idea para reconocer {a n b n c n }.
{a n b n c n }, pseudocódigo While veo a a x Avanzar (R) saltando {a,y}, hasta ver b b y Avanzar (R) saltando {b,z}, hasta ver c c z Avanzar (L) saltando {a,y,b,z}, hasta ver x Avanzar (R) Avanzar (R) saltando {y,z} hasta ver Aceptar Ejercicio: Hacer la MT Proponer alternativa que use sólo {a,b,c,x, } como alfabeto en la cinta.
LR:decidido; LRE:aceptado Decimos que una máquina de Turing M decide un lenguaje L si M acepta L, y además M siempre se detiene. Los lenguajes que son decididos por alguna MT se llaman lenguajes recursivos (LR). Los lenguajes que son aceptados por alguna MT se llaman lenguajes recursivos enumerables (LRE). Nótese que, por definición, LR LRE.
Funciones Turing-computables Otra forma de “usar” una MT es mirando lo que deja en la cinta cuando se detiene. Como la MT es determinista, el estado final de la cinta está determinado completamente por el estado inicial: es una función del estado inicial. Dada una MT M y un input w *, hay dos casos: Si M se detiene con configuración upv, definimos f M (w)=uv. Si M nunca se detiene, definimos f M (w)= (decimos que para w, f M diverge).
Funciones Turing-computables Entonces, toda MT M induce una función f M : * * { } Decimos que una función f es Turing-computable si existe una MT que la induce. Config. inicialConfig. final Loop ( )
Funciones Turing-computables Observaciones: Sin perder generalidad, podemos suponer que el dominio de f está restringido a un dominio D *. Algunos autores exigen que al terminar el cómputo el cabezal esté en el inicio de f(w). No es difícil modificar la MT para cumplir con eso, si hace falta. Para efectos prácticos, los argumentos de f M se suelen codificar en * (i.e., en general no los escribimos tal cual como los leeríamos nosotros).
Ejemplo: x+y Para simplificar, codificaremos números enteros en sistema unario. 5 decimal 101 binario unario Demostremos que la suma de números naturales es una función computable. Input: x0y Output: xy0 Aprovecharemos que x concatenado con y da x+y, en unario
Ejemplo: x+y
T= 0
T= 1
T= 2
T= 3
T= 4
T= 5
T= 6
T= 7
T= 8
T= 9
T= 10
T= 11
Parar y aceptar T= 12
Otro ejemplo: 2x Esta MT calcula 2x, para x en unario:
Otro ejemplo: 2x Describamos su funcionamiento en pseudocódigo informal: Reemplazar cada 1 por un $. REPETIR Encontrar el $ de más a la derecha, cambiarlo a 1. Ir al extremo derecho, insertar un 1. HASTA que no queden $ ¿Cómo calcularíamos xy? ¿Y n!?
Más cómputos Si quisiéramos calcular el “pseudocódigo” sería: Para cada 1 en x, ir borrándolo y borrando un 1 del y. Si en algún momento busco un 1 en y, y no encuentro, entonces borrar todo y escribir un 1. Si eso nunca ocurre, y es x el que se acaba, borrar todo y escribir un 0. Ejercicio: construir la MT.
Combinación de máquinas Programar MT es engorroso, pero esencialmente fácil. El paradigma resulta sorprendentemente flexible. También es notablemente robusto: es posible agregar muchas “features” (por ejemplo, una segunda cinta) a una MT sin que su poder de cómputo cambie. Veremos varios de esos “features”; con ellos en mano, es más fácil construir MT más ambiciosas.
Combinación de máquinas En particular, será posible ver cada MT como una “caja negra”, que se puede usar como subrutina en otra MT. MT inputoutput MT comparadora MT sumadora MT borradora
Variaciones c/r a las MT estándar Nuestro modelo estándar: cabezal que escribe y lee transiciones entre los estados internos de la MT son determinísticas 1 cinta, infinita en ambas direcciones (movimiento es a izquierda o derecha)
Variaciones c/r a las MT estándar Algunas variantes: Cinta semi-infinita. Varias cintas. “Cinta” bidimensional. Opción de no mover el cabezal. Opción de insertar símbolos. Transiciones no deterministas. MT “offline” ( el input queda sin tocar, en su propia cinta). Largo Etc.
Variaciones c/r a las MT estándar Ninguna de estas variantes altera el poder de cómputo de las MT. ¿Qué significa eso? Que los lenguajes que se pueden aceptar o decidir son los mismos. En cada caso se demuestra que si MT estándar M, entonces MT M’ del tipo modificado que es equivalente, y viceversa.
Variaciones c/r a las MT estándar ¿Qué significa que las máquinas sean equivalentes? Si estamos viendo la MT como un reconocedor de lenguajes, significa dos cosas: que L(M)=L(M’) que M se detiene con input w ssi M’ se detiene con input w. Si en cambio vemos la MT como el cómputo de una función, significa que f M =f M’ (Pues en la opción f M (w)= ya está incluida la información sobre la detención)
MT con opción “Stay” Una MT+stay (máquina de Turing con opción “stay”) es similar a la MT estándar, pero además de poder mover el cabezal a izquierda o derecha (“L” o “R”), tiene la opción de dejarlo donde está (“S”). Por ejemplo, una transición podría ser y al aplicarla ocurrirán cosas del tipo...
MT con opción “Stay” Teorema: las MT+stay tienen el mismo poder de cómputo que las MT estándar. Demostración: demostraremos que 1.Las MT+stay tienen al menos el poder de cómputo de las MT estándar. 2. Las MT estándar tienen al menos el poder de cómputo de las MT+stay.
MT con opción “Stay” 2. Las MT estándar tienen al menos el poder de cómputo de las MT+stay. Para eso, veremos cómo convertir una MT+stay en una MT estándar, sin alterar su funcionamiento. 1.Las MT+stay tienen al menos el poder de cómputo de las MT estándar. Demostración: directo, pues la MT estándar es un caso particular de MT+stay.
MT con opción “Stay” Para cada transición que use el “S” (stay), agregamos un estado auxiliar, y reemplazamos la transición por 1+| | transiciones: Una de esas por cada x QED
MT con opción “Stay” T = 1T = 2 en M, la MT+stay T = 1T = 2T = 3 en M’, la MT estándar
Ejercicio: MT con movimiento en dos pasos A sugerencia del público, ejercicio: Diremos que una MT es de "dos pasos" si sus opciones de movimiento son {L, L 2, R, R 2 }, donde L y R se entienden como antes, L 2 mueve el cabezal dos posiciones hacia la izquierda, y R 2 lo mueve posiciones a la derecha. EJ: Demostrar que las MT de "dos pasos" tienen el mismo poder de cómputo de las MT estándar. N De hecho, dado k N, una MT con movimientos {L, L 2,..., L k, R, R 2,...,R k } también sigue siendo equivalente.
MT con varias “pistas” Una MT “multitrack” (varias pistas) tiene una única cinta de memoria, pero esa cinta tiene más de una pista de información: pista 1 pista 2 Habrá transiciones de la forma
MT con varias “pistas” Claramente las MT multitrack son una generalización de las MT estándar (basta con ignorar las pistas adicionales para volver al caso estándar). pista 1 pista 2 Por otro lado, para simular una MT multitrack con alfabeto y k pistas, usando una MT estándar, basta que tomemos ’ = k. Cada casilla de la cinta nueva contendrá lo que había en las k pistas, en esa posición.
MT con varias “pistas” M, multitrackM’, estándar T=0 T=1
MT con memoria "interna" finita Una MT con memoria interna posee una o más variables cuyo valor se guarda dentro del estado interno (no en la cinta); cada variable debe tener un rango finito. Por ejemplo: una MT podría tener las variables m 1 D 1 = {0, 1} m 2 D 2 = {blanco, azul, rojo} m 3 D 3 = { , } Los valores se pueden consultar y modificar en las transiciones (si no se modifican, quedan como estaban).
MT con memoria "interna" finita Sin perder generalidad, podemos verlo como que fuese una sola variable: m = (m 1,m 2,m 3 ) D = D 1 D 2 D 3 Claramente, es una extensión c/r a las MT estándar. Pero: no cambia el poder de cómputo. Para simular una MT con memoria interna mediante una MT estándar, la idea es: Reemplazar Q por Q' = Q D.
MT con memoria "interna" finita Q' = Q D La condición sobre valores de variables se convierte simplemente en condición sobre el estado interno, y la modificación de valores, en elegir a qué estado paso. Es importante que el rango (valores posibles) de las variables internas sea finito; de lo contrario, Q' quedaría infinito. Nótese que esta extensión también funciona para AFD y para PDA. estado interno estado "de control" variables internas
MT con cinta semi-infinita Una MT con cinta semi-infinita tiene una cinta que es infinita en una sola dirección: en lugar de... se tiene Aquí el # marca el fin de la cinta (como el "$" que marcaba el fondo de la pila en los PDA). Algunos textos (p.ej. el Hopcroft) usan este tipo de MT como "estándar"
MT con cinta semi-infinita A diferencia de las modificaciones previas, esta no es una "generalización", sino una "restricción" respecto a nuestras MT estándar. Las restricciones pueden restringir el poder de cómputo (por ejemplo, si la MT no puede escribir, su poder se reduce al de los AFD). Sin embargo, esta restricción particular no cambia el poder de cómputo:
MT con cinta semi-infinita Es directo ver que toda MT con cinta semi-infinita puede ser simulada por una MT estándar: simplemente no usamos la cinta a la izquierda. En dirección contraria: necesitamos probar que dada una MT estándar, la podemos simular en una con cinta semi-infinita.
MT con cinta semi-infinita Fijamos un punto de referencia en nuestra cinta infinita (puede ser la posición de inicio del cabezal). "Doblamos" la cinta infinita en torno a ese punto, dejando una cinta semi-infinita de dos pistas: lado derecho lado izquierdo
MT con cinta semi-infinita Los movimientos L, R se invierten si estamos "abajo". Al pasar por el punto de referencia, "viramos". Aplicamos el método previo para pasar a una única cinta. Para saber si hay que mirar arriba o abajo, guardamos una variable en memoria interna ("arriba", "abajo") lado derecho lado izquierdo
MT con marcas en la cinta Podemos agregar a la MT la posibilidad de poner y quitar marcas en la cinta (aparte del símbolo contenido en la celda) Y luego podemos usar la marca para reconocer la celda. La condición es que la variedad de marcas sea finita: por ejemplo, M={, , } (donde es "sin marca"). ¿Cómo hacemos esto con una MT estándar? Reemplazamos por ' = M
MT con Insert/Delete Una MT con insert puede hacer transiciones del tipo (Duplica la celda, y se sitúa a la izquierda).
MT con Insert/Delete Una MT con delete puede hacer transiciones del tipo (Borra la celda, y se sitúa a la izquierda).
MT con Insert/Delete Ambas operaciones se pueden implementar en una MT estándar: Para duplicar: Marcamos la celda Avanzamos hasta el final del área de trabajo Retrocedemos copiando cada celda en la siguiente...hasta llegar a la celda marcada. Para borrar: Marco la celda y copia en ella el valor de la celda vecina. Sigo copiando hasta llegar al final del área de trabajo Me devuelvo hasta la celda marcada.
MT con varias cintas A diferencia de la máquina "con varias pistas" que vimos antes, en la MT "multicinta" cada cinta tiene su propio cabezal. Las transiciones miran ambas cintas, y deciden escritura y movimiento en ambas cintas. Unidad de control Cinta 1Cinta 2
MT con varias cintas T = 1 T = 2 Cinta 1Cinta 2
MT con varias cintas ¿Cómo podemos simular una MT multicinta, usando una MT estándar? Lo que haremos será simularla usando una MT con una cinta, pero varias pistas (y esa ya sabemos que es equivalente a la estándar). Idea: Por cada cinta de la MT multicinta, ponemos dos pistas: Una con los datos Otra que indica dónde está el cabezal.
MT con varias cintas Cinta 1 "Cabezal" de la cinta 1 Cinta 2 "Cabezal" de la cinta 2 Cinta 1Cinta 2 Cabezal de la MT multipista
MT con varias cintas Para simular un paso de la MT multicinta, la MT multipista hace lo siguiente: Sitúa su cabezal a la izquierda de todos los "cabezales". Avanza hacia la derecha hasta ver todos los "cabezales", y guardando en variables internas el símbolo apuntado por cada uno de ellos. Aplica la regla de la MT multicinta, y guarda en variables internas los nuevos símbolos y los movimientos de cada cinta. Avanza a la izquierda, aplicando eso a cada cinta a medida que va encontrando los cabezales.
MT con varias cintas Por lo tanto, toda MT multipista se puede simular con una MT estándar, y viceversa. Observaciones: Obviamente esta construcción es poco práctica: la máquina multipista requiere muchos pasos para simular cada paso de la máquina multicinta. Sin embargo, por ahora no nos interesa la velocidad. Lo que interesa: es que lo computable (lenguajes, funciones) no cambia.
MT multidimensionales Z Z 2 Z 3 En una MT multidimensional, en lugar de tener una cinta infinita (que se puede ver como una función Z ), tenemos un plano, volumen, o algo de dimensión mayor (que se pueden ver como funciones Z 2 , Z 3 , etc). En dimensión 2, los movimientos serán L,R,U,D (agregamos up y down). El poder de cómputo tampoco aumenta (pero no lo demostraremos!).
MT no-deterministas En una MT no determinista, existe más de una transición posible a partir de una configuración dada. T = 1 T = 2 Opción 1Opción 2
MT no-deterministas Como de costumbre, el lenguaje asociado a una MT no- determinista será el conjunto de palabras para las cuales existe alguna cadena de decisiones que conduce a un estado de aceptación. Nuevamente se tiene la equivalencia: todo lenguaje aceptado por una MT no-determinista, es aceptado por una MT estándar (determinista). Hay varias construcciones posibles; aquí solo bosquejaremos una. Sea M la MT no-determinista, y veamos como construir M' estándar, equivalente a M.
MT no-deterministas Idea: a la usanza de los viejos sistemas operativos, simularemos una máquina paralela usando una máquina secuencial. En la cinta habrá una serie (finita) de áreas de trabajo, cada una con la posición de su "cabezal" marcada área 1 $ $ área 2 $ En cada vuelta, M' recorrerá todas las áreas, ejecutando una iteración de M en cada una de ellas.
MT no-deterministas Cada vez que toque "adivinar" un paso, el área de trabajo se bifurcará (usamos un "insert"), y ahora habrá un área por cada opción. Si en algún momento en alguna versión del área de trabajo M llega a aceptar el input, M' lo aceptará área 1 $ $ área 2 $ área 1b $ $ área 2 $ área 1a $
MT offline Una MT offline tiene dos cintas: el input, que sólo se lee, y otra para trabajar. Unidad de control Cinta de entrada Cinta de trabajo sólo lectura lectura/escritura Claramente, el poder de cómputo tampoco cambia.
LLC LRE Ya vimos que los lenguajes regulares pueden ser aceptados por MT (y sin siquiera escribir en la cinta). Para ver que los lenguajes de libre contexto son aceptados por MT, tomamos un PDA cualquiera... Input Pila Estados internos PDA...y lo podemos ver como una MT no- determinista con dos cintas: una de sólo lectura (con el input) la otra (la pila) inicialmente vacía.
Jerarquía de lenguajes Sabíamos que los lenguajes regulares eran un caso particular de los lenguajes de libre contexto; ahora vemos que los de libre contexto son caso particular de los recursivos. Vimos un lenguaje ( {a n b n c n } ) que es recursivo pero no es LLC. E hicimos notar que recursivo recursivo enumerable (es decir, que ser decidido por una MT implica ser aceptado por una MT). Tenemos entonces las siguientes inclusiones:
Jerarquía de lenguajes Pronto veremos ejemplos concretos que muestran que cada una de estas inclusiones es propia. Lenguajes Lenguajes recursivos enumerables (r.e.) Lenguajes recursivos Lenguajes de libre contexto Lenguajes regulares
Dos teoremas sobre complementos Teorema: L es recursivo ssi L C es recursivo. Demostración: Usamos la misma MT, pero cambiamos sus estados de aceptación: F' = Q \ F. Teorema: Si L es r.e. y L C es r.e., entonces L es recursivo. Demostración: Dado un input w, ejecutamos simultáneamente las MT de L y de L C (un paso a la vez para cada una). Tarde o temprano una de las dos se tiene que detener, y sabremos si w L.
EnumeraciónEnumeración N Dijimos que un conjunto es numerable si es finito, o si tiene el cardinal de los números naturales (N). Para evitar confusión le llamaremos a eso contable. Ejemplos de infinitos contables: ZZ (enteros) QQ (racionales) ZZ (pares ordenados de enteros) Z2Z (números pares) Ejemplos de infinitos no contables: RR (reales) [0,1] (o cualquier intervalo con más de 1 elemento) NNP(N) (cjto. formado por los subconjuntos de N).
EnumeraciónEnumeración Por lo general para demostrar que un conjunto es contable lo que se hace es describir un procedimiento de enumeración. Sea L un conjunto de palabras. Definiremos un procedimiento de enumeración para L como una máquina de Turing que: no recibe ningún input genera todas las palabras de L cada palabra es generada en tiempo finito Podemos suponer que hay una cinta de trabajo, y otra en la cual escribir las palabras de L.
EnumeraciónEnumeración área de trabajo w2w2 w3w3 # w1w1 # # Es útil pensar en la cinta de salida como una "impresora", donde la MT va agregando palabras. Que la MT enumere L significa que: w L, t w en que w es impresa. Si w es impresa, w L.
EnumeraciónEnumeración OJO: Diremos que un lenguaje es enumerable (con "e") si hay una MT que lo enumere. Si un conjunto (en particular, un lenguaje) es enumerable, entonces necesariamente es contable (de hecho, cualquier lenguaje es contable). Sin embargo, lo contrario no es necesariamente cierto: puede que un conjunto sea contable y sin embargo no exista una MT que lo enumere.
EnumeraciónEnumeración Sea un alfabeto (es decir, un conjunto finito cualquiera). Entonces * es un conjunto infinito enumerable. ¿Por qué? Hay que describir una forma de enumerar las palabras de * No toda idea es buena. Tomemos ={a,b} como ejemplo. Una idea que no funciona es listarlas en orden alfabético (poniéndole algún orden alfabético a ): como hay infinitas palabras que parten con a, jamás llegaremos a listar las que parten con b.
EnumeraciónEnumeración En cambio, sí podemos enumerar * si primero listamos todas las palabras de largo 0, luego las de largo 1, luego las de largo 2, etc. Dentro de las de un mismo largo, podemos seguir orden alfabético. # a # b # aa # ab # ba # bb # aaa #... A este tipo de orden (en longitud creciente, y orden alfabético dentro de la misma longitud) se le llama orden canónico.
EnumeraciónEnumeración Teorema: L * es recursivo enumerable ssi existe una MT que lo enumera. Demostración: ( ) Existe una MT M E que enumera L, y queremos crear una MT M A que acepte L. MA:MA: Recibe un input w, y lo deja intacto en una cinta. Usa dos cintas más para echar a correr M E. Cada vez que M E imprime una palabra, M A la compara con w. Si es igual, acepta w y se detiene. De lo contrario, continúa.
EnumeraciónEnumeración Teorema: L * es recursivo enumerable ssi existe una MT que lo enumera. Demostración: ( ) Existe una MT M A que acepta L, y queremos crear una MT M E que enumere L. Tentación: que M E vaya listando las palabras de * en orden canónico, y ejecutando M A para cada una, para ver acaso están en L (e imprimiéndolas, cuando la respuesta es sí). Problema: para alguna palabra M A puede no detenerse, y M E se quedará pegada (y nunca seguirá listando).
EnumeraciónEnumeración Teorema: L * es recursivo enumerable ssi existe una MT que lo enumera. Solución a eso: Construimos M E para que funcione de acuerdo al siguiente algoritmo: Para k=0,1,2,... Listar las primeras k palabras (del orden canónico): w 1,...,w k Para cada w i, Ejecutar M A con input w i durante k pasos. Si M A aceptó w i, imprimir w i. QED
EnumeraciónEnumeración Teorema: L * es recursivo enumerable ssi existe una MT que lo enumera. Teorema: L * es recursivo ssi existe una MT que lo enumera en orden canónico. Demostración: ejercicio. Otros ejercicios: construir MT para enumerar: {a n b n, n>0} los números naturales, en binario los números enteros, en decimal
CodificaciónCodificación Para efectos de enumerar, pero también para efectos de calcular funciones, y/o decidir propiedades, necesitamos convertir el input en un string. Sólo así puede ser input para una MT Eso puede requerir una codificación no trivial, pero en principio es siempre posible (con información digital). Después de todo, los mp3, avi, jpg, son precisamente información convertida a strings. Lo importante es precisar qué codificación se usa. Luego nuestra MT se ocupará de entenderla.
CodificaciónCodificación Ejemplo: codificar un grafo dirigido. AB C Una opción: codificar la cantidad de nodos, y la matriz de adyacencia, en que A ij =1 si hay arco de i a j, A ij =0 si no. 111# A B C A B C Cantidad de nodos (en unario) Matriz de adyacencia
CodificaciónCodificación Ejemplo: codificar un grafo dirigido. Otra opción: codificar la cantidad de nodos, y luego los arcos. 111#1#11#11#11#1#111#111#11 AB C Cantidad de nodos (en unario) (A,B)(B,B)(A,C)(C,B) Ejercicios: codificar AFD codificar GLC
CodificaciónCodificación Algo más complicado: las propias máquinas de Turing. Podemos codificar en unario los símbolos de y los estados de Q (usaremos el contexto para evitar ambigüedad). También los movimientos del cabezal: 1 para L, 11 para R. símbolos codificación estados
CodificaciónCodificación Codificando una transición: Codificando las transiciones:
CodificaciónCodificación Podemos codificar la máquina entera dando: [cantidad de estados] # [cantidad de símbolos en ] # [lista de transiciones] # [lista de estados que son de aceptación] Y tendremos un lenguaje L MT sobre el alfabeto {#,1}, formado por todas las posibles MT.
CodificaciónCodificación L MT es un lenguaje recursivo: podemos construir una MT que vaya generando las palabras de {#,1} * en orden canónico para cada una, chequeará si es una MT válida (basta ver que siga el formato que describimos) y los números calcen si es válida, imprime la palabra; si no, la ignora. L MT se puede enumerar, y más aún, se puede enumerar en orden canónico.
CodificaciónCodificación Se deduce que existen lenguajes que no son r.e. (es decir, no son aceptados por ninguna MT): Fijemos el alfabeto, . Como vimos, * es un infinito contable. P( * ) es un infinito no contable: es decir, existe una infinidad no contable de lenguajes distintos. Las MT sobre el alfabeto son un conjunto enumerable, ergo contable. No puede haber una MT (distinta) para cada lenguaje. ¡No alcanzan!
Un lenguaje fuera de LRE Sin embargo, podemos ser un poco más explícitos: usaremos el método diagonal de Cantor para construir: un lenguaje que no es r.e. un lenguaje que es r.e., pero no recursivo Consideremos el alfabeto = {a}. Consideremos también las MT que aceptan lenguajes sobre . Son enumerables: llamémoslas M 1, M 2, M 3,...
Un lenguaje fuera de LRE Cada L(M i ) es un conjunto de palabras de la forma a n. Podemos entonces hacer una "tabla" infinita anotando qué palabras están en qué lenguajes. Definamos el lenguaje L como { a k : a k L(M k ) }
Un lenguaje fuera de LRE Por construcción, L C (ojo, el complemento de L) no coincide con L(M k ) para ningún k. L C no es recursivo enumerable L
Un lenguaje fuera de LRE L C no es recursivo enumerable. Por otro lado, L sí es recursivo enumerable. En efecto, existe una MT que lo acepta, y la construímos de la siguiente forma: Dado un input w=a k, identificamos el valor de k. Usando la MT que enumera las M 1, M 2,..., encontramos M k. Echamos a correr M k, dándole el input w. Si se detiene y acepta, aceptamos w.
Un lenguaje fuera de LRE L es recursivo enumerable. L C no es recursivo enumerable. Por lo tanto, L no es recursivo. Si lo fuera, L C sería recursivo también. Pero en tal caso sería r.e. contradicción
Un lenguaje fuera de LRE Lenguajes Lenguajes recursivos enumerables (r.e.) Lenguajes recursivos Lenguajes de libre contexto Lenguajes regulares L L es recursivo enumerable pero no recursivo. LCLC L C no es recursivo enumerable.
MT y PDAs “aumentados” Puede parecer un poco brusco el salto desde los LLC y los PDA, a las máquinas de Turing (en las que se puede programar prácticamente lo que se nos ocurra). Sin embargo: Definamos los "autómatas de cola", como autómatas finitos a los que en lugar de agregarles una pila, les agregamos una cola. Definamos los "2PDA", autómatas finitos a los que en lugar de agregarles una pila, les agregamos 2 pilas. Ejr.: cada una de esas clases es equivalente a las MT.
Gramáticas generales Dijimos que una gramática, en su forma más general, admitía producciones de la forma abbacXaYb bbabXX Xa baa | Y A diferencia de la GLC, en el caso general no hay restricción sobre el lado izquierdo de las producciones. Al derivar una palabra se usan las reglas para ir reemplazando lo que está a la izquierda por lo que esté a la derecha.
Gramáticas generales Ejemplo: una gramática para un lenguaje que no es de libre contexto. S XYZS | XY YX YZ ZY XZ ZX X a Y b Z c Teorema [no veremos la demo.]: un lenguaje es recursivo enumerable ssi existe una gramática que lo genera.
Otros modelos de cómputo Por distintos lados (gramáticas, autómatas con cola, autómatas con dos pilas, MT) se llega a la misma clase de lenguajes (el mismo poder de cómputo). Y al agregar más cosas (más cintas, más pilas, no determinismo, etc etc), ya no aumenta. * Es la punta del iceberg: todos los otros modelos de computo que se han inventado han resultado ser equivalente (o inferiores) al poder de cómputo de las máquinas de Turing.
Continuará...