Программа "найти_или_спросить"

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

Имея в виду изложенное выше, предположим, что мы составляем процедуру общего назначения, в которой применяется такой же подход к работе с неизвестной информацией, как и в программе "место". Новая процедура носит название "найти_или_спросить", так как если она не сможет найти нужные сведения в базе данных, то попросит пользователя предоставить эти сведения. Программа "найти_или_спросить" будет работать только с такими отношениями и атрибутами, сведения о которых разрешено запрашивать в соответствии с фразой "можно_запрашивать".

Аргументом процедуры "найти_или_спросить" является запрос. Процедура пытается выполнить этот запрос. Если запрос будет успешным, то процедура "найти_или_спросить" просто выдаст результат. Если же запрос потерпит неудачу, то процедура проверит по специальной базе данных "можно_запрашивать", можно ли задавать пользователю вопрос об ответе. Если предикат содержится в базе данных "можно—запрашивать", то процедура "найти_или_спросить" попросит пользователя ввести отсутствующую информацию, добавит ранее введенный запрос как факт в текущую программу и выдаст значение, введенное пользователем. Если предикат не попадает в категорию "можно_запрашивать", то запрос к "найти_или_спросить" терпит неудачу.

найти_или_спросить (Запрос): -

Запрос.

найти_или_спросить (3апрос): -

можно_запрашивать (Запрос, Подсказка, Значение),

var ( Значение),

write (Запрос), n1,

write (Подсказка), write (' '),

read (Значение),

assert (Запрос).

% Факт

можно_запрашивать (путешествие (А, Б, Вид_трансп),

% Подсказка Переменная

‘введите вид транспорта: ',Вид_трансп): -

nonvar (A), nonvar (B).

путешествие (манхэттен, куинс, жел_дорога).

Программой "найти_или_спросить" можно воспользоваться следующим образом:

|?—найти_или_спросить (путешествие (манхэттен, куинс, Т)). %1

Т = жел_дорога

|? -найти_или_спросить (путешествие (манхэттен. бруклин, Т)). %2

путешествие (манхэттен, бруклин, _0)

введите вид транспорта: метро

Т = метро

|? найти_или_спросить (путешествие (манхэттен, бруклин. Т)). %3

Т = метро

Запрос (2) показывает, как ведет себя программа "наити_или_спросить", если попросить ее выдать сведения о виде транспорта, которым можно добраться из одного неизвестного программе пункта в другой. Заметьте, что при выполнении запроса (3) факт «путешествие (манхэттен, бруклин, метро)» уже содержится в программе, и поэтому процедура ни о чем не спрашивает пользователя.

Соседние файлы в папке Гл.0,1,2,3,4,5,Предисловие