Prolog es el lenguaje que más lejos lleva la idea declarativa: no se escriben instrucciones, se escriben hechos y reglas, y el sistema busca por sí mismo las respuestas que se derivan de ellos. Escribir Prolog exige desaprender casi todo lo demás — y por eso enseña tanto.
🎯 Por qué está en este programa
Prolog es un primo de la familia lógica y declarativa (Atlas), cuyo representante en el núcleo es SQL.
Aporta al programa el paradigma lógico en su forma pura (clase 119): unificación en lugar de asignación, vuelta atrás en lugar de bucles, y una relación que se puede recorrer en las dos direcciones. Es el contraste más fuerte de todo el Atlas frente a los lenguajes imperativos.
| Año | 1972; ISO Prolog en 1995 |
| Autoría | Alain Colmerauer y Philippe Roussel, Marsella; teoría de Robert Kowalski |
| Familia | Lógica; basado en la resolución SLD sobre cláusulas de Horn |
| Paradigma | Lógico declarativo |
| Tipado | Dinámico y sin tipos declarados; los términos son la única estructura |
| Memoria | Recolección de basura, con pila de puntos de elección |
| Ejecución | Máquina abstracta de Warren (WAM); compilado o interpretado |
| Estado | 🟢 Vivo en nichos: IA simbólica, procesamiento de lenguaje, verificación |
En 1972, Alain Colmerauer trabajaba en Marsella en procesamiento de lenguaje natural — concretamente, en responder preguntas en francés—. Necesitaba una forma de expresar reglas gramaticales y deducir consecuencias, y con la base teórica de Robert Kowalski —que había demostrado que un subconjunto de la lógica de primer orden, las cláusulas de Horn, se puede ejecutar— nació Prolog: programmation en logique.
La idea de Kowalski se resume en una ecuación famosa:
Algoritmo = Lógica + Control.
Es decir: lo que se quiere calcular y cómo se busca son cosas separables. El programa Prolog expresa la lógica; el motor aporta el control.
David H. D. Warren hizo Prolog práctico en 1983 con la WAM, una máquina abstracta que se convirtió en el objetivo de compilación estándar — y cuyo papel es el mismo que la JVM tendría después (clase 125).
El momento de máxima atención llegó con el Proyecto de Quinta Generación japonés (1982-1992), que apostó mil millones de dólares por construir ordenadores basados en lógica y en paralelismo. No alcanzó sus objetivos, y su fracaso —junto con el del auge de los sistemas expertos— arrastró la reputación de Prolog durante décadas.
Y hoy sus ideas están más vivas que su nombre: Datalog en bases de datos, la programación por restricciones en logística e industria, y la unificación en los sistemas de tipos de casi todos los lenguajes con inferencia.
La unificación no es asignación (clase 119):
X = 3. % ← liga X con 3, o comprueba que ya vale 3
persona(ana, 30).
persona(luis, 25).
?- persona(Quien, 30). % ← ¿quién tiene 30 años?
Quien = ana.
El mismo = sirve para ligar y para comprobar, y una variable solo se liga una vez — es lo
que la clase 041 llamaría una constante, no una variable.
Y de ahí sale la propiedad más asombrosa del paradigma: una relación se puede recorrer en cualquier dirección.
concat([], L, L).
concat([H|T], L, [H|R]) :- concat(T, L, R).
?- concat([1,2], [3], X). % X = [1,2,3] ← concatenar
?- concat(X, [3], [1,2,3]). % X = [1,2] ← ¡DESCONCATENAR!
?- concat(X, Y, [1,2,3]). % TODAS las formas de partir la lista
Se define una vez y se usa de tres maneras. En un lenguaje imperativo habría que escribir tres funciones. Esa reversibilidad es lo que ningún otro paradigma da, y es la razón de que Prolog siga enseñándose.
Y la vuelta atrás es el mecanismo de control:
?- persona(X, E), E > 26. % prueba ana → sí; prueba luis → no; devuelve ana
El motor prueba alternativas y deshace lo que no funciona, automáticamente. Es búsqueda con retroceso, integrada en el lenguaje.
Y la honestidad exige decir dónde se rompe la abstracción: el orden de las cláusulas importa, y un programa lógicamente correcto puede entrar en un bucle infinito según cómo esté escrito. Por eso existe el corte (
!), que poda la búsqueda — y con él vuelve el control imperativo por la puerta de atrás. La ecuación de Kowalski es un ideal; la práctica es más sucia, y saberlo forma parte de entender el paradigma.
janus), depurador gráfico y gestor de paquetes (clase 143).swipl -g main -t halt main.pl < entrada.txt # ejecutar un guion
swipl # consola interactiva: el uso natural
?- [main]. % cargar
?- trace. % ← depurador de resolución, paso a paso (clase 141)
Es la versión que aparece en el
primos.md de la clase 041.
:- initialization(main, main).
main :-
read_line_to_string(user_input, Linea),
split_string(Linea, " ", "", Partes),
maplist([S, N]>>number_string(N, S), Partes, [Precio, Cantidad, Descuento]),
Total is Precio * Cantidad * (1 - Descuento),
format("Total: ~2f~n", [Total]).
Lo que hay que ver.
Total is ... NO es una asignación. is evalúa la expresión aritmética y unifica el
resultado con Total. Si Total ya estuviera ligado, esto sería una comprobación, no una
escritura (clase 041).Precio es una variable; main es
un átomo. Es al revés de la convención de casi todos los lenguajes.A, B significa "demuestra A
y demuestra B", y si B falla, se vuelve atrás sobre A para probar otra alternativa.maplist con [S,N]>>... es una lambda (biblioteca yall), y aplica la relación
number_string a cada elemento — la misma idea que map en el resto de las fichas (clase 115).main no es una función: es un predicado que se demuestra. Si algo falla, el predicado falla
y el programa termina sin salida — que es la semántica lógica, no la imperativa.⏮️ Volver al Atlas · 🗂️ Todas las fichas · 🔗 Relacionadas: Datalog · SQL · Erlang · Common Lisp