Preguntar a un programa, no darle órdenes
Prolog es un lenguaje de programación lógica: escribes hechos que son ciertos y después le haces preguntas. Con él puedes consultar datos, por ejemplo quién es hijo de quién, sin escribir ningún bucle.
Una agenda familiar o la lista de precios de una tienda se escriben así. En esta lección aprendes a escribir hechos y a preguntar, y lo pruebas en un Prolog de verdad.
Al final de esta lección
Nota
Puedo enunciar hechos y hacer a Prolog una pregunta con una variable.
Palabras clave
| Palabra | Qué significa | Ejemplo |
|---|---|---|
| Hecho | algo que decimos que es verdad | price(milk, 2). |
| Átomo | un nombre que empieza por minúscula | milk |
| Variable | un hueco con nombre que empieza por mayúscula | X |
| Consulta | una pregunta que se hace a Prolog | |
| Unificación | hacer coincidir una pregunta con un hecho | |
| Predicado | el nombre de un hecho y cuántos datos lleva |
Las celdas que rellenan los estudiantes quedan en blanco en esta vista previa.
Un hecho afirma algo que es verdad
Un hecho es una frase corta que damos por cierta. price(milk, 2). significa que la leche cuesta 2 euros.
price es el predicado: el nombre de la relación. milk y 2 son los datos. Los nombres como milk son átomos y empiezan por minúscula. Todo hecho acaba en un punto.
Tres hechos sobre una tienda
% Los nombres del código van en inglés, como en Python.
price(bread, 1).
price(milk, 2).
price(eggs, 3).
% Un hecho con un solo dato:
on_sale(eggs).
Cómo pregunta el laboratorio a Prolog
El laboratorio tiene un Prolog listo, SWI-Prolog, dentro de una máquina llamada prolog. docker exec prolog ejecuta una orden dentro de ella.
swipl abre Prolog. -g le pasa una pregunta y -t halt lo cierra al terminar. Al final va el archivo de hechos. Lo que escribe Prolog sale siempre en inglés: los nombres de las personas, yes, no y los errores.
Lee los hechos del laboratorio
docker exec prolog cat facts.plSe muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.
Una consulta pregunta si algo es cierto
Una consulta es una pregunta a Prolog. Si no lleva variables, la respuesta es sí o no: ¿está ese hecho entre los que conoces?
Los siguientes Runs usan -> y ; para escribir yes o no según lo que conteste Prolog. Antes de pulsar, decide qué crees que saldrá.
Una pregunta cuyo hecho existe
docker exec prolog swipl -q -g "(parent(tom, ann) -> write(yes) ; write(no)), nl" -t halt facts.plSe muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.
La misma pregunta, al revés
docker exec prolog swipl -q -g "(parent(ann, tom) -> write(yes) ; write(no)), nl" -t halt facts.plSe muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.
Una variable le pide a Prolog que busque
Si en la consulta pones una variable, Prolog busca todos los valores que la hacen cierta. Una variable empieza por mayúscula: X, Hijo.
Prolog prueba cada hecho. Si encaja con la pregunta, hay una unificación: el patrón y el hecho coinciden, y Prolog apunta qué valió la variable. forall repite lo de dentro una vez por cada respuesta, write escribe y nl cambia de línea.
Ejemplo: parent(X, cat) contra cada hecho
| Hecho | ¿Coincide? | Qué vale X |
|---|---|---|
| parent(tom, ann) | No: ann no es cat | Nada |
| parent(tom, ben) | No: ben no es cat | Nada |
| parent(ann, cat) | Sí | ann |
| parent(ben, dan) | No: dan no es cat | Nada |
Las celdas que rellenan los estudiantes quedan en blanco en esta vista previa.
Todos los hijos de tom
docker exec prolog swipl -q -g "forall(parent(tom, X), (write(X), nl))" -t halt facts.plSe muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.
Quién es padre o madre de cat
docker exec prolog swipl -q -g "forall(parent(X, cat), (write(X), nl))" -t halt facts.plSe muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.
Dos variables: todas las parejas
docker exec prolog swipl -q -g "forall(parent(X, Y), (write(X-Y), nl))" -t halt facts.plSe muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.
Cuántos hechos parent hay
docker exec prolog swipl -q -g "aggregate_all(count, parent(_, _), N), write(N), nl" -t halt facts.plSe muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.
Un error frecuente
Advertencia
Mucha gente cree que si Prolog contesta no, la pregunta está mal escrita. No es así: no quiere decir que Prolog no puede probarlo con los hechos que tiene. Si falta un hecho, la respuesta es no, aunque en la vida real sea cierto.
Para ir más lejos
Prolog solo sabe lo que dicen sus hechos. A eso se le llama el mundo cerrado. Una base de datos SQL piensa igual: si una fila falta, la consulta no la encuentra.
Piensa qué pregunta de SQL equivale a parent(tom, X). Después explica en una frase por qué parent(X, X) no da ninguna respuesta en el laboratorio.