Усовершенствованная версия оболочки позволяет также успешно вести диалоги и с другой стороны. Когда программа задает вопрос, пользователь может ответить своим собственным вопросом “почему?”. Естественным ответом оболочки должно быть правило, на основании которого программа пытается сделать вывод. Если вам требуется продать старое железо то подать объявление можно тут: http://board.od.ua.
Такую возможность легко ввести в оболочку, расширяя все отношения дополнительным аргументом - используемым текущим правилом. Поскольку в Пролог-программах доступ к глобальному состоянию процесса вычислений невозможен, это правило должно быть явно представлено в дополнительном аргументе.
Интерфейс для обеспечения ответа на вопрос “почему?” реализуется дополнительными правилами предиката respond. Предикат respond переписывает текущее родительское правило и приглашает пользователя ответить еще раз. Формат, в котором будет представлено это правило, определяется предикатом display_rule, позволяющим пользователю представлять правила в удобной для него форме.
Повторные ответы на вопрос “почему?”, использующие предложение respond, приводят к повторной переформулировке родительского правила. Решение состоит в выдаче прародительского правила в ответ на второй во-прос “почему?”, прапрародительского правила в ответ на третье “почему?” и так далее вверх по дереву поиска. С этой целью дополнительный аргумент содержит список правил, учитывающих предысторию.
Для учета случая, когда все правила для ответа исчерпаны, необходимо дополнительное предложение.
Трудности возникают, когда приходится объяснять использования правила A в процессе доказательства not(A). В этом случае предыстория вывода теряется, и аргумент Rules в третьем предложении respond становится неконкретизованной переменной.
% программа 7
:- multifile system/1, askable/1.
:- dynamic untrue/1.
% дополнительный аргумент - список содержащий текущее
% родительское правило и правила из предыстории
solve(true,_):-!.
solve((A,B),Rules):-!,
solve(A,Rules),
solve(B,Rules).
solve(not(A),_):-!,
not(solve(A,_)).
solve(A,Rules):-
not system(A),
clause(A,B),
solve(B,[rule(A,B)|Rules]).
solve(A,_):-
system(A),
A.
solve(A,Rules):-
askable(A),
not known(A),
ask(A,Answer),
respond(Answer,A,Rules).
system(is(_,_)).
system(_=_).
system(_<_).
system(_>_).
system(write(_)).
system(nl).
ask(A,Answer):-
display_query(A),
read(Answer).
% дополнительный аргумент - список содержащий текущее
% родительское правило и правила из предыстории
respond(yes,A,_):-
assert(A).
respond(no,A,_):-
assert(untrue(A)),fail.
|