- •Глава 4
- •Введение
- •Три точки зрения на Пролог-программу
- •4. 1. Реляционный подход
- •Изображение отношений
- •Ограничения, обеспечивающие целостность, которые накладываются при записи отношений в программу
- •Ограничения, обеспечивающие целостность, накладываемые при выборке фраз
- •Реализация свойств отношений
- •Нерефлексивность
- •Симметричное и транзитивное отношение
- •Первая попытка
- •Вторая попытка
- •Запоминание списка посещенных мест
- •4. 2. Взгляд на программу с точки зрения потока данных Переход от выходного потока данных к программе
- •Упорядоченные множества ответов
- •Генерирование бесконечного множества
- •Экологический процесс
- •Версия программы, в которой применяется поиск с возвратом
- •Рекурсивная версия программы
- •Планирование производственных операций
- •Сильные и слабые стороны подхода к программе с позиций потока данных
- •4.3. Бихевиористический подход Приведенные ранее примеры, в которых проявился бихевиористический подход
- •Ограничение сферы действия эффектов поведения
- •Программа "найти_или_спросить"
- •Оценка бихевиористического подхода
- •Библиографические заметки
- •Упражнения
Программа "найти_или_спросить"
При программировании, однако, возникают ситуации, в которых требуется обеспечить такое поведение программы, какого нельзя добиться при простых запросах к базам данных Пролога. В категорию таких программ обычно попадают компоненты больших программ, обеспечивающие интерфейс с пользователем, так как вряд ли следует ожидать, что при применении программы пользователь будет самостоятельно вводить Пролог-запросы. Другим примером такой ситуации служит поведение программы "место": когда эта программа не может найти ответ в базе данных "адрес", она спрашивает ответ у пользователя, а затем добавляет полученный ответ в базу данных.
Имея в виду изложенное выше, предположим, что мы составляем процедуру общего назначения, в которой применяется такой же подход к работе с неизвестной информацией, как и в программе "место". Новая процедура носит название "найти_или_спросить", так как если она не сможет найти нужные сведения в базе данных, то попросит пользователя предоставить эти сведения. Программа "найти_или_спросить" будет работать только с такими отношениями и атрибутами, сведения о которых разрешено запрашивать в соответствии с фразой "можно_запрашивать".
Аргументом процедуры "найти_или_спросить" является запрос. Процедура пытается выполнить этот запрос. Если запрос будет успешным, то процедура "найти_или_спросить" просто выдаст результат. Если же запрос потерпит неудачу, то процедура проверит по специальной базе данных "можно_запрашивать", можно ли задавать пользователю вопрос об ответе. Если предикат содержится в базе данных "можно—запрашивать", то процедура "найти_или_спросить" попросит пользователя ввести отсутствующую информацию, добавит ранее введенный запрос как факт в текущую программу и выдаст значение, введенное пользователем. Если предикат не попадает в категорию "можно_запрашивать", то запрос к "найти_или_спросить" терпит неудачу.
найти_или_спросить (Запрос): -
Запрос.
найти_или_спросить (3апрос): -
можно_запрашивать (Запрос, Подсказка, Значение),
var ( Значение),
write (Запрос), n1,
write (Подсказка), write (' '),
read (Значение),
assert (Запрос).
% Факт
можно_запрашивать (путешествие (А, Б, Вид_трансп),
% Подсказка Переменная
‘введите вид транспорта: ',Вид_трансп): -
nonvar (A), nonvar (B).
путешествие (манхэттен, куинс, жел_дорога).
Программой "найти_или_спросить" можно воспользоваться следующим образом:
|?—найти_или_спросить (путешествие (манхэттен, куинс, Т)). %1
Т = жел_дорога
|? -найти_или_спросить (путешествие (манхэттен. бруклин, Т)). %2
путешествие (манхэттен, бруклин, _0)
введите вид транспорта: метро
Т = метро
|? найти_или_спросить (путешествие (манхэттен, бруклин. Т)). %3
Т = метро
Запрос (2) показывает, как ведет себя программа "наити_или_спросить", если попросить ее выдать сведения о виде транспорта, которым можно добраться из одного неизвестного программе пункта в другой. Заметьте, что при выполнении запроса (3) факт «путешествие (манхэттен, бруклин, метро)» уже содержится в программе, и поэтому процедура ни о чем не спрашивает пользователя.