- •У.Клоксин, к.Меллиш программирование на языке пролог Для программистов и пользователей эвм. Предисловие редакторов перевода
 - •Предисловие ко второму изданию
 - •Предисловие к первому изданию
 - •Глава 1 введение
 - •1.1. Факты
 - •1.2. Вопросы
 - •1.3. Переменные
 - •1.4. Конъюнкции
 - •1.5. Правила
 - •1.6. Заключение и упражнения
 - •Глава 2 более детальное описание
 - •2.1. Синтаксические правила
 - •2.1.1. Константы
 - •2.1.2. Переменные
 - •2.1.3. Структуры
 - •2.2. Литеры
 - •2.3. Операторы
 - •2.4. Равенство и установление соответствия
 - •2.5. Арифметика
 - •2.6. Общая схема согласования целевых утверждений
 - •2.6.1. Успешное доказательство конъюнкции целевых утверждений
 - •2.6.2. Рассмотрение целевых утверждений при использовании механизма возврата
 - •2.6.3. Установление соответствия
 - •Глава 3. Использование структур данных
 - •3.1. Структуры и деревья
 - •3.2. Списки
 - •3.3. Принадлежность элементов списку
 - •3.4. Пример: преобразование предложений
 - •3.5. Пример: упорядочение по алфавиту
 - •3.6. Использование предиката присоединить и спецификация деталей
 - •Глава 4. Возврат и отсечение
 - •4.1. Порождение множественных решений
 - •4.2. Отсечение
 - •4.3. Общие случаи использования отсечения
 - •4.3.1. Подтверждение правильности выбора правила
 - •4.3.2. Комбинация «отсечение-fail»
 - •4.4. Проблемы, связанные с использованием отсечения
 - •Глава 5 ввод и вывод
 - •5.1. Ввод и вывод термов
 - •5.1.1. Вывод термов
 - •5.1.2. Ввод термов
 - •5.2. Ввод и вывод литер
 - •5.2.1. Вывод литер
 - •5.2.2. Ввод литер
 - •5.3. Ввод предложений
 - •5.4. Чтение файлов и запись в файлы
 - •5.4.1. Запись в файлы
 - •5.4.2. Чтение файлов
 - •5.4.3. Ввод программ
 - •5.5. Объявление операторов
 - •Глава 6. Встроенные предикаты
 - •6.1. Ввод новых утверждений
 - •Списковая форма записи
 - •6.2. Выполнение и невыполнение целевого утверждения
 - •6.3. Классификация термов
 - •6.4. Работа с утверждениями как с термами
 - •6.5. Создание структур и работа с компонентами структур
 - •6.6. Воздействие на процесс возврата
 - •Отсечение
 - •6.7. Формирование составных целевых утверждений
 - •Конъюнкция целей
 - •Дизъюнкция целей
 - •6.8. Равенство
 - •6.9. Ввод и вывод данных
 - •6.10. Обработка файлов
 - •6.11. Вычисление арифметических выражений
 - •6.12. Сравнение чисел
 - •6.13. Наблюдение за выполнением программы на Прологе
 - •Глава 7. Еще несколько примеров программ
 - •7.1. Словарь в виде упорядоченного дерева
 - •7.2. Поиск в лабиринте
 - •7.3. Ханойские башни
 - •7.4. Справочник комплектующих деталей
 - •7.5. Обработка списков
 - •7.6. Представление и обработка множеств
 - •7.7. Сортировка
 - •7.8. Использование базы данных: random, генатом, найтивсе
 - •Генератор случайных чисел (random)
 - •Генератор имен (генатом)
 - •Генератор списков структур (найтивсе)
 - •7.9. Поиск по графу
 - •7.10. Просеивай Двойки, Просеивай Тройки
 - •7.11. Символьное дифференцирование
 - •7.12. Отображение структур и преобразование деревьев
 - •7.13. Применение предикатов clause и retract
 - •Глава 8. Отладка пролог-программ
 - •8.1. Расположение текстов программ
 - •8.2. Типичные ошибки
 - •8.3. Модель трассировки
 - •8.4. Трассировка и контрольные точки
 - •Выдача информации о цели
 - •Выдача информации о предшественниках
 - •Изменение уровня трассировки
 - •Вмешательство в процесс согласования цели
 - •Другие команды
 - •Заключение
 - •8.5. Фиксация ошибок
 - •Глава 9. Использование грамматических правил в прологе
 - •9.1. Проблема синтаксического анализа
 - •9.2. Описание синтаксического анализа на языке Пролог
 - •9.3. Запись грамматических правил в Прологе
 - •9.4. Присоединение дополнительных аргументов
 - •9.5. Введение дополнительных условий
 - •9.6. Заключение
 - •Глава 10. Пролог и математическая логика
 - •10.1. Краткое введение в исчисление предикатов
 - •10.2. Приведение формул к стандартной форме
 - •Этап 1 - исключение импликаций и зквивалентностей
 - •Этап 2 - перенос отрицания внутрь формулы
 - •Этап 3 - сколемизация
 - •Этап 4 - вынесение кванторов общности в начало формулы
 - •Этап 5 - использование дистрибутивных законов для & и #
 - •Этап 6 - выделение множества дизъюнктов
 - •10.3. Форма записи дизъюнктов
 - •10.4. Принцип резолюций и доказательство теорем
 - •10.5. Хорновские дизъюнкты
 - •10.6. Пролог
 - •10.7. Пролог и логическое программирование
 - •Глава 11. Программные проекты на прологе
 - •11.1. Простые проекты
 - •11.2. Более сложные проекты
 - •Приложение а. Ответы к некоторым упражнениям
 - •Приложение в. Программа приведения формул исчисления предикатов к стандартной форме
 - •Этап 1 - исключение импликаций
 - •Этап 2 - перенос отрицания внутрь формулы
 - •Этап 3 - сколемизация
 - •Этап 4 - вынесение кванторов общности в начало формулы
 - •Этап 5 - использование дистрибутивных законов для. & и #
 - •Этап 6 - выделение множества дизъюнктов
 - •Печать утверждений
 - •Приложение с. Различные версии языка пролог
 - •Синтаксис
 - •Различные ограничения
 - •Возможности окружения
 - •Компиляция
 - •Специальные встроенные предикаты
 - •Средства отладки
 - •Приложение d. Пролог для эвм dec system-10
 - •Пример сеанса работы
 - •Синтаксис
 - •Различные ограничения
 - •Возможности окружения
 - •Компиляция
 - •Различия во встроенных предикатах
 - •Дополнительные встроенные предикаты
 - •Средства отладки
 - •Литература
 - •Приложение е. Микро-пролог
 - •Пример сеанса работы
 - •Синтаксис
 - •Различные ограничения
 - •Возможности окружения
 - •Специальные встроенные предикаты
 - •Средства отладки
 - •Литература
 - •Приложение f. Система мпролог[19]
 - •Пример сеанса работы
 - •Синтаксис
 - •Модульность
 - •Компоненты системы мПролог
 - •Различные ограничения
 - •Дополнительные встроенные предикаты
 - •Средства отладки
 - •Литература
 - •Примечания
 
9.5. Введение дополнительных условий
Рассматривавшиеся до сих пор грамматические правила, входящие в программу синтаксического анализатора, содержали информацию лишь о том, какая часть входной последовательности обрабатывается каждым из правил. Каждый элемент описания правил должен содержать указание о том, как обрабатывать два дополнительных аргумента, добавленных транслятором грамматических правил. Так что каждое целевое утверждение в результирующем утверждении Пролога обрабатывало определенную часть входной последовательности. Иногда может возникнуть желание определить целевые утверждения иного типа, не связанные непосредственно с обработкой входной последовательности, и рассматриваемый формализм грамматических правил позволяет сделать это. В языке принято следующее соглашение: каждое целевое утверждение, заключенное в фигурные скобки {}, при трансляции не меняется.
Рассмотрим несколько примеров ситуаций, в которых было бы полезно использовать эту возможность. Мы покажем, как можно улучшить «словарь» синтаксического анализатора, т. е. его «знания» о словах обрабатываемого языка.
Прежде всего рассмотрим накладные расходы, связанные с введением нового слова в программу, в которой используются оба множества дополнительных аргументов (для согласования формы числа и для построения дерева разбора). Если нужно добавить новое слово, например banana, то для этого необходимо добавить хотя бы правило
существительное(едч, существительное(banana))--› [banana].
которое сводится к следующему факту на Прологе:
существительное(едч, существительное(banana),[banana|S],S).
Это слишком большой объем информации для определения каждого существительного, особенно когда мы знаем, что каждое существительное представляется лишь одним элементом входного списка и порождает небольшое дерево с функтором существительное. Значительно более экономичный способ представления основывается на разделении информации. Информация, общая для всех существительных, помещается в одном месте, а информация о конкретных словах в другом месте. Это можно сделать, если одновременно использовать возможности грамматических правил и обычного Пролога. Общая информация о том, каким образом существительные входят в другие словосочетания, представляется с помощью грамматического правила, а информация о том, какие слова являются существительными, представляется с помощью обычных утверждений Пролога. Этот подход можно применить к последнему примеру следующим образом:
существительное(S,существительное(N)) --› [N], {является_существительным(N,S)}.
где обычный предикат является_существительным указывает, какие слова являются существительными и в какой форме - единственного или множественного числа – они употребляются.
является_существительным(banana,едч).
является_существительным(bananas,мнч).
является_существительным(man,едч).
. . .
Давайте подробно разберем, что означает это грамматическое правило. Оно указывает, что словосочетание класса существительное может состоять из единственного слова N (переменная, определенная в списке), удовлетворяющего некоторому ограничению. Это ограничение заключается в том, что N должно входить в число слов, представленных предикатом является_существительным, с указанием конкретной формы числа S. В этом случае, форма числа словосочетания также S, а порождаемое дерево разбора состоит из двух вершин: вершины существительное и расположенной под ней вершины N. Почему целевое утверждение является_существительным (N,S) должно быть заключено в фигурные скобки? Потому, что оно выражает отношение, не имеющее ничего общего с обработкой входной последовательности. Если убрать фигурные скобки, то результат трансляции будет выглядеть примерно так:
является_существительным(N,S,S1,S2)
и это целевое утверждение никогда не было бы сопоставлено с утверждениями для является_существительным. Заключив целевое утверждение в фигурные скобки, мы тем самым предотвращаем какие-либо его изменения при трансляции. Так что правило будет правильно оттранслировано в следующее утверждение
существительное(S,существительное(N),[N|Посл],Посл):- является_существительным(N,S).
Несмотря на внесенное изменение, используемый способ обработки отдельных слов по-прежнему остается недостаточно изящным. Неудобство этого способа состоит в том, что для каждого вновь вводимого слова надо записывать два утверждения является_существительным – одно для формы единственного числа, а другое для формы множественного числа. Но в этом нет необходимости, поскольку для большинства существительных формы единственного и множественного числа связаны простым правилом:
Если X – существительное в форме единственного числа, то слово, получаемое в результате прибавления 's' к концу слова X, является формой множественного числа этого существительного.
Это правило можно использовать для пересмотра определения для существительное. В результате будет получено новое множество условий, которым должно удовлетворять слово N, для того, чтобы быть существительным. Так как эти условия связаны с внутренней структурой слова и не имеют никакого отношения к обработке входной последовательности, то они будут записаны с использованием фигурных скобок. Слова английского языка представляются как атомы Пролога и поэтому обсуждение вопроса разбиения слов на буквы сводится к рассмотрению литер, составляющих соответствующие атомы. Следовательно, в новом определении необходимо будет использовать предикат name. Улучшенный вариант правила выглядит следующим образом:
существительное(мнч,существительное(КореньN))--›
[N], {(name(М,Мнимя), присоединить(Едимя,"s",Мнимя), name(КореньN,Едимя), является_существительным(КореньN,едч))}.
Конечно, представленное здесь общее правило о форме множественного числа существительных справедливо не во всех случаях (например, множественное число для «fly» не совпадает с «flys»), И по-прежнему необходимо исчерпывающим образом описывать все исключения. Обратите внимание на использование двойных кавычек для представления списка, содержащего литеру 's'. Теперь необходимо определять утверждения для предикатаявляется_существительным лишь для существительных в единственном числе, если форма множественного числа для них образуется по указанному выше правилу. Заметьте, что в соответствии с приведенным определением в дерево разбора вставляется существительное в форме единственного, а не множественного числа. Это может оказаться полезным при последующей обработке дерева разбора. Обратите также внимание на то, как использованы фигурные скобки. В различных реализациях Пролога некоторые детали синтаксиса могут немного отличаться, но наиболее безопасно заключать содержимое фигурных скобок в дополнительные круглые скобки, если оно состоит более чем из одного целевого утверждения, и оставлять пропуск между фигурной скобкой и точкой, завершающей правило.
Большинство трансляторов синтаксических правил, помимо целевых утверждений, заключенных в фигурные скобки, оставляют неизменными и некоторые другие целевые утверждения. Так, обычно нет необходимости заключать в фигурные скобки '!' или дизъюнкции (;) целевых утверждений.
