write tutorial swi raiz programas operadores explicados ejercicios ejemplos cuadrada corte prolog prolog-cut

tutorial - Evitar el uso de corte en el predicado de valor absoluto de Prolog



raiz cuadrada en prolog (3)

Implementé la siguiente función en prolog con el siguiente código:

abs2(X, Y) :- X < 0, Y is -X. abs2(X, X) :- X >= 0, !.

¿Cómo puedo implementar esta función sin el uso de cut ("!")?


Mi prólogo está un poco oxidado, pero ¿por qué necesitas el corte? Si escribe el predicado correctamente, retroceder no puede tener éxito, por lo que el corte es innecesario:

abs(X, Y) :- number(X) , X < 0 , Y is -X . abs(X, X) :- number(X) , X >= 0 .


Está el corte "oculto" en la construcción if-then-else de Prolog:

abs2(X,Y) :- X < 0 -> Y is -X ; Y = X.

Es algo así como una peculiaridad, pero Prolog no retrocede en el subgrupo que forma la "premisa" de una construcción si-entonces o si-luego-otra. Aquí, si X <0 tiene éxito en el primer intento, se comete la elección de la cláusula "then" sobre la cláusula "else" (de ahí la descripción de este comportamiento como un corte "oculto").

Hay más de un rol para un corte en la primera cláusula del predicado abs2 / 2 como está escrito en la pregunta. Como señala Nicholas, el corte al final de la segunda cláusula no tiene ningún efecto (no quedan puntos de elección cuando llegas allí). Pero como señala Kaarel, hay un punto de elección que queda abierto si la primera cláusula tiene éxito.

Entonces, lo que habría escrito, permitiendo el uso de un corte, es este:

abs2(X,X) :- X >= 0, !. abs2(X,Y) :- Y is -X.

Los comentarios de Nicholas también sugieren formas de "aritmetizar" el valor absoluto (en lugar de usar una definición lógica) y evitar "cortar" de esa manera.


¡No es necesario usar prolog-cut !

Simplemente escribe:

abs2(X,Y) :- Y is abs(X).