close

Вход

Забыли?

вход по аккаунту

?

up logprogram 2014

код для вставкиСкачать
В. С. Зурахов
ЛОГИЧЕСКОЕ
ПРОГРАММИРОВАНИЕ
Министерство образования и науки Российской Федерации
Федеральное государственное бюджетное образовательное учреждение
высшего профессионального образования
«Санкт-Петербургский государственный университет технологии и дизайна»
В. С. Зурахов
ЛОГИЧЕСКОЕ
ПРОГРАММИРОВАНИЕ
Утверждено Редакционно-издательским советом
университета в качестве учебного пособия
Санкт-Петербург
2014
УДК 004.42(075.8)
ББК 32.973-018я73
З94
Рецензенты:
доктор экономических наук, профессор
Санкт-Петербургского экономического университета Е. В. Стельмашонок;
кандидат технических наук, профессор
Санкт-Петербургского государственного университета технологии и дизайна Е. Г. Суздалов
З94
Зурахов, В. С.
Логическое программирование: учеб. пособие / В. С. Зурахов. –
СПб.: ФГБОУВПО «СПГУТД», 2014. – 96 с.
ISBN 978-5-7937-1015-2
Учебное пособие рассматривает разделы дисциплины «Логическое
программирование», обязательной в подготовке бакалавров по направлению
036000.62 – Интеллектуальные системы в гуманитарной сфере. Материал
подобран с позиций минимальной необходимости, но достаточности получаемых
знаний. К каждой рассматриваемой теме предлагается практическое задание.
Наличие подобных заданий с рекомендациями по их выполнению позволяет
использовать пособие для организации самостоятельной работы.
Предназначено для студентов, обучающихся по направлению 036000.62 –
Интеллектуальные системы в гуманитарной сфере, и может быть использовано в
подготовке студентов других направлений, а также в системе повышения
квалификации преподавателей в области применения информационных
технологий в учебном процессе.
УДК 004.42(075.8)
ББК 32.973-018я73
ISBN 978-5-7937-1015-2
© ФГБОУВПО «СПГУТД», 2014
© Зурахов В. С., 2014
ОГЛАВЛЕНИЕ
ВВЕДЕНИЕ .................................................................................................................. 4
1. ПРИНЦИПЫ ЛОГИЧЕСКОГО ПРОГРАММИРОВАНИЯ ................................ 6
1.1. БАЗОВЫЕ ПОНЯТИЯ ............................................................................................. 6
1.2. ТЕРМИНОЛОГИЯ ................................................................................................ 12
1.3. СЛОЖНЫЕ ТЕРМЫ, ИЛИ СТРУКТУРЫ ................................................................. 16
1.4. СИНТАКСИС СТРОК ........................................................................................... 17
1.5. УТВЕРЖДЕНИЯ .................................................................................................. 18
1.6. ЗАПРОСЫ ........................................................................................................... 19
1.7. ВВОД ПРОГРАММ............................................................................................... 20
1.8. УНИФИКАЦИЯ ................................................................................................... 21
1.9. АРИФМЕТИЧЕСКИЕ ВЫРАЖЕНИЯ ...................................................................... 21
1.10. ВЫЧИСЛЕНИЕ АРИФМЕТИЧЕСКИХ ВЫРАЖЕНИЙ ............................................. 23
1.11. СРАВНЕНИЕ РЕЗУЛЬТАТОВ АРИФМЕТИЧЕСКИХ ВЫРАЖЕНИЙ ......................... 24
2. СТРУКТУРЫ ДАННЫХ НА ЯЗЫКЕ ПРОЛОГ ................................................ 26
2.1. СПИСКИ............................................................................................................. 26
2.2. БИНАРНЫЕ ДЕРЕВЬЯ .......................................................................................... 35
2.3. МЕХАНИЗМ ВОЗВРАТА И ПРОЦЕДУРНАЯ СЕМАНТИКА ...................................... 39
3. ПРЕДСТАВЛЕНИЕ МОДЕЛЕЙ ЗНАНИЙ ........................................................ 47
3.1. ПРОЦЕСС ПРЕДСТАВЛЕНИЯ ЗНАНИЙ ................................................................. 47
3.2. СЕМАНТИЧЕСКИЕ СЕТИ ..................................................................................... 52
3.3. ФРЕЙМЫ............................................................................................................ 53
3.4. МЕХАНИЗМ НАСЛЕДОВАНИЯ В ПРОЛОГЕ ......................................................... 56
3.5. СОЗДАНИЕ ДИНАМИЧЕСКИХ БАЗ ДАННЫХ ........................................................ 63
3.6. ПРЕДСТАВЛЕНИЕ ЗАДАЧ В ВИДЕ И/ИЛИ-ГРАФОВ ............................................ 68
4. ЭКСПЕРТНЫЕ СИСТЕМЫ ................................................................................. 73
4.1. СИСТЕМЫ ЭКСПЕРТНЫХ КОНСУЛЬТАЦИЙ ......................................................... 73
4.2. ЗАПОМИНАНИЕ ПУТИ ВЫВОДА ......................................................................... 86
5. ПРИМЕР ЗАДАЧИ НА ПРЕДСТАВЛЕНИЕ ЗНАНИЙ .................................... 92
ЗАКЛЮЧЕНИЕ ......................................................................................................... 95
БИБЛИОГРАФИЧЕСКИЙ СПИСОК...................................................................... 96
ВВЕДЕНИЕ
В настоящее время для удовлетворения экспоненциально растущих
информационных запросов часто бывает недостаточно изменений только в
соответствующем программном обеспечении. Информационные запросы порой
уже не ограничиваются проблемами расширения функций, а многие
принципиальные постановки задач требуют коренного пересмотра всего
комплекса программ. При этом знания, заложенные в программы, например для
автоматизированных предприятий, не изменяются относительно нового
запроса, а могут лишь дополняться в связи с новыми формами производства
или изменением состава оборудования. Здесь, на границе возможностей
применения процедурного программирования, начинается совсем другая
область, а именно область интеллектуального программирования, некоторым
вопросам применения которого посвящено данное учебное пособие.
Интеллектуальное программирование предназначено для получения знаний в
форме композиции новых фактов ("knowledge mining" вместо используемого
сегодня "data mining") из технологии работы с базами данных. Основные
преимущества
применения
интеллектуального
программирования
(программирование без программистов) заключаются в
использовании
подмножеств естественного языка; в построении парадигмы отладки знаний;
расширении
области
применения
компьютеров;
формировании
инструментария, аналогичного, например, системе Паскаль, но без таких
формализмов, как операторы.
Целью данного пособия является освещение вопросов представления
знаний методами логического программирования, изучаемых в курсах
«Информационные технологии» и «Системы искусственного интеллекта и
нейрокомпьютеры» [1].
В
частности,
рабочая программа курса
«Информационные технологии» предусматривает изучение таких вопросов, как
информационные технологии логического программирования; логическое
программирование на языке Пролог; логика высказываний; логика предикатов;
синтаксис языка Пролог; фразы Хорна как средство представления знаний;
арифметика и структуры данных; списки; способы представления базы данных
на языке Пролог и другие, а рабочая программа курса «Системы
искусственного интеллекта и нейрокомпьютеры» предусматривает изучение
методов представления знаний; семантических сетей, фреймов, построения
экспертных систем и т. п.
Необходимость издания пособия вызвана тем, что имеющаяся литература
недостаточно полно освещает ряд специальных вопросов, возникающих в
процессе изучения данных курсов. В литературе по языку Пролог, как правило,
дается лишь общий синтаксис языка, без указаний по его применению в
системах баз данных и знаний. В то же время литература, посвященная
искусственному интеллекту, освещает модели представления знаний
применительно, в основном, к робототехническим комплексам, а не к
информационным технологиям логического программирования.
4
В связи с этим излагаемый в данном пособии материал кроме описания
базового синтаксиса содержит примеры создания баз данных и экспертных
систем, а также механизм реализации на языке Пролог таких моделей
искусственного интеллекта, как семантические сети и фреймы.
Иными словами, предлагаемое учебное пособие кроме изучения общего
теоретического материала позволяет изучить процесс создания систем и
моделей представления знаний, ориентированных на язык логического
программирования Пролог как с точки зрения информационных технологий,
так и с точки зрения искусственного интеллекта.
5
1. ПРИНЦИПЫ ЛОГИЧЕСКОГО ПРОГРАММИРОВАНИЯ
1.1. Базовые понятия
Развитие систем баз данных первоначально было мотивировано
потребностью в эффективных средствах хранения, манипуляции и извлечения
большого количества разнообразных данных. По мере того, как в достижении
этих целей наблюдался прогресс, возникла дополнительная заинтересованность
в возможности задавать информационным системам правила, применяемые к
хранимым фактам (данным), с тем, чтобы появилась возможность вывода
фактов, т. е. получения новых знаний.
Включение знаний в системы баз данных было подсказано
исследованиями в области искусственного интеллекта (ИИ), который
занимается вопросами программирования разумного поведения. Разработки в
области ИИ включали исследования представлений логических правил,
применяемых к данным. Экспертные системы (ЭС) — это особый раздел ИИ,
посвященный представлению правил и процедур, которым следует специалист,
решая задачи в конкретной предметной области. К таким областям относятся
медицина, планирование налогов, проектирование компьютеров и т. д. Таким
образом, экспертные системы (ЭС) можно определить как системы,
моделирующие процесс принятия решений специалистами в разных
предметных областях методами искусственного интеллекта [2], [3].
Хотя исследования в области экспертных систем значительно повлияли
на методы представления знаний, основанные на логических правилах,
экспертные системы не являются базами знаний, поскольку они не
обеспечивают полные возможности управления данными, присущие системам
управления базами данных (СУБД). Язык Пролог, наиболее популярный язык
экспертных систем, является естественным мостом между базами данных и
базами знаний. Этот язык основан на исчислении предикатов, а его предикаты
могут рассматриваться как реляционные таблицы. Кроме того, в нем имеется
возможность выражения той логики, которой пользуется человек, преобразуя
факты из базы данных в информацию, помогающую принимать решения [4].
В Средние века знание латинского и греческого языков являлось
существенной частью образования любого ученого. Ученый, владеющий
только одним языком, неизбежно чувствовал себя неполноценным, поскольку
он был лишен той полноты восприятия, которая возникает благодаря
возможности посмотреть на мир сразу с двух точек зрения. Таким же
неполноценным ощущает себя сегодняшний исследователь в области
искусственного интеллекта, если он не обладает основательным знакомством с
Лиспом и Прологом – основными языками искусственного интеллекта. Без
знания этих языков невозможен более широкий взгляд на предмет
исследования.
В самом широком смысле эволюция языков программирования – это
движение от языков низкого уровня, при использовании которых программист
6
описывает то, как что–либо следует делать, к языкам высокого уровня, на
которых просто указывается, что необходимо сделать. Так, например,
появление Фортрана освободило программистов от необходимости
разговаривать с машиной на языке адресов и регистров.
Однако Фортран, Си и большинство других языков программирования
все еще остаются языками типа «как». Чемпионом среди этих языков является,
пожалуй, современный модернизированный язык Лисп. Например, Common
Lisp, имея богатейшие выразительные возможности, позволяет программисту
описывать наиболее «выразительно» именно то, как что-либо следует делать. В
то же время Пролог порывает с традициями языков типа «как», поскольку он
определенным образом направляет программистское мышление, заставляя
программиста давать определения ситуаций и формулировать задачи вместо
того, чтобы во всех деталях описывать способ их решения. Программист только
сообщает системе то, что ему известно, и задает вопросы. Его в большей
степени интересуют знания и в меньшей – алгоритмы, при помощи которых из
этих знаний извлекается нужная информация.
Пролог – это язык программирования, предназначенный для обработки
символьной нечисловой информации [2]. Особенно хорошо он приспособлен для
решения задач, в которых фигурируют объекты и отношения между ними.
Для иллюстрации особенностей представления знаний на языке Пролог
(не вдаваясь в тонкости, которые будут рассмотрены далее в соответствующих
разделах), рассмотрим на примере описания родословной Иисуса из Евангелия
от Матфея. Как известно, эта родословная в Евангелии представлена в
следующем виде.
1. Родословие Иисуса Христа, Сына Давидова, Сына Авраамова.
2. Авраам родил Исаака; Исаак родил Иакова; Иаков родил Иуду и братьев его.
3. Иуда родил Фареса и Зару от Фамари; Фарес родил Есрома; Есром родил
Арама.
4. Арам родил Аминадава; Аминадав родил Наассона; Наассон родил Салмона.
5. Салмон родил Вооза от Рахавы; Вооз родил Овида от Руфи; Овид родил
Иессея.
6. Иессей родил Давида царя; Давид царь родил Соломона от бывшей за Уриею.
7. Соломон родил Ровоама; Ровоам родил Авию; Авия родил Асу.
8. Аса родил Иосафата; Иосафат родил Иорама; Иорам родил Озию.
9. Озия родил Иоафама; Иоафам родил Ахаза; Ахаз родил Езекию.
10. Езекия родил Манассию; Манассия родил Амона; Амон родил Иосию.
11. Иосия родил Иоакима; Иоаким родил Иехонию и братьев его, перед
переселением в Вавилон.
12. По переселении же в Вавилон, Иехония родил Салафииля; Салафииль родил
Зоровавеля.
13. Зоровавель родил Авиуда; Авиуд родил Елиакима; Елиаким родил Азора.
14. Азор родил Садока; Садок родил Ахима; Ахим родил Елиуда.
15. Елиуд родил Елеазара; Елеазар родил Матфана; Матфан родил Иакова.
7
16. Иаков родил Иосифа, мужа Марии, от Которой родился Иисус, называемый
Христос.
17. Итак всех родов от Авраама до Давида четырнадцать родов; и от Давида до
переселения в Вавилон четырнадцать родов; и от переселения в Вавилон до
Христа четырнадцать родов.
Суть задачи состоит в получении ответов на вопросы о типе родства тех
или иных имен, содержащихся в приведенной родословной. Для получения
ответов от системы данную родословную необходимо представить в более
формализованном виде. Тот факт, что Авраам является родителем Исаака, можно
записать на Прологе так:
Родитель (авраам, исаак).
Здесь мы выбрали родитель в качестве имени отношения, а авраам и
исаак – в качестве его аргументов. По причинам, которые станут понятны
позднее, мы записываем имена начиная со строчной буквы. В результате
поддерево дерева родственных отношений может быть описано следующей
пролог–программой:
родитель(авраам, исаак).
родитель(исаак, иаков).
родитель(иаков, иуда).
родитель(иуда, фарес).
родитель(иуда, зара).
родитель(фамарь, фарес).
родитель(фамарь, зара).
родитель(фарес, есром).
родитель(есром, арам).
родитель(арам, аминадав).
родитель(аминадав, наассон).
родитель(наассон, салмон).
родитель(салмон, вооз).
родитель(рахава, вооз).
родитель(вооз, овид).
родитель(руфь, овид).
родитель(овид, иессей).
Эта программа содержит 17 предложений. Каждое предложение
объявляет об одном факте наличия отношения родитель.
После ввода такой программы в пролог–систему последней можно будет
задавать вопросы, касающиеся отношения родитель. Например, является ли
Овид родителем Иессея? Этот вопрос можно передать пролог-системе, набрав
на клавиатуре терминала:
?– родитель(овид, иессей).
8
Найдя этот факт в программе, система ответит
yes (да).
Другим вопросом мог бы быть такой:
?– родитель(руфь, иессей).
Система ответит
nо
(нет),
поскольку в программе ничего не говорится о том, является ли Руфь родителем
Иессея. Программа ответит «нет» и на вопрос
?– родитель( соломон, вооз).
потому, что имя Соломон (в отличие от Салмон) в программе даже не
упоминается.
Можно задавать и более интересные вопросы. Например: "Кто является
родителем Аминадава?"
?– родитель( X, аминадав).
На этот раз система ответит не просто «да» или «нет». Она скажет нам,
каким должно быть значение X (ранее неизвестное), чтобы вышеприведенное
утверждение было истинным. Поэтому мы получим ответ:
X = арам
Вопрос «Кто дети Иуды?» можно передать пролог–системе в такой
форме:
?– родитель( иуда, X).
В этом случае возможно несколько ответов. Сначала система сообщит
первое решение:
X = фарес
Возможно, мы захотим увидеть и другие решения. О нашем желании мы
можем сообщить системе (во многих реализациях для этого надо набрать точку
с запятой), и она найдет другой ответ:
X = зара
Если мы потребуем дальнейших решений, система ответит «нет»,
поскольку все решения исчерпаны.
Нашей программе можно задавать и более общие вопросы: «Кто чей
родитель?» Приведем другую формулировку этого вопроса:
Найти X и Y такие, что X – родитель Y. На Прологе это записывается так:
?– родитель( X, Y).
Система будет по очереди находить все пары вида «родитель–ребенок».
По мере того, как мы будем требовать от системы новых решений, они будут
выводиться на экран одно за другим до тех пор, пока все они не будут найдены.
Ответы выводятся следующим образом:
X = авраам
Y = исаак;
X = исаак
Y = иаков;
9
X = иаков
Y = иуда;
...
Мы можем остановить поток решений, набрав, например, точку вместо
точки с запятой (выбор конкретного символа зависит от реализации).
Пролог-системе можно задавать и еще более сложные вопросы, скажем,
кто является родителем родителя Иакова? Поскольку в нашей программе прямо
не сказано, что представляет собой отношение родитель–родителя, такой
вопрос следует задавать в два этапа.
Кто родитель Иакова?
Предположим, что это некоторый Y.
Кто родитель Y?
Предположим, что это некоторый X.
Такой составной вопрос на Прологе записывается в виде последовательности
двух простых вопросов:
?– родитель( Y, иаков), родитель( X, Y).
Ответ будет:
X = авраам
Y = исаак
Наш составной вопрос можно интерпретировать и так: «Найти X и Y,
удовлетворяющие следующим двум требованиям»:
родитель( Y, иаков) и родитель( X, Y)
Если мы поменяем порядок этих двух требований, то логический смысл
останется прежним:
родитель( X, Y) и родитель( Y, иаков)
Этот вопрос можно задать нашей пролог–системе и в такой форме:
?– родитель( X, Y), родитель( Y, иаков).
При этом результат будет тем же. Таким же образом можно спросить:
«Кто внуки Авраама?»
?– родитель(авраам, X), родитель( Х, Y).
Система ответит так:
X = авраам
Y = иаков
Следующим вопросом мог бы быть такой: «Есть ли у Фареса и Зары
общий родитель?» Его тоже можно выразить в два этапа:
(1) Какой X является родителем Фареса?
(2) Является ли (тот же) X родителем Зары?
Соответствующий запрос к пролог-системе будет тогда выглядеть так:
?– родитель( X, фарес), родитель( X, зара).
Ответ:
X = иуда;
10
Х = фамарь
Теперь добавим к нашей программе о родственных связях еще одно
отношение – предок. Определим его через отношение родитель. Ключевая идея
здесь – определить отношение предок через него самого.
Для всех X и Z,
X – предок Z, если
существует Y, такой, что
(1) X – родитель Y и
(2) Y – предок Z.
Предложение Пролога, имеющее тот же смысл, записывается так:
предок( X, Z) :–
родитель( X, Y),
предок( Y, Z).
Теперь мы построили полную программу для отношения предок,
содержащую два правила: одно для ближайших предков и другое для
отдаленных предков. Здесь приводятся они оба вместе:
предок ( X, Z) :–
родитель ( X, Z).
предок ( X, Z) :–
родитель ( X, Y),
предок ( Y, Z).
Ключевым моментом в данной формулировке было использование самого
отношения предок в его определении. Такое определение может озадачить –
допустимо ли при определении какого-либо понятия использовать его же, ведь
оно определено еще не полностью. Такие определения называются
рекурсивными. Логически они совершенно корректны и понятны. Но будет ли в
состоянии пролог-система использовать рекурсивные правила? Оказывается,
что пролог-система довольно легко может обрабатывать рекурсивные
определения. На самом деле, рекурсия – один из фундаментальных приемов
программирования на Прологе. Без рекурсии с его помощью невозможно
решать задачи сколько-нибудь ощутимой сложности.
Возвращаясь к нашей программе, можно задать системе такой вопрос:
«Кто потомки Авраама?» То есть: «Кто тот человек, чьим предком является
Авраам?»
?– предок( авраам, X).
X = исаак;
X = иаков;
X = иуда;
X = фарес
…
11
Наша программа-пример помогла проиллюстрировать некоторые важные
моменты, а именно:
На Прологе легко определить отношение, подобное отношению родитель,
указав объекты, для которых это отношение выполняется.
Пользователь может легко задавать пролог-системе вопросы, касающиеся
отношений, определенных в программе.
Пролог-программа состоит из предложений. Каждое предложение
заканчивается точкой.
Аргументы отношения могут быть (среди прочего): конкретными
объектами, или константами (такими, как авраам и иаков), или абстрактными
объектами, такими как X и Y. Объекты первого типа называются атомами.
Объекты второго типа – переменными.
Вопросы к системе состоят из одного или более целевых утверждений
(или кратко – целей). Последовательность целей, такая как
родитель( X, фарес), родитель( X, зара)
означает конъюнкцию этих целевых утверждений:
X – родитель Фареса и
X – родитель Зары.
Пролог-система рассматривает вопросы как цели, к достижению которых
нужно стремиться.
Ответ на вопрос может оказаться или положительным, или
отрицательным в зависимости от того, может ли быть соответствующая цель
достигнута или нет. В случае положительного ответа мы говорим, что
соответствующая цель достижима и успешна. В противном случае цель
недостижима, имеет неуспех или терпит неудачу.
Если на вопрос существует несколько ответов, пролог-система найдет
столько из них, сколько пожелает пользователь.
Предложения могут быть заданы рекурсивно.
1.2. Терминология
Теперь, уже с формальной стороны, рассмотрим основную
терминологию. Поскольку базы знаний – относительно новый предмет, то
некоторые из используемых здесь определений еще не устоялись. Это
несколько затрудняет обсуждение излагаемого материала. Например,
некоторые авторы пользуются термином основанные на знаниях системы,
тогда как другие говорят о системах управления базами знаний [5]. Оба
термина, обозначающие одно и то же, широко распространены.
Вывод – процесс получения заключения из некоторых предложений.
Система управления базами знаний – это система, обладающая всеми
стандартными возможностями систем управления базами данных, т. е.
хранения данных и манипуляций ими, а также средствами создания правил
вывода, их хранения и применения к хранимым таблицам данных.
Основанная на знаниях система – это альтернативный термин для
12
системы управления базой знаний.
Система баз знаний (СБЗ) – компьютерная система, имеющая следующие
составляющие:
o база данных, содержащая основные факты;
o база данных, содержащая правила, которые позволяют делать выводы
из базы данных фактов;
o программное обеспечение, называемое системой управления базой
знаний (СУБЗ), которое поддерживает обычные функции СУБД, а
также управление процессом вывода в базе данных правил,
оперирующих базой данных фактов.
Система управления базой знаний (СУБЗ) – это системное программное
обеспечение, которое поддерживает обычные функции СУБД, а также
осуществляет управление процессом вывода правил в базе данных,
оперирующей базой данных фактов.
Общий успех систем управления базами данных в сочетании с
информационными
потребностями
менеджмента
и
исследованиями
искусственного интеллекта привел к росту заинтересованности в превращении
систем управления базами данных в системы управления базами знаний. Это
переход к более высокому уровню абстракции информации. Поясним данное
обстоятельство на конкретном примере. Пусть в базе данных находится
информация
Собрание собрание_38 проводится в Санкт-Петербурге.
Здесь имеется в виду, что для конкретного вида мероприятия (в данном
случае – собрание, а не заседание и т. д.), и его условного обозначения
(собрание_38 а не заседание_01) определено место проведения (СанктПетербург).
Это простой факт. Очевидно, что соответствующую этому факту
информацию можно выразить в следующей строке реляционной таблицы:
собрание (собрание_38, Санкт-Петербург)
С другой стороны, информация, подобная следующей:
Собрание собрание_38 плодотворно
не является простым фактом и представляет собой информацию более высокого
уровня. Значение этого факта отражено в классификации, предложенной
Уидерхолдом (Wiederhold, 1984) [1]:
o Структурное знание — это знание о зависимостях между данными и
ограничениями на них. Например, «перевод студента на следующий курс
зависит от того, были ли им сданы зачеты и экзамены в предыдущую
сессию»;
13
o Общее процедурное знание — это знание, которое можно описать только
процедурой. Например, «совпадение заказанного количества товара с
полученным количеством товара позволяет санкционировать оплату»;
o Прикладное знание — знание, которое определяется правилами и
соглашениями, относящимися к конкретной предметной области,
например, «определению наиболее дешевого плана двухнедельного
отдыха на море»;
o Знание предприятия — знание, помогающее предприятию принимать
решения. Например, для фирмы, производящей компьютеры, анализ
информации о ценах, прибылях, продажах и конкурирующих товарах
может помочь в принятии решений о стратегии маркетинга.
Знание, существующее в базах данных, состоит из фактов и элементов,
хранящихся в реляционных таблицах. Оно называется экстенсивным знанием.
Знание, которое определяется независимо от наполнения базы данных фактами,
обычно при помощи логических механизмов, называется интенсивным
знанием. Большинство из разрабатываемых баз знаний хранят интенсивное
знание в виде логических правил.
Логическое программирование – программирование, основанное на
использовании механизма доказательства теорем в логике, позволяющее
выяснить, является ли противоречивым некоторое множество логических
формул. При этом программа рассматривается как набор логических формул,
описывающих предметную область, совместно с теоремой, которая должна
быть доказана. Логическое программирование избавляет разработчика от
необходимости определения точной последовательности шагов выполнения
вычислений. Далее приведем основные термины Пролога [2].
Программа на языке Пролог – набор утверждений, составляющих базу
фактов и базу правил, к которым допустимо обращение с запросами,
касающимися их содержимого. Запросы называются также целевыми
утверждения.
Терм языка Пролог – это либо константа, либо переменная, либо
структура. Константами являются атомы и числа.
Константы используются для обозначения (именования) конкретных
объектов предметной области и конкретных отношений между ними.
Атом языка Пролог – это
 последовательность букв, цифр и знака "подчеркивание", обязательно
начинающаяся со строчной буквы;
 последовательности специальных знаков ":–", "?–", "=", ">" и других.
Переменная языка Пролог – последовательность букв, цифр и знака
"подчеркивание", обязательно начинающаяся с прописной буквы.
База фактов в языке Пролог – последовательность утверждений,
описывающих факты предметной области в виде структур, функторами
14
которых являются атомы – имена отношений (предикатные буквы), а
компонентами – предметные константы.
Каждый факт представляет собой элементарную формулу (предикат)
исчисления предикатов первого порядка и является дизъюнктом Хорна,
состоящим из одного (положительного) литерала. При описании фактов
переменные не используются.
База правил – совокупность правил в программе на языке Пролог.
Правило представляет собой дизъюнкт Хорна, содержащий один
положительный литерал и несколько отрицательных, и записывается
следующим образом:
<структура–0>:–<структура–1>, ... ,<структура–N>.
Здесь каждая структура представляет собой предикат, областью действия
переменных является все правило. Предикат, стоящий слева от атома ":–",
называется заголовком правила, все остальные предикаты образуют его тело.
Правило может трактоваться следующим образом: предикат, являющийся
заголовком правила доказан (удовлетворен), когда доказан каждый предикат
тела правила.
В качестве предикатов, составляющих тело правила, могут выступать
 предикаты, фигурирующие в базе фактов;
 предикаты, совпадающие с заголовком других правил;
 встроенные предикаты систем программирования Пролог.
Встроенный предикат – предикат, выводимость (согласованность)
которого устанавливается непосредственно системой программирования
Пролог.
Запрос на языке Пролог – утверждение, рассматриваемое в качестве
целевого, имеющее следующий вид:
?–<структура–1>, ...,<структура–N>.
Здесь каждая структура представляет собой предикат, возможно, содержащий
переменные. Причем областью действия переменной является все утверждение
в целом, т. е. одна и та же переменная в пределах утверждения означает один и
тот же объект.
Символ "," между предикатами трактуется как логическая связка "И", т. е.
запрос необходимо рассматривать как требование на поиск в базе фактов и
правил информации, удовлетворяющий одновременно всем предикатам
целевого утверждения. Предикаты, объединенные связкой "И" в таком запросе,
называются подцелями (имея в виду весь запрос целью).
15
Конкретизация переменной – связывание переменной языка Пролог с
конкретным значением.
Конкретизация переменной обеспечивает возврат искомых значений
переменных по запросам.
Выполнение запроса в языке Пролог – процесс доказательства
выводимости всех подцелей целевого утверждения методом резолюции с
использовании линейной по входу стратегии.
Получив запрос, состоящий из нескольких предикатов, интерпретатор
выбирает первый в последовательности запроса предикат и делает попытку
(если этот предикат не встроенный) согласовать его с утверждениями,
составляющими базы фактов и правил, для чего выполняется сопоставление
этого предиката со всеми фактами и заголовками этих правил в простом
линейном порядке до тех пор, пока оно не даст положительного результата.
Если этого не происходит, ответом на запрос будет "Нет". В ходе согласования
возможна конкретизация переменных значениями.
Если в ходе просмотра произошло сравнение с заголовком правила, то
тело правила рекурсивно рассматривается в качестве нового целевого
утверждения, доказательство которого реализуется с помощью
рассматриваемой здесь процедуры.
Удовлетворив один предикат (подцель) запроса, интерпретатор переходит к
соседнему справа, обрабатывая его аналогичным образом.
Запрос считается выполненным после удовлетворения его последней
(крайней справа) подцели. Если же какая-либо подцель (но не первая) не может
быть удовлетворена (согласована), то в работу включается механизм
бэктрекинга, который заставляет интерпретатор, передвигаясь по предикатам
целевого утверждения справа налево, вновь согласовывать эти предикаты, но
уже на новых утверждениях программы. Если попытка пересогласовать какой–
либо предикат (подцель) удается, то интерпретатор продолжает рассмотрение
подцелей от данной в обычном порядке (слева направо).
1.3. Сложные термы, или структуры
Следует отметить, что данный раздел нельзя рассматривать как полный
учебник по языку Пролог, а только как краткое введение, служащее для
иллюстрации принципов логического программирования, более подробно
описанных в [2], [3], [4].
16
Структура состоит из атома, называемого главным функтором, и
последовательности
термов,
называемых
компонентами
структуры.
Компоненты разделяются запятыми и заключаются в круглые скобки.
Приведем примеры структурированных термов:
собрание (место_проведения),
параметры_собрания (Х,У).
Число компонент в структуре называется арностью структуры. Так, в
данном примере структура собрание имеет арность 1 (записывается как
объект/1),
а
структура
параметры_собрания
–
арность
2
(параметры_собрания/2). Заметим, что атом можно рассматривать как
структуру арности 0.
Для некоторых типов структур допустимо использование альтернативных
форм синтаксиса. Это синтаксис операторов для структур арности 1 и 2,
синтаксис списков для структур в форме списков и синтаксис строк для
структур, являющихся списками кодов символов.
Структуры арности 1 и 2 могут быть записаны в операторной форме, если
атом, используемый как главный функтор в структуре, объявить оператором.
Список есть не что иное, как некоторая структура арности 2. Данная
структура становится интересной и чрезвычайно полезной в случае, когда
вторая компонента тоже является списком. Вследствие важности таких
структур в Прологе имеются специальные средства для записи списков.
1.4. Синтаксис строк
Строка определяется как список кодов символов. Коды символов имеют
особое значение в языках программирования. Они выступают как средство
связи компьютера с внешним миром. В большинстве реализации Пролога
существует специальный синтаксис для записи строк. Он подобен синтаксису
атомов. Строкой является любая последовательность символов, которые могут
быть напечатаны (кроме двойных кавычек), заключенная в двойные кавычки.
Двойные кавычки в пределах строки записываются дважды “”.
17
В некоторых реализациях Пролога строки рассматриваются как
определенный тип объектов подобно атомам или спискам. Для их обработки
вводятся специальные встроенные предикаты. В других реализациях строки
обрабатываются в точности так же, как списки, при этом используются
встроенные предикаты для обработки списков. Поскольку все строки могут
быть определены как атомы или как списки целых чисел, и понятие строки
является чисто синтаксическим, мы не будем более к нему возвращаться.
1.5. Утверждения
Программа на Прологе представляет собой совокупность утверждений.
Утверждения состоят из целей и хранятся в базе данных Пролога. Таким
образом, база данных Пролога может рассматриваться как программа на
Прологе. В конце утверждения ставится точка “.”. Иногда утверждение
называется предложением.
Основная операция Пролога – доказательство целей, входящих в
утверждение.
Существуют два типа утверждений:
 факт: это одиночная цель, которая, безусловно, истинна;
 правило: состоит из одной головной цели и одной или более хвостовых
целей, которые истинны при некоторых условиях.
Правило обычно имеет несколько хвостовых целей в форме конъюнкции
целей.
Таким образом, правило согласовано, если согласованы все его хвостовые
цели.
Примеры фактов:
собрание(собрание_38).
параметры_собрания (место_проведения, время_проведения).
служащий (Иван).
18
Примеры правил:
руководитель (X) :– руководство (X,Y), служащий (Y).
человек (Х) :– служащий (Х).
Разница между правилами и фактами чисто семантическая. Хотя для
правил мы используем синтаксис операторов (более подробное рассмотрение
операторного и процедурного синтаксисов выходит за рамки пособия), нет
никакого синтаксического различия между правилом и фактом.
1.6. Запросы
После записи утверждений в базу данных вычисления могут быть
инициированы вводом запроса.
Запрос выглядит так же, как и целевое утверждение, образуется и
обрабатывается по тем же правилам, но он не входит в базу данных
(программу). В Прологе вычислительная часть программы и данные имеют
одинаковый синтаксис. Программа обладает как декларативной, так и
процедурной семантикой. Запрос обозначается в Прологе утверждением ?–,
имеющим арность 1. Обычно запрос записывается в операторной форме: за
знаком ?– следует ряд хвостовых целевых утверждений (чаще всего в виде
конъюнкции).
Приведем примеры запросов:
?– руководитель (X).
?– руководство(Х,У), служащий (Y).
19
Запрос иногда называют управляющей командой (директивой), так как он
требует от Пролог-системы выполнения некоторых действий. Во многих
реализациях Пролога для управляющей команды используется альтернативный
символ, а символ ?– обозначает приглашение верхнего уровня интерпретатора
Пролога. Альтернативным символом является :–. Таким образом,
:–write(служащий).
- это управляющая команда, в результате выполнения которой печатается
атом служащий. Управляющие команды будут рассмотрены ниже при
описании ввода программ.
1.7. Ввод программ
Введение списка утверждений в Пролог-систему осуществляется с
помощью встроенного предиката consult. Аргументом предиката consult
является атом, который обычно интерпретируется системой как имя файла,
содержащего текст программы на Прологе. Файл открывается, и его
содержимое записывается в базу данных. Если в файле встречаются
управляющие команды, они сразу же выполняются. Возможен случай, когда
файл не содержит ничего, кроме управляющих команд для загрузки других
файлов. Для ввода утверждений с терминала в большинстве реализации
Пролога имеется специальный атом, обычно user. С его помощью утверждения
записываются в базу данных, а управляющие команды выполняются
немедленно.
Помимо предиката consult, в Прологе существует предикат reconsult. Он
работает аналогичным образом. Но перед добавлением утверждений к базе
данных из нее автоматически удаляются те утверждения, головные цели
которых сопоставимы с целями, содержащимися в файле перезагрузки. Такой
механизм позволяет вводить изменения в базу данных. В Прологе имеются и
другие методы добавления и удаления утверждений из базы данных. Некоторые
реализации языка поддерживают модульную структуру, позволяющую
разрабатывать модульные программы.
20
1.8. Унификация
Одним из наиболее важных аспектов программирования на Прологе
является использование унификации (отождествления) и конкретизации
переменных.
Пролог пытается отождествить термы при доказательстве, или
согласовании, целевого утверждения. Например, в программе для согласования
запроса ?– человек (Х) целевое утверждение человек(X) может быть
отождествлено с фактом служащий(Иван), в результате чего переменная Х
станет конкретизированной: Х= Иван.
Переменные, входящие в утверждения, отождествляются особым
образом – сопоставляются. Факт доказывается для всех значений переменной
(переменных). Правило доказывается для всех значений переменных в
головном целевом утверждении при условии, что хвостовые целевые
утверждения доказаны. Предполагается, что переменные в фактах и головных
целевых утверждениях связаны квантором всеобщности. Переменные
принимают конкретные значения на время доказательства целевого
утверждения.
В том случае, когда переменные содержатся только в хвостовых целевых
утверждениях, правило считается доказанным, если хвостовое целевое
утверждение истинно для одного или более значений переменных.
Переменные, содержащиеся только в хвостовых целевых утверждениях,
связаны квантором существования. Таким образом, они принимают конкретные
значения на то время, когда целевое утверждение, в котором переменные были
согласованы, остается доказанным.
Терм Х сопоставляется с термом Y по следующим правилам. Если
Х и Y – константы, то они сопоставимы, только если они одинаковы. Если Х
является константой или структурой, а Y – неконкретизированной переменной,
то Х и Y сопоставимы и Y принимает значение Х (и наоборот). Если Х и Y –
структуры, то они сопоставимы тогда и только тогда, когда у них одни и те же
главный функтор и арность и каждая из их соответствующих компонент
сопоставима. Если Х и Y – неконкретизированные (свободные) переменные, то
они сопоставимы, в этом случае говорят, что они сцеплены.
1.9. Арифметические выражения
Язык Пролог не предназначен для программирования задач с большим
количеством арифметических операций. Для этого используются процедурные
языки программирования. Однако в любую Пролог-систему включаются все
обычные арифметические операторы:
21
+ сложение
– вычитание
* умножение
/ деление
mod остаток от деления целых чисел
div целочисленное деление.
В некоторых реализациях языка Пролог присутствует более широкий
набор встроенных арифметических операторов.
Пролог позволяет также сравнивать арифметические выражения,
используя следующие встроенные предикаты:
Диапазоны чисел, входящих в арифметические выражения, зависят от
реализации Пролога. Например, система ICLPROLOG оперирует с целыми
числами со знаком в диапазоне: –8388606 ... 8388607.
Арифметическое выражение является числом или структурой. В
структуру может входить одна или более компонент, таких как числа,
арифметические
операторы,
арифметические
списковые
выражения,
переменная, конкретизированная арифметическим выражением, унарные
функторы, функторы преобразования и арифметические функторы.
Числа и их диапазоны определяются в конкретной реализации Пролога.
Арифметические списковые выражения. Если Х – арифметическое
выражение, то список [X] также является арифметическим выражением,
например [1,2,3]. Первый элемент списка используется как операнд в
выражении. Так,
X is ([l,2,3]+5)
имеет значение 6.
Арифметические списковые выражения полезны и при обработке
символов, поскольку последние могут рассматриваться как небольшие целые
числа. Например, символ "а" эквивалентен [97] и, будучи использован в
выражении, вычисляется как 97. Поэтому значение выражения “р”+"А"–"а"
равно 80, что соответствует коду ASCII для “Р”.
Переменная, конкретизированная арифметическим выражением.
Х–5+2 и У–3*(2+А)
Унарные функторы:
+(Х) и –(У)
22
Функторы преобразования. В некоторых реализациях Пролога имеется
арифметика с плавающей точкой, а следовательно, и функторы преобразования.
Например, float (X) преобразует целое число Х в число с плавающей точкой.
1.10. Вычисление арифметических выражений
В Прологе не допускаются присваивания вида Сумма=2+4.
Выражение такого типа вычисляется только с помощью системного
предиката is, например:
Сумма is 2 + 4.
Предикат is определен как инфиксный оператор. Его левый аргумент –
или число, или неконкретизированная переменная, а правый аргумент –
арифметическое выражение.
Попытка доказательства целевого утверждения Х is Y заканчивается
успехом в одном из следующих случаев:
а) Х – неконкретизированная переменная, а результат вычисления
выражения Y – число;
б) Х – число, которое равно результату вычисления выражения Y. Цель Х
is Y не имеет побочных эффектов и не может быть согласована вновь. Если Х
не является неконкретизированной переменной или числом, или если Y – не
арифметическое выражение, возникает ошибка.
Примеры:
D is 10– 5 заканчивается успехом и D становится равным 5
4 is 2 * 4 – 4 заканчивается успехом
2 * 4 – 4 is 4 заканчивается неудачей
a is 3 + 3 заканчивается неудачей
X is 4 + а заканчивается неудачей
2 is 4 – X заканчивается неудачей
Обратите внимание, что предикат is требует, чтобы его первый аргумент
был числом или неконкретизированной переменной. Поэтому М – 2 is 3
записано неверно. Предикат is не является встроенным решателем уравнений.
23
1.11. Сравнение результатов арифметических выражений
Системные предикаты =:=, =\=, >, <, >= и <= определены как инфиксные
операторы и применяются для сравнения результатов двух арифметических
выражений.
Для предиката @ доказательство целевого утверждения X@Y
заканчивается успехом, если результаты вычисления арифметических
выражений Х и Y находятся в таком отношении друг к другу, которое задается
предикатом @.
Такое целевое утверждение не имеет побочных эффектов и не может
быть согласовано вновь. Если Х или Y – не арифметические выражения,
возникает ошибка.
С помощью предикатов описываются следующие отношения:
Х =:= Y Х равно Y;
Х =\= Y Х не равно Y;
Х < Y Х меньше Y;
Х > Y Х больше Y;
Х <= Y Х меньше или равно Y;
Х >= Y Х больше или равно Y.
Использование предикатов иллюстрируют такие примеры:
а > 5 заканчивается неудачей;
5+2+7 > 5+2 заканчивается успехом;
3+2 =:= 5 заканчивается успехом;
3+2 < 5 заканчивается неудачей;
2 + 1 =\= 1 заканчивается успехом;
N > 3 заканчивается успехом, если N больше 3, и неудачей в противном случае.
24
Контрольные вопросы и упражнения
1. Что такое терм?
2. Что такое факт?
3. Чем правило на языке Пролог отличается от факта?
4. Напишите составной запрос, в котором конкретизируется переменная
Х, получая значение 10, а затем конкретизируется переменная У, которой
присваивается значение, получаемое в результате умножения Х на 3.
5. Запустите транслятор Пролога. Введите несколько фраз со сведениями
о Вашей семье, либо со сведениями из хорошо знакомой предметной области.
Придумайте запросы к этим фразам, используя в них константы и переменные.
25
2. СТРУКТУРЫ ДАННЫХ НА ЯЗЫКЕ ПРОЛОГ
Термы Пролога позволяют выразить самую разнообразную информацию.
В настоящей главе мы рассмотрим два вида широко используемых структур
данных: списки и бинарные деревья, и покажем, как они представляются
термами Пролога [3].
2.1. Списки
Задачи, связанные с обработкой списков, на практике встречаются очень
часто. Скажем, нам понадобилось составить список студентов, находящихся в
аудитории. С помощью Пролога мы можем определить список как
последовательность термов, заключенных в скобки. Приведем примеры
правильно построенных списков Пролога:
[андрей, александр, борис, владимир, александр]
[имя (александр, иванов), возраст (андрей, 24), X]
[Х.У.дата (12,январь, 1986) ,Х]
[]
Запись [H|T] определяет список, полученный добавлением Н в начало
списка Т. Говорят, что Н – голова, а Т – хвост списка [HIT]. На вопрос
?–L=[a | [b, c, d]]. будет получен ответ
L=[a, b, c, d]
а на запрос
?–L= [a, b, c, d], L2=[2 | L]. – ответ
L=[a, b, c, d], L2– [2, a, b, c, d]
Запись [Н | Т] используется для того, чтобы определить голову и хвост
списка. Так, запрос
?– [X | Y]=[a, b, c]. дает
Х=а, Y=[b, c]
26
Заметим, что употребление имен переменных Н и Т необязательно. Кроме
записи вида [H|T], для выборки термов используются переменные. Запрос
?–[a, X, Y]=[a, b, c].
определит значения
X=b
Y=c
а запрос
?– [личность(Х) | Т]=[личность(александр), а, b].
значения
Х=александр
Т=[а, Ь]
Покажем на примерах, как можно использовать запись вида [Н | T] вместе
с рекурсией для определения некоторых полезных целевых утверждений для
работы со списками.
Принадлежность
списку.
Сформулируем
принадлежности данного терма списку.
задачу
проверки
Граничное условие:
Терм R содержится в списке [H|T], если R=H.
Рекурсивное условие:
Терм R содержится в списке [H|T], если R содержится в списке Т.
Первый вариант записи определения на Прологе имеет вид
содержится (R, L) :–
L=[H I T],
H=R.
содержится (Р, L) :–
27
L= H|T],
содержится (R, T).
Цель L=[H I T] в теле обоих утверждений служит для того, чтобы
разделить список L на голову и хвост.
Можно улучшить программу, если учесть тот факт, что Пролог сначала
сопоставляет с целью голову утверждения, а затем пытается согласовать его
тело. Новая процедура, которую мы назовем принадлежит, определяется таким
образом:
принадлежит (R, [R | Т]).
принадлежит (R, [H | Т]) :– принадлежит (R, T).
На запрос
?– принадлежит(а, [а, Ь, с]).
будет получен ответ
да
на запрос
?– принадлежит(b, [a, b, с]).
– ответ
да
но на запрос
?– принадлежит(d, (a, b, c)).
Пролог дает ответ
нет
В большинстве реализации Пролога предикат принадлежит является
встроенным.
Соединение двух списков. Задача присоединения списка Q к списку Р, в
результате чего получается список R, формулируется следующим образом:
Граничное условие:
Присоединение списка Q к [] дает Q.
28
Рекурсивное условие:
Присоединение списка Q к концу списка Р выполняется так: Q
присоединяется к хвосту Р, а затем спереди добавляется голова Р.
Определение можно непосредственно написать на Прологе:
соединить([],0,0).
соединить(Р,Q,Р) :–
Р=[НР | ТР],
соединить(TP, Q, TR),
R=[HP | TR].
Однако, как и в предыдущем примере, воспользуемся тем, что Пролог
сопоставляет с целью голову утверждения, прежде чем пытаться согласовать
тело:
присоединить([] ,Q,Q).
присоединить(HP | TP], Q, [HP | TR]) :–
присоединить (TP, Q, TR).
На запрос
?– присоединить [а, b, с], [d, e], L).
будет получен ответ
L = [a, b, c, d].
но на запрос
?– присоединить([a, b], [c, d], [e, f]).
ответом будет
нет
Часто процедура присоединить используется для получения списков,
находящихся слева и справа от данного элемента:
29
присоединить (L [владимир, р], [андрей, петр, владимир, тимофей, владимир,
федор] ) .
L = [андрей, петр]
R = [тимофей, владимир, федор]
другие решения (да/нет)? да
L=[андрей, петр, владимир, тимофей]
R=[федор]
другие решения (да/нет)? да
других решений нет
Индексирование списка. Задача получения N-гo терма в списке
определяется следующим образом:
Граничное условие:
Первый терм в списке [Н | Т] есть Н.
Рекурсивное условие:
N–й терм в списке [Н | Т] является (N–I)–м термом в списке Т.
Данному определению соответствует программа:
% Граничное условие:
получить ([H | Т], 1, Н). /* Рекурсивное условие:
получить([Н | Т], N, У) :–
М is N – 1,
получить (Т, М ,Y).
Построение списков из фактов. Иногда бывает полезно представить в
виде списка информацию, содержащуюся в известных фактах. В большинстве
реализации Пролога есть необходимые для этого предикаты:
bagof(X,Y,L) определяет список термов L, конкретизирующих переменную Х
как аргумент предиката Y, которые делают истинным предикат Y.
30
setof(X,Y,L) все сказанное о предикате bagof относится и к setof, за
исключением того, что список L отсортирован и из него удалены все
повторения.
Если имеются факты:
служащий (максим).
служащий (иван).
служащий (сергей).
служащий (иван).
то на запрос
?– bagof(D, служащий(D), L),
будет получен ответ
L=[ максим, иван, сергей, иван]
в то время как
?–setof(D, служащий(D), L). дает значение
L=[иван, максим, сергей].
Рассмотрим пример использования списков решения задач на примере
представления и сложения многочленов.
Представление многочленов. Посмотрим, как можно представить
многочлен вида
Р(х)=3+3х–4х^3+2х^9
Q(х)=4х+х^2–3х^3+7х^4+8х^5
Заметим, что каждое подвыражение (такое, как Зх ^3, Зх, 3) имеет самое
большее две переменные компоненты: число, стоящее перед х, называемое
коэффициентом, и число, стоящее после ^ – степень. Следовательно,
подвыражение представляется термом
х(Коэффициент, Степень)
Так, 5х^2 записывается как х(5,2), х^З представляется как х(1,3), а
поскольку х^0 равно 1, подвыражению 5 соответствует терм х(5,0).
31
Теперь запишем многочлен в виде списка. Приведенный выше многочлен
Р(х), например, будет выглядеть следующим образом:
[x(3, 0), '+', x(3, l), '–', x(4, 3), '+', x(2, 9)]
Воспользуемся тем, что многочлен
3 + 3х – 4х^3 + 2х^9
допускает замену на эквивалентный
3 + 3х + (–4)х^3 + 2х^9 Тогда он выражается списком:
[х(3, 0), '+', х(3, 1), '+', х(–4, 3), '+', х(2, 9)]
В такой записи между термами всегда стоят знаки '+'. Следовательно, их
можно опустить, и многочлен принимает окончательный вид
[х(3, 0), х(3, 1), х(–4, 3), х(2, 9)]
Подразумевается, что между всеми термами списка стоят знаки '+'.
Представлением многочлена Q(x) будет
[х(4, 1), х(1, 2), х(–3, 3), х(7, 4), х(8, 5)]
Сложение многочленов. Теперь напишем целевые утверждения для
сложения двух многочленов. Сложение многочленов
3–2х^2+4х^3+6х^6
–1+3х^2–4х^3
в результате дает
2+х^2+6х^6
Аргументами целевого утверждения являются многочлены, представленные в
виде списков. Ответ будет получен также в виде списка.
Сложение многочлена Р с многочленом Q осуществляется следующим
образом:
Граничное условие:
Р, складываемый с [], дает Р.
[], складываемый с Q, дает Q.
Рекурсивное условие:
32
При сложении Р с Q, в результате чего получается многочлен R, возможны 4
случая:
а) степень первого терма в Р меньше, чем степень первого терма в Q. В
этом случае первый терм многочлена Р образует первый терм в R, а хвост R
получается при прибавлении хвоста Р к Q. Например, если Р и Q имеют вид
Р(х)=3х^2+5х^3
Q(x)=4x^3+3x^4
то первый терм R(x) равен 3х^2 (первому терму в Р(х)). Хвост R(x) равен
9х^3+3х^4, т. е. результату сложения Q(x) и хвоста Р(х);
б) степень первого терма в Р больше степени первого терма в Q. В данном
случае первый терм в Q образует первый терм в R, а хвост R получается при
прибавлении Р к хвосту Q. Например, если
Р(х)=2х^3+5х^'4
Q(x)=3x^3–x^4
то первый терм R(x) равен 3х^2 (первому терму в Q(x)), а хвост R(x) равен
2х^3+4х^4 (результату сложения Р(х) и хвоста Q(x));
в) степени первых термов в Р и Q равны, а сумма их коэффициентов
отлична от нуля. В таком случае первый терм в R имеет коэффициент, равный
сумме коэффициентов первых термов в Р и Q. Степень первого терма в R равна
степени первого терма в Р (или Q). Хвост R получается при сложении хвоста Р
и хвоста Q. Например, если Р и Q имеют вид
Р(х)=2х+3х^3
Q(x)=3x+4x^4
то первый терм многочлена R (х) равен 5х (результату сложения первого терма
в Р(х) с первым термом в Q(x)). Хвост R(x) равен 3х^3+4х^4 (результату
сложения хвоста Р(х) и хвоста Q(x));
г) степени первых термов в Р и Q одинаковы, но сумма коэффициентов
равна нулю. В данном случае многочлен R равен результату сложения хвоста Р
с хвостом Q. Например, если
р(х)=2+2х
Q(x)=2–3x^2
то
R(x)=2x–3x^2
33
(это результат сложения хвостов многочленов Р (х) и Q (х)).
Рассмотренный процесс сложения многочленов можно непосредственно
записать на языке Пролог:
/* Граничные условия
слож_мн([], Q Q).
слож_мн(P, [], P).
/* Рекурсивное условие
/* (a)
слож_мн([x(Pc, Pp)|Pt], [x(Qc, Qp)|Qt],
[x(Pc,Pp)IRt]) :–
PpQp,
слож_мн(Рt, [х(Qс,Qр) | Qt], Rt).
/*(б)
слож_мн([x(Pc, Pp) | Pt], [x(Qc, Qp) | Qt],
[x(Qc, Qp) | Rt]) :–
PpQp,
слож_мн([x(Pc, Pp) | Pt], Qt, Rt).
/*(в)
слож_мн([x(Pc, Pp) | Pt], [х(Qc,Pp) | Qt],
[x(Rc, Pp) | Rt]) :–
Rc is Pc+Qc,
Rc =/= 0,
слож_мн(Pt, Qt,Rt).
/*(r)
34
слож_мн([х(Рс, Рр) | Pt],
[x(Qc.Pp) | Qt], Rt) :–
Re is Pc+Qc,
Rc =:= 0,
слож_мн(Pt, Qt, Rt).
Заметим, что в двух последних утверждениях проверка на равенство
осуществляется следующим образом: степени первых термов складываемых
утверждений обозначает одна и та же переменная Pp.
Списки как термы. В начале главы мы упомянули о том, что список
представляется с помощью терма. Такой терм имеет функтор '.', Два аргумента
и определяется рекурсивно. Первый аргумент является головой списка, а
второй – термом, обозначающим хвост списка. Пустой список обозначается [].
Тогда список [а, b] эквивалентен терму.(а,.(b, [])).
Таким образом, из списков, как и из термов, можно создавать вложенные
структуры. Поэтому выражение
[[a, b], [c, d], [a], a]
есть правильно записанный список, и на запрос
?– [Н | Т]=[[а, b], с].
Пролог дает ответ
Н=[а, b]
Т=[с]
2.2. Бинарные деревья
Бинарное дерево определяется рекурсивно как имеющее левое поддерево,
корень и правое поддерево. Левое и правое поддеревья сами являются
бинарными деревьями. На рис. 2.1 показан пример бинарного дерева.
35
Бинарное дерево
Рис. 2.1 Бинарное дерево
Такие деревья можно представить термами вида
бд(Лд, К, Пд),
где Лд – левое поддерево, К – корень, а Пд – правое поддерево. Для
обозначения пустого бинарного дерева будем использовать атом nil. Бинарное
дерево на рис. 2.1 имеет левое поддерево
бд(бд(nil, d, nil), b, бд(nil, е, nil))
правое поддерево
бд(nil,с, nil)
и записывается целиком как
бд(бд(бд(nil,d, nil), b, бд(nil,е, nil)), а, бд(nil, с, nil)).
Описание множеств в виде списков позволяет использовать для множеств
целевое утверждение принадлежит, определенное ранее для списков.
Однако для множеств, состоящих из большого числа элементов,
списковые целевые утверждения становятся неэффективными. Рассмотрим,
например, как целевое утверждение принадлежит позволяет моделировать
принадлежность множеству. Пусть L – список, описывающий множество из
первых 1024 натуральных чисел. Тогда при ответе на запрос
?– принадлежит(3000, b).
36
Прологу придется проверить все 1024 числа, прежде чем заключить, что такого
числа нет:
нет
Представление множества бинарным деревом позволяет добиться
лучшего результата. При этом бинарное дерево должно быть упорядочено
таким образом, чтобы любой элемент в левом поддереве был меньше, чем
значение корня, а любой элемент в правом поддереве — больше. Поскольку мы
определили поддерево как бинарное дерево, такое упорядочение применяется
по всем поддеревьям. На рис. 2.2 приведен пример упорядоченного бинарного
дерева (дерево на рис. 2.1 является неупорядоченным).
Рис. 2.2. Упорядоченное бинарное дерево
Обратите внимание, что упорядочение приводит не к единственному
варианту представления множества с помощью дерева. Например, на рис. 2.3
изображено то же множество, что и на рис. 2.2.
Будем называть линейным представление такого вида, как на рис. 2.3, и
сбалансированным – такое, как на рис. 2.2.
Линейное представление
Рис. 2.3. Линейное бинарное дерево
37
Моделирование принадлежности множеству. Имея множество, описанное
бинарным деревом, мы можем моделировать принадлежность множеству с
помощью целевого утверждения принадлежит_дереву. При этом используется
оператор @<, выражающий отношение “меньше, чем”, и оператор @>,
выражающий отношение “больше, чем”.
/* Граничное условие: Х принадлежит
/* дереву, если Х является корнем.
принадлежит_дереву(Х, бд(Лд, Х, Пд)),
/* Рекурсивные условия
/* Х принадлежит дереву, если Х больше
/* значении корня и находится в правом
/* поддереве:
принадлежит_дереву(Х, бд(Лд, У, Пд)) :– X@Y,
принадлежит_дереву(Х, Пд).
/* Х принадлежит дереву, если Х меньше
/* значения корня и находится в левом
/* поддереве:
принадлежит_дереву(Х, бд(Лд ,У ,Пд)) :–X@Y,
принадлежит_дереву(Х, Лд).
Если множество из первых 1024 чисел описать
сбалансированного бинарного дерева Т, то при ответе на запрос
?– принадлежит_дереву(3000, Т).
с
помощью
Пролог сравнит число 3000 не более чем с 11 элементами множества.
прежде чем ответит:
нет
Конечно, если Т имеет линейное представление, то потребуется
сравнение 3000 с 1024 элементами множества.
Построение бинарного дерева. Задача создания упорядоченного
бинарного дерева при добавлении элемента Х к другому упорядоченному
бинарному дереву формулируется следующим образом:
Граничное условие:
Добавление Х к nil дает бд(nil, Х, nil).
Рекурсивные условия:
При добавлении Х к бд(Лд, К, Пд) нужно рассмотреть два случая, чтобы
быть уверенным, что результирующее дерево будет упорядоченным.
1. Х меньше, чем К. В этом случае нужно добавить Х к Лд, чтобы
получить левое поддерево. Правое поддерево равно Пд, а значение корня
результирующего дерева равно К.
2. Х больше, чем К. В таком случае нужно добавить Х к Пд, чтобы
получить правое поддерево. Левое поддерево равно Лд, а значение корня – К.
Такой формулировке задачи соответствует программа
38
/* Граничное условие:
включ_бд(nil, Х, бд(nil, Х, nil)).
/* Рекурсивные условия:
/*(1)
включ_бд(бд(Лд, К, Пд), Х, бд(Лднов, К, Пд)) :–
Х@К,
включ_бд(Лд,Х,Лднов).
/*(2)
включ_бд(бд(Лд, К, Пд), Х, бд(Лд, К, Пднов)) :–
Х@К,
включ_бд(Пд, Х, Пднов).
На запрос
?– включ_бд(nil, d, Т1), включ_бд(Т1, а, Т2).
будут получены значения
Т1=бд(nil, d, nil)
Т2=бд(бд(nil, а, nil), d, nil)
Процедуру включ_бд() можно
упорядоченного дерева из списка
использовать
для
построения
/* Граничное условие:
список_в_дерево([], nil).
/* Рекурсивное условие:
список_в_дерево([Н | Т], Бд) :–
список_в_дерево(Т, Бд2),
включ_бд(Н, Бд2, Бд).
Заметим, что включ_бд не обеспечивает построения сбалансированного
дерева. Однако существуют алгоритмы, гарантирующие такое построение.
2.3. Механизм возврата и процедурная семантика
При согласовании целевого утверждения в Прологе используется метод,
известный под названием механизма возврата. В этом разделе мы показываем, в
каких случаях применяется механизм возврата, как он работает и как им
пользоваться.
Механизм возврата. При попытке согласования целевого утверждения
Пролог выбирает первое из тех утверждений, голова которых сопоставима с
целевым утверждением. Если удастся согласовать тело утверждения, то целевое
утверждение согласовано. Если нет, то Пролог переходит к следующему
утверждению, голова которого сопоставима с целевым утверждением, и так
далее до тех пор, пока целевое утверждение не будет согласовано или не будет
доказано, что оно не согласуется с базой данных.
В качестве примера рассмотрим следующие утверждения:
39
меньше(X.Y) :–
XY, write(X),
write ('меньше, чем'),write(Y).
меньше(Х.У) :–
XY, write(Y),
write ('меньше, 4CM'),write(X).
Целевое утверждение
?– меньше (5, 2).
сопоставляется с головой первого утверждения при Х=5 и У=2. Однако не
удается согласовать первый член конъюнкции в теле утверждения X<Y. Значит,
Пролог не может использовать первое утверждение для согласования целевого
утверждения меньше(5, 2). Тогда Пролог переходит к следующему
утверждению, голова которого сопоставима с целевым утверждением. В нашем
случае это второе утверждение. При значениях переменных Х=5 и Y=2 тело
утверждения согласуется. Целевое утверждение меньше (5,2) доказано, и
Пролог выдает сообщение “2 меньше, чем 5”. Запрос
?–меньше (2, 2).
сопоставляется с головой первого утверждения, но тело утверждения
согласовать не удается. Затем происходит сопоставление с головой второго
утверждения, но согласовать тело опять-таки оказывается невозможно.
Поэтому попытка доказательства целевого утверждения меньше(2, 2)
заканчивается неудачей.
Такой процесс согласования целевого утверждения путем прямого
продвижения по программе называется прямой трассировкой (forward tracking).
Даже если целевое утверждение согласовано, с помощью прямой трассировки
мы можем попытаться получить другие варианты его доказательства, т.е. вновь
согласовать целевое утверждение.
40
Пролог производит доказательство конъюнкции целевых утверждений
слева направо. При этом может встретиться целевое утверждение, согласовать
которое не удается. Если такое случается, то происходит смещение влево до тех
пор, пока не будет найдено целевое утверждение, которое может быть вновь
согласовано, или не будут исчерпаны все предшествующие целевые
утверждения. Если слева нет целевых утверждений, то конъюнкцию целевых
утверждений согласовать нельзя. Однако, если предшествующее целевое
утверждение может быть согласовано вновь, Пролог возобновляет процесс
доказательства целевых утверждений слева направо, начиная со следующего
справа целевого утверждения. Описанный процесс смещения влево для
повторного согласования целевого утверждения и возвращения вправо носит
название механизма возврата.
В качестве примера использования механизма возврата напишем
процедуру для поиска пути в лабиринте. Лабиринт представлен фактами вида
стена(I, J) для позиции в I–м ряду и J–й колонке, где есть стена,
отсутств_стена(I, J) для позиции в I–м ряду и J–й колонке, где нет стены,
выход(I, J) для позиции в I–м ряду и J–й колонке, являющейся выходом
Рассмотрим небольшой лабиринт (рис. 2.4).
Стена
Стена
Стена
Стена
Стена
Стена
Стена
Стена
Стена
Выход
Стена
Стена
Стена
Стена
Стена
Стена
Стена
Рис. 2.4. Лабиринт
Последний ряд лабиринта описывается следующими фактами:
стена(4,1).
стена(4,3).
стена(4,4).
стена(4,5).
отсутств_стена(4,2).
41
Если задана исходная позиция, путь к выходу можно найти следующим
образом.
Граничное условие:
Если исходная позиция является выходом, то путь найден.
Рекурсивные условия:
Ищем путь из исходной позиции в северном направлении. Если пути нет,
идем на юг. Если пути нет, идем на запад. Если нельзя, идем на восток. Если
соседняя позиция на севере (юге, западе, востоке) является стеной, то нет
смысла искать путь из начальной позиции к выходу. Чтобы не ходить кругами,
будем вести список позиций, в которых мы побывали.
Изложенному способу решения задачи соответствует процедура путь: она
ищет путь (второй аргумент) к выходу из некоторой позиции (первый
аргумент). Третьим аргументом является список позиций, где мы побывали.
% Терм a(I, J) представляет позицию в
% I-м ряду и J-й колонке.
% Нашли путь ?
путь(а(I, J),[а(I, J)], Были) :– выход(I, J).
% Пытаемся идти на север
путь(а(I, J),[а(I, J) | Р], Были) :–
К is I–1,
можем_идти(a (K, J), Были),
путь(а(I, J) ,Р, [a(K, J) | Были]).
% Пытаемся идти на юг
путь(а(I, J),[а(I, J) | Р], Были) :–
К is I+1,
можем_идти(a (K, J), Были),
42
путь(а(I, J) ,Р, [a(K, J) | Были]).
% Пытаемся идти на запад
путь(а (I, J), [a (I, J) | P], Были) :–
L is J–1,
можем_идти(а(I, L), Были),
путь(а(I, L), Р, [а(I, L)| Были]).
% Пытаемся идти на восток
путь(а (I, J), [a (I, J) | P], Были) :–
L is J+1,
можем_идти(а(I, L), Были),
путь(а(I, L), Р, [а(I, L)| Были]).
% в позицию a(I, J) можно попасть при
% условии, что там нет стены и мы
% не побывали в ней прежде
можем_идти(а(I, J)), Были) :–
отсутств_стена(I, J),
not (принадлежит (a (I, J), Были)).
Для того чтобы понять, каким образом процедура ищет путь к выходу,
рассмотрим процесс согласования запроса с описанием лабиринта, описанного
выше:
?–путь(а(4,2), Р, [а(4.2)]).
Выходом из лабиринта является позиция выход (3,1).
43
Выбор первого утверждения не приводит к согласованию целевого
утверждения, поскольку а (4,2) – не выход. Во втором утверждении делается
попытка найти путь в северном направлении, т. е. согласовать целевое
утверждение
путь(а(3, 2), Р2, [а(3, 2), а(4, 2)]).
Целевое утверждение не удается согласовать с первым утверждением
путь(а(3, 2), Р2, [а(3, 2), а(4, 2)])
так как а (3,2) не является выходом. Во втором утверждении предпринимается
попытка найти путь, двигаясь на север, т. е. согласовать целевое утверждение
путь(а(2,2), РЗ, [а(2, 2), а(3, 2), а(4, 2)]).
Ни одно из утверждений не может согласовать
путь(а(2, 2), РЗ, [а(2, 2), а(3, 2), а(4, 2)]).
Первое утверждение – потому, что а (2, 2) не является выходом, второе –
потому, что северная позиция является стеной, третье утверждение – потому,
что в южной позиции мы уже побывали, а четвертое и пятое утверждения –
потому, что западная и восточная границы – это стены.
Неудача в согласовании
путь(а(2, 2), РЗ, [а(2, 2), а(3, 2), а(4, 2)])
заставляет Пролог-систему вернуться в ту точку, где было выбрано второе
утверждение при попытке согласовать
путь(а(3, 2), Р2, [а(3, 2), а(4, 2)]).
Решение пересматривается и выбирается третье утверждение.
В третьем утверждении осуществляется попытка найти путь, двигаясь на
юг, но она оказывается неудачной, поскольку мы уже побывали в позиции а (4,
2). Тогда, чтобы согласовать
путь(а(3, 2), Р2, [а(3, 2), а(4, 2)]),
44
выбирается четвертое утверждение. Мы успешно находим путь, двигаясь в
западном направлении к позиции а(3,1), которая и является выходом. Рекурсия
сворачивается, и в результате получается путь
Р=[а(4, 2),а(3, 2), а(3,1)]
другие решения(да/нет)? да
Других решений нет
Альтернативный путь
[a(4,2), a(3,2), a(2,2), a(3,2), a(3,1)]
мы получить не можем, потому что не разрешается дважды бывать в одной и
той же позиции.
Описанная процедура не обязательно находит кратчайший путь к выходу.
Кратчайший путь можно найти, генерируя альтернативные пути с помощью
вызова состояния неудачи и запоминая кратчайший из них.
Контрольные вопросы и упражнения
1. Создайте файл с Пролог-програмой, который называется «группа».
Внесите в программу факты, в каждом из которых должны быть указаны имя
студента, и имя группы, в которой этот студент числится. Составьте правило,
задающее условия согласно которым одно лицо знает другое, если они оба
входят в состав одной и той же группы.
2. Создайте программу «Советник по транспорту». Выберите сеть,
состоящую из городов, либо транспортную сеть маршрутов городского
транспорта в пределах одного города. Вы должны информировать систему о
том, откуда и куда Вы собираетесь добраться, а система должна выдавать
рекомендации о том, чем Вам нужно воспользоваться, чтобы добраться до
пункта назначения.
3. Напишите правило, позволяющее вычислить площадь прямоугольника.
У этого правила должны быть три аргумента: основание, высота и площадь
прямоугольника. Напишите несколько запросов к этому правилу, используя в
качестве аргумента и числа, и переменные.
4. Составьте процедуру «найти_слово», в которой будет подсчитываться,
сколько раз заданное слово встречается в списке.
45
5. Напишите процедуру «длина», в которой при подсчете элементов
списка не учитывается слово «пусто». Например, для списка [a,b,c,d,e] длина
списка равна пяти, а для [a,пусто,c,d,e] длина списка равна четырем.
46
3. ПРЕДСТАВЛЕНИЕ МОДЕЛЕЙ ЗНАНИЙ
3.1. Процесс представления знаний
Для того чтобы более четко проиллюстрировать то, какие преимущества
дает программисту использование методов логического программирования при
представлении знаний, рассмотрим, как на процедурном языке (например, на
языке Си) можно составить программу, предназначенную для представления
знаний. Сам по себе язык Си не является средством логического
программирования. Поэтому для того, чтобы воспользоваться этим языком при
представлении знаний, необходимо реализовать нужные средства в рамках
языка Си. В типичной Си–программе для этого требуется:
1) определение структур данных, конкретные экземпляры которых будут
использоваться для описания структуры системы;
2) составление процедур, предназначенных для выполнения
вычислительных операций над экземплярами структур данных, иными словами,
для придания описаниям определенного формального смысла.
Неопытный программист, пользующийся языком Си, стремится
изобретать новые средства для каждой новой области применения (т. е. для
каждой представляемой системы). В результате этого тип формального
смыслового значения, реализуемого процедурами программы, будет сильно
зависеть от конкретных особенностей представляемой системы. Обратите
внимание на то, насколько сильно это отличается от языка Пролог:
символическое обозначение отношения и Пролог-программе имеет один и тот
же тип формального смыслового значения независимо от того, какая система
представляется. Самым большим недостатком введении новых средств для
каждой новой области применения является то, что лицу, пытающемуся
прочитать программу, потребуется изучить как ее описание, так и описание
системы, реализованное структурами данных этой программы.
Процесс представления знаний с помощью Пролог-программы может
состоять из следующих этапов [4]:
1. Специалист, знакомый с системой, анализирует ее структуру для того,
чтобы выделить все значимые сущности и важные отношения между этими
сущностями.
2. Программист выбирает символические обозначения для представления
каждой сущности и каждого отношения.
3. Специалист по системе определяет каждое отношение семантически,
при этом отмечается, какие конкретные реализации отношения будут
истинными, а какие – ложными.
4. Программист аксиоматически определяет каждое отношение при
помощи фраз языка Пролог. Аксиоматическое определение будет правильным,
если интерпретатор Пролога сможет вывести из этого определения каждую
истинную конкретную реализацию данного отношения.
47
После того как знания о системе будут описаны в Пролог-программе,
пользователь сможет обращаться к этим знаниям посредством запросов или при
помощи более совершенного интерфейса программы с пользователем.
В
качестве
примера
рассмотрим
систему,
образованную
межличностными отношениями служащих, регулярно посещающих собрания в
некоторой организации. Руководитель организации, хорошо разбирающийся в
этой системе, проводит ее анализ и разбивает систему на следующие
компоненты. Каждый служащий (Мария Кравчук, Федор Александров, Роман
Иванов, Иван Фирсов и Евгения Харченко) – это значимая сущность. Каждое
собрание (собрание_38 и собрание_39) – это также значимая сущность.
Отношение между служащим и собранием, которое он должен посещать,
является важным. Отношение между служащими, которые знают друг друга,
также является важным.
Программист выбирает следующие символические обозначения этих
сущностей и отношений:
«мария», «роман», «федор», «иван» и «евгения» – это служащие;
«собрание_38» и «собрание_39» – это виды собраний;
«собрание» – это отношение между служащим и собранием, которую он
посещает;
«знает» – это отношение между служащими, которые знают друг друга.
Руководитель организации семантически определяет отношение
«собрание», устанавливая, что истинны следующие конкретные реализации
этого отношения:
собрание (мария,
собрание (роман,
собрание (иван,
собрание (федор,
собрание (евгения,
собрание_38).
собрание_38).
собрание_39).
собрание_39).
собрание_39).
а все остальные конкретные реализации – ложны. Руководитель организации
определяет отношение "знает", утверждая, что любые два лица, посещающие
одно и то же собрание, знают друг друга. Из этого следует, что истинными
будут такие конкретные реализации отношения "знает":
знает (мария,
знает (роман,
знает (иван,
знает (федор,
знает (иван,
знает (евгения,
знает (федор,
48
роман).
мария).
федор).
иван).
евгения).
иван).
евгения).
знает (евгения,
федор).
Все остальные конкретные реализации этого отношения будут ложными.
Программист, "вооружившись" этими семантическими определениями,
определяет отношение "собрание" аксиоматически, при этом каждая истинная
конкретная реализация данного отношения записывается в виде факта:
%
Служащий
собрание (мария,
собрание (роман,
собрание (иван,
собрание (федор,
собрание (евгения,
Вид собрания
собрание_38).
собрание_38).
собрание_39).
собрание_39).
собрание_39).
Проверка корректности данных аксиоматических определений состоит в
необходимости продемонстрировать то, что интерпретатор языка Пролог
сможет вывести из них все истинные конкретные реализации каждого
отношения.
Формальный смысл. Символические обозначения, используемые дня
представления сущностей и отношений в такой Пролог-программе, имеют как
формальный смысл, выражаемый через другие символические обозначения, так
и внешний смысл, который связывает их с компонентами представляемой
системы. Для того чтобы оценить по достоинству силу Пролога как
формализма, полезно подробно рассмотреть природу обоих типов смысловых
значений.
Формальный смысл символического обозначения, употребляемого в
Пролог-программе, является продуктом дескриптивных фраз программы и
обрабатывающей структуры Пролога. Рассмотрим формальный смысл
символического обозначения отношения (т. е. имени предиката), используемого
в Пролог-программе. С формальной точки зрения отношение – это отображение
п термов-переменных (где п – количество аргументов) на истинностное
значение. В Пролог-программе отношение определяется аксиоматически
множеством фраз языка Пролог. Интерпретатор – это процедура, обладающая
способностью выводить истинные конкретные реализации отношения из фраз,
определяющих это отношение. С этой точки зрения интерпретатор реализует
смысл аксиоматического определения отношения. Формальный смысл
символического обозначения отношения – это множество истинных
конкретных реализаций отношения, которые могут быть выведены
интерпретатором из фраз, содержащихся в программе,
Сходным образом формальный смысл терма, не содержащего
переменных (т. е. константы или структуры без переменных), – это множество
истинных конкретных реализации отношений, в которые может входить этот
терм.
49
Внешний смысл. Для того чтобы обеспечить возможность представления
знаний о мире при помощи Пролог-программы, символические обозначения
программы (константы и имена предикатов и структур) должны обладать
внешним смыслом, связывающим их с компонентами представляемой системы.
Этот смысловой уровень существует в умах программистов и пользователей
программы. Он сходен со смысловым значением слов естественного языка. В
приведенном выше примере программист выбрал символическое обозначение
«мария» для представления служащей Мария Кравчук, следовательно, Мария
Кравчук – это внешний смысл символического обозначения «мария».
Для того чтобы сделать более ясной разницу между формальным и
внешним смыслом символических обозначений, рассмотрим фразу
знает (евгения, федор).
На рис. 3.1 показано, как внешние смысловые значения связывают
символические обозначения программы с компонентами представляемой
системы.
Описание
Обрабатывающая
структура
Выходная
информация
Приписывание символических обозначений
при описании компонент системы
Система (часть мира)
Рис. 3.1. Представление фразы
Формальный смысл символического обозначения "знает" – это
множество истинных конкретных реализации отношения "знает/2". Частью
формального смысла символического обозначения "евгения" является то, что,
данное обозначение может служить первым аргументом истинного конкретного
случая отношения "знает/2". В приведенном выше примере подразумеваемым
внешним смыслом обозначения "знает" является знакомство друг с другом двух
лиц, общающихся между собой в некоторой социальной ситуации, а
предполагаемым внешним смыслом символического обозначения «евгения»
является человек по имени Евгения Харченко. Если выражаться в терминах
логики предикатов, то внешний смысл символического обозначения
константы – это его значение при некоторой интерпретации. Интерпретатор
языка Пролог реализует формальный смысл символических обозначений; мы
же, как программисты и пользователи программы должны придать этим
обозначениям внешний смысл.
50
Программа, предназначенная для представления знаний о системе,
окажется удачной, если пользователь сможет извлекать эти знания из
программы и использовать их способом, целесообразным для выполнения
действий с системой. Иными словами, поведение и выходная информация
программы должны отражать структуру системы. Если пользователь
обнаружит, что выходная информация программы противоречит его
пониманию системы, то это будет означать, что программа непригодна для
работы.
С точки зрения пользователя подразумеваемый внешний смысл
символических обозначений, встречающихся в выходных данных, – это ключ к
знаниям, воплощенным в программе. Так, если внешний смысл, который
пользователь придает символическим обозначениям в выходной информации
программы, будет отличаться от внешнего смысла, который в них вкладывал
программист, то пользователю может показаться, что программа составлена
некорректно.
Рассмотрим в качестве примера человека, который в первый раз пришел в
библиотеку с компьютеризированным каталогом. Программа спрашивает этого
человека: «Тип книги?», не давая никаких указаний о том, что может
обозначать слово «тип». Пользователь судорожно пытается сообразить, что же
следует ввести в ответ – « небеллетристика» ? «иностранная» ? «красная»? Он в
конце концов решает ввести слово «небеллетристика», но программа отвергает
это слово, сообщая, что «небеллетристика – это неверный тип». Пользователь
знаком со структурой каталога и предполагает, что эта структура корректно
реализована в программе. Однако для того, чтобы воспользоваться
программой, он вначале должен выяснить, какой смысл программист вложил в
символическое обозначение «тип».
Внешний смысл символических обозначений – это "подводный камень"
любой программы, представляющей знания, поскольку почти всегда у
конкретного символического обозначения существует более чем одно внешнее
смысловое значение. Символические обозначения, представляющие из себя
неоднозначные слова естественного языка (как слово «тип»), наиболее
ненадежны в этом отношении. Для того чтобы сузить диапазон внешних
смысловых значений символического обозначения, лучше всего делать более
точные определения отношений, в которых используются эти обозначения. К
примеру, внешним смыслом обозначения «мария», входящего в истинную
конкретную реализацию отношения "собрание/2"
собрание (мария, собрание_38).
может быть любое количество людей, первое имя которых – Мария. Но если
при определении отношения добавить номер человека по социальному
страхованию:
собрание (мария, 121_76_7720, собрание_38).
51
то это существенно сузит круг лиц с именем "Мария", к которым будет иметь
отношение символическое обозначение «мария», если только данная
конкретная реализация отношения "собрание/2" будет истинной.
3.2. Семантические сети
Рассмотрим принцип организации семантических сетей [4]. В
семантической сети сущности и классы сущностей ассоциируются с узлами, а
отношения между сущностями ассоциируются с дугами, соединяющими узлы.
Дуга, подсоединенная к единственному узлу, устанавливает свойство этого
узла. Семантическая сеть позволяет выполнять вывод но цепочкам,
описываемым определенными типами дуг. Например, в сети, изображенной на
рис. 3.2, узел «мероприятие» обладает свойством «проводится». Узел
«собрание» соединен дугой с узлом «мероприятие», поэтому можно прийти к
выводу о том, что узел «собрание» также обладает свойством «проводится».
Важнейшей концепцией формализма семантических сетей является
иерархия, поэтому данный формализм особенно удобен для представления
таксономий знаний. Каждый уровень таксономии представляется в виде узла,
который соединен дугами "является" с более высокими и более низкими
уровнями. К примеру, на рис. 3.2 «мероприятие» – это наивысший уровень
таксономии, а на следующем уровне могут располагаться различные виды
мероприятий.
проводится
мероприятие
является
собрание
место назначения
зал заседаний
присутствуют
роман
является
собрание_38
Рис. 3.2. Мероприятия
Если рассматривать семантическую сеть как описание отношений,
которые поддерживаются между сущностями, то ее можно непосредственно
реализовать при помощи языка Пролог. Нижеследующая программа выражает
структуру сети с «мероприятиями», представленную на рис. 3.2:
является (собрание, мероприятие).
является (собрание_38, собрание).
присутствуют(роман, собрание_38).
проводится (мероприятие).
52
проводится (X ) :– является ( X, Y ) , проводится ( Y ).
назначается_в (X,Y) :– является (X, Z), назначается_в (Z, Y).
Вторая фраза "назначается_в" позволяет сделать вывод о том, что
«собрание_38» назначается в зале заседаний, так как «собрание_38» – это
собрание, а любая сущность, которая является собранием, назначается в зале
заседаний. Вывод можно выполнить в любом месте, где два узла диаграммы
связаны дугой "является". Дуга "является" представляет либо отношение
включения в класс (например, класс собраний включается в класс
мероприятий), либо отношение принадлежности к классу («собрание_38» – это
член класса собраний).
3.3. Фреймы
Концепция фреймов является одним из способов представления знаний о
ситуациях [4]. Каждый фрейм содержит слоты (в буквальном переводе –
щели), которые идентифицируют тип ситуации или задают параметры
конкретной ситуации. К примеру, фрейм, описывающий ситуацию на собрании,
может иметь слот тип, значение которого будет определять тип собрания. В
этом фрейме могут также присутствовать слоты время и место, значениями
которых будут параметры конкретного собрания. Формализм фреймов можно
рассматривать как обобщение формализма семантических сетей. Иерархия –
это одна из важнейших концепций формализма фреймов, поэтому данный
формализм также пригоден для представления таксономий знаний.
Выражение, записанное на языке фреймов, таком как FRL, декларирует
существование фрейма. В нижеследующем примере упоминаются три фрейма –
МЕРОПРИЯТИЕ, СОБРАНИЕ и СОБРАНИЕ_38. Фрейм МЕРОПРИЯТИЕ –
наиболее общий, фрейм СОБРАНИЕ – более конкретный, описывающий вид
МЕРОПРИЯТИЯ, а фрейм СОБРАНИЕ_38 – наиболее уточненный фрейм,
описывающий конкретное СОБРАНИЕ. Фрейм СОБРАНИЕ называется
субфреймом фрейма МЕРОПРИЯТИЕ, а фрейм СОБРАНИЕ_38 будет
субфреймом фрейма СОБРАНИЕ.
(СОБРАНИЕ
(РАЗНОВИДНОСТЬ
(ВРЕМЯ
(МЕСТО
)
(СОБРАНИЕ_38
(РАЗНОВИДНОСТЬ
(ПРИСУТСТВУЮТ
($VALUE
($DEFAULT
($DEFAULT
(МЕРОПРИЯТИЕ)))
(СРЕДА 14.00)))
(ЗАЛ ЗАСЕДАНИЙ)))
($VALUE
($VALUE
(СОБРАНИЕ)))
(РОМАН)
(АННА)
(БОРИС))
имя фрейма
имена и значения слотов
(умалчиваемые
значения наследуются
субфреймами
имя фрейма
имена и значения слотов
Наследование значений слотов. Другой важнейшей концепцией
формализма фреймов является наследование. Можно дать указание о том, что
53
если значение слота в одном из фреймов не задается, то фрейм должен
унаследовать умалчиваемое значение этого слота из фрейма более высокого
уровня. Наследование фреймами значений слотов будет осуществляться в том
случае, если в фрейме будет присутствовать слот РАЗНОВИДНОСТЬ, в
котором содержится имя другого фрейма. Например, слоты ВРЕМЯ и МЕСТО
фрейма СОБРАНИЕ будут унаследованы фреймом СОБРАНИЕ_38. Слот
РАЗНОВИДНОСТЬ языка фреймов аналогичен дуге "является" семантической
сети в том смысле, что он представляет отношение включения в класс или
отношение принадлежности к классу.
Оценка формализма фреймов. Фрейм лучше всего трактовать как
некоторую разновидность структур данных. Наследование от фрейма к фрейму
реализуется процедурами, которые осуществляют доступ к конкретным
экземплярам структур данных. Если язык фреймов не обеспечивает тот тип
вывода, который нужен программисту, то программист может написать новую
процедуру, обеспечивающую такой вывод. В худшем случае это означает, что
каждый возможный вывод потребуется записывать в явной форме. Для
действительного понимания смысла программы, написанной на языке фреймов,
необходимо соотнести выражения на языке фреймов с процедурами,
реализующими выводы для фреймов. Это может оказаться весьма сложным, так
как процедуры записываются на языке, отличном от языка фреймов.
Реализация фрейм-программы на Прологе. Нижеследующая Прологпрограмма выражает структуру приведенного выше примера СОБРАНИЕ.
разновидность (собрание, мероприятие).
разновидность (собрание_38, собрание).
% локальные значения слотов для фрейма СОБРАНИЕ:
собрание (время, 'Среда 14.00').
собрание (место, 'Зал заседаний').
% локальные значения слотов для фрейма СОБРАНИЕ_38:
собрание_38 (присутствуют, [роман, анна, борис]). % (1)
% правило наследования
собрание_38 (Атрибут, Значение) :– % (2)
разновидность (собрание_38, Фрейм),
подцель =. . [фрейм, Атрибут, Значение],
подцель.
Обратите внимание на то, что и "собрание", и "собрание_38" – это базы
данных, в которых хранятся атрибуты. База данных "собрание" связана с базой
данных "собрание_38" при помощи факта «разновидность(собрание_38,
собрание)». Правило наследования позволяет "собранию_38" наследовать
54
любые значения атрибутов от "собрания" Если запросить время проведения
"собрания_38":
? – собрание_38 (время, X).
Х='Среда.14.00'
то ответ будет получен по факту "собрание" при помощи правила
наследования.
Факты, противоречащие друг другу. Представьте себе, что сперва
планировалось провести "собрание_38" в принятое по умолчанию время
(Среда, 14.00), но потом по какой–то причине понадобилось его перенести.
Посмотрим, что получится, если в базу данных "собрание_38" добавить атрибут
"время", противоречащий уже имеющемуся атрибуту.
собрание_38 (время, 'Четверг 9.00').
Теперь в слоте "время" фрейма "собрание_38" будут находиться два значения –
локальное значение и унаследованное значение:
?– собрание_38 (время, X).
Х = 'Четверг 9.00';
Х = 'Среда 14.00';
нет
Здесь трудность состоит в том, что "собрание_38" должно описывать
реальное собрание, которое может быть проведено только один раз. Иными
словами, отношение между собранием и временем его проведения должно
регулироваться ограничением вида один–к–одному, обеспечивающим
целостность отношения. Однако в данной версии программы запрос
вырабатывает два значения времени проведения собрания. Значение «Четверг
9.00» должно перекрывать умалчиваемое значение «Среда 14.00», так что
запрос, подобный приведенному выше, должен вырабатывать только значение
«Четверг 9.00».
Запрет наследования. Проблема решается при помощи приводимой ниже
программы. Предикат "сократить" в первом правиле "собрание_38" гарантирует
то, что если у фрейма "собрание_38" будет иметься локальное значение слота,
то этот фрейм не сможет унаследовать другое значение того же самого слота от
фрейма "собрание".
разновидность: (собрание, мероприятие).
разновидность (с_38, собрание).
% значения слотов фрейма "собрание":
собрание (время. 'Среда 14.00').
55
собрание (место, 'Зал заседаний').
% локальное правило
собрание_38 (Атрибут, Значение) :–
с_38 (Атрибут, Значение),!.
% правило наследования
собрание_38 (Атрибут, Значение) :–
разновидность (с_38, Фрейм),
Подцель =..[Фрейм, Атрибут, Значение],
Подцель.
% значения слотов, локальные по отношению к фрейму
% "собрание_38":
с_38 (присутствуют, [роман, анна, борис]).
с_38 (время, 'Четверг 9.00').
Все атрибуты, являющиеся локальными для фрейма "собрание_38",
теперь хранятся в базе данных "с_38". Первое правило "собрание_38"
проверяет, имеется ли в базе данных "с_38" фраза с требуемым атрибутом. Если
имеется, то возвращается нужное значение, а предикат "сократить"
предотвращает дальнейшую выдачу ответов. Если такой фразы нет в базе
данных "с_38", то второе правило "собрание_38" ищет требуемый атрибут в
базе данных "собрание". Теперь запрос о времени проведения собрания выдает
единственный ответ:
?– собрание_38 (время, X).
Х = 'Четверг 9.00';
нет
?– собрание_38 (место, X).
Х = 'Четверг 9.00';
Х = 'Зал заседаний';
нет
%по «с_38»
%по «собрание_38»
3.4. Механизм наследования в Прологе
Формализм фреймов допускает, чтобы значения слотов фрейма общего
вида наследовались конкретным фреймом. Наследование можно запретить,
если ввести значение слота в конкретный фрейм, при этом наследуемое
значение слота будет перекрыто [4].
Наследование в Прологе. До сих пор в данном разделе рассматривались
неуниверсальные способы реализации механизма наследования при помощи
56
языка Пролог. Так, в примере с собранием наследование осуществлялось
посредством процедуры:
% локальное правило
собрание_38 (Атрибут, Значение) :–
с_38 (Атрибут, Значение), !.
% правило наследования
собрание_38 (Атрибут, Значение) :–
разновидность(с_38, Фрейм),
подцель = ..[Фрейм, Атрибут, Значение],
подцель.
Такой подход приводит к искаженному отображению структуры
представляемой системы. Ему к тому же свойственны два ограничения:
1) он применим только к базам данных, информация в которых хранится в
виде атрибутов, представленных в форме «фрейм (Атрибут, Значение)»;
2) применение предиката "сократить" в первом правиле не дает
возможности употребить в правиле "собрание_38" более одного
локального значения атрибута. Было бы желательным иметь общий
механизм описания наследования в Прологе, свободный от этих
ограничений.
Наследование можно трактовать как разновидность вывода,
выполняемого между состояниями знаний [4]. Дадим полную интерпретацию
символических обозначений для примера с собранием. Предположим, что
еженедельные собрания, в которых участвуют Роман, Анна и Борис, проводятся
регулярно по средам в 14.00. Можно сказать, что среда 14.00 – это
умалчиваемое время проведения еженедельных собраний, в которых
принимают участие эти лица. Когда первоначально планировалось
еженедельное собрание "собрание_38", то все его участники предполагали, что
оно будет проведено в обычное время. В среду утром, однако, Борис узнает, что
он должен уехать после обеда, и поэтому просит перенести "собрание_38".
Участники собрания соглашаются перенести его на четверг на 9.00. Перенос
срока проведения собрания привел к изменению состояния знаний этих людей
о еженедельном собрании. В новом состоянии знаний умалчиваемое время
проведения собрания перекрывается новым значением времени.
При представлении этой ситуации с помощью фреймов состояния знаний
о ней (до и после действий Бориса) задаются в неявном виде. Представление
ситуации станет более четким, если состояния знаний будут выражены в явной
форме. Этого можно будет добиться, если присвоить имена состояниям знаний
и добавить в каждое отношение, входящее в представление, дополнительный
параметр, который будет связывать отношение с тем состоянием, в котором это
отношение имеет место. Отношение между состояниями знаний также должно
быть выражено явно. Тогда наследование информации от общего состояния
57
знании к конкретному состоянию знаний можно будет реализовать при помощи
процедуры общего назначения.
В оставшейся части данного раздела рассматриваются реализация и
применение универсального механизма наследования, написанного на языке
Пролог. Механизм основывается на явных ссылках к состояниям знаний. Он
даст возможность программисту представлять структуру систем, в которых
существует наследование (например, "собрание"), без необходимости
использовать побочные эффекты управления во фразах, ориентированных на
конкретное применение. Данный механизм является расширением
обрабатывающей структуры Пролога, которое должно усилить выразительную
силу языка.
Обзор механизма наследования. Механизм наследования – это метод
представления многих состояний знаний, при котором конкретное состояние
может наследовать информацию от общего состояния. Фраза ставится в
соответствие состоянию путем добавления имени состояния в заголовок фразы
(в виде первого ее аргумента); все остальные аргументы не изменятся.
Отношение между общим и конкретным состояниями записывается в виде
факта "порождение/2". Наследование фраз от состояния к состоянию
реализуется процедурой "послать". С декларативных позиций процедуру
"послать" можно трактовать как отношение, существующее между состоянием
знаний и запросом, если можно доказать истинность запроса по фразам,
связанным с данным состоянием.
Главной аналитической задачей при использовании механизма
наследования является установление иерархии состояний знаний. Взаимосвязь
состояний можно рассматривать как дерево, в котором каждое состояние
представляется узлом. Пусть имеются два состояния А и Б. Если состояние Б –
это узел дерева, порожденный состоянием А, то Б унаследует все фразы,
связанные с А, за исключением тех, которые явно опровергаются в Б.
Предположим, что самым верхним состоянием конкретного дерева
является состояние «служащие». Оно содержит информацию, в целом
применимую по отношению ко всем служащим, такую как места расположения
отделов, имена менеджеров отделов и т. д. У состояния «служащие» есть два
порожденных им состояния – «служащие, получающие оклад», и «служащие,
работающие по контракту». Состояние «служащие, получающие оклад»
содержит базу данных, в которой хранятся сведения об именах служащих,
получающих оклад, и иную информацию, например, данные о виде налоговой
ведомости, которую эти служащие получают в конце года. Состояние
«служащие, работающие по контракту» содержит базу данных со сведениями
об именах служащих, работающих по контракту, и иную относящуюся к этим
служащим информацию. Данное дерево состояний изображено на рис. 3.3.
58
Служащие
СЛУЖАЩИЕ,
порождение
РАБОТАЮЩИЕ
СЛУЖАЩИЕ
Менеджеры
Места
расположения
отделов
ПО
КОНТРАКТУ
Служащие
Агентства
Рис. 3.3. Служащие
Налоговые
ведомости
СЛУЖАЩИЕ,
порождение
ПОЛУЧАЮЩИЕ
ОКЛАД
Служащие
Налоговые
ведомости
Создание дерева состояний. Отношение двух состояний описывается в
базе данных "порождение". Для того чтобы реализовать приведенный выше
пример в виде программы, нужно, чтобы один факт "порождение"
свидетельствовал о том, что состояние «служащие, получающие оклад»,
порождено состоянием «служащие», а другой факт говорил о том, что и
состояние «служащие, работающие по контракту», является порождением
состояния «служащие». Связь фразы Пролог–программы с определенным
состоянием устанавливается благодаря введению дополнительного аргумента,
содержащего имя состояния.
Приведем версию программы для примера со служащими.
% дерево состояний:
порождение (на_окладе, служащие).
порождение (по_контракту, служащие) .
% фразы, связанные с состоянием "служащие":
%
Состояние Отд. Расположение
расположение_отдела( служащие, 100, 'Флигель 2–й этаж').
расположение_отдела ( служащие, 200, 'Здание 4073').
%
менеджер_отдела (
менеджер_отдела (
Состояние Отд. Менеджер
служащие, 100, иванов).
служащие, 200, романов).
% собрание всех служащих отдела 100:
собрание_отдела (служащие, 100, 'Вт 22.01 Комната 235').
% фразы, связанные с состоянием "на_окладе":
%
Состояние Имя
Отд. Оклад
служ (
на_окладе, слонов,
100, 55000).
служ (
на_окладе, ливанов, 100, 40000).
служ (
на_окладе, антонов, 200, 35000).
59
%
налогов_ведомость (
Состояние Форма
на_окладе, 2).
% собрание только для служащих отдела 100, получающих
% оклад:
собрание_отдела (на_окладе, 100, 'Пн 21.01 Комната 201').
% фразы, связанные только с состоянием "по_контракту":
%
Состояние
Имя
Отд. Оклад
служ(по_контракту,
алексей,
100, неприменим).
служ (по_контракту, виктор,
200, неприменим).
%
Состояние
Форма
налогов_ведомость ( по_контракту, 1099).
Процедура "послать". Наследование фраз от состояния к порожденным
им состояниям реализуется процедурой "послать". У этой процедуры два
аргумента – имя состояния, к которому обращен запрос, и Пролог-запрос, в
котором отсутствует аргумент, обозначающий имя состояния. Нижеследующий
вызов процедуры "послать" запрашивает номер формы налоговой ведомости,
которую следует выдать служащим, работающим по контракту:
?– послать (по_контракту, налогов_ведомость (Форма)).
Форма = 1099 ;
нет
Обратите внимание на то, что процедура "послать" смогла найти только
один ответ на запрос «налогов__ведомость(Форма)». В следующем вызове
процедуры "послать" задается вопрос о менеджере служащих, работающих в
отделе 100 по контракту. Из ответа видно, что состояние «по_контракту»
наследует фразы от состояния «служащие».
?– послать (по_контракту, менеджер_отдела (100, Кто)).
Кто = иванов ;
Нет
Переадресация запроса. Если процедура "послать" не может решить
запрос в соответствии с фразами заданного состояния, она переадресует этот
запрос к порождающему состоянию. Если запрос потерпит повторную неудачу
в порождающем состоянии, то процедура "послать" переадресует его к
порождающему состоянию еще более высокого уровня. Этот процесс может
продолжаться до тех пор, пока не будет достигнуто порождающее состояние
самого высокого уровня.
Нижеследующий запрос спрашивает о собраниях, в которых должны
принять участие все служащие отдела 100, получающие оклад. Данный пример
60
показывает, что процедура "послать" может вырабатывать ответы на основании
информации, получаемой более чем из одного состояния.
?– послать (на_окладе, собрание_отдела (100, М)).
М = 'Пн 21.0] Комната 201' ;
% по состоянию "на_окладе"
М =• Вт 22.01 Комната 235'
% по состоянию "служащие"
Опровержение фразы. Предположим, что компания в качестве
поспешной дискриминационной меры решает переместить в подвальное
помещение флигеля всех служащих отдела 100, работающих по контракту. Это
равнозначно изменению структуры системы, что потребует надлежащего
изменения описания системы. Такое изменение можно осуществить при
помощи деструктивного перекодирования соответствующих баз данных. Но
есть и другой способ внесения изменений, при котором существующие базы
данных будут затронуты в минимальной мере. Для этого нужно добавить к
состоянию «по_контракту» новый факт «расположение_отдела» и опровергнуть
старый факт:
расположение_отдела (по_контракту, 100, 'Подвал флигеля').
опровергнуть (по_контракту,
расположение_отдела (служащие, 100, 'Флигель 2-й этаж')).
Состояние «по_контракту» – это состояние, для которого осуществляется
опровержение, а фраза «расположение_отдела (служащие, 100, 'Флигель 2-й
этаж')» – это опровергаемая фраза. После того как в Программу будут
добавлены приведенные выше фразы, при просьбе выдать место расположения
отдела 100, адресованной к состоянию «по_контракту», будет выводиться
новое значение:
?– послать (по_контракту, расположение_отдела (100, Р)).
Р = 'Подвал флигеля ;
нет;
Но по требованию выдать ту же самую информацию, адресованному к
состоянию «служащие», все еще будет вырабатываться старое значение:
?– послать (служащие, расположение_отдела:(100,Р))
Р = 'Флигель 2-й этаж ;
нет
Если фраза опровергнута для конкретного состояния, то она больше не
будет наследоваться ни этим состоянием, ни любыми другими порожденными
им состояниями. Если же к состоянию была бы добавлена новая фраза, то она
стала бы наследоваться всеми ею порожденными состояниями. Описанное
61
употребление факта "опровергнуть" значительно облегчает сопровождение
программы.
Концепции механизма наследования. Механизм наследования базируется
на следующих ключевых концепциях:
1) иерархия состояний знаний;
2) наследование фраз oт состояния к состоянию и
3) отмена наследования фразы путем ее опровержения.
Концепции формализма фреймов так соответствуют приведенным выше
концепциям:
– фрейм соответствует состоянию знаний;
– слот соответствует фразе, относящейся к состоянию знаний;
– наследование значений слотов от фрейма к фрейму соответствует
наследованию фраз от состояния к состоянию;
– способность локального значения слота перекрывать наследуемое
значение слота соответствует возможности опровергнуть унаследованную
фразу и заменить ее новой фразой.
Пример с собранием. Для разъяснения данных положений целесообразно
посмотреть, как можно воспользоваться механизмом наследования для
реализации простых примеров, приведенных ранее в данной главе. Ниже дается
версия программы для примера с собранием. У состояния «собрание» имеются
два потомка (т. е. порожденных состояния): «собрание_38», наследующее от
состояния «собрание» умалчиваемое значение времени проведения собрания, и
«собрание_39», в котором задается свое собственное время.
% дерево состояний:
порождение (собрание, мероприятие).
порождение (собрание_38, собрание).
порождение (собрание_39, собрание).
% фразы, относящиеся к состоянию "собрание":
время (собрание, 'Среда 14.00').
место (собрание, 'Зал заседаний').
% фразы, относящиеся к состоянию " собрание_39":
присутствуют (собрание._38, [роман, анна, борис]).
% фразы, относящиеся к состоянию "собрание_39"
тема (собрание_39, 'версия 3.0').
присутствуют (собрание_39, [марта, роман, анна]).
опровергнуть (собрание_39, время (собрание, _))
время (собрание_39, 'Четверг 9.00' ).
Обратите внимание на то, что значение времени, наследуемое из
состояния «собрание», опровергается в состоянии «собрание_39». Это
62
опровержение предохраняет состояние «собрание_39» от появления двух
противоречащих друг другу значений времени проведения собрания. Заметьте
также, что все приведенные фразы свободны от побочных эффектов
управления.
3.5. Создание динамических баз данных
Динамическая база данных – это база данных, в которую время от
времени требуется вносить изменения, отражающие изменения структуры
описываемой системы [4]. Один из методов реализации динамической базы
данных заключается в деструктивном редактировании базы данных при
необходимости внесения в нее изменений. К сожалению, при деструктивном
редактировании исчезает возможность возврата к состоянию базы данных,
существовавшему ранее. Это затрудняет анализ изменений базы данных.
Аксиома фреймов является альтернативной концепцией реализации
динамической базы данных. Если необходимо внести изменение, то исходная
база данных остается неизменной, а записывается собственно изменение.
Текущая форма базы данных получается при использовании ее исходной
формы с учетом сделанных изменений. Ниже формулируется аксиома фреймов,
в которой U обозначает любое отношение, а состояние S+1 является
результатом выполнения действия А в состоянии S.
Аксиома фреймов. Отношение U будет соблюдаться в состоянии S + 1,
являющемся результатом выполнения действия А в состоянии S, если U
соблюдается в состоянии S, а А не влияет на U.
Иными словами, состояние базы данных унаследует каждую фразу
предыдущего состояния, если только эти фразы не были явно изменены при
переходе в данное состояние.
В соответствии с аксиомой фреймов для представления динамической
базы данных можно воспользоваться механизмом наследования. Начальное
состояние базы данных соответствует самому верхнему узлу дерева состояний.
Каждое новое состояние базы данных вводится как состояние–потомок
предыдущего состояния.
После введения нового состояния базы данных как потомка
существующего состояния каждая фраза, связанная с существующим состоянием, либо будет унаследована состоянием–потомком (т. е. не изменится), либо
будет перекрыта новым значением (т. е. изменится), либо будет опровергнута
(т. е. удалена). Помимо этого в новое состояние могут быть введены новые
фразы.
Мир кубиков. Мир кубиков – это пример, часто используемый для того,
чтобы проиллюстрировать аксиому фреймов. Для точного описания мира
кубиков требуется динамическая база данных, в которой задаются положения
кубиков на крышке стола. Метод, употребляемый для представления мира
63
кубиков, можно с успехом применить и в других задачах, где требуется
динамическая база данных.
Описываемая версия мира кубиков основывается на базе данных,
состоящей из фактов "на/3", при помощи которых задается положение кубиков.
Факт «на(5, А, В)» означает, что в состоянии S кубик А находится на верхней
части кубика В. Процедура "поместить" позволяет пользователю перемещать
кубики, входящие в мир, на другие места, что соответствует переходам к новым
состояниям базы данных "на". Начальное состояние базы данных "на" носит
название "1", следующее состояние – "2" и т. д.
Характеристики отношения "на". Отношение "на" – это отношение либо
между двумя кубиками в некотором состоянии, либо между кубиком и столом.
Согласно определению данное отношение несимметрично, нерефлексивно и
нетранзитивно. Все кубики имеют одинаковый размер, отношение "на" между
двумя кубиками регулируется ограничением вида один–к–одному,
обеспечивающим целостность. Иными словами, если кубик А уже находится на
кубике В, то на кубике В не может быть никаких других кубиков. На столе
может поместиться более одного кубика.
Главной функцией процедуры "поместить" является сбор данных – она
собирает у пользователя сведения о необходимых изменениях базы данных.
Для защиты базы данных "на" от некорректных изменений в процедуре
"поместить" применяются ограничения, обеспечивающие целостность базы
данных. К примеру, если кубик А уже находится на кубике В, а пользователь
попытается поставить на В кубик С, то процедура "поместить" откажется
выполнить предписываемое перемещение и выдаст пользователю
предупреждающее сообщение. Тем самым процедура "поместить" следит за
тем, чтобы в точке, где пользователь пытается вносить изменения в базу
данных, отношение "на" между двумя кубиками имело вид один–к–одному.
Процедура "поместить" накладывает и другие ограничения, обеспечивающие
целостность, такие как недопущение употребления кубика, отсутствующего в
текущем состоянии.
Первоначально база данных, описывающая мир кубиков, состоит из
следующих фактов:
на(1, а, стол).
на (1, б, стол).
на(1, в, а).
на(1, г,в).
текущее_состояние (1).
Факт "текущее_состояние"
состояния базы данных.
64
содержит
наименование
самого
последнего
Картина
состояния.
Экранно-ориентированная
процедура
"отобразить_состояние" строит на экране дисплея изображение кубиков для
заданного состояния базы данных. Начальное состояние выглядит так:
?– отобразить_состояние (1).
Г
В
А
С
Б
Т
О
Л
Внесение изменений в базу данных при помощи процедуры "поместить".
Процедура "поместить" вносит изменение в базу данных, генерируя состояниепотомок текущего состояния. Она добавляет новые данные в состояниепотомок, а затем деструктивно изменяет значение факта "текущее_состояние",
превращая его в обозначение потомка. Первым аргументом процедуры
"поместить" является обозначение кубика, который нужно передвинуть, а
вторым аргументом служит место, куда нужно поставить этот кубик.
Например, если текущее состояние – это "1", то запрос
?– поместить (г, стол).
% запрос (1)
вызовет добавление в программу следующих фраз:
текущее_состояние (2).
на (2, г, стол).
опровергнуть (2, на (_,г,в)).
Кроме того, из программы будет удалена фраза «текущее_состояние (1)».
Выяснение того, где находятся кубики. Нижеследующий запрос покажет,
где находятся кубики в состоянии "2" базы данных:
?– послать (2, на (_X, Y)).
Х=г
У=стол;
%по состоянию «2»
Х=а
У=стол;
%по состоянию «1»
Х=б
У=стол;
%по состоянию «1»
Х=в
65
У=стол;
%по состоянию «1»
нет
Эта информация будет лучше восприниматься, если ее представить в
графическом виде:
?– отобразить_состояние (2).
Г
С
В
А
Т
Б
О
Л
Посмотрим, как будет выглядеть база данных после внесения еще
нескольких изменений.
?– поместить (а, б).
% запрос (2)
да
?–поместить (в, г).
% запрос (3)
да
? – текущее_состояние (X).
Х=4
? – отобразить_состояние (4).
В
Г
С
А
Б
Т
О
Л
Реализация процедуры "поместить".
% запретить использование неизвестного кубика:
поместить (Кубик. Куда_поставить) : –
% проверить, отсутствуют ли
% Кубик и Куда_поставить:
not (на(...; Кубик, _))
;
Куда_поставить \== стол,
not (на(...; Куда_поставить, _)),
write(‘неверное обращение к кубику’), nl, !.
% запретить изменение, если переменная Куда_поставить обозначает
% кубик, на котором уже стоит другой кубик:
поместить (Кубик. Куда_поставить) : –
Куда_поставить \== стол,
Текущее_состояние(Состояние),
послать(Состояние, на(Занят, Куда_поставить)),
66
write(Занят),
write(‘ уже находится на ’)
write(Куда_поставить), nl,!.
% здесь база данных изменяется:
поместить (Кубик, Куда_поставить) :–
текущее_состояние (Состояние),
НовоеСостояние is Состояние + 1,
assert (порождение (НовоеСостояние, Состояние)),
%
послать (Состояние, на (Кубик, Под_кубиком)),
assert (опровергнуть (НовоеСостояние,
на(_, Кубик, Под_кубиком))),
assert (на (НовоеСостояние, Кубик, Куда_поставить)),
retract (текущее_состояние (Состояние)),
assert (текущее_состояние (НовоеСостояние)), !.
%1
%2
%3
%4
%5
%6
%7
%8
Ограничения, обеспечивающие целостность, которые накладываются во
время сбора данных. Первое правило "поместить" отвергает кубики, которые
отсутствуют в мире. Второе правило не разрешает пользователю ставить кубик
на другой кубик, место над которым уже занято. Если два первых правила
потерпят неудачу, то это будет означать, что ограничения, обеспечивающие
целостность базы данных, не будут нарушены при предлагаемом ее изменении.
Собственно изменение осуществляется третьим правилом "поместить".
Подцели (2) и (3) этого правила устанавливают новое состояние базы данных
"порождение". Подцель (4) выясняет текущее местоположение кубика "Кубик",
а подцель (5) опровергает это местоположение. Подцель (6) добавляет к новому
состоянию новое местоположение кубика "Кубик". В заключение подцели (7) и
(8) деструктивно изменяют значение факта "текущее_состояние".
Перемещение колонки кубиков. В рассматриваемой версии программы
"поместить" разрешается передвигать за один раз целую колонку кубиков.
Иными словами, не запрещается перемещать кубик, если на нем стоит еще один
кубик. Это именно то, что будет сделано в ответ на приведенный выше запрос
(2): «поместить (а, б)». Все кубики, стоящие над перемещаемым, наследуют
новое положение этого кубика. Можно было бы добавить еще одно правило,
которое реализовывало бы ограничение, обеспечивающее целостность,
гарантируя то, что за один раз будет перемещаться только один кубик.
Оценка механизма наследования. Механизм наследования – это
практическое воплощение концепции наследования. Он пригоден для
представления таких ситуаций, в которых имеется множество состояний
знаний, иерархически взаимосвязанных друг с другом. Тем самым механизм
наследования создает основу для перевода на Пролог знаний, выраженных при
помощи формализма фреймов или объектно-ориентированного формализма.
Уже существующую фразу Пролог-программы легко можно адаптировать к
этому механизму, просто добавив в заголовок этой фразы дополнительный
67
аргумент, содержащий имя состояния знаний. Примеры данного раздела
показывают, что применение механизма наследования позволяет реализовать
удобную дня восприятия аксиоматизацию системы, свободную от побочных
эффектов управления.
Недостатком механизма наследования является то, что он работает
неэффективно, если запросу к процедуре "послать" приходится анализировать
длинные цепи состояний. В приведенной форме механизм наследования
позволяет порожденному состоянию иметь более одного родителя. В объектно–
ориентированном формализме это называется множественным наследованием.
Неэффективность процедуры "послать" возрастает, если состояние, к которому
обращен запрос, имеет более одного родителя.
3.6. Представление задач в виде И/ИЛИ-графов
Представление в виде И/ИЛИ-графов наиболее хорошо приспособлено
для задач, которые естественным образом разбиваются на взаимно независимые
подзадачи [1]. Примерами таких задач могут служить поиск маршрута, игровые
задачи, доказательство теорем и т. п.
Для некоторых категорий задач представление в форме И/ИЛИ-графа
является более естественным. Такое представление основано на разбиении
задач на подзадачи. Разбиение на подзадачи дает преимущества в том случае,
когда подзадачи взаимно независимы, а следовательно, и решать их можно
независимо друг от друга.
Проиллюстрируем это на примере [2]. Рассмотрим задачу отыскания на
карте дорог маршрута между двумя заданными городами, как показано на рис.
3.4. Не будем пока учитывать длину путей. Разумеется, эту задачу можно
сформулировать как поиск пути в пространстве состояний. Соответствующее
пространство состояний выглядело бы в точности, как карта рис. 3.4: вершины
соответствуют городам, дуги – непосредственным связям между городами. Тем
не менее давайте построим другое представление, основанное на естественном
разбиении этой задачи на подзадачи.
Рис. 3.4. Поиск маршрута из а в z на карте дорог
68
На карте рис. 3.4 мы видим также реку. Допустим, что переправиться
через нее можно только по двум мостам: один расположен в городе f, другой –
в городе g. Очевидно, что искомый маршрут обязательно должен проходить
через один из мостов, значит, он должен пройти либо через f, либо через g.
Таким образом, мы имеем две главных альтернативы:
Для того чтобы найти путь из а в г, необходимо найти одно из двух:
(1) путь из а в г, проходящий через f, или
(2) путь из а в г, проходящий через g.
Рис. 3.5. И/ИЛИ-представление задачи поиска маршрута
Теперь каждую из этих двух альтернативных задач можно, в свою
очередь, разбить следующим образом:
1. Для того, чтобы найти путь из а в г через f, необходимо:
1.1. Найти путь из а в f .
1.2. Найти путь из f в z.
2. Для того, чтобы найти путь из a в z через g, необходимо:
2.1 Найти путь из а в g и
2.2 Найти путь из g в z.
69
Итак, мы имеем две главных альтернативы для решения исходной задачи:
(1) путь через f или (2) путь через g. Далее, каждую из этих альтернатив можно
разбить на подзадачи (1.1 и 1.2 или 2.1 и 2.2 соответственно). Здесь важно то
обстоятельство, что каждую из подзадач в обоих альтернативах можно решать
независимо от другой. Полученное разбиение исходной задачи можно
изобразить в форме И/ИЛИ-графа (рис. 3.5).
Рис. 3.6. Задачи приемников
Граф, показанный на рис. 3.5, – это всего лишь верхняя часть всего
И/ИЛИ–дерева. Дальнейшее разбиение подзадач можно было бы строить на
основе введения дополнительных промежуточных городов.
Какие вершины И/ИЛИ-графа являются целевыми? Целевые вершины –
это тривиальные, или «примитивные», задачи. В нашем примере такой
подзадачей можно было бы считать подзадачу «найти путь из а в с», поскольку
между городами а и с на карте имеется непосредственная связь.
Рассматривая наш пример, мы ввели ряд важных понятий. И/ИЛИ-граф –
это направленный граф, вершины которого соответствуют задачам, а дуги
отношениям между задачами. Между дугами также существуют свои
отношения. Это отношения И и ИЛИ в зависимости от того, должны ли мы
решить только одну из задач-преемников или же несколько из них (см. рис.
3.6). В принципе из вершины могут выходить дуги, находящиеся в отношении
И вместе с дугами, находящимися в отношении ИЛИ. Тем не менее, мы будем
предполагать, что каждая вершина имеет либо только И-преемников, либо
только ИЛИ-преемников; дело в том, что в такую форму можно преобразовать
любой И/ИЛИ-граф, вводя в него при необходимости вспомогательные ИЛИвершины. Вершину, из которой выходят только И-дуги, называют И-вершиной;
вершину, из которой выходят только ИЛИ-дуги, – ИЛИ-вершиной.
Что же является решением в случае И/ИЛИ-представления? Решение
должно, конечно, включать в себя все подзадачи И-вершины. Следовательно,
это уже не путь, а дерево. Такое решающее дерево Т определяется следующим
образом:
 исходная задача Р – это корень дерева Т;
70
 если Р является ИЛИ-вершиной, то в Т содержится только один из ее
преемников (из И/ИЛИ-графа) вместе со своим собственным решающим
деревом;
 если Р – это И-вершина, то все ее преемники (из И/ИЛИ-графа) вместе со
своими решающими деревьями содержатся в Т.
Рис. 3.7. Решающее дерево Т
Иллюстрацией к этому определению может служить рис. 3.7. Используя
стоимости, мы можем формулировать критерии оптимальности решения.
Например, можно определить стоимость решающего графа как сумму
стоимостей всех входящих в него дуг. Тогда, поскольку обычно мы
заинтересованы в минимизации стоимости, мы отдадим предпочтение
решающему графу, изображенному на рис. 3.7, с.
Для задачи отыскания кратчайшего маршрута (рис. 3.4) И/ИЛИ-граф
вместе с функцией стоимости можно определить следующим образом:
 ИЛИ-вершины представляются в форме X–Z, что означает: найти
кратчайший путь из X в Z.
 И-вершины имеют вид X–Z через Y , что означает: найти кратчайший путь
из X в Z, проходящий через Y.
 Вершина X–Z является целевой вершиной (примитивной задачей), если на
карте существует непосредственная связь между X и Z.
 Стоимость каждой целевой вершины X–Z равна расстоянию, которое
необходимо преодолеть по дороге, соединяющей X с Z.
 Стоимость всех остальных (нетерминальных) вершин равна 0.
В этом разделе нас будет интересовать какое-нибудь решение задачи
независимо от его стоимости, поэтому проигнорируем пока стоимости связей
71
или вершин И/ИЛИ-графа. Простейший способ организовать поиск в И/ИЛИграфах средствами Пролога – это использовать переборный механизм,
заложенный в самой Пролог-системе. Оказывается, что это очень просто
сделать, потому что процедурный смысл Пролога это и есть не что иное, как
поиск в И/ИЛИ-графе. Например, И/ИЛИ-граф рис. 3.7 (без учета стоимостей
дуг) можно описать при помощи следующих предложений:
a :– b.
% а – ИЛИ-вершина с двумя преемниками
a :– c.
%b ис
b :– d, е.
% b – И-вершина с двумя преемниками d и е
c :– h.
c :– f, g.
f :– h, i.
d. g. h.
% d, g и h – целевые вершины
Для того чтобы узнать, имеет ли эта задача решение, нужно просто
спросить:
?– а.
Получив этот вопрос, Пролог-система произведет поиск в глубину в дереве
рис. 3.7 и после того, как пройдет через все вершины подграфа,
соответствующего решающему дереву (рис. 3.7, b), ответит «да».
Контрольные вопросы и упражнения
1. Что такое фрейм?
2. Дайте определение семантической сети.
3. Перепишите программу «Советник по транспорту» с использованием
механизма фреймов.
4. Перепишите программу «Советник по транспорту» с использованием
механизма семантических сетей.
72
4. ЭКСПЕРТНЫЕ СИСТЕМЫ
4.1. Системы экспертных консультаций
В самом узком смысле термин экспертная система используется дли
описания одной из небольшого числа программ, разработанных
общепризнанными специалистами в области инженерии знаний. Назначение
этих программ состоит в воспроизведении возможностей решения задач
которыми обладает эксперт [4]. Инженер по знаниям – это специалист,
обученный искусству перенимать знания у экспертов и переводить эти знания в
форму, воспринимаемую компьютером. Большинство экспертных систем не
может полностью изменить человека. Такие системы используют дни
повышения эффективности работы и расширения знаний персонала средней
квалификации.
Программы, ведущие себя как экспертные системы, но не
основывающиеся на знаниях экспертов, называют также системами,
базирующимися на знаниях, или системами экспертных консультаций. С точки
зрения методологии создания программ почти безразлично, проводились ли
консультации с экспертами перед написанием программы или нет.
В настоящее время сложилась определенная технология разработки ЭС,
которая включает следующие шесть этапов: идентификация, концептуализация,
формализация, выполнение, тестирование и опытная эксплуатация [5].
Этап идентификации
Этап идентификации связан, прежде всего, с осмыслением тех задач,
которые предстоит решить будущей ЭС, и формированием требований к ней.
Результатом данного этапа является ответ на вопрос, что надо сделать и какие
ресурсы необходимо задействовать (идентификация задачи, определение
участников процесса проектирования и их роли, выявление ресурсов и целей).
Обычно в разработке ЭС участвуют не менее трех–четырех человек —
один эксперт, один или два инженера по знаниям и один программист,
привлекаемый для модификации и согласования инструментальных средств.
Также к процессу разработки ЭС могут по мере необходимости привлекаться и
другие участники. Например, инженер по знаниям может пригласить других
экспертов, чтобы убедиться в правильности своего понимания основного
эксперта, представительности тестов, демонстрирующих особенности
рассматриваемой задачи, совпадения взглядов различных экспертов на качество
предлагаемых решений. Кроме того, для сложных систем считается
целесообразным привлекать к основному циклу разработки несколько
экспертов. Однако в этом случае, как правило, требуется, чтобы один из
экспертов отвечал за непротиворечивость знаний, сообщаемых коллективом
экспертов.
73
Идентификация задачи заключается в составлении неформального
(вербального) описания, в котором указываются: общие характеристики задачи;
подзадачи, выделяемые внутри данной задачи; ключевые понятия (объекты), их
входные (выходные) данные; предположительный вид решения, а также знания,
относящиеся к решаемой задаче.
В процессе идентификации задачи инженер по знаниям и эксперт
работают в тесном контакте. Начальное неформальное описание задачи
экспертом используется инженером по знаниям для уточнения терминов и
ключевых понятий. Эксперт корректирует описание задачи, объясняет, как
решать ее и какие рассуждения лежат в основе того или иного решения. После
нескольких циклов, уточняющих описание, эксперт и инженер по знаниям
получают окончательное неформальное описание задачи.
При проектировании ЭС типичными ресурсами являются источники
знаний, время разработки, вычислительные средства и объем финансирования.
Для эксперта источниками знаний служат его предшествующий опыт по
решению задачи, книги, известные примеры решения задач, а для инженера по
знаниям — опыт в решении аналогичных задач, методы представления знаний
и манипулирования ими, программные инструментальные средства. При
определении времени разработки обычно имеется в виду, что сроки разработки
и внедрения ЭС составляют, как правило, не менее года (при трудоемкости
5 чел.-лет). Определение объема финансирования оказывает существенное
влияние на процесс разработки, так как, например, при недостаточном
финансировании предпочтение может быть отдано не разработке оригинальной
новой системы, а адаптации существующей.
При идентификации целей важно отличать цели, ради которых создается
ЭС, от задач, которые она должна решать. Примерами возможных целей
являются: формализация неформальных знаний экспертов; улучшение качества
решений, принимаемых экспертом; автоматизация рутинных аспектов работы
эксперта (пользователя); тиражирование знаний эксперта.
Этап концептуализации
На данном этапе проводится содержательный анализ проблемной
области, выявляются используемые понятия и их взаимосвязи, определяются
методы решения задач. Этот этап завершается созданием модели предметной
области (ПО), включающей основные концепты и отношения. На этапе
концептуализации определяются следующие особенности задачи: типы
доступных данных; исходные и выводимые данные, подзадачи общей задачи;
используемые стратегии и гипотезы; виды взаимосвязей между объектами ПО,
типы используемых отношений (иерархия, причина — следствие, часть —
целое и т. п.); процессы, используемые в ходе решения; состав знаний,
используемых при решении задачи; типы ограничений, накладываемых на
процессы, используемые в ходе решения; состав знаний, используемых для
обоснования решений.
74
Существуют два подхода к процессу построения модели предметной
области, которая является целью разработчиков ЭС на этапе концептуализации.
Признаковый или атрибутивный подход предполагает наличие полученной от
экспертов информации в виде троек объект — атрибут — значение атрибута, а
также наличие обучающей информации. Этот подход развивается в рамках
направления, получившего название формирование знаний или "машинное
обучение" (machine learning).
Второй подход, называемый структурным (или когнитивным),
осуществляется путем выделения элементов предметной области, их
взаимосвязей и семантических отношений.
Для атрибутивного подхода характерно наличие наиболее полной
информации о предметной области: об объектах, их атрибутах и о значениях
атрибутов. Кроме того, существенным моментом является использование
дополнительной обучающей информации, которая задается группированием
объектов в классы по тому или иному содержательному критерию. Тройки
объект — атрибут — значение атрибута могут быть получены с помощью так
называемого метода реклассификации, который основан на предположении, что
задача является объектно–ориентированной и объекты задачи хорошо известны
эксперту. Идея метода состоит в том, что конструируются правила
(комбинации значений атрибутов), позволяющие отличить один объект от
другого. Обучающая информация может быть задана на основании прецедентов
правильных экспертных заключений, например, с помощью метода извлечения
знаний, получившего название "анализ протоколов мыслей вслух".
При наличии обучающей информации для формирования модели
предметной области на этапе концептуализации можно использовать весь
арсенал методов, развиваемых в рамках задачи распознавания образов. Таким
образом, несмотря на то, что здесь атрибутивному подходу не уделено много
места, он является одним из потребителей всего того, что было указано в главе,
посвященной распознаванию образов и автоматического группирования
данных.
Структурный подход к построению модели предметной области
предполагает выделение следующих элементов знаний:
1. Понятия.
2. Взаимосвязи.
3. Метапонятия.
4. Семантические отношения.
Выделяемые понятия предметной области должны образовывать систему,
под которой понимается совокупность понятий, обладающая следующими
свойствами:
уникальностью
(отсутствием
избыточности);
полнотой
(достаточно полным описанием различных процессов, фактов, явлений и т. д.
предметной области); достоверностью (валидностью — соответствием
выделенных единиц смысловой информации их реальным наименованиям) и
непротиворечивостью (отсутствием омонимии).
75
При построении системы понятий с помощью "метода локального
представления" эксперта просят разбить задачу на подзадачи для перечисления
целевых состояний и описания общих категорий цели. Далее для каждого
разбиения (локального представления) эксперт формулирует информационные
факты и дает им четкое наименование (название). Считается, что для
успешного решения задачи построения модели предметной области число
таких информационных фактов в каждом локальном представлении, которыми
человек способен одновременно манипулировать, должно быть примерно равно
семи.
"Метод вычисления коэффициента использования" основан на
следующей гипотезе. Элемент данных (или информационный факт) может
являться понятием, если:
1. Он используется в большом числе подзадач.
2. Используется с большим числом других элементов данных.
3. Редко используется совместно с другими элементами данных по
сравнению с общим числом его использования во всех подзадачах (это и
есть коэффициент использования).
Полученные значения могут служить критерием для классификации всех
элементов данных и, таким образом, для формирования системы понятий.
"Метод формирования перечня понятий" заключается в том, что
экспертам (желательно, чтобы их было больше двух) дается задание составить
список понятий, относящихся к исследуемой предметной области. Понятия,
выделенные всеми экспертами, включаются в систему понятий, остальные
подлежат обсуждению.
"Ролевой метод" состоит в том, что эксперту дается задание обучить
инженера по знаниям решению некоторых задач предметной области. Таким
образом, эксперт играет роль учителя, а инженер по знаниям — роль ученика.
Процесс обучения записывается на магнитофон. Затем третий участник
прослушивает магнитофонную ленту и выписывает на бумаге все понятия,
употребленные учителем или учеником.
При использовании метода "составления списка элементарных действий"
эксперту дается задание составить такой список при решении задачи в
произвольном порядке.
В методе "составление оглавления учебника" эксперту предлагается
представить ситуацию, в которой его попросили написать учебник.
Необходимо составить на бумаге перечень предполагаемых глав,
разделов, параграфов, пунктов и подпунктов книги.
"Текстологический метод" формирования системы понятий заключается в
том, что эксперту дается задание выписать из руководств (книг по
специальности) некоторые элементы, представляющие собой единицы
смысловой информации.
Группа методов установления взаимосвязей предполагает установление
семантической близости между отдельными понятиями. В основе установления
76
взаимосвязей лежит психологический эффект "свободных ассоциаций", а также
фундаментальная категория близости объектов или концептов.
Эффект свободных ассоциаций заключается в следующем. Испытуемого
просят отвечать на заданное слово первым пришедшим на ум словом. Как
правило, реакция большинства испытуемых (если слова не были слишком
необычными) оказываются одинаковой. Количество переходов в цепочке может
служить мерой "смыслового расстояния" между двумя понятиями.
Многочисленные опыты подтверждают гипотезу, что для двух любых слов
(понятий) существует ассоциативная цепочка, состоящая не более чем из семи
слов.
"Метод свободных ассоциаций" основан на психологическом эффекте,
описанном выше. Эксперту предъявляется понятие с просьбой назвать как
можно быстрее первое пришедшее на ум понятие из сформированной ранее
системы понятий. Далее производится анализ полученной информации.
В методе "сортировка карточек" исходным материалом служат
выписанные на карточки понятия. Применяются два варианта метода. В первом
эксперту задаются некоторые глобальные критерии предметной области,
которыми он должен руководствоваться при раскладывании карточек на
группы. Во втором случае, когда сформулировать глобальные критерии
невозможно эксперту дается задание разложить карточки на группы в
соответствии с интуитивным пониманием семантической близости
предъявляемых понятий.
"Метод обнаружения регулярностей" основан на гипотезе о том, что
элементы цепочки понятия, которые человек вспоминает с определенной
регулярностью, имеют тесную ассоциативную взаимосвязь. Для эксперимента
произвольным образом отбирается 20 понятий. Эксперту предъявляется одно из
числа отобранных. Процедура повторяется до 20 раз, причем каждый раз
начальные концепты должны быть разными. Затем инженер по знаниям
анализирует полученные цепочки в целях нахождения постоянно
повторяющихся понятий (регулярностей). Внутри выделенных таким образом
группировок устанавливаются ассоциативные взаимосвязи.
Кроме рассмотренных выше неформальных методов для установления
взаимосвязей между отдельными понятиями применяются также формальные
методы. Сюда в первую очередь относятся методы семантического
дифференциала и репертуарных решеток.
Выделенные понятия предметной области и установленные между ними
взаимосвязи служат основанием для дальнейшего построения системы
метапонятий — осмысленных в контексте изучаемой предметной области
системы группировок понятий. Для определения этих группировок применяют
как неформальные, так и формальные методы.
Интерпретация, как правило, легче дается эксперту, если группировки
получены неформальными методами. В этом случае выделенные классы более
понятны эксперту. Причем в некоторых предметных областях совсем не
77
обязательно устанавливать взаимосвязи между понятиями, так как
метапонятия, образно говоря, "лежат на поверхности".
Последним этапом построения модели предметной области при
концептуальном анализе является установление семантических отношений
между выделенными понятиями и метапонятиями. Установить семантические
отношения — это значит определить специфику взаимосвязи, полученной в
результате применения тех или иных методов. Для этого необходимо каждую
зафиксированную взаимосвязь осмыслить и отнести ее к тому или иному типу
отношений.
Существуют около 200 базовых отношений, например, "часть — целое",
"род — вид", "причина — следствие", пространственные, временные и другие
отношения. Для каждой предметной области помимо общих базовых
отношений могут существовать и уникальные отношения.
"Прямой метод" установления семантических отношений основан на
непосредственном осмыслении каждой взаимосвязи. В том случае, когда
эксперт затрудняется дать интерпретацию выделенной взаимосвязи, ему
предлагается следующая процедура. Формируются тройки: понятие
1 — связь— понятие 2. Рядом с каждой тройкой записывается короткое
предложение или фраза, построенное так, чтобы понятие 1 и понятие 2 входили
бы в это предложение. В качестве связок используются только содержательные
отношения и не применяются неопределенные связки типа "похож на" или
"связан с".
Для "косвенного метода" необязательно иметь взаимосвязи, а достаточно
лишь наличие системы понятий. Формулируется некоторый критерий, для
которого из системы понятий выбирается определенная совокупность
концептов. Эта совокупность предъявляется эксперту с просьбой дать
вербальное описание сформулированного критерия. Концепты предъявляются
эксперту все сразу (желательно на карточках). В случае затруднений эксперта
прибегают к разбиению отобранных концептов на группы с помощью более
мелких критериев. Исходное количество концептов может быть произвольным,
но после разбиения на группы в каждой из таких групп должно быть не более
десяти концептов. После того как составлены описания по всем группам,
эксперту предлагают объединить эти описания в одно.
Следующий шаг в косвенном методе установления семантических
отношений — это анализ текста, составленного экспертом. Концепты заменяют
цифрами (это может быть исходная нумерация), а связки оставляют. Тем самым
строится некоторый граф, вершинами которого служат концепты, а дугами —
связки (например, "ввиду", "приводит к", "выражаясь с одной стороны",
"обусловливая", "сочетаясь", "определяет", "вплоть до" и т. д.) Этот метод
позволяет устанавливать не только базовые отношения, но и отношения,
специфические для конкретной предметной области.
Рассмотренные выше методы формирования системы понятий и
метапонятий, установления взаимосвязей и семантических отношений в разных
78
сочетаниях применяются на этапе концептуализации при построении модели
предметной области.
Этап формализации
Теперь все ключевые понятия и отношения выражаются на некотором
формальном языке, который либо выбирается из числа уже существующих,
либо создается заново. Другими словами, на данном этапе определяются состав
средств и способы представления декларативных и процедурных знаний,
осуществляется это представление и в итоге формируется описание решения
задачи ЭС на предложенном (инженером по знаниям) формальном языке.
Выходом этапа формализации является описание того, как
рассматриваемая задача может быть представлена в выбранном или
разработанном формализме. Сюда относится указание способов представления
знаний (фреймы, сценарии, семантические сети и т. д.) и определение способов
манипулирования этими знаниями (логический вывод, аналитическая модель,
статистическая модель и др.) и интерпретации знаний.
Этап выполнения
Цель этого этапа — создание одного или нескольких прототипов ЭС,
решающих требуемые задачи. Затем на данном этапе по результатам
тестирования и опытной эксплуатации создается конечный продукт, пригодный
для промышленного использования. Разработка прототипа состоит в
программировании его компонентов или выборе их из известных
инструментальных средств и наполнении базы знаний.
Главное в создании прототипа заключается в том, чтобы этот прототип
обеспечил проверку адекватности идей, методов и способов представления
знаний решаемым задачам. Создание первого прототипа должно подтвердить,
что выбранные методы решений и способы представления пригодны для
успешного решения, по крайней мере, ряда задач из актуальной предметной
области, а также продемонстрировать тенденцию к получению
высококачественных и эффективных решений для всех задач предметной
области по мере увеличения объема знаний.
После разработки первого прототипа ЭС–1 круг предлагаемых для
решения задач расширяется, и собираются пожелания и замечания, которые
должны быть учтены в очередной версии системы ЭС–2. Осуществляется
развитие ЭС–1 путем добавления "дружественного" интерфейса, средств для
исследования базы знаний и цепочек выводов, генерируемых системой, а также
средств для сбора замечаний пользователей и средств хранения библиотеки
задач, решенных системой.
Выполнение экспериментов с расширенной версией ЭС–1, анализ
пожеланий и замечаний служат отправной точкой для создания второго
прототипа ЭС–2. Процесс разработки ЭС–2 итеративный. Он может
79
продолжаться от нескольких месяцев до нескольких лет в зависимости от
сложности предметной области, гибкости выбранного представления знаний и
степени соответствия управляющего механизма решаемым задачам (возможно,
потребуется разработка ЭС–3 и т. д.). При разработке ЭС–2, кроме
перечисленных задач, решаются следующие:
 анализ функционирования системы при значительном расширении базы
знаний;
 исследование возможностей системы в решении более широкого круга
задач и принятие мер для обеспечения таких возможностей;
 анализ мнений пользователей о функционировании ЭС;
 разработка системы ввода–вывода, осуществляющей анализ или синтез
предложений ограниченного естественного языка, позволяющей
взаимодействовать с ЭС–2 в форме, близкой к форме стандартных
учебников для данной области.
Если ЭС–2 успешно прошла этап тестирования, то она может
классифицироваться как промышленная экспертная система.
Этап тестирования
В ходе данного этапа производится оценка выбранного способа
представления знаний в ЭС в целом. Для этого инженер по знаниям подбирает
примеры, обеспечивающие проверку всех возможностей разработанной ЭС.
Различают следующие источники неудач в работе системы: тестовые
примеры,
ввод–вывод,
правила
вывода,
управляющие
стратегии.
Показательные тестовые примеры являются наиболее очевидной причиной
неудачной работы ЭС. В худшем случае тестовые примеры могут оказаться
вообще вне предметной области, на которую рассчитана ЭС, однако чаще
множество тестовых примеров оказывается слишком однородным и не
охватывает всю предметную область. Поэтому при подготовке тестовых
примеров следует классифицировать их по подпроблемам предметной области,
выделяя стандартные случаи, определяя границы трудных ситуаций и т.п.
Ввод–вывод характеризуется данными, приобретенными в ходе диалога с
экспертом, и заключениями, предъявленными ЭС в ходе объяснений. Методы
приобретения данных могут не давать требуемых результатов, так как,
например, задавались неправильные вопросы или собрана не вся необходимая
информация. Кроме того, вопросы системы могут быть трудными для
понимания, многозначными и не соответствующими знаниям пользователя.
Ошибки при вводе могут возникать также из–за неудобного для пользователя
входного языка. В ряде приложения для пользователя удобен ввод не только в
печатной, но и в графической или звуковой форме.
Выходные сообщения (заключения) системы могут оказаться непонятны
пользователю (эксперту) по разным причинам. Например, их может быть
слишком много или, наоборот, слишком мало. Также причиной ошибок может
80
являться неудачная организация, упорядоченность заключений или
неподходящий пользователю уровень абстракций с непонятной ему лексикой.
Наиболее распространенный источник ошибок в рассуждениях касается
правил вывода. Важная причина здесь часто кроется в отсутствии учета
взаимозависимости сформированных правил. Другая причина заключается в
ошибочности, противоречивости и неполноте используемых правил. Если
неверна посылка правила, то это может привести к употреблению правила в
неподходящем контексте. Если ошибочно действие правила, то трудно
предсказать конечный результат. Правило может быть ошибочно, если при
корректности его условия и действия нарушено соответствие между ними.
Нередко к ошибкам в работе ЭС приводят применяемые управляющие
стратегии. Изменение стратегии бывает необходимо, например, если ЭС
анализирует сущности в порядке, отличном от "естественного" для эксперта.
Последовательность, в которой данные рассматриваются ЭС, не только влияет
на эффективность работы системы, но и может приводить к изменению
конечного результата. Так, рассмотрение правила А до правила В способно
привести к тому, что правило В всегда будет игнорироваться системой.
Изменение стратегии бывает также необходимо и в случае неэффективной
работы ЭС. Кроме того, недостатки в управляющих стратегиях могут привести
к чрезмерно сложным заключениям и объяснениям ЭС.
Критерии оценки ЭС зависят от точки зрения. Например, при
тестировании ЭС–1 главным в оценке работы системы является полнота и
безошибочность правил вывода. При тестировании промышленной системы
превалирует точка зрения инженера по знаниям, которого в первую очередь
интересует вопрос оптимизации представления и манипулирования знаниями.
И, наконец, при тестировании ЭС после опытной эксплуатации оценка
производится с точки зрения пользователя, заинтересованного в удобстве
работы и получения практической пользы
Этап опытной эксплуатации
На этом этапе проверяется пригодность ЭС для конечного пользователя.
Пригодность ЭС для пользователя определяется в основном удобством работы
с ней и ее полезностью. Под полезностью ЭС понимается ее способность в ходе
диалога определять потребности пользователя, выявлять и устранять причины
неудач в работе, а также удовлетворять указанные потребности пользователя
(решать поставленные задачи). В свою очередь, удобство работы с ЭС
подразумевает естественность взаимодействия с ней (общение в привычном, не
утомляющем пользователя виде), гибкость ЭС (способность системы
настраиваться на различных пользователей, а также учитывать изменения в
квалификации одного и того же пользователя) и устойчивость системы к
ошибкам (способность не выходить из строя при ошибочных действиях
неопытного пользователях).
81
В ходе разработки ЭС почти всегда осуществляется ее модификация.
Выделяют следующие виды модификации системы: переформулирование
понятий и требований, переконструирование представления знаний в системе и
усовершенствование прототипа.
Экспертные системы, параллельные и последовательные решения
Как известно, в большинстве алгоритмов подразумевается, что к началу
работы алгоритма уже известна вся входная информация, которая
перерабатывается параллельно. Однако ее получение зачастую требует
определенных усилий. Да и наши наблюдения за реальными экспертами
подтверждают, что зачастую они задают два–три вопроса, после чего делают
правильные выводы. Представьте себе, если бы врач (эксперт в области
медицины) перед постановкой диагноза "ангина" заставлял бы пациента пройти
полное обследование вплоть до позвоночника.
Соответственно большинство алгоритмов модифицируются, чтобы
обеспечить выполнение следующих условий:
 алгоритмы должны работать в условиях неполной информации
(последовательно);
 последовательность запроса информации должна быть оптимальна по
критериям быстроты получения результата и (или) наименьшей
трудоемкости (болезненности, стоимости и т. д.) получения этой
информации.
Одной из возможных стратегий для оптимизирования запросов является
стратегия получения в первую очередь той информации, которая подтверждает
либо опровергает наиболее вероятный на текущий момент результат. Другими
словами, мы пытаемся подтвердить или опровергнуть наши догадки (обратный
вывод).
Пример ЭС, основанной на правилах логического вывода и действующую
в обратном порядке
Допустим, вы хотите построить ЭС в области медицинской диагностики.
В этом случае вам вряд ли нужно строить систему, использующую обучение на
примерах, потому что имеется большое количество доступной информации,
позволяющей непосредственно решать такие проблемы. К сожалению, эта
информация приведена в неподходящем для обработки на компьютере виде.
Возьмите медицинскую энциклопедию и найдите в ней статью, например,
о гриппе. Вы обнаружите, что в ней приведены все симптомы, причем они
бесспорны. Другими словами, при наличии указанных симптомов всегда можно
поставить точный диагноз.
Но чтобы использовать информацию, представленную в таком виде, вы
должны обследовать пациента, решить, что у него грипп, а потом заглянуть в
энциклопедию, чтобы убедиться, что у него соответствующие симптомы. Что–
82
то здесь не так. Ведь необходимо, чтобы вы могли обследовать пациента,
решить, какие у него симптомы, а потом по этим симптомам определить, чем
он болен. Энциклопедия же, похоже, не позволяет сделать это так, как надо.
Нам нужна не болезнь со множеством симптомов, а система, представляющая
группу симптомов с последующим названием болезни. Именно это мы сейчас и
попробуем сделать.
Идеальной будет такая ситуация, при которой мы сможем в той или иной
области предоставить машине в приемлемом для нее виде множество
определений, которые она сможет использовать примерно так же, как человекэксперт. Именно это и пытаются делать такие программы, как PUFF,
DENDRAL, PROSPECTOR.
С учетом байесовской системы логического вывода примем, что большая
часть информации не является абсолютно точной, а носит вероятностный
характер. Итак, начнем программирование:
№
Симптомы
1
Симптом_1
2
Симптом_2
N
Симптом_N
Полученный формат данных мы будем использовать для хранения
симптомов. При слове "симптомы" создается впечатление, что мы связаны
исключительно с медициной, хотя речь может идти о чем угодно. Суть в том,
что компьютер задает множество вопросов, содержащихся в виде символьных
строк <Симптом_1>, <Симптом_2> и т. д.
Например, Симптом_1 может означать строку "Много ли вы кашляете?",
или, если вы пытаетесь отремонтировать неисправный автомобиль, — строку
"Ослаб ли свет фар?".
Теперь оформим болезни:
№
Болезнь
p
[j, py, pn]
1
Болезнь_1
p1
[j, py, pn]1
2
Болезнь_2
p2
[j, py, pn]2
N
Болезнь_N
pn
[j, py, pn]n
В таком виде мы будем хранить информацию о болезнях. Это не
обязательно должны быть болезни — могут быть любые результаты, и каждый
83
оператор содержит один возможный исход и всю информацию, относящуюся к
нему.
Поле "болезнь" характеризует название возможного исхода, например
"Грипп". Следующее поле — p — это априорная вероятность такого исхода
P(H), т. е. вероятность исхода в случае отсутствия дополнительной
информации. После этого идет ряд повторяющихся полей из трех элементов.
Первый элемент — j — это номер соответствующего симптома (свидетельства,
переменной, вопроса, если вы хотите назвать его по–другому). Следующие два
элемента — P(E : H) и P(E : не H) — соответственно вероятности получения
ответа "Да" на этот вопрос, если возможные исход верен и неверен. Например:
2010
Грипп
0.01
(1, 0.9, 0.01); (2, 1, 0.01); (3, 0, 0.01)
Здесь сказано, существует априорная вероятность P(H)=0.01, что любой
наугад взятый человек болеет гриппом.
Допустим, программа задает вопрос 1 (симптом 1). Тогда мы имеем P(E :
H)=0.9 и P(E : не H)=0.01, а это означает, что если у пациента грипп, то он в
девяти случаях из десяти ответит "да" на этот вопрос, а если у него нет гриппа,
он ответит "да" лишь в одном случае из ста. Очевидно, ответ "да" подтверждает
гипотезы о том, что у него грипп. Ответ "нет" позволяет предположить, что
человек гриппом не болеет.
Так же и во второй группе симптомов (2, 1, 0.01). В этом случае P(E :
H)=0.9, т. е. если у человека грипп, то этот симптом должен присутствовать.
Соответствующий симптом может иметь место и при отсутствии гриппа (P(E :
не H)=0.01), но это маловероятно.
Вопрос 3 исключает грипп при ответе "да", потому что P(E : H)=0. Это
может быть вопрос вроде такого: "наблюдаете ли вы такой симптом на
протяжении большей части жизни?" — или что-нибудь вроде этого.
Нужно подумать, а если вы хотите получить хорошие результаты, то и
провести исследование, чтобы установить обоснованные значения для этих
вероятностей. И если быть честным, то получение такой информации,
вероятно, труднейшая задача, в решении которой компьютер также сможет
существенно помочь Вам. Если вы напишите программу общего назначения, ее
основой будет теорема Байеса, утверждающая:
P(H : E) = P(E : H) * P(H) / (P(E : H) * P(H) +P(E : не H) * P(не H).
Вероятность осуществления некой гипотезы H при наличии
определенных подтверждающих свидетельств Е вычисляется на основе
априорной вероятности этой гипотезы без подтверждающих свидетельств и
вероятности осуществления свидетельств при условиях, что гипотеза верна или
неверна.
Поэтому, возвращаясь к нашим болезням, оказывается:
P(H : E) = py * p / (py * p + pn * (1 – p)) .
В данном случае мы начинаем с того, что Р(Н) = р для всех болезней.
Программа задает соответствующий вопрос и в зависимости от ответа
вычисляет P(H : E). Ответ "да" подтверждает вышеуказанные расчеты, ответ
84
"нет" тоже, но с (1 – py) вместо py и (1 – pn) вместо pn. Сделав так, мы
забываем об этом, за исключением того, что априорная вероятность P(H)
заменяется на P(H : E). Затем продолжается выполнение программы, но с
учетом постоянной коррекции значения P(H) по мере поступления новой
информации.
Описывая алгоритм, мы можем разделить программу на несколько
частей.
Часть 1.
Ввод данных.
Часть 2.
Просмотр данных на предмет нахождения априорной вероятности P(H).
Программа вырабатывает некоторые значения массива правил и размещает их в
массиве RULEVALUE. Это делается для того, чтобы определить, какие
вопросы (симптомы) являются самыми важными, и выяснить, о чем спрашивать
в первую очередь. Если вы вычислите для каждого вопроса RULEVALUE[I] =
RULEVALUE[I] + ABS (P(H : E) – P(H : не E)), то получите значения
возможных изменений вероятностей всех болезней, к которым они относятся.
Часть 3.
Программа находит самый важный вопрос и задает его. Существует ряд
вариантов, что делать с ответом: вы можете просто сказать: "да" или "нет".
Можете попробовать сказать "не знаю", — изменений при этом не произойдет.
Гораздо сложнее использовать шкалу от –5 до +5, чтобы выразить степень
уверенности в ответе.
Часть 4.
Априорные вероятности заменяются новыми значениями при получении
новых подтверждающих свидетельств.
Часть 5.
Подсчитываются новые значения правил. Определяются также
минимальное и максимальное значения для каждой болезни, основанные на
существующих в данный момент априорных вероятностях и предположениях,
что оставшиеся свидетельства будут говорить в пользу гипотезы или
противоречить ей. Важно выяснить: стоит ли данную гипотезу продолжать
рассматривать или нет? Гипотезы, которые не имеют смысла, просто
отбрасываются. Те же из них, чьи минимальные значения выше определенного
уровня, могут считаться возможными исходами. После этого возвращаемся к
части 3.
Составные части системы экспертных консультаций. В любой системе
экспертных консультаций обязательно должны иметься следующие три
компоненты:
1) язык представления знаний, с помощью которого можно интуитивно
представить знания о сложной области;
85
2) стратегия, решения задач, позволяющая выполнять действия с
представленными знаниями столь же компетентно и умело, как это делают
эксперты–люди;
3) интерфейс с пользователем, обеспечивающий естественность и
удобство доступа к знаниям, которыми обладает программа, и способный
объяснить свои ответы, как неопытным пользователям, так и пользователям–
экспертам.
Пролог пригоден для разработки систем экспертных консультаций,
поскольку в нем имеются и язык представления знаний (Фразы Хорна), и
общецелевая стратегия решения задач, основанная на принципе резолюций.
Интерфейс с пользователем. Важной особенностью интерфейсов с
пользователем многих систем экспертных консультаций является их
способность объяснить, как были найдены ответы. Это свойство необходимо
для того, чтобы пользователи программы прониклись к ней доверием. Если
такое объяснение не будет обеспечиваться, то у пользователей не будет
оснований считать ответы экспертной системы достоверными. Ответ можно
пояснить путем отображения цепочки выводов, выполненных программой при
поиске ответа.
Стратегия решения задач. В интерпретаторе Пролога применяется
стратегия решения задач с обратным ходом решения: он начинает свою работу
с цели и продвигается назад до тех пор, пока не встретит факты. В некоторых
других системах решения задач (например, в системе, реализующей язык OPS–
5) принята стратегия с прямым ходом решения. Некоторые задачи могут быть
решены более изящно при помощи стратегии с прямым ходом решения (к
примеру, решение уравнений или грамматический разбор языков, содержащих
леворекурсивные конструкции, скажем, японского языка).
Подробное объяснение стратегии решения задач, принятой в
интерпретаторе языка Пролог, было дано ранее. Процедура "вып",
рассматриваемая далее, в точности моделирует эту стратегию решения задач.
Поэтому можно трактовать процедуру "вып" как реализацию Пролога,
написанную на самом Прологе.
4.2. Запоминание пути вывода
Процедура "вып". Единственным аргументом процедуры "вып"
(сокращение от слова "выполнить") является запрос, который эта процедура
выполняет. Если выполнение запроса окажется успешным, то процедура "вып"
напечатает запрос с конкретизированными переменными, а затем спросит
пользователя, не желает ли он посмотреть путь доказательства или получить
иной ответ. Если ответов на запрос больше не существует, то процедура "вып"
потерпит неудачу.
Использование процедуры "вып". Посмотрите, как процедура "вып"
отвечает на запрос к нижеследующей базе данных "разновидность",
86
содержащей сведения о разновидностях собраний, которые включают в себя
другие вспомогательные собрания:
разновидность (собрание_38, собрание_381).
разновидность (собрание_381, собрание_382).
разновидность (собрание_39, собрание_391).
?– вып (разновидность (собрание_38, X)).
разновидность (собрание_38, собрание_381)
введите символ h для просмотри пути доказательства или символ ; для
получения другого ответа.
Поскольку данный запрос может быть успешно выполнен, процедура
"вып" печатает его, причем переменная Х унифицирована с константой
«собрание_381». Теперь, если пользователь введет символ "h", процедура "вып"
пояснит, как она выполнила запрос:
h
разновидность (собрание_38, собрание_381) содержится в программе.
Объяснение. Объяснение вырабатывается следующим образом. Если
запрос унифицируется с фактом, содержащимся в текущей программе, то на
печать выдаются текст запроса и слова «содержится в программе». Если
запрос унифицируется с правилом, входящим в текущую программу, то
печатаются запрос и вопросительный знак. Далее по этой же схеме печатаются
подцели данного правила. Подцели выделяются при печати с помощью отступа.
Ниже приводится пример сеанса работы с процедурой "вып", который
иллюстрирует выдачу объяснений этой процедурой. Обратите внимание на то,
что форма объяснений отражает форму фраз, которые используются при
выполнении запроса. Транзитивное отношение "имеет_отношение_к"
основывается на приведенной выше базе данных "разновидность". Отношение
"имеет_отношение_к" выражает то обстоятельство, что тема одного собрания
может косвенно затрагивать тему другого, т. е. через тему промежуточного
собрания.
имеет_отношение_к (X,Y) :–
разновидность (X,Y).
имеет_отношение_к (X,Y) :–
разновидность (X,Z),
имеет_отношение_к (Z,Y).
?– вып (имеет_отношение_к (собрание_38, X)).
имеет_отношение_к (собрание_38, собрание_381) % первый ответ
введите символ h для просмотра пути доказательства или символ ; для
получения другого ответа.
87
h
имеет_отношение_к (собрание_38, собрание_381) ?
разновидность (собрание_38, собрание_381) содержится в программе.
имеет_отношение_к (собрание_38, собрание_381)
введите символ h для просмотра пути доказательства или символ ; для
получения другого ответа.
;
имеет_отношение_к (собрание_38, собрание_382) % второй ответ
введите символ h для просмотра пути доказательства или символ ; для
получения другого ответа.
h
имеет_отношение_к (собрание_38, собрание_382) ?
разновидность (собрание_38, собрание_381) содержится в программе.
имеет_отношение_к (собрание_381, собрание_382) ?
разновидность (собрание_381, собрание_382) содержится в программе.
имеет_отношение_к (собрание_38, собрание_382)
введите символ h для просмотра пути доказательства или символ ; для
получения другого ответа.
;
нет
Заметьте, что процедура "вып" повторно печатает запрос после ввода
пользователем символа h.
Как работает процедура "вып". Единственным аргументом процедуры
"вып" является запрос, который она далее передает процедуре "вып()".
Процедура "вып()" возвращает структуру вида
п (Запрос, ПутьДоказательства)
через свой второй аргумент. Здесь «Запрос» – это исходный запрос, а
«ПутьДоказательства» – это структура, описывающая шаги, необходимые для
доказательства запроса. В простейшем случае, когда запрос можно доказать по
единственному факту, переменная «ПутьДоказательства» унифицируется со
словами «есть_в_программе». Если запрос доказывается при помощи правила,
то переменная «ПутьДоказательства» унифицируется с рекурсивной
структурой "п", содержащей все подцели правила.
После конкретизации переменная «ПутьДоказательства» передается
процедуре
"спросить_у_пользователя".
Эта
процедура
спрашивает
пользователя, желает ли он просмотреть путь доказательства. В случае
88
утвердительного ответа вызывается процедура "отобразить_путь", а в
противном случае процедура "спросить_у_пользователя" терпит неудачу и
процедура "вып()" возвращается назад для поиска другого ответа.
Реализация программы "вып"
% выполнить запрос.
вьп(Х) :–
вып() (Х,Р),
спросить_у_пользователя (X, Р).
спросить_у_пользователя (X, Р) :–
write (X), nl,
write (' введите символ h для просмотра пути доказательства '),
write (' или символ ; '),nl,
write (' для получения другого ответа.'),
nl,
get() (A),get0 (_),
% ввод символа + перевод строки
А = 104,
% ascii–код символа 'h'
отобразить_путь ('', Р), % "означает отсутствие отступа
!,
спросить_у_пользователя (X, Р).
% исходный случай: последняя фраза была фактом.
%
+
–
%
Запрос
Путь
вып()(true, есть_в_программе) :– !.
% составной запрос; вернуть Р1, соединенную с Р2 запятой
вып()(А, Б), (Р1, Р2)) :–
!,
вып()(А, Р1),
вып()(Б, Р2).
% простой запрос; вернуть структуру п( )
вып()(А,п (А,Р1)):–
clause (А, Тело),
вып() (Тело,Р1).
% отобразить путь выполнения:
%
+
+
отобразить_путь (Отступ, п (Фраза, есть_в_программе)) :–
write (Отступ), write (Фраза),
write (содержится в программе.'), nl, !.
89
% первая подцель составного запроса
отобразить_путь (Отступ, п (Фраза, (Подцель, Подцели)) ) :–
сцепить (Отступ,' ', НовыйОтступ),
отобразить_путь (НовыйОтступ, Подцель),
!,
отобразить_путь (НовыйОтступ, Подцели).
% остальные подцели составного запроса
отобразить_путь (Отступ, (Подцель, Путь)) :–
отобразить_путь (Отступ, Подцель),
!,
отобразить_путь (Отступ, Путь).
отобразить_путь (Отступ, п (Фраза, Путь)) :–
write (Отступ), write (Фраза),
write (' ? '), nl,
сцепить (Отступ,' ', НовыйОтступ),
!,
отобразить_путь (НовыйОтступ, Путь).
%
+ +
–
сцепить (X, Y,
Z) :– % сцепить два атома
name (X, Хсписок),
name (У, Усписок),
присоединить (Хсписок, Усписок, Zсписок),
name (Z, Zсписок),!.
Доказательство факта. Лучше всего можно будет понять работу
процедуры "вып", если рассмотреть входную и выходную информацию ее
подцелей. Посмотрите, что получится, если на вход процедуры "вып()"
поступит запрос, который является доказуемым по факту:
?– вып() (разновидность (собрание_38, X), ПутьДоказательства).
Процедура "вып()" вызовет подцель "clause", которая унифицирует
переменную Х с константой «собрание_381», а переменную «Тело» – с «true»,
так как «разновидность (собрание_38, собрание_381)» — это факт.
Следующий вызов процедуры "вып()" будет эквивалентен такому
запросу:
?– вып() (true, P1).
Р1 = есть_–в_программе
90
Ответ на этот запрос получен по первому правилу "вып()". Значение
переменной Р1 передается далее и становится частью структуры "п", которая
'''возвращается через предыдущий вызов "вып()":
ПутьДоказательства = п (разновидность (собрание_38, собрание_381),
есть_в_программе)
Доказательство правила. Предположим, что на вход процедуры "вып()"
поступает запрос, который можно доказать только при помощи правила:
?– вып() (имеет_отношение_к (собрание_38, X), Путь).
%(1)
Этот вызов согласуется с третьим правилом процедуры "вып()". Подцель
"clause" этого правила эквивалентна запрос:
?– clause (имеет_отношение_к (собрание_38, X), Тело1).
Тело1 =" разновидность (собрание_38, X).
%(2)
Подцель "вып()" данного правила эквивалентна
?– вып() (разновидность (собрание_38, Х), Р1).
%(3)
P1 =n(разновидность (собрание_38, собрание_381), есть_в_программе)
А этот запрос – точно такой же, как и проанализированный ранее. Теперь
запрос (1) к процедуре "вып()"даст следующий результат:
Путь = п (имеет_отношение_к (собрание_38, собрание_381), п (разновидность
(собрание_38, собрание_381),
есть_в_программе))
Показ цепочки выводов. Требование просмотреть путь доказательства
вызовет серию обращений к процедуре "отобразить, путь", что эквивалентно
следующим запросам:
?– отобразить_путь (' ' ,п (имеет_отношение_к (собрание_38. собрание_381),
п (разновидность (собрание_38, собрание_381), есть_в_программе))).
имеет_отношение_к (собрание_38, собрание_381) ?
?– отобразить_путь (‘
‘, п (разновидность (собрание_38, собрание_381),
есть_в_ программе)).
разновидность (собрание_38, собрание_381) содержится в программе.
Ограничения программы "вып". В приведенной версии программы "вып,"
не моделируется действие предиката "сократить". Если на вход программы
"вып" подать запрос к процедуре, содержащий предикат "сократить", то этот
предикат будет трактоваться как всегда истинная подцель. Предикат
91
"сократить" не остановит процесс поиска с возвратом, выполняемый этой
процедурой.
Контрольные вопросы и упражнения
1. Дайте определение понятию «интенсивное знание».
2. Дайте определение понятию «экстенсивное знание».
3. В чем ключевое отличие экспертной системы от базы данных?
5. ПРИМЕР ЗАДАЧИ НА ПРЕДСТАВЛЕНИЕ ЗНАНИЙ
Проблема выбора конфигурации компьютера. При приобретении ПЭВМ
перед покупателем встает проблема выбора такого компьютера, который
максимально бы удовлетворял его нуждам и при этом был доступен в цене, а
конфигурация не содержала бы излишних элементов, бесполезных для задач
покупателя. Зачастую тот ясно и не осознает настоящего предназначения тех
или иных компонентов и не представляет, каким именно должен быть его
компьютер. Определиться с конфигурацией при покупке ему помогают
работники торгового предприятия – эксперты, хорошо знающие все
особенности предлагаемой продукции, знакомые с задачами, которые
покупатель предполагает решать с помощью компьютера, и умеющие
подобрать для их решения оптимальную конфигурацию ЭВМ.
Предметная область. Требования к ЭВМ могут быть формально
представлены при определении пользователем набора стоящих перед ним
задач, т. е. областей применения компьютера. Таких областей может быть
несколько и конфигурация должна удовлетворять им всем.
Все виды элементов ЭВМ условно разбиты на классы:
o монитор;
o принтер;
o процессор;
o системная плата;
o память;
o мышь;
o клавиатура;
o CD–ROM drive;
o блок бесперебойного питания;
o сетевая карта;
o видеокарта;
o звуковая карта;
o колонки;
o жесткий диск;
o корпус;
92
o другие элементы.
Для каждого класса могут быть выделены свойства, являющиеся самыми
весомыми критериями отбора:
o Монитор: диагональ, разрешение.
o Принтер: разрешение, тип, скорость, формат.
o Корпус: размер, форм-фактор.
o Клавиатура: разъем, форма.
o Мышь: разъем, тип.
o Процессор: производитель, частота, тип, разъем.
o Системная плата: тип процессора, разъем, поддержка AGP, формфактор, чипсет, число гнезд для модулей DIMM, число гнезд для
модулей SIMM, наличие SCSI интерфейса, наличие интерфейса
инфракрасной связи.
o Винчестер: размер, интерфейс, производитель.
o Видеокарта: интерфейс, размер видеопамяти, возможность наращивать
видеопамять.
o CD–ROM drive: скорость, интерфейс.
o Звуковая карта: тип синтеза.
o Колонки: мощность.
Также могут быть выделены свойства, общие для всех классов:
наименование, цена, дороговизна, список предпочтений. Дороговизна – это
качественная оценка численного значения цены. Многие из свойств также
будут иметь качественную оценку, так как именно такими оценками оперирует
человек. Значения таких оценок будут следующими: большой, малый, средний,
высокий, низкий. Качественно оценивать значения свойств при составлении
базы данных будет сам оператор.
Другие, не учтенные здесь свойства могут определяться ценой продукта –
чем цена выше, тем больше продукт подходит для тех областей, где он важен и
менее – для тех, где не важен.
Итак, при подборе конфигурации учитываются следующие критерии:
список предпочтений, свойства элементов каждого класса, значимость класса
для выбранной области, цена элемента. Конфигурация должна удовлетворять
таким требованиям, как соответствие областям применения и предполагаемым
покупателем затратам.
Представления о функционировании системы, сеансе работы. Определяя
конфигурацию ЭВМ, система должна руководствоваться такими данными,
вводимыми пользователем, как требования к ЭВМ и предполагаемые затраты.
Экспертная система будет располагать базой данных, содержащей перечень
различных возможных элементов ЭВМ и их характеристики, влияющие на их
выбор. При работе с системой пользователь сможет формулировать требования
и определять свои предполагаемые затраты. Далее система подберет и
предложит ему наиболее подходящий вариант конфигурации компьютера. В
процессе подбора конфигурации система возможно задаст пользователю
93
вопросы для уточнения его требований и потребностей. В итоге будет получен
список элементов ЭВМ.
94
ЗАКЛЮЧЕНИЕ
Оперативное изменение комплекса программ обычно наталкивается на
естественные ограничения самого процесса программирования. Принцип типа
"Эта программа может все" общеизвестен; он стимулирует хорошее качество
программ, однако другой принцип "Все можно запрограммировать" можно
назвать более важным и действенным, поскольку он утверждает необходимость
алгоритмического знания, навсегда вошедшего в нашу жизнь. Тем не менее
практика все чаще подбрасывает нам примеры существенных недостатков
процедурного
программирования,
которые
стимулировают
сегодня
интеллектуализацию применения компьютеров:
 некоторые знания "плохо формализуются" с помощью алгоритмов,
 не все виды знаний можно представить программой,

некоторые знания или запросы неопределенны частично или
полностью,
 с увеличением размеров программы теряется ее гибкость,
 программы не могут определять или доопределять понятия,
 программы выводят только запланированные результаты или
ошибочные ситуации, а альтернативные решения не предусматриваются,
 для конкретного применения важны объективность (ориентация на
общие знания) и субъективность программ (ориентация на конкретную
организацию).
Решение каждой из этих проблем требует перепрограммирования, что по
стоимости часто равносильно созданию новых программ. Необходим иной
подход к разрешению запросов пользователя с учетом главной проблемы –
использование компьютера силами самого пользователя, не обладающего
знаниями в области программирования, но хорошо ориентирующегося в своих
прикладных областях, и владеющего специфическими профессиональными
знаниями. Перечисленные недостатки формируют требования к новому
подходу, который кроме этого обязан учитывать и возможности, присущие
традиционному процедурному программированию.
Таким образом, данное учебное пособие можно рассматривать как
практическое введение в интеллектуальное программирование, в данном случае
на языке Пролог.
95
БИБЛИОГРАФИЧЕСКИЙ СПИСОК
1. Чернухин, Ю. В. Представление знаний и логическое программирование
в системах искусственного интеллекта / Ю. В. Чернухин, В. Ф. Гузик,
А. И. Костюк; под ред. Ю. В. Чернухин. – Таганрог: ТГРУ, 2001.
2. Чернухин, Ю. В. Искусственный интеллект и нейрокомпьютеры / Ю. В.
Чернухин. – Таганрог: ТРТУ, 1997.
3. Братко, И. Программирование на языке Пролог для искусственного
интеллекта / И. Братко. – М.: Мир, 1990.
4. Красилов, А. А. Экспертные системы / А. А. Красилов – М.: Радио и
связь, 1996.
5. Малпас, Дж. Реляционный язык Пролог и его применение: пер. с англ. /
Дж. Малпа; под ред. В. Н. Соболева. – М.: Наука, 1990.
6. Хансен, Г. Базы данных: разработка и управление / Г. Хансен, Д. Хансен;
пер. с англ. – М.: БИНОМ, 1999.
7. Справочник. Искусственный интеллект: в 3 кн. Кн. 1. Системы общения и
экспертные системы. Кн. 2. Модели и методы. Кн. 3. Программные и
аппаратные средства. – М., Радио и связь, 1990.
8. Сотников, С. Л. Основы проектирования систем с искусственным
интеллектом / С. Л. Сотников. – Днепродзержинск: ДГТУ, 1997.
96
Учебное издание
Зурахов Владимир Сергеевич
ЛОГИЧЕСКОЕ ПРОГРАММИРОВАНИЕ
Учебное пособие
Редактор Н. А. Ерина
Оригинал-макет подготовлен автором
Подписано в печать 30.06. 2014 г. Формат 60х84 1/16.
Электронный адрес: http://publish.sutd.ru
Усл. печ. л. 5,6. Тираж 100 экз. Заказ 421/14.
Отпечатано в типографии ФГБОУ ВПО «СПГУТД»
191028, С.-Петербург, ул. Моховая, 26
Документ
Категория
Без категории
Просмотров
5
Размер файла
945 Кб
Теги
logprogram, 2014
1/--страниц
Пожаловаться на содержимое документа