. «Чистая» сборки может удалить «мертвую древесину», которая может быть оставлена лежащей рядом с предыдущими сборками, неудачными сборками, неполными сборками и другими проблемами сборки.
В общем случае среда IDE или сборка будет включать в себя некоторую форму «чистой» функции, но это может быть неправильно настроено (например, в ручном файле) или может завершиться неудачей (например, промежуточные или результирующие двоичные файлы - только).
После завершения «очистки» убедитесь, что «чистый» преуспел, и весь сгенерированный промежуточный файл (например, автоматический файл makefile) был успешно удален.
Этот процесс можно рассматривать как конечный вариант, но часто является хорошим первым шагом ; особенно если недавно был добавлен код, связанный с ошибкой (локально или из исходного репозитория).
Элегантные системы предоставляют 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
не является строго необходимым, но довольно приятным.
EDIT: Иногда я вижу новичков, которые хотят указать, например, «мое отношение не выполняется для пустого списка ", а затем добавьте:
my_relation([]) :- false.
в свой код. Это не необходимо, а не - хороший пример использования false/0
, за исключением, например, фрагментов отказа, которые программно сгенерированы. Вместо этого сосредоточьтесь на том, чтобы указать, что удерживает за ваши отношения. В этом случае просто оставьте все предложение и определите отношение только для списков, которые не являются пустыми, т. Е. Имеют хотя бы один элемент:
my_relation([L|Ls]) :- etc.
или, если вы также описываете другие термины в дополнение к спискам, используйте ограничение, подобное:
my_relation(T) :- dif(T, []), etc.
Учитывая только (или даже оба) этих двух предложений, запрос ?- my_relation([]).
автоматически выйдет из строя. Нет необходимости вводить дополнительное предложение, которое никогда не удастся с этой целью.
Явный сбой. fail
часто используется в сочетании с разрезом: ... !, fail.
для обеспечения отказа.
Для всех конструкций. Явное использование fail
/ false
для перечисления через backtracking - очень склонная к ошибкам активность. Рассмотрим случай:
... ( generator(X), action(X), fail ; true ), ...
Идея, таким образом, должна «делать» действие для всех X
. Но что происходит, если action(X)
терпит неудачу? Эта конструкция просто продолжается со следующим кандидатом - mdash; как будто ничего не произошло. Таким образом, некоторые ошибки могут оставаться необнаруженными очень долго.
Для таких случаев лучше использовать \+ ( generator(X), \+ action(X) )
, который терпит неудачу, если action(X)
не сработает для некоторого X
. Некоторые системы предлагают это как встроенный forall/2
. Лично я предпочитаю использовать \+
в этом случае, потому что \+
немного яснее, что конструкция не оставляет привязки.
Сбой. В диагностических целях часто полезно добавлять целевые false
в свои программы. Подробнее см. сбой .
Один случай (взятый из Программирование логики Constraint с использованием Eclipse ) представляет собой реализацию not / 1:
:- op(900, fy, not).
not Q :- Q, !, fail.
not _ .
Если Q преуспевает, разрез (!) вызывает второе неклассическое условие, которое должно быть отброшено, а сбой - отрицательный результат. Если Q терпит неудачу, тогда первое первое условие не срабатывает.
Еще одно использование для сбоя - принудительное отключение альтернатив при использовании предикатов с побочными эффектами:
writeall(X) :- member(A,X), write(A), fail.
writeall(_).
Некоторые люди могут не учитывать этот особенно хороший стиль программирования. :)