Скачиваний:
201
Добавлен:
17.06.2016
Размер:
2.69 Mб
Скачать

Представление проверки в правиле.

Посмотрите более внимательно на четвертое правило для action. Оно

будет сопоставлено для любого аргумента, переданного правилу. Но вы хоти-

те быть уверенными, что оно не напечатает "Я не знаю такого числа" если

число попадает в правильный диапазон. Это задача для подцелей

X<>1, X<>2, X<>3,

где <> обозначает не равно. Для того, чтобы напечатать Я не знаю такого

числа, Пролог должен сначала доказать , что Х не равен 1,2 или 3. Если

какая-нибудь из этих подцелей не потерпит неуспех, то Пролог попытается

использовать последнюю альтернативу. Но здесь не указано последней аль-

тернативы и поэтому конец предложения никогда не выполнится.

Обратите внимание, что action подразумевает, что Choice уже связана.

Если вы вызываете action со свободной переменной в качестве аргумента, то

цель будет сопоставлена со всеми предложениями. Первые три правила вернут

альтернативные решения, а последнее вызовет ошибку, так как вы не можете

проверить равна ли несвязанная переменная числу.

Отсечение как goto.

Программа CH05EX13.PRO неудачна из-за того, что после выбора и вы-

полнения нужного правила, Пролог все еще продолжает поиск альтернатив и

будет принудительно завершен, так как последнее правило неприменимо.

Вы могли бы сэкономить память и время, если бы могли сообщить Проло-

гу где нужно прекратить поиск альтернатив. И вы можете это сделать, ис-

пользуя отсечение (пишется !), что означает: "Если вы зашли так далеко,

не нужно возвращаться из этого правила и не нужно искать больше альтерна-

тив этому правилу."

Другими словами, "Сжигаем за собой мосты". Возвращение все еще воз-

можно, но только на более высоком уровне. Если текущее правило вызывается

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

испробованы. Но отсечение отбрасывает альтернативы внутри правила и аль-

тернативы данному правилу.

Используя отсечение, эта программа может быть переписана следующим

образом:

/* программа CH05EX14.PRO */

predicates

action(integer)

clauses

action(1) :- !

write("Вы нажали 1").

action(2) :- !

write("Вы нажали два").

action(3) :- !

write("Набрано три").

action(_) :-

write("Я не знаю такого числа").

goal

write("Наберите число от 1 до 3"),

readreal(Choice),

action(Choice).

Отсечение не производит эффект во время непосредственного выполне-

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

войти в правило, содержащее отсечение и достичь точки где расположено от-

сечение. Отсечение может быть представлено другими примерами, как этот

action(X) :- X>3, ! , write("Слишком много").

В этом правиле отсечение не произведет никакого действия, пока не

будет достигнута первая подцель Х>3.

Заметьте, что порядок правил здесь имеет значение. В CH05EX13.PRO вы

могли написать правила в любом порядке; только одно из них сопоставлялось

с конкретным числом. Но в примере 14 вы должны быть уверены, что компь-

ютер не сделает попытки выполнить правило, печатающее "Я не знаю такого

числа", раньше чем все предыдущие правила будут испробованы (и не выпол-

нят своих отсечений).

Отсечения в CH05EX14.PRO некоторые называют "красными отсечениями" -

так как они меняют логику программы. Если вы сохраните проверки

Х<>1,Х<>2,Х<>3, изменив программу только вставкой отсечений в каждом

предложении, то вы сделаете "зеленое отсечение", которые экономят время и

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

ний. Выигрыш при этом не так велик, но риск внести ошибку в программу

уменьшается.

Отсечение (cut) - это мощный, но и опасный оператор Пролога. В этом

отношении он соответствует предложению goto в остальных языках программи-

рования - вы можете делать с ним многие вещи, но это делает вашу програм-

му более трудной для понимания. Мы еще обсудим cut в Справочном руководс-

тве.

Соседние файлы в папке Документация