Выполнение запросов на чтение баз знаний и данных из кода агентов
Введение
В документе описывается технология выполнения запросов к графовым базам знаний/данных и работы с их результатами в коде агентов платформы.
⚠ Для понимания данного документа необходимо ознакомиться с документом Конструирование и выполнение запросов на чтение баз знаний и данных.
⚠ В настоящее время поддерживаются только запросы на чтение.
Использование механизма запросов состоит из двух этапов:
- на первом этапе разработчик агента/решателя формирует запрос/-ы к базе/-ам знаний определённого типа (созданным на основе некоторой метаинформации или их группы)
- на втором этапе происходит выполнение этих запросов для выбранного информационного ресурса (ресурсов), сохранение полученных данных и их использование (для просмотра и т.п.)
Для реализации первого этапа программист должен выполнить формирование инфоресурса запроса с помощью общих методов формирования инфоресурсов, доступных через API. Здесь работа с этими методами рассматриваться не будет.
Выполнение запросов
Выполнение запроса возможно только, если полны три подграфа в исполняемом запросе:
- подграф, описывающий формальные параметры запроса
- подграф, описывающий тело запроса
- подграф, задающий описание фактических параметров запроса (под выбранной вершиной "выполнение")
Выполнение запроса доступно через вызов одного из методов класса Agent:
/**
* Исполнить запрос (вычислить его уже готовое "выполнение" - со сформированными параметрами)
* @param queryExecutionHead понятие, являющееся корнем подграфа, описывающего выполнение запроса (экземпляр мета-вершины "выполнение")
* @param caller вызывающий агент (this)
* @return понятие, являющееся корнем подграфа, описывающего результат выполнения запроса
* @throws StorageException ошибка при работе с хранилищем инфоресурсов
*/
public IConcept evaluateQuery(IConcept queryExecutionHead, Object caller)
throws StorageException;
/**
* Исполнить запрос, сформировав новое выполнение с параметрами
* @param queryHead понятие, являющееся корнем подграфа, описывающего запрос
* @param inforesourceParams параметры-инфоресурсы
* @param miscParams прочие параметры
* @param caller вызывающий агент (this)
* @return понятие, являющееся корнем подграфа, описывающего результат выполнения запроса
* @throws StorageException ошибка при работе с хранилищем инфоресурсов
*/
public IConcept executeQuery(IConcept queryHead, Map<String, IInforesource> inforesourceParams, Map<String, Object> miscParams, Object caller)
throws StorageException;
Исполнение запроса состоит в его интерпретации путём вычисления термов и формул на основе заданных значений параметров и содержимого базы (баз) знаний и сохранение полученного значения в поддерево выполнений (в поддереве некоторого выполнения, создаваемом в первом случае вручную, а во втором – автоматически).
Результат работы метода – вершина, являющаяся корнем подграфа, описывающего результат выполнения запроса, то есть имеющая метапонятие "результат". Такая вершина создаётся автоматически (с очерденым порядковым номером - так как в метаинформации использован спецификатор ~seq). В случае вызова второго метода также выше данной вершины (начиная с корневой вершины запроса) формируются экземпляры вершин "выполнения" (если она отсутствовала, иначе - используется существующая), "выполнение" (с именем "autogenerated execution"). Под экземпляром вершины "результат" формируется вершина, содержащая само полученное значение (по одному из доступных метапонятий – см. выше). Для того, чтобы "добраться" до вершины с полученным значением необходимо выполнить:
IConcept resultValueConcept = executeQuery(...).getSuccessor("результаты / 1", this).getDirectSuccessors[0];
Далее с результатом необходимо работать разными способами, в зависимости от его типа (он известен разработчику агента при написании кода):
Важно отметить, что инфоресурс, хранящий исполняемый запрос, должен быть подключён в решатель (как собственный) или сервис (как выходной), чтобы быть доступным для модификации при выполнении БП.
При возникновении ошибки при вычислении результата запроса будет создано исключение типа StorageException, с указанием подробностей ошибки в его тексте.
Конструктор запросов
Процесс вычисления запроса состоит в:
- формировании пользователем вершины "выполнения" у запроса (если таковой ещё нет)
- формировании под вершиной "выполнения" пользователем новой вершины по метапонятию "выполнение" (с заданием некоторого имени, отражающего суть этого выполнения) – при необходимости задания нового массива входных данных, а при отсутствии такой необходимости можно использовать ранее созданную вершину с таким метапонятием
- формировании ниже описания значений фактических параметров (для инфоресурсов и данных, если они есть) – причём все имена параметров должны быть зависимо-склонированы от имён формальных параметров, указываемые ссылками на корень целевые инфоресурсы должны быть сформированы по указанным в формальных параметрах метаинформациям, а значения данных должны соответствовать указанным в формальных параметрах типам
- формировании под вершиной "выполнения" пользователем новой вершины по метапонятию "результаты", а в случае повторного использования выполнений некоторого запроса можно использовать ранее созданную вершину с таким метапонятием
- отправке пользователем команды на вычисление результата запроса (по нажатию порождения "результат")
- выполнении конструктором вычисления результата запроса (это может быть длительный процесс, возможно, окно конструктора станет неактивно)
- отображении результата проверки (в момент, когда пользователь, обновит состояние конструктора, а результат проверки уже получен)
Примеры
Рассмотрим предметную область Медицина.
Пример 1
Одной из баз знаний является База наблюдений. В этом инфоресурсе описываются группы признаков, их имена и указываются их допустимые значения. Для изучения наполнения базы наблюдений пользователь может сформировать запрос на извлечение всех признаков, находящихся в некоторой группе, например, "Жалобы":
Ниже представлена модель онтологии базы наблюдений:
Онтология наблюдений
{
~setmm ~new группа признаков
{
~setmm ~new -> группа признаков;
~setmm ~new признак
{
~one ~new нижняя граница [real]
~one ~new верхняя граница [real]
}
}
}
Для описания запросов формируется отдельный целевой инфоресурс (по метаинформации "Язык описания запросов").
Сформулируем запрос более формально: найти все вершины с метапонятием "признак" под всеми вершинами с меткой "Жалобы" и метапонятием "группа признаков". Написание такого запроса делится на три части:
- указание на необходимость нахождения всех вершин с метапонятием "группа признаков"
- извлечь из них все те, у которых метка = "Жалобы"
- под всеми найденными вершинами найти все вершины с метапонятием "признак" (на любом "расстоянии" от вершин "Жалобы")
- вернуть объединение полученных множеств
Такой запрос с применением предложенного языка задаётся "снизу-вверх" следующим образом:
Примеры запросов <<< Платформа IACPaaS/Ядро платформы/Язык описания запросов
{
запрос [Извлечь жалобы из БН] {
формальные параметры {
инфоресурсы {
имя параметра [База Наб] {
инфоресурс [-> Онтология базы медицинской терминологии и наблюдений$;]
}}
данные {}
}
тело запроса {
терм {
квантор объединения {
терм-множество {
множество соответствующих мета-пути вершин {
начало пути {
переменная [жалобы] {
терм-множество {
квантор интенсиональности {
формула {
равенство {
левая часть {
терм {
метка вершины {
терм {
переменная [группы признаков] {
терм-множество {
множество соответствующих мета-пути вершин {
начало пути {
вершина {
инфоресурс [-> Онтология базы медицинской терминологии и наблюдений$/.../Группа признаков;]
область выбора [<- Примеры запросов$/Извлечь жалобы из БН/формальные параметры/инфоресурсы/База Наб;]
}}}}}}}}}
правая часть {
терм {
строковая константа ["Жалобы"]
}}}}
переменная [-> Примеры запросов$/Извлечь жалобы из БН/тело запроса/терм/квантор объединения/терм-множество/множество соответствующих мета-пути вершин/начало пути/жалобы/терм-множество/квантор интенсиональности/формула/равенство/левая часть/терм/метка вершины/терм/группы признаков;]
}}}}
конец пути {
элемент пути [1] {
инфоресурс [-> Онтология базы медицинской терминологии и наблюдений$/.../Группа признаков/Признак;]
}}}}
переменная [-> Примеры запросов$/Извлечь жалобы из БН/тело запроса/терм/квантор объединения/терм-множество/множество соответствующих мета-пути вершин/начало пути/жалобы;]
}}}
выполнения { ... }
}
}
Особенности составления данного запроса следующие:
- в качестве формального параметра введён "База Наб" и под ним указан тип значений этого параметра – поставлена ссылка на корень инфоресурса "Онтология базы медицинской терминологии и наблюдений"
- далее при формировании "выполнения" задаётся значение соответствующего фактического параметра:
- в качестве имени фактического параметра сделан зависимый клон его имени из подграфа "формальные параметры"
- в качестве значения указан инфоресурс "База наблюдений" – поставлена ссылка на корень этого инфоресурса
- "данные" не используются и не указываются среди параметров (вершины "данные" в формальных и в фактических параметрах созданы и не имеет содержимого)
- из базы наблюдений выбираются ВСЕ вершины, которые могут иметь метку "жалобы" и метапонятие "группа признаков", так как нельзя быть уверенным в том, что некоторый инфоресурс содержит лишь одну вершину, удовлетворяющую каким-то условиям – всегда надо оперировать множеством
- для перехода от вершины "Жалобы" к вершинам, сформированным по метапонятию "признак", используется "окончание пути" и не используется "продолжение пути", так как такие вершины могут быть на произвольном удалении от вершины "Жалобы"
К особенностям исполнения запроса можно отнести, то что его результатом является "множество" (вершина, создаваемая под вершиной "результат"), под которым сформированы ссылки на искомые вершины базы наблюдений (в составленном примере база наблюдений содержит 2849 признаков, а запрос вычислил 205, находящихся в группе "Жалобы").
Ниже представлен интерфейс Конструктора запросов с телом запроса, и его выполнением.
Рис.1. Поиск всех "Жалоб"
Пример 2
Другой задачей, стоящей перед мед. персоналом, может быть вычисление коэффициентов, характеризующих пациентов. Рассмотрим вычисление так называемого "Индекса массы тела". Формула для его вычисления следующая: ИМТ = вес / рост².
Сформулируем запрос на это вычисление формально: разделить вес на произведение роста и роста.
Такой запрос задаётся так:
Примеры запросов <<< Платформа IACPaaS/Ядро платформы/Язык описания запросов
{
запрос [ИМТ] {
формальные параметры {
инфоресурсы {}
данные {
имя параметра [вес] {
["вершина"]
}
имя параметра [рост] {
["вершина"]
}}}
тело запроса {
терм {
частное {
делимое {
терм-число {
метка вершины {
терм {
параметр [<- Примеры запросов$/ИМТ/формальные параметры/данные/вес;]
}}}}
делитель {
терм-число {
произведение {
сомножитель [1] {
терм-число {
метка вершины {
терм {
параметр [<- Примеры запросов$/ИМТ/формальные параметры/данные/рост;]
}}}}
сомножитель [2] {
терм-число {
метка вершины {
терм {
параметр [<- Примеры запросов$/ИМТ/формальные параметры/данные/рост;]
}}}}}}}}}}
выполнения {...}
}}
Особенности составления данного запроса следующие:
- "инфоресурсы" среди формальных и фактических параметров не задаются (можно будет вычислять запрос на разного типа инфоресурсах, описывающих пациентов – архивах историй болезни, электронных медицинских картах и т.п.)
- в качестве формальных параметров введёны два "данных": "рост" и "вес" с типом значений "вершина", так как конкретные вершины, описывающие рост и вес пациента должны быть выбраны из некоторого инфоресурса с историей болезни перед исполнением запроса (и в каждом исполнении могут быть разные)
- далее при формировании "выполнения" задаётся значение соответствующих фактических параметров:
- в качестве имён фактических параметров "рост" и "вес" сделаны зависимые клоны имён соответствующих параметров из подграфа "формальные параметры"
- в качестве значения пользователь устанавливает ссылки на вершины со значением роста и веса
Ниже представлен интерфейс Конструктора запросов с телом запроса, и его выполнением.
Рис.2. Вычисление "ИМТ"
Пример 3
Ещё одной задачей, которая имеет более широкую область применения, является поиск вершин в базе знаний. В общем случае можно сформулировать запрос на поиск вершин так: "среди всех вершин инфоресурса выбрать те, метка которых содержит заданную строку (без учёта регистра)".
Сформулируем запрос на такую выборку формально (выбрав искомую подстроку "боль"): перебрать все вершины заданного инфоресурса и вернуть такое их подмножество, для каждой вершины которого её метка соотетствует регулярому выражению, описывающему правило "включает подстроку 'боль' независимо от регистра букв".
Такой запрос (исключая результаты выполнений) задаётся так:
Примеры запросов <<< Платформа IACPaaS/Ядро платформы/Язык описания запросов
{
запрос [поиск боль] {
формальные параметры {
инфоресурсы {
имя параметра [ИР] {
инфоресурс [-> инфоресурс$;]
}}
данные {}
}
тело запроса {
терм {
квантор интенсиональности {
переменная [вершина из ИР] {
терм-множество {
все вершины {
область выбора [<- Примеры запросов$/поиск боль/формальные параметры/инфоресурсы/ИР;]
}}}
формула {
соответствие регулярному выражению {
строка {
терм-строка{
метка вершины{
терм {
переменная [-> Примеры запросов$/поиск боль/тело запроса/терм/квантор интенсиональности/вершина из ИР;]
}}}}
регулярное выражение [".*Б|бО|оЛ|лЬ|ь.*"]
}}}}}
выполнения {
выполнение [1] {
фактические параметры {
инфоресурсы {
имя фактического параметра [<- Примеры запросов$/поиск боль/тело запроса/терм/квантор интенсиональности/вершина из ИР/терм-множество/все вершины/ИР;] {
инфоресурс [-> База медицинской терминологии и наблюдений$;]
}}
данные {}
}
результаты {...}
}}}}
Особенности составления данного запроса следующие:
- вместо онтолого-ориантированного терма "множество соответствующих мета-пути вершин" используется онтолого-независиый терм "все вершины" (при работе с по конкретным онтологиям следует избегать использования данного терма)
- для поиска в метке вершины подстроки "боль" (независимо от регистра) используется регулярное выражение ".*Б|бО|оЛ|лЬ|ь.*", где:
- .* – любая подстрока
- Б|бО|оЛ|лЬ|ь – последовательность из 4 символов, где на первом месте либо "Б", либо "б" и т.д.