Процедура useranswer

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

В ходе диалога от пользователя часто требуется, чтобы он ответил словом "yes", "по" или "why". Назначение процедуры get reply состоит в получении подобного от­вета от пользователя, а также в правильном преобразовании этого ответа, если поль­зователь вводит сокращение ("у" или "п") или допускает опечатку. А если ответ пользователя невозможно понять, то getreply запрашивает у него другой ответ.

Следует отметить, что процедура getreply должна использоваться с осторожно­стью, поскольку в ней предусмотрено взаимодействие с пользователем с помощью предикатов read и write, поэтому она может трактоваться только процедурно, а не декларативно. Например, если процедура getreply будет вызвана на выполнение следующим образом: getreplyl yes)

а пользователь введет "по", то процедура не сможет сопоставить два разных атома и выдаст ответ; "Answer unknown, try again please" (Ответ непонятен, сделайте, пожалуйста, еще одну попытку). Поэтому процедуру getreply следует вызывать с неконкретизированным параметром, например, как показано ниже. getreplyt Reply),

.-( Reply - yes, interpret yes ( ...! Reply = no, interpret»©! ...}

Процедура useranswer; Goal, Trace, Answer)

запрашивает у пользователя информацию, касающуюся цели Goal, а результатом этого запроса является ответ Answer. Трассировка Trace используется для выдачи объяснения в том случае, если пользователь спрашивает "why". Процедура useranswer должна вначале проверить, относится ли Goal к информации того типа, о которой можно спрашивать пользователя. В данном командном интерпретаторе це­ли такого рода обозначены как "askable" (запрашиваемые). Для начала предполо­жим, что запрашиваемые сведения определены с помощью следующего отношения; askable С Goal)

Это определение будет уточнено позднее. Если цель Goal относится к типу "askable", то эта цель отображается и пользователь должен указать, является ли она истинной или ложной. В том случае, если пользователь спрашивает, для чего по­требовалась эта информация, введя вопрос "why", отображается трассировка Trace.

Глава 16. Командный интерпретатор экспертной системы 369


Цель Goal является истинной, если пользователь задает также необходимые значе­ния переменных в цели Goal (при условии, что они имеются) . Первая попытка ре-шить эти задачи в программе может состоять в следующем:

useranswer Goal, Trace, Answer) :-

askable [ Goal) , ask( Goal, Trace, Answer).
пользователю с запросом,
запросом,

* Можно ли обращаться к % касающимся цели Goal? % Обратиться к пользователю касающимся цели Goal

Вывести запрос к пользователю Прочитать ответ пользователя

ask( Goal, Trace, Answer) :-introduce! Goal) , getreply t Reply) , process! Reply, Goal, Trace,

Answer) . » Обработать ответ

process(
Goal, Trace, Answer)
для чего

% Пользователь спросил,

% нужна эта информация

showtraceC Trace), ask< Goal, Trace, Answer). process! yes, Goal, Trace, Answer) Answer - true, askvars[ Goal)

i Показать трассировку

% Снова вывести запрос

что цель Goal

% Пользователь сообщил,

% является истинной

i Задать вопрос, касающийся переменных

ask( Goal, Trace, Answer). * Запросить дополнительные решения process) no. Goal, Trace, false) . % Пользователь сообщил, что цель Goal

i является ложной


introduce! Goal) :-

nl, write! Ts it true: '), write 1 Goal) , writet ?) , nl.

После вызова процедуры askvars { Goal) пользователь получает запрос ввести значение каждой переменной в цели Goal, следующим образом:

askvars ( Terra) :-

var( Term), !, % Переменная?

nl, write! Term), write ( ' — ' ) ,

read( Term), I Прочитать значение переменной

askvars t Terra) :-

Term ■=.. [Functor Args], % Получить параметры структуры

askarglist(Args). I Задать вопрос, касающийся переменных в параметрах

askarglist([)).

askarglist( [Term ] Terms]) :-

askvars( Term),

askarglist! Terms) .

Проведем несколько экспериментов с процедурой useranswer. Например, пред­положим, что в виде "askable" объявлено бинарное отношение eats, как показано ниже . askable[ X eats Y) .

пользователем текст, введенный

Б следующем диалоге между системой Prolog пользователем, обозначен полужирным шрифтом.

?-useranswert peter eats meat,[],Answer).

пользователю
% Ответ пользователя

Is ittrue: peter eats meat? * Запрос

yes .

true

Answer

Более интересный пример, в котором используются переменные, может выглядеть


следующим образом:

?- -jserar.swer . Who eats What, Is it true: _17 eats _1S?

yes.

_17 = peter. 18 = meat.


[ ) , Answer) .

% Система Prolog присваивает переменным % внутренние имена

% Запрос, касающийся переменных


 



Часть II. Применение языка Prolog в области искусственного интеллекта


Answer = true

Who = peter

What = meat % Перебор с возвратами для получения дополнительных решений

Is it true: _17 eats _18?

yes.

_17 = susan.

_18 = bananas.

Answer = true

Who = susan

What = bananas;

Is it true: eats _18?

no.

Answer = false