Ремонт принтеров, сканнеров, факсов и остальной офисной техники


назад Оглавление вперед




[126]

Упражнение 4.47.

Хьюго Дум говорит, что поскольку глагольная группа - это либо глагол, либо глагольная группа плюс предложная группа, было бы намного естественнее определить процедуру parse-verb-phrase так (и то же сделать для именных групп):

(define (parse-verb-phrase) (amb (parse-word verbs) (list verb-phrase

(parse-verb-phrase) (parse-prepositional-phrase))))

Работает ли этот вариант? Изменится ли поведение программы, если мы поменяем местами выражения в amb?

Упражнение 4.48.

Дополните описанную выше грамматику так, чтобы она могла работать с более сложными предложениями. Например, можно позволить именным и глагольным группам включать прилагательные и наречия, или же можно обрабатывать сложные предложения.53

Упражнение 4.49.

Лизу П. Хакер больше интересует не анализ предложений, а их порождение. Она замечает, что если изменить процедуру parse-word так, чтобы она игнорировала «входное предложение», всегда заканчивалась успехом и порождала подходящее слово, мы сможем использовать те же программы, которые мы написали для анализа, для порождения предложений. Реализуйте идею Лизы и покажите первые пять-шесть порожденных предложений.54

4.3.3 Реализация amb-интерпретатора

Выполнение выражения в обыкновенной Scheme может вернуть результат, может вообще не завершиться, и, наконец, может закончиться сообщением об ошибке. В недетерминистской Scheme при выполнении выражения, в дополнение ко всему этому, может еще обнаружиться тупик, и в этом случае вычисление должно откатиться к предыдущей точке выбора. Интерпретация недетерминистской Scheme осложняется из-за этой дополнительной возможности.

Мы построим amb-интерпретатор для недетерминистской Scheme, модифицировав анализирующий интерпретатор из раздела 4.1.7.55 Как и в анализи-

53Грамматики такого рода могут быть сколь угодно сложными, но по сравнению с настоящей обработкой естественного языка они остаются игрушкой. Настоящее понимание естественного языка компьютером требует сложного сочетания синтаксического анализа с интерпретацией значения. С другой стороны, даже простые анализаторы могут быть полезны для поддержки гибких командных языков в программах вроде систем поиска информации. Уинстон (Winston 1992) описывает вычислительные подходы к пониманию настоящего естественного языка, а также применение простых грамматик в командных языках.

54 Несмотря на то, что идея Лизы (будучи удивительно простой) дает результат, порождаемые предложения оказываются довольно скучными - они не отображают возможные предложения нашего языка никаким интересным образом. Дело в том, что грамматика рекурсивна во многих местах, а метод Лизы «проваливается» в одну из рекурсий и там застревает. Как с этим можно бороться, Вы увидите в упражнении 4.50.

55В разделе 4.2 мы решили реализовать ленивый интерпретатор как модификацию обыкновенного метациклического интерпретатора из раздела 4.1.1. Напротив, здесь в основу amb-интерпретатора мы кладем анализирующий интерпретатор из раздела 4.1.7, поскольку исполнительные процедуры этого интерпретатора служат удобной базой для реализации поиска с возвратом.


рующем интерпретаторе, вычисление выражения происходит путем вызова исполнительной процедуры, которая получается при анализе этого выражения. Разница между интерпретацией обыкновенной Scheme и недетерминистской Scheme будет полностью сводиться к исполнительным процедурам.

Исполнительные процедуры и продолжения

Напомним, что исполнительные процедуры обыкновенного интерпретатора принимают один аргумент: окружение, в котором происходит вычисление выражения. В противоположность этому, исполнительные процедуры amb-интерпретатора принимают три аргумента: окружение и две процедуры, называемые процедурами продолжения (continuation procedures). Вычисление выражения будет заканчиваться вызовом одного из этих продолжений: если результатом вычисления является значение, то зовется продолжение успеха (success continuation) с этим значением в качестве аргумента; если вычисление натыкается на тупик, вызывается продолжение неудачи (failure continuation). Построение и вызов соответствующих продолжений служит механизмом, с помощью которого в недетерминистском интерпретаторе реализуется поиск с возвратом.

Задача продолжения успеха - принять значение и продолжить вычисление. Помимо этого значения, продолжение успеха получает дополнительное продолжение неудачи, которое нужно будет вызвать, если использование значения приведет в тупик.

Задача продолжения неудачи - попробовать другую ветвь недетерминистского процесса. Главная особенность недетерминистского языка состоит в том, что выражения могут представлять собой точки выбора между вариантами. Выполнение такого выражения должно продолжиться согласно одному из указанных взаимоисключающих вариантов, несмотря на то, что заранее неизвестно, какие варианты приведут к приемлемым результатам. При обработке такой ситуации интерпретатор выбирает один из вариантов и передает его значение продолжению успеха. Кроме того, он строит и передает вместе со значением продолжение неудачи, которое потом можно вызвать, чтобы рассмотреть другой вариант.

Неудача возникает во время вычисления (то есть, зовется продолжение неудачи), когда пользовательская программа явным образом отказывается от текущего рассматриваемого варианта (например, вызов require может привести к выполнению (amb), а это выражение всегда терпит неудачу - см. раздел 4.3.1). В этом месте продолжение неудачи вернет нас к последней по времени точке и оттуда направит по другому варианту. Если же в этой точке выбора больше не осталось вариантов, то запускается неудача в предыдущей точке выбора, и так далее. Кроме того, продолжения неудачи запускаются управляющим циклом в ответ на запрос try-again, чтобы найти еще одно значение последнего выражения.

Помимо того, если на какой-то ветке процесса, возникшей в результате выбора, происходит операция с побочным эффектом (например, присваивание переменной), то может понадобиться отменить побочный эффект, если процесс наткнется на неудачу, прежде чем будет сделан новый выбор. Этого мы добиваемся, заставив операцию с побочным эффектом порождать продолжение неудачи, которое отменяет эффект и отправляет неудачу дальше.

Итак, продолжения неудачи порождаются


•в выражениях amb - чтобы обеспечить механизм выбора альтернативных вариантов, если текущий выбор, сделанный внутри amb, приведет к тупику;

•в управляющем цикле верхнего уровня - чтобы иметь возможность сообщить о неудаче, когда перебраны все альтернативы;

•в присваиваниях - чтобы во время отката перехватывать неудачи и отменять присваивания.

Неудачи возбуждаются только тогда, когда программа заходит в тупик. Это происходит

•если пользовательская программа выполняет выражение (amb);

•если пользователь печатает try-again в управляющем цикле.

Кроме того, продолжения неудачи вызываются при обработке неудачи:

•Когда продолжение неудачи, порожденное присваиванием, заканчивает отмену побочного эффекта, оно вызывает то предложение неудачи, которое оно само перехватило, и посредством его отправляет неудачу назад до точки выбора, которая привела к присваиванию, либо до верхнего уровня.

•Когда продолжение неудачи для amb исчерпывает все варианты выбора, оно вызывает продолжение неудачи, которое изначально было дано amb, и посредством его распространяет неудачу до предыдущей точки выбора, либо до верхнего уровня.

Структура интерпретатора

Процедуры представления синтаксиса и данных в amb-интерпретаторе, а также базовая процедура analyze, совпадают с соответствующими процедурами в интерпретаторе из раздела 4.1.7, только здесь требуются дополнительные синтаксические процедуры для анализа особой формы amb:56

(define (amb? exp) (tagged-list? exp amb))

(define (amb-choices exp) (cdr exp))

Кроме того, требуется добавить в процедуру разбора analyze ветку, которая будет распознавать эту особую форму и порождать соответствующую исполнительную процедуру:

((amb? exp) (analyze-amb exp))

Процедура верхнего уровня ambeval (сходная с версией eval?, приведенной в разделе 4.1.7) анализирует данное выражение и применяет полученную исполнительную процедуру к данному окружению и двум данным продолжениям:

(define (ambeval exp env succeed fail) ((analyze exp) env succeed fail))

56Мы предполагаем, что интерпретатор поддерживает let (см. упражнение 4.22), который мы использовали в недетерминистских программах.



[стр.Начало] [стр.1] [стр.2] [стр.3] [стр.4] [стр.5] [стр.6] [стр.7] [стр.8] [стр.9] [стр.10] [стр.11] [стр.12] [стр.13] [стр.14] [стр.15] [стр.16] [стр.17] [стр.18] [стр.19] [стр.20] [стр.21] [стр.22] [стр.23] [стр.24] [стр.25] [стр.26] [стр.27] [стр.28] [стр.29] [стр.30] [стр.31] [стр.32] [стр.33] [стр.34] [стр.35] [стр.36] [стр.37] [стр.38] [стр.39] [стр.40] [стр.41] [стр.42] [стр.43] [стр.44] [стр.45] [стр.46] [стр.47] [стр.48] [стр.49] [стр.50] [стр.51] [стр.52] [стр.53] [стр.54] [стр.55] [стр.56] [стр.57] [стр.58] [стр.59] [стр.60] [стр.61] [стр.62] [стр.63] [стр.64] [стр.65] [стр.66] [стр.67] [стр.68] [стр.69] [стр.70] [стр.71] [стр.72] [стр.73] [стр.74] [стр.75] [стр.76] [стр.77] [стр.78] [стр.79] [стр.80] [стр.81] [стр.82] [стр.83] [стр.84] [стр.85] [стр.86] [стр.87] [стр.88] [стр.89] [стр.90] [стр.91] [стр.92] [стр.93] [стр.94] [стр.95] [стр.96] [стр.97] [стр.98] [стр.99] [стр.100] [стр.101] [стр.102] [стр.103] [стр.104] [стр.105] [стр.106] [стр.107] [стр.108] [стр.109] [стр.110] [стр.111] [стр.112] [стр.113] [стр.114] [стр.115] [стр.116] [стр.117] [стр.118] [стр.119] [стр.120] [стр.121] [стр.122] [стр.123] [стр.124] [стр.125] [стр.126] [стр.127] [стр.128] [стр.129] [стр.130] [стр.131] [стр.132] [стр.133] [стр.134] [стр.135] [стр.136] [стр.137] [стр.138] [стр.139] [стр.140] [стр.141] [стр.142] [стр.143] [стр.144] [стр.145] [стр.146] [стр.147] [стр.148] [стр.149] [стр.150] [стр.151] [стр.152] [стр.153] [стр.154] [стр.155] [стр.156] [стр.157] [стр.158] [стр.159] [стр.160] [стр.161] [стр.162] [стр.163] [стр.164] [стр.165] [стр.166] [стр.167] [стр.168] [стр.169] [стр.170] [стр.171] [стр.172] [стр.173] [стр.174] [стр.175] [стр.176] [стр.177] [стр.178] [стр.179] [стр.180] [стр.181] [стр.182] [стр.183] [стр.184] [стр.185] [стр.186] [стр.187] [стр.188] [стр.189] [стр.190] [стр.191] [стр.192] [стр.193] [стр.194] [стр.195] [стр.196]