Я не могу придумать ситуацию, где мне была бы нужна она.
Элегантные системы предоставляют false / 0
как декларативный синоним императивного fail / 0
. Пример, в котором это полезно, - это когда вы вручную хотите принудительно выполнить обратное отслеживание для побочных эффектов, например:
?- between(1,3,N), format("line ~w\n", [N]), false.
line 1
line 2
line 3
Вместо false / 0
вы также можете использовать любую цель, которая не выполняется, например, немного короче. :
?- between(1,3,N), format("line ~w\n", [N]), 0=1.
line 1
line 2
line 3
Таким образом, false / 0
не обязательно, но очень удобно.
РЕДАКТИРОВАТЬ : иногда я вижу новичков, которые хотят заявить, например, «мое отношение не выполняется для пустого списка», а затем добавить:
my_relation ([]): - false.
к их кодексу. Это не необходимо, и не хороший пример использования false / 0
, за исключением, например, срезов отказов, которые генерируются программно. Вместо этого сконцентрируйтесь на изложении того, что имеет в ваших отношениях. В этом случае просто опустите все предложение и определите отношение только для списков, которые не являются пустыми, т. Е. Имеют хотя бы один элемент:
my_relation ([L | Ls]): - и т. Д.
или , если вы описываете другие термины в дополнение к спискам, используйте ограничение вроде:
my_relation (T): - dif (T, []) и т. д.
Учитывая только один (или даже оба) из эти два предложения, запрос ? - my_relation ([]).
автоматически завершится ошибкой. Нет необходимости вводить дополнительный пункт, который никогда не подходит для этой цели.
Один случай (взятый из Логическое программирование с ограничениями с использованием Eclipse) представляет собой реализацию not/1:
:- op(900, fy, not).
not Q :- Q, !, fail.
not _ .
Если Q успешен, то разрезание (!) приводит к отбрасыванию второго пункта not, а fail гарантирует отрицательный результат. Если Q не удается, то сначала срабатывает второе условие not.
Другое применение fail - принудительный обратный путь через альтернативы при использовании предикатов с побочными эффектами:
writeall(X) :- member(A,X), write(A), fail.
writeall(_).
Хотя некоторые люди могут не считать это особенно хорошим стилем программирования. :)
.