fail
в retract(q(_,_)),fail.
делает цикл до тех пор, пока в базе данных не останется больше q/2
s.
Как это работает, Пролог хочет доказать, что цель ему дана;поэтому, когда наша цель заканчивается явным fail
, то fail
всегда терпит неудачу, поэтому общая цель тоже терпит неудачу;но Пролог хочет доказать это и поэтому продолжает пытаться доказать это, поэтому он "повторяет" любые точки выбора любых выдающихся целей, которые все еще находятся "над" этим fail
.
Проще говоря, он повторяет цель retract(q(_,_))
.
Каждая цель retract(q(_,_))
извлекает один экземпляр q/2
из нашей базы данных data .Таким образом, в этом отказоустойчивом цикле все они удаляются, и окончательный результат по-прежнему является ошибочным.
В чистом виде учитывается только этот результат - провал или успех цели.Но assert
и retract
виды предикатов призваны к их побочным эффектам , а не к их успеху или провалу.Их побочный эффект заключается в том, что они влияют на состояние нашей базы данных.
На самом деле, обычно цикл, управляемый сбоем, будет выглядеть как
retract(q(_,_)),fail ; true.
для достижениятот же эффект, но преуспевает (вместо сбоя), чтобы сигнализировать, об успешном достижении ожидаемого эффекта.