Curso intermedio de programación en Prolog

El corte es un predicado predefinido que no recibe argumentos. Se representa mediante un signo de admiración (!). Sin duda, es el predicado más difícil de entender. El corte tiene la espantosa propiedad de eliminar los puntos de elección del predicado que lo contiene.

Es decir, cuando se ejecuta el corte, el resultado del objetivo (no sólo la cláusula en cuestión) queda comprometido al éxito o fallo de los objetivos que aparecen a continuación. Es como si a Prolog "se le olvidase" que dicho objetivo puede tener varias soluciones.

Otra forma de ver el efecto del corte es pensar que solamente tiene la propiedad de detener el backtracking cuando éste se produce. Es decir, en la ejecución normal el corte no hace nada. Pero cuando el programa entra en backtracking y los objetivos se recorren marcha atrás, al llegar al corte el backtracking se detiene repentinamente forzando el fallo del objetivo.

. Ejemplo

Para entender de manera simple el uso del corte vamos a comparar dos predicados que solamente se diferencian en un corte:

 % Sin corte. 
 p(X,Y) :- 
   X > 15, 
   Y > 50. 
 
 p(X,Y) :- 
   X > Y, 

 % Con corte.
 q(X,Y) :- 
   X > 15, 
   !, 
   Y > 50. 
 
 q(X,Y) :- 
   X > Y, 
 

Veamos que ocurre si ejecutamos el objetivo p(25,12):

  • Obsérve que ambas cláusulas unifican con la cabeza, luego existen dos puntos de elección que se anotan.
  • Prolog entra por el primer punto de elección (primera cláusula) eliminandolo.
  • Prolog ejecuta el primer objetivo del cuerpo (X>15), que tiene éxito.
  • Prolog ejecuta el segundo objetivo del cuerpo (X>50), que falla.
  • Empieza el backtracking.
  • Se recorren ambos objetivos hacia atrás pero no hay variables que se hayan ligado en ellos.
  • Encontramos el segundo punto de elección (segunda cláusula) que detiene el backtracking eliminandolo en el proceso. La ejecución continúa hacia delante.
  • Prolog ejecuta el cuerpo de la segunda cláusula que consiste en X>Y. Este objetivo tiene éxito.
  • El objetivo p(25,12) tiene éxito.

Ahora comprobamos lo que ocurre cuando éxiste el corte, ejecutamos q(25,12):

  • Ambas cláusulas unifican con la cabeza, luego existen dos puntos de elección que se anotan.
  • Prolog entra por el primer punto de elección (primera cláusula) eliminandolo.
  • Prolog ejecuta el primer objetivo del cuerpo (X>15), que tiene éxito.
  • Se ejecuta el segundo objetivo del cuerpo que es el corte. Por tanto, se eliminan todos los puntos de elección anotados que son debidos al objetivo q(25,12). Solamente teníamos uno, que se elimina.
  • Prolog ejecuta el tercer objetivo del cuerpo (X>50), que falla.
  • Empieza el backtracking.
  • Se recorren ambos objetivos hacia atrás pero no hay variables que se hayan ligado en ellos.
  • No encontramos ningún punto de elección porque fueron eliminados por el corte.
  • El objetivo p(25,12) falla.

Como puede comprobar, los resultados son sustacialmente diferentes. La segunda cláusula del predicado q/2 ni siquiera ha llegado a ejecutarse porque el corte ha comprometido el resultado del objetivo al resultado de Y>15 en la primera cláusula.

. Usos del corte

El corte se utiliza muy frecuentemente, cuanto más diestro es el programador más lo suele usar. Los motivos por los que se usa el corte son, por orden de importancia, los siguientes:

  1. Para optimizar la ejecución. El corte sirve para evitar que por culpa del backtracking se exploren puntos de elección que, con toda seguridad, no llevan a otra solución (fallan). Para los entendidos, esto es podar el árbol de búsqueda de posibles soluciones.
  2. Para facilitar la legibilidad y comprensión del algoritmo que está siendo programado. A veces se situan cortes en puntos donde, con toda seguridad, no van a existir puntos de elección para eliminar, pero ayuda a entender que la ejecución sólo depende de la cláusula en cuestión.
  3. Para implementar algoritmos diferentes según la combinación de argumentos de entrada. Algo similar al comportamiento de las sentencias case en los lenguajes imperativos.
  4. Para conseguir que un predicado solamente tenga una solución. Esto nos puede interesar en algún momento. Una vez que el programa encuentra una solución ejecutamos un corte. Así evitamos que Prolog busque otras soluciones aunque sabemos que éstas existen.

. Corte y fallo

Es muy habitual encontrar la secuencia de objetivos corte-fallo: !,fail. El predicado fail/0 es un predicado predefinido que siempre falla. Se utiliza para detectar prematuramente combinaciones de los argumentos que no llevan a solución, evitando la ejecución de un montón de código que al final va a fallar de todas formas.

© Copyright 2000-2001

Angel Fernández Pineda.

COMPARTE ESTE ARTÍCULO

ENVIAR A UN AMIGO
COMPARTIR EN FACEBOOK
COMPARTIR EN TWITTER
COMPARTIR EN GOOGLE +
SIGUIENTE ARTÍCULO

¡SÉ EL PRIMERO EN COMENTAR!
Conéctate o Regístrate para dejar tu comentario.