- •Глава 3 управление ходом выполнения программы
- •3. 1. Как выполняется запрос в прологе
- •Три семантические модели
- •Выполнение запроса
- •Правила, описывающие унификацию термов
- •Пример с программой "дядя"
- •Активация запроса
- •Унификация запроса
- •Обработка тела фразы
- •Обработка подцели "брат"
- •Обработка подцели "отец"
- •Неудача запроса и возврат назад
- •Поиск третьего ответа
- •Поиск несуществующих ответов
- •Выполнение запроса к правилу "регистрация"
- •Автоматический просмотр выполнения программы
- •3.2. Предикат "сократить" Пространство поиска запроса
- •Предикат "сократить" останавливает возврат назад
- •Влияние предиката "сократить" на составной запрос
- •Влияние предиката "сократить" на процедуру
- •Предикат "сократить" как подцель в составном запросе
- •Использование предиката "сократить" для того, чтобы сделать процедуру детерминированной
- •Применение предиката "сократить" для отбрасывания части пространства поиска
- •Ограничение сферы действия предиката "сократить"
- •Общее правило ограничения сферы действия предиката "сократить"
- •3. 3. Отрицание как неудача запроса Негативная информация
- •Предположение о замкнутости мира
- •Тогда и только тогда, когда
- •Предположение об открытости мира
- •Отрицание в явной форме
- •Пример процедуры, поведение которой соответствует предположению об открытости мира
- •3. 4. Встроенные предикаты, предназначенные для обеспечения ввода-вывода Побочные эффекты ввода-вывода
- •Пример запроса, в котором используется предикат "read"
- •3. 5. Встроенные предикаты, предназначенные для управления файлами
- •3. 6. Проверка типа терма
- •Использование предикатов "var" и "nonvar"
- •3. 7. Действия с текущей программой
- •Изменение значения факта
- •Алгоритм поиска с возрастом, в котором используется предикат "assert"
- •Процедура, которая учится у пользователя
- •Программа, которая модифицирует сама себя
- •3. 8. Компараторы
- •3. 9. Прочие встроенные предикаты
- •Программа ввода "вводполя"
- •3. 10. Операции Расширяемость синтаксиса языка Пролог
- •Инфиксная операция ",", обладающая правой ассоциативностью
- •Инфиксная операция, не обладающая свойством ассоциативности
- •Объявление операций
- •3. 11. Преобразование процедурного алгоритма в программу на языке пролог Сравнение поиска с возвратом и рекурсии
- •Цикл "пока"
- •Рекурсия
- •Поиск с возвратом
- •Применение предиката "findall"
- •Библиографические заметки
- •Упражнения
3. 10. Операции Расширяемость синтаксиса языка Пролог
Внешняя форма синтаксиса языка Пролог расширяема в том смысле, что предикат или структуру с одним или двумя аргументами можно объявить операцией. Это достигается путем обращения к встроенному предикату "ор/3".
Предикат или структуру с двумя аргументами можно объявить инфиксной операцией. Обозначение инфиксной операции записывается между ее аргументами, а скобки при этом не нужны. Предикат или структуру с одним аргументом можно объявить либо префиксной, либо постфиксной операцией.
Ряд операций в языке Пролог определен изначально. Примером встроенного предиката, являющегося операцией, может служить предикат "is". Структуры "+", "—" и т. д. также являются операциями.
ор (Старшинство, Тип, Имя)
Имя (третий аргумент предиката "ор") должно быть атомом. Обращение к "ор" равнозначно объявлению этого имени названием операции. «Старшинство» — это число, используемое для того, чтобы избежать неоднозначностей в выражениях, в состав которых входит более одной операции. Конкретный диапазон допустимых значений старшинства операций будет зависеть от версии языка Пролог. К примеру, если операция "*" обладает более высоким старшинством, чем операция "+", то будут эквивалентными такие выражения:
X+ Y* Z
Х+ (Y* Z)
+ (X,* (Y, Z))
Для изменения порядка выполнения операций, определяемого их старшинством, всегда можно воспользоваться скобками.
Тип может принимать одно из следующих значений:
инфиксные операции xfx xfy yfx
префиксные операции fx fy
постфиксные операции xf yf
Инфиксная операция "+", обладающая левой ассоциативностью
Операция "+" обладает такими свойствами, как если бы она была объявлена следующим образом:
|? -op (500, yfx,+).
да
Тип yfx означает, что операция "+" обладает свойством левой ассоциативности. Так, выражение
A+ B+ C+ D, т. е.+ (+ (+ (A, B), C), D)
можно представить в виде дерева, "растущего" вниз и влево рис. 3. 1).
Инфиксная операция ",", обладающая правой ассоциативностью
Операция "," обладает такими свойствами, как если бы она была введена при помощи объявления:
|? -ор (1000, xfy,,).
да
Тип xfy означает, что операция "," обладает свойством правой ассоциативности. Выражение
A, B, C, D т. е., (А,, (В,, (С, D)))
можно представить в виде дерева, "растущего" вправо (рис. 3. 2).
Инфиксная операция, не обладающая свойством ассоциативности
Тип xfx означает, что операция не обладает ни левой, ни правой ассоциативностью. Примером операции этого типа может служить операция "mod". Поэтому выражение, в котором одно подвыражение с операцией "mod" выступает в качестве аргумента другого, например,
|? - Х is 120 mod 50 mod 5.
является недопустимым. Такое выражение вызовет выдачу диагностического сообщения о синтаксической ошибке.
Объявление операций
Если Вы составляете процедуру с одним или двумя аргументами, которой будете часто пользоваться, то можно объявить имя процедуры как операцию. Наиболее важный критерий, которым следует руководствоваться при принятии такого решения, - это читабельность программы. Применение одних операций будет способствовать улучшению читабельности программы, в то время как употребление ряда других операций, смысл которых не столь очевиден, может привести к тому, что в программе никто, включая самого автора, не сможет разобраться.
В следующей команде "знает" объявляется как инфиксный предикат:
|? -ор (750, xfx, знает).
да
Теперь факты "знает" можно представлять в текущей программе в инфиксной форме:
джейк знает бетти.
сюзан знает мери.
Запросы к этой базе данных можно также записывать в инфиксной форме:
|? -Х знает мери.
Х = сюзан
Условная конструкция "— >"
Еще одним примером операции служит предикат "->", определение которого приводится ниже. Этот предикат употребляется некоторыми программистами как условная конструкция, позволяющая расширить возможности стандартного соединителя "или", обозначаемого символом;. Первым аргументом предиката "—>" является подцель А, а вторым аргументом — выражение с соединителем "или", т. е. В; С. Если подцель А окажется истинной, то далее будет обрабатываться подцель В, а подцель С будет проигнорирована. Если же подцель А потерпит неудачу, то будет выполняться подцель С, а подцель В игнорируется.
|? - ор (1101, xfy, ->).
да
% читается: если А, то В, иначе С.
(А-> В; С): -А,!, В.
(А -> В; С): - С.
служащий (джейн).
служащий (салли).
начальник (салли).
|?— служащий (X),
) начальник (X) -> write (' не приглашать');
write С пригласить ')),
write (Х), n1,
fail.
пригласить джейн
не приглашать салли
нет