Pregunta

No se me ocurre una situación en la que lo necesitaría.

¿Fue útil?

Solución

Los sistemas elegantes proporcionan false/0 como sinónimo declarativo para la fail/0 imprescindible. Un ejemplo en el que es útil es cuando se quiere manualmente a la fuerza de retroceso de efectos secundarios, como:

?- between(1,3,N), format("line ~w\n", [N]), false.
line 1
line 2
line 3

En lugar de false/0, también se puede utilizar cualquier meta que falla, por ejemplo, un poco más corto:

?- between(1,3,N), format("line ~w\n", [N]), 0=1.
line 1
line 2
line 3

Por lo tanto, false/0 no es estrictamente necesario, pero bastante agradable.

Editar : a veces veo principiantes que quieran estado, por ejemplo, "mi relación no se mantiene en la lista vacía", y luego añadir:

my_relation([]) :- false.

a su código. Esto es no necesario, y no un buen ejemplo del uso de false/0, excepto por ejemplo en rebanadas de fallo que se generan mediante programación. En su lugar, concentrado en establecer los cosas que bodega sobre su relación. En este caso, simplemente dejar de lado todo el cláusula, y definir la relación sólo para listas que no están vacías, es decir, tener al menos un elemento:

my_relation([L|Ls]) :- etc.

o, si usted está describiendo otros términos, además de las listas, así, utilizar una restricción como:

my_relation(T) :- dif(T, []), etc.

Teniendo en cuenta solamente uno (o incluso dos) de estas dos cláusulas, la ?- my_relation([]). consulta fallará automáticamente. No es necesario introducir una cláusula adicional que no tiene éxito para ese propósito.

Otros consejos

Fracaso explícito. fail se utiliza a menudo junto con cortar: ... !, fail. para imponer el fracaso.

Para toda construcción. Uso explícito de fail/false enumerar a través de retroceder es una actividad muy propensa a errores.Consideremos un caso:

... ( generator(X), action(X), fail ; true ), ...

La idea es, pues, "hacer" acciones para todos X.Pero ¿qué pasa si action(X) falla?Esta construcción simplemente continúa con el siguiente candidato, como si nada hubiera pasado.De esta manera, algunos errores pueden pasar desapercibidos durante mucho tiempo.

Para tales casos es mejor utilizar \+ ( generator(X), \+ action(X) ) que falla, debería action(X) fracasar por algunos X.Algunos sistemas ofrecen esto como una función incorporada. forall/2.Personalmente prefiero usar \+ en este caso porque el \+ Es un poco más claro que la construcción no deja un enlace.

Rebanada de fracaso. Para fines de diagnóstico suele ser útil añadir a propósito false en sus programas.Ver para más detalles.

Otro uso para Despiste es forzar dar marcha atrás a través de alternativas utilizando las predicados con efectos secundarios:

writeall(X) :- member(A,X), write(A), fail.
writeall(_).

Algunas personas no podría considerar este particular buen estilo de programación sin embargo. :)

Uno de los casos (tomado de Programación con restricciones lógica usando Eclipse ) es una implementación de no / 1:

:- op(900, fy, not).
not Q :- Q, !, fail.
not _ .

Si Q tiene éxito, el corte (!) Hace que la segunda cláusula no se descarta y el fallo asegura un resultado negativo. Si Q falla, entonces el segundo no incendios cláusula primera.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top