\documentclass[10pt,a4paper]{article}
\usepackage[utf8]{inputenc}
\usepackage[spanish]{babel}
\usepackage{amsmath}
\usepackage{amsfonts}
\usepackage{amssymb}
\usepackage{hyperref}
\usepackage{graphicx}
\usepackage{listings}
\usepackage{xcolor}
\usepackage{caption}
\usepackage{pgf}
\usepackage{tikz}
\usetikzlibrary{automata,positioning,arrows}

\definecolor{codegreen}{rgb}{0,0.6,0}
\definecolor{codegray}{rgb}{0.5,0.5,0.5}
\definecolor{codepurple}{rgb}{0.58,0,0.82}
\definecolor{backcolour}{rgb}{0.95,0.95,0.92}
\definecolor{darkblue}{rgb}{0,0,.75}

\lstdefinestyle{mystyle}{
    backgroundcolor=\color{backcolour},   
    commentstyle=\color{codegreen},
    keywordstyle=\color{magenta},
    numberstyle=\tiny\color{codegray},
    stringstyle=\color{codepurple},
    basicstyle=\ttfamily\footnotesize,
    breakatwhitespace=false,         
    breaklines=true,                 
    captionpos=b,                    
    keepspaces=true,                 
    numbers=left,                    
    numbersep=5pt,                  
    showspaces=false,                
    showstringspaces=false,
    showtabs=false,                  
    tabsize=2
}

\lstset{style=mystyle}

\lstloadlanguages{Matlab} %use listings with Matlab for Pseudocode
\lstnewenvironment{PseudoCode}[1][]
{\lstset{language=Matlab,basicstyle=\scriptsize, keywordstyle=\color{darkblue},numbers=left,xleftmargin=.04\textwidth,#1}}
{}

\renewcommand{\rmdefault}{ptm}
%\usepackage[all,cmtip]{xy}
%\usepackage{graphicx}
\author{Programación funcional para la física computacional}
\title{Cálculo $\lambda$ y programación funcional}
\begin{document}
\maketitle
\section*{Máquinas de Turing}

La máquina de Turing es uno de los modelos de computación más usados, 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. Ahora lo mencionó sólo para dar entrada a la idea del cálculo $\lambda$, para entender las cosas. 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. 
		
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 el resto de casillas de la cinta para distinguir que no contienen caracter alguno está pre-escrito el símbolo $\textvisiblespace$. Un esquema ejemplificando esta disposición se muestra en la figura \ref{fig:tur}.

\begin{figure}[h]
  \begin{center}
    \begin{tikzpicture}[every node/.style={block},
        block/.style={minimum height=1.5em,outer sep=0pt,draw,rectangle,node distance=0pt}]
      \node (A) {$a$};
      \node (B) [left=of A] {$\ldots$};
      \node (C) [left=of B] {$\vdash$};
      \node (D) [right=of A] {$\ldots$};
      \node (E) [right=of D] {$\textvisiblespace$};
      \node (F) [above = 0.75cm of A,draw=red,thick] {\textsf Q};
      \draw[-latex] (F) -- (A);
      %\draw[-latex,blue] ($(F.east)!0.5!(A.east)$) -- ++(7mm,0);
      \draw (C.north west) -- ++(-1cm,0) (C.south west) -- ++ (-1cm,0) 
      (E.north east) -- ++(1cm,0) (E.south east) -- ++ (1cm,0);
    \end{tikzpicture}
    \caption{Esquema mecánico de una máquina de Turing.}
  \end{center}
  \label{fig:tur}
\end{figure}

Podemos dar una 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}

\subsection*{Un ejemplo}

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$.

\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}

\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}

\section*{Otros modelos computacionales}

El modelo de máquina de Turing ajusta muy bien para cuando se trabaja de manera teórica con computadoras, pero quizá pueda parecer demasiado mecánico y no se parece a como operamos con computadoras hoy en día. Existen más modelos que sonm equivalentes, sabemos de esa equivalencia por la \textbf{tesis Church-Turing}.

\newtheorem{church}{Tesis de Church-Turing}
\begin{church}
  Toda función es efectivamente calculable sí y sólo sí es calculable por una máquina de Turing.
\end{church}

En esos otros modelos se encuentran las funciones recursivas $\mu$, relacionadas dierctamente al trabajo de Gödel al preguntarse ¿cuál es el mínimo de funciones necesarias para definir a todas las funciones computables?

\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}

\begin{thebibliography}{10}
\bibitem{Thompson1996} Thompson, Simon J.. ``Haskell - the craft of functional programming.'' International computer science series (1996).
\bibitem{VanRoy2009} Van Roy, Peter. ``Programming paradigms for dummies: what every programmer should know.'' (2009).
\bibitem{VanRoy2004} Van Roy, Peter, Haridi, Seif. ``Concepts, Techniques, and Models of Computer Programming''. *The MIT Press*, (2004). ISBN: 0262220695
\bibitem{Kowalski1988} Kowalski, Robert. ``The early years of logic programming'',\textit{Communications of the ACM}, \textbf{31}, 1, (1988).
\bibitem{python_concurrency} \url{https://realpython.com/python-concurrency/}, revisado el 15 de febrero de 2023.
  
\end{thebibliography}

\end{document}
