Cómo busca Prolog y por qué vuelve atrás
La vuelta atrás (backtracking en inglés) es la forma en que Prolog busca respuestas. Prueba una opción y, si no sirve, vuelve al último punto y prueba otra. Entenderla explica por qué una sola pregunta puede tener muchas respuestas.
Es la misma idea con la que se calculan todas las rutas posibles entre dos paradas de metro.
Al final de esta lección
Nota
Puedo explicar cómo busca Prolog y cómo vuelve atrás cuando una opción falla.
Palabras clave
| Palabra | Qué significa | Ejemplo |
|---|---|---|
| Lista | varios datos en orden, entre corchetes | [3, 5, 2] |
| Cabeza y cola | el primer elemento y la lista de los demás | [H|T] |
| Vuelta atrás | volver al último punto de elección y probar otra opción | |
| Punto de elección | un lugar donde Prolog tiene varias opciones | |
| Fallar | no poder probar algo, y por eso volver atrás |
Las celdas que rellenan los estudiantes quedan en blanco en esta vista previa.
Una lista tiene cabeza y cola
Una lista se escribe entre corchetes: [3, 5, 2]. Para trabajar con ella, Prolog la parte en cabeza y cola: [H|T].
La cabeza H es el primer elemento. La cola T es la lista de todos los demás. La lista vacía es [] y no tiene cabeza. Casi toda regla sobre listas trata primero la lista vacía y después la cabeza.
Parte una lista en cabeza y cola
docker exec prolog swipl -q -g "[H|T] = [10, 20, 30], write(H), nl, write(T), nl" -t haltSe muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.
Lee las reglas de listas
docker exec prolog cat lists.plSe muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.
Suma una lista con total
docker exec prolog swipl -q -g "total([3, 5, 2], S), write(S), nl" -t halt lists.plSe muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.
Dobla cada número con double
docker exec prolog swipl -q -g "double([1, 2, 3], D), write(D), nl" -t halt lists.plSe muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.
Ejemplo: total de [3, 5, 2]
| Lista | Cabeza | Cola | Qué hace la regla |
|---|---|---|---|
| [3, 5, 2] | 3 | [5, 2] | Calcula total de la cola y le suma 3 |
| [5, 2] | 5 | [2] | Calcula total de la cola y le suma 5 |
| [2] | 2 | [] | Calcula total de la cola y le suma 2 |
| [] | Ninguna | Ninguna | Caso base: la suma es 0 |
Las celdas que rellenan los estudiantes quedan en blanco en esta vista previa.
Prolog prueba las opciones de una en una
member(X, Lista) es cierto si X está en la lista. Si preguntas con una variable, X puede ser cualquiera de los elementos: tiene varias opciones.
Prolog toma la primera. Si la condición siguiente falla, vuelve atrás hasta ese punto de elección y toma la segunda. Así sigue hasta agotar la lista.
Todas las opciones de member
docker exec prolog swipl -q -g "forall(member(X, [red, green, blue]), (write(X), nl))" -t haltSe muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.
Mira cada intento y cuándo falla
docker exec prolog swipl -q -g "forall((member(X, [1, 2, 3, 4]), write(try(X)), nl, X > 2), (write(X), nl))" -t haltSe muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.
Lo mismo que hace Prolog, en Python
# Lo que hace Prolog con member: probar uno por uno, en orden.
for x in [1, 2, 3, 4]:
print("pruebo", x)
if x > 2:
print("sirve", x)
# Cambia el 2 por un 3 y vuelve a ejecutar.
Un error frecuente
Advertencia
Mucha gente cree que Prolog mira todas las opciones a la vez. No es así: prueba una, en orden, y solo vuelve atrás si falla o si le pides más respuestas. Por eso el orden de los hechos cambia el orden de las respuestas.
Reúne todas las combinaciones en una lista
docker exec prolog swipl -q -g "findall(X-Y, (member(X, [a, b]), member(Y, [1, 2])), L), write(L), nl" -t haltSe muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.
Todas las formas de partir una lista
docker exec prolog swipl -q -g "forall(append(A, B, [1, 2]), (write(A-B), nl))" -t haltSe muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.
Para ir más lejos
El orden de las reglas importa. Con el caso recursivo antes del caso base, las respuestas salen en otro orden.
Piensa qué cambiaría en la tarea si explore probara las calles de la última a la primera. ¿Cambia el número de caminos o solo su orden?