ТАБЛИЦЫ ПРИНЯТИЯ РЕШЕНИЙ В СУБД С ТАБЛИЧНОЙ МОДЕЛЬЮ ДАННЫХ

Создать базу данных для инструментального средства, предназначенного для работы с таблицами принятия решений, встроенными в СУБД Oracle, создать пакет процедур и функций, реализующий процессы, обеспечивающие создание, редактирование и работу с таблицами принятия решений, доработать интерфейсы, разработанные в курсовой работе Дербеневой Е. «Адаптивный интерфейс для работы с таблицами принятия решений», выполнить экспериментальную проверку инструментального средства.

2015-07-13

1.22 MB

18 чел.


Поделитесь работой в социальных сетях

Если эта работа Вам не подошла внизу страницы есть список похожих работ. Так же Вы можете воспользоваться кнопкой поиск


ММИНИСТЕРСТВО ОБРАЗОВАНИЯ И НАУКИ РОССИЙСКОЙ ФЕДЕРАЦИИ

Федеральное государственное бюджетное образовательное учреждение

высшего профессионального образования

«КУБАНСКИЙ ГОСУДАРСТВЕННЫЙ УНИВЕРСИТЕТ»

(ФГБОУ ВПО «КубГУ»)

Кафедра математического моделирования

ДОПУСТИТЬ К ЗАЩИТЕ В ГАК

Заведующий кафедрой

д-р физ.-мат. наук, академик РАН

___________ Бабешко В.А.

(подпись) (инициалы, фамилия)

2014 г.

ВЫПУСКНАЯ КВАЛИФИКАЦИОННАЯ (ДИПЛОМНАЯ)

РАБОТА

«ТАБЛИЦЫ ПРИНЯТИЯ РЕШЕНИЙ В СУБД С ТАБЛИЧНОЙ МОДЕЛЬЮ ДАННЫХ»

Работу выполнил ________________________________________ Зубко М.Д.

(подпись, дата)  (инициалы, фамилия)

Факультет компьютерных технологий и прикладной математики

Специальность прикладная информатика и математика

Научный руководитель

канд. тех. наук,

доцент ______________________________________________ Бессарабов Н.В.

(подпись, дата)   (инициалы, фамилия)

Нормоконтролер

канд. физ.-мат. наук,

доцент _______________________________________________ Капустин М.С.

(подпись, дата)   (инициалы, фамилия)

Краснодар 2014

РЕФЕРАТ

Дипломная работа 64 с.,  31 рис.,  4 таблицы,  11 источников,  3 приложения.

ИСКУССТВЕННЫЙ ИНТЕЛЛЕКТ, ЭКСПЕРТНЫЕ СИСТЕМЫ, ТАБЛИЦЫ ПРИНЯТИЯ РЕШЕНИЙ, АДАПТИВНЫЙ ИНТЕРФЕЙС, СУБД ORACLE.

Объектом исследования является встроенное в базу данных интеллектуальное расширение СУБД, использующее таблицы принятия решений.

Цели работы: создать систему ТПР, встроенную в СУБД Oracle. Провести экспериментальные исследования быстродействия.

Более детально:

  •  создать базу данных для инструментального средства, предназначенного для работы с таблицами принятия решений, встроенными в СУБД Oracle,
  •  создать пакет процедур и функций, реализующий процессы, обеспечивающие создание, редактирование и работу с таблицами принятия решений,
  •  доработать интерфейсы, разработанные в курсовой работе Дербеневой Е. «Адаптивный интерфейс для работы с таблицами принятия решений», выполнить экспериментальную проверку инструментального средства.

Исследования проводились с помощью СУБД Oracle.

Адаптивный WEB-интерфейс пользователя был реализован с использованием технологий HTML5, CSS3, JavaScript, JSON, PHP.


СОДЕРЖАНИЕ

[1] ВВЕДЕНИЕ

[2] 1 Таблицы принятия решений

[2.1] 1.1 Продукции общего вида. Продукции по Поспелову

[2.2] 1.2 Переходы внутри таблиц. Работа с исключениями

[2.3] 1.3 Прямой и обратный логический выводы.

[2.4] 1.4 Возможность реализации таблиц принятия решений в СУБД

[2.5] 1.5 Универсальная модель данных

[2.6] 1.6 Динамические SQL-запросы и их использование

[2.7] 1.7 Нечёткая логика в таблицах принятия решений

[3] 2 Реализация ТПР, встроенных в БД табличного типа.

[3.1] 2.1 Схемы базы данных

[3.2] 2.2 Пакет pkg_ get_answer. Использование процедур и функций пакета.

[3.3] 2.3 Контроль корректности данных

[3.4] 2.4 Адаптивный интерфейс пользователя

[4] 3 Экспериментальные исследования

[5] ЗАКЛЮЧЕНИЕ

[6] СПИСОК ИСПОЛЬЗОВАННЫХ ИСТОЧНИКОВ

[7] ПРИЛОЖЕНИЕ А

[8] ПРИЛОЖЕНИЕ Б

[9] ПРИЛОЖЕНИЕ В

 

ВВЕДЕНИЕ

Искусственный интеллект – это один из разделов информатики, в котором рассматриваются задачи аппаратного и программного моделирования тех видов человеческой деятельности, которые считаются интеллектуальными [1].

Экспертные системы являются одним из основных направлений искусственного интеллекта. Как правило, экспертные системы создаются для решения практических задач в некоторых узкоспециализированных областях, где большую роль играют знания и опыт специалистов. Фундаментом экспертной системы любого типа является база знаний, которая составляется на основе знаний специалистов [2].

Второе направление – интеллектуальное управление – методы управления, которые используют различные подходы искусственного интеллекта, такие как искусственные нейронные сети, нечеткая логика, машинное обучение, эволюционные вычисления и генетические алгоритмы [3].

Одно из важнейших отличий интеллектуального управления от экспертной системы в том, что входные данные могут поступать не от человека, а от программных модулей и, поэтому, нуждаются в более тщательных проверках. Возможно прерывание процесса с целью получения решения пользователя. В этом случае, необходимо предоставить ему корректные данные и, насколько возможно, проконтролировать последовательность действий по принятию решения. Тем не менее, основная нагрузка по контролю корректности данных всё так же остаётся на плечах пользователей и экспертов, предоставляющих данные системе.

Таблицы принятия решений (ТПР) – способ компактного представления модели со сложной логикой. ТПР возникли в деловой практике еще в 60-ых годах прошлого века, зарекомендовав себя как удобное средство для быстрого, простого описания сложных процессов, структур и задач.

Аналогично условным операторам в языках программирования, они устанавливают связь между условиями и действиями. Но, в отличие от традиционных языков программирования, таблицы решений в простой форме могут представлять связь между множеством независимых условий и действий.

Высокая эффективность работы с таблицами решений позволяет строить сложные системы искусственного интеллекта. Их преимущества по сравнению с обычными экспертными системами – простота эксплуатации, встраивание в базу данных и, вытекающая из этого обстоятельства, возможность использования индексов базы для ускорения доступа к большому объёму фактов, представленных таблицами базы данных.

Также, таблицы принятия решений могут представляться деревьями принятия решений, которые в настоящее время широко  используются в области статистики и анализа данных: на ребрах дерева записываются атрибуты, от которых зависит целевая функция, в «листьях» – значения целевой функции, а в остальных узлах – атрибуты, по которым различаются случаи.

В представленной работе используются таблицы принятия решений, встроенные в СУБД Oracle, которые не требуют инсталяции Oracle Fusion Middleware и потому могут работать в любой комплектации СУБД, в частности в бесплатной для коммерческого использования версии Oracle XE.

1 Таблицы принятия решений

1.1 Продукции общего вида. Продукции по Поспелову

В общем виде под продукцией понимают выражение вида:

AB.

Импликация, чаще всего, может истолковываться в обычном логическом смысле, как знак логического следования B из А. Но классическая продукционная система Поста с продукциями общего вида слишком ограниченна. Имеется гораздо более широкое определение.

По Поспелову Д.А. [10] продукционная модель знаний основывается на правилах, имеющих в общем случае вид:

И; О; У; А К; П

где  И – идентификатор продукции;

О – область применения;

У – условие применения;

А – антецедент;

К – консеквент;

П – последействие.

Более точно, ядро продукции АК для предлагаемого проекта следовало бы записать в виде:

АХ КУ.

где x,y Î{БД, РС, БЗ} и через БД обозначен внешний мир, которым в нашем случае является база данных, РС это рассуждающая система, БЗ – база знаний.

Имеется в виду, что информация может поступать из внешнего мира (АБД), из базы знаний (АБЗ) и из самой рассуждающей системы (АРС), а следствие представляет изменения в базе данных (КБД), в базе знаний (КБЗ) или в рассуждающей системе (КРС).

Поясним на примере, как ядро продукции можно реализовать с помощью SQL-запроса. Любую таблицу можно воспринимать как набор фактов описываемых предикатом, полученным взаимно однозначным отображением схемы таблицы в предикат.

В качестве примера возьмём таблицы employees, departmets и locations из многим известной учебной схемы HR в СУБД Oracle. Используем продукцию, определяющую отношение «Работает в городе», то есть «город, в котором находится отдел, в котором работает сотрудник»:

Работает_в_отделе(employee, department) Ù

Отдел_находится_в_городе(department, city) Þ

Сотрудник_работет_в_городе(employee,city)

В языке SQL этой продукции соответствует запрос:

SELECT e.employee_id, l.city

FROM employees e, departments d, locations l

WHERE e.department_id = d.department_id

AND d.location_id = l.location_id

Заметим, что подобная реализация через запросы с соединениями таблиц для практики из-за плохих планов исполнения, приемлема только в том случае, когда в ядре продукции используются предикаты, представленные таблицами базы данных.

В общем случае таблица принятия решений, предназначенная для восприятия человеком, разделяется на четыре области (таблица 1).

Условия

Комбинации выполнения условий

Действия

Выполняемые действия

Таблица 1 – Таблица принятия решений

Каждое правило таблица принятия решений состоит из посылки (условия) и заключения (действия). В древовидном представлении, предпосылки и заключении являются узлами, а ветви дерева являются связями между посылками и заключениями.

Пример таблицы решений, для ситуации «Вода в гостинной» приведён в таблице 2.

В ванной сухо

Нет

Да

Да

Да

На кухне сухо

Нет

Да

Да

Потолок в гостиной сухой

Да

Нет

Окно в гостиной закрыто

_

Да

Проверить сантехнику в ванной

Х

Проверить сантехнику на кухне

Х

Идти к соседям сверху

Х

Закрыть окно

Х

Таблица  – Пример таблицы принятия решений

Четыре верхних строки относятся к условиям, остальные четыре – к действиям. Такая структура таблиц удобна для восприятия человеком, поэтому таблицы принятия решений просты для изучения и понимания специалистами различных профессий, довольно легко модифицируемы и имеют более универсальную, в сравнении с блок-схемами, форму.

1.2 Переходы внутри таблиц. Работа с исключениями

В некоторых случаях разделение на условие и действие может оказаться довольно затруднительным, так как некоторые действия могут быть связаны с условием, подразумевая, что они должны быть выполнены перед проверкой условия. В то время как другие могут быть выполнены уже после проверки одного или нескольких условий. Кроме того, комбинации  условий или действий сами по себе могут ссылаться на другие таблицы решений. Например, действие может включать в себя вызов процедуры для выполнения некоторой задачи, обращение к базе, для получения каких-либо данных или для выполнения той же задачи может быть определено условие в другой таблице решения.

Таблицу решения, вызванную  другой таблицей решения, называют подтаблицей-действием или подтаблицей-условием. Эти подтаблицы играют важную роль в структурировании решения и позволяют производить более тщательный и детальный анализ.

Как частный случай перехода от одной таблицы к другой можно рассматривать переходы внутри таблицы, что позволяет работать с исключениями из правил. Например, представим, что таблица принятия решений содержит 7 условий, первые 2 из которых являются исключением из правил, и, если  истинно хотя бы одно из них, проверка остальных 5 условий не имеет смысла. В том случае, если мы хотим обойти рассмотрение этих исключений, можно осуществить переход не к началу таблицы, а к какой-либо её части. А затем, при необходимости, вернуться к началу для проверки истинности условий-исключений (рисунок 1).

Рисунок 1 – схема работы с исключениями

1.3 Прямой и обратный логический выводы.

Механизм логического вывода выполняет функции поиска в базе правил, последовательного выполнения операций над знаниями и получения заключений. Существует два способа проведения таких заключений: прямой и обратный выводы.

Формирование рассуждений в стиле обратного логического вывода может осуществляться следующим образом. Работа по поиску причин появления воды на полу в гостиной начинается с выдвижения гипотезы.  Например, в рассмотренном выше примере это «утечка в кухне».  После этого цепочка рассуждений в сети логического вывода формируется в обратном направлении. Для подтверждения этой гипотезы необходимо, чтобы утверждения «неисправность в кухне», «вода не капает с потолка» и «вода не поступает снаружи» были истинными [7].

В обратном механизме логического вывода работа начинается от поставленной цели. Если цель A согласуется с консеквентом (заключением) продукции, то антецедент (посылка) принимается за подцель и делается попытка подтверждения истинности этого факта. Процесс повторяется до тех пор, пока не будут просмотрены все правила, имеющие в качестве заключения требуемый факт.

Прямой логический вывод начинается не с гипотез, а с некоторых подтвержденных фактов. Обнаружив, что в гостиной вода, а в ванной сухо, можно сделать вывод, что неисправность в кухне. Кроме того, заметив, что окно кухни закрыто и потолок сухой можно сделать заключение, что вода не поступает извне. Это ведет к окончательному выводу, что утечка в кухне.

На практике, для решения довольно большого класса задач естественным является прямой логический вывод. Прямой логический вывод начинается не с гипотез, а с некоторых подтвержденных фактов [2]. Обнаружив, что в гостиной вода, а в ванной сухо, можно сделать вывод, что неисправность в кухне; кроме того, заметив, что окно кухни закрыто, можно сделать заключение, что вода не поступает снаружи; это ведет к окончательному выводу, что утечка в кухне.

В представленной работе использован прямой вывод.

1.4 Возможность реализации таблиц принятия решений в СУБД

Для хранения таблицы решений в базе данных реляционного типа (см. табл. 3), транспонируем представляющую матрицу:

В ванной сухо

В кухне сухо

Потолок в гостиной сухой

Окно в гостиной закрыто

Проверить сантехнику в ванной

Проверить сантехнику в кухне

Идти к соседям сверху

Закрыть окно

нет

Х

да

нет

Х

да

да

нет

Х

да

да

да

нет

Х

Таблица 3 – реляционное представление таблицы принятия решений для ситуации «вода на полу».

Каждой строке этой таблицы соответствует продукция. Например, для первой строки:

В ванной сухо (Да) Ù В кухне сухо (нет) Утечка в кухне

Преобразование транспонированием известно давно. Оно же было использовано в предыдущих разработках  [9].

Ситуации, в которых консеквент относится к одной или нескольким столбцам, не повторяющимся в разных продукциях, крайне неудобны. Поэтому используется таблица вида:

В ванной сухо

В кухне сухо

Потолок в гостиной сухой

Окно в гостиной закрыто

Действие

Последействие

Таблица 4 – реляционное представление таблицы принятия решений.

Например, при работе с правилами, имеющими исключения, действий при одних и тех же условиях может быть больше одного. Поэтому, в реализованном варианте для каждого действия предусмотрена своя строка (т. е. продукция). Возможен вариант продкуций со списком действий в столбце «Действие».

В столбце «Последействия» записываются возможные переходы к другим строкам таблицы (это позволяет работать с исключениями из правил) или к другим таблицам.

Поскольку в данной работе используется прямой логический вывод, то для выбора антецедента в экспертной системе используется ответ пользователя на поставленные вопросы, консеквентом – соответствующее действие.

Прямой вывод в ТПР экспертной системы легко реализуется простым запросом к единственной таблице решений, когда выбирается одна или несколько продукций. Множественный выбор должен появляться только в ТПР с нечёткостями.

1.5 Универсальная модель данных

Как упоминалось выше, возможность использования запросов SQL с соединениями в качестве эквивалентов простых продукций вида A®K известна. В предлагаемой дипломной работе применяется более эффективное решение, в котором одной продукции соответствует единственный простой запрос к одной таблице. Этот подход распространён на таблицы принятия решений (с ограниченным и расширенными вводами), основанными на продукциях общего вида (с выбором области и подобласти, условий применения и заданием последействия). Для хранения этих таблиц и работы с любыми таблицами решения была использована универсальная модель данных (УМД).

УМД состоит из фиксированного набора таблиц. Она может хранить в себе и данные, и метаданные нескольких виртуальных схем базы. В простейшем варианте УМД представляет собой набор из четырех таблиц изображённый на рисунке 2.

Рисунок 2 – схема УМД

Этот набор таблиц остаётся неизменным. Для добавления имени таблицы в виртуальную схему необходимо добавить одну строку в таблицу «Таблица», а для добавления столбца – добавить одну строку в таблицу «Столбец». Количество строк в таблице «Данные», определяющих одну строку таблицы, равно числу столбцов у этой таблицы. Заметим, что тип столбца может быть описан в колонке «Описание» таблицы «Столбец», но может быть добавлен в дополнительном столбце [6].

Универсальность расширения обеспечивается, прежде всего, хранением множества систем таблиц принятия решений, или продукций в универсальной модели данных. При добавлении любого количества интеллектуальных подсистем структура хранения не меняется. При добавлении новых таблиц принятии решений, условия и действия записываются в таблицу metadata, а содержимое таблиц – в decision. Таким образом, одной продукции соответствует единственный простой запрос к одной таблице.

Особенности УМД – низкая скорость. Но в наших задачах для экспертных систем малые объёмы данных.

Высокая эффективность работы с таблицами решений позволяет строить сложные системы искусственного интеллекта. Их преимущества по сравнению с обычными экспертными системами – простота эксплуатации,  легкость встраивания в базу данных и вытекающая из этого обстоятельства возможность использования индексов базы для ускорения доступа к большому объёму фактов, представленных таблицами базы данных.

1.6 Динамические SQL-запросы и их использование

Хранение таблиц решений в универсальной модели данных позволяет осуществлять работу с таблицами при помощи однотипных запросов, состоящих из трёх базовых фраз языка SQL: SELECT, FROM, WHERE в стандарте SQL-2, что обеспечивает встраиваемость в различные СУБД с табличной моделью данных.

Универсальность построения запросов обеспечивается использованием технологии динамических SQL-запросов, что позволяет избегать соединения нескольких таблиц, для получения каких-либо вспомогательных данных и обеспечивает работу с любым количеством условий.

Например, для поиска нужных продукций, заполнения таблицы с историей работы пользователя, может потребоваться получить дополнительную информацию, такую как ответы пользователя, информация о предыдущем шаге работе и др. Запросы с соединением таблиц, внешних для ТПР может иметь невыгодный план запроса. Намного выгодней выполнить несколько простых запросов к одиночным таблицам с временным сохранением результатов и последующей генерацией динамического запроса, на основе этих данных.

Приведём пример сгенерированного запроса, для поиска продукции, соответствующей комбинации ответов пользователя, где ответы заранее извлечены в одномерный массив:

SELECT actions, aftereffect FROM decision

WHERE sysname = 'Medicine' AND Domain = 'Diagnostics'

AND Subdomain ='Breathing System' AND table_id = 1

AND  ( ( ('yes'='yes') OR 'yes'='_') AND(   ('no'='no') OR 'no'='_')

AND(   ('yes'='yes') OR 'yes'='_') );

Здесь подчёркнутые «yes» и «no» – элементы массива, содержащего ответы пользователя на поставленные условия, хранящиеся в отдельной таблице базы и извлечённые заранее.

1.7 Нечёткая логика в таблицах принятия решений

Классическая логика, по определению, не может оперировать с нечетко очерченными понятиями, поскольку все высказывания в формальных логических системах могут иметь только два взаимоисключающих состояния: «истина» со значением истинности «1» и «ложь» со значением истинности «0».

Одной из попыток уйти от двузначной бинарной логики для описания неопределенности было введение Лукашевичем трехзначной логики с третьим состоянием «возможно» со значением истинности «0,5». Введя в рассмотрение нечеткие множества, Заде предложил обобщить классическую бинарную логику на основе рассмотрения бесконечного множества значений истинности. В предложенном Заде варианте нечеткой логики множество значений истинности высказываний обобщается до интервала [0;1] , т.е. включает как частные случаи классическую бинарную логику и трехзначную логику Лукашевича. Такой подход позволяет рассматривать высказывания с различными значениями истинности и выполнять рассуждения с неопределенностью.

Нечеткое высказывание – это законченная мысль, об истинности или ложности которой можно судить только с некоторой степенью уверенности [0;1]: «возможно истинно», «возможно ложно» и т.п. Чем выше уверенность в истинности высказывания, тем ближе значение степени истинности к 1. В предельных случаях 0, если мы абсолютно уверены в ложности высказывания, и 1, если мы абсолютно уверены в истинности высказывания, что соответствует классической бинарной логике. В нечеткой логике нечеткие высказывания обозначаются так же, как и нечеткие множества: A, B, C … . Введем нечеткое отображение T: Ω→[0 ; 1] , которое действует на множестве нечетких высказываний Ω=A, B, C… . В этом случае значение истинности высказывания AΩ определяется как TA[0;1] и является количественной оценкой нечеткости, неопределенности, содержащейся в высказывании A .

Логическое отрицание нечеткого высказывания A обозначается ¬A – это унарная (т.е. производимая над одним аргументом) логическая операция, результат которой является нечетким высказыванием «не A », «неверно, что A », значение истинности которого:

T ¬ A = 1 − T A .

Логическая конъюнкция нечетких высказываний A и B обозначается A∩B– это бинарная (т.е. производимая над двумя аргументами) логическая операция, результат которой является нечетким высказыванием «A и B», значение истинности которого:

T A ∩ B = min (T A ; T B) .

Помимо приведенного выше исторически принятого основного определения логической конъюнкции (нечеткого «И»), введенного Заде, могут использоваться альтернативные формулы, например:

T A ∩ B = max (T A + T B − 1 ; 0) – в базисе Лукашевича-Гилеса;

Логическая дизъюнкция нечетких высказываний A и B обозначается AB – это бинарная логическая операция, результат которой является нечетким высказыванием «A или B», значение истинности которого:

T A B = max (TA ; TB).

Могут использоваться альтернативные формулы, например:

T A B = min ( T A + T B ; 1) – в базисе Лукашевича-Гилеса;

Нечеткая импликация нечетких высказываний A и B обозначается A B – это бинарная логическая операция, результат которой является нечетким высказыванием «из A следует B », «если A , то B », значение истинности которого:

T A B = max( (min T A ; T B) ; 1 − T A) .

Помимо приведенного выше исторически принятого основного определения нечеткой импликации, введенного Заде, могут использоваться следующие альтернативные определения нечеткой импликации, предложенные различными исследователями в области теории нечетких множеств:

T A B = max (1 − T A ; T B) – Гедель;

T A B = min (T A ; T B) – Мамдани;

T A B = min (1 ; 1 − T A + T B) – Лукашевич;

T A B = min (T A + T B ; 1) – Лукашевич-Гилес.

Общее число введенных определений нечеткой импликации не ограничивается приведенными выше. Большое количество работ по изучению различных вариантов нечеткой импликации обусловлено тем, что понятие нечеткой импликации является ключевым при нечетких выводах и принятии решений в нечетких условиях. Наибольшее применение при решении прикладных задач нечеткого управления находит нечеткая импликация Заде.

Так же, как в классической бинарной логике, в нечеткой логике с помощью рассмотренных выше логических связок можно формировать достаточно сложные логические высказывания [9].

В представленной работе нечёткие логики используются для нахождения значимости полученного решения и определения приоритета в случае нескольких решений: пусть, необходимо работать с предикатами, атрибуты которых имеют разные значимости. На каждый основной атрибут вводится по одному дополнительному атрибуту, хранящему его вес. Взвешенная сумма произведений весов на признаки наличия атрибута (0 или 1), даёт значимость продукции, позволяющую выбирать наиболее существенные из выделенных, обычно, нескольких продукций и «отсекать» продукции, значимость которых ниже какого-либо установленного порога.  

Например, пусть исходная комбинация условий имеет вид:

условие_1&( условие_2|| ^условие_3),

где значимость первого условия равна 0.2, второго – 0.7, третьего – 0.6. С учётом весов комбинация примет вид:

0.2&(0.7||^0.6)

При условии, что & есть min(A;B), || – max(A;B), а ^ есть (1–A), получим значение продукции равное 0.2.

Для более точного анализа можно применить расширенный ввод, использование которого, позволит пользователю отвечать на поставленные условия не строго «да»/«нет», но выставлять «показатель выраженности» условия, значения которого также могут находиться в интервале [0;1].

Введём для предыдущего примера дополнительные показатели для 3х условий: 0.7, 0.8 и 0.2 соответственно. Тогда получим:

(0.2*0.7) & ( (0.7*0.8) || (0.6*0.2) ),

где значение продукции будет равно 0.14.


2 Реализация ТПР, встроенных в БД табличного типа.

Общая схема приложения для СУБД Oracle приведена на рисунке 3.

Рисунок 3 – схема приложения для Oracle

2.1 Схемы базы данных 

Для хранения таблиц решения в УМД используются 2 таблицы: decision и metadata. То есть, при добавлении новых таблиц принятия решений не требуется создание новых таблиц для их хранения.

Таблицы data_users и data_clients содержат данные о пользователях и «привязанных» к ним клиентах и служат для поддержки работы интерфейса.

Схема модели данных в Oracle приведена на рисунке 4. Условные обозначения на рисунке: P – превичный ключ, F – внешний ключ.

Рисунок 4 – схема базы данных в Oracle

Таблица data (рисунок 5)  – хранит ответы клиента на условия, пройденных таблиц решения. Также содержит имя системы, область, подобласть, в которых работает клиент, его идентификационный номер. Данные в таблицу заносятся в процессе работы клиента с системой: на соответствующей странице интерфейса клиент отвечает на поставленные вопросы (условия в соответствующей таблице принятия решений), после чего ответ автоматически заносится в таблицу и обрабатывается системой для получения «ответа» (действия) и возможного перехода на следующую таблицу.  

Рисунок 5 – таблица data

Здесь: sysname – название системы, domain – название области, subdomain – название подобласти, table_id – номер таблицы принятия решений, tablename – название этой таблицы, client_id – номер клиента, condition_id – номер условия, condition_name – само условие, answer – ответ клиента на заданное условие, sid – суррогатный ключ. В случае ограниченного ввода ответы клиента имеют вид «yes», «no» или «_» (безразлично). На рисунке 6 приведён пример заполнения таблицы data с расширенным вводом, где значения поля answer характеризуют степень выраженности условия.

Рисунок 6 – пример заполнения таблицы data

Таблица data_clients (рисунок 7) – содержит личную информацию о клиентах,  данные  об областях в которых он работает, а также номер пользователя (является уникальным), к которому он «привязан». Например, в случае постановки медицинского диагноза, клиентом является пациент, а пользователем – доктор. Таким образом, каждый клиент должен быть привязан к какому-либо пользователю.

Клиент в каждый момент времени может находиться только в одной системе, области и подобласти. Учётная запись клиента создаётся пользователем, данные в таблицу так же добавляются пользователем. При этом пользователь имеет право редактировать данные только своих клиентов.

Данные о текущей таблице решения и номере продукции заносятся автоматически в процессе работы с системой.

Рисунок 7 – таблица data_clients

Здесь: current_progress – номер текущей таблицы решения и номер продукции, dob – дата рождения, home_city – город проживания, home_state – штат/область, home_street – улица, marital_status – семейное положение, name – имя, next_visit – дата последнего посещения, sex – пол, user_id – номер пользователя, к которому привязан клиент, visit – первичный визит, basis_id и basis_name – id и название базиса с которым работает клиент. Базис для каждого клиента устанавливается пользователем перед началом работы системы и сохраняется до её окончания.

Таблица data_users (рисунок 8) – содержит личную информацию о всех пользователях, работающих с системой: имя, адрес, id, названия системы, области и подобласти, с которыми работает данный пользователь, а также логин и пароль для входа в систему. Причём логин является уникальным и не может быть одинаковым у разных пользователей. Данные пользователя заносятся в таблицу автоматически  при регистрации пользователя в системе. При этом пользователь может находиться только в одной области и подобласти.

Рисунок 8 – таблица data_users

Таблица decision (рисунок 9) – хранит все таблицы принятия решений, т.е. при добавлении новых таблиц решений не требуется создание новых таблиц в базе для их хранения. Наборам ответов на условия, хранящимся в столбце conditions, соответствуют наборы действий и последействий (actions и aftereffects).

Рисунок 9 – таблица decision

Здесь: prod_id – номер соответствующей продукции, sid – суррогатный ключ, генерирующийся автоматически при помощи триггера, conditions – комбинация ответов на условия, actions – содержит комбинацию действий, соединенные между собой логическим «И», aftereffect – последействие (переход на другую таблицу/продукцию). Для столбца conditions допустимы логические операции: and (&) и or (||).

Рисунок 10 – пример заполнения таблицы decision

Данные в таблицу decision заносятся администратором и не могут редактироваться пользователями и клиентами.

Таблица metadata (рисунок 11) – содержит списки всех условий и действий, соответствующих данной таблице принятия решений, названия системы, области и подобласти, к которым принадлежит эта таблица, а также вспомогательные  поля для верного построения логического условия, такие как: type, определяющее «вид» ответа клиента: checkbox, в случае ограниченного ввода, и text, в случае расширенного ввода (например, значение температуры); connection – определяет тип соединения данного условия с последующим («AND» или «OR»); brackets – наличие открывающей или закрывающей скобок. Для поддержки нечётких логик используются следующий поля: condition_weight и action_weight – вес условий и действий, значения от 0 до 1; prod_limit – «порог» значения продукции, т.е. продукции, значение которых ниже этого порога, не рассматриваются в дальнейшей работе системы. Данные в таблицу также заносятся администратором и недоступны пользователям и клиентам для редактирования.

Рисунок 11 – таблица metadata

Рисунок 12 – пример заполнения таблицы metadata

Таблица history (рисунок 13) – хранит историю работы каждого клиента. Содержит последовательность переходов между таблицами принятия решения, а также информацию о завершении работы с той или иной таблицей принятия решений. Помимо номера таблицы, к которой осуществляется переход, также хранится номер условия, с которого будет начата работа на следующем шаге (по умолчанию имеет значение 1), номер продукции, по которой был осуществлён переход, полученное при работе значение продукции и название базиса, в соответствии с которым это значение рассчитывалось. Также присутствует поле reason, в которое выводится информация о причинах принятого решения.

Последовательность шагов пользователя с системой может разветвляться и принимать древовидную структуру, некоторые ветки могут «обрезаться» в соответствии с порогом значимости, установленным для продукции.

Рисунок 13 – таблица history

Поля: status – статус работы с таблицей, step – номер шага, на котором осуществлялась работа с таблицей.

Рисунок 14 – пример заполнения таблицы history(часть 1)

Рисунок 15 – пример заполнения таблицы history(часть 2)

Данные в таблицу заносятся автоматически, после нахождения набора действий, соответствующего ответам клиента на заданные условия.  Изначально статус работы с таблицей имеет значение «nostarted». По завершении работы принимает значение «complete».

Информацию об области и подобласти, с которыми работает клиент, можно извлечь из таблицы decision, используя суррогатный ключ из столбца sid.

Таблица bases (рисунок 16) – содержит формулы конъюнкции, дизъюнкции, отрицания и импликации в различных базисах, которые используются для вычисления значимости продукции.

Рисунок 16 – таблица bases

Поля: basis_id, formula_idid базиса и одной из 4х формул, вместе образуют первичный ключ. Basis_name – название базиса, например «базис Вебера», formula_type – тип описываемой формулы, принимает одно из четырёх значений: «&»(and), «||»(or), «^»(not), «->»(implication). Поле formula содержит непосредственно формулы соответствующих операций. Для унарных операций в качестве обозначения переменной используется «А», для бинарных «А» и «В». Каждую операцию над двумя переменными следует выделять скобками, например, для операции импликации:

max(min(A,B),(1-A))

2.2 Пакет pkg_ get_answer. Использование процедур и функций пакета.

Рисунок 17 – схема пакета pkg_get_answer

Пакет pkg_get_answer (рисунок 17) содержит процедуры и функции, реализующие процессы, обеспечивающие создание, редактирование и работу с таблицами принятия решений

Процедура prc_go – основная процедура, вызывается клиентом после заполнения формы с предложенными условиями. Осуществляет работу с таблицей принятия решений: по набору ответов клиента находит соответствующие действия и последействия и, в случае успешного поиска вызывает процедуру для добавления очередного шага разбора в таблицу истории, для каждого найденного соответствия.

Для поиска соответствий каждая продукция соответствующей таблицы принятия решений разбивается в массив и поэлементно сравнивается с массивом ответов пользователя. При сравнении учитываются логические операции AND и OR, а также скобки.

Пример поиска нужной продукции:

((p(1)=a(1)) OR (p(1)='_')) AND ((p(2)= a(2)) OR (p(2)='_')) AND

((p(3)= a(3)') OR ( p(3)='_')) AND ((p(4)= a(4)) OR (p(4)='_')) AND

((p(5)= a(5)) OR (p(5)='_')) , где p(i) – массив элементов продукции, a(i) – массив ответов пользователя.

Входными параметрами являются имя системы (p_sysname), область (p_domain), подобласть (p_subdomain), номер таблицы (p_table_id), id клиента (p_client_id).

Пример вызова процедуры:

begin

get_answer.go('Medicine','Diagnostics','Skin',1,1);

end;

Процедура add_history – добавляет данные о новом шаге работы пользователя в таблицу history: id таблицы, с которой пользователь завершил работу, полученный список действий и последействий, номер шага.  В столбце последействия записывается номер таблицы и условия, к которому будет осуществлён переход. Если последействие имеет значение null, то процедура записывает шаг в таблицу history (рисунок 21) без перехода на другие таблицы и выдаёт сообщение о завершении работы с системой. В этом случае, в поле current_progress таблицы data_clients будет записано значение null.Помимо этого процедура сравнивает значение продукции с порогом значимости и, в случае, если значение ниже этого порога, ставит статус «abort», означающий, что с данной веткой дальнейшая работа невозможна. В поле reason выводится обоснование принятого решения: исходные условия, по которым была выбрана эта продукция, значение продукции, значение порога

Перед добавлением данных процедура проверяет: работал ли клиент с таблицей, к которой мы собираемся перейти. Если работа с этой таблицей уже была закончена, то данное последействие игнорируется и не заносится в таблицу. В случае успешного перехода к новой таблице, её номер записывается в поле current_progress таблицы data_clients.

Входными параметрами процедуры add_history являются суррогатный ключ (p_sid), id клиента (p_client), id пользователя (p_user), номер продукции, по которому будет осуществлён переход (p_prod_id), номер условия, с которого начата работа с таблицей (p_position) и значение данной продукции (p_prod_value). Вызывается только в процессе работы другой процедуры prc_go.

Процедура trans – осуществляет преобразование заданной таблицы решения в вид, понятный пользователю. Результат записывается в соответствующую временную таблицу.

Входными параметрами являются имя системы (sysname), область (domain), подобласть (subdomain), номер таблицы (tableno).

Пример работы процедуры trans для одной из таблиц учебной базы приведен на рисунках 22 и 23.

Пример вызова процедуры:

begin

get_answer.trans('Medicine','Diagnostics','Skin',1);

end;

Функция  fnc_get_value – вычисляет значение необходимой продукции в указанном базисе, в своей работе использует вспомогательную функцию fnc_calculation. На основе продукции составляются 2 формулы, учитывающие все логические операции и значимости: отдельно для условий, отдельно для действий. Например, для ограниченного ввода, исходная комбинация условий

yes&(yes||no),

где значимость первого условия равна 0.2, второго – 0.7, третьего – 0.6, примет вид:

0.2&(0.7||^0.6)

Унарная операция отрицания уже на этом этапе вычисляется при помощи функции fnc_calculation, в соответствии с выбранным базисом. Например, ^A = 1-A. Тогда ^0.6 = 0.4 Далее, используя принцип обратной польской нотации, формула приводится к виду, удобному для вычисления системой:

0.2 ; 0.7 ; 0.4 ; || ; &.

После нахождения значений комбинации условий и действий, вычисляется значений самой продукции:

вес комбинации условий -> вес комбинации действий.

В ситуации с расширенным вводом помимо значимости условий, учитываются ещё и степень «выраженности». Например, если есть всего два условия, соединённых &, и значимость  первого равна 0.3, степень 0.6, второго – 0.7 и 1, тогда значение продукции будет вычислено как:

(0.3*0.6)&(0.7*1).

Входными параметрами служат суррогатный ключ sid, id клиента и номер продукции, значение которой нужно вычислить.

Пример вызова:

value := pkg_get_answer.fnc_get_value(1, 1, 1);

Для вычисления операций &, ||, ^, -> используется функция fnc_calculation, которая выбирает необходимую формулу из таблицы bases, подставляет в неё значения, полученные в качестве входных параметров и вычисляет её, также используя обратную польскую нотацию. Работает как с унарными, так и бинарными операторами. Входные параметры: id базиса, тип логической операции, 2 числовых параметра. Пример вызова:

x := pkg_get_answer.fnc_calculation(0.1,  0.9,  '&',  1);

Обе функции возвращают числовые значения.

2.3 Контроль корректности данных

Большая часть используемых таблиц заполняется вручную администратором, либо пользователем через интерфейс, что значительно увеличивает возможность появления синтаксических ошибок. Помимо этого, не стоит исключать вероятность сбоев в работе системы, которые также могут повлечь за собой заполнение таблиц базы некорректными данными.

Поэтому, немаловажную роль в работе системы играет контроль за корректностью хранимых данных. Но, к  сожалению, на программном уровне возможно отследить лишь малую часть ошибок в заполнении данных на уровне синтаксиса, большая же часть этой задачи, в особенности проверка достоверности данных, остаётся «на совести» пользователей и администраторов, занимающихся наполнением базы знаний. Например, можно отследить строгое заполнение ответов пользователя значениями «да» и «нет» при ограниченном вводе, но программа никак не сможет проверить логичность переходов между таблицами или достоверность вводимых фактов.

Часть подобных задач довольно легко реализуются на уровне интерфейса пользователя, например проверка формата логина для пользователя при регистрации. Но некоторые задачи, проще реализовать на уровне базы данных посредством использования набора триггеров и ограничений целостности.

Такой подход поможет, насколько, это возможно избежать типичных синтаксических ошибок, возникающих при вводе данных вручную или каких-либо сбоях в работе системы, хотя, при большом объёме данных может несколько замедлить работу системы.

В представленной работе, «эталонной» таблицей считается metadata. Подразумевается, что в ней хранятся верная информация о системах, областях, подобластях, таблицах, условиях и действиях. При добавлении данных в таблицы decision, data, data_users, data_clients проверяется наличие таковых данных в metadata и, в случае их отсутствия, выдаётся ошибка. Это позволит сохранить «согласованность» данных не только при сбоях в работе интерфейса, но и в случае заполнения таблиц непосредственно из СУБД.

Также, ведётся контроль за  форматом хранения комбинации условий (поле conditions в таблице decision). Комбинация должна содержать только ответы «yes», «no» и символы «& ||  _». Например

yes&(no||yes)

Ошибки вида «yesno&&yes» помогает исключить использование регулярных выражений.

Аналогичным образом контролируются ответы пользователя: допустимы значения «yes» и «no», в случае ограниченного ввода, и числовые значения в интервале от 0 до 1 в случае расширенного.

Помимо триггеров, контролировать данные помогают ограничения целостности, например ограничение CHECK(formula_type IN ('&', '||', '^', '->')) в комбинации с UNIQUE(basis_id, formula_type) в таблице bases позволяет хранить лишь 4 различных типа формул на каждый базис. Внешние ключи позволяют контролировать привязку клиентов к пользователям.

Примеры используемых триггеров можно посмотреть в приложении.

2.4 Адаптивный интерфейс пользователя

В представленной работе был доработан адаптивный web-интерфейс, основная часть которого была разработана в курсовой работе «Адаптивный интерфейс для работы с таблицами принятия решений», автор – Дербенева Е.Е.

В сравнении с предыдущей версией появились страницы, отображающие историю работы с системой и ответы конкретных клиентов, страница с информацией о базисах, с которыми возможна работа в данной системе. Также реализована работа с расширенным вводом ответов клиента.

Обмен данными с пользовательским интерфейсом осуществляется с помощью технологии Ajax, с использованием формата JSON. На стороне клиента создаётся подключение к СУБД и формируются SQL-запросы.

Для работы с таблицами принятия решений пользователь вызывает необходимые ему процедуры и функции, находящиеся в пакете PKG_GET_ANSWER. При вызове, пользователь указывает, в общем случае, название системы, области и подобласти, номер таблицы, с которыми работает пользователь, а также id клиента. Результат выводится во временные таблицы, данные из которых можно извлечь соответствующим SQL-запросом.

Главная страница интерфейса (рисунки 18-20) представляет собой меню, с помощью которого пользователь может войти в систему и выбрать соответствующие область и подобласть знаний. Новые пользователи имеют возможность зарегистрироваться. При желании пользователь может загрузить обучающие материалы и по таблицам принятия решений, и работе интерфейса.

Рисунок 18 – главная страница интерфейса

Рисунок 19 – Главная страница интерфейса

Рисунок 0 – главная страница

При аутентификации (рисунок 20) пользователь выбирает соответствующую область знаний из динамически строящегося списка всех доступных областей.

Рисунок 20 – аутентификация

Так выглядит регистрационная форма (рисунок 21). Обязательными являются только три поля: имя, логин и пароль.

Рисунок 21 – регистрация пользователя

Если аутентификация пройдена успешно, то пользователь попадает на вторую страницу (рисунок 22). На ней находится динамически построенный список его клиентов. Для обеспечения динамики необходимые параметры (имя системы, область, подобласть, идентификатор пользователя) передаются странице в адресной строке.

Рисунок 22 – база клиентов

При необходимости пользователь может добавлять и удалять клиентов (рисунок 23). Данные манипуляции проводятся с таблицей Data_Clients.

Рисунок 23 – регистрация клиентов

По нажатию на надпись Bases в левом верхнем углу, открывается страница, с базисами данной системы (рисунок 24). У пользователя есть права только на просмотр, изменять данные нельзя.

Рисунок 24 – страница с базисами

На странице с данными о клиентах столбцы ANS и HIS содержат ссылки на страницы, отображающие данные обо всех ответах конкретного клиента и историю его работы с системой соответственно (рисунки 25-26).

Рисунок 25 – страница с ответами клиента

Рисунок 26 – страница с историей клиента

Пользователь имеет возможность удалить некоторые строки, но у него нет прав добавлять вручную новые данные или изменять существующие.

В столбце CURRENT_PROGRESS находится номер следующей таблицы решений. И при нажатии на ссылку происходит переход на страницу заполнения (рисунки 27-28). В качестве параметров выступают: имя системы, область, подобласть знаний, номер таблицы и идентификатор клиента.

Рисунок 27 – опрос клиента (вариант с ограниченным вводом)

Рисунок 28 – опрос клиента (вариант с ограниченным вводом)

В первой вкладке при загрузке создается форма для заполнения текущей таблицы решений. При нажатии на кнопке Submit происходит вставка сформированных из выбора пользователя строк в таблицу DATA. Во второй вкладке находится таблица с данными о предыдущих заполнениях таблиц для данного клиента, эта информация находится в таблице DATA.

Рисунок 29 – отображение таблицы принятия решений

В третьей вкладке приводится таблица принятия решений для текущей заполняемой формы (рисунок 29). Верхняя часть таблицы – условия и комбинации условий, нижняя – действия и комбинации действий. Данные запрашиваются из временной таблицы, созданной процедурой PRC_TRANS().

По завершении работы открывается страница с результатами: поля step, tablename, actions, value пройденных таблиц принятия решения, загруженные из истории клиента (рисунок 30).

В рамочке отображаются действия с наибольшим значением продукции.

Рисунок 30 – страница с результатами


3 Экспериментальные исследования

Для экспериментального исследования разработанных инструментов была выбрана часто встречающаяся в повседневной жизни задача выбора мобильного телефона, в частности смартфона.

В настоящее время многие сайты предлагают помощь в решении данного вопроса, но большинство из них основывается на предположении, что человек хоть немного разбирается в технических особенностях устройств. В разработанной схеме выбор основывается на необходимых качествах без уточнения технических параметров. Однако, в связи с довольно широким спектром устройств, система не предлагает выбор между конкретными моделями, а лишь помогает сузить диапазон поиска устройства.

Основными запрашиваемыми характеристиками служат тип операционной системы, предназначение, качество камеры, ценовой диапазон. Отдельным, частным случаем можно рассматривать выбор конкретной модели фирмы Apple.

База знаний для решения данной задачи реализована, как система таблиц принятия решения, переходы между которыми осуществляются за счет использования введения последействий.  Структура таблиц решения приведена на рисунке 31.

Рисунок 31 – схема тестовой базы

Время работы в Oracle процедуры prc_go, включая вызов процедуры prc_add_history и функций fnc_get_value и fnc_calculation для одной из таблиц учебной базы:  00.233 секунд.

Время работы в Oracle процедуры prc_translate для одной таблицы:  00.118 секунд.


ЗАКЛЮЧЕНИЕ

Создана база данных для инструментального средства, предназначенного для работы с таблицами принятия решений, встроенными в СУБД Oracle.

Создан пакет процедур и функций, реализующий процессы, обеспечивающие создание, редактирование и работу с таблицами принятия решений,

Доработаны интерфейсы, разработанные в курсовой работе Дербеневой Е. «Адаптивный интерфейс для работы с таблицами принятия решений», выполнить экспериментальную проверку инструментального средства. В частности, созданы страницы редактирования истории и таблицы ответов пользователей, реализован расширенный ввод данных.

Проведены экспериментальные исследования быстродействия.


СПИСОК ИСПОЛЬЗОВАННЫХ ИСТОЧНИКОВ

  1.  Экспертные и обучающиеся системы [электронный ресурс]. URL: http://www.lessons–tva.info/edu/e–inf2/m2t4_10.html
  2.  Портал искусственного интеллекта, роботы с искусственным интеллектом [электронный ресурс]. URL: http://www.aiportal.ru/articles/expert-systems/expert-systems.html
  3.  Интеллектуальное управление [электронный ресурс]. URL: http://dic.academic.ru/dic.nsf/ruwiki/1378388
  4.  Википедия – свободная энциклопедия [электронный ресурс]. URL: http://ru.wikipedia.org/
  5.  Бессмертный И.А., Применение реляционных операций для логического вывода в продукционных системах. Изв. вузов. Приборостроение,  2010 – с.34-38.
  6.  Бессарабов Н.В., Муса-Оглы Е.С.  Универсальная модель данных. RSDN, 2011, №3 – с. 51-55.
  7.  Братко И., Алгоритмы искусственного интеллекта на языке PROLOG. Мск.: Вильямс, 2004 – с. 331-334.
  8.  В. Г. Рубанов, А. Г. Филатов, И. А. Рыбин. Интеллектуальные системы автоматического управления. Нечеткое управление в технических системах [электронное пособие]. URL: http://nrsu.bstu.ru/
  9.  Бессарабов Н.В., Семенютина Л.В. Таблицы принятия решений встроенные в базы данных. – INTELS, 2014.
  10.  Поспелов Д. А. Моделирование рассуждений. Опыт анализа мыслительных актов. М.: Радио и связь, 1989,  184 с.
  11.  Продукционная модель представления знаний [электронный ресурс]. URL: http://itteach.ru/predstavlenie–znaniy/produktsionnaya–model–predstavleniya–znaniy
  12.  

ПРИЛОЖЕНИЕ А

Спецификация пакета pkg_get_answer:
create or replace PACKAGE pkg_get_answer AS

PROCEDURE prc_go(   p_sysname     decision.sysname%TYPE,

                   p_domain      decision.domain%TYPE,

                   p_subdomain   decision.subdomain%TYPE,

                   p_table_id    decision.table_id%TYPE,

                   p_client_id     data.client_id%TYPE);

PROCEDURE prc_add_history(    p_sid          history.sid%TYPE,

                           p_user         history.user_id%TYPE,

                           p_client       history.client_id%TYPE,

                           p_prod_id       NUMBER,

                           p_position  NUMBER,

                           p_prod_value history.prod_value%TYPE

                       );

PROCEDURE prc_translate(     p_sysname    decision.sysname%TYPE,

                       p_domain      decision.domain%TYPE,

                       p_subdomain   decision.subdomain%TYPE,

                       p_table_id     decision.table_id%TYPE

                   );

FUNCTION fnc_get_value(p_sid          metadata.sid%TYPE,

                          p_client_id    data_clients.client_id%TYPE,

                          p_prod_id    decision.prod_id%TYPE)

RETURN NUMBER;

FUNCTION fnc_calculation( p_x1 VARCHAR2

                       , p_x2 VARCHAR2

                       , p_operation VARCHAR2

                       , p_basis_id data_clients.basis_id%TYPE)

RETURN NUMBER;

END pkg_get_answer;​


ПРИЛОЖЕНИЕ Б

Тело пакета pkg_get_answer:

CREATE OR REPLACE PACKAGE BODY pkg_get_answer AS    

   

TYPE arr_type IS TABLE OF VARCHAR2(2000)INDEX BY BINARY_INTEGER;

 

PROCEDURE prc_go(   p_sysname     decision.sysname%TYPE,

                   p_domain      decision.domain%TYPE,

                   p_subdomain   decision.subdomain%TYPE,

                   p_table_id    decision.table_id%TYPE,

                   p_client_id     data.client_id%TYPE)

AS

   c_sid NUMBER;

   c_user_id   NUMBER;

   c_condition NUMBER; --число условий

   c_min_condition  NUMBER;

   c_action   NUMBER; --число действий

   c_product  NUMBER; --число продукций

   q_select VARCHAR(2000);

   q_where  VARCHAR(2000);

   i NUMBER; --чёрная рабочая сила)

   j NUMBER;

   v_in_str NUMBER;

   v_substr_condition VARCHAR2(2000);

   v_char_left  VARCHAR(5);

   v_char_right VARCHAR(5);        

   v_connection VARCHAR(5);

   m_answer     arr_type; -- масс  в ответов пользователя

   m_connection arr_type; -- массив логических операций

   m_char       arr_type; -- массив со скобками

   m_product    arr_type; -- массив, в который помещаются все распасенные продукци

   v_productuctno NUMBER; -- массив с номерами эквивалентных продукций

   v_prod_value history.prod_value%TYPE := 0;

   v_condition  decision.conditions%TYPE;

   --m_condition arr_type; -- массив с продукциями

   v_equals_cnt  NUMBER;

   v_count NUMBER := 0;

  -- c_prc_name  VARCHAR2(50) := 'PKG_GET_ANSWER_NEW.PRC_GO';

   --v_prc_step  NUMBER := 0;

   v_right_bkt NUMBER;

   v_left_bkt  NUMBER;

   x NUMBER;

   v_type metadata.type%TYPE;

   TIME_START TIMESTAMP;

   TIME_END     TIMESTAMP;

BEGIN

   TIME_START := SYSTIMESTAMP;    

   

   SELECT DISTINCT sid INTO c_sid FROM metadata

    WHERE sysname = p_sysname

      AND domain = p_domain

      AND subdomain = p_subdomain

      AND table_id = p_table_id;

          

   SELECT COUNT(condition_id),COUNT(action_id) INTO c_condition, c_action --находим количество условий и действий

     FROM metadata

    WHERE sid = c_sid;

   

   IF c_condition < 1 THEN raise_application_error(-20050,'Количество условий должно быть не меньше 1.');  END IF;

   IF c_action < 1 THEN raise_application_error(-20050,'Количество  действий должно быть не меньше 1.'); END IF;

   

   SELECT COUNT(brackets) INTO v_right_bkt

     FROM metadata

    WHERE sid = c_sid

      AND table_id = p_table_id

      AND brackets = '(';

   

   SELECT COUNT(brackets) INTO v_left_bkt

     FROM metadata

    WHERE sid = c_sid

      AND brackets = ')';

   

   IF v_left_bkt <> v_right_bkt  THEN raise_application_error(-20050,'Количество открывающих и закрывающих скобок в таблице metadata не совпадает. Обратитесь к разработчику.'); END IF;

   

   SELECT user_id INTO c_user_id FROM data_clients

    WHERE client_id = p_client_id;           

   

   SELECT COUNT(prod_id) INTO c_product --находим количество продукций для данной таблицы

     FROM decision

    WHERE sid = c_sid;

   

   FOR i IN 1..c_condition LOOP --записываем логические операции в массив

       SELECT connection, brackets INTO m_connection(i),m_char(i)

         FROM metadata

        WHERE sid = c_sid

          AND condition_id = i;

   END LOOP;

   SELECT MIN(condition_id) INTO c_min_condition  

     FROM data --берём номер условия, с которого есть ответы пользователя

    WHERE sid = c_sid

      AND client_id = p_client_id;

   

   FOR i IN c_min_condition..c_condition LOOP

       SELECT type INTO v_type

         FROM metadata

        WHERE sid = c_sid

          AND condition_id = i;

          

       CASE v_type

           WHEN 'checkbox' THEN

               SELECT answer INTO m_answer(i)

                 FROM data --берём ответы пользователя

                WHERE sid = c_sid

                  AND client_id = p_client_id

                  AND condition_id = i;

           WHEN 'text' THEN

               SELECT CASE  

                      WHEN TO_NUMBER(answer, '999D9999') > 0 THEN 'yes'

                      ELSE 'no'

                      END INTO m_answer(i)

                 FROM data --берём ответы пользователя

                WHERE sid = c_sid

                  AND client_id = p_client_id

                  AND condition_id = i;

       END CASE;    

       

   END LOOP;

   

   IF c_min_condition > 1 THEN -- если в начале ответов не хватает, то заполняем пробелы '_'

       FOR i IN 1..c_min_condition LOOP

          m_answer(i):='_';

       END LOOP;

   END IF;

      

   FOR i IN 1..c_product   LOOP --=== режем все комбинации ответов и записываем в один массив

       SELECT conditions INTO v_condition--m_condition(i)

         FROM decision

        WHERE sid = c_sid

          AND prod_id = i;  

  

       FOR j IN 1..c_condition-1 LOOP

           --IF j <> c_condition THEN

           --BEGIN       

               SELECT regexp_substr(v_condition, '[^'||m_connection(j)||']+', 1, 1),

                      INSTR(v_condition,m_connection(j))

                 INTO m_product((i-1)*c_condition+j),

                      v_in_str  

                 FROM dual; --режем исходную строку с комбинацией условий в один большой массив

               

               --SELECT INSTR(v_condition,m_connection(j)) INTO v_in_str --ищем номер первого вхождения условия соединения

               --  FROM dual;

               

               SELECT SUBSTR(v_condition,v_in_str+1,LENGTH(v_condition)) INTO v_substr_condition --вырезаем строку, начиная с этой позиции

                 FROM dual;

               

               v_condition := v_substr_condition;

           --END;    

           --ELSE m_product((i-1)*c_condition+j):=v_substr_condition;

           --END IF;        

       END LOOP;

       

       m_product((i-1)*c_condition+c_condition):=v_substr_condition;

   END LOOP;  

   

   FOR i IN 1..c_product LOOP

       v_equals_cnt := 0;

       q_select:= 'SELECT COUNT(*) FROM dual WHERE ';

       q_where:='';

       FOR j IN 1..c_condition LOOP         

           IF m_connection(j)='&' THEN v_connection :=' AND ';

           ELSIF m_connection(j)='||' THEN v_connection :=' OR ';

           ELSE v_connection :='';

           END IF;

   

           IF    SUBSTR(m_char(j),1,1)='(' THEN v_char_left:=m_char(j);   v_char_right:=''; --чтобы правильно расставить скобки

           ELSIF SUBSTR(m_char(j),1,1)=')' THEN v_char_left:='';          v_char_right:=m_char(j);

           ELSE                                 v_char_left:='';          v_char_right:='';

           END IF;

       

           q_where:= q_where||v_char_left||'(('''||m_answer(j)||'''='''||m_product((i-1)*c_condition+j)||''')OR('''||m_product((i-1)*c_condition+j)||'''=''_''))'||v_char_right;

           IF j <> c_condition THEN q_where:=q_where||v_connection; END IF;-- если есть ещё условия, добавляем соединение    

       END LOOP;

       q_select:=q_select||q_where;

       

       EXECUTE IMMEDIATE q_select INTO v_equals_cnt;    -- есть ли совпадения, если есть - запоминаем

       IF v_equals_cnt > 0 THEN  v_count := v_count+1;

           v_productuctno:=i;                            -- если нашлось совпадение, считаем значение полученной продукции

           v_prod_value := pkg_get_answer.fnc_get_value(c_sid, p_client_id, v_productuctno);

           --dbms_output.put_line('Продукция = '||v_prod_value);

           PRC_ADD_HISTORY(c_sid, c_user_id, p_client_id, v_productuctno, v_count, v_prod_value);

       END IF;

       

   END LOOP;    

   

   SELECT MIN(step) INTO x

     FROM history

    WHERE client_id = p_client_id

      AND status = 'nostarted'

      AND user_id  = c_user_id;

   

   IF x = 0 THEN

      dbms_output.put_line('Работа с системой завершена. Проверьте результаты');

   END IF;

   

   TIME_END := SYSTIMESTAMP;

  -- TIME_WORK := TIME_END - TIME_START;

   dbms_output.put_line('Времы работы: '||(TIME_end-TIME_START));

END prc_go;

PROCEDURE PRC_ADD_HISTORY(  p_sid          history.sid%TYPE,

                           p_user         history.user_id%TYPE,

                           p_client       history.client_id%TYPE,

                           p_prod_id      NUMBER,

                           p_position     NUMBER,

                           p_prod_value   history.prod_value%TYPE )

AS

   c_table_name metadata.tablename%TYPE;

   c_table_id NUMBER; -- номер таблицы, для которой вызвали процедуру

   c_action      decision.actions%TYPE; -- нераспарсенные строки

   c_aftereffect decision.aftereffect%TYPE;    

   v_condition  decision.conditions%TYPE;    

   c_condition NUMBER; --количество условий

   c_step NUMBER :=0; -- номер последнего шага

   v_step NUMBER :=0; -- номер шага, который запишем

   v_query VARCHAR2(2000):=''; -- для динамического запроса

   v_action      NUMBER; -- число действий

   v_aftereffect NUMBER; -- число последействий

   v_table_id     NUMBER;

   v_sid         NUMBER;

   v_progress VARCHAR2(50);

   v_in_str NUMBER;

   v_substr_condition VARCHAR2(2000);

   v_basis_name history.basis_name%TYPE := '';

   m_action        arr_type; -- массив рспарсенных действий

   m_aftereffect   arr_type;

   --m_condition_num arr_type;

   v_condition_num VARCHAR2(5);

   v_product_part metadata.condition%TYPE;

   v_reason_part  metadata.condition%TYPE;

   v_limit        metadata.prod_limit%TYPE;

   v_connection VARCHAR2(5);

  -- чёрная рабочая сила 

   i NUMBER;

   j NUMBER;    

   c NUMBER;

   f BOOLEAN;

   s VARCHAR2(2000);

   v_reason VARCHAR2(2000) := '';

   v_in_array NUMBER :=0;

   c_sysname     decision.sysname%TYPE;

   c_domain      decision.domain%TYPE;

   c_subdomain   decision.subdomain%TYPE;

   c_min_condition_id NUMBER := 1;

BEGIN

   SELECT DISTINCT table_id, tablename, sysname, domain, subdomain

     INTO c_table_id, c_table_name, c_sysname, c_domain,  c_subdomain

     FROM metadata --ищем номер таблицы по sid

    WHERE sid = p_sid;

   

   SELECT COUNT(*) INTO c

     FROM history --смотрим были ли уже в этой таблице и прошли ли её полностью

    WHERE client_id = p_client

      AND user_id = p_user

      AND sid = p_sid

      AND condition_id = 1

      AND status = 'complete';

 

   IF c>0 THEN

       --здесь проверить список условий

       raise_application_error(-20050, 'Таблица, для которой была вызвана процедура уже была использована.');

   END IF;

   

   SELECT NVL(MAX(step),0) INTO c_step

     FROM history

    WHERE user_id = p_user

      AND client_id = p_client;

      

   IF p_position = 1 THEN v_step := c_step + 1; --если это первая продукция для данной таблицы, то шаг=МАХ+1

   ELSE  v_step := c_step;

   END IF; -- иначе шаг=МАХ

   

   -- если в этой таблице не работали, или прошли её не полностью

   IF c_step>0 THEN

       v_query := 'UPDATE history SET status = ''complete'' WHERE user_id='||p_user||

                                                            ' AND client_id='||p_client||

                                                            ' AND step='||c_step;

       EXECUTE IMMEDIATE V_QUERY ; COMMIT;

       --dbms_output.put_line(v_query);

   END IF;

   SELECT basis_name INTO v_basis_name --смотрим базис, в котором рабоает клиент

     FROM data_clients

    WHERE client_id = p_client;     

    

   --порог 

   SELECT MAX(prod_limit) INTO v_limit

     FROM metadata

    WHERE sid = p_sid;

   --формируем обоснование

   SELECT COUNT(condition_id) INTO c_condition --находим количество условий и действий

     FROM metadata

    WHERE sid = p_sid;

    

   SELECT conditions INTO v_condition --берём продукцтю

     FROM decision

    WHERE sid = p_sid

      AND prod_id = p_prod_id;  

   

   FOR j IN 1..c_condition-1 LOOP

       SELECT connection INTO v_connection --m_connection(i)

         FROM metadata

        WHERE sid = p_sid

          AND condition_id = j;           

   

       SELECT regexp_substr(v_condition, '[^'||v_connection||']+', 1, 1),

              INSTR(v_condition,v_connection)

         INTO v_product_part, --m_product(j),

              v_in_str  

         FROM dual; --режем исходную строку с комбинацией условий в один большой массив

       

       SELECT condition INTO v_reason_part

         FROM metadata

        WHERE sid = p_sid

          AND condition_id = j;

   

       IF v_product_part = 'yes' THEN v_reason := v_reason || v_reason_part || ', ';

       ELSIF v_product_part = 'no' THEN v_reason := v_reason || 'not ' || v_reason_part || ', ';

       ELSIF v_product_part = '_' THEN v_reason := v_reason || 'no matter ' || v_reason_part || ', ';

       END IF;

  

       SELECT SUBSTR(v_condition,v_in_str+1,LENGTH(v_condition)) INTO v_substr_condition --вырезаем строку, начиная с этой позиции

         FROM dual;

       

       v_condition := v_substr_condition;        

   END LOOP;  

   

   SELECT condition INTO v_reason_part

     FROM metadata

    WHERE sid = p_sid

      AND condition_id = c_condition;

   

   IF v_substr_condition = 'yes' THEN v_reason := v_reason || v_reason_part;

   ELSIF v_substr_condition = 'no' THEN v_reason := v_reason || 'not ' || v_reason_part;

   ELSIF v_substr_condition = '_' THEN v_reason := v_reason || 'no matter ' || v_reason_part || ', ';

   END IF;

    

   IF p_prod_value < v_limit THEN --если продукция не проходит порог 

       v_reason := v_reason || ' (value = '||p_prod_value||'< lower limit = '||v_limit||')';

   

       v_query := 'INSERT INTO history(sid, tablename, user_id, client_id, status, step, prod_id, prod_value, basis_name, condition_id, reason)

                                VALUES('||p_sid||', '''||c_table_name||''', '||p_user||', '||p_client||', ''abort'', '||v_step||', '||p_prod_id||', '||p_prod_value||', '''||v_basis_name||''', '||c_min_condition_id||', '''||v_reason||''')'; --m_condition_num(i)

       EXECUTE IMMEDIATE v_query; COMMIT;

   ELSE

       v_reason := v_reason || ' (value = '||p_prod_value||'> lower limit = '||v_limit||')';

       

       SELECT actions, aftereffect INTO c_action, c_aftereffect

         FROM decision

        WHERE sid = p_sid

          AND prod_id = p_prod_id;

       

       SELECT LENGTH(c_action)-LENGTH(REPLACE(c_action, '&')) INTO v_action FROM dual;

              v_action := v_action + 1; --считаем количество действий в строке (кол-во разделителей+1)

       

       FOR i IN 1..v_action LOOP

           SELECT REGEXP_SUBSTR(c_action,'[^&]+',1,i) INTO m_action(i) --режем эту строку в массив

             FROM dual;--(SELECT c_action FROM dual);  

       END LOOP;

       

       IF c_aftereffect IS NULL THEN

       

           FOR i IN 1..v_action LOOP --записываем список действий

               v_query := 'INSERT INTO history (sid, tablename, user_id, client_id, action, aftereffect, status, step, prod_value, reason, basis_name)

                                  VALUES('||p_sid||', '''||c_table_name||''', '||p_user||', '||p_client||', '''||m_action(i)||''', ''null'', ''end'', '||v_step||', '||p_prod_value||', '''||v_reason||''', '''||v_basis_name||''')';

               EXECUTE IMMEDIATE v_query;  

               --dbms_output.put_line(v_query);

               COMMIT;

           END LOOP;

       

           --проверяем, есть ли непройденные ветки

           /* SELECT MIN(step) INTO x

               FROM history

               WHERE client_id = p_client

               AND status = 'nostarted'

               AND user_id  = p_user;

           

               IF x > 0 THEN

                   SELECT MIN(prod_id) INTO y

                   FROM history

                   WHERE client_id = p_client

                     AND status = 'nostarted'

                     AND user_id  = p_user

                     AND step = x;

           

                   SELECT aftereffect INTO z

                     FROM history

                    WHERE client_id = p_client

                     AND status = 'nostarted'

                     AND user_id  = p_user

                     AND step = x

                     AND prod_id = y;

           

                   v_query := 'UPDATE data_clients SET current_progress = '||SUBSTR(z,7,3)||' WHERE client_id='||p_client;

                   EXECUTE IMMEDIATE v_query;

                   COMMIT;

                   dbms_output.put_line('Работа с одной из веток завершена. Проверьте результаты');

                ELSE */

                --т.к. дошли до конца, ставим current_progress = 0

           v_query := 'UPDATE data_clients SET current_progress = 0 WHERE client_id='||p_client;

           EXECUTE IMMEDIATE v_query;

           --dbms_output.put_line(v_query);

           COMMIT;

           dbms_output.put_line('Работа с веткой решений завершена.');--('Работа с системой завершена. Проверьте результаты');

            --END IF;

   -- Если последействие IS NOT NULL --

       ELSE

           SELECT MIN(condition_id) INTO c_min_condition_id

             FROM data

            WHERE sid = p_sid

              AND client_id = p_client;    

           

           SELECT LENGTH(c_aftereffect)-LENGTH(REPLACE(c_aftereffect, '|')) INTO v_aftereffect FROM dual;

           v_aftereffect := v_aftereffect +1; --считаем количество последействий (кол-во разделителей +1)

       

           FOR i IN 1..v_aftereffect LOOP

               --f := false;-- повторений не было

       

               SELECT REGEXP_SUBSTR(c_aftereffect  ,'[^|]+',1,i) INTO s--распарсиваем список последействий по разделителям

                 FROM dual;

               

               --SELECT REGEXP_SUBSTR(s,'[^"]+',1,2) INTO v_tablename --берём название таблицы из кавычек

               --  FROM dual;

               

               SELECT DISTINCT table_id INTO v_table_id

                 FROM metadata --ищем номер таблицы по названию

                WHERE UPPER(tablename) = UPPER((SELECT REGEXP_SUBSTR(s,'[^"]+',1,2) --берём название таблицы из кавычек

                                     FROM dual))

                  AND sysname = c_sysname

                  AND domain = c_domain

                  AND subdomain = c_subdomain;

               

               SELECT DISTINCT sid INTO v_sid

                 FROM metadata -- ищем sid по номеру

                WHERE table_id = v_table_id

                  AND sysname = c_sysname

                  AND domain = c_domain

                  AND subdomain = c_subdomain;

       --    !!!!!!!!!!!!!!!!          

               SELECT COUNT(*) INTO c FROM history --смотрим были ли уже в таблице, на которую хотим перейти

                   WHERE client_id = p_client

                     AND user_id = p_user

                     AND sid = v_sid

                     AND condition_id = 1

                     AND status = 'complete';

               

               IF c = 0 THEN -- если нет, то запишем последействия    

                   --IF v_in_array > 0 THEN -- если в массив уже что-то записали, то ищем повторения

                   --    FOR j IN 1..v_in_array LOOP

                   --       IF 'table_'||v_table_id||'_1' = m_aftereffect(j) THEN f := true; END IF; --нашли повторение

                   --    END LOOP;

                   --END IF;

                   --

                   --IF f = false THEN -- если повторений нет, то записываем новый элемент

                   v_in_array := v_in_array + 1;

                   SELECT NVL(REGEXP_SUBSTR(s,'[0-9]*$'),1) INTO v_condition_num--m_condition_num(v_in_array )

                     FROM dual; --(SELECT s FROM dual);  --вытаскиваем номер условия, к которому нужно перейти

                   

                   IF v_condition_num IS NULL THEN m_aftereffect(v_in_array):='table_'||v_table_id||'_1';

                   ELSE m_aftereffect(v_in_array):='table_'||v_table_id||'_'||v_condition_num;

                   END IF;

                   --END IF;

               END IF;   

           END LOOP;

       

           IF v_in_array = 0 THEN raise_application_error(-20050, 'Все таблицы из списка последействий уже пройдены.'); END IF;

       

           v_aftereffect := v_in_array ;

           IF v_aftereffect > v_action THEN --== дополняем массивы

               FOR i IN v_action+1..v_aftereffect LOOP

                   m_action(i):='';

               END LOOP;

               c := v_aftereffect;

           ELSE

               FOR i IN v_aftereffect+1..v_action LOOP

                   m_aftereffect(i):='';

               END LOOP;

               c:=v_action;

           END IF;         

       

           FOR i IN 1..c LOOP  -- записываем следующие шаги      

               v_query := 'INSERT INTO history(sid, tablename, user_id, client_id, action, aftereffect, status, step, prod_id, prod_value, basis_name, condition_id, reason)

                                VALUES('||p_sid||', '''||c_table_name||''', '||p_user||', '||p_client||',

                                     '''||m_action(i)||''', '''||m_aftereffect(i)||''',

                                     ''nostarted'', '||v_step||', '||p_prod_id||', '||p_prod_value||', '''||v_basis_name||''', '||c_min_condition_id||', '''||v_reason||''')'; --m_condition_num(i)

               EXECUTE IMMEDIATE v_query; COMMIT;

               --dbms_output.put_line(v_query);

           END LOOP;

       

        --== берём номер таблицы, на которую перешли, записываем в progress в client_id ==

           v_progress :=  SUBSTR(m_aftereffect(1),7,3);

           v_query := 'UPDATE data_clients SET current_progress ='''||v_progress||''' WHERE client_id='||p_client;

           EXECUTE IMMEDIATE v_query; COMMIT;        

           --dbms_output.put_line(v_query);

        

       END IF; -- close if aftereffect is not null

   END IF; --close limit

END prc_add_history;

PROCEDURE PRC_TRANSLATE( p_sysname    decision.sysname%TYPE,

                        p_domain      decision.domain%TYPE,

                        p_subdomain   decision.subdomain%TYPE,

                        p_table_id     decision.table_id%TYPE )

AS

   m_action     arr_type; --массив действий

   m_connection arr_type;

   m_product    arr_type;    

   c_sid        NUMBER;

   v_condition  NUMBER; --чиcло условий

   v_action     NUMBER; --число действий

   v_product    NUMBER;

   v_in_str     NUMBER;

   --для динамических запросов

   q            VARCHAR(2000);

   q_execute    VARCHAR(2000);

   --чёрная рабочая сила

   i NUMBER;

   c NUMBER;

   j NUMBER;

   s            decision.actions%TYPE;

   str          decision.actions%TYPE;

   M_CONDITION  DECISION.CONDITIONS%TYPE;

   TIME_START TIMESTAMP;

   time_end   TIMESTAMP;

BEGIN

   TIME_START := SYSTIMESTAMP;

   

   SELECT DISTINCT sid INTO c_sid FROM metadata

    WHERE sysname = p_sysname

      AND domain = p_domain

      AND subdomain = p_subdomain

      AND table_id = p_table_id;

   SELECT COUNT(condition_id),COUNT(action_id) INTO v_condition, v_action --находим количество условий и действий

     FROM metadata

    WHERE sid = c_sid;

   

   FOR i IN 1..v_action LOOP --записываем названия условий в массив

       SELECT action INTO m_action(i) FROM metadata

        WHERE sid = c_sid

          AND action_id = i;

   END LOOP;

   

   FOR i IN 1..v_condition LOOP --записываем логические операции в массив

       SELECT connection INTO m_connection(i) FROM metadata

        WHERE sid = c_sid

          AND condition_id = i;

   END LOOP;

   

   SELECT COUNT(prod_id) INTO v_product --находим количество продукций

     FROM decision

    WHERE sid = c_sid;

   

   FOR i IN 1..v_product LOOP

       q:=q||', prod_'||i||' VARCHAR(30)';

   END LOOP;

   

   SELECT COUNT(table_name) INTO c FROM user_tables WHERE table_name='DECISION_'||p_table_id;

   

   IF c=0 THEN

       q_execute :='CREATE GLOBAL TEMPORARY TABLE decision_'||p_table_id||'(names varchar2(100)'||q||') ON COMMIT DELETE ROWS';

       EXECUTE IMMEDIATE q_execute;

   END IF;    

 

   FOR i IN 1..v_product   LOOP --=== режем все продукции на элементы и записываем в один   ольшой массив

       SELECT conditions INTO m_condition

         FROM decision

        WHERE sid = c_sid

          AND prod_id = i;   

       

       FOR j IN 1..v_condition LOOP

           IF j <> v_condition THEN     

               SELECT regexp_substr(m_condition, '[^'||m_connection(j)||']+', 1, 1) INTO m_product((i-1)*v_condition+j)

                 FROM dual; -- выпезаем первое условие

            

               SELECT INSTR(m_condition, m_connection(j)) INTO v_in_str

                 FROM dual; -- находим позицию первого соединения

            

               SELECT SUBSTR(m_condition, v_in_str + 1, LENGTH(m_condition)) INTO s

                 FROM dual;

               m_condition := s; -- вырезаем строку с этой позиции и обрабатываем дальше

            

           ELSE m_product((i-1)*v_condition+j) := s;

           END IF;       

       END LOOP;

   END LOOP;

 

   FOR i IN 1..v_condition LOOP --=== заполняем decision условиями

       SELECT condition INTO m_condition

         FROM metadata

        WHERE sid = c_sid

          AND condition_id = i;

   

       q := '';

       FOR j IN 1..v_product LOOP    

           SELECT DECODE(m_product((j-1)*v_condition+i),'yes','+','no','-','_','/','[/w0-9<>]*') INTO s

           FROM (SELECT m_product((j-1)*v_condition+i) FROM dual);    -- преобразуем ответы в символьный вид    

           q:=q||', '''||s||'''';

       END LOOP;

       q_execute:='INSERT INTO decision_'||p_table_id||' VALUES('''||m_condition||''''||q||')';

       EXECUTE IMMEDIATE q_execute; -- заполняем таблицу условиями

   END LOOP;

 

   FOR i IN 1..v_action LOOP

       q_execute:='INSERT INTO decision_'||p_table_id||'(names) VALUES('''||m_action(i)||''')';

       EXECUTE IMMEDIATE q_execute;  -- заполняем таблицу названиями действий

   END LOOP;

       

   FOR j IN 1..v_product LOOP  

       SELECT actions INTO str

         FROM decision  

        WHERE sid = c_sid

          AND prod_id = j;

 

       FOR i IN 1..v_condition LOOP -- парсим строку действий в массив

           IF i <> v_condition THEN     

               SELECT regexp_substr(str, '[^'||m_connection(i)||']+', 1, 1) INTO m_product(i)

                 FROM (SELECT str FROM dual);

               SELECT INSTR(str, m_connection(i)) INTO v_in_str FROM (SELECT str FROM dual);

               SELECT SUBSTR(str, v_in_str+1, LENGTH(str)) INTO s FROM (SELECT str FROM dual);

               str := s;

           ELSE m_product(i):=s;

           END IF;     

       END LOOP;

  

       FOR i IN 1..v_condition LOOP -- ставим крестики напротив необходмых действий

           q_execute:='UPDATE decision_'||p_table_id||' SET prod_'||j||'=''x'' WHERE names='''||m_product(i)||'''';

           EXECUTE IMMEDIATE q_execute;

       END LOOP;

   END LOOP;

   TIME_END := SYSTIMESTAMP;

   dbms_output.put_line('Времы работы: '||(TIME_END-TIME_START));

END prc_translate;

BEGIN

   NULL;    

END pkg_get_answer;


ПРИЛОЖЕНИЕ В

Интерфейс пользователя:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> // главная страница

<html xmlns="http://www.w3.org/1999/xhtml" >

<head>

   <title>БЗ</title>

 <link rel="shortcut icon" href="images/favicon.ico" type="image/x-icon">

   <link rel="stylesheet" href="style.css">

<link rel="stylesheet" href="accord.css">

   <script type="text/javascript" src="files/2/jquery.tools.min.js" ></script>

   <script type="text/javascript" src="files/2/main.js"></script>

</head>

<body>

<div id='header'>

 <img class='home' src='images/robot.png' >

 <div class='ithink'>IThink</div>

</div>

<div id='wrap'>

 

  <div id="accordion">

  <img src="files/2/images/i1.jpg" />

  <div style="width:200px; display:block">

   <h2>Work with knowledgebase </h2>

   <a class='menu' id='logdb' href="#" rel="#login">Login</a>

  </div>

  <img src="files/2/images/i2.jpg" />

  <div >

   <h2>Knowledge base</h2>

   <a class='menu' href="createdb.htm">Create</a>

   

  </div>

  <img src="files/2/images/i3.jpg" />

  <div>

   <h2>Getting started</h2>

   <a class='menu' href="doc/usermanual.doc">User Manual</a>

   <a class='menu' href="doc/adminmanual.doc">Admin Manual</a>

  </div>

  <img src="files/2/images/i4.jpg" />

  <div >

   <h2>Manual</h2>

   <a class='menu' href="index1.htm">A production system</a>

   <a class='menu' href="index2.htm">Decision table</a>

  </div>

   </div>

   

   

   <div id="dept"></div>

   <div class="overlay" id="login">

   <a class="close"></a>

   <form id="myform1">

      <h2>Login form</h2><br>

      <div class='styled-select'><select id='sp1' size="1" >  </select></div><br>

      <div class='styled-select'><select id='sp2' size="1" ></select></div><br>

      <div class='styled-select'><select id='sp3' size="1" ></select></div><br>

      <div>Login</div> <input type="text" name="name" pattern="[a-zA-Z ]{5,}" minlength="4" maxlength="30" id='log1' />*<br><br>

      <div>Password</div> <input type="password" name="password"  minlength="4" id='pas1'/>*<br><br>

      

      <button class='submit' type="submit">Submit form</button>

      <br><br> <a id='registr'  class='menu'href='#' rel='#regis'>R e g i s t r a t i o n</a>

      <A HREF="" id='mainref' ></A>

   </form>

   </div>

   <div class="overlay" id="regis">

   <a class="close"></a>

   <form id="myform2">

      <h2>Registration form</h2><br>

      <div>Name</div> <input type="text" name="name" maxlength="30" id='name'/>*

      <br><br>

      <div class='inline'><div>Login </div><input type="text" name="name" pattern="[a-zA-Z0-9_]{5,}" minlength="4" maxlength="30" id='log2'/>*<br><br></div>

      <div class='inline'><div>Password </div><input type="password" name="password"  minlength="4" id='pas2'/>*<br><br></div>

      <fieldset>

       <div class='inline'>Home   city </div> <input type="text" name="city" maxlength="30" id='city'/><br><br>

       <div class='inline'>Home  state </div><input type="text" name="state" maxlength="30" id='state'/><br><br>

       <div class='inline'>Home street </div><input type="text" name="street" maxlength="30" id='street'/>

      </fieldset>

      <br><br><br>

      <button class='submit' type="submit">Submit</button>

   </form>

   </div>

</div>

<div id='footer'>footer</div>

</body>

<!—скрипт для главной страницы-->

 $(function() {

     $("#accordion").tabs("#accordion div", {      //Инициализация аккордиона

     tabs: 'img',

     effect: 'horizontal'

   });

//$(":date").dateinput({lang: 'fr',});

 $('#sp2').parent().css('display', 'none');     //Скрываем 2-ой и 3-ий списки в форме аутентификации

 $('#sp3').parent().css('display', 'none');

 

$("#registr").overlay({       // Инициализация регистрационной формы

 onBeforeLoad: function() {

 // $("#myform1").validator().destroy();

 // $("#myform2").validator();

 $("#logdb").overlay().close();

 $('#log1').val("");

 $('#pas1').val("");

 },

 mask: {  color: '#fff',

    loadSpeed: 200,

    opacity: 0.65

     },

 });

$("#myform2").submit(function(e) {   // Кнопка submit в регистрационной форме

 var city = $('#city').val();

 var state = $('#state').val();

 var street = $('#street').val();

 var log = $('#log2').val();

 var name = $('#name').val();

 var pas = $('#pas2').val();

 //var sysname=$('#sp1').val();

 //alert(sysname);

 

 if ((log!="")&&(pas!="")) {

  $("#registr").overlay().close();

  $.ajax({    type:'GET',

       url:'index2.php',

       data: "col=insert into data_users (user_id,home_city,home_state,home_street,login,name,password,sysname,domain,subdomain) "

        +"values (data_us_seq.nextval,'"+city+"','"+state+"','"+street+"','"+log+"','"+name+"','"+pas

        +"','Medicine','Diagnostics','Skin')",

       timeout: 3000,

       success: function(data){

        alert('User is added!');

        

       },

      });

 }

  return e.preventDefault();

 });

$("#myform1").submit(function(e) {     // Кнопка submit в аутентификационной форме

 var log = $('#log1').val();

 var pas = $('#pas1').val();

 var sysname = $('#sp1').val();

 var domain = $('#sp2').val();

 var subdomain = $('#sp3').val();

 //alert("("+log+") ("+pas+")");

 if ((log!="")&(pas!=""))

 {

  $.ajax({    type:'GET',

       url:'index1.php',

       data: "tag=a&col=select user_id from data_users "+

           "where UPPER(sysname)=UPPER('"+sysname+"') and UPPER(domain)=UPPER('"+domain+"') "+

           "and UPPER(subdomain)=UPPER('"+subdomain+"') and UPPER(login)=UPPER('"+log+"') and password='"+pas+"'",

       timeout: 3000,

        async: false,

       success: function(data){

        //alert(data);

        //if (data != "")

        // {

          $("#logdb").overlay().close();

          //alert('Welcome!');

          document.location.href ='patients.htm?Name='+sysname+'&ID='+data+'&Domain='+domain+'&Subdomain='+subdomain;

        // }

        //else { alert('Неверный логин/пароль'); }

        $('#log1').val("");

        $('#pas1').val("");

       },

      });

  

 }

 return e.preventDefault();

 });

 $("#logdb").overlay({             // Инициализация аутентификационной формы

   onBeforeLoad: function() {

     //$("#myform1").validator();

     //$("#myform1").validator().submit(function(e){

     // alert(e.html());

     //});

     /*$("#myform1").data("validator").onSuccess(function(e, els) {

      //alert(els.html());

      

      // we don't want to submit the form. just show events.

      return true;

     });*/

     $.ajax({

      type:'GET',

      url:'index1.php',

      data: 'tag=option&col=select distinct sysname from decision where LENGTH(sysname)=9',

      timeout: 3000,

      success: function(data){

       //alert(data);

       $('#sp1').html("<option value='Please fix this value'>Choose Knowledge base</option>"

        +"<option>"+data+"</option>");

      },

     });

     

   },

 });

 

 $('#sp1').change(function() {      // Выбор 1-ого списка

  $('#sp2').parent().css('display', 'block');

  $.ajax({

      type:'GET',

      url:'index1.php',

      data: "tag=option&col=select distinct domain from decision where sysname='"+$('#sp1 option:selected').text()+"'",

      timeout: 3000,

      success: function(data){

       $('#sp2').html("<option value='Please fix this value'> Choose Domain </option>"+"<option>"+data+"</option>");

      },

     });

 });

 $('#sp2').change(function() {    // Выбор 2-ого списка

  $('#sp3').parent().css('display', 'block');

  $.ajax({

      type:'GET',

      url:'index1.php',

      data: "tag=option&col=select distinct subdomain from decision where sysname='"+

        $('#sp1 option:selected').text()+"' and domain='"+

        $('#sp2 option:selected').text()+"'",

      timeout: 3000,

      success: function(data){

       $('#sp3').html("<option value='Please fix this value'>Choose Subdomain </option>"+"<option>"+data+"</option>");

      },

     });

 });

$("#myform1").bind("onFail", function(e, errors)  {   //    Красный кант

 

// we are only doing stuff when the form is submitted

 if (e.originalEvent.type == 'submit') {

 // loop through Error objects and add the border color

  $.each(errors, function()  {

   var input = this.input;

   input.css({borderColor: 'red'}).focus(function()  {

    input.css({borderColor: '#444'});

   });

  });

 }

});

 

 

 $.tools.validator.fn("[minlength]", function(input, value) {

  var min = input.attr("minlength");  

  return value.length >= min ? true : {

  en: "Please provide at least " +min+ " character" + (min > 1 ? "s" : ""),

  };

   });

$('.close').click(function(){}); // Кнопка "Закрыть"

   });



 

Другие похожие работы, которые могут вас заинтересовать.
12191. РАЗРАБОТКА И ВЕДЕНИЕ ХРАНИЛИЩА ДАННЫХ ДЛЯ СИСТЕМ ПОДДЕРЖКИ ПРИНЯТИЯ РЕШЕНИЙ 79.68 KB
  Целью работы является повышение эффективности обработки и хранения больших объемов информации за счет использования технологии хранилищ данных.
9098. СУБД MS Access. Работа с данными таблицы. Создание форм 622.88 KB
  Правка данных и печать формы. Формы. Процесс создания новой формы аналогичен созданию таблицы т. надо просто выбрать объект базы данных Формы – Создать и далее в диалоговом окне Новая форма выбрать режим создания формы.
1828. Критерий принятия решений 116.95 KB
  Критерий принятия решений – это функция, выражающая предпочтения лица, принимающего решения (ЛПР), и определяющая правило, по которому выбирается приемлемый или оптимальный вариант решения.
9877. Создание пользовательских баз данных в СУБД Access 290.11 KB
  Создание пользовательских баз данных в СУБД ccess посвящена созданию базы данных для учета и обработки информации по деловой документации предприятия частного бизнеса. Разработанная база данных будет использоваться в делопроизводстве предприятия. Использование данной базы данных позволяет сократить время требуемое на подготовку отчетов уменьшить непроизводительные затраты что дает для частного предприятия прямой экономический эффект...
10997. Психологические аспекты принятия решений 93.55 KB
  МЕТОДИЧЕСКАЯ РАЗРАБОТКА для проведения лекции № 9 по дисциплине УПРАВЛЕНЧЕСКИЕ РЕШЕНИЯ Тема 9: Психологические аспекты принятия решений Для студентов специальности: 080507 Менеджмент организации Одобрена на заседании Методического совета института...
20690. СУБД Access база данных Музыкальная школа 448.49 KB
  Существует несколько разновидностей систем управления базами данных СУБД одни ориентированы на программистов другие - на обычных пользователей. Она позволяет не прибегая к программированию с легкостью выполнять основные операции с БД: создание редактирование и обработка данных. Microsoft ccess служит удобным инструментом для ввода анализа и представления данных и обеспечивает высокую скорость разработки приложений.
7980. Процесс принятия и реализации управленческих решений 24.35 KB
  При возникновении и определении проблемы необходимо ответить на следующие вопросы: В чем суть проблемы Где возникла проблема объект проблемы бригада оборудование коллектив С кем связана проблема субъект проблемы социальный или интеллектуальный ее элемент С чем связана проблема связи проблемы Для чего необходимо решать проблему цель решения проблемы Понятие решение в научной литературе трактуется поразному. Основные компоненты управленческого решения: множество возможных вариантов; нормативный документ...
11100. Анализ процесса принятия управленческих решений 15.26 KB
  Принятие управленческих решений в условиях активизации управленческого мышления. Анализ процесса принятия управленческих решений. Деятельность руководителя в повышении эффективности принятия решений. Проанализировать процесс принятия управленческих решений.
10964. Анализ задач и методов принятия решений (ПР) 46.89 KB
  Для других людей мотивы принятия решения могут быть и вовсе неясными. Поэтому с целью придания ясности следует найти численную меру для определения того насколько каждое из решений является подходящим. Руководителю фирмы требуется решить какую программу для управления предприятием следует приобрести. Главная цель – выбор наилучшей программы для управления предприятием.
10567. Технология разработки и принятия управленческих решений 124.08 KB
  Методы моделирования и оптимизации решений Методы моделирования называемые также методами исследования операций базируются на использовании математических моделей для решения наиболее часто встречающихся управленческих задач. Количество конкретных всевозможных моделей почти также велико как и число проблем для решения которых они разработаны. Очевидно что возможность прогнозировать действия конкурентов существенное преимущество для любой коммерческой организации. Первоначально разработанные для военностратегических целей модели...
© "REFLEADER" http://refleader.ru/
Все права на сайт и размещенные работы
защищены законом об авторском праве.