Edición de «Demostraciones (Teoría de Lenguajes)»

De Cuba-Wiki
Advertencia: no has iniciado sesión. Tu dirección IP se hará pública si haces cualquier edición. Si inicias sesión o creas una cuenta, tus ediciones se atribuirán a tu nombre de usuario, además de otros beneficios.

Puedes deshacer la edición. Antes de deshacer la edición, comprueba la siguiente comparación para verificar que realmente es lo que quieres hacer, y entonces publica los cambios para así efectuar la reversión.

Revisión actual Tu texto
Línea 2: Línea 2:
{{Back|Teoría de Lenguajes}}
{{Back|Teoría de Lenguajes}}


= Lenguajes Regulares =
= Lenguajes regulares =


{{:Demostraciones Lenguajes Regulares (Teoría de Lenguajes)}}
== Automatas ==
 
=== Funcion de transicion extendida ===
 
La funcion de transicion extendida o generalizada se define recursivamente sobre la cadena a la que se aplica. En el caso base (cadena vacia) devuelve el mismo estado (o su clausura lambda en un AFND-λ); en el inductivo, toma la cadena ''w + a'' y devuelve el conjunto resultante de aplicar la transicion por ''a'' al conjunto de estados generado por la transicion sobre ''w''.
 
Esta naturaleza recursiva permite demostrar propiedades sobre la funcion de transicion generalizada a partir de propiedades de la funcion de transicion comun utilizando induccion sobre la longitud de la cadena. Supongamos se tiene una funcion delta igual a una delta prima, se quiere probar que la igualdad vale tambien para la generalizada:
 
<math>\hat \delta \prime (q_0, wa) = \delta \prime (\hat \delta \prime (q_0, w), a)</math>  por definicion de generalizada,
<br/><math> = \delta \prime (\hat \delta (q_0, w), a) </math>  por HI,
<br/><math> = \delta (\hat \delta (q_0, w), a)</math>  por igualdad entre delta,
<br/><math>= \hat \delta (q_0, wa)</math>  por definicion de generalizada.
 
Este esquema puede usarse para probar equivalencias o propiedades sobre funciones generalizadas dadas las de las funciones no generalizadas, y eventualmente predicar sobre el lenguaje en lugar de solamente caracteres.
 
=== Lenguaje aceptado por un automata ===
 
El lenguaje aceptado por un automata generalmente se define como el conjunto de cadenas que derivan en un estado final al consumirse partiendo del estado inicial. Es decir, se define en funcion de la funcion de transicion extendida.
 
<math>w \in L(M) \Leftrightarrow \exists q_f \in \hat \delta (q_0, w)</math>
 
Esto hace que demostrar una propiedad sobre la funcion de transicion extendida permita demostrar propiedades sobre el lenguaje aceptado por un automata. Al demostrar equivalencia entre automatas, conviene demostrar equivalencias entre funciones de transicion extendidas.
 
== Equivalencias ==
 
=== AFND en AFD ===
 
Para probar que todo AFND puede representarse con un AFD, se construye uno equivalente tomando como estados todos los posibles conjuntos de estados del AFND original (partes de <math>Q</math>). Las transiciones entre los estados de este nuevo AFD se definen como las transiciones entre los conjuntos de estados del AFND. Los estados finales del AFD son aquellos conjuntos de estados del AFND que contenían algún estado final. O sea, por ejemplo, si <math>\delta'</math> es la función de transición del AFD, <math>\delta'([q_1,...,q_j], a) = [p_1,...,p_i] \Leftrightarrow \delta(\{q_1,...,q_j\},a) = \{p_1,...,p_i\}</math> .
 
Una manera de demostrar que ambos aceptan el mismo lenguaje, es demostrar primero que la función de transición extendida mantiene la misma relación que la ya definida partiendo de <math>q_0</math> (el estado inicial), y luego chequear las condiciones de aceptación de una cadena de ambos autómatas.
 
Para probar que el conjunto de estados al que se llega en el AFND a partir de una cadena ''x'' es el estado definido por ese mismo conjunto en el AFD, se hace inducción en la longitud de ''x'' para probar <math>\delta'([q_0], x) = [p_1,...,p_i] \Leftrightarrow \delta(q_0,x) = \{p_1,...,p_i\}</math>. El caso base (longitud cero) es trivial. El paso inductivo parte la cadena ''x'' en ''y + a'', siendo ''a'' un caracter, y aplica hipótesis inductiva y la definición de delta del AFD.
 
Al saber que cualquier cadena lleva a estados análogos en el AFND y en el AFD, basta verificar la aceptación de la cadena. En el AFND es aceptada sii en el conjunto de estados al que se llega hay alguno final, mientras que en el AFD cada estado se marca como final si en el conjunto que representa había alguno final. Por lo tanto, el AFND acepta una cadena sii el AFD la acepta, con lo que representan el mismo lenguaje.
 
=== AFND-L en AFND ===
 
Antes de la demostración, es necesario notar que en el caso de los AFND-L la función de transición extendida para un caracter no es equivalente a la función de transición común (pues la primera efectúa la clausura lambda sobre el conjunto de llegada), con lo cual ya no pueden usarse indistintamente.
 
La demostración nuevamente es constructiva, a partir de un AFND-L se crea un AFND que admite el mismo lenguaje. Para esto se toma el mismo conjunto de estados, alfabeto y los mismo estados finales aunque se les agrega el inicial sii tiene algún final en su clausura lambda. La función de transición en el AFND se define como la función de transición extendida (para un caracter) del AFND-L, es decir, se le agrega la clausura lambda a cada paso.
 
Intuitivamente, el AFND generado es igual al AFND-L, pero se quitan las transiciones lambda al agregar transiciones a toda la clausura de la transición original. Por ejemplo, si se tenia <math>A \rightarrow aB</math> y <math>B \rightarrow \lambda C</math>, se reemplaza por <math>A \rightarrow aB</math> y <math>A \rightarrow aC</math>. El único detalle es que para el estado inicial se pierden las transiciones lambda, por eso hay que agregarlo (a veces) a los finales.
 
El lema intermedio a demostrar en este caso es análogo al anterior: <math>\delta'(q_0, x) = \delta\hat (q_0, x)</math> para <math>|x| \ge 1</math>. Se busca probar por inducción que vale la equivalencia (definida entre las funciones de transición de los autómatas) en la función de transición extendida a partir del estado inicial. Nuevamente se demuestra a partir de separar el primer caracter del resto de la cadena, aplicar la definición original y luego hipótesis inductiva.
 
Sabiendo que partiendo de los estados iniciales y consumiendo las mismas cadenas en ambos autómatas se llegan a los mismos estados, resta probar que los lenguajes son iguales. Recordar que la condición de aceptación del AFND y del AFND-L es que la función de transición extendida aplicada a la cadena desde el estado inicial devuelva un conjunto que contenga algún estado final; la diferencia entre AFND y AFND-L es que la función de este ultimo incluye la clausura lambda a cada paso.
 
Si la cadena a aceptar es vacía, entonces en el AFNDL la condición de aceptación es que la clausura lambda del estado inicial contenga un final. Como los finales en el AFND equivalente se definieron incluyendo al estado inicial si esto sucedía, entonces lambda es aceptada en uno sii lo es en el otro.
 
Si la cadena a aceptar es no vacía, entonces ambas funciones de transición llevan al mismo conjunto de estados (por el lema intermedio). Como los estados finales son equivalentes o difieren en <math>q_0</math>, entonces la cadena es aceptada en un autómata sii (hay que separar el análisis según si se agregó a los estados finales <math>q_0</math> o no).
 
Por lo tanto, el AFND así construido reconoce el mismo lenguaje que el AFNDL original.
 
=== Expresiones Regulares en AFND-L ===
 
Dada cualquier expresion regular, se puede construir un AFND-L con un unico estado final y sin transiciones a partir de este, haciendo induccion sobre la estructura de la expresion regular.
 
[[Image:REtoAFNDL.png]]
 
=== AFD en Expresiones Regulares ===
 
La demostración de la existencia de una expresión regular que captura el mismo lenguaje que un AFD es constructiva. Se basa en la definición de un sublenguaje (o conjunto de cadenas) <math>R^k_{i,j}</math>, previo numerar los estados del autómata de ''1'' a ''n''.
 
La expresión <math>R^k_{i,j}</math> representa a todas las cadenas que se obtienen en el automata yendo desde el estado ''i'' al estado ''j'' pasando por estados de índice a lo sumo ''k''. Notar que ''i'' y ''j'' pueden ser mayores a ''k'', pero solamente si aparecen como principio y final del camino. Análogamente, se define <math>r^k_{i,j}</math> como la expresión regular cuyo lenguaje es dicho conjunto de cadenas.
 
La construcción de los ''R'' se hace mediante inducción sobre ''k''´y lo que debemos demostrar constructivamente por inducción es que podemos dar una expresión regular cuyo lenguaje es ''R''. El caso base es cuando se tiene <math>R^0_{i,j}</math>, esto es, todos los caminos que van de ''i'' a ''j'' sin pasar por ningún estado intermedio (pues están numerados a partir de 1). Esto es el conjunto de terminales que se encuentran en todos los arcos que van de ''i'' a ''j'', más lambda si ''i'' y ''j'' son el mismo estado (el conjunto también puede ser vacío). La expresión regular que lo denota es simplemente la disyunción de todos los terminales así obtenidos, con o sin <math>\lambda</math> según corresponda, la expresión regular <math>\emptyset</math>.
 
Para el paso inductivo, <math>R^k_{i,j}</math> con <math>k \geq 1</math>, para cada camino se pueden dar dos posibilidades. Una es que el camino no pase por ningun estado de índice ''k'', con lo que <math>r^k_{i,j} = r^{k-1}_{i,j}</math>.
 
El caso más elaborado es cuando pasa al menos una vez por el nodo ''k''. Cada camino puede partirse entonces en tres partes: desde ''i'' a la primera aparición de ''k'', desde la primera aparición de ''k'' hasta la ultima (que a su vez se puede dividir como cero o más caminos que empezaron y terminaron en k), y desde la última aparición de ''k'' hasta ''j''.
 
[[Image:AfdToRegex.PNG|Caminos de i a j pasando una o mas veces por k]]
 
Esto puede escribirse como <math>R^{k-1}_{i,k} (R^{k-1}_{k,k})^* R^{k-1}_{k,j}</math>. Sumado al caso en que no se pasa por el nodo ''k'', y reemplazando cada conjunto de cadena por la ER que la representa, se tiene que la expresión regular final que denota las cadenas de <math>R_{i,j}^k</math> es <math>r^{k-1}_{i,j} | r^{k-1}_{i,k} (r^{k-1}_{k,k})^* r^{k-1}_{k,j}</math> (se aplicó la hipótesis inductiva en cada <math>R^{k-1}</math>).
 
En castellano, esto significa que para ir del nodo ''i'' al ''j'' pasando por nodos de a lo sumo índice ''k'', se puede o bien ir directamente de ''i'' a ''j'' pasando por nodos de a lo sumo ''k-1'', o bien ir hasta ''k'', hacer cero o varios loops, y luego hacer el ultimo tramo de ''k'' a ''j''.
 
Por lo tanto, se pueden generar expresiones regulares para todos los conjuntos de cadenas <math>R^n_{i,j}</math>, esto es, todas las cadenas que resultan de recorrer los caminos de ''i'' a ''j'', sin restricción sobre los nodos intermedios.
 
Notar que el autómata acepta una cadena si existe un camino que la genera que comience en el estado inicial y termine en un estado final. Por lo tanto, las cadenas aceptadas serán aquellas de la forma <math>R^n_{i,j}</math>, con ''i'' estado inicial y ''j'' algún estado final.
 
Entonces, la expresión regular que genera el mismo lenguaje que el autómata es  <math>r^n_{1,f_1} | r^n_{1,f_2} | \ldots | r^n_{1,f_m}</math>, siendo <math>f_1 \ldots f_m</math> los estados finales del autómata, y 1 el estado inicial.
 
=== Gramaticas Regulares en AFND ===
 
Dada una gramática regular <math>G = <V_n, V_T, P, S></math> existe un <math>AFND</math>  <math>M = <Q, \Sigma, \delta, q_0, F></math>
 
Se puede definir <math>M</math> como:
 
# <math>Q = V_N \cup \{q_f\}</math>
# <math>\Sigma = V_T</math>
# <math>q_0 = q_s</math>
# <math>q_B \in \delta(q_A, a) \leftrightarrow A \rightarrow aB \in P</math>
# <math>q_f \in \delta(q_A, a) \leftrightarrow A \rightarrow a \in P</math>
# <math>q_A \in F \leftrightarrow A \rightarrow \lambda \in P</math>
# <math>q_f \in F</math>
 
La idea es que <math>M</math> va a ser un AFND donde cada no terminal sea un estado, los terminales son las etiquetas de las transiciones entre estados  y <math>q_A</math> se conecta con <math>q_B</math> por <math>a</math> si en <math>G</math> está la producción <math>A \rightarrow aB</math>. El estado inicial va a ser el del no terminal distinguido (<math>q_S</math>) y se agrega otro estado final (<math>q_f</math>)  para conectar con <math>q_A</math> si está <math>A \rightarrow a</math>.
 
'''Idea de la demostración''':
 
Se demuestra primero el lema <math>A \Rightarrow^* wB \Leftrightarrow q_B \in \delta(q_A,w)</math> por inducción en <math>w</math>:
* El caso base <math>w = \lambda</math> es aútomático, porque si <math>w</math> es vacia, <math>B</math> tiene que ser <math>A</math> (por las producciones que puede tener la gramática) y por definición de <math>\delta</math> también se cumple lo otro.
* Luego se prueba para <math>w = \alpha a</math>. Se ve que si <math>A \Rightarrow^* \alpha(aB)</math>, de <math>q_A</math> se puede llegar a <math>q_C</math> por <math>\alpha</math> por hip. inductiva, y que de <math>q_C</math> se puede llegar a <math>q_B</math> por <math>a</math> por la regla 4 de la definición de <math>M</math>. Entonces de <math>q_A</math> se puede llegar a <math>q_B</math> por <math>\alpha a</math>.
 
Después se debe probar que el lenguaje generado por <math>G</math> y <math>M</math> es el mismo:
* Se parte de:  <math>wa \in L(G) \Leftrightarrow S \Rightarrow^* wa</math> .
** Hay dos formas en que de <math>S</math> se puede llegar a la forma sentencial de sólo terminales <math>wa</math>:
**#  Se llega al <math>a</math> final usando como último paso <math>A \rightarrow a</math>. Entonces, (por el '''lema''' aplicado a <math>w</math>), de <math>q_S</math> se llegó a <math>q_A</math>,  y '''(por def. 5)'''  <math>q_A</math> se conecta a <math>q_f</math> por <math>a</math>.
**#  La otra opción es que como último paso nos deshacemos de un no terminal <math>B</math> que le seguía al terminal <math>a</math>, y que desapareció usando <math>B \rightarrow \lambda</math>. Entonces, por el '''lema''' (aplicado a <math>waB</math>), de <math>q_S</math> se llega a <math>q_B</math> por <math>wa</math>, y '''(por def. 6)''' <math>q_B</math> es final.
** Llegamos entonces a que de <math>q_S</math> se llega por <math>wa</math> a <math>q_f</math> o a un estado final <math>q_B</math>, lo cual es equivalente a  <math>wa \in L(M)</math>.
* Se ve aparte: <math>\lambda \in L(G) \; \Leftrightarrow \; S \rightarrow \lambda \; \Leftrightarrow  \; q_S \in F \; \Leftrightarrow \; \lambda \in L(M)</math>.
 
=== AFD en Gramáticas Regulares ===
 
Dado un AFD  <math>M = <Q, \Sigma, \delta, q_0, F></math> existe un gramática regular <math>G = <V_n, V_T, P, S></math> equivalente. Se demuestra definiendo <math>G</math> así y probando luego que <math>M</math> y <math>G</math> generan el mismo lenguaje.
 
# <math>V_N = Q</math>
# <math>V_T = \Sigma</math>
# <math>S = A_{q_0}</math>
# <math>A_p \rightarrow aA_q \in P \leftrightarrow q = \delta(p, a) </math>
# <math>A_p \rightarrow a \in P \leftrightarrow \delta(p, a) \in F </math>
# <math>S \rightarrow \lambda \in P \leftrightarrow q_0 \in F</math>
 
La idea es casi es la inversa que para pasar de gramática regular a AFND.
 
'''Idea de la demostración''':
 
Se demuestra primero el lema <math>\delta(p,w) = q \Leftrightarrow A_p \Rightarrow^* wA_q</math> por inducción en <math>w</math>:
* El caso base <math>w = \lambda</math> es verdadero por definición en los dos lados del ssi.
* Se prueba para <math>w = \alpha a</math>  separando el último paso de <math>\delta</math> y aplicando la hip. inductiva a <math>\alpha</math> para llegar a que <math>A_p \Rightarrow^* wA_x</math>  (donde <math>x</math> es el estado anterior para llegar a <math>q</math>) y usando que como de <math>x</math> se llega a <math>q</math>, por la '''regla 4'''  <math>A_x \rightarrow aA_q</math>.
 
Después se debe probar que el lenguaje generado por <math>G</math> y <math>M</math> es el mismo:
* Analizamos cadenas no vacias partiendo de <math>wa \in L(M) \Leftrightarrow \delta(q_0, wa) \in F</math> . Separamos <math>\delta</math> en el estado <math>p</math> al que se llega consumiendo <math>w</math> y la última transición por <math>a</math> al estado final. Por el '''lema''', al anteúltimo estado <math>p</math> se llega con <math>w</math> ssi  <math>A_{q_0} \Rightarrow^* wA_p</math>, y por la '''def. 5''' <math>A_p \rightarrow a</math>. Esas dos cosas son equivalentes a <math>A_{q_0} \Rightarrow^* wa</math>.
* Por '''def. 6'''  <math>q_0</math> M es final (acepta la cadena vacía) ssi <math>S \rightarrow \lambda</math>.
 
== Propiedades ==
 
=== Unión ===
 
'''El conjunto de lenguajes regulares incluido en''' <math>\Sigma^*</math> '''es cerrado respecto de la unión. Dados''' <math>L_1</math> = <math>L(M_1)</math> y
<math>L_2 = L(M_2)</math>, <math>L_1 \cup L2</math> '''es un lenguaje regular'''.
 
* Esto es inmediato con expresiones regulares, ya que el lenguaje generado por <math>ER(L_1)+ER(L_2)</math> es regular y el más es por definición la unión de los lenguajes <math>L_1</math> y <math>L_2</math>.
 
* Si lo queremos probar con autómatas, basta con:  pegar <math>M_1</math> al lado de <math>M_2</math>, agregar un estado inicial <math>q_0</math> que tiene transiciones a los mismos estados (y por los mismos símbolos) que los iniciales de <math>M_1</math> y <math>M_2</math>, marcarlo como final si alguno de los lenguajes acepta la cadena vacía y listo (transiciones y finales queda igual).
 
=== Complemento ===
 
'''El complmento de un lenguaje regular es regular'''
 
* Una forma constructiva de probar esto es tomando el AFD del lenguaje y complementando el conjunto de estados finales (poniendo los finales como no finales y vicevera). Es inmediato que esto genera el complemento. Si <math>\Delta</math> es el alfabeto del autómata y queremos tomar el complemento respecto a un superconjunto <math>\Sigma</math> de <math>\Delta</math>, basta con encontrar el autómata del complemento <math>M'</math> y calcular: <math>L(M') \cup \Sigma^*(\Sigma - \Delta)\Sigma^*</math> (''notar que es una unión de lenguajes regulares''). Recordar que el AFD debe estar completo (tener el estado "trampa").
 
=== Intersección ===
 
'''La intersección de un lenguaje regular es regular'''
 
Es inmediata usando la ley de DeMorgan, ya que <math>L_1 \cap L_2 = \overline{\overline{L_1} \cup \overline{L_2}}</math>.
 
También se puede realizar de forma constructiva a partir de los autómatas. Se arma un gran autómata que tiene como estados el producto cartesiano de los estados de los otros dos de forma tal que un estado <math>(a, b)</math> es final si <math>a</math> y <math>b</math> son finales en sus respectivos autómatas.
 
=== Unión e Intersección finita ===
 
'''La unión finita y la intersección finita de lenguajes regulares dan por resultado un leguaje regular'''. Es trivial de probar con una inducción.
 
'''Esto NO VALE para INFINITO'''. (pensar en la unión infinita de <math>a^k b^k</math>)
 
=== Pertenencia ===
 
'''Saber si una cadena pertenece a un lenguaje regular es decidible''' (Dado el lenguaje regular, se construye su AFD y se pone a prueba la cadena).
 
=== Finitud ===
 
'''Todo lenguaje finito es regular'''. Ya que se puede ver como la unión finita de los elementos uno a uno.
 
'''Determinar si un lenguaje regular es finito es decidible'''
 
Un lenguaje regular es finito si en su AFD ningún estado desde el cual se pueda alcanzar un estado final puede dar lugar a un "ciclo".
 
Alternativamente, un lenguaje regular es infinito sii su AFD acepta al menos una cadena de longitud <math>k</math> tal que <math>2n > k \geq n</math>, donde <math>n</math> es la cantidad de estados del AFD.
 
=== Vacuidad ===
 
'''Determinar si un lenguaje regular es vacío es decidible'''. Se construye el AFD y se mira si alguno de los estados alcanzables es final.
 
=== Equivalencia ===
 
'''Determinar si dos lenguajes regulares son equivalentes es decidible.''' Se construyen sus respectivos autómatas. Luego se construye el autómata de <math>(L_1 \cap \overline{L_2}) \cup (\overline{L_1} \cap L_2)</math>. Si es vacío, son equivalentes, sino no lo son.
 
== Lema de Pumping ==
 
=== Transición para Config Instantánea ===
 
La función de transición entre dos configuraciones instantáneas se define como <math>(q, a \alpha ) \vdash (p, \alpha)</math> sii existe una transición de ''q'' a ''p'' por ''a''. Asimismo se define la función de transición generalizada.
 
Vale que si <math>(q, \alpha \beta ) \vdash ^*(q, \beta)</math>, entonces <math>(q, \alpha ^i \beta ) \vdash ^*(q, \beta)</math> para cualquier <math>i \geq 0</math>. Es decir, si es posible hacer un loop sobre el estado ''q'' consumiendo la cadena alfa, entonces es posible realizar ese loop tantas veces como se desee. Se demuestra fácilmente por inducción en la cantidad de repeticiones de alfa.
 
=== Pumping ===
 
El lema de pumping expresa que dada una longitud mínima '''n''' (que depende del lenguaje), todas las cadenas ''z'' de longitud mayor o igual a ''n'' pueden escribirse como ''z = uvw'', donde ''uv'' no supera a ''n'', ''v'' es no vacía y es posible repetir tantas veces ''v'' como se desee sin que la cadena deje de pertenecer al lenguaje. Es decir, <math>uv^*w</math> pertenece al lenguaje.
 
Intuitivamente, significa que existe una longitud '''n''' (para la cual puede tomarse la cantidad de estados del AFD mínimo que captura el lenguaje) tal que toda cadena mayor o igual resulta de haber realizado al menos un ciclo sobre uno de los estados del autómata. Esto es, si se tiene ''w = xyz'', se obtiene un recorrido de la siguiente forma.
 
[[Image:PumpingRegular.PNG|Lema de pumping]]
 
Notar que la cadena ''y'' debe ser no vacía para que el ciclo efectivamente exista, ''xy'' es menor que la cantidad de estados del autómata, y la cadena total debe superar la cantidad de estados (o podría ser capturada por el autómata sin efectuar ningún ciclo). Expresado en transiciones de configuraciones instantáneas:
 
<math>(q_0, xyz) \vdash ^* (q_{i_j}, yz) \vdash ^* (q_{i_k}, z) \vdash ^* (q_{m}, \lambda )</math>
 
Como <math>q_{i_j} = q_{i_k}</math> y por la propiedad ya demostrada, es posible repetir ''y'' tantas veces como se desee y volver siempre al mismo estado, que tras consumir la cadena ''z'' se sabe que lleva a un estado final con lo que la cadena resulta aceptada.
 
El lema de pumping es una manera útil de determinar si un lenguaje es regular o no. Si no verifica este lema, entonces se sabe que no es regular. Notar que la implicación no vale a la inversa, esto es, un lenguaje no regular puede cumplir pumping de regulares. En estos casos generalmente se recurre a demostrar que el complemento, inverso, unión o alguna combinación a partir de dicho lenguaje no lo verifica.
 
== Minimizacion ==
 
Minimizacion se aplica solamente a AFD, no existe equivalente sobre AFND. Tambien es necesario que el AFD no tenga estados inalcanzables (debe haber un camino orientado desde el estado inicial hacia cualquier otro).
 
Se basa en el concepto de estados indistinguibles. Dos estados son indistinguibles sii para cualquier cadena, partiendo de esos estados se llega siempre o a finales o a no finales. Vale que los estados a los que se llegan son tambien indistinguibles. Indistinguibilidad es una relacion de equivalencia.
 
=== Indistinguibilidad de orden K ===
 
Es analogo a indistinguibilidad pero sujeto a cadenas de longitud a lo sumo K. Es el que se usa en la practica.
 
==== Relacion de equivalencia ====
 
Al igual que indistinguibilidad, es una relacion de equivalencia (reflexiva, simetrica y transitiva). La demostracion es trivial.
 
==== K+1 implica K ====
 
La relacion de orden K+1 esta contenida no estrictamente en la de orden K. Si dos estados son indistinguibles respecto de cadenas de longitud a lo sumo K+1, entonces, en particular, lo son para cadenas de longitud a lo sumo K.
 
==== Cociente por orden 0 ====
 
El conjunto de estados de un automata, cocientado por la relacion de indistinguibildad de orden 0, lo separa en dos clases de equivalencia: los finales y los no finales.
 
==== K+1 sii K por todo terminal ====
 
Dos estados ''p'' y ''r'' son indistinguibles de orden K+1 sii para todo terminal ''a'' vale que los estados que se alcanzan a partir de consumir ''a'' por ''p'' y ''r'' son indistinguibles de orden K. Esto permite dar una definicion inductiva de indistinguibilidad.
 
La ida se prueba por absurdo. Si existe un terminal ''a'' tal que al consumirlo se llega a dos estados ''p' ''y ''r' ''distinguibles por alguna cadena ''alfa'' de longitud a lo sumo K, entonces la cadena ''a + alfa'' distingue K+1 a ''p'' y ''r'', lo que contradice la hipotesis.
 
La vuelta tambien se puede probar por absurdo. Si ''p'' y ''r'' son distinguibles por ''alfa'' de longitud K+1, entonces ''p' ''y ''r' '', alcanzados tras consumir el primer caracter de alfa, son distinguibles por el resto de alfa, que tiene longitud a lo sumo K, lo que contradice la hipotesis.
 
==== K+1 = K implica K+n = K ====
 
Si para cualquier par de estados ''q'' y ''p'' vale que la relacion de indistinguibilidad de orden K+1 es igual a la de orden K, entonces cualquier indistinguibilidad de orden superior seguira siendo igual. Esto da un criterio de corte para la definicion inductiva de indistinguibilidad de orden K, y permite generalizar de orden K a indistinguibilidad en general.
 
Puede demostrarse por induccion en ''n''. El caso base es trivial. Para el paso inductivo, simplemente se usa que si dos estados son indistinguibles orden ''k+n+1'', entonces los estados a los que se llega por cualquier terminal lo son orden ''k+n'', y luego se aplica la hipotesis inductiva.
 
Intuitivamente, esto sucede pues indistinguibilidad de orden K permite distinguir a todos los estados que estan a "distancia" K de algun estado final. Al pasar a K+1, se agregan todos los estados que están a un paso más. Si no hay cambios, es porque ya se cubrieron todos los estados del automata, y no es necesario tener cadenas mas largas para distinguirlos.
 
=== Automata Minimo ===
 
Un automata minimo se logra tomando como estados las clases de equivalencia generadas por la relacion de indistinguibilidad en el automata original. Las transiciones en el nuevo automata se definen como <math>\delta \prime ([q], a) = [ \delta (q,a)]</math>, es decir, el estado alcanzable en el AFDM a partir de la clase ''[q]'' por el terminal ''a'', es la clase que se alcanza por ''a'' a partir de todos los estados que conforman ''q'' en el AFD original.
 
==== Transiciones entre clases indistinguibles ====
 
Dada la definicion de funcion de transicion anterior, vale la equivalencia tambien para la funcion de transicion extendida. Esto es, si en el AFD original se llegaba al estado ''r'' desde ''q'' por la cadena ''alfa'', entonces en el minimo se llega a la clase de equivalencia de ''r'' desde ''q'' via ''alfa''.
 
<math>\hat \delta (q,a) = r \Longrightarrow \hat \delta \prime ([q],a) = [r]</math>
 
Se demuestra por induccion en la longitud de la cadena. El caso base (longitud cero) es trivial. Para el paso inductivo, se parte la cadena en ''a + alfa'', y se aplica la definicion de la funcion no extendida (sobre ''a'') junto con la hipotesis inductiva (sobre ''alfa''), mas propiedades de la funcion de transicion extendida.
 
==== Cantidad de estados ====
 
Dados dos AFDs M y M', si para todo par de cadenas que conducen a estados diferentes en M desde q0 tambien conducen a estados diferentes en M' desde q0', entonces M' debe tener tantos o más estados que M.
 
Para demostrarlo, se puede obtener una funcion inyectiva de Q en Q', esto es, alguna funcion que para todo estado de Q vaya a un estado de Q' y no repita imagenes. Esto garantiza que <math>|Q| \leq |Q'|</math>.
 
Dicha funcion ''f(q)'' se puede definir como el estado que se alcanza en M' a desde ''q0' ''consumiendo la cadena ''g(q)''. La funcion ''g'' puede definirse como la menor cadena en M tal que al consumirla desde ''q0'' se llegue al estado ''q''; o sea, qué camino hay que seguir en M para llegar a ''q''.
 
Como todas las cadenas generadas por ''g'' llevan a estados diferentes, entonces al consumirlas en M' tambien se llegan a estados diferentes (por hipotesis). Por lo tanto, se tiene la funcion inyectiva buscada.
 
==== Minimo ====
 
Se desea probar que el automata minimo construido a partir de las clases de equivalencia de la funcion de indistinguibilidad es efectivamente minimo. Esto es, que no existe ningun automata M' que reconozca el mismo lenguaje que MR (siendo MR el automata reducido) y que tenga menos estados.
 
Por la demostracion anterior, esto implica que deberia existir un par de cadenas ''alfa'' y ''beta'' tales que lleven a estados distintos ''p'' y ''r'' en MR y a estados iguales en M'.
 
Al ser ''p'' y ''r'' estados distintos en MR, significa que son distinguibles, esto es, que hay una cadena que lleva a uno a un estado final y a otro a uno no final. Esto significa que al concatenar esta cadena a las dos ''alfa'' y ''beta'' que habian dado origen a ''p'' y ''r'', se obtienen dos cadenas, las cuales una pertenece al lenguaje y la otra no.
 
Ahora bien, como ''p'' y ''r'' coinciden en M', cualquier cadena los lleva al mismo estado, sea final o no. Entonces, al realizar la misma concatenacion que antes, se llega a ambas cadenas pertenecen o no. Por lo tanto, M' no reconoce el mismo lenguaje que MR, absurdo que proviene de suponer que MR no era minimo en cantidad de estados.


= Lenguajes libres de contexto =
= Lenguajes libres de contexto =
Línea 54: Línea 335:
== Lema de Pumping (LIC) ==
== Lema de Pumping (LIC) ==


=== Altura del árbol ===
=== Altura del arbol ===


La altura del árbol de derivación es la longitud del camino más largo en el árbol de derivación tal que comienza en la raíz y el final es una hoja (definicion natural de arbol). Vale que la hoja siempre es un terminal o <math>\lambda</math>. Notar que en el árbol de derivación, la base (hojas leídas en preorder) es igual a la cadena derivada.
La altura del arbol de derivacion es la longitud del camino más largo en el arbol de derivacion tal que comienza en la raiz y el final es una hoja (definicion natural de arbol). Vale que la hoja siempre es un terminal. Notar que en el arbol de derivacion, la base (hojas leidas en preorder) es igual a la cadena derivada.


Sea una gramatica donde <math>a</math> es la longitud del lado derecho más largo entre todas las producciones. Dado un árbol T para una cadena <math>\alpha</math>, vale que <math>| \alpha | \leq a^h</math>, donde <math>h</math> es la altura del arbol.  
Sea una gramatica donde ''a'' es la longitud del lado derecho más largo entre todas las producciones. Dado un arbol T para una cadena alfa, vale que <math>| \alpha | \leq a^h</math>, donde ''h'' es la altura del arbol.  


La demostración se hace por inducción sobre la altura. El caso base con h = 0 es trivial (<math>\alpha = S \implies | \alpha | = 1 \leq a^0 = 1</math>). El paso inductivo para <math>h + 1</math> se basa en que la base correspondiente a la altura <math>h</math>, llamémosla <math>\gamma</math>, cumple la HI; y como <math>\alpha</math> se deriva a partir de <math>\gamma</math> expandiendo a lo sumo <math>| \gamma |</math> simbolos no terminales, entonces <math>| \alpha | \leq a * | \gamma | \leq a * a^h = a^{h + 1}</math>.
La demostracion se hace por induccion sobre la altura. El caso base con h = 0 es trivial. El paso inductivo se basa que la base correspondiente a la altura ''h'', llamemosla <math>\gamma</math>, cumple la HI; y como <math>\alpha</math> se deriva a partir de <math>\gamma</math> expandiendo a lo sumo <math>| \gamma |</math> simbolos no terminales, entonces <math>| \alpha | \leq a * | \gamma |</math>.


=== Pumping (LIC) ===
=== Pumping (LIC) ===
Línea 66: Línea 347:
El lema de pumping para LIC es similar al de gramaticas regulares. La idea es que para toda cadena que supere una longitud critica ''n'' del lenguaje (puede tomarse <math>a^{|V_N|+1}</math>), la cadena pueda descomponerse en 5 partes ''r,x,y,z,s'' tal que puedan insertarse tantas repeticiones de ''x'' y ''z'' como se desee y que la cadena se mantenga en el lenguaje. Se pide ademas que la longitud de ''x+z'' sea no nula (para que haya algo a insertar) y que ''x+y+z'' no supere a '''n'''.
El lema de pumping para LIC es similar al de gramaticas regulares. La idea es que para toda cadena que supere una longitud critica ''n'' del lenguaje (puede tomarse <math>a^{|V_N|+1}</math>), la cadena pueda descomponerse en 5 partes ''r,x,y,z,s'' tal que puedan insertarse tantas repeticiones de ''x'' y ''z'' como se desee y que la cadena se mantenga en el lenguaje. Se pide ademas que la longitud de ''x+z'' sea no nula (para que haya algo a insertar) y que ''x+y+z'' no supere a '''n'''.


Decimos que un árbol de derivación mínimo T para la cadena <math>\alpha</math> es uno de altura mínima tal que no existe otro de la misma altura que tenga menos derivaciones. La demostración parte de un árbol T mínimo para una cadena <math>\alpha</math> con <math>|\alpha| \geq n</math>. Usando el lema anterior, puede probarse que <math>a^h \geq | \alpha| \geq n = a^{|V_N|+1}</math>, lo que lleva a que <math>h \geq |V_N|+1</math>.
La demostracion parte de una cadena <math>\alpha</math> y un arbol de derivacion minimo T (es decir, de altura minima). Usando el lema anterior, puede probarse que <math>a^h \geq | \alpha| \geq n = a^{|V_N|+1}</math>, lo que lleva a que <math>h \geq |V_N|+1</math>.


En otras palabras, si la cadena es lo suficientemente grande, entonces la altura del arbol que la genera sera mayor estricto a la cantidad de simbolos no terminales que tiene la gramatica. Por lo tanto, recorriendo la rama mas larga del arbol, debe haber por lo menos un no terminal repetido (supongamos ''A'').
En otras palabras, si la cadena es lo suficientemente grande, entonces la altura del arbol que la genera sera mayor estricto a la cantidad de simbolos no terminales que tiene la gramatica. Por lo tanto, recorriendo la rama mas larga del arbol, debe haber por lo menos un no terminal repetido (supongamos ''A'').
Línea 75: Línea 356:


Esto significa que ''A'' deriva (en uno o mas pasos) tanto en ''y'' como en ''xyz'', y que ''S'' deriva en ''rAs''. Haciendo induccion en la cantidad de apariciones de ''x'' y ''z'' (caso base es cero) es sencillo ver que ''A'' termina derivando en ''xAz'' o ''y'', con lo que <math>r x^i y z^i s</math> es forma sentencial del lenguaje.
Esto significa que ''A'' deriva (en uno o mas pasos) tanto en ''y'' como en ''xyz'', y que ''S'' deriva en ''rAs''. Haciendo induccion en la cantidad de apariciones de ''x'' y ''z'' (caso base es cero) es sencillo ver que ''A'' termina derivando en ''xAz'' o ''y'', con lo que <math>r x^i y z^i s</math> es forma sentencial del lenguaje.
Nos falta ver que <math>|xz| > 0</math>. Llamemos <math>A_2</math> a la aparición más baja de A, y <math>A_1</math> a la que le precede. Supongamos que <math>|xz| = 0</math>. Esto quiere decir que podríamos reemplazar el subárbol con raíz en <math>A_1</math> por el árbol con raíz en <math>A_2</math> y tener un árbol T' que genera la misma cadena <math>\alpha</math>. Como <math>A_2</math> ocurre después que <math>A_1</math>, T' tendría menos derivaciones que T. Pero dijimos que T es un árbol mínimo. Absurdo, que vino de suponer que <math>|xz| = 0</math>.
'''NOTA''': Un detalle importante que se toma en el final (y que no queda tan claro en los apuntes) es la justificación de que <math>|xyz| \leq a^{|V_N|+1} </math> (en el dibujo es vwx).
La respuesta es sencilla, recorremos el árbol de abajo hacia arriba buscando la segunda aparición de A, la cantidad  MÁXIMA de no terminales por los que tenemos que pasar hasta encontrar el primer repetido es <math>|V_N|+1 </math>. Esa es la justificación por la que podemos afirmar que ese subárbol tiene esa altura y de ahí acotar la longitud de <math>xyz</math>.


== Decidibilidad ==
== Decidibilidad ==
Línea 207: Línea 483:


Resumiendo, la idea es mantener tres ''niveles'' en el autómata, uno de los cuales contiene los estados finales (3), el otro los estados alcanzados a través de una transición lambda que pasaron por un final (2) y el último los no alcanzados por lambda desde un final (1).
Resumiendo, la idea es mantener tres ''niveles'' en el autómata, uno de los cuales contiene los estados finales (3), el otro los estados alcanzados a través de una transición lambda que pasaron por un final (2) y el último los no alcanzados por lambda desde un final (1).
= Máquinas de Turing =
Las máquinas de Turing se definen como un autómata con una cinta infinita a derecha (es decir, las celdas van de cero a infinito positivo) con la siguiente aridad:
<math>MT = <Q, \Gamma ,B , \Sigma , \delta ,q_0, F></math>
* <math>Q</math> conjunto de estados
* <math>\Gamma</math> alfabeto de la cinta
* <math>B \in \Gamma</math> símbolo blanco, representa una celda vacía
* <math>\Sigma \subset \Gamma</math> alfabeto de entrada, no incluye al blanco
* <math>\delta : Q \times \Gamma \rightarrow partes(Q \times \Gamma \times \{ L,R\} )</math> acciones
* <math>q_0 \in Q</math> estado inicial
* <math>F \subseteq Q</math> estados finales
Las acciones de la máquina dependen del estado actual y del símbolo que hay bajo la cabeza lectora/escritora, e implican escribir otro símbolo (puede ser el mismo) y moverse a izquierda o derecha.
La configuración instantánea de una máquina de Turing se define como <math>\alpha _1 q \alpha _2</math>, donde <math>\alpha _1</math> es el contenido de la cinta (sucesión de caracteres) a la izquierda del cabezal, ''q'' es el estado actual de la máquina, y <math>\alpha _2</math> es el contenido de la cinta desde el cabezal hasta el último símbolo distinto de blanco. Así, se puede especificar cuál es el estado actual, el contenido de la cinta y la posición del cabezal.
La cinta inicialmente comienza llena de blancos, excepto al comienzo donde tiene escrito el input a reconocer. Notar que el caracter blanco no puede pertenecer al alfabeto de entrada.
La máquina acepta una cadena si en su ejecución llega a un estado final, notar que la máquina no tiene transiciones desde un estado final. Como la cadena está escrita en la cinta, no existe el concepto de consumir la cadena de entrada.
== Máquina de Turing determinística ==
Una máquina de Turing es determinística cuando dado un estado y un símbolo bajo el cabezal existe una única acción. Vale que una máquina determinística puede emular a una no determinística.
Para esto se construye una MTD M' que reconoce la cadena cuando esta pertenece al lenguaje y se cuelga cuando no pertenece. La MTD construida tiene tres cintas (se puede demostrar que una máquina con un número finito de cintas equivale a una de una sola cinta). La idea es guardar en la primer cinta la cadena de entrada, en la segunda un número que simboliza una traza a seguir de la máquina M original, y la tercera usarla para emular las operaciones de M.
Para simbolizar una traza, se calcula el máximo grado de salida (r) de los nodos de la máquina M, se numera cada transición a partir de cada estado con un número de 1 a r, y se escribe una secuencia de dígitos entre 1 y r. Esto permite recorrer todas las posibles secuencias de configuraciones instantáneas en BFS.
La MTD M', entonces, en cada iteración copia la entrada de la primer cinta a la tercera, incrementa en 1 el valor de la segunda cinta (número expresado en base ''r'' que simboliza la traza) y con esa traza emula a M sobre la tercer cinta. Si termina en estado de aceptación, se acepta la cadena. Si se traba o termina en un estado no final, se itera nuevamente.
== Lenguajes Recursivamente Enumerables ==
Los LRE (lenguajes tipo 0 en la jerarquía de Chomsky) son lenguajes reconocibles por una máquina de Turing. Son aquellos que pueden especificarse sin restricciones sobre sus producciones.
=== Gramática a MTND ===
Para pasar de una gramática tipo 0 a una MTND, se utilizan dos cintas. En la primera se guarda la cadena; en la segunda se van generando formas sentenciales de manera no determinística a partir del símbolo distinguido S. Cuando se encuentra alguna que matchea la entrada, se acepta; si no, la máquina se cuelga.
=== MT a Gramática ===
Para pasar de una MT a una gramática se establece una equivalencia entre los símbolos de la gramática y las configuraciones instantáneas de la máquina de Turing. Los símbolos generados son de la forma [a,b], donde ''a'' representará el caracter original de la cadena de entrada y ''b'' el caracter sobre el que opera la máquina.
Se proveen producciones para generar, incialmente, una cadena arbitraria de símbolos [a,a], siendo ''a'' cualquier terminal. Esto equivale a tener inicialmente en la cinta cualquier cadena. Seguidos a estos se genera una cantidad libre de simbolos [lambda,Blanco], tantos como necesitaría la cinta para operar.
La gramática genera, al principio de todo, un caracter ''q'' que representará el cabezal de la máquina. Las producciones de la gramática permiten "mover" ''q'' entre los símbolos [a,b] (modificando solamente los ''b'') en base a las acciones permitidas por la MT original.
Una vez alcanzado un estado final, se generan producciones que eliminan todos los símbolos [a,b] dejando solamente los ''a'' correspondientes a la cadena original, y finalmente a ''q''. Así, la cadena final de terminales es la cadena a generar.
== Lenguajes Sensitivos al Contexto ==
Los lenguajes dependientes del contexto se expresan con gramáticas tipo 1 en la jerarquía de Chomsky, que tienen la restricción de que la longitud del lado derecho de una producción no puede ser menor a la del lado izquierdo.
=== Autómata Linealmente Acotado ===
Los ALA pueden verse como máquinas de Turing con la cinta acotada. En un ALA el alfabeto de entrada incluye dos símbolos, usados como tope de entrada y tope de salida. El autómata no puede moverse más allá de los topes ni sobreescribirlos.
Notar que un ALA tal que en la cinta tenga una cantidad de blancos lineal a la longitud de la entrada es equivalente a un ALA con cero blancos, que opera exclusivamente sobre la cadena de entrada.
A diferencia de lo que sucedía con las MT, no hay equivalencia entre ALA y ALAD. A primera vista puede observarse que el método anterior no funciona pues el número que simboliza la traza a emular (en la segunda cinta) puede crecer arbitrariamente.
=== Gramática a ALA ===
La equivalencia entre una gramática sensitiva al contexto y un ALA se demuestra exactamente igual que para máquinas de Turing en general, excepto que en este caso puede agregarse la restricción de que si la cadena que se está generando excede el tamaño de la que se ha de reconocer se corta esa rama (pues ninguna cadena de terminales y no terminales puede derivar en una de longitud menor). Así la cantidad de posibilidades a explorar es finita.
== Lenguajes Recursivos ==
Los lenguajes recursivos se encuentran estrictamente entre los sensitivos al contexto y los recursivamente enumerables. Son aquellos reconocibles por una HTM (halting Turing machine). Es decir, existe una máquina de Turing que dada cualquier entrada, siempre para y devuelve si una cadena pertenece o no (no puede colgarse).
=== Inclusión de Sensitivos al Contexto ===
Para demostrar que los LSC están incluidos dentro de los recursivos, se construye una HTM que determine si una cadena pertenece al lenguaje. Dada una gramática GSC y una cadena de entrada w de longitud n, se construye un grafo finito donde cada nodo es un string de terminales y no terminales de longitud menor o igual a n.
Los arcos en este grafo representan si es posible ir de un string a otro mediante derivaciones de la gramática. Notar que este grafo es finito y puede construirse mediante un algoritmo.
Luego, para determinar si una cadena ''w'' pertenece al lenguaje, simplemente se verifica mediante un algoritmo si existe un camino desde ''S'' hasta el nodo que contiene a ''w''. Como lo anterior es un algoritmo (siempre termina) existe una HTM que lo ejecuta, con lo cual el lenguaje LSC es recursivo.
=== Lenguaje Recursivo no LSC ===
Para demostrar que existe un lenguaje recursivo no sensitivo al contexto se utiliza un argumento diagonal. Primero se prueba un lema que indica que dada cualquier enumeración de HTMs, existe un lenguaje recursivo que no es aceptado por ninguna de ellas (el lenguaje que dada la cadena ''i'', la acepta sii no es reconocida por la iesima HTM de la enumeración).
Eventualmente se llega a una contradicción, pues si existe una HTM de índice ''i'' en la enumeración, la cadena ''i'' debe ser reconocida por dicha HTM sii no lo es. Notar que este lenguaje es recursivo, pues existe un algoritmo (procedimiento que siempre termina) que puede determinar si una cadena ''i'' pertenece al conjunto: simplemente corre la HTM ''i'' con esa cadena y devuelve la negación.
A partir de esto, se construye una enumeración de las HTM que reconocen todos los LSC, lo cual es posible ya que se pueden enumerar las GSCs. Pero por el lema anterior existe un lenguaje que no es reconocido por ninguna de estas HTMs, es decir, por ningún LSC. Y este lenguaje es recursivo.
La demostración parece basarse en que el conjunto de HTMs no es Recursivamente Enumerable, mientras que el de GSCs sí lo es. Por lo tanto debe existir alguna HTM que genere un lenguaje no sensitivo al contexto.
== Lenguaje Diagonal ==
El lenguaje diagonal es un ejemplo de un lenguaje que no es recursivamente enumerable. Requiere enumerar las MT y entradas posibles y llegar a una contradicción similar a la del problema de la parada.
Más formalmente, se basa en construir una tabla infinita de dos entradas. La celda (i,j) entonces vale 1 sii la máquina de Turing de nro ''j'' reconoce la cadena ''i''. La MT se encuentra codificada en binario, y la cadena de entrada es de 0s y 1s.
Entonces, puede construirse el lenguaje de las cadenas ''i'' tal que no pertenecen a la MT de igual número (lenguaje diagonal). Si este lenguaje es recursivamente enumerable, entonces existe una MT ''Mk'' tal que reconce sus cadenas. En otras palabras,
<math>w_k \in L_d \Longleftrightarrow w_k \not \in L(M_k) = L_d</math>
Con lo que se llega a una contradicción. La cadena de igual número que ''M'' es reconocida por la máquina sii no es reconocida.
Otra opción (distinta a la del pdf, revisar) es un lenguaje que acepta una cadena sii esta representa una máquina de Turing con una entrada dada, y dicha máquina para. Si dicha máquina existiera, resolvería el halting problem, lo que no es posible.
== Lenguaje Universal ==
El lenguaje universal es el que se corresponde a la MT que ejecuta cualquier otra MT con cualquier entrada. En otras palabras, toma pares de cadena y MT, y determina si la cadena es reconocida por esa MT.
'''Recursivamente Enumerable'''
Este lenguaje es recursivamente enumerable. Puede construirse una MT con 3 cintas, de las cuales la primera contiene el input (la MT ''M'' más la cadena de entrada ''w''), la segunda (inicializada con la cadena ''w'') emula la cinta de ''M'', y la tercera permite llevar cuenta del estado en el que se encuentra la ''M'' emulada.
'''No Recursivo'''
Para demostrar que este lenguaje no es recursivo, se supone inicialmente que lo es y se intenta llegar al absurdo. Para esto, se construye un algoritmo (es decir, un procedimiento que siempre para, emulable por una HTM) que dada una cadena de entrada, genera su MT con igual número. Luego se determina, usando la HTM del lenguaje universal (supusimos que era recursivo) si <math>(w_i, MT_i)</math> es aceptado, esto es, si la máquina ''i'' acepta la cadena ''i''.
Notar que este es el complemento del lenguaje diagonal. Como es un algoritmo, siempre termina y devuelve verdadero o falso. Con lo que puede generarse fácilmente una HTM que reconozca el lenguaje diagonal directamente. Lo que es absurdo puesto que no es siquiera recursivamente enumerable.
Intuitivamente, el que el lenguaje universal sea recursivo significaría que es posible tener un método que siempre termina que resuelve (por sí o por no) la pertenencia de cualquier cadena a cualquier MT. Es decir, es capaz de decidir el halting problem.


= Analizadores Sintácticos Descendentes =
= Analizadores Sintácticos Descendentes =
Línea 345: Línea 504:
Un símbolo es alcanzable sii aparece en alguna derivación a partir del símbolo distinguido, es decir, <math>S \Rightarrow ^+ \alpha A \beta</math>.
Un símbolo es alcanzable sii aparece en alguna derivación a partir del símbolo distinguido, es decir, <math>S \Rightarrow ^+ \alpha A \beta</math>.


=== Orden de aplicación ===
=== Orden de aplicacón ===


Todos los casos anteriores son salvables mediante un algoritmo, es decir, hay algoritmos para generar una gramática G' a partir de G tal que G' no tenga símbolos anulables, ni renombramientos, ni símbolos inactivos, ni símbolos inalcanzables. El orden de aplicación de los algoritmos es el aquí expuesto.
Todos los casos anteriores son salvables mediante un algoritmo, es decir, hay algoritmos para generar una gramática G' a partir de G tal que G' no tenga símbolos anulables, ni renombramientos, ni símbolos inactivos, ni símbolos inalcanzables. El orden de aplicación de los algoritmos es el aquí expuesto.
Línea 440: Línea 599:
<br/><math>A' \rightarrow \beta _1 | \beta _2</math>
<br/><math>A' \rightarrow \beta _1 | \beta _2</math>


Notar que a pesar de los algoritmos para eliminar factorización y recursividad a izquierda, puede haber lenguajes para los que no haya una gramática LL(1) que los reconozca (por ejemplo, cualquier lenguaje libre de contexto no determinístico, como ser <math>ww^r</math>).
Notar que a pesar de los algoritmos para eliminar factorización y recursividad a izquierda, puede haber lenguajes para los que no haya una gramática LL(1) que los reconozca (por ejemplo, cualquier lenguaje libre de contexto no determinístico, como ser wwr).


=== ASDP Recursivo ===
=== ASDP Recursivo ===
Línea 610: Línea 769:
=== Definiciones ===
=== Definiciones ===


'''Prefijo viable''': Sea <math>\alpha \rho \beta</math> una fsd (forma sentencial derecha) donde <math>\rho</math> es pivote, <math>\gamma</math> es prefijo viable si es prefijo de <math>\alpha \rho</math>. Son los prefijos de una fsd que pueden aparecer en el stack de un parser shift-reduce. Intuitivamente, son los prefijos de cualquier cadena que termine en el pivote. Vale que el conjunto de los prefijos viables de un lenguaje libre de contexto genera un lenguaje regular.
'''Prefijo viable''': Sea <math>\alpha \rho \beta</math> una f.s.d. donde <math>\rho</math> es pivote, <math>\gamma</math> es prefijo viable si es prefijo de <math>\alpha \rho</math>. Son los prefijos de una f.s.d. que pueden aparecer en el stack de un parser shift-reduce. Intuitivamente, son los prefijos de cualquier cadena que termine en el pivote. Vale que el conjunto de los prefijos viables de un lenguaje libre de contexto genera un lenguaje regular.


'''Item''': Un item LR(0) de una gramática G es una producción de G con un punto en alguna posición del lado derecho (definición del dragón). Notar que el conjunto de items de una gramática es finito.
'''Item''': Un item LR(0) de una gramática G es una producción de G con un punto en alguna posición del lado derecho (definición del dragón). Notar que el conjunto de items de una gramática es finito.
Línea 633: Línea 792:
** El caso base es long=1, con lo cual la única transición posible <math>\lambda</math>  (por '''1''') y <math>\gamma</math> tiene que ser la cadena vacía.  Como <math>\delta(q_0,\gamma) = \delta(q_0,\lambda)</math> y  <math>S \rightarrow . \alpha \in \delta(q_0,\lambda)</math> y es además un item válido para el prefijo viable <math>\gamma = \lambda</math>, el caso base se cumple.
** El caso base es long=1, con lo cual la única transición posible <math>\lambda</math>  (por '''1''') y <math>\gamma</math> tiene que ser la cadena vacía.  Como <math>\delta(q_0,\gamma) = \delta(q_0,\lambda)</math> y  <math>S \rightarrow . \alpha \in \delta(q_0,\lambda)</math> y es además un item válido para el prefijo viable <math>\gamma = \lambda</math>, el caso base se cumple.
** Para el paso inductivo asumimos verdadera la HI para long de camino menores a <math>k</math>. Las reglas para las transiciones 2) y 3) implican dos formas posibles para la última transición en el camino. Nuestra hipótesis es <math>[A \rightarrow \alpha.\beta] \in \delta(q_0,\gamma)</math> en <math>k</math> transiciones:
** Para el paso inductivo asumimos verdadera la HI para long de camino menores a <math>k</math>. Las reglas para las transiciones 2) y 3) implican dos formas posibles para la última transición en el camino. Nuestra hipótesis es <math>[A \rightarrow \alpha.\beta] \in \delta(q_0,\gamma)</math> en <math>k</math> transiciones:
**# Está etiquetada con <math>X \in V</math>:  Por hipótesis y como además sabemos que en la última transición consumimos <math>X</math>, si tomamos <math>\alpha = \alpha' X</math> y <math>\gamma = \gamma' X</math>, el estado anterior tienen que ser  <math>[A \rightarrow \alpha'.X \beta]</math>, al que se llegó de <math>q_0</math> por <math>\gamma'</math> en <math>k-1</math> pasos, es decir, <math>[A \rightarrow \alpha' . X \beta] \in \delta(q_0,\gamma')</math>. Pero al ser <math>k-1</math> transiciones, vale la hipótesis inductiva, o sea, vale que <math>[A \rightarrow \alpha' . X \beta]</math> es un item válido para el prefijo viable <math>\gamma'</math>. Qué significa esto? Que <math>\alpha' X \beta</math> es un pivote, también que <math>\gamma' = \delta \alpha'</math> y que <math>S \rightarrow_{D}^* \ \delta A w \ \rightarrow_{D} \ \delta \alpha' X \beta w</math> (todo por la definición de prefijo viable e item válido para el mismo). Pero entonces notemos que <math>\delta \alpha' X = \gamma</math> también cumple la definición de prefijo viable (por quién es el pivote) y que <math>[A \rightarrow \alpha' X. \beta]</math> es un item válido para <math>\gamma</math>. Como  <math>[A \rightarrow \alpha' X. \beta] =  [A \rightarrow \alpha . \beta]</math>, llegamos a lo que queríamos: <math>[A \rightarrow \alpha.\beta] \in \delta(q_0,\gamma)</math>  implica <math>[A \rightarrow \alpha . \beta]</math> es un item válido para <math>\gamma</math> prefijo viable.
**# Está etiquetada con <math>X \in V</math>:  Por hipótesis y como además sabemos que en la última transición consumimos <math>X</math>, si tomamos <math>\alpha = \alpha' X</math> y <math>\gamma = \gamma' X</math>, el estado anterior tienen que ser  <math>[A \rightarrow \alpha'.X \beta]</math>, al que se llegó de <math>q_0</math> por <math>\gamma'</math> en <math>k-1</math> pasos, es decir, <math>[A \rightarrow \alpha' . X \beta] \in \delta(q_0,\gamma')</math>. Pero al ser <math>k-1</math> transiciones, vale la hipótesis inductiva, o sea, vale que <math>[A \rightarrow \alpha' . X \beta]</math> es un item válido para el prefijo viable <math>\gamma'</math>. Qué significa que esto? Que <math>\alpha' X \beta</math> es un pivote, también que <math>\gamma' = \delta \alpha'</math> y que <math>S \rightarrow_{D}^* \ \delta A w \ \rightarrow_{D} \ \delta \alpha' X \beta w</math> (todo por la definición de prefijo viable e item válido para el mismo). Pero entonces notemos que <math>\delta \alpha' X = \gamma</math> también cumple la definición de prefijo viable (por quién es el pivote) y que <math>[A \rightarrow \alpha' X. \beta]</math> es un item válido para <math>\gamma</math>. Como  <math>[A \rightarrow \alpha' X. \beta] =  [A \rightarrow \alpha . \beta]</math>, llegamos a lo que queríamos: <math>[A \rightarrow \alpha.\beta] \in \delta(q_0,\gamma)</math>  implica <math>[A \rightarrow \alpha . \beta]</math> es un item válido para <math>\gamma</math> prefijo válido.
**# Está etiquetada con <math>\lambda</math>: Como la última transición fue <math>\lambda</math> tiene que haber sido usando la definición '''2''' de <math>\delta</math>. Primero, esto implica que para que el item tenga la forma  <math>[B \rightarrow . \gamma]</math>  debe pasar que <math>\alpha = \lambda</math>. Segundo, el estado previo tiene que haber sido de la forma <math>[B \rightarrow \alpha_1 . A \beta_1]</math>, y a él se tiene que haber llegado del estado inicial por el mismo <math>\gamma</math> (ya que no se consumió entrada), o sea, tiene que pertenecer a <math>\delta(q_0,\gamma)</math>. Nuevamente vale la hipótesis inductiva, entonces podemos deducir que <math>[B \rightarrow \alpha_1 . A \beta_1]</math> es item válido del prefijo viable <math>\gamma</math>. O sea, <math>S \rightarrow_{D}^* \ \delta B w \ \rightarrow_{D} \ \delta \alpha_1 A \beta_1 w \ \rightarrow_{D} \ \delta \alpha_1 \beta \beta_1 w </math> (el último paso por hipótesis y porque concluimos que <math>\alpha = \lambda</math>). Pero entonces <math>\gamma = \delta\alpha_1</math> es también prefijo viable para el pivote <math>\beta</math>, para el cual <math>[A \rightarrow \ .\beta]</math> es un item válido, llegando así a lo que queríamos probar.
**# Está etiquetada con <math>\lambda</math>: Como la última transición fue <math>\lambda</math> tiene que haber sido usando la definición '''2''' de <math>\delta</math>. Primero, esto implica que para que el item tenga la forma  <math>[B \rightarrow . \gamma]</math>  debe pasar que <math>\alpha = \lambda</math>. Segundo, el estado previo tiene que haber sido de la forma <math>[B \rightarrow \alpha_1 . A \beta_1]</math>, y a él se tiene que haber llegado del estado inicial por el mismo <math>\gamma</math> (ya que no se consumió entrada), o sea, tiene que pertenecer a <math>\delta(q_0,\gamma)</math>. Nuevamente vale la hipótesis inductiva, entonces podemos deducir que <math>[B \rightarrow \alpha_1 . A \beta_1]</math> es item válido del prefijo viable <math>\gamma</math>. O sea, <math>S \rightarrow_{D}^* \ \delta B w \ \rightarrow_{D} \ \delta \alpha_1 A \beta_1 w \ \rightarrow_{D} \ \delta \alpha_1 \beta \beta_1 w </math> (el último paso por hipótesis y porque concluimos que <math>\alpha = \lambda</math>). Pero entonces <math>\gamma = \delta\alpha_1</math> es también prefijo viable para el pivote <math>\beta</math>, para el cual <math>[A \rightarrow \ .\beta]</math> es un item válido, llegando así a lo que queríamos probar.
* '''Vuelta (<=)'''
* '''Vuelta (<=)'''
** Probamos primero el '''Lema''': Si <math>[A \rightarrow .\alpha]</math> es item válido para <math>\gamma</math> prefijo viable, entonces <math>[A \rightarrow .\alpha] \in \delta(q_0, \gamma)</math>. Demostración por inducción sobre <math>i</math> en <math>S \rightarrow_{D}^i \ \gamma A w \ \rightarrow_{D} \ \gamma \alpha w</math> (esto es aplicar las definiciones de p.v. e i.v. ).  
** Probamos primero el '''Lema''': Si <math>[A \rightarrow .\alpha]</math> es item válido para <math>\gamma</math> prefijo viable, entonces <math>[A \rightarrow .\alpha] \in \delta(q_0, \gamma)</math>. Demostración por inducción sobre <math>i</math> en <math>S \rightarrow_{D}^i \ \gamma A w \ \rightarrow_{D} \ \gamma \alpha w</math> (esto es aplicar las definiciones de p.v. e i.v. ).  
*** Caso base i = 0: Debe pasar que <math>S \rightarrow \gamma \alpha w = \alpha \ \ (\gamma, w = \lambda)</math>. En este caso el item es en realidad <math>S \rightarrow . \alpha</math> y <math>\gamma = \lambda</math>. Por construcción de <math>\delta</math> sabemos que <math>[S \rightarrow . \alpha] \in \delta(q_0, \lambda)</math>.
*** Caso base i = 0: Debe pasar que <math>S \rightarrow \gamma \alpha w = \alpha \ \ (\gamma, w = \lambda)</math>. En este caso el item es en realidad <math>S \rightarrow . \alpha</math> y <math>\gamma = \lambda</math>. Por construcción de <math>\delta</math> sabemos que <math>[S \rightarrow . \alpha] \in \delta(q_0, \lambda)</math>.
*** Paso inductivo: (supongamos HI cierta para <math>i</math>). Por hipotesis del lemma y def. de p.v. e i.v.,  <math>S \rightarrow_{D}^{i+1} \ \gamma A w \ \rightarrow_{D} \ \gamma \alpha w</math> . Como el <math>A</math> tiene que haber surgido en alguna derivación anterior o igual a <math>i+1</math>,  <math>S \rightarrow_{D}^k \ \gamma' B w'\rightarrow_{D} \ \gamma' \gamma'' A w'' w' \ \rightarrow_{D}^{i-k} \ \gamma A w</math> . Notar que <math>\gamma' \gamma'' = \gamma</math> ya que ningún no terminal a la derecha de <math>A</math> puede expandirse antes que esta (por ser derivación más a la derecha). Ahora, como <math>\gamma' \gamma'' A w'' w'</math> es una f.s.d,  <math>[B \rightarrow .\gamma'' A w'']</math> es un ítem válido para el prefijo viable <math>\gamma'</math>. Por H.I., entonces <math>[B \rightarrow .\gamma'' A w''] \in \delta(q_0, \gamma')</math>. Pero aplicando la definición (3) de <math>\delta</math> por cada símbolo de <math>\gamma'</math> se ve que podemos llegar del estado <math>[B \rightarrow .\gamma'' A w'']</math>  a <math>[B \rightarrow \gamma'' . A w'']</math> consumiendo <math>\gamma''</math>. Entonces, <math>[B \rightarrow \gamma'' . A w''] \in \delta(q_0, \gamma' \gamma'') = \delta(q_0, \gamma)</math> . Para terminar, por la def. (2),  <math>[A \rightarrow .\alpha]  \in \delta(\delta(q_0, \gamma), \lambda) = \delta(q_0, \gamma)</math>, como queríamos probar.
*** Paso inductivo: (supongamos HI cierta para <math>i</math>). Por hipotesis del lemma y def. de p.v. e i.v.,  <math>S \rightarrow_{D}^{i+1} \ \gamma A w \ \rightarrow_{D} \ \gamma \alpha w</math> . Como el <math>A</math> tiene que haber surgido en alguna derivación anterior o igual a <math>i+1</math>,  <math>S \rightarrow_{D}^k \ \gamma' A' w'\rightarrow_{D} \ \gamma' \gamma'' A w'' w' \ \rightarrow_{D}^{i-k} \ \gamma A w</math> . Notar que <math>\gamma' \gamma'' = \gamma</math> ya que ningún no terminal a la derecha de <math>A</math> puede expandirse antes que esta (por ser derivación más a la derecha). Ahora, como <math>\gamma' \gamma'' A w'' w'</math> es una f.s.d,  <math>[B \rightarrow .\gamma'' A w'']</math> es un ítem válido para el prefijo viable <math>\gamma'</math>. Por H.I., entonces <math>[B \rightarrow .\gamma'' A w''] \in \delta(q_0, \gamma')</math>. Pero aplicando la definición (3) de <math>\delta</math> por cada símbolo de <math>\gamma'</math> se ve que podemos llegar del estado <math>[B \rightarrow .\gamma'' A w'']</math>  a <math>[B \rightarrow \gamma'' . A w'']</math> consumiendo <math>\gamma''</math>. Entonces, <math>[B \rightarrow \gamma'' . A w''] \in \delta(q_0, \gamma' \gamma'') = \delta(q_0, \gamma)</math> . Para terminar, por la def. (2),  <math>[A \rightarrow .\alpha]  \in \delta(\delta(q_0, \gamma), \lambda) = \delta(q_0, \gamma)</math>, como queríamos probar.
** Ahora, con el lema probado si <math>[A \rightarrow \alpha . \beta]</math> es item válido para <math>\gamma</math>,  entonces debe pasar que <math>[A \rightarrow . \alpha \beta]</math> es item válido para <math>\delta'</math> prefijo viable (con <math>\gamma = \delta' \alpha</math>)- Por el lema anterior , <math>[A \rightarrow . \alpha \beta] \in \delta(q_0, \delta') \Rightarrow</math>  (usando la definición 3 de <math>\delta</math>)  <math> [A \rightarrow \alpha . \beta] \in \delta(q_0, \delta' \alpha) = \delta(q_0, \gamma)</math>
** Ahora, con el lema probado si <math>[A \rightarrow \alpha . \beta]</math> es item válido para <math>\gamma</math>,  entonces debe pasar que <math>[A \rightarrow . \alpha \beta]</math> es item válido para <math>\delta'</math> prefijo viable (con <math>\gamma = \delta' \alpha</math>)- Por el lema anterior , <math>[A \rightarrow . \alpha \beta] \in \delta(q_0, \delta') \Rightarrow</math>  (usando la definición 3 de <math>\delta</math>)  <math> [A \rightarrow \alpha . \beta] \in \delta(q_0, \delta' \alpha) = \delta(q_0, \gamma)</math>


=== Construccion de conjuntos de items ===
=== Construccion de conjuntos de items ===
Línea 768: Línea 928:
=== Propiedades LR ===
=== Propiedades LR ===


'''Propiedad:''' Si L es LLCD (Lenguaje Libre de Contexto Determinístico) y libre de prefijos, entonces existe una gramatica LR(0) que lo captura.
'''Propiedad:''' Si L es LLCD y libre de prefijos, entonces existe una gramatica LR(0) que lo captura.


'''Propiedad:''' Para todo lenguaje LLCD existe una gramatica LR(k) que lo representa.
'''Propiedad:''' Para todo lenguaje LLCD existe una gramatica LR(k) que lo representa.
Línea 775: Línea 935:


'''Propiedad:''' Toda gramática analizable con un parser predictivo descendente es analizable con un LR(1).
'''Propiedad:''' Toda gramática analizable con un parser predictivo descendente es analizable con un LR(1).
= Máquinas de Turing =
Las máquinas de Turing se definen como un autómata con una cinta infinita a derecha (es decir, las celdas van de cero a infinito positivo) con la siguiente aridad:
<math>MT = <Q, \Gamma ,B , \Sigma , \delta ,q_0, F></math>
* <math>Q</math> conjunto de estados
* <math>\Gamma</math> alfabeto de la cinta
* <math>B \in \Gamma</math> símbolo blanco, representa una celda vacía
* <math>\Sigma \subset \Gamma</math> alfabeto de entrada, no incluye al blanco
* <math>\delta : Q \times \Gamma \rightarrow partes(Q \times \Gamma \times \{ L,R\} )</math> acciones
* <math>q_0 \in Q</math> estado inicial
* <math>F \subseteq Q</math> estados finales
Las acciones de la máquina dependen del estado actual y del símbolo que hay bajo la cabeza lectora/escritora, e implican escribir otro símbolo (puede ser el mismo) y moverse a izquierda o derecha.
La configuración instantánea de una máquina de Turing se define como <math>\alpha _1 q \alpha _2</math>, donde <math>\alpha _1</math> es el contenido de la cinta (sucesión de caracteres) a la izquierda del cabezal, ''q'' es el estado actual de la máquina, y <math>\alpha _2</math> es el contenido de la cinta desde el cabezal hasta el último símbolo distinto de blanco. Así, se puede especificar cuál es el estado actual, el contenido de la cinta y la posición del cabezal.
La cinta inicialmente comienza llena de blancos, excepto al comienzo donde tiene escrito el input a reconocer. Notar que el caracter blanco no puede pertenecer al alfabeto de entrada.
La máquina acepta una cadena si en su ejecución llega a un estado final, notar que la máquina no tiene transiciones desde un estado final. Como la cadena está escrita en la cinta, no existe el concepto de consumir la cadena de entrada.
== Máquina de Turing determinística ==
Una máquina de Turing es determinística cuando dado un estado y un símbolo bajo el cabezal existe una única acción. Vale que una máquina determinística puede emular a una no determinística.
Para esto se construye una MTD M' que reconoce la cadena cuando esta pertenece al lenguaje y se cuelga cuando no pertenece. La MTD construida tiene tres cintas (se puede demostrar que una máquina con un número finito de cintas equivale a una de una sola cinta). La idea es guardar en la primer cinta la cadena de entrada, en la segunda un número que simboliza una traza a seguir de la máquina M original, y la tercera usarla para emular las operaciones de M.
Para simbolizar una traza, se calcula el máximo grado de salida (r) de los nodos de la máquina M, se numera cada transición a partir de cada estado con un número de 1 a r, y se escribe una secuencia de dígitos entre 1 y r. Esto permite recorrer todas las posibles secuencias de configuraciones instantáneas en BFS.
La MTD M', entonces, en cada iteración copia la entrada de la primer cinta a la tercera, incrementa en 1 el valor de la segunda cinta (número expresado en base ''r'' que simboliza la traza) y con esa traza emula a M sobre la tercer cinta. Si termina en estado de aceptación, se acepta la cadena. Si se traba o termina en un estado no final, se itera nuevamente.
== Lenguajes Recursivamente Enumerables ==
Los LRE (lenguajes tipo 0 en la jerarquía de Chomsky) son lenguajes reconocibles por una máquina de Turing. Son aquellos que pueden especificarse sin restricciones sobre sus producciones.
=== Gramática a MTND ===
Para pasar de una gramática tipo 0 a una MTND, se utilizan dos cintas. En la primera se guarda la cadena; en la segunda se van generando formas sentenciales de manera no determinística a partir del símbolo distinguido S. Cuando se encuentra alguna que matchea la entrada, se acepta; si no, la máquina se cuelga.
=== MT a Gramática ===
Para pasar de una MT a una gramática se establece una equivalencia entre los símbolos de la gramática y las configuraciones instantáneas de la máquina de Turing. Los símbolos generados son de la forma [a,b], donde ''a'' representará el caracter original de la cadena de entrada y ''b'' el caracter sobre el que opera la máquina.
Se proveen producciones para generar, incialmente, una cadena arbitraria de símbolos [a,a], siendo ''a'' cualquier terminal. Esto equivale a tener inicialmente en la cinta cualquier cadena. Seguidos a estos se genera una cantidad libre de simbolos [lambda,Blanco], tantos como necesitaría la cinta para operar.
La gramática genera, al principio de todo, un caracter ''q'' que representará el cabezal de la máquina. Las producciones de la gramática permiten "mover" ''q'' entre los símbolos [a,b] (modificando solamente los ''b'') en base a las acciones permitidas por la MT original.
Una vez alcanzado un estado final, se generan producciones que eliminan todos los símbolos [a,b] dejando solamente los ''a'' correspondientes a la cadena original, y finalmente a ''q''. Así, la cadena final de terminales es la cadena a generar.
== Lenguajes Sensitivos al Contexto ==
Los lenguajes dependientes del contexto se expresan con gramáticas tipo 1 en la jerarquía de Chomsky, que tienen la restricción de que la longitud del lado derecho de una producción no puede ser menor a la del lado izquierdo.
=== Autómata Linealmente Acotado ===
Los ALA pueden verse como máquinas de Turing con la cinta acotada. En un ALA el alfabeto de entrada incluye dos símbolos, usados como tope de entrada y tope de salida. El autómata no puede moverse más allá de los topes ni sobreescribirlos.
Notar que un ALA tal que en la cinta tenga una cantidad de blancos lineal a la longitud de la entrada es equivalente a un ALA con cero blancos, que opera exclusivamente sobre la cadena de entrada.
A diferencia de lo que sucedía con las MT, no hay equivalencia entre ALA y ALAD. A primera vista puede observarse que el método anterior no funciona pues el número que simboliza la traza a emular (en la segunda cinta) puede crecer arbitrariamente.
=== Gramática a ALA ===
La equivalencia entre una gramática sensitiva al contexto y un ALA se demuestra exactamente igual que para máquinas de Turing en general, excepto que en este caso puede agregarse la restricción de que si la cadena que se está generando excede el tamaño de la que se ha de reconocer se corta esa rama (pues ninguna cadena de terminales y no terminales puede derivar en una de longitud menor). Así la cantidad de posibilidades a explorar es finita.
== Lenguajes Recursivos ==
Los lenguajes recursivos se encuentran estrictamente entre los sensitivos al contexto y los recursivamente enumerables. Son aquellos reconocibles por una HTM (halting Turing machine). Es decir, existe una máquina de Turing que dada cualquier entrada, siempre para y devuelve si una cadena pertenece o no (no puede colgarse).
=== Inclusión de Sensitivos al Contexto ===
Para demostrar que los LSC están incluidos dentro de los regulares, se construye una HTM que determine si una cadena pertenece al lenguaje. Dada una gramática GSC y una cadena de entrada w de longitud n, se construye un grafo finito donde cada nodo es un string de terminales y no terminales de longitud menor o igual a n.
Los arcos en este grafo representan si es posible ir de un string a otro mediante derivaciones de la gramática. Notar que este grafo es finito y puede construirse mediante un algoritmo.
Luego, para determinar si una cadena ''w'' pertenece al lenguaje, simplemente se verifica mediante un algoritmo si existe un camino desde ''S'' hasta el nodo que contiene a ''w''. Como lo anterior es un algoritmo (siempre termina) existe una HTM que lo ejecuta, con lo cual el lenguaje LSC es recursivo.
=== Lenguaje Recursivo no LSC ===
Para demostrar que existe un lenguaje recursivo no sensitivo al contexto se utiliza un argumento diagonal. Primero se prueba un lema que indica que dada cualquier enumeración de HTMs, existe un lenguaje recursivo que no es aceptado por ninguna de ellas (el lenguaje que dada la cadena ''i'', la acepta sii no es reconocida por la iesima HTM de la enumeración).
Eventualmente se llega a una contradicción, pues si existe una HTM de índice ''i'' en la enumeración, la cadena ''i'' debe ser reconocida por dicha HTM sii no lo es. Notar que este lenguaje es recursivo, pues existe un algoritmo (procedimiento que siempre termina) que puede determinar si una cadena ''i'' pertenece al conjunto: simplemente corre la HTM ''i'' con esa cadena y devuelve la negación.
A partir de esto, se construye una enumeración de las HTM que reconocen todos los LSC, lo cual es posible ya que se pueden enumerar las GSCs. Pero por el lema anterior existe un lenguaje que no es reconocido por ninguna de estas HTMs, es decir, por ningún LSC. Y este lenguaje es recursivo.
La demostración parece basarse en que el conjunto de HTMs no es numerable, mientras que el de GSCs sí lo es. Por lo tanto debe existir alguna HTM que genere un lenguaje no sensitivo al contexto.
== Lenguaje Diagonal ==
El lenguaje diagonal es un ejemplo de un lenguaje que no es recursivamente enumerable. Requiere enumerar las MT y entradas posibles y llegar a una contradicción similar a la del problema de la parada.
Más formalmente, se basa en construir una tabla infinita de dos entradas. La celda (i,j) entonces vale 1 sii la máquina de Turing de nro ''j'' reconoce la cadena ''i''. La MT se encuentra codificada en binario, y la cadena de entrada es de 0s y 1s.
Entonces, puede construirse el lenguaje de las cadenas ''i'' tal que no pertenecen a la MT de igual número (lenguaje diagonal). Si este lenguaje es recursivamente enumerable, entonces existe una MT ''Mk'' tal que reconce sus cadenas. En otras palabras,
<math>w_k \in L_d \Longleftrightarrow w_k \not \in L(M_k) = L_d</math>
Con lo que se llega a una contradicción. La cadena de igual número que ''M'' es reconocida por la máquina sii no es reconocida.
Otra opción (distinta a la del pdf, revisar) es un lenguaje que acepta una cadena sii esta representa una máquina de Turing con una entrada dada, y dicha máquina para. Si dicha máquina existiera, resolvería el halting problem, lo que no es posible.
== Lenguaje Universal ==
El lenguaje universal es el que se corresponde a la MT que ejecuta cualquier otra MT con cualquier entrada. En otras palabras, toma pares de cadena y MT, y determina si la cadena es reconocida por esa MT.
'''Recursivamente Enumerable'''
Este lenguaje es recursivamente enumerable. Puede construirse una MT con 3 cintas, de las cuales la primera contiene el input (la MT ''M'' más la cadena de entrada ''w''), la segunda (inicializada con la cadena ''w'') emula la cinta de ''M'', y la tercera permite llevar cuenta del estado en el que se encuentra la ''M'' emulada.
'''No Recursivo'''
Para demostrar que este lenguaje no es recursivo, se supone inicialmente que lo es y se intenta llegar al absurdo. Para esto, se construye un algoritmo (es decir, un procedimiento que siempre para, emulable por una HTM) que dada una cadena de entrada, genera su MT con igual número. Luego se determina, usando la HTM del lenguaje universal (supusimos que era recursivo) si <math>(w_i, MT_i)</math> es aceptado, esto es, si la máquina ''i'' acepta la cadena ''i''.
Notar que este es el complemento del lenguaje diagonal. Como es un algoritmo, siempre termina y devuelve verdadero o falso. Con lo que puede generarse fácilmente una HTM que reconozca el lenguaje diagonal directamente. Lo que es absurdo puesto que no es siquiera recursivamente enumerable.
Intuitivamente, el que el lenguaje universal sea recursivo significaría que es posible tener un método que siempre termina que resuelve (por sí o por no) la pertenencia de cualquier cadena a cualquier MT. Es decir, es capaz de decidir el halting problem.


= Compiladores =
= Compiladores =
Ten en cuenta que todas las contribuciones a Cuba-Wiki pueden ser editadas, modificadas o eliminadas por otros colaboradores. Si no deseas que las modifiquen sin limitaciones, no las publiques aquí.
Al mismo tiempo, asumimos que eres el autor de lo que escribiste, o lo copiaste de una fuente en el dominio público o con licencia libre (véase Cuba-Wiki:Derechos de autor para más detalles). ¡No uses textos con copyright sin permiso!

Para editar esta página, responde la pregunta que aparece abajo (más información):

Cancelar Ayuda de edición (se abre en una ventana nueva)