вторник, 30 августа 2011 г.

Aiemp Framework. Введение.


В этой статье я напишу про свою разработку, платформу метапрограммирования искусственного интеллекта Aiemp Framework. Это свободное ПО, написанное на языке C# для платформы .NET Framework 4.0, позволяющее создавать экспертные системы (ЭС) и оболочки ЭС, а затем интегрировать их с вашей программой. Я расскажу о мыслях, мотивировавших меня потратить массу свободного и несвободного времени на все затронутые стадии жизненного цикла Aiemp. Я перечислю цели проекта, поясню название и определю его настоящие и будущие возможности, а в конце статьи обозначу текущий статус проекта.



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

А загорелся я после того, как познакомился с довольно старой оболочкой ЭС, именуемой «GURU». Меня восхитили ее широкие интеллектуальные возможности, такие как мощная поддержка нечеткой логики. Но, к сожалению, эта программа работала под DOS и была очень стара, что сводило на нет любые попытки интеграции ее с современным ПО. В более современных оболочках ЭС (например, в модификациях CLIPS) я не нашел точно таких же возможностей (плохо искал, да). Поэтому решил написать оболочку ЭС, дублирующую функционал GURU. Однако со временем это желание превратилось в нечто большее.

Количество человек в команде для желания начать разработку не играло роли, а возможно даже ускоряло разработку. Мне не нужно было писать ТЗ, тщательно вырисовывать UML, ведь требования и интерфейсы я мог свободно менять в процессе разработки.

Но то, что я мог их менять, еще не значит то, что должен был. Когда я сразу с головой окунулся в проект, я понял, что далеко так не уплыву. И не уплыл, самый первый вариант программы еще на ранних стадиях показал свою неработоспособность. В итоге я выбросил весь написанный код, но мое представление о том, каким будет Aiemp, стало гораздо более четким. Можно сказать, что эта «проба пера» была прототипом, который выявил недостатки в требованиях и интерфейсах.

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

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


Цели разработки
Здесь я перечислю основные цели, которые должна была достигнуть (и, надеюсь, вот-вот достигнет!) платформа Aiemp Framework. Некоторые из этих целей менялись в процессе разработки, другие были определены сразу. Перечисляю их, начиная с наиболее важных.

Цель №1: Обеспечить тесную интеграцию экспертной системы с кодом, который ее использует. Экспертная система может либо непосредственно использоваться человеком (оператором), либо самостоятельно извлекает данные из внешней среды (например, с помощью датчиков), либо ею управляет другая часть программы, которая определяет начальные данные и запрашивает результат (например, какое решение принять или какой прогноз более вероятен).

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

Для Aiemp интеграцию осуществить проще, поскольку она выполняется не между двумя различными приложениями, а в пределах одного и того же – Aiemp становится частью вашего приложения.

Рис. 1. Из выражений экспертной системы обращение к другим подсистемам вашего приложения идентично тому, что вы выполняете в любом другом месте этой программы.

Цель №2: Обеспечить расширяемость. Можно создавать расширения, не изменяющие исходный код Aiemp, но привносящие еще «больше жизни» в платформу: новые типы переменных, новые метаданные (данные, описывающие знания), стратегии вычисления факторов уверенности и создания конфликтных наборов, переопределение средств ввода/вывода, или даже определение собственного алгоритма выполнения процедуры логического вывода. Я реализовал за неимением времени лишь прямой логический вывод – forward chaining (от фактов), – но никто не мешает сделать обратный логический вывод (от целей) и интегрировать его в Aiemp, не изменяя при этом ни строчки его исходного кода.

Рис. 2. Расширение для Aiemp в терминах экспертных систем
аналогично созданию своей оболочки ЭС.

Цель №3: Определить гибкий подход в создании базы знаний. Единый подход к определению четких и нечетких данных (под последним подразумевается нечеткая логика – Fuzzy Logic), применимость к различным предметным областям. Другой способ достижения гибкости объясняется под заголовком «Метапрограммирование» ниже.

Рис. 3. Одинаковый подход к работе с данными, независимо от их представления. Выражение "A cf B" означает, что задано значение A с фактором уверенности B (в интервале (0;100] ).


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

Первый способ: PLINQ может использоваться для параллельной фильтрации базы знаний, происходящей, например, при составлении конфликтного набора, для выбора подходящих на текущем шаге продукций (однако можно настроить среду выполнения на отключение данной возможности). Это ускоряет выполнение единственной процедуры логического вывода, причем даже для небольшой базы знаний ускорение на 4-х ядерном процессоре достигает до полутора раз (чем больше база знаний, тем быстрее будут вычисления в несколько потоков относительно времени вычислений в один поток).

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

Рис. 4. Асинхронное вычисление пакета задач реализовано простым, но мощным API.

Цель №5: Создать свободное программное обеспечение. Вы не должны думать о том, сможете ли вы использовать мой продукт из-за его лицензионных ограничений. Поэтому Aiemp выпускается по BSD-лицензии.

Рис. 5. Используйте Aiemp в своих проектах без ограничений.


Цель №6: Обеспечить небольшой размер основных модулей (ядра) и, как следствие, сделать Aiemp независимым от других продуктов. Вы можете модифицировать Aiemp под свои нужды (написать расширение, изменить исходный код) или использовать его в более крупной системе, но вы не должны переносить в эту систему вместе с ядром Aiemp компоненты сторонних производителей, используемые в нем. Поэтому таких зависимостей нет.

Рис. 6. Миниатюрный размер дистрибутива приложения
особенно важен для мобильных решений.


Цель №7: Обеспечить переносимость ядра Aiemp. Оно должно работать не только под .NET Framework (Windows), но и под Mono (Windows, Mac OS X, Linux), частично под .NET Compact Framework (Windows Phone), и возможно под другими реализациями CLR (Common Language Runtime). Однако указанные среды выполнения должны быть совместимыми с версией .NET Framework 4.0, более ранние версии не поддерживаются.

Рис. 7. Кроссплатформенность достигается за счет поддержки нескольких CLR.

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

Aiemp – это платформа метапрограммирования искусственного интеллекта. На английском звучит как «Artificial Intelligence Expert Metaprogramming Platform» (слова не очень сочетаются, но смысл передает). Разберем, что обозначают эти слова по отдельности.

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

Aiemp Framework – это именно платформа, она представляет базу знаний как иерархию абстрактных классов, от которых можно получить конкретную реализацию экспертной системы с помощью наследования, определять поведение которой можно с помощью задания свойств и переопределения виртуальных методов. Кроме того используется собственная расширяемая система типов переменных, имеются и многие другие возможные точки расширения функциональности. Aiemp предоставляет не пустой «скелет», но и конкретную функциональность, такую как алгоритм процедуры логического вывода и система объяснения решений. Все это вместе делает из программы (приложения или компоненты), созданной с помощью платформы Aiemp, полноценную экспертную систему. Описанные здесь возможности инкапсулированы в части ядра Aiemp, именуемой средой выполнения Aiemp.Shell.

Рис. 8. Классы каркаса Aiemp.Shell (сверху) и классы вашей ЭС (снизу).
Это упрощенная UML-диаграмма.

Метапрограммирование
Исторически программы, которым нужно было поведение, подобное экспертным системам, реализовывали его самостоятельно, и оно было неотъемлемой частью этого ПО. Но потом было решено отделить интеллектуальную составляющую от остальной части программы, так возникло разделение на базу знаний (изменяемую сущность) и оболочку экспертной системы (неизменную сущность).

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

Метапрограммирование в Aiemp заключается в том, что при составлении базы знаний вы не используете модель, предлагаемую каркасом Aiemp.Shell, напрямую. Вы динамически составляете этот каркас из сущностных классов модели прототипа базы знаний KBP (Knowledge Base Prototype). Т.е. вместо наследования от абстрактных классов каркаса вы создаете экземпляр сущностного класса KBP и настраиваете его свойства и поведение с помощью свойств класса KBP. Код методов заменяется обычной строкой, содержащей выражение на языке C# (в потенциале на любом языке, поддерживаемом CTS (Common Type System), например на Visual Basic). Позже строки выражений обрабатываются препроцессором.

Сущностные классы объединяются в иерархию (модель), достигаемую не с помощью наследования, а через композицию, что опять же повышает гибкость. Классы модели имеют настраиваемые операции, такие как каскадное удаление и переименование, затрагивающие всю модель. Для модели определяются ошибки и предупреждения, возникающие при неверной установке свойств. Если проверки успешно пройдены, то выполняется преобразование модели в иерархию независимых от языка классов (похожую на Code DOM), а затем и в текстовое представление классов на конкретном языке, которое передается компилятору языка (компилятор C# входит в состав .NET Framework). Таким образом, осуществляется генерация исходного кода для KBP, а затем и его компиляция в библиотеку классов, называемую модулем искусственного интеллекта AIU (Artificial Intelligence Unit).

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

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


Рис. 9. Раннее связывание вашего приложения со сгенерированным AIU.


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


Рис. 10. Позднее связывание вашего приложения с AIU.

Часть Aiemp Framework, отвечающая за метапрограммирование, называется Aiemp.Core и не зависит от наличия среды выполнения Aiemp.Shell, ответственной за выполнение скомпилированных модулей AIU. Т.е. в случае раннего связывания вашей программы с AIU вам не нужен Aiemp.Core, что позволяет сэкономить на размере дистрибутива программы. Если вы делаете редактор базы знаний, то вам не нужен Aiemp.Shell для создания AIU. Но для позднего связывания с AIU, описанного выше, понадобятся оба модуля Aiemp.Core и Aiemp.Shell.

Рис. 11. Метапрограммирование Aiemp.Core упрощает структуру каркаса
и делает ее более гибкой. Это упрощенная UML-диаграмма.

Искусственный интеллект
Системами искусственного интеллекта являются те экспертные системы (ЭС), которые вы можете создать средствами Aiemp Framework. Для каждой ЭС выполняется процедура логического вывода до тех пор, пока не будет определены все целевые переменные набора продукций с достаточной степенью определенности (т.е. с достаточно большим фактором уверенности). Эта процедура состоит в поиске порядка выполнения подходящих продукций (выражений «если-то-иначе»), наполняющих базу знаний.

Рис. 12. Упрощенная схема выполнения процедуры прямого логического вывода. Пунктиром отмечены альтернативные пути выбора продукций на соответствующих шагах.

Ниже описаны средства времени выполнения (т.е. средства Aiemp.Shell), задаваемые в процессе построения KBP (с помощью Aiemp.Core).


1. Нечеткая логика. Часть рабочей памяти представлена в виде совокупности переменных, каждая из которых имеет значение и тип (я определил следующие типы: Integer, Real, Decimal, String, Boolean, DateTime, TimeSpan). Значение может быть как четко определенным, так и нечетким, т.е. представленным в виде одной или более версий, каждая из которых имеет собственно значение и ассоциированный фактор уверенности.

Aiemp освобождает инженера по знаниям, составляющего KBP, от необходимости знать, является ли переменная четкой или же нечеткой. Кроме того, учитывается не только неопределенность данных (значений переменных), но и неопределенность знаний (в конкретной продукции вы можете быть уверены только на 70%, а не на все 100%), а также неопределенность условий (в выражении «если» продукции могут участвовать нечеткие данные, которые налагают свой «отпечаток» на факторы уверенности переменных, устанавливаемых в выражениях «то» и «иначе»). Все это прозрачно происходит «за кулисами», поэтому вы можете сосредоточиться на особенностях предметной области ЭС, а не на способе представления данных в выражениях конкретной продукции.

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


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

Вы можете определить стратегии вычисления факторов уверенности, а именно их пересечения (умножения CF1*CF2, операции И) и объединения (сложения CF1+CF2, операции ИЛИ), причем можно установить различные стратегии для выражений условия и заключений продукции, а также для влияния других факторов (неуверенность в продукции и в условном выражении).

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

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


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

Например, вы можете определить, что значение некоторой переменной устанавливается в соответствии с информацией, полученной от вашего собственного поставщика данных (определяющего, например, интерфейс доступа в Private Cloud). Для этого даже не нужно писать расширение Aiemp, просто включите компоненту с вашим поставщиком в список ссылок AIU и используете собственные классы напрямую, без proxy-интерфейсов. В этом и есть интеграционные преимущества Aiemp Framework.
// -- это выражение If для некоторой продукции
$A < 0
// -- это выражение Then для этой же продукции
// обращаемся к некоторому внешнему API-интерфейсу напрямую
int externalValue = MyEnterprise.ExternalPrivateCloud.GetValue("A");
// мы уверены в полученном значении с фактором уверенности 50%
$A = CF(externalValue, 50);


4. Выражение Find для переменных. Вы можете задать выражение, цель которого – определить первоначальное значение переменной (например, запросив его у пользователя через консоль или получив из веб-службы). Момент выполнения этого выражения не определен так же, как и то, будет ли оно вообще выполнено. Другими словами оно выполняется лишь при необходимости, и вы освобождаетесь от самостоятельного определения этой необходимости.
// -- это выражение Find для переменной A
// мы можем установить значение напрямую:
$A = 5;
// то же самое:
Value = 5;
// или, запросив его у пользователя через консоль:
Value = Input(VariableType, "variable A"
);
// то же самое:
$A = Input(
"Integer""variable A"
);
// и еще раз то же самое:
InputThis("variable A");


5. Обнаружение и разрешение тупиков и зацикливаний в процедуре логического вывода. Любое изменение состояния рабочей памяти (присваивание переменной, включение новой предметной области и т.п.) записывается в виде атомарной операции с возможностью отката к предыдущему состоянию (транзакции). Если возникла ситуация, в которой отсутствуют невыбранные продукции в конфликтном наборе (тупик), либо обнаружена повторяющаяся последовательность продукций (зацикливание), то выполняется откат всех изменений на один или несколько шагов назад и выбор уже другой продукции из конфликтного набора, что как бы переводит логический вывод на альтернативную ветку выполнения. Если все возможные ветки пройдены, то происходит завершение процедуры логического вывода с ошибкой: задача неразрешима. Конечно же, упомянутые проверки можно отключить, что ускоряет выполнение.

Рис. 14. Обнаружение и разрешение тупиковой ситуации.

Рис. 15. Обнаружение и разрешение зацикливаний.

6. Управление ходом логического вывода. В процессе написания выражений продукций вы можете решить, что логический вывод нужно завершить, или прекратить уточнение данных на текущем шаге, а может принудительно откатить на шаг назад и перевести вычисления на альтернативную ветку выполнения, или даже полностью перезапустить логический вывод, но использовать теперь уже другие исходные данные. Все это очень просто выполнить, вручную изменив текущее состояние выполнения логического вывода (т.н. Execution State).
// -- это выражение Then для некоторой продукции
if (rollbackConditionIsTrue)
// если выполнено некоторое наше условие, то
  // после завершения выполнения выражений продукции выполняется
  // откат на шаг назад и выбор альтернативной ветки выполнения
  RuleSet.Metadata["ExecutionState"] = "RollbackNow";
}

7. Метаданные знаний. Это сериализуемая иерархическая структура данных, описывающих каждое знание независимо от его типа (набор продукций, отдельная продукция, переменная, предметная область и др.). Стоит отметить, что описываемая структура не имеет отношения к метаданным CLR; однако, если учесть, что каждый новый экземпляр знания определяется отдельным типом, наследуемым от каркаса Aiemp.Shell, то можно считать понятия «метаданные типа» и «метаданные экземпляра» идентичными применительно к знаниям Aiemp.

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

Многие стратегии составления конфликтного набора используют метаданные для определения порядка выбора продукций. Их можно использовать для задания приоритета продукций в метапродукциях или выражениях пред- и постусловий продукций. Можно определить поставщик доступа для разделения прав чтения/записи к различным частям дерева метаданных, что и сделано для запрета изменения статистической информации о знаниях, собираемой средой выполнения, такой как количество успешных выполнений продукции, в коде выражений KBP. Таким образом, метаданные представляют удобный контейнер для реализации расширений Aiemp или задания некоторой логики в выражениях KBP.
// -- это может быть выражение инициализации для набора продукций
InfoProvider infoProvider;  // поставщик доступа для метаданных
if (!Metadata.ContainsNamespace("MySpace"))
// добавляем пространство имен в метаданные текущего знания
  Metadata.AddNamespace(
    "MySpace",
    ShellMetadata.UnlimitedValuesCount,
    out infoProvider);
  // создаем наши данные и изменяем их несколько раз
  Metadata["MySpace.SomeData"] = 1;
  Metadata["MySpace.SomeData"] = 2;
  Metadata["MySpace.SomeData"] = 3;
  // поставщик доступа ограничивает количество сохраняемых значений
  // для всех метаданных в пространстве имен
  infoProvider.ValuesLimit = 2;
  // принимаем новые ограничения
  // это удаляет самое раннее значение "1"
  Metadata.LimitValues();
  // выводим на экран последнее сохраненное значение "3"
  PrintLine("SomeData Value = {0}", Metadata["MySpace.SomeData"]);
  // выводим на экран предыдущие значения
  foreach (var item in Metadata.GetItem("MySpace.SomeData").OldValues)
  { // будет выведено одно предыдущее значение "2"
    PrintLine("SomeData OldValue = {0}", item.Value);
  }
}


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

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

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

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

9. Схожая базовая функциональность у всех выражений KBP. Можно узнать имя текущего знания, вызвав свойство Name; или получить пару «значение – фактор уверенности», вызвав функцию CF(value,confidenceFactor); вывести сообщение на консоль методом Print; запросить или модифицировать изменяющиеся параметры среды выполнения через свойство Environment (такие как задействованные предметные области или используемая стратегия выбора продукций из конфликтного набора). Все эти и многие другие операции вы задаете единообразно, независимо от того, в каком именно выражении KBP их используете.
// -- этот код работает в любом выражении набора продукций
// добавляем новую предметную область Domain1
RuleSet.KnowledgeDomains.Add("Domain1"string.Empty);
// помещаем Domain1 в список текущих предметных областей
Environment.CurrentKnowledgeDomains.Add("Domain1");
// выводим на консоль имя и описание текущего знания
PrintLine("{0}: {1}", Name, Description);
// увеличиваем значение переменной A на "5 cf 70"
$A += CF(5, 70);


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

Направления развития
Здесь я приведу несколько возможностей, которые сейчас отсутствуют в Aiemp, но уже запланированы для реализации в будущих версиях.
  • Графический редактор базы знаний (на WPF). Без него платформа может использоваться программистами, но не инженерами по знаниям, которые имеют более скромный опыт программирования. Тем более, с помощью GUI можно проще и быстрее создать ЭС с необходимой функциональностью.
  • Списки. Пока что единственный способ использовать массив однотипных данных переменной длины в базе знаний – задействовать метаданные знаний в качестве хранилища. Однако такой массив не подвержен принудительным изменениям рабочей памяти, таким как откаты и перезапуск среды выполнения, поэтому нужно создать списочные типы переменных.
  • Фреймы. Иерархическая модель организации нечетких данных в виде фреймов дает возможность лучше структурировать данные, а также производить поиск других фреймов по образцу. Эта модель должна прозрачно интегрироваться в текущую модель нечетких данных и систему типов, а также поддерживать откат изменений.
  • Динамическое создание переменных. Сейчас доступно определение новых предметных областей прямо в процессе исполнения процедуры логического вывода. Было бы хорошо таким же образом создавать переменные, вместо определения всех переменных заранее.
  • Удобство обмена нечеткими данными с внешними программными модулями. В настоящий момент для этого приходится передавать в AIU отдельно значение каждой версии и ассоциированный фактор уверенности. Также есть мысль унифицировать ввод данных из консоли и из внешних ресурсов, если консоль не задана (определена как Fake).
  • Определение пользовательских функций, принимающих и возвращающих нечеткие данные. Что будет, если попытаться вычислить логарифм некоторого нечеткого числового значения? Aiemp должен возвращать нечеткий числовой результат и позволять вам создавать новые сущности, определяющие такие функции.
  • Переделанная подсистема внешних ресурсов Aiemp.Resources. Я позаимствовал этот модуль из другой своей разработки, написанной три года назад, и это как раз тот случай, когда подсистему нужно переписать полностью, оптимизируя ее для использования в Aiemp Framework.
  • Локализация всех сообщений платформы (в т.ч. сообщений, описывающих исключения). Возможность использования английской и русской языковых версий Aiemp, сейчас доступна только русская версия.
  • XML-документация всех экспортируемых типов на английском языке.

Заключение

Итак, для чего же предназначена платформа Aiemp Framework?
  • Для создания экспертных систем, имеющих консольный пользовательский интерфейс (консолью может быть и красивое GUI-окошко, обладающее способностью вводить и выводить символьные строки, или даже веб-форма). 
  • Для создания экспертных систем, извлекающих данные из внешней среды (из базы данных, датчиков движения и т.п.) напрямую через API, определенный этой средой. 
  • Для создания экспертных систем, интегрированных в сложные системы и ведущих «диалог» с программной подсистемой, а не пользователем или внешней средой. 
  • Для создания оболочек экспертных систем, лучше адаптированных к определенной предметной области и реализующих дополнительный функционал. Это достижимо за счет расширяемости модулей Aiemp. 
Резюмируя, Aiemp Framework – это универсальная платформа для создания ЭС и оболочек ЭС средствами метапрограммирования.

Библиографический список
  1. Макконнелл С, "Совершенный код": Пер. с англ. – М.: Издательство «Русская редакция», 2011. – 896 стр. : ил. 
  2. Гамма Э., Хелм Р., Джонсон Р., Влиссидес Д. "Приемы объектно-ориентированного проектирования. Паттерны проектирования" – СПб: 2010. – 366 с. 
  3. Джексон П., "Введение в экспертные системы": Пер. с англ. – М.: ООО "И.Д. Вильямс", 2001. – 624 с. 
  4. Частиков А.П., Гаврилова Т.А., Белов Д.Л. "Разработка экспертных систем. Среда CLIPS" – СПб: "БХВ-Петербург", 2003. – 393 c.


Post Scriptum
В настоящий момент разработка находится на стадии третьей альфа-версии (Milestone 3), вслед за которой выйдет бета-версия (в ней уже будет вся описанная выше функциональность, кроме раздела «направления развития»). Исходный код будет выложен к моменту выпуска Milestone 3. В дальнейшем я планирую написать пост, более подробно затрагивающий применяемый механизм нечеткой логики и системы типов, а также несколько постов, демонстрирующих возможности Aiemp на простых примерах.


Твиттер Aiemp: @aiempnet

2 комментария:

  1. Здравствуйте, Сергей!
    Хотелось бы как-то связаться по поводу Вашего проекта. Алексей

    ОтветитьУдалить
  2. Алексей, добрый день. Можете написать ваш вопрос на почту alikin89@gmail.com

    ОтветитьУдалить