- •Приложение 4-5
- •IV. Версии языка пролог СиПролог Поставщик
- •Синтаксис и встроенные предикаты
- •Директивы
- •Среда для разработки программ
- •Отладчик
- •Отладочные команды
- •Компилятор
- •Запомненные состояния
- •Интерфейс с иными языками программирования
- •Расширения языка
- •Квинтус Пролог Поставщик
- •Синтаксис и встроенные предикаты
- •Директивы
- •Среда разработки программ
- •Отладчик
- •Компилятор
- •Запомненные состояния
- •Система программирования на Прологе фирмы Сайлоджик Поставщик
- •Синтаксис и встроенные предикаты
- •Директивы
- •Среда разработки программ
- •Отладчик
- •Компилятор
- •Запомненные состояния
- •Интерфейс с иными языками программирования
- •Расширения
- •Пролог-2 Поставщик
- •Синтаксис и встроенные предикаты
- •Директивы
- •Среда разработки программ
- •Отладчик
- •Компилятор
- •Запомненные состояния
- •Интерфейс с иными языками программирования
- •Расширения
- •Эрити Пролог Поставщик
- •Синтаксис и встроенные предикаты
- •Среда разработки программ
- •Отладчик
- •Компилятор
- •Запомненные состояния
- •Расширения
- •Унсв Пролог Поставщик
- •Синтаксис и встроенные предикаты
- •Директивы
- •Среда разработки программ
- •Отладчик
- •Компилятор
- •Запомненные состояния
- •Интерфейс с иными языками программирования
- •Турбо Пролог Поставщик
- •Синтаксис и встроенные предикаты
- •Среда разработки программ
- •Отладчик
- •Запомненные состояния
- •Интерфейс с иными языками программирования
- •Расширения
- •V. Ответы к упражнениям Ответы к упражнениям
- •Глава 2
- •Глава 3
- •Глава 5
- •Глава 6
- •Глава 7
Запомненные состояния
Механизм запомненных состояний Квинтус Пролога во многом похож на этот механизм в СиПрологе. В версиях для операционной системы UNIX можно запускать Пролог-процесс и восстанавливать запомненное состояние просто при помощи ввода имени запомненного состояния в командной строке операционной системы.
Интерфейс с иными языками программирования
Процедуры, написанные на других языках программирования, можно постепенно подсоединять к Пролог-процессу и вызывать во время сеанса работы, так же как и прочие встроенные предикаты. Имеются средства сопряжения с языками Си, Паскаль, ассемблер, Фортран, Кобол и Лисп. Для каждого из этих языков существуют механизмы отображения их структур данных на структуры данных Пролога и обратно с целью передачи аргументов.
Расширения
В Квинтус Пролог включено DCG-расширение, о котором рассказывалось выше при описании СиПролога.
Разное
Фразы при просмотре или компиляции анализируются подсистемой проверки стиля программирования. Эта подсистема выдает предупреждающие сообщения о возможных ошибках (к примеру, о переменной, которая встречается во фразе лишь один раз). Этот вид сообщений поможет локализовать ошибки правописания.
Индексация первого аргумента
В откомпилированных процедурах Квинтус Пролога (за исключением динамических процедур) автоматически индексируется первый аргумент. Это означает, что при выполнении запроса к процедуре для ускорения доступа к фразам процедуры, имеющим такой же первый аргумент, как и у запроса, применяется хеш-таблица. Если первым аргументом служит структура, то фразы индексируются по имени этой структуры.
Оптимизация остаточной рекурсии
В Квинтус Прологе автоматически осуществляется оптимизация остаточной рекурсии для процедуры, которая детерминированна в точке вызова рекурсивной подцели. Оптимизация остаточной рекурсии — это метод экономии стековой памяти, требующейся для выполнения запроса к процедуре. Он обеспечивает то, что для обработки рекурсивной подцели процедуры больше не выделяется дополнительных блоков стековой памяти. Вместо этого рекурсивная подцель использует повторно те блоки стека, которые были выделены для породившей ее цели. Поэтому процедура может осуществлять рекурсию на любую глубину, пользуясь постоянным числом блоков стековой памяти.
В качестве примера того, как можно воспользоваться преимуществами, предоставляемыми оптимизацией остаточной рекурсии, рассмотрим две версии процедуры "суммировать". Эта процедура должна складывать друг с другом все числа из списка.
% + -
суммировать1 ([ ], 0).
суммировать1 ([N | R], Итог) : —
суммировать1 (R, Текущ_сумма),
Итог is N + Текущ_сумма.
% + +
суммировать2([ ], Итог, Итог).
суммировать2([N | R], Текущ сумма, Итог): —
НовТекущ_сумма is N + Текущ_сумма,
суммировать2(R, НовТекущ_сумма, Итог) .
| ?-суммировать1 ([2,2], Т1).
Т1=4
| ?-. суммировать2([2,2],0,Т2).
Т2=4
Компилятор не применит оптимизацию остаточной рекурсии к процедуре "суммировать1", так как в момент вызова рекурсивной подцели (« суммировать 1 (R, Текущ_сумма »)) остается еще одна подцель, которая должна быть выполнена. Компилятор употребит, однако, оптимизацию остаточной рекурсии в случае процедуры "суммировать2", поскольку к моменту вызова рекурсивной подцели («суммировать 2 (Р, НовТекущ_сумма, Итог »)) все предыдущие подцели (« НовТекущ_сумма is N + Текущ_сумма ») являются детерминированными, а после рекурсив- ной подцели не располагаются никакие другие подцели.