Maniac, de Benjamín Labatut, es una de esas novelas que consiguen lo raro: convertir ideas abstractas en material literario fascinante. La novela, a medio camino entre la biografía histórica y la divulgación, habla de los límites de las matemáticas, de la irracionalidad, de los horrores tecnológicos y de la historia de la computación, desde la arquitectura von Neumann hasta los éxitos de Alpha Zero. En general está muy bien planteado y de verdad que lo recomiendo. Me lo devoré en pocos días. Pero me parece interesante señalar dos puntos en los que creo que el autor patina. Por un lado, al interpretar el problema de parada de Alan Turing; por otro, al explicar como funciona Sotckfish, el motor de ajedrez. Vamos a ello:
1. Turing y el problema de la parada
En la página 225, pone en palabras ficticias de Nils Aall Barricelli la siguiente afirmación:
“Porque esa es una verdad de la computación que muy pocas personas entienden, pero que Turing probó matemáticamente: no hay manera de saber de antemano lo que hará un código a menos que lo ejecutes.”
La frase suena contundente, atractiva, pero es una mala interpretación del famoso problema de la parada de Turing. Lo que Turing demostró es que no existe un procedimiento general que nos diga, para cualquier programa y cualquier entrada, si ese programa se detendrá o se quedará ejecutándose para siempre.
Eso no significa que no se pueda saber nunca lo que va a hacer un programa. En muchos casos concretos, sí podemos predecir su comportamiento: por inspección directa, con pruebas formales, o incluso con herramientas automáticas de análisis estático. Lo que no se puede es construir un algoritmo universal que funcione para todos los programas posibles. De hecho, en un script desarrollado por un programador, lo normal es que este sepa, o pueda saber, cuál va a ser el resultado, si no, programaríamos a ciegas. Los casos incomputables que encuentra Turing suelen ser ideas retorcidas que implican autoreferencias paradójicas. En cualquier caso, lo que dice Turing es que no podemos saber en todos los casos, cuál será el resultado de un algoritmo. Puede parecer un matiz, pero lo cierto es que cambia completamente las implicaciones.
Está bien traído el problema de parada en el libro porque está influido por el teorema de incompletitud de Göedel, que tiene presencia en la novela antes, pero simplemente no es correcta la interpretación que hace Labatut.
2. Motores de ajedrez, fuerza bruta y árboles infinitos
Aquí entramos en la apasionante Teoría de juegos, que también está citada en el libro, pues Von Neumann es uno de los pioneros. En la página 327, en la tercera parte, habla sobre programas de ajedrez “como Fritz, Komodo o Stockfish”, en un preámbulo antes de entrar a hablar del go, para dejar claro que el juego del go es más difícil a nivel de computación que el ajedrez, cosa que es totalmente cierta, pero digamos que Labatut lo exagera llegando a plantearlo de manera muy incorrecta. Se refiere a estos algoritmos como de fuerza bruta y dice lo siguiente:
“El programa construye un árbol de búsqueda: sus ramas son los posibles futuros que surgen de esa configuración particular de piezas; el árbol crece hasta llegar al final de la partida, y el programa simplemente elige una de las ramas como el resultado que considera más ventajoso. Con cada movimiento brota un nuevo árbol, que se ramifica a medida que el juego cambia, pero el computador puede mirar tan lejos que siempre estará a un paso -o varios miles de pasos- por delante de cualquier jugador de carne y hueso en una partida de ajedrez. ”
Aquí el problema es doble: primero, se da a entender que los programas exploran todas las jugadas posibles hasta el final de la partida, cosa que no hacen ni de lejos; y segundo, se sugiere que el ajedrez puede resolverse por fuerza bruta -dice explícimante “fuerza bruta” un poco antes de este extracto- como si bastara con suficiente potencia de cálculo.
En realidad, los motores de ajedrez modernos (como Stockfish) calculan en profundidad limitada, generalmente entre 30 y 60 plies (medios turnos), aplicando técnicas de poda (ahorrarse recorrer todas las ramas del árbol) como alpha-beta y funciones heurísticas que estiman la calidad de las posiciones sin tener que llegar al jaque mate. Además, usan aperturas predefinidas, bases de finales, y toda una batería de trucos para no ahogarse en el mar de variantes.
Tampoco es cierto que estén “miles de pasos por delante” del humano. Sí, calculan más, y mejor, pero dentro de márgenes pequeños. La clave está en cómo descartan ramas irrelevantes y qué tipo de evaluación aplican en los nodos terminales del árbol.
Labatut quiere remarcar tanto la diferencia de complejidad entre el go y el ajedrez que se pasa de frenada. En realidad, el planteamiento es esencialmente el mismo en un caso y en otro. En ambos es inabarcable calcular todos los posibles movimientos y, por lo tanto, en ambos es necesario que el programa sea capaz de analizar lo mejor posible una posicion -como lo hace un humano- para saber qué ramas debe seguir indagando y cuáles no, y cuál es el valor que asigna a una determinada posición “hoja” de su árbol, que está lejos de ser el final de la partida. La diferencia está en que como en el go el árbol crece más rápido, hay que afinar más ese cálculo de posiciones y hacer una poda mejor. Y eso es lo que llevó a Demis Hassabis a buscar una IA capaz de hacerlo mejor. Pero eso no quiere decir que Stockfish no lo intente también, es solo que no es tan bueno.
En la página siguiente da números para explicar lo mucho más complejo que es el go y dice que en un tablero de ajedrez se pueden jugar 10¹²³ partidas mientras que en uno de go sube a 10⁷⁰⁰. Ciértamente la cifra del go e astronómicamente mayor que la del ajedrez, pero es que la cifra del ajedrez ya es terríblemente alta, por lo que no supone una diferencia en este sentido, simplemente, en ambos casos es inabarcable el número de partidas totales.
Pero insisto: un libro muy recomendable. Ameno e inteligente.