logo search
TurboProlog / Документация / TOM_1

Предотвращение поиска с возвратом к следующему предложению.

Отсечение может быть использовано как способ сообщить Турбо Прологу,

что он выбрал верное предложение для определенного предиката. Например,

рассмотрим следующий фрагмент:

r(1) :- !, a, b, c.

r(2) :- !, d.

r(3) :- !, c.

r(_) :- write("Тhis is a catch-all clause.").

Использование отсечения делает предикат r детерминированным. В дан-

ном случае Турбо Пролог выполняет обращение к r с единственным целым ар-

гументом. Предположим, что произведено обращение r(1). Турбо Пролог прос-

матривает программу в поисках соответствия для обращения; он находит его

с первым предложением, определяющим r. Поскольку имеется более, чем одно

возможное решение для данного обращения, Турбо Пролог проставляет точку

возврата около этого предложения.

Теперь пришел черед правила, и Турбо Пролог начинает обработку тела

правила. Первое, что происходит, это то, что он проходит через отсечение;

таким образом исключается возможность возвращения к другому предложению

r. Это отменяет точки поиска с возвратом, повышая эффективность выполне-

ния программы. Это также гарантирует, что отлавливающее ошибки предложе-

ние будет выполнено лишь в том случае, если ни одно из других условий не

будет соответствовать обращению к r.

Обратите внимание, что конструкция такого типа весьма похожа на кон-

струкцию case в других языках программирования. Также обратите внимание

на то, что условие проверки записывается в заголовке правил. Вы могли бы

попросту написать такие предложения

r(X) :- X=1, !, a, b, c.

r(X) :- X=2, !, d.

r(X) :- X=3, !, c.

r(_) :- write("Тhis is a catch-all clause.").

Однако вам следует помещать проверочное условие в заголовок правила,

когда только возможно: это повышает эффективность программы и упрощает ее

чтение.

В качестве другого примера рассмотрим следующую программу. Запустите

ее и задайте вопрос friend(bill, Who) по подсказке Goal:

/* Program CH05EX08.PRO */

predicates

friend(symbol, symbol)

girl(symbol)

likes(symbol, symbol)

clauses

friend(bill, jane) :-

girl(jane), likes(bill, jane), !.

friend(bill, jim) :-

likes(jim, baseball), !.

friend(bill, sue) :-

girl(sue).

girl(mary).

girl(jane).

girl(sue).

likes(jim, basesall).

likes(bill, sue).

Если бы в программе не было отсечения, то Турбо Пролог предложил бы

два решения: Билл является другом как Джейн, так и Сью. Однако отсечение

в первом предложении, определяющем friend, говорит Турбо Прологу, что ес-

ли это предложение согласовано, то друг Билла уже найден, и нет нужды

продолжать поиск других кандидатур. В сущности, отсечение такого рода го-

ворит, что вы удовлетворены найденным решением, и нет смысла продолжать

поиск другого друга.

Поиск с возвратом может иметь место внутри предложений в попытке

согласовать обращение, но, однажды обнаружив решение, Турбо Пролог прохо-

дит через отсечение. Предложения friend, записанные так, как показано вы-

ше, возвратят одного и только одного друга Билла (если друг вообще может

быть найден).