Pregunta

He implementado 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 ("!")?

¿Fue útil?

Solución

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

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

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

Hay más un papel para un corte en el primero 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 opción cuando llegas allí). Pero como señala Kaarel, queda un punto de elección abierto si la primera cláusula tiene éxito.

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

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.

Otros consejos

Mi prólogo está un poco oxidado, pero ¿por qué necesitas el corte? Si escribe el predicado correctamente, el retroceso 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 .

No hay necesidad de usar !

Simplemente escriba:

abs2(X,Y) :- Y is abs(X).
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top