2. Разработка экспертной системы выбора туристического тура

advertisement
Зарегистрировано «___»_____20___г.
________ __________________________
Подпись
(расшифровка подписи)
ФЕДЕРАЛЬНОЕ ГОСУДАРСТВЕННОЕ АВТОНОМНОЕ ОБРАЗОВАТЕЛЬНОЕ УЧРЕЖДЕНИЕ ВЫСШЕГО ПРОФЕССИОНАЛЬНОГО ОБРАЗОВАНИЯ
БЕЛГОРОДСКИЙ ГОСУДАРСТВЕННЫЙ НАЦИОНАЛЬНЫЙ
ИССЛЕДОВАТЕЛЬСКИЙ УНИВЕРСИТЕТ
(НИУ «БелГУ»)
ФАКУЛЬТЕТ КОМПЬЮТЕРНЫХ НАУК И ТЕЛЕКОММУНИКАЦИЙ
КАФЕДРА МАТЕМАТИЧЕСКОГО ОБЕСПЕЧЕНИЯ И АДМИНИСТРИРОВАНИЯ
ВЫЧИСЛИТЕЛЬНЫХ СИСТЕМ
РАЗРАБОТКА ЭКСПЕРТНОЙ СИСТЕМЫ
ВЫБОРА ТУРИСТИЧЕСКОГО ТУРА
Курсовая работа
студентки дневного отделения 4 курса группы 140901
Батищева Дениса Сергеевича
Научный руководитель:
ассистент Сунцова А.И.
БЕЛГОРОД 2013
Содержание
Введение ....................................................................................................................... 3
1. Экспертные системы. Базы знаний. Prolog........................................................... 5
1.1 Назначение экспертных систем ........................................................................ 5
1.2 Особенности экспертных систем ..................................................................... 6
1.3 Язык логического программирования ............................................................. 8
2. Разработка экспертной системы выбора туристического тура ........................ 11
2.1 Разработка экспертной системы..................................................................... 11
2.2 Разработка интерфейса ЭС на языке Visual C# 2010. .................................. 15
3. Тестирование экспертной системы ..................................................................... 19
Заключение ................................................................................................................ 22
Библиографический список ..................................................................................... 23
Приложение 1 ............................................................................................................ 24
Приложение 2. ........................................................................................................... 29
Введение
Целью данной курсовой работы является разработка экспертной системы
«Выбор туристического тура».
Тема практически актуальна, так как все больше ресурсов переносится в
онлайн, все больши́е базы знаний составляются по разным предметам, и все
больше тенденция к потребительству наблюдается у основной части населения
планеты.
Экспертная система не говорит что лучше, она предоставляет те
варианты, критерии которых устраивают пользователя в большей мере.
Главным достоинством экспертных систем является возможность накопления
знаний и сохранение их длительное время. В отличие от человека к любой
информации экспертные системы подходят объективно, что улучшает качество
проводимой экспертизы.
Цель данной работы – построение экспертной системы выбора
туристического тура, на основе любых данных, и реализация ЭС и оболочки
для нее на языке логического программирования Пролог и любого
высокоуровневого языка для приложения windows.
При построении экспертной системы необходимо решить следующие
задачи:
 Сбор и анализ информации об объекте исследования, а именно о
туристических турах.
 Изучение
методов
построения
базы
знаний
и
выбор
подходящего.
 Изучение механизмов логического вывода.
 Программирование базы знаний и методов логического вывода.
наиболее
4
 Программирование windows приложения, которое реализует функционал
пользовательского интерфейса для разработанной базы знаний.
Экспертная система по выбору туристического тура, может выбрать
оптимальный вариант, основываясь на выборе опций пользователем. Все это
возможно только благодаря наличию базы знаний в экспертной системе.
В первой главе данной курсовой работы рассматриваются экспертные
системы, а именно:
 их назначение и общие принципы построения;
 механизмы действия и принципы функционирования;
 классификация экспертных систем.
Во второй главе курсовой работы рассматриваются среды разработки, в
которых создаются экспертные системы.
В третьей главе ведется непосредственное описание процесса разработки
экспертной
системы, иллюстрированное комментариями и
скриншотам
различных аспектов данной экспертной системы.
Курсовая работа содержит 35 страниц, 6 рисунков, 2 приложения.
5
1. Экспертные системы. Базы знаний. Prolog
Экспертная система — компьютерная программа, способная частично
заменить
специалиста-эксперта
в
разрешении
проблемной
ситуации.
Современные ЭС начали разрабатываться исследователями искусственного
интеллекта в 1970-х годах, а в 1980-х получили коммерческое подкрепление.
Предтечи экспертных систем были предложены в 1832 году С. Н. Корсаковым,
создавшим механические устройства, так называемые «интеллектуальные
машины», позволявшие находить решения по заданным условиям, например,
определять наиболее подходящие лекарства по наблюдаемым у пациента
симптомам заболевания [1].
Таким образом, экспертная система, это программа, которая «эмулирует»
способности эксперта в принятии решений.
В этом разделе будут рассмотрены принципы работы экспертных систем,
их применение на практике, отличия от «обычных» программ.
1.1 Назначение экспертных систем
В информатике экспертные системы рассматриваются совместно с базами
знаний как модели поведения экспертов в определенной области знаний с
использованием процедур логического вывода и принятия решений, а базы
знаний — как совокупность фактов и правил логического вывода в выбранной
предметной области деятельности.
Похожие действия выполняет такой программный инструмент как
Мастер. ПО данного типа применяется как в системных программах, так и в
прикладных для упрощения интерактивного общения с пользователем. Главное
отличие мастеров от ЭС — отсутствие базы знаний — все действия жестко
запрограммированы. Это просто набор форм для заполнения пользователем.
6
Другие
подобные
программы
—
поисковые
или
справочные
(энциклопедические) системы. По запросу пользователя они предоставляют
наиболее подходящие (релевантные) разделы базы статей (представления об
объектах областей знаний, их виртуальную модель).
Программные средства, базирующиеся на технологии экспертных систем,
или инженерии знании получили значительное распространение в мире.
Важность экспертных систем состоит в следующем:

технология экспертных систем существенно расширяет круг
практически значимых задач, решаемых на компьютерах, решение которых
приносит значительный экономический эффект;

технология ЭС является важнейшим средством в решении
глобальных проблем традиционного программирования: длительность и,
следовательно, высокая стоимость разработки сложных приложений;

высокая стоимость сопровождения сложных систем, которая часто
в несколько раз превосходит стоимость их разработки; низкий уровень
повторной используемости программ и т.п.;

объединение
технологии
ЭС
с
технологией
традиционного
программирования добавляет новые качества к программным продуктам за
счет: обеспечения динамичной модификации приложений пользователем, а не
программистом; большей «прозрачности» приложения.
1.2 Особенности экспертных систем
Особенности экспертных систем:
• компетентность – в конкретной предметной области экспертная система
должна достигать того же уровня, что и специалисты-люди; при этом она
должна пользоваться теми же эвристическими приемами, также глубоко и
широко отражать предметную область;
7
• символьные рассуждения – знания, на которых основана экспертная
система,
представляют
в
символьном
виде
понятия
реального
мира,
рассуждения также происходят в виде преобразовании символьных наборов;
• глубина – экспертиза должна решать серьезные, нетривиальные задачи,
отличающиеся сложностью знаний, которые экспертная система использует,
или обилием информации; это не позволяет использовать полный перебор
вариантов как метод решения задачи и заставляет прибегать к эвристическим,
творческим, неформальным методам;
• самосознание – экспертная система должна включать в себя механизм
объяснения того, каким образом она приходит к решению задачи.
Экспертные системы создаются для решения разного рода проблем, но
они имеют схожую структуру (рис. 1.1.) и основные типы их деятельности
можно сгруппировать в категории.
Рис. 1.2.1 Схема обобщенной экспертной системы
Диагностические системы используются для установления связи между
нарушениями деятельности организма и их возможными причинами.
Прогнозирующие системы предсказывают возможные результаты или
события на основе данных о текущем состоянии объекта. Хотя пока еще
отсутствуют ЭС, которые способны за счет своей информации о конъюнктуре
рынка помочь вам увеличить капитал, прогнозирующие системы уже сегодня
могут предсказывать погоду, урожайность и поток пассажиров. Даже на
персональном компьютере, установив простую систему, основанную на
знаниях, вы можете получить местный прогноз погоды.
Планирующие системы предназначены для достижения конкретных
целей при решении задач с большим числом переменных.
8
Интерпретирующие
системы
обладают
способностью
получать
определенные заключения на основе результатов наблюдения.
Системы, основанные на знаниях, могут применяться в качестве
интеллектуальных систем контроля и принимать решения, анализируя данные,
поступающие от нескольких
источников. Такие системы уже работают на
атомных электростанциях, управляют воздушным движением и осуществляют
медицинский контроль. Они могут быть также полезны при регулировании
финансовой деятельности предприятия и оказывать помощь при выработке
решений в критических ситуациях.
В сфере диагностики неисправностей в механических и электрических
устройств используются системы, основанные на знаниях, незаменимы как при
ремонте механических и электрических машин (автомобилей, дизельных
локомотивов и т.д.), так и
при устранении неисправностей и ошибок в
аппаратном и программном обеспечении компьютеров.
Системы, основанные на знаниях, могут входить составной частью в
компьютерные
системы
обучения.
Система
получает
информацию
о
деятельности некоторого объекта (например, студента) и анализирует его
поведение. База знаний изменяется в соответствии с поведением объекта.
Примером этого обучения может служить компьютерная игра, сложность
которой увеличивается по мере возрастания степени квалификации играющего
Большинство ЭС включают знания, по содержанию которых их можно
отнести одновременно к нескольким типам.
1.3. Язык логического программирования
При использовании ЭВМ для решения задач можно выделить два
взаимосвязанных способа представления знания:
1)
процедурное
обработки данных;
представление,
т.е.
определение
алгоритма
9
2)
декларативное представление, т.е. определение отдельных
понятий, их состояния в конкретные моменты времени и связей между ними.
Традиционные алгоритмические языки (Паскаль, Си, Фортран) являются
процедурными, поскольку их цель – описание алгоритма. Но они содежрат и
декларативные компоненты (описание переменных).
В языке Пролог, напротив, основной является декларативная компонента,
так что он предназначен не столько для обработки данных, как для обработки
фактов и декларативных правил. Факты представляют собой логические
формулы. База знаний (БЗ) задаётся совокупностью таких формул. Логические
методы обеспечивают получение новых фактов из фактов, представленных в
БЗ.
Пролог может использоваться при разработке экспертных систем, а также
для следующих задач:
- доказательства теорем и вывода решений в задачах;
- создания пакетов символьной обработки при решении уравнений,
дифференцировании, интегрировании и т.д.;
- разработки упрощенных версий систем ИИ;
- создания естественно-языковых интерфейсов для существующих
программ;
- перевода текстов с одного языка на другой, в том числе – с одного языка
программирования на другой.
Задача пролог – программы заключается в том, чтобы доказать, является
ли заданное целевое утверждение следствием из имеющихся фактов и правил.
Программа на языке пролог включает следующие основные разделы:
описание имён и структур объектов (domains);
описание предикатов – названий отношений, существующих между
объектами (predicates);
раздел целевых утверждений (goal), который может отсутствовать; в этом
случае программа будет запрашивать целевое утверждение при запуске;
10
описание фактов и правил, описывающих отношения (clauses).
Запрос – это последовательность из одного предиката или множества
предикатов, разделяемых запятыми и завершающаяся точкой. С помощью
запросов
можно
установить
истинность
соответствующего
выражения.
Предикат запроса называется целью. Простые запросы, не содержащие
переменных, называют да-нет-вопросами. Они допускают лишь два возможных
ответа: «Yes» или «No». В случае первого ответа говорят, что цель достигнута
[2].
11
2. Разработка экспертной системы выбора туристического
тура
В данном разделе рассматривается процесс разработки экспертной
системы на Prolog и Windows Forms приложения как оболочки.
В качестве реализации языка логического программирования Пролог
выбран SWI-Prolog. Данная реализация – наиболее полная и динамично
развивающаяся.
Имеет
в
наличии
биндинги
для
всех
популярных
высокоуровневых языков программирования, в том числе и для C#.
В качестве языка программирования для реализации windows приложения
выбран C#. Данный язык изучался на младших курсах, поэтому знания по нему
наиболее полные.
2.1 Разработка экспертной системы
Основа экспертной системы – база знаний с фактами и предикаты для
логического вывода решения на основе этих фактов.
Общую структуру базы знания может охарактеризовать дерево знаний.
Дерево состоит из n-листьев. Листья с метками q<n> - вопросы системы, с
метками a<n> - ответы.
База знаний спроектирована таким образом, что каждый тур описывается
общим набором вопросов.
Так как каждый туристический тур описывается отдельным термом с
общими
вопросами,
на
дереве
знаний
тур
представлен
в
последовательности листьев, соединенных связью положительного ответа.
виде
12
В случае, когда ответ не предусмотрен текущим описанием предиката
тура в силу невозможности его дальнейшей унификации база знаний переходит
к следующему предикату тура.
q00
q0
q2
q3
q7
q9
q14
q19
q20
q21
q22
q23
Not(q0)
Not(q1)
Not(q2)
q3
q1
q3
q5
q6
q5
q10
q7
q14
q9
q15
q12
q20
q16
q23
q19
a2
q20
a1
Not(q2)
Not(q3)
q8
q9
q9
q11
q12
q16
q14
q20
q16
q22
a3
q21
a7
a8
Рис. 2.1.1 Дерево знаний
На рисунке 2.1.1 выше представлен фрагмент дерево знаний. Как можно
заметить описаны только 5 туров из 10. При большем количестве из-за
масштабирования рисунка он станет нечитаемым, поэтому только фрагмент.
Для реализация данной базы знания на прологе было введено два
предиката: tour<n> и q<n>. Предикат tour<n> описывает логические связи
между вопросами, тем самым формируя цепочку вывода.
Инициализация экспертной системы выполняется в предикате startQuiz/0.
В нем происходит очистка всех основных термов, а так же вызов первого
вопроса.
Более подробно, описанное выше представлено на листинге с кодом на
языке Пролог.
Листинг 2.1.1 – Пример кода инициализации базы знаний
cleanAndClear :retractall( yes(_) ),
13
retractall( no(_) ),
retractall( resultTour(_) ),
retractall( currentQuestion(_) ),
retractall( askedQuestions(_,_) ).
startQuiz :cleanAndClear,
tour( Tour ),
assert( resultTour(Tour) ).
Чтобы понять логику описания ответов, ниже приведен пример для
одного тура:
Листинг 2.1.2 – Пример кода описания предиката тура
tour1 :q00, q0, q2, q3, q7, q9, q14, q19, q20, q21, q22, q23
.
То есть, каждый тур описывается набором предикатов q/1, в которых
описываются ответы. Таким образом, для ответа на вопрос Пролог помещает
текст унификации предиката q/1 в терм CurrentQuestion, который потом
читается на клиентской стороне.
Далее вся логика ответа пользователя на вопросы экспертной системы
основывается на встроенных в Пролог предикатах thread_send_message и
thread_get_message. Смысл в том, что экспертная система загружает в предикат
currentQuestion один из термов q, и далее с помощью thread_get_message ждет
реакции пользователя. Пользователь же, в Windows приложении, отвечая «да»
или «нет» неявно вызывает предикат thread_send_message, который передает в
терм Response или «y», или «n». Далее на основе полученного значения вопрос
записывается либо в положительные, либо отрицательные.
Реализация описанного выше на языке Пролог:
14
Листинг 2.1.3 – Пример кода, загружающего текущий вопрос, автоматически
отвечающего на уже заданные вопросы.
ask(Question) :retractall(currentQuestion(_)),
assert(currentQuestion(Question)),
thread_get_message(Response),
assert(askedQuestions(Question, Response)),
( Response == y ->
assert(yes(Question))
;
assert(no(Question)),
fail
) .
answer(S) :(yes(S) ->
true ;
(no(S) ->
fail ;
ask(S))).
Как можно заметить, в предикате answer/1 добавлены условия для уже
вопросов, на которые пользователь дал ответ. Это реализуется с помощью
попытки унификации предиката yes/1 или no/1. Таким образом, если
пользователь уже отвечал на вопросы, которые содержатся в следующем
предикате q/1, ему не надо отвечать повторно, Пролог за счет унификации
пометит эти вопросы решенными. В случае, когда ответа на вопрос нет, Пролог
передает терм S в предикат ask/1, в котором уже данные терм помещается как
аргумент предиката currentQuestion и вызывается предикат thread_get_message.
В зависимости от полученного из данного предиката значения терма Response
15
терм текущего вопроса помечается или как положительно отвеченный, либо –
отрицательно.
2.2 Разработка интерфейса ЭС на языке Visual C# 2010
Приложение разрабатывалось с использованием ЯП C#. В качестве
Prolog-библиотеки выступал SWI-Prolog v 6.2.13.
Основная форма приложения содержит главное меню с тремя кнопками,
одну кнопку типа Button и компонент RichTextBox.
Работу с базой знаний приложения начинает сразу после запуска
основной формы. Для этого в обработчик события загрузки формы добавлен
код открытия OpenFileDialog с помощью которого выбирается файл с базой
знаний. Далее этот файл используется, как аргумент для запуска движка Пролог
методом PlEngine.Initialize( string[] params ).
Листинг 2.2.1 – Пример кода инициализации базы знаний на языке C#
String[
]
_params
=
new
String[
]
{
«-q»,
«-f»,
expertSystemDBFile };
if ( !PlEngine.IsInitialized )
PlEngine.Initialize( _params );
Так же на форме расположена одна кнопка, меню и компонент
RichTextBox.
Компонент
RichTextBox
содержит
трассировку
заданных
вопросов и их ответов. С помощью этой трассировки пользователь может
видеть историю заданных вопросов, которая является своего рода логической
цепочкой вывода ответа.
В меню с помощью обработчика события нажатия на кнопку «Load Quiz»
происходит вызов предиката startQuiz/0, который инициализирует необходимые
термы пролога и вызывает первый вопрос.
Ниже представлен участок кода – обработчика события открытия формы.
Листинг 2.2.2 – Пример кода для загрузки базы знаний в win32 приложении
16
this._LogsForm.AddLog( «\nLoading quiz...» );
this.askQuestionButton.Enabled = true;
PlQuery.PlCall( «startQuiz», new PlTermV( 0 ) );
String tourName = String.Empty;
PlQuery query = new PlQuery( «resultTour( TourName )» );
foreach
(
PlQueryVariables
answVar
in
query.SolutionVariables )
tourName = answVar[«TourName»].ToString( );
MessageBox.Show( «Ваш выбор - « + tourName, «Result»,
MessageBoxButtons.OK );
this.askQuestionButton.Enabled = false;
Как можно заметить, сначала происходит вызов предиката startQuiz, и,
так как его арность 0, это надо явно указывать. Далее, в этом же обработчике
идет вызов предиката, который возвращает терм в котором указано найденное
решение. Можно подумать, что это не логично, но так работает библиотека
SwiPlCs. Дело в том, что при вызове предиката startQuiz/0 происходит переход
в
предикат
ask/1,
thread_get_mesage/1
который
ожидает
с
помощью
реакции
встроенного
пользователя,
но
предиката
так
как
thread_get_message не возвращает управление пользователю, это неявно делает
SwiPlCs. Таким образом, становится реальным использование двух запросов в
пределах одного обработчика события. То есть, после вызова startQuiz/1
происходит неявное возвращение управления пользователю и реализуется
логика
вопрос-ответ,
далее,
при
нахождении
решения,
управление
возвращается в обработчик события открытия формы, и становится возможной
выборка терма с найденным решением.
17
Далее, щелкая по кнопке Question, происходит вызов предиката
currentQuestion, который является текущим вопросом для пользователя.
Значение данного терма используется, как сообщение для компонента
MessageBox. MessageBox удобен модальностью, то есть однозначность выбора
либо «Да», либо «Нет».
В зависимости от ответа пользователя вызывается встроенный в пролог
предикат
thread_send_message/2,
с
помощью
которого
осуществляется
определение ответа пользователя.
Ниже
представлен
фрагмент
кода
на
C#
для
определения
пользовательского ответа.
Листинг 2.2.3 – Код реализующий диалог ответов на вопросы в win32
приложении
String question = String.Empty;
PlQuery query = new PlQuery( «currentQuestion( Question
)» );
foreach ( PlQueryVariables answVar in
query.SolutionVariables )
question = answVar[«Question»].ToString( );
DialogResult quesionDialogResult;
quesionDialogResult = MessageBox.Show( ( question + «?»
), «???», MessageBoxButtons.YesNo );
if ( quesionDialogResult == DialogResult.Yes )
PlQuery.PlCall( «thread_send_message(1, y)» );
else
PlQuery.PlCall( «thread_send_message(1, n)» );
При условии достижения любой из целей предиката tour<1> возвращается
управление в метод обработчика события нажатия по кнопке «Start Quiz». В
данном обработчике прочитывается терм resultTour, в котором содержится или
18
достигнутое решение с названием тура, либо сообщение о недостижимости
цели в случае неизвестной комбинации ответов.
Для отображения трассировки заданных вопросов в цикле происходит
вызов предиката askedQuestions, который возвращает 2 переменных: вопрос и
ответ на него.
Реализуется с помощью следующего кода:
Листинг 2.2.1 – Код, выводящий либо полное решение, либо временное –
вопросы заданные до текущего вопроса
PlQuery query = new PlQuery( «askedQuestions( Question,
Answer )» );
foreach
(
PlQueryVariables
answVar
in
query.SolutionVariables )
this.questionsTraceRichTextBox.Text
StringBuilder(
answer:
).AppendFormat(
\»{1}\»\n»,
«Question:
+=
(
\»{0}\»,
answVar[«Question»].ToString(
answVar[«Answer»].ToString( ) ).ToString( ) );
new
),
19
3. Тестирование экспертной системы
После запуска приложения, происходит автоматический вызов диалога
открытия файла, в котором надо выбрать файл с базой знаний. Далее, этот файл
загружается в движок пролог и появляется основная форма.
Рис. 3.1. Вид основной формы приложения после запуска.
Как можно заметить – кнопка для ответа на вопрос не активна, так как
еще не инициализирован опрос и не загружен первый вопрос. После нажатия на
кнопку «Load Quiz» происходят необходимые действия и кнопка «Question»
становится активной. Стоит отметить, что после завершения опроса и
нахождения решения, она опять переключается в неактивное состояния. Это
сделано
для
того,
чтобы
не
генерировать
необъяснимые
Активировать обратно кнопку можно инициализировав опрос заново.
ситуации.
20
После активации кнопки «Question» можно вызвать сообщение с текущим
вопросом и вариантами ответов для него.
Рис 3.2. MessageBox с текущим вопросом и кнопками ответа на него
После ответа на несколько вопросов становится возможным вывод
результирующего ответа и отображение его в новом MessageBox.
Рис. 3.3. MessageBox с возможным решением
Кроме того, в любой момент можно отобразить трассировку заданных
вопрос с ответами на них.
Данное действие реализуется через нажатие кнопки «Trace» в меню
«Show…».
Под трассировкой подразумевается вывод вопросов, приведших к
окончательному решению – аналог вопроса «Почему?», так как данный вопрос
подразумевает
пояснения
последовательности
действий,
выполнения которых произошло то или иное действие.
в
результате
21
Аналог вопроса «Как?» так же реализуется через кнопку «Trace» из меню
«Show…».
Эквивалентность
заключается
в
том,
что
вопрос
«Как?»
подразумевает так же последовательность действий «как так получилось?».
Пример работы кнопки «Trace» представлен на рисунке 3.4. В данном
случае на форме полный вывод, так как экспертная система смогла вывести
решение на основе ответов пользователя.
В случае частичного решения, либо вызова этой кнопки в ходе процесса
вывода решения, на форме будут отображены вопросы, на которые уже ответил
пользователь.
Реализация данного действия описана в главе о разработке приложения.
Рис. 3.4. Пример трассировки заданных вопросов с найденным решением
22
Заключение
При выполнении курсовой работы была достигнута поставленная цель:
создана экспертная система «Выбор туристического тура». При этом мною
были изучены теоретические сведения об экспертных системах и их
применении, закреплены навыки программирования на языке С#, изучены
основы работы с языком логического программирования Пролог.
Известно, что огромное количество людей практически каждый год
уезжают на отдых. Но многие из них еще до конца не определились. Поэтому,
при условии качественного наполнения базы знаний фактами, отражающими
реальность, можно с уверенностью говорить о том, что такие системы могут
пользоваться определенным спросом в современное время.
При выполнении курсовой были решены следующие задачи:
Во-первых,
разработана
база
знаний
на
языке
логического
программирования Пролог с набором необходимых термов и предикатов для
вывода корректного решения;
Во-вторых,
разработана
Windows
оболочка
для
базы
знаний,
реализующая все поставленные задачи
В совокупности – разработана экспертная система, которая на основе
нескольких вопросов выбирает подходящий ответ. Система протестирована и
удовлетворяет
базовым
критериям
реагирования на действия пользователя.
работоспособности
и
адекватности
23
Библиографический список
1. М. В. Бураков – Язык логического программирования Пролог –
Санкт-Петербург, 2003. – 37 с.
2. Стерлинг Л., Шапиро Э. Искусство программирования на языке
Пролог – Москва, 1990. – 325 с.
24
Приложение 1
База знаний. Экспертная система
:- dynamic resultTour/1 .
:- dynamic currentQuestion/1 .
:- dynamic askedQuestions/2 .
:- dynamic yes/1 , no/1 .
cleanAndClear :retractall( yes(_) ),
retractall( no(_) ),
retractall( resultTour(_) ),
retractall( currentQuestion(_) ),
retractall( askedQuestions(_,_) ).
startQuiz :cleanAndClear,
tour( Tour ),
assert( resultTour(Tour) ).
tour('Вам не нужна экспертная система') :- not(q00), ! .
tour('Вы бы определились уже..!') :- notKnown, ! .
25
tour('Болгария,
курортный
поселок
Дюни,
отель
Марина
Бийч') :- tour1, !.
tour('Болгария,
Святой
Влас,
аппартаменты
Дейзи')
:-
tour2, ! .
tour('Египет, Хургада, отель El Tabia') :- tour3, ! .
tour('Египет, Макади Бей, отель Royal Azur') :- tour4, !
.
tour('Мальта,
Буджиба,
отель
The
Bugibba
Hotel')
:-
отель
Hilton
Malta')
:-
tour5, ! .
tour('Мальта,
Сент-Джулианс,
tour6, ! .
tour('Россия, Анапа, лагерь Энергетик') :- tour7, ! .
tour('Россия, Анапа, санаторий Россиянка') :- tour8, ! .
tour('Абхазия,
Гагра,
гостиница
Alex
Beach
Hotel')
:-
tour9, ! .
tour('Абхазия, Золотой берег, Гудаутский район, пансионат
Золотой Берег') :- tour10, ! .
tour( 'Не могу ничего посоветовать :(' ) :- ! .
notKnown :- q00, not(q0), ( not(q1) , not(q2) ).
tour1 :q00, q0, q2, q3, q7, q9, q14, q19, q20, q21, q22, q23
.
tour2 :q00, q0, not(q1), q3, q5, q6, q10, q14, q15, q20,
q23.
tour3 :q00, q0, not(q2), q3, q5, q7, q9, q12, q16, q19, q20,
q22.
tour4 :-
26
q00, q0, (q1 ; q2), q3, q6, q7, q8, q9, q14, q15, q23
.
tour5 :q00, q0, (q1 ; q2), q4, q5, q7, q8, q10, q13, q14,
q16, q21 .
tour6 :q00, q0, (not(q1) ; q2), q3, q7, q8, q9, q13, q15,
q20, q22 .
tour7 :q00, not(q0), (q1 ; not(q2)), not(q3), q8, q9, q12,
q16, q20 .
tour8 :q00, not(q0), (q1 ; not(q2)), not(q3), q9, q11, q12,
q14, q16, q21 .
tour9 :q00, not(q0), not(q1), q4, q5, q6, q7, q10, q20 .
tour10 :q00, not(q0), (not(q1) ; not(q2)), q4, q5, q8, q16,
q18, q20, q21 .
q00 :- answer('Выбираете тур?').
q0 :- answer('Направление: Европа?').
q1 :- answer('Тип: отдых с детьми').
q2 :- answer('Тип: пляжный отдых').
q3 :- answer('Расположения отеля: отель на пляже').
q4 :- answer('В номере: наличие санузела/душа в номере').
q5 :- answer('В номере: наличие телевизора').
q6 :- answer('В номере: минибар').
q7 :- answer('Тип питания: швецкий стол').
q8 :- answer('На территории: наличие бассейна').
27
q9 :- answer('Тип пляжа: песчаный').
q10 :- answer('Тип пляжа:
галечный').
q11 :- answer('Для детей: детский стол').
q12 :- answer('Для детей: детская площадка').
q13 :- answer('Развлечения: пляжное парти').
q14 :- answer('Развлечения: дискотека').
q15 :- answer('Развлечения: мини-гольф').
q16 :- answer('Развлечения: анимационные программы').
q17 :- answer('Красота и здоровье: джакузи').
q18 :- answer('Красота и здоровье: сауна').
q19 :- answer('Красота и здоровье: фитнес').
q20 :- answer('Развлечения: экскурсии').
q21 :- answer('Красота и здоровье: массаж').
q22 :- answer('Развлечения: рядом aквапарк').
q23 :- answer('Красота и здоровье: SPA-центр').
ask(Question) :retractall(currentQuestion(_)),
assert(currentQuestion(Question)),
thread_get_message(Response),
assert(askedQuestions(Question, Response)),
( Response == y ->
assert(yes(Question))
;
assert(no(Question)),
fail
) .
28
answer(S) :(yes(S) ->
true ;
(no(S) ->
fail ;
ask(S))).
29
Приложение 2.
Windows приложение
using System;
using System.IO;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using SbsSW.SwiPlCs;
namespace ExpertSystem {
public partial class MainForm : Form {
private LogsForm _LogsForm;
public MainForm( ) {
InitializeComponent( );
}
// load knowledge base
private
void
MainForm_Load(
EventArgs e ) {
this._LogsForm = new LogsForm( this );
object
sender,
30
OpenFileDialog openFileDialog = new OpenFileDialog( );
String expertSystemDBFile = ««;
if ( openFileDialog.ShowDialog( ) == DialogResult.OK )
expertSystemDBFile = openFileDialog.FileName;
String[
]
_params
=
new
String[
]
{
«-q»,
«-f»,
expertSystemDBFile };
if ( !PlEngine.IsInitialized ) {
PlEngine.Initialize( _params );
this._LogsForm.AddLogsRange(
«PlEngine
new
initialized»,
).AppendFormat(
«Loaded
file:
string[
]
{
new
StringBuilder(
{0}»,
expertSystemDBFile
).ToString( ) } );
}
this.askQuestionButton.Enabled = false;
}
// clean and stop prolog engine
private
void
MainForm_FormClosing(
object
sender, FormClosingEventArgs e ) {
PlEngine.PlCleanup( );
PlEngine.PlHalt( );
}
// load quiz. Fill currentQuesting term. Some
kind of Prolog magic :)
31
private
void
loadQuizToolStripMenuItem_Click(
object sender, EventArgs e ) {
this._LogsForm.AddLog( «\nLoading quiz...» );
this.askQuestionButton.Enabled = true;
PlQuery.PlCall( «startQuiz», new PlTermV( 0 ) );
String tourName = String.Empty;
PlQuery query = new PlQuery( «resultTour( TourName )» );
foreach
(
PlQueryVariables
answVar
in
query.SolutionVariables )
tourName = answVar[«TourName»].ToString( );
MessageBox.Show( «Ваш выбор - « + tourName, «Result»,
MessageBoxButtons.OK );
this.askQuestionButton.Enabled = false;
}
private
void
showTraceToolStripMenuItem_Click(
object sender, EventArgs e ) {
this.questionsTraceRichTextBox.Text = ( «Asked questions
backtrace...\n» );
PlQuery query = new PlQuery( «askedQuestions( Question,
Answer )» );
foreach
(
PlQueryVariables
answVar
in
query.SolutionVariables )
this.questionsTraceRichTextBox.Text
StringBuilder(
).AppendFormat(
+=
«Question:
(
new
\»{0}\»,
32
answer:
\»{1}\»\n»,
answVar[«Question»].ToString(
),
answVar[«Answer»].ToString( ) ).ToString( ) );
query = new PlQuery( «resultTour( TourName )» );
foreach
(
PlQueryVariables
answVar
in
query.SolutionVariables )
this.questionsTraceRichTextBox.Text
StringBuilder(
).AppendFormat(
+=
«\nSuggestion:
(
new
\»{0}\»,
\n», answVar[«TourName»].ToString( ) ).ToString( ) );
}
// raise and show logs form
private
void
showLogsToolStripMenuItem_Click(
object sender, EventArgs e ) {
this._LogsForm.Show( );
this._LogsForm.Select( );
}
private
void
askQuestionButton_Click(
object
sender, EventArgs e ) {
String question = String.Empty;
PlQuery query = new PlQuery( «currentQuestion( Question
)» );
foreach
(
PlQueryVariables
answVar
query.SolutionVariables )
question = answVar[«Question»].ToString( );
DialogResult quesionDialogResult;
in
33
quesionDialogResult = MessageBox.Show( ( question + «?»
), «???», MessageBoxButtons.YesNo );
if ( quesionDialogResult == DialogResult.Yes )
PlQuery.PlCall( «thread_send_message(1, y)» );
else
PlQuery.PlCall( «thread_send_message(1, n)» );
}
private
tourGeneratorToolStripMenuItem_Click(
void
object
EventArgs e ) {
}
}
}
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace ExpertSystem {
public partial class LogsForm : Form {
private MainForm _QwnerForm;
sender,
34
public LogsForm( ) {
InitializeComponent( );
}
public LogsForm( MainForm owner ) {
this._QwnerForm = owner;
InitializeComponent( );
}
private
void
LogsForm_Shown(
object
sender,
EventArgs e ) {
this.Location = new Point( ( this._QwnerForm.Location.X +
this._QwnerForm.Size.Width
+
10
),
this._QwnerForm.Location.Y );
}
private
void
LogsForm_FormClosing(
object
sender, FormClosingEventArgs e ) {
this.Hide( );
e.Cancel = true;
}
public void AddLog( String newLog ) {
String[ ] _currentContent = this.logsRichTextBox.Lines;
List<String> _newContent = new List<String>( );
_newContent.AddRange( _currentContent );
_newContent.Add( newLog );
this.logsRichTextBox.Lines = _newContent.ToArray( );
}
public void AddLogsRange( String[ ] newLogs ) {
35
String[ ] _currentContent = this.logsRichTextBox.Lines;
List<String> _newContent = new List<String>( );
_newContent.AddRange( _currentContent );
_newContent.AddRange( newLogs );
this.logsRichTextBox.Lines = _newContent.ToArray( );
}
}
}
Download