commit maquinas

This commit is contained in:
Vladimir Lemus 2021-09-27 12:08:14 -05:00
parent ec39e17905
commit 72a7084c32
11 changed files with 863 additions and 0 deletions

BIN
chomsky_schutzenberger.pdf Normal file

Binary file not shown.

128
chomsky_schutzenberger.tex Normal file
View File

@ -0,0 +1,128 @@
\documentclass[10pt,a4paper]{article}
\usepackage[utf8]{inputenc}
\usepackage[spanish]{babel}
\usepackage{amsmath}
\usepackage{amsfonts}
\usepackage{amssymb}
\usepackage{hyperref}
\usepackage{graphicx}
\usepackage{subcaption}
\usepackage{pgf}
\usepackage{tikz}
\usetikzlibrary{automata,positioning,arrows}
%\tikzset{->, % makes the edges directed
% >=stealth, % makes the arrow heads bold
% node distance=3cm, % specifies the minimum distance between two nodes. Change if necessary.
% every state/.style={thick, fill=gray!10}, % sets the properties for each state node
% initial text=$ $ % sets the text that appears on the start arrow
% }
%\usetikzlibrary{arrows,automata}
%\usepackage[all,cmtip]{xy}
%\usepackage{graphicx}
\author{Autómatas y lenguajes formales}
\title{Teorema Chomsky-Schützenberger}
\begin{document}
\maketitle
\section*{Lenguaje de \emph{Dyck}}
Este tema en el plan del curso iba antes, pero lo salté, aquí lo recupero pues es necesario para lo que sigue.
Podemos definir un lenguaje para los paréntesis bien balanceados de distinto tipo\footnote{Como ya su experiencia en la matemáticas les habrá hecho ver, cuando usan más de un paréntesis, en ocasiones es útil usar paréntesis diferenciados, por ejemplo si en una misma expresión requieren tres tipos de paréntesis pueden usar [\{()\}]. Aunque en programación se suele usar sólo un tipo y la programadora/programador o el editor está al pendiente de donde abre y cierra cada tipo.}, que llamaremos $D_n$ de la siguiente forma:
\begin{equation*}
S \rightarrow \underset{1}{[} S \underset{1}{]} | \underset{2}{[} S \underset{2}{]} | ... | \underset{n}{[} S \underset{n}{]} | SS | \epsilon,
\end{equation*}
\noindent con esas producciones se pueden generar $n$ pares de paréntesis bien anidados.
Un concepto importante en matemáticas y en las ciencias de la computación es la conversión de un problema a otro ya conocido\footnote{Incluso hay un chiste sobre cuántos matemáticos se necesitan para cambiar un foco, no me lo sé y para no arruinarlo no lo cuento.}, así si en el problema nuevo no encontramos solución, si lo podemos convertir a un viejo conocido con solución, pues ya solo convirtiendo algunas cosas tenemos la solución del nuevo. Esta es la base del teorema de Chomsky-Schützberger.
\section*{Teorema de Chomsky-Schützberger}
\newtheorem{defi}{Teorema}
\begin{defi}
Todo lenguaje independiente de contexto es una imagen homomorfa de la intersección de un lenguaje de paréntesis y un conjunto regular. En otras palabras, para todo lenguaje independiente de contexto $\mathbf{A}$, hay una $n\geq 0$, un conjunto regular $R$ y un homomorfismo $h$ tales que:
\begin{equation*}
\mathbf{A} = h(D_n \cap R)
\end{equation*}
\end{defi}
Diciéndolo en otras palabras, todo lenguaje independiente de contexto es una ampliación a un lenguaje regular, ya que es equivalente a la unión de un lenguaje regular con un lenguaje de paréntesis de \emph{Dyck} (que es un ejemplo muy sencillo de un lenguaje independiente de contexto).
El homomorfismo es un mapeo que va de un dominio a otro, en este caso $h: \Gamma^* \rightarrow \Lambda^*$, por ejemplo la función $h(x,y) = h(x)h(y)$, donde $x,y\in \Gamma^*$ y $h(x)h(y)\in \Lambda^*$. Como el nombre lo indica, un mapeo pasa punto por punto a algo muy parecido, como aquellos mapamundis que usaban en la escuela, que pasan el globo terráqueo a una superficie plana, sin dejar fuera ningún país. Una imagen para recordar un poco como es eso se muestra en la figura\ref{fig:hom}.
\begin{figure}[h]
\begin{center}
\includegraphics[width=0.5\linewidth]{group_hom2.jpg}
\caption{Ejemplo de un homomorfismo, piense que el conjunto de la izquierda es $\Gamma^*$ y el de la derecha $\Sigma^*$. Imagen adaptada de una tomada de la página: https://mathstrek.blog/2012/09/28/casual-introduction-to-group-theory-6/}
\label{fig:hom}
\end{center}
\end{figure}
¿Cómo se hace este homomorfismo de la intersección de un lenguaje de \emph{Dyck} y un lenguaje regular a un lenguaje independiente de contexto? Si recuerdan un lenguaje independiente de contexto se define por un cuarteto del tipo $G = (\Sigma,\Gamma,S,\rightarrow)$, con $\Sigma$ el alfabeto de entrada, $\Gamma$ el alfabeto de la memoria, $S$ la variable inicial y $\rightarrow$ el conjunto de producciones.
Vamos a desglosar un poco este último conjunto, las producciones son varias, en este caso las llamaremos a partir de letras griegas minúsculas. Sólo para identificarlas con las funciones en el nuevo dominio.
\begin{equation*}
\{\pi,\rho,\sigma,...\}\in \rightarrow,
\end{equation*}
\noindent esta elección de llamar al conjunto de producciones $\rightarrow$ al momento puede ser medio confuso, pero espero conforme avancemos no lo sea tanto. Otra manera de verlo es como si cada producción tuviera un nombre:
\begin{equation*}
\{\underset{\pi}{\rightarrow},\underset{\rho}{\rightarrow},\underset{\sigma}{\rightarrow},...\}\in \rightarrow,
\end{equation*}
\noindent pero sólo las identificaremos por las letras que las designan.
Lo que sigue es transformar las producciones al lenguaje de paréntesis, por ejemplo si se tiene el lenguaje independiente de contexto:
\begin{align*}
A&\rightarrow BC \\
A&\rightarrow a,
\end{align*}
Las podemos juntar en una sola producción:
\begin{equation*}
A \rightarrow BC|a
\end{equation*}
\noindent como pueden ver ya en forma normal de Chomsky, a esta le llamamos nuestra producción $\pi$. En el lenguaje de \emph{Dyck} se transforma a:
\begin{align*}
A&\rightarrow \underset{\pi}{\overset{1}{[}} B \underset{\pi}{\overset{1}{]}} \underset{\pi}{\overset{2}{[}} C \underset{\pi}{\overset{2}{]}}\\
A&\rightarrow \underset{\pi}{\overset{1}{[}} \underset{\pi}{\overset{1}{]}} \underset{\pi}{\overset{2}{[}} \underset{\pi}{\overset{2}{]}},
\end{align*}
\noindent respectivamente. Los números de arriba indican el tipo de paréntesis (un paréntesis del tipo $1$ no cierra con uno del tipo $2$) y la letra griega minúscula inferior hace referencia a la producción, en este caso $\pi$.
Para hacerlo más claro completemos el lenguaje:
\begin{align*}
A&\rightarrow BC \\
A&\rightarrow a \\
B&\rightarrow b \\
C&\rightarrow c,
\end{align*}
\noindent aprovechando que ya está en forma normal de Chomsky. Cada regla de producción que involucre a la misma variable del lado izquierdo se marca con el mismo símbolo, así la producción $\pi$ designa a las primeras dos líneas (con la variable $A$), la producción de $B$ la llamaremos $\rho$, y la de $C$ será $\sigma$. Por suerte estas últimas dos solo tienen una regla.
Ponerlo en forma normal de Chomsky lo reduce a que tengamos sólo dos tipos distintos de paréntesis por cada producción, sólo habrá dos tipos para $\pi$, dos tipos para $rho$ y dos para $\sigma$, pero un paréntesis de $\pi$ no puede ser cerrado con uno de $\sigma$ o $\rho$, son reglas de producción distintas. El lenguaje se transforma en:
\begin{align*}
A&\rightarrow \underset{\pi}{\overset{1}{[}} B \underset{\pi}{\overset{1}{]}} \underset{\pi}{\overset{2}{[}} C \underset{\pi}{\overset{2}{]}}\\
A&\rightarrow \underset{\pi}{\overset{1}{[}} \underset{\pi}{\overset{1}{]}} \underset{\pi}{\overset{2}{[}} \underset{\pi}{\overset{2}{]}} \\
B&\rightarrow \underset{\rho}{\overset{1}{[}} \underset{\rho}{\overset{1}{]}} \underset{\rho}{\overset{2}{[}} \underset{\rho}{\overset{2}{]}} \\
C&\rightarrow \underset{\sigma}{\overset{1}{[}} \underset{\sigma}{\overset{1}{]}} \underset{\sigma}{\overset{2}{[}} \underset{\sigma}{\overset{2}{]}}.
\end{align*}
De aquí se pueden ver unas reglas para el acomodo de los paréntesis y de que forma pueden ser identificados unos con variables y otros con terminales, eso ya se los dejo un poco a su análisis, pero éstas son las reglas. Por ejemplo las cadenas en ese lenguaje independiente de contexto son $a$ y $bc$, en el nuevo lenguaje se transforman en $\underset{\pi}{\overset{1}{[}} \underset{\pi}{\overset{1}{]}} \underset{\pi}{\overset{2}{[}} \underset{\pi}{\overset{2}{]}}$ y $\underset{\pi}{\overset{1}{[}} \underset{\rho}{\overset{1}{[}} \underset{\rho}{\overset{1}{]}} \underset{\rho}{\overset{2}{[}} \underset{\rho}{\overset{2}{]}} \underset{\pi}{\overset{1}{]}} \underset{\pi}{\overset{2}{[}} \underset{\sigma}{\overset{1}{[}} \underset{\sigma}{\overset{1}{]}} \underset{\sigma}{\overset{2}{[}} \underset{\sigma}{\overset{2}{]}} \underset{\pi}{\overset{2}{]}}$ respectivamente.
Este lenguaje de puros paréntesis es equivalente al anterior, aunque no lo parezca, esos monstruos de paréntesis ya son un lenguaje independiente de contexto, todos los símbolos son el alfabeto del lenguaje de \emph{Dyck}, pero las reglas para que hagan sentido es la intersección con un lenguaje regular (esta construcción podría representarse por un autómata finito).
\begin{thebibliography}{10}
\bibitem{Kozen} Kozen, Dexter C. ``Automata and Computability'' Springer (1997)
\end{thebibliography}
\end{document}

BIN
group_hom2.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

BIN
last_of_us.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

BIN
maquinas_turing.pdf Normal file

Binary file not shown.

279
maquinas_turing.tex Normal file
View File

@ -0,0 +1,279 @@
\documentclass[10pt,a4paper]{article}
\usepackage[utf8]{inputenc}
\usepackage[spanish]{babel}
\usepackage{amsmath}
\usepackage{amsfonts}
\usepackage{amssymb}
\usepackage{hyperref}
\usepackage{graphicx}
\usepackage{subcaption}
\usepackage{pgf}
\usepackage{tikz}
\usetikzlibrary{automata,positioning,arrows}
%\tikzset{->, % makes the edges directed
% >=stealth, % makes the arrow heads bold
% node distance=3cm, % specifies the minimum distance between two nodes. Change if necessary.
% every state/.style={thick, fill=gray!10}, % sets the properties for each state node
% initial text=$ $ % sets the text that appears on the start arrow
% }
%\usetikzlibrary{arrows,automata}
%\usepackage[all,cmtip]{xy}
%\usepackage{graphicx}
\author{Autómatas y lenguajes formales}
\title{Máquinas de Turing}
\begin{document}
\maketitle
\section*{Máquina de Turing}
La máquina de Turing es uno de los modelos de computación más poderosos, es lo más cercano a una computadora (como la que usaron para bajar este pdf, y quizá hasta para leerlo), pero no es el único modelo. Tomaremos la máquina de Turing como el formalismo con el que trabajaremos ahora, para entender las cosas, pero más adelante veremos otros modelos de máquinas. No sé si será el método más pedagógico, o el más sencillo, pero es el estándar en la mayoría de libros del tema (además de que Turing es el más famoso de los matemáticos que trabajaron inicialmente en el área). Los modelos son equivalentes, así que no perderemos generalidad.
A su vez hay variaciones en los modelos de máquinas de Turing, estos extras ayudan a hacer más entendible el modelo, reducir la notación, ahorrar un poco de trabajo, pero de nueva cuenta, son equivalentes entre sí.
Una máquina de Turing se compone de un conjunto finito de estados $Q$, una cinta semi-infinita limitada por la izquierda con el símbolo $\vdash$ e ilimitada por la derecha (este límite izquierdo es para saber donde empieza la cinta) y una cabeza que puede moverse a izquierda y derecha, capaz de leer y escribir caracteres en la cinta\footnote{Son muy jóvenes para recordar los casetes quizá, aunque por ahí hay unos intentos retros de revivirlos, pero si alguna vez han visto uno con su respectivo reproductor podrán notar que cuenta con una cinta magnética de color café o negro, que es leída por una cabeza también magnética. Era un formato de no muy buena calidad, de riesgo pues un imán de potencia suficiente podía dañar la cinta y los carretes podían provocar accidentes como enrollarse o atorarse. Hubo computadoras que usaban casetes para leer programas, para una crónica al respecto echen un ojo a: \url{https://www.xataka.com/historia-tecnologica/cuando-los-videojuegos-venian-en-cassette-y-habia-que-rebobinarlos-para-poder-jugar}}. Las palabras de entrada, de longitud finita, se escriben sobre la cinta de izquierda a derecha (como escribimos nosotros), al terminar la palabra de entrada, en las casillas de la cinta vacías para distinguir que no contienen caracter alguno de interés para el lenguaje está pre-escrito el símbolo $\textvisiblespace$. Un esquema ejemplificando de esta disposición se muestra en la figura \ref{fig:tur} de la página \pageref{fig:tur}.
\begin{figure}[h]
\begin{center}
\includegraphics[width=0.8\linewidth]{turing1.jpg}
\caption{Esquema de una máquina de Turing, imagen alterada a partir de la original de Kozen, Dexter C. "Automata and Computability", Springer 1997, pp. 210.}
\label{fig:tur}
\end{center}
\end{figure}
Esto puede verse un poco más complicado que nuestro clásico diagrama de estados, aquí los estados no son tan obvios ya que además van acompañados de acciones sobre la cabeza lectora y sobre la cinta. La máquina se encontrará, recién iniciada, en su estado inicial, leerá el caracter en la cinta y dependiendo de lo que lea, y el estado, escribe un nuevo símbolo (puede escribir el mismo símbolo y se entiende que no alteró la cinta) y la cabeza lectora se mueve a la izquierda o derecha en una sola posición y entra en un nuevo estado.
Las reglas que nos dan las transiciones entre estados son las ya conocidas transiciones $\delta$, para detenerse la máquina entra en su estado final de \emph{aceptación} o \emph{rechazo}, aunque existe la posibilidad de que no entre a ninguno de estos estados y se quede trabajando por siempre, en un \emph{loop} o ciclo infinito.
\subsection*{Definición formal}
\newtheorem{defi}{Definición}
\begin{defi}
Una máquina de Turing determinista, de cinta única es una 9-tupla (yo lo traduciría como un noneto o enéada, pero quizá no es la terminología) descrita como:
\begin{equation*}
M=(Q,\Sigma, \Gamma,\vdash,\textvisiblespace,\delta,s,t,r)
\end{equation*}
con:
\begin{itemize}
\item $Q$ es el conjunto finito de estados
\item $\Sigma$ es el alfabeto de entrada (finito)
\item $\Gamma$ es el alfabeto de cinta (finito), con $\Sigma \subseteq \Gamma$
\item $\vdash \in \Gamma - \Sigma$ el símbolo de inicio de la cinta
\item $\textvisiblespace \in \Gamma - \Sigma$ el símbolo de espacio en blanco
\item $\delta: Q\times \Gamma \rightarrow Q\times \Gamma \times \{ \rightarrow,\leftarrow \}$ la función de transición
\item $s\in Q$ el estado inicial
\item $t\in Q$ el estado de aceptación
\item $r\in Q$ el estado de rechazo.
\end{itemize}
\end{defi}
La manera de describir las transiciones es: $\delta (p,a) = (q,b,\rightarrow)$, que se entiende como "si la maquina en el estado $p$ lee en la posición de la cinta en que se encuentra la cabeza lectora una $a$ entonces pasa a un estado $q$, escribe en la misma posición de la cinta una $b$ y mueve la cabeza lectora a la derecha ($\rightarrow$ o $R$)". Un caso especial es cuando se lee el símbolo $\vdash$, no puede escribirse otro símbolo que no sea el mismo, y la cinta no puede ir más a la izquierda, entonces si se tiene: $\delta(q,\vdash) = (p,\vdash,\rightarrow)$, nunca con $\leftarrow$.
Si se entra a los estados de aceptación o rechazo, ahí se queda la máquina: $\delta(t,a)=(t,b,\rightarrow / \leftarrow)$, puede moverse izquierda o derecha de la cinta, incluso escribir en la cinta pero ya no sale del estado, y $\delta(r,d) = (r,f,\rightarrow /\leftarrow)$, de manera similar, puede moverse en cualquier dirección de la cinta la cabeza, puede escribir en ella, pero no sale del estado de rechazo.
\subsection*{Un ejemplo}
Como hemos hecho regularmente vamos a ver un ejemplo que vaya más allá de los modelos que hemos visto antes, en este caso trabajaremos el lenguaje dependiente de contexto $\{ a^nb^nc^n| n\geq 0 \}$. Lo que hará la máquina es lo siguiente:
\begin{enumerate}
\item[0] Empieza en su estado inicial, supongamos que la cabeza lectora está al inicio de la cinta (si no lo está solo haría falta poner una función de \emph{reset} o algo parecido, no es relevante ahora, imaginemos todo ideal), al leer que la cinta está en su orilla izquierda la cabeza lectora empieza a moverse a la derecha.
\item[1] Seguimos en el estado inicial y lo que esperamos al movernos al primer símbolo no vacío de la cinta es hallar una $a$, mientras se lean $a$'s la cabeza sigue moviéndose a la derecha, se sobrescriben las $a$'s y se queda en el estado inicial.
\item[2] Al leer la primera $b$ se pasa al estado $q_1$ y la cabeza lectora sigue andando a la derecha, mientras lea $b$'s se quedará en el estado $q_1$ y la cabeza seguirá corriendo a la derecha.
\item[3] La máquina sigue en el estado $q_1$ y lee una $c$, entonces se pasa al estado $q_2$ y la cabeza lectora sigue su camino a la derecha, mientras lea $c$'s se queda en el estado $q_2$.
\item[3b] Si está en el estado $q_1$ leyendo $b$'s y de repente se encuentra una $a$ en lugar de una $c$, se manda al estado de rechazo $r$ y la cinta podría seguir corriendo, pero no tiene sentido, se puede parar ahí, fin, la cadena no es parte del lenguaje.
\item[4] La máquina se encuentra en el estado $q_2$ leyendo $c$'s y se encuentra con un símbolo vacío, es decir $\textvisiblespace$, entonces pasa al estado $q_3$ y escribe un símbolo especial, en este caso escribimos una $\dashv$ pero podría ser una $x$, o un símbolo que no vayamos a usar, este no es crucial, sólo es para que en los próximos escaneos sepa donde pararse. Hasta aquí sólo se hizo el primer recorrido, se comprobó que la cadena tiene el orden correcto en los caracteres, ahora hay que contar. Una vez llegando al final, marcando la orilla derecha, la cabeza empieza a viajar a la izquierda.
\item[5] Fase de conteo: La cabeza ahora corre hacia la izquierda (de regreso), si encuentra una $c$ la borra (escribiendo $\textvisiblespace$) y pasa al estado $q_4$, mientras la cabeza sigue corriendo a la izquierda. Las siguientes $c$'s que encuentre las sobre escribirá, se quedará en el mismo estado y seguirá la cabeza corriendo a la izquierda.
\item[5b] Si está en el estado $q_3$, corriendo a la izquierda la cabeza lectora, y lee una $b$ o $a$ en lugar de una $c$, inmediatamente se va al estado de rechazo (en principio no debería pasar, pues ya checamos el orden en la primera fase, pero nunca está de más reiterar las órdenes, además de que en muchos casos no se guarda memoria de instrucciones anteriores).
\item[6] La máquina está en el estado $q_4$ y corre a la izquierda, si de repente se encuentra una $b$, se borra (se sustituye por $\textvisiblespace$), se pasa al estado $q_5$ y la cabeza continúa su camino a la izquierda. Mientras encuentre $b$ subsecuentes se quedará en el mismo estado y no les hará nada a esos símbolos (reescribirá $b$), la cabeza seguirá su camino a la izquierda.
\item[6b] Si se encuentra en el estado $q_4$ y en lugar de $b$ la cabeza lectora lee una $a$ o el símbolo del extremo izquierdo de la cinta, $\vdash$, se va a un estado de rechazo y no hace nada más.
\item[7] La máquina se encuentra en el estado $q_5$, la cabeza corre a la izquierda, si en su camino encuentra una $a$ la sustituye por $\textvisiblespace$, pasa al estado $q_6$ y continúa corriendo a la izquierda. Las siguientes $a$'s que encuentre las reescribirá, se quedará en el mismo estado y seguirá la cabeza su camino a la izquierda.
\item[7b] Si se encuentra en el estado $q_5$ y en lugar de $a$ la cabeza lectora lee la orilla izquierda de la cinta, $\vdash$, se va a un estado de rechazo y no hace nada más.
\item[8] En el estado $q_6$, la cabeza sigue corriendo a la izquierda, en este punto ya ha marcado (borrando) una $c$, una $b$ y una $a$, si la cabeza lee el símbolo $\vdash$, como sabemos por principio lo reescribe, pasa al estado $q_7$ y la cabeza se da vuelta, empieza a correr a la derecha y de nueva cuenta borra conforme se vaya encontrando, y en el orden, una $a$, una $b$ y una $c$.
\end{enumerate}
\begin{table}
\begin{center}
\begin{tabular}{ |p{0.6cm}||p{1.5cm}|p{1.5cm}|p{1.5cm}|p{1.6cm}|p{1.6cm}|p{1.5cm}|}
\hline
& $\vdash$ & $a$ & $b$ & $c$ & $\textvisiblespace$ & $\dashv$\\
\hline
\hline
$s$ & $(s,\vdash,\rightarrow)$ & $(s,a,\rightarrow)$ & $(q_1,b,\rightarrow)$& $(q_2,c,\rightarrow)$ & $(q_3,\dashv,\leftarrow)$ & \\
\hline
$q_1$ & & $(r,-,-)$ & $(q_1,b,\rightarrow)$ & $(q_2,c,\rightarrow)$ & $(q_3,\dashv,\leftarrow)$ & \\
\hline
$q_2$ & & $(r,-,-)$ & $(r,-,-)$ & $(q_2,c,\rightarrow)$ & $(q_3,\dashv,\leftarrow)$ &\\
\hline
$q_3$ & $(t,-,-)$ & $(r,-,-)$ & $(r,-,-)$ & $(q_4,\textvisiblespace,\leftarrow)$ & $(q_3,\textvisiblespace,\leftarrow)$ &\\
\hline
$q_4$ & $(r,-,-)$ & $(r,-,-)$ & $(q_5,\textvisiblespace,\leftarrow)$ & $(q_4,c,\leftarrow)$ & $(q_4,\textvisiblespace,\leftarrow)$ &\\
\hline
$q_5$ & $(r,-,-)$ & $(q_6,\textvisiblespace,\leftarrow)$ & $(q_5,b,\leftarrow)$ & & $(q_5,\textvisiblespace,\leftarrow)$ &\\
\hline
$q_6$ & $(q_7,\vdash,\rightarrow)$& $(q_6,a,\leftarrow)$ & & & $(q_6,\textvisiblespace,\leftarrow)$ &\\
\hline
$q_7$ & & $(q_8,\textvisiblespace,\rightarrow)$ & $(r,-,-)$ & $(r,-,-)$ & $(q_7,\textvisiblespace,\rightarrow)$ & $(t,-,-)$ \\
\hline
$q_8$ & & $(q_8,a,\rightarrow)$ & $(q_9,\textvisiblespace,\rightarrow)$ & $(r,-,-)$ & $(q_8,\textvisiblespace,\rightarrow)$ & $(r,-,-)$\\
\hline
$q_9$ & & & $(q_9,b,\rightarrow)$ & $(q_{10},\textvisiblespace,\rightarrow)$ & $(q_9,\textvisiblespace,\rightarrow)$ & $(r,-,-)$\\
\hline
$q_{10}$ & & & & $(q_{10},c,\rightarrow)$ & $(q_{10},\textvisiblespace,\rightarrow)$ & $(q_3,\dashv,\leftarrow)$\\
\hline
\end{tabular}
\end{center}
\caption{Tabla de transiciones de la máquina de Turing.}
\label{fig:tur2}
\end{table}
La idea es que la cinta vaya recorriendo, borrando una y otra vez, si se encuentra símbolos sin borrar cuando los correspondientes en orden ya hayan sido borrados, rechaza la cadena, si no halla ya más que vacío, acepta la cadena. Hay algunas características que no definí pero pueden verse en la tabla \ref{fig:tur2} de la página \pageref{fig:tur2}.
Hay que ver más ejemplos, por el momento les dejo definiciones importantes:
\begin{defi}
Un lenguaje es \emph{Turing-reconocible} si alguna máquina de Turing lo reconoce.
También se dice que es recursivamente enumerable.
\end{defi}
La colección de cadenas aceptadas por una máquina de Turing $T$, es el lenguaje reconocido por la máquina, $L(T)$.
\begin{defi}
Un lenguaje es \emph{Turing-decidible} o simplemente \emph{decidible} si alguna máquina de Turing lo decide.
También se dice que es recursivo.
\end{defi}
¿Cuál es la diferencia entre decidible o reconocible? Una cadena reconocida es aceptada por la máquina de Turing, está en su alfabeto de entrada, pero puede ser que la cadena provoque que la máquina entre a un estado de aceptación, a uno de rechazo o se quede atrapada en un ciclo infinito.
Quedar atrapado en un ciclo infinito es un problema, a veces no se puede saber si está en un ciclo infinito o sólo está tardando demasiado (pasa en la vida), entonces nos gustaría tener máquinas de Turing que sólo puedan entrar a estados de aceptación o rechazo, nada de ciclos infinitos (esto es muy idóneo), en ese caso, las cadenas que al entrar en una máquina de Turing sólo pueden producir estados de aceptación o rechazo, nunca ciclos infinitos, forman un lenguaje Turing-decidible, y la máquina asociada se llama total. Determinar estos lenguajes es un gran problema teórico en la mayoría de máquinas.
Una forma matemática de decir si una cadena es decidible:
\begin{equation*}
(s,\vdash \alpha {\textvisiblespace}^{\infty},0) \implies^* (q,\vdash \beta {\textvisiblespace}^{\infty},n)
\end{equation*}
\noindent $q$ debe ser el estado $t$ (aceptación) o $r$ (rechazo), $n$ son los pasos que toma para llegar al estado de aceptación o rechazo. Lo que verá en la cinta antes de empezar será $\vdash \alpha {\textvisiblespace}^{\infty}$, con $\alpha \in \Sigma^*$ y los símbolos que ya conocemos, es una forma reducida de decir qué está escrito en la cinta, como es infinita y la cadena aceptada es finita, los espacios en blanco al final de la cinta los escribimos como $\textvisiblespace^{\infty}$. Al terminar la lectura y escritura y llegar a un estado de aceptación o rechazo, seguramente habrá alterado la cinta (como hicimos en el ejemplo anterior) y ahora hay una nueva cadena $\beta\in \Gamma^*$, en caso de que hallamos agregado símbolos nuevos como indicadores.
\subsection*{Otro ejemplo}
Veamos un ejemplo más, sea la máquina de Turing que decida el lenguaje $A=\{ 0^{2^n}|n\geq 0 \}$, es decir, el lenguaje con puras cadenas de $0$'s que su longitud sea una potencia de $2$.
Sea nuestra máquina $M$ y la haremos algo parecida a la del ejemplo anterior, la idea es llevar la cuenta de la cantidad de $0$'s que hay.
\begin{enumerate}
\item Estamos en el estado inicial $s$, si hay un sólo $0$ la idea es aceptarlo (es parte del lenguaje), pero aún hay que comprobar que es el único. Para los siguientes ceros se llevará la cuenta, por el momento, para evitar un movimiento extra hasta el borde izquierdo de la cinta el primer $0$ lo podemos sustituir por un espacio en blanco $\textvisiblespace$ y movemos la cabeza lectora a la derecha buscando más $0$'s, pasamos del estado inicial al estado $q_1$. Si la cadena está vacía o tiene cualquier otro símbolo, vamos al estado de rechazo $r$.
\item Estamos en $q_1$ y se lee un espacio en blanco, es decir, se acaba la cadena, entonces hay un sólo $0$ y se va a el estado de aceptación $t$. El estado $q_1$ será crucial para todas las cadenas aceptadas, hay que tenerlo en cuenta. Si en cambio se lee otro $0$, la cabeza escribe una $x$ sobre él, empezamos a llevar la cuenta, cambiamos al estado $q_2$ y se mueve la cabeza lectora a la derecha. Si se lee una $x$ quiere decir que ya estamos en una de las subsecuentes vueltas de la cabeza, ya llevamos ese $0$ en la cuenta, nos quedamos en el mismo estado y la cabeza lectora se mueve a la derecha (a la izquierda ya no hay a qué ir, hay un espacio en blanco).
\item Vamos en el estado $q_2$, si estamos aquí es que llevamos al menos dos ceros detrás de nosotros, el siguiente $0$ que se reciba no se marca (se reescribe el $0$), pasamos al estado $q_3$ y la cabeza lectora se mueve a la derecha. Si en lugar de un $0$ se lee un espacio en blanco $\textvisiblespace$ quiere decir que llegamos a la orilla derecha de la cinta, entonces se pasa al estado $q_4$, no se altera el $\textvisiblespace$ y la cabeza empieza a moverse a la izquierda (vamos de regreso). Si se lee una $x$ es que ya pasamos por aquí al menos una vez, entonces ya se agregó ese cero a la cuenta, no se cambia lo escrito en la cinta, se queda en el mismo estado y la cabeza lectora sigue su camino a la derecha.
\item Estamos en el estado $q_3$, si la cabeza lectora encuentra un $0$ lo marca, es decir, lo sustituye por una $x$, regresa al estado $q_2$ y la cabeza continúa su recorrido a la derecha. Entre estos dos estados entra en un ciclo, dejando un $0$ sin marcar y marcando el siguiente, así hasta que llega al final de la cinta o sucede lo siguiente: estamos en el estado $q_3$ y la cabeza lectora encuentra el final de la cadena, eso quiere decir que llevamos un número impar de $0$'s, en definitiva no puede ser de longitud potencia de dos si es impar, se va al estado $r$, si encuentra una casilla marcada $x$ quiere decir que ya pasamos por aquí en un recorrido anterior, no se hace nada (reescribe $x$), se queda en el mismo estado y continúa su camino a la derecha.
\item Estamos en el estado $q_4$, recordemos que llegamos aquí porque en el estado $q_3$ dimos con el final derecho de la cadena, la cabeza ya corre hacia la izquierda y empieza a recorrer lo que ya recorrimos al menos una vez, los $0$'s y $x$'s que encuentre los deja sin alterar (los reescribe) y continúa su camino a la izquierda, se queda en el mismo estado $q_4$, pero en el momento que encuentre la orilla izquierda de la cinta (que recordarán es un $0$ que marcamos como $\textvisiblespace$) entonces regresa al estado $q_1$ sin cambiar nada de ese limite de la cinta y la cabeza vuelve a viajar hacia la derecha, vamos darle un repasada a la cadena. Del estado $q_2$ decide si debe seguir contando (marcando con $x$) o si ya está todo marcado y se llega al final derecho de la cinta, la cadena pasa al estado $t$.
\end{enumerate}
Escribimos la tabla con estas transiciones:
\begin{center}
\begin{tabular}{ | c | c | c | c | c | c }
\hline
& $\vdash$ & $0$ & $x$ & $\textvisiblespace$ \\ \hline
$s$ & $(s,\vdash,\rightarrow)$ & $(q_1,\textvisiblespace,\rightarrow)$ & $(r,-,-)$ & $(r,-,-)$ \\ \hline
$q_1$ & & $(q_2,x,\rightarrow)$ & $(q_1,x,\rightarrow)$ & $(t,-,-)$ \\ \hline
$q_2$ & & $(q_3,0,\rightarrow)$ & $(q_2,x,\rightarrow)$ & $(q_4,\textvisiblespace,\leftarrow)$ \\ \hline
$q_3$ & & $(q_2,x,\rightarrow)$ & $(q_3,x,\rightarrow)$ & $(r,-,-)$ \\ \hline
$q_4$ & & $(q_4,0,\leftarrow)$ & $(q_4,x,\leftarrow)$ & $(q_1,\textvisiblespace,\rightarrow)$ \\
\hline
\end{tabular}
\end{center}
Para $t$ (aceptación) y $r$ (rechazo) no hay transiciones, no las ponemos, los guiones dentro de los estados es porque ya no importa que pase con la cinta y la cabeza lectora, y los espacios en blanco son estados inaccesibles. Como no son tantos estados, podemos hacer un diagrama de estados, como se ve en la figura \ref{fig:tur3}, noten la diferencia entre $\Rightarrow$ que hace referencia a la transición, y $\rightarrow$ que es el movimiento hacia la derecha de la cabeza lectora, como ya se mencionó $-$ denota que ya no importa a dónde se mueva la cabeza lectora.
\begin{figure}[h]
\begin{center}
\begin{tikzpicture}%[shorten >=1pt,node distance=2cm,on grid,auto]
\node[state,initial,initial text= ] (S) {$S$};
\node[state,xshift=1cm,right=of S] (q_1) {$q_1$};
\node[state,above right=of q_1] (q_4) {$q_4$};
\node[state,below right=of q_4] (q_2) {$q_2$};
\node[state,below=of S] (r) {$r$};
\node[state,below=of q_1] (t) {$t$};
\node[state,below=of q_2] (q_3) {$q_3$};
\path [-stealth,thick]
(S) edge node[yshift=-0.3cm]{$0\Rightarrow \textvisiblespace, \rightarrow$} (q_1)
edge node[xshift=-0.5cm] {$\begin{array}{c l}
\textvisiblespace \Rightarrow - \\
x\Rightarrow -
\end{array}$} (r)
(q_1) edge node[yshift=-0.3cm]{$0\Rightarrow x,\rightarrow$} (q_2)
edge [loop above] node {$x\Rightarrow \rightarrow$} ()
edge node[xshift=-0.5cm]{$\textvisiblespace \Rightarrow -$} (t)
(q_2) edge[loop above] node{$x\Rightarrow \rightarrow$} ()
edge [bend right] node[xshift=-0.5cm]{$0\Rightarrow \rightarrow$} (q_3)
edge node{$\textvisiblespace \Rightarrow \leftarrow$} (q_4)
(q_3) edge[bend right] node[xshift=0.5cm]{$0\Rightarrow x,\rightarrow$} (q_2)
edge [loop right] node{$x\Rightarrow \rightarrow$} ()
edge [bend left] node[yshift=0.3cm]{$\textvisiblespace \Rightarrow -$} (r)
(q_4) edge[loop above] node{$\begin{array}{c l}
0 \Rightarrow \leftarrow \\
x\Rightarrow \leftarrow
\end{array}$} ()
edge node{$\textvisiblespace \Rightarrow \rightarrow$} (q_1);
\end{tikzpicture}
\caption{Diagrama de estados de la máquina de Turing descrita.}
\label{fig:tur3}
\end{center}
\end{figure}
Esta construcción puede parecer un tanto sacada de la manga ¿cómo nos consta que funciona para el lenguaje mencionado? Pues debemos checar, por ejemplo la cadena $0000$, de acuerdo a la descripción está en el lenguaje, vamos a meterla en nuestra máquina para checar. Lo vamos viendo por pasos:
\begin{itemize}
\item[$\overset{\rightarrow}{s}0000$] Empezamos la maquina en el estado $s$ y en la orilla izquierda de la cinta. La cabeza lectora empezará a correr hacia la derecha, donde se encuentra el primer cero, el cual cambiará por un $\textvisiblespace$ y pasará al estado $q_1$.
\item[$\textvisiblespace \overset{\rightarrow}{q_1} 000$] Noten que los estados van recorriendo la cadena, pero no ocupan espacios en la cinta, la ponemos ahí para facilidad de entendimiento. Estamos en el estado $q_1$, la cabeza lectora corre hacia la derecha, donde halla un $0$, lo cambia por un $x$ (lo marca), pasa al estado $q_2$.
\item[$\textvisiblespace x \overset{\rightarrow}{q_2} 00$] Ya en el estado $q_2$ la cabeza sigue corriendo a la derecha donde encuentra otro cero, como se puede ver en el diagrama y la tabla de transiciones, en este estado de hallarse un $0$ no lo marca, se va al estado $q_3$ y la cabeza sigue corriendo a la derecha.
\item[$\textvisiblespace x0 \overset{\rightarrow}{q_3} 0$] Ahora en el estado $q_3$ la cabeza lectora corriendo hacia la derecha se encuentra un cero, por la tabla de transiciones cambia el $0$ por una $x$, regresa al estado $q_2$ y la cinta sigue corriendo hacia la derecha.
\item[$\textvisiblespace x0x \overset{\rightarrow}{q_2} \textvisiblespace$] Llegamos al final de la palabra (no habíamos puesto antes el símbolo de espacio vacío pero realmente ahí estaba al final de la cadena), estamos en el estado $q_2$, cuando esto pasa se va al estado $q_4$, deja igual escrito el espacio vacío y la cabeza lectora empieza a correr ahora hacia la izquierda (eso lo tendremos en cuenta en nuestras próximas cadenas).
\item[$\textvisiblespace x0x\overset{\leftarrow}{q_4} \textvisiblespace$] Ahora estamos en el estado $q_4$, la cabeza lectora está corriendo a la izquierda, así que se encuentra una $x$, no la altera, se queda en el mismo estado y la cabeza sigue corriendo a la izquierda.
\item[$\textvisiblespace x0\overset{\leftarrow}{q_4}x \textvisiblespace$] Seguimos en el estado $q_4$, la cabeza lectora corre hacia la izquierda y se encuentra un $0$, lo deja igual, se queda en el mismo estado y la cabeza lectora sigue corriendo a la izquierda.
\item[$\textvisiblespace x\overset{\leftarrow}{q_4} 0x \textvisiblespace$] Seguimos en el estado $q_4$, la cabeza lectora corre hacia la izquierda y se encuentra una $x$, la deja igual, se queda en el mismo estado y la cabeza lectora sigue corriendo a la izquierda.
\item[$\textvisiblespace \overset{\leftarrow}{q_4} x0x \textvisiblespace$] En el estado $q_4$, la cabeza corre hacia la izquierda y se encuentra el espacio vacío del inicio de la cadena (el primer cero que convertimos en un $\textvisiblespace$), entonces pasa al estado $q_1$, la cabeza empieza a correr a la derecha y deja el espacio como estaba.
\item[$\textvisiblespace \overset{\rightarrow}{q_1} x0x \textvisiblespace$] Ahora en el estado $q_1$ la cabeza corriendo a la derecha se halla una $x$ (un cero que marcamos en un paso anterior), se queda en el mismo estado, la cabeza corre a la derecha y no se cambia nada en la cinta.
\item[$\textvisiblespace x\overset{\rightarrow}{q_1}0x \textvisiblespace$] Estamos en el estado $q_1$, la cabeza lectora corre hacia la derecha, donde halla un $0$, lo cambia por un $x$ (lo marca), pasa al estado $q_2$.
\item[$\textvisiblespace xx\overset{\rightarrow}{q_2}x \textvisiblespace$] Ahora en el estado $q_2$ la cabeza corriendo a la derecha se halla una $x$ (un cero que marcamos en un paso anterior), se queda en el mismo estado, la cabeza corre a la derecha y no se cambia nada en la cinta.
\item[$\textvisiblespace xxx\overset{\rightarrow}{q_2} \textvisiblespace$] Llegamos al final de la palabra, estamos en el estado $q_2$, cuando esto pasa se va al estado $q_4$, deja igual escrito el espacio vacío y la cabeza lectora empieza a correr ahora hacia la izquierda.
\item[$\textvisiblespace xxx\overset{\leftarrow}{q_4} \textvisiblespace$] En el estado $q_4$, la cabeza lectora corre a la izquierda, se encuentra una $x$, no la altera, se queda en el mismo estado y la cabeza sigue corriendo a la izquierda.
\item[$\textvisiblespace xx\overset{\leftarrow}{q_4}x \textvisiblespace$] Lo mismo del inciso anterior.
\item[$\textvisiblespace x\overset{\leftarrow}{q_4}xx \textvisiblespace$] Lo mismo del inciso anterior.
\item[$\textvisiblespace \overset{\leftarrow}{q_4}xxx \textvisiblespace$] Llegamos a la orilla izquierda de la cadena, se pasa al estado $q_1$ y la cabeza corre a la derecha.
\item[$\textvisiblespace \overset{\rightarrow}{q_1} xxx \textvisiblespace$] Ahora en el estado $q_1$ la cabeza corriendo a la derecha se halla una $x$ (un cero que marcamos en un paso anterior), se queda en el mismo estado, la cabeza corre a la derecha y no se cambia nada en la cinta.
\item[$\textvisiblespace x\overset{\rightarrow}{q_1}xx \textvisiblespace$] Lo mismo del inciso anterior.
\item[$\textvisiblespace xx\overset{\rightarrow}{q_1}x \textvisiblespace$] Lo mismo del inciso anterior.
\item[$\textvisiblespace xxx\overset{\rightarrow}{q_1} \textvisiblespace$] Estamos en $q_1$, la cabeza corre a la derecha y se encuentra un espacio vacío, la máquina pasa al estado de aceptación y ya no importa que pase con la cabeza lectora y la cinta, ya llegó a su fin la máquina y la cadena fue aceptada.
\item[$\textvisiblespace xxx\textvisiblespace r$] Fin, cadena aceptada.
\end{itemize}
Prueben con cadenas más grandes, pero ya se pueden dar una idea de como funciona la máquina, es un proceso recursivo que va dividiendo a mitades la cadena y checando que cada mitad tenga la longitud igual a una potencia de $2$.
\section*{Recomendación de lectura para este encierro}
Les dejo una recomendación para leer, no es un libro de ciencia ni de texto, menos divulgativo, es una novela policiaca.
Quizá conozcan una famosa serie de películas y novelas suecas, con \emph{remake} estadounidense y una más reciente película que según dicen no se apega a la historia original, llamada Milennium: "Los hombres que no amaban a las mujeres", "La chica que soñaba con una cerilla y un bidón de gasolina", "La reina en el palacio de las corrientes de aire" (estas tres novelas son de Stieg Larsson, periodista y escritor sueco, también fueron hechas película en Suecia, y la primera tiene una version estadounidense, aunque grabada en Suecia, valen la pena), "Lo que no te mata te hace más fuerte", "El hombre que perseguía su sombra" y "La chica que vivió dos veces" (estas últimas tres el autor original no las terminó, falleció incluso antes de que se publicaran las primeras tres, David Lagercrantz fue el escritor designado por la editorial para terminar la serie, de estas últimas tres hubo una supuesta adaptación no muy clara).
Son novelas policiacas que al parecer son muy populares en Suecia, a diferencia de las series y películas policiacas de Estados Unidos (y otros países que los siguen muy de cerca) los héroes no son detectives o policías honestos y honrados, o que de menos caigan bien (eso no suele suceder en la mayoría de países), son periodistas, y en esta serie en específico, un periodista y una \emph{hacker}. Yo no he leído estas novelas, son muy extensas, quizá algún día. Lo interesante aquí es el autor de las últimas tres.
David Lagercrantz fue elegido por la editorial, en una maniobra plenamente comercial, para terminar la serie dado el éxito de un libro policiaco que escribió antes: "El enigma de Turing". Recabando algunos datos históricos, incluso con una excelente y muy bien explicada sección sobre el \emph{Entscheidungsproblem}, Lagercrantz altera un poco la historia para contarla como una novela policiaca, donde Turing aparece en las anécdotas y las historias referentes a él (no es un personaje activo en la novela).
La novela, muy al gusto Sueco diría yo, es algo extensa, muy rica en descripciones, en generar el ambiente (en ocasiones se aleja demasiado de la historia para contar cosas aparentemente secundarias) pero al final justo salta la intriga, hay un poco de acción aunque no hay pistolas y solo un poco de sangre. Hay una adaptación cinematográfica, que no es mala, aunque un poco absurda en ciertas cosas, la novela es mucho mejor y va más allá de lo que cuenta la película.
Dirán: "Si bueno, mucha recomendación, ¿pero de donde la voy a sacar? Ha de ser costosa (seguramente es edición española), quién sabe si haya en las librerías cerca de casa y prefiero no salir a buscarla". Eso no es problema, si les interesa y tiene la posibilidad de leer en un lector electrónico, su celular o tableta (hay aplicaciones o en la misma configuración que les ayuda a hacer más tolerable la luz de la pantalla) o en la computadora (asegúrense de descansar la vista) yo se las presto muy amablemente, de cuates (no somos piratas porque no robamos barcos, yo ni nadar sé, no le robamos nada a nadie), el libro electrónico.
Descarguen el libro de: \url{https://www.dropbox.com/s/f010wkl7usewzet/Lagercrantz%2C%20David%20-%20El%20enigma%20Turing%20%5B36660%5D%20%28r1.2%29.epub?dl=0}. Esta en formato epub, hay varias aplicaciones libres para celular, tableta y computadora para leerlo.
\begin{thebibliography}{10}
\bibitem{Kozen} Kozen, Dexter C. ``Automata and Computability'' Springer (1997)
\bibitem{Sipser} Sipser, Michael ``Introduction to the Theory of Computation'' 2a ed., Thomson Course Tecnology (2006)
\end{thebibliography}
\end{document}

BIN
maquinas_turing_2.pdf Normal file

Binary file not shown.

209
maquinas_turing_2.tex Normal file
View File

@ -0,0 +1,209 @@
\documentclass[10pt,a4paper]{article}
\usepackage[utf8]{inputenc}
\usepackage[spanish]{babel}
\usepackage{amsmath}
\usepackage{amsfonts}
\usepackage{amssymb}
\usepackage{hyperref}
\usepackage{graphicx}
\usepackage{subcaption}
\usepackage{pgf}
\usepackage{tikz}
\usetikzlibrary{automata,positioning,arrows}
%\tikzset{->, % makes the edges directed
% >=stealth, % makes the arrow heads bold
% node distance=3cm, % specifies the minimum distance between two nodes. Change if necessary.
% every state/.style={thick, fill=gray!10}, % sets the properties for each state node
% initial text=$ $ % sets the text that appears on the start arrow
% }
%\usetikzlibrary{arrows,automata}
%\usepackage[all,cmtip]{xy}
%\usepackage{graphicx}
\author{Autómatas y lenguajes formales}
\title{Máquinas de Turing 2a parte}
\begin{document}
\maketitle
\section{Reducción}
Quería irme directo al teorema de Rice, pero necesitamos saber un poco de reducción. Como ya habrán visto en su camino por la facultad en las matemáticas se trata de buscar problemas similares a uno que ya se haya resuelto, ver como reducirlo al ya resuelto y no hacer más, pues si un problema puede por pasos sencillos convertirse en uno que ya resolvieron prácticamente ya está resuelto también.
Antes de resolver, si se sabe de antemano que hay un problema que busquemos por donde busquemos no tiene solución, reducir nos puede indicar problemas similares que tampoco tienen solución.
Del texto anterior recordemos las definiciones:
\newtheorem{defi}{Definición}
\begin{defi}
Un conjunto es \emph{recursivamente enumerable} (r.e.) si el $L(M)$ para alguna máquina de Turing $M$, es decir $L(M)$ es el conjunto de cadenas aceptadas por la máquina $M$, entonces el conjunto $L$ es \emph{recursivamente enumerable} si es aceptado por alguna máquina de Turing $M$.
\end{defi}
\begin{defi}
Un conjunto es \emph{recursivo} (r.) si el $L(M_T)$ para alguna máquina de Turing total $M_T$. Una máquina de Turing total es aquella que acepta o rechaza todas las cadenas, sin nunca entrar a un ciclo infinito.
\end{defi}
Y una definición extra que no estaba en las notas pasadas:
\begin{defi}
Un conjunto es \emph{co-recursivamente enumerable} (co-r.e.) si su complemento es recursivamente enumerable.
\end{defi}
Dado que el problema de la detención ($HP$) es un problema que sabemos es indecidible, y hasta podríamos considerarlo el ejemplo paradigmático (aquí hablo muy informalmente), la idea es reducir el problema de la detención, que sabemos indecidible, a algún otro para ver que al igual es indecidible.
\begin{defi}
Dados los conjuntos $A\subseteq \Sigma^*$ y $B\subseteq \Delta^*$, una (muchos-uno) reducción de $A$ a $B$ es una función computable:
\begin{equation*}
\sigma: \Sigma^* \rightarrow \Delta^*
\end{equation*}
tal que para toda $x\in \Sigma^*$ si:
\begin{equation*}
x\in A \iff \sigma(x)\in B
\end{equation*}
\end{defi}
Si recuerdan en unas notas pasadas que hablamos del homomorfismo, $\sigma$ es algo similar, toda cadena en $A$ va a una cadena a $B$ bajo $\sigma$, aunque en este caso la función no requiere ser sobre o uno a uno, basta con que sea total y efectivamente computable. No considero necesario ahondar mucho en ello a esta altura, pero si no, pregunten.
Cuando se cumple lo de la definición decimos que $A$ es reducible a $B$ a través del mapeo $\sigma$, lo que para escribir en corto se pone como $A\leq_m B$. La $m$ hace referencia a muchos-uno (\textit{many-one}), ya que no es sobre ni uno a uno, identifica a esta relación.
Un teorema que será de ayuda pronto:
\newtheorem{teo}{Teorema}
\begin{teo}
Sean $A$ y $B$ dos conjuntos, tenemos:
\begin{enumerate}
\item Si $A\leq_m B$ ($A$ es reducible a $B$) y $B$ es un conjunto recursivamente enumerable, entonces $A$ también lo es. De manera equivalente si $A\leq_m B$ y $A$ no es un conjunto recursivamente enumerable, entonces $B$ tampoco lo es.
\item Si $A\leq_m B$ y $B$ es un conjunto recursivo, entonces $A$ también lo es. De manera equivalente si $A\leq_m B$ y $A$ no es un conjunto recursivo, entonces $B$ tampoco lo es.
\end{enumerate}
\end{teo}
Usando lo visto hasta ahora para un ejemplo, sea el conjunto
\begin{equation}
FIN = \{ M | L(M) \text{ es finito} \}
\end{equation}
Ni este conjunto ni su complemento son recursivamente enumerables. Como se imaginarán la idea es reducir el problema de la detención a ambos conjuntos, aunque ahora nos conviene reducir su complemento, que se escribe $\sim HP$. Tenemos
\begin{equation*}
\sim HP = \{ M\#x\ |\ M \text{ no se detiene con } x \}
\end{equation*}
Que se reducirá a ambos conjuntos
\begin{enumerate}
\item $\sim HP \leq_m FIN$,
\item $\sim HP \leq_m \sim FIN$
\end{enumerate}
De tener estas reducciones, por el teorema arriba mencionado ya tendríamos la demostración. Sabemos que $HP$ no es recursivamente enumerable, tampoco su complemento, ello implicaría que ni $FIN$ ni su complemento serían recursivamente enumerables.
Vamos a construir un mapeo que vaya de las cadenas aceptadas por $\sim HP$, es decir, de $M\# x$ a cadenas en $FIN$, que las vamos a denotar como $\sigma(M\# x)$, de esta forma construiremos la máquina de Turing a la que le daremos como entrada el conjunto finito, es decir
\begin{align*}
M'&=\sigma(M\# x) \\
\text{Si } M \text{ no se detiene con }x &\iff L(M') \text{ es finito}
\end{align*}
Dada $M\# x$ construimos $M'$ tal que al darle como entrada $y$ sucede:
\begin{enumerate}
\item borra la entrada $y$
\item escribe en la cinta la cadena $x$ ($x$ ya está guardada en la máquina $M'$, solo es traída de memoria y se pone en la cinta para manipularla)
\item corre la máquina $M$ (también guardada en alguna parte de la memoria de $M'$) con entrada $x$
\item la cadena y es aceptada si $M$ se detiene con $x$
\end{enumerate}
Entonces si en el paso tres la máquina $M$ no se detiene con $x$, la máquina $M'$ tampoco se detiene, no sigue al paso 4, no acepta $y$, sea lo que sea $y$, el conjunto que acepta es el vacío. Si por el contrario la máquina $M$ se detiene con $x$ la máquina $M'$ sigue al paso cuatro y acepta $y$ (no importa que sea $y$, ya hasta la borramos y aún así la acepta). Como acepta cualquier $y$ pues entonces es un conjunto infinito de cadenas ($y\in \Sigma^*$). Resumiendo:
\begin{align*}
M \text{ se detiene con }x &\implies L(M')= \Sigma^* \implies L(M') \text{ es infinito} \\
M \text{ no se detiene con }x &\implies L(M')= \emptyset \implies L(M') \text{ es finito}
\end{align*}
Como pueden ver $M'$ depende del problema de la detención, que la máquina $M$ se detenga con la cadena $x$, como ese problema no es recursivamente enumerable, entonces el problema de saber si la máquina que acepta las cadenas de un lenguaje finito tampoco es recursivamente enumerable.
Lo que hicimos fue construir una máquina que reducía el complemento del problema de detención en el problema de aceptar cadenas finitas $\sim HP\leq_m FIN$ (cuando $M$ no se detiene entonces $M'$ acepta cadenas de un lenguaje finito, en particular el conjunto vacío). Por lo tanto ya que el complemento del problema de detención, que no es recursivamente enumerable, se reduce al problema dado, entonces este tampoco es recursivamente enumerable.
Lo mismo se puede hacer para $\sim HP$.
\section*{Teorema de Rice}
En cada conjunto \emph{recursivamente enumerable} podemos definir una propiedad
\begin{defi}
Una propiedad de un conjunto \emph{recursivamente enumerable} es un mapeo del tipo:
\begin{equation*}
P:\{subconjuntos\ r.e.\ de\ \Sigma^*\}\rightarrow \{\top,\bot\},
\end{equation*}
\end{defi}
Donde $\top$ se refiere a verdadero y $\bot$ a falso, asignaciones lógicas. Un ejemplo de estas propiedades sería:
\begin{equation*}
P(A) =
\begin{cases}
\top & \quad \text{si } A =\emptyset \\
\bot & \quad \text{si } A \neq \emptyset
\end{cases}
\end{equation*}
Es decir, saber si un conjunto (no una máquina) es vacío, por ejemplo, si yo digo que $A$ es el conjunto recursivamente enumerable (que lo puedo meter a una máquina de Turing y acepta o rechaza) de las cadenas de longitud $n$, esta propiedad me diría si tal conjunto es vacío o no.
\begin{teo}
(Teorema de Rice) Toda propiedad no trivial de un conjunto \emph{recursivamente enumerable} es indecidible.
\end{teo}
Para poder inspeccionar estas propiedades lo hacemos a través de una máquina de Turing, las propiedades deben estar escritas de tal forma que sean una cadena aceptada por una máquina.
Pero una parte importante es saber qué es no trivial y qué no lo es. En este caso no trivial es que la propiedad no sea universalmente falsa ni universalmente verdadera, es decir, que al menos existe un conjunto que cumple la propiedad y al menos uno que no la cumple.
Para entender un poco mejor esto veamos la demostración:
\newtheorem{dem}{Demostración}
\begin{dem}
Sea $P$ una propiedad no trivial de un conjunto recursivamente enumerable, supongamos, sin perder generalidad, que esta propiedad es falsa para un conjunto vacío, $P(\emptyset) = \bot$ (bien podría ser cierta e igual se puede continuar la demostración, esta decisión es, como se imaginarán, para tener definido el caso base). Como ya dijimos que $P$ es no trivial entonces existe al menos un conjunto $A$ para el cual la propiedad es verdadera, $P(A)=\top$. Sea $K$ la máquina de Turing que acepta el conjunto $A$.
Como ya lo hemos hecho antes, vamos a apoyarnos del problema más famoso de indecibilidad, el problema de la detención (\textit{halting problem} HP), para ver que esta propiedad tampoco es decidible. Vamos a escribir HP de forma reducida como $\{ M | P(L(M)) = T \}$, es decir, todas las máquinas $M$ tales que su conjunto recursivamente enumerable asociado tiene dicha propiedad como verdadera.
Construimos una máquina $M'$ relacionada a la máquina $M$ de la forma $M'= \sigma (M\# x)$ ($M'$ es una variante de $M$ a la que además se le ha anexado una cadena $x$, en la definición de $M'$ de incluye, de alguna manera, la definición de $M$ y una cadena estática $x$).
Hasta aquí ya llevamos tres máquinas definidas, $K$ que al momento no hemos dicho como va a usarse, $M$ que son las máquinas que aceptan como lenguaje el conjunto para el cual la propiedad es verdadera, y $M'$ la máquina definida a partir de una $x$ y la descripción de la máquina $M$, desbaratemos un poco el nudo viendo más de la construcción de $M'$.
Cuando a la máquina $M'$ se le da como entrada la cadena y sucede lo siguiente:
\begin{enumerate}
\item guarda $y$ en algún lugar separado de la cinta
\item escribe $x$ en la cinta ($x$ ya estaba guardada en algún lugar de la máquina, por ejemplo una cinta e sólo lectura, en este paso es puesta en la cinta en la que se puede manipular)
\item corre $M$ para la entrada $x$ (igual, $M$ es traída desde algún lugar de la memoria de la máquina $M'$, esto no se le da en la entrada)
\item si $M$ se detiene en $x$ (recuerden que es una descripción de H.P.) ahora $M'$ corre $K$ con $y$ como entrada y acepta sí $K$ acepta.
\end{enumerate}
Aquí el paso crucial es el tercero, $M$ puede detenerse o no con $x$ (si $x$ no cumple la propiedad la máquina no se detiene). Si $M$ no se detiene con $x$ en el paso cuatro $M'$ rechaza la entrada $y$ (no tiene que correr a $K$, sólo rechaza). En cambio, si $M$ se detiene con $x$ se pasa al paso cuatro, se le da $y$ como entrada a $K$, esta $y$ es aceptada por $M'$ si es aceptada por $K$.
Las opciones se ven así:
\begin{align*}
M \text{ se detiene con }x &\implies L(M')= A \implies P(L(M')) = P(A) = \top \\
M \text{ no se detiene con }x &\implies L(M')= \emptyset \implies P(L(M')) = P(\emptyset) = \bot
\end{align*}
Como en el ejemplo de la sección anterior hemos reducido el problema de la aceptación a este problema, es decir $HP\leq_m \{ M\ |\ P(L(M))=\top \}$, por el teorema de la sección anterior entonces $\{ M\ |\ P(L(M))=\top \}$ tampoco es recursivo, entonces el lenguaje que satisface la propiedad $P$ tampoco es recursivo (pero si es recursivamente enumerable, eso ya lo tenia por default), por ende tampoco es decidible.
\end{dem}
Pero hay una parte dos de este teorema, porque el primero fue un éxito en taquilla... no, porque es una cosa un poco más específica, para propiedades monótonas.
\begin{defi}
Una propiedad $P: \{\text{Conjuntos r.e.}\} \rightarrow \{ \top,\bot \}$ de los conjuntos recursivamente enumerables es monótona si para todos los conjuntos r.e. $A$ y $B$, si $A\subseteq B$ entonces $P(A)\leq P(B)$, donde el orden se especifica como $\bot\leq \top$. Para ponerlo menos revuelto, todo subconjunto de un conjunto más grande hereda sus propiedades.
\end{defi}
Por ejemplo $FIN$ que vimos en la sección anterior es monótono, todo subconjunto es finito también. Vamos al teorema.
\begin{teo}
Ninguna propiedad monótona de un conjunto recursivamente enumerable (r.e.) es semidecidible. Es decir, si $P$ es una propiedad no-monótona de conjuntos r.e., entonces el conjunto $T_P = \{ M\ |\ P(L(M))=\top \}$ no es recursivamente enumerable.
\end{teo}
Ya de ese más o menos pueden hacer la demostración.
\begin{thebibliography}{10}
\bibitem{Kozen} Kozen, Dexter C. ``Automata and Computability'' Springer (1997)
\bibitem{Sipser} Sipser, Michael ``Introduction to the Theory of Computation'' 2a ed., Thomson Course Tecnology (2006)
\end{thebibliography}
\end{document}

BIN
otros_modelos.pdf Normal file

Binary file not shown.

247
otros_modelos.tex Normal file
View File

@ -0,0 +1,247 @@
\documentclass[10pt,a4paper]{article}
\usepackage[utf8]{inputenc}
\usepackage[spanish]{babel}
\usepackage{amsmath}
\usepackage{amsfonts}
\usepackage{amssymb}
\usepackage{hyperref}
\usepackage{graphicx}
\usepackage{subcaption}
\usepackage{pgf}
\usepackage{tikz}
\usetikzlibrary{automata,positioning,arrows}
%\tikzset{->, % makes the edges directed
% >=stealth, % makes the arrow heads bold
% node distance=3cm, % specifies the minimum distance between two nodes. Change if necessary.
% every state/.style={thick, fill=gray!10}, % sets the properties for each state node
% initial text=$ $ % sets the text that appears on the start arrow
% }
%\usetikzlibrary{arrows,automata}
%\usepackage[all,cmtip]{xy}
%\usepackage{graphicx}
\author{Autómatas y lenguajes formales}
\title{Otros formalismos}
\begin{document}
\maketitle
\section{Los otros modelos}
Ahora que estamos a la distancia y nos parece tan lejana la vida en la facultad (en algunas cosas para bien, en otras no) iniciaré esta nota con una anécdota. Tuve en la facultad un profesor de geometría y álgebra lineal que aún está ahí en el departamento de matemáticas. En su época de estudiante de ciencias la costumbre era estudiar las dos carreras de física y matemáticas (ya ven que en la facultad casi no se da eso), él por ser parte del ``hype'' entró a ambas carreras, originalmente estudiaba física.
Como era de esperar la demanda de tiempo y trabajo era demasiada, a medio semestre ya estaba flaco, ojeroso y sin ilusiones, no soportó tanto y decidió abandonar una carrera. Lo raro fue que no decidió abandonar la carrera extra, que era matemáticas, prefirió renunciar a física. Sus razones eran las siguientes: la ventaja de la matemática sobre la física es que puedes tomar varios caminos, el que te agrade, el que se te ocurra, y llegar al resultado, más de uno de esos caminos es correcto. En cambio en la física es todo más rígido, hay un sólo camino (por lo regular) y no hay mucha posibilidad para cambiar la ruta.
Esto se debe mucho a la experiencia que tuvo este profesor en ese entonces estudiante, seguro hay áreas de la física que dan libertad. Pero en lo que concuerdo completamente es que en las matemáticas hay un poco más de libertad para enfrentar un problema, más de una persona puede llegar al resultado correcto por caminos distintos y ser válido. Lo mismo sucede en teoría de la computación (que como han podido ver en este y otros cursos tiene un origen en común con las matemáticas), no sólo hay un único modelo computacional.
Ahora, sí yo quisiera hacer otro modelo ¿cómo podría saber que es correcto? '¿Cómo saber que en efecto estos modelos distintos hacen lo mismo? La idea de base es la \emph{computabilidad efectiva}, el rasgo en común que tienen estos modelos. La tesis de Church-Turing (que es más una afirmación) dice:
\newtheorem{church}{Tesis de Church-Turing}
\begin{church}
Toda función es calculable efectivamente sí y sólo sí es calculable por una máquina de Turing.
\end{church}
Aquí van a decir que ya cayó más pronto un hablador que un cojo, hay una posición preferente a la máquina de Turing ¿no que muy incluyente? Es cierto, la máquina de Turing tiene una posición preferente, de acuerdo al texto por su simplicidad y claridad, pero todos los modelos equivalentes pueden representarse por una máquina de Turing, entonces, como lo hemos hecho en el curso, la máquina de Turing es la que tomamos como paradigma, pero los formalismos que veremos son equivalentes. Si para ustedes no fue tan claro y les queda más claro por estos modelos, entonces podrán decir que se toma la máquina de Turing por pura formalidad. Lo que veremos en estas opciones es que en algunos casos son más parecidos a un lenguaje de programación de los que ahora usamos.
\section{Funciones recursivas $\mu$}
Una buena pregunta sería, ¿cuál es el mínimo de funciones necesarias para definir a todas las funciones computables? ¿Cuáles son las funciones de ese conjunto mínimo? De acuerdo a Gödel esas funciones numérico-teóricas ${\mathbb{N}}^k \rightarrow \mathbb{N} $ son:
\begin{enumerate}
\item \emph{Sucesor}. La función $\mathbf{s}:\mathbb{N} \rightarrow \mathbb{N}$ dadas por $\mathbf{s}(x)=x+1$ es computable.
\item \emph{Cero}. La función $\mathbf{z}: \mathbb{N}^0 \rightarrow \mathbb{N}$ dada por $\mathbb{z}()=0$ es computable.
\item \emph{Proyecciones}. Las funciones $\pi_k^n: \mathbb{N}^n \rightarrow \mathbb{N}$ dadas por $\pi_k^n(x_1,...,x_n) = x_k,\ 1\leq k \leq n$, son computables.
\item \emph{Composición}. Si $f:\mathbb{N}^k \rightarrow \mathbb{N}$ y $g_1,...g_k:\mathbb{N}^n \rightarrow \mathbb{N}$ son computables, entonces también lo es la función $f\circ (g_1,...,g_k):\mathbb{N}^n \rightarrow\mathbb{N}$ que en la entrada $\overline{x}= x_1,...,x_n$, da
\begin{equation*}
f(g_1(\overline{x}),...,g_k(\overline{x}))
\end{equation*}
\item \emph{Recursión primitiva}. Si $h_i:\mathbb{N}^{n} \rightarrow \mathbb{N}$ y $g_i:\mathbb{N}^{n+k+1} \rightarrow \mathbb{N}$ son computables, $1\leq i \leq k$, entonces también lo son las funciones $f_i:\mathbb{N}^{n+1} \rightarrow \mathbb{N},\ 1\leq i \leq k$, definidas por inducción mutua de la siguiente manera:
\begin{align*}
f_i(0,\overline{x}) &\overset{def}{=} h_i(x) \\
f_i(x+1,\overline{x}) &\overset{def}{=} g_i(x,\overline{x},f_1(x,\overline{x}),...,f_k(x,\overline{x})),
\end{align*}
donde $\overline{x}=x_1,...,x_n$.
\item \emph{Minimización no acotada}. Si $g:\mathbb{N}^{n+1} \rightarrow \mathbb{N}$ es computable, entonces también lo es la función $f:\mathbb{N}^n \rightarrow $ que con la entrada $\overline{x}=x_1,...,x_n$ de al menos $y$ tal que $g(z,\overline{x})$ esté definida para todas las $z\leq y$ y $g(y,\overline{x})=0$ si tal $y$, y está indefinida de otra manera. Esto se denota como:
\begin{equation*}
f(\overline{x})=\mu y.(g(y,\overline{x})=0)
\end{equation*}
\end{enumerate}
Algunas de estas funciones suenan demasiado enredadas, pero vamos viendo por pasos. Las primeras cuatro parecen bastante directas, el \emph{sucesor} nos da la posibilidad de construir cualquier número a partir de una base, e incluso nos es útil para definir operaciones más complicadas, como la suma de dos o más números, la multiplicación, el factorial (no se preocupen, lo vamos viendo). La operación lo que hace es sumar un $1$ al número que se le dé como entradad a la función.
La función \emph{cero}, $\mathbf{z}$, construye nuestro primer número, el cero, sin necesidad de una entrada, a partir de él podemos construir los demás naturales. La función \emph{proyección},$\pi_k^n$ elige el elemento $k$ (esta enumeración va de acuerdo a su posición en la lista) de una lista de $n$ elementos. Y la función \emph{composición} hace la composición que ya conocemos de dos funciones, así podemos componer \emph{proyección} con \emph{sucesor}, de forma que al elemento $k$ le sumemos un $1$ y eso de como resultado.
\begin{equation*}
s(\pi_k^n(\overline{x}))=x_k+1.
\end{equation*}
Para poder definir funciones más complicadas necesitamos de la recursión primitiva, aquí ya empieza a sonar a lenguaje de programación. Veamos como podemos armar la suma con estas funciones.
Vamos a llamarle la función $suma(x)$ y vamos a ponerla en forma de recursión primitiva. Siguiendo los pasos del quinto punto debemos tener una $h$ y una $g$. Sea $h=\pi_1^1$, la proyección de una lista de un miembro en la posición $1$ (no hace nada esta función más que darnos el mismo número que le hemos dado) y sea $g=\mathbb{s}\circ \pi_3^3$ la composición de la función sucesión con la proyección del tercer miembro de una lista de $3$. Noten que la función $h:\mathbb{N} \rightarrow \mathbb{N}$, va de la dimensión uno a la dimensión uno, $n=1$, y $g: \mathbb{N}^3 \rightarrow \mathbb{N}$, notemos que como $n=1$, entonces $k=1$ y así $n+k+1=3$.
¿Porqué se eligieron así las funciones? Para verlo lo ponemos en la forma de la recursión primitiva, \emph{suma} será nuestra función $f_i$, como $1 \leq i \leq k$ y en nuestro caso $k=1$ entonces $i=1$, sólo hay una $f=suma$:
\begin{align*}
suma(0,y) &\overset{def}{=} h(y) = \pi_1^1(y) = y \\
suma(x+1,y) &\overset{def}{=} g(x,y,suma(x,y)) = s(\pi_3^3(x,y,suma(x,y))) = s(suma(x,y))
\end{align*}
Y ahí con recursión se puede llegar a suma de cualquier par de números.
Ahora, a partir de la suma definimos la multiplicación:
\begin{align*}
mult(0.y) &\overset{def}{=} z() =0 \\
mult(x+1,y) &\overset{def}{=} suma(y,mult(x,y))
\end{align*}
De nueva cuenta hay una recursión inmiscuida para hacer cualquier operación.
Se dan una idea de cómo hacer más cosas ¿cierto? Ahora de tarea, para todxs lxs gamers, hagan el \textit{The Last of us} con puras funciones recursivas, debe quedarles algo como en la figura \ref{fig:lou}.
\begin{figure}[h!]
\begin{center}
\includegraphics[width=0.5\linewidth]{last_of_us.png}
\caption{\textit{The Last of Us} en 8 bits. Imagen de Rgznsk, tomada de: \url{https://www.it8bit.com/post/158114971533/the-last-of-us-pixel-art-created-by-rgznsk}}
\label{fig:lou}
\end{center}
\end{figure}
Bueno, después de mi chiste bobo y antes de pasar a cálculo $\lambda$, seguro se preguntarán ¿y la sexta función, la minimización no acotada, dónde se usa? Bueno, esta es una operación que como verán en la descripción está relacionada con hasta que punto está definida la función, esto se puede relacionar con el orden y la búsqueda en listas, no coman ansias, ya lo verán en análisis de algoritmos. Su utilidad es un poco menos intuitiva que las demás funciones, así que en este punto es importante que sepan que existe.
\section*{Calculo $\lambda$}
\emph{Lisp} y sus variaciones (\emph{scheme, common lisp}) son lenguajes de programación muy parecidos al cálculo $\lambda$. Este es el histórico, \emph{lisp} es uno de los lenguajes más antiguos y en verdad ahora se considera una familia. \emph{Haskell} es un lenguaje un poco más moderno (un poco menos moderno que ustedes, data de 1990 su primera versión), esto del calculo $\lambda$ seguro les va a parecer familiar si conocen \emph{haskell} o algún dialecto de \emph{lisp}. Y si son gamers han de saber que el estudio que hace \textit{The Last of Us} inició trabajando con su propio dialecto de \emph{lisp}, que ahora usan menos por cuestiones de portabilidad estando en una empresa más grande, \textit{sony}.
El cálculo $\lambda$ hace uso de un conjunto de objetos llamados $\lambda$-términos y algunas reglas para manejarlos. Por ejemplo, si queremos escribir la función sucesor de las funciones recursivas $\mu$, lo escribiríamos:
\begin{equation*}
\lambda x.(x+1),
\end{equation*}
\noindent que quiere decir "con la entrada $x$ calcula $(x+1)$", es decir, la función sucesor. Al aplicarlo a un número, digamos $4$, se escribiría $(\lambda x.(x+1))4 \rightarrow 4+1=5$. La composición sería:
\begin{equation*}
\lambda x.f(gx),
\end{equation*}
\noindent con la entrada $x$ le aplica $g$ y luego $f$, lo único que se le da como entrada a esta función es $x$; $g$ y $f$ ya están definidas dentro. Si quisiéramos darlas también como entradas de la función entonces se escribiría $\lambda f. \lambda g. \lambda x. f(gx)$. ¿Tienen una idea? Si no, no dejen de preguntar. Ahora veremos una versión refinada que llaman el cálculo $\lambda$ puro.
\section*{Calculo $\lambda$ puro}
En esta variante sólo hay variables y operadores para $\lambda$-abstracciones y aplicaciones. Para construir un $\lambda$-término de manera inductiva a partir de:
\begin{itemize}
\item Cualquier variable $x$ es un $\lambda$-término
\item Si $M$ y $N$ son $\lambda$-términos, entonces $MN$ es un $\lambda$-término (aplicación funcional, $M$ es la función que está a punto de ser aplicada a la entrada $N$)
\item Si $M$ es un $\lambda$-término y $x$ es una variable, entonces $\lambda x.M$ es un $\lambda$-término (abstracción funcional, $\lambda x.M$ es la función que con la entrada $x$ computa $M$).
\end{itemize}
Esto suena mucho a \emph{haskell} y como el mismo formalismo lo menciona, algo abstracto, vamos revisando.
\begin{itemize}
\item La aplicación funcional no es asociativa, y si se escribe sin paréntesis por convención las expresiones se asocian a la izquierda, es decir $MNP=(MN)P$
\item Los $\lambda$-términos sirven como funciones y datos (recuerden lo de universalidad y autoreferencia), de tal manera para definir la función sucesión debemos decodificarla de alguna manera.
\item Si tenemos funciones con más de una variable la podemos definir como:
\begin{equation*}
\lambda x_1 x_2...x_n.M \overset{def}{=} (\lambda x_1.(\lambda x_2.(...(\lambda x_n.M)...))),
\end{equation*}
los paréntesis mantienen el orden y podemos ver el orden de la abstracción.
\end{itemize}
¿Cómo realizamos la codificación del punto $2$? A la sustitución se le llama una $\beta$-reducción y funciona más o menos así: en un término mucho más grande y general se puede tener el subtérmino $(\lambda x.M)N$ puede ser substituido por $M_{[x/N]}$, este término abreviado denota a lo obtenido cuando:
\begin{enumerate}
\item renombrando las variables acotadas de $M$ (las $y$ que se dan como entrada a $M$ como un término $\lambda y$), así ninguna $x$ o $N$ aparezcan como acotadas a $M$. Así evitamos confundir variables.
\item Sustituyendo $N$ para todas las ocurrencias de $x$ en el término resultante (esta realmente es la sustitución, el anterior sólo es un paso previo).
\end{enumerate}
Como pueden ver en el término abreviado cualquier aplicación se hará sobre $M$, $x$ y $N$ van en la bolsa. Lo de renombrar variables en unos casos puede verse como una labor directa, por ejemplo en el término $\lambda y.xy$ podemos renombrar $y$ como $z$ y queda $\lambda z.xz$ que realmente no cambia en nada el término, pero si hubiera una doble aplicación nos ayudaría a diferenciar. Pero veamos un ejemplo, la función que duplica la entrada:
\begin{equation*}
(\lambda x.xx)z \underset{\beta}{\rightarrow} (xx)_{[x:=z]}=zz
\end{equation*}
Comparando con la $\beta$ reducción en esquema: $M$ es $xx$, $N$ es $z$ y $\lambda x$ es ella misma. Una vez que se ha aplicado la $\beta$-reducción el término está en su forma normal. La forma normal se traduce directamente a una función de transición en una máquina de Turing. No todos los términos tienen $\beta$-reducción.
Ahora convirtiendo las funciones recursivas $\mu$ a cálculo $\lambda$:
\begin{align*}
V_{bool} &\overset{def}{=} \lambda xy.x \\
F_{bool} &\overset{def}{=} \lambda xy.y \\
[M,N] &\overset{def}{=} \lambda z.zMN \\
\overline{0} &\overset{def}{=} \lambda x.x \\
\overline{n+1} &\overset{def}{=} [F,\overline{n}] \\
S &\overset{def}{=} \lambda x.[F,x] \\
P &\overset{def}{=} \lambda x.xF \\
C &\overset{def}{=} \lambda x.\overline{0} \\
Cero &\overset{def}{=} \lambda x.xV \\
\pi_i^n &\overset{def}{=} \lambda x_1,...,x_n.x_i \\
Y &\overset{def}{=} \lambda f .(\lambda x.f(xx))(\lambda x.f(xx))
\end{align*}
Con $\overline{0}$ y $\overline{n+1}$ construimos los números naturales (en las funciones recursivas $\mu$ no mostramos el constructor de los número naturales, pero pueden checarlo o intentar hacerlo). $S$ es la función sucesor y por facilidad agregamos la $P$ (predecesor, que también se puede contruir de funciones recursivas $\mu$), $V$ y $F$ los valores booleanos, por ahí también pueden ver la proyección, una función que comprueba si la entrada es igual a cero y da una salida booleana.
¿Para que sirve esa función $Y$? Es para la recursión. Veamos como definiríamos la recursión primitiva en cálculo $\lambda$. Pongamos de ejemplo que tenemos dos funciones $f:\mathbb{N}^k \rightarrow \mathbb{N}$ y un grupo de funciones $g_1,...,g_k: \mathbb{N}^n \rightarrow \mathbb{N}$, hacemos la $\beta$-reducción para estas funciones, entonces $f$ la pasamos a $F$ y las $g_1,...,g_k$ a $G_1,...,G_k$, la composición se escribiría como:
\begin{equation}
\lambda x_1...x_n.F(G_1 x_1...x_n)...(G_k x_1...x_n).
\end{equation}
Con esta base pasamos a la definición de la recursión primitiva (chequen líneas arriba), con las funciones dadas $h:\mathbb{N}^n \rightarrow \mathbb{N}$ y $g: \mathbb{N}^{n+2} \rightarrow \mathbb{N}$ computables que en $\beta$-reducción pasan a $H$ y $G$. Ahora la función recursiva $f:\mathbb{N}^{n+1} \rightarrow \mathbb{N}$ que se define a partir de $h$ y $g$, con sus respectivas $beta$-reducciones:
\begin{equation*}
Y \lambda f. \lambda yx_1...x_n.(Cero\ y)(H x_1...x_n)(G(P y)x_1...x_n(f(P y)x_1...x_n)).
\end{equation*}
Con esta estructura podemos construir la suma de forma recursiva en cálculo $\lambda$ (nuestra función $f$ será $SUMA$):
\begin{align*}
H &\overset{def}{=} \lambda x_1.x_1 \\
G &\overset{def}{=} \lambda z,x_1,x_2 . S((\lambda x_1,x_2,x_3 .x_3)zx_1x_2) \\
SUMA &\overset{def}{=} Y \lambda f. \lambda yx.(Cero\ y)(H x)(G(P y)x(f(P y)x)).
\end{align*}
Esto lo pueden ver sólo de sustituir en la estructura de arriba, tomando en cuenta que $k=1$ y $n=1$, es decir, sólo hay una $x$.
De manera similar pueden convertir la minimización no acotada.
\section*{Programas While}
De nueva cuenta nos movemos a terrenos más conocidos de la programación, para ello definimos un lenguaje de programación sencillo.
\begin{enumerate}
\item asignación simple: $x:=0,\ x:=y+1,\ x:=y$
\item composición secuencial: $p:q$
\item condicional: $if\ x<y\ then\ p\ else\ p$
\item $for$ en ciclos: $for\ y\ do\ p$
\item $while$ en ciclos: $while\ x<y\ do\ p$
\end{enumerate}
\noindent con las relaciones $<,>,\leq,\geq, =, \neq$ intercambiables en los puntos 3 y 5.
Ya saben como funciona el $for$ y $while$, que incluso hasta cierto grado son intercambiables salvo que los programas con $for$ se detienen y el $while$ puede no detenerse y entrar en un ciclo infinito. Eso suena a una máquina de Turing bastante general y por eso nos centraremos en él.
Un estado o ambiente $\sigma$ es una asignación de un número natural a cada variable en el conjunto \textbf{Var}. Al conjunto de los ambientes le llamaremos \textbf{Env}. Al ejecutar el programa las variables irán cambiando, por lo que los ambientes también, pero todo dentro de los conjuntos definidos. En un programa las variables van cambiando, las asignaciones son dinámicas, entonces un programa es una función parcial que va de un ambiente a otro $[[p]]:\mathbf{Env} \rightarrow \mathbf{Env}$. Si el programa se detiene el ambiente final será $[[p]]\sigma$, de no detenerse esto no estará definido.
En este formalismo un programa $while$ se definiría a partir de $\sigma \in \mathbf{Env}$, $x \in \mathbf{Var}$ y $a \in \mathbb{N}$, siendo el ambiente $\sigma[x\leftarrow a]$ (el ambiente idéntico $\sigma$ excepto por el valor $x$ que es $a$). Formalmente:
\begin{align*}
\sigma[x\leftarrow a](y) &\overset{def}{=} \sigma (y) \textbf{ sí y no es x}\\
\sigma[x\leftarrow a](y) &\overset{def}{=} a
\end{align*}
\section*{Extra}
Ahora les van recomendaciones de libros que pueden descargar desde internet:
\emph{Editorial Tumbona}. Es una editorial independiente mexicana dedicada a el ensayo en su mayor parte. Es muy recomendable su colección \textbf{Versus} de ensayos cortos, entre ellos está un compendio llamado \textit{Contra el Copyright} con textos de Richard Stallman y la colectividad Wu Ming. De ahí debió nacer la idea de compartir varios de sus títulos, no sólo de esa colección. Muy recomendable \textit{Contra el copyright} y también \textit{Contra la televisión} de Heriberto Yépez, autor tijuanense. Quizá ya hoy en día la televisión esté muy superada, pero es un libro interesante donde el autor desarrolla sus ideas sobre el daño que la televisión le ha hecho a la sociedad mexicana, le llama la \emph{telefísica}. Echen un ojo al catálogo y llévense el que les agrade, como decía, los ensayos de \textbf{Versus} son cortos por lo que no será tan incómodo leerlos con pausas en una pantalla. La página es: \url{http://tumbonaediciones.com/descarga-de-libros/}.
\emph{Crunch editores}. Era una editorial mexicana dedicada a editar puros libros electrónicos, en un principio en pdf, después ya en epub. Su página oficial ya no existe y los libros sólo se encuentran en el \emph{internet archive}, por suerte siempre fueron gratis y de libre distribución. Les recomiendo \textit{La gente se droga} de otro escritor de Tijuana, Rafa Saavedra. Es un libro muy corto pero bastante experimental, sin perder contenido. Echen un ojo al catálogo, son libros cortos. En el internet archive la búsqueda: \url{https://archive.org/search.php?query=crunch%20editores}.
\emph{Librería del Partido Interdimensional Pirata}. Seguro ya conocen al partido Pirata, con sedes en varios países, desde el principio han estado a favor de compartir libremente la cultura. En su librería hay textos políticos en su mayoría, algunos zines, todo en descarga libre y en varios formatos. Aquí sí no puedo recomendarles nada, he ojeado varios de estos libros, los he empezado a leer, conozco otros de algunos de los autores, pero no puedo decirles más. Si les es útil, quieren conocer estas ideas y seguro si las comparten les dará gusto saber que no son los únicos que piensan así. La página: \url{https://utopia.partidopirata.com.ar/}.
Hay muchos libros que se encuentran en dominio público y valen la pena, es fácil encontrarlos en distintas ediciones electrónicas. \textit{El Juguete Rabioso} del escritor argentino Roberto Arlt es una novela centrada en la vida de un joven a principios del siglo XX, sin mucho futuro, algo molesto con la vida. Anterior a John Fante, me parece una novela muy cercana a \textit{Espera la Primavera Bandinni}, pero en versión latinoaméricana. La historia no es parecida, pero el estilo que posteriormente llamaron realismo sucio me parece ya se notaba desde Arlt. Es un libro más extenso, quizá si llama su atención pueda convenir conseguirlo impreso (debe haber edición ya en editoriales muy baratas), pero por si gustan y tienen la posibilidad pueden bajar la versión escaneada de aquí: \url{https://archive.org/details/RobertoArltElJugueteRabioso}.
\begin{thebibliography}{10}
\bibitem{Kozen} Kozen, Dexter C. ``Automata and Computability'' Springer (1997)
\end{thebibliography}
\end{document}

BIN
turing1.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.8 KiB