Иван Братко - Программирование на языке Пролог для искусственного интеллекта
'рыжевато-коричневый цвет' и
Животное имеет 'черные полосы'
то
Животное это тигр.
прав6: если
Животное это птица и
Животное 'не может' летать и
Животное плавает
то
Животное это пингвин.
прав7: если
Животное это птица и
Животное летает хорошо
то
Животное это альбатрос.
факт: X это животное :-
принадлежит( X, [гепард, тигр, пингвин, альбатрос]).
можно_спросить( _ 'кормит детенышей' _,
'Животное' 'кормит детенышей' 'Чем').
можно_спросить( _ летает, 'Животное' летает).
можно_спросить( _ откладывает яйца,
'Животное' откладывает яйца).
можно_спросить( _ ест _, 'Животное' ест 'Что').
можно_спросить( _ имеет _,'Животное' имеет 'Нечто').
можно_спросить( _ 'не может' _,
'Животное' 'не может' 'Что делать').
можно_спросить( _ плавает, 'Животное' плавает).
можно_спросить( _ летает хорошо,
'Животное' летает хорошо).
Рис. 14.5. Простая база знаний для идентификации животных. Заимствовано из Winston (1984). Отношение "можно_спросить" определяет вопросы, которые можно задавать пользователю. Операторы если, то, и, или определены на рис. 14.10.
Рассмотрим еще одну небольшую базу знаний, которая может помочь локализовать неисправности в простой электрической схеме, состоящей из электрических приборов и предохранителей. Электрическая схема показана на рис. 14.6. Вот одно из возможных правил:
если
лампа1 включена и
лампа1 не работает и
предохранитель1 заведомо цел
то
лампа1 заведомо неисправна.
Вот другой пример правила:
если
радиатор работает
то
предохранитель1 заведомо цел.
Рис. 14.6. Соединения между предохранителями и приборами в простой электрической схеме.
Эти два правила опираются на некоторые факты (относящиеся к нашей конкретной схеме), а именно что лампа1 соединена с предохранитель1 и что лампа1 и радиатор имеют общий предохранитель. Для другой схемы нам понадобится еще один набор правил. Поэтому было бы лучше сформулировать правила в более общем виде (используя прологовские переменные) так, чтобы они были применимы к любой схеме, а затем уже дополнять их информацией о конкретной схеме. Например, вот одно из полезных правил: если прибор включен, но не работает, а соответствующий предохранитель цел, то прибор неисправен. На наш формальный язык это транслируется так:
правило_поломки:
если
Прибор включен и
не (Прибор работает) и
Прибор соединен с Предохранитель и
Предохранитель заведомо цел
то
Прибор заведомо неисправен.
База знаний такого рода показана на рис. 14. 7.
% Небольшая база знаний для локализации неисправностей в
% электрической схеме
% Если прибор включен, но не работает, и предохранитель цел,
% то прибор неисправен.
правило_поломки:
если
вкл( Прибор) и
прибор( Прибор) и
не работает( Прибор) и
соед( Прибор, Предохр) и
доказано( цел( Предохр) )
то
доказано( неиспр( Прибор) ).
% Если устройство работает, то его предохранитель цел
правило_цел_предохр:
если
соед( Прибор, Предохр)
и работает( Прибор)
то
доказано( цел( Предохр) ).
% Если два различных прибора подключены к одному и тому же
% предохранителю, оба включены и не работают, то предохранитель
% сгорел.
% ЗАМЕЧАНИЕ: предполагается, что из двух приборов неисправных -
% не более одного!
правило_предохр:
если
соед( Прибор1, Предохр) и
вкл( Прибор1) и
не работает( Прибор1) и
общ_предохр( Прибор2, Прибор1) и
вкл( Прибор2) и
не работает( Прибор2)
то
доказано( сгорел( Предохр) ).
правило_общ_предохр:
если
соед( Прибор1, Предохр) и
соед( Прибор2, Предохр) и
различны( Прибор1, Прибор2)
то
общ_предохр( Прибор1, Прибор2).
факт: различны( X, Y) :- not (X=Y).
факт: прибор( радиатор).
факт: прибор( лампа1).
факт: прибор( лампа2).
факт: прибор( лампа3).
факт: прибор( лампа4).
факт: соед( лампа1, предохр1).
факт: соед( лампа2, предохр1).
факт: соед( радиатор, предохр1).
факт: соед( лампа3, предохр2).
факт: соед( лампа4, предохр2).
можно_спросить( вкл( П), вкл( 'Прибор') ).
можно_спросить( работает( П), работает(' Прибор')).
Рис. 14.7. База знаний для локализации неисправностей в схеме, показанной на рис. 14.6.
Упражнения
14.1. Рассмотрите "если-то"-правила рис. 14.2-14.4 и транслируйте их в нашу систему обозначений для правил. Предложите расширение нотации, чтобы, при необходимости, можно было работать с оценками уверенности.
14.2. Придумайте какую-нибудь задачу принятия решений и сформулируйте соответствующие знания в форме "если-то"-правил. Можете рассмотреть, например, планирование отпуска, предсказание погоды, простой медицинский диагноз и лечение и т.п.
14.4. Разработка оболочки
Если мы посмотрим на правила наших двух маленьких баз знаний рис. 14.5 и 14.7, мы сразу увидим, что они по своему смыслу эквивалентны правилам Пролога. Однако, с точки зрения синтаксиса Пролога, эти правила в том виде, как они написаны, соответствуют всего лишь фактам. Для того, чтобы заставить их работать, самое простое, что может прийти в голову, это переписать их в виде настоящих прологовских правил. Например:
Животное это млекопитающее :-
Животное имеет шерсть;
Животное 'кормит детенышей' молоком.
Животное это хищник :-
Животное это млекопитающее,
Животное ест мясо.
...
Теперь эта программа сможет подтвердить, что тигр по имени Питер — это действительно тигр, если мы добавим в нее некоторые из свойств Питера (в виде прологовских фактов):
питер имеет шерсть.
питер ленив.
питер большой.
питер имеет 'рыжевато-коричневый цвет'.
питер имеет 'черные полосы'.
питер ест мясо.
Тогда мы можем спросить:
?- питер это тигр.
yes
?- питер это гепард.
no
Хотя пролог-система и отвечает на вопросы, используя для этого нашу базу знаний, нельзя сказать, что ее поведение вполне соответствует поведению эксперта. Это происходит по крайней мере по двум причинам:
(1) Мы не можем попросить систему объяснить свой ответ; например, как она установила, что Питер это тигр, и почему Питер это не гепард.
(2) Прежде, чем задать вопрос, нужно ввести в систему всю необходимую информацию (в виде прологовских фактов). Но тогда пользователь, возможно, введет какую-нибудь лишнюю информацию (как в нашем примере) или же упустит какую-нибудь информацию, имеющую решающее значение. В первом случае будет проделана ненужная работа, а во втором - система будет давать неверные ответы.
Для того, чтобы исправить эти два недостатка, мы нуждаемся в более совершенном способе взаимодействия между пользователем и системой во время и после завершения процесса рассуждений. Поставим себе целью добиться того, чтобы система взаимодействовала с пользователем так, как в следующем примере диалога (ответы пользователя даются полужирным шрифтом, реплики пролог-системы — курсивом):
Пожалуйста, спрашивайте:
питер это тигр.
Это правда: питер имеет шерсть?
да.