Главная arrow Робототехника arrow Возможности ООСУБД
Как начинался компьютер
Компьютерная революция
Двоичный код
Разработки военных лет
Интегральные микросхемы
Микрокомпьютер
Персоны
Сеть
Язык компьютера
Развитие ПО
Гибкие системы
Средства разработки
Информатика
Вычислительная наука
Операционные системы
Искусственный интеллект
Предыстория
Поиск
Знания и рассуждения
Логика
Робототехника
 

 
Возможности ООСУБД Печать

Системы искусственного интеллекта требуют наличия подсистем хранения и обработки данных и знаний. База знаний должна обеспечить хранение и обработку огромного количества информационных взаимосвязей. Этому требованию соответствуют базы данных/знаний построенные на основе сетевой модели данных. Одним из перспективных направлений позволяющих обеспечить хранение и обработку сложно структурированных данных и знаний являются объектно-ориентированные системы. Как было показано в объектно-ориентированные базы данных должны разрабатываться с учетом применения в системах искусственного интеллекта. В связи с этим разработка объектно-ориентированной системы управления сетевой базой данных/знаний специально предназначенной для применения в системах искусственного интеллекта является актуальной научной задачей. Целью данной работы является анализ внутренней архитектуры сетевой объектно-ориентированной базы данных/знаний и возможности ее применения в системах искусственного интеллекта.

Идентификация экземпляров

В СООБЗ Cerebrum применяются "мягкие" указатели. Идентификатор объекта можно рассматривать как указатель на объект в памяти системы. Однако от запуска к запуску указатель в памяти на объект, очевидно, не будет постоянен. Для того чтобы избежать необходимости модификации объектов в БД систему реализуют так, чтобы идентификатор объекта не зависел от времени. Это можно сделать по-разному, через индексы, двойную разадресацию ... В Cerebrum применяются мягкие идентификаторы объектов. В одном контексте адресации одному идентификатору всегда соответствует один и тот же объект. Тип данных для идентификатора объекта - Cerebrum.Runtime.NativeHandle. Размер идентификатора объекта - 32 бита. Поиск объекта в индексе по его идентификатору происходит в три этапа. 32 бита разбиваются на 12, 12 и 8 бит. По этим значением строится 3х уровневое дерево индексов. Коллекции объектов организованы на основании того же механизма. Коллекция представляет собой такой же индекс 12-12-8, который производит отображение одного идентификатора на другой идентификатор.

Важной особенностью СООБЗ Cerebrum является отличие в адресации объектов по сравнению со стандартом объектных баз данных ODMG [4]. В Cerebrum каждый объект, так же как и в ODMG адресуется с использованием мягкого указателя или ID объекта Cerebrum.Runtime.NativeHandle. Получение указателей на экземпляры объектов, внешних по отношению к некоторому текущему объекту, производится в пределах контекста текущего объекта. Объект может адресовать только те объекты, с которыми он установил связь. Каждый объект, связанный с текущим, имеет идентификатор. Каждый уникальный идентификатор определяет в пределах текущего объекта экземпляр связанного с ним объекта. В пределах текущего объекта каждый идентификатор может адресовать только один экземпляр. Однако важным отличием от ODMG является возможность иметь в пределах некоторого объекта несколько различных NativeHandle адресующих один и тот же экземпляр. В пределах некоторого заданного объекта несколько разных идентификаторов могут ссылаться на один и тот же экземпляр объекта. В отличие от ODMG, где каждый объект имеет только один уникальный идентификатор в Cerebrum один и тот же объект может иметь различные идентификаторы. Если рассмотреть не один экземпляр, а всю базу, то по аналогии с явлениями естественного языка синонимии и омонимии в СООБЗ Cerebrum возникает явления синонимии и омонимии идентификаторов объектов. В различных контекстах определяемых различными экземплярами объектов один и тот же идентификатор объекта NativeHandle может адресовать как разные экземпляры, так и один и тот же экземпляр. Это явление можно назвать омонимией объектных идентификаторов. Так же как и в естественном языке при омонимии один и тот же идентификатор в разных контекстах одной и той же базы данных может адресовать как различные, так и одинаковые экземпляры объектов. Как в одном и том же контексте, так и в разных контекстах различные идентификаторы могут ссылаться на один и тот же экземпляр объекта. В этом случае возникает явление синонимии объектных идентификаторов, когда один экземпляр может иметь в пределах базы множество различных идентификаторов - синонимов. Эту возможность удобно использовать для построения семантических и иерархических семантических сетей.

Сборка мусора

В настоящее время в СУСООБЗ Cerebrum работают 3 подсистемы сборки мусора. Первые две подсистемы обеспечивают сборку объектов в оперативной памяти, третья подсистема - в хранилище. Учитывая различные цели и требования, стоящие перед .NET Framework и Cerebrum, идеология системы сборки мусора в оперативной памяти значительно отличается. В .NET уничтожение объекта возможно только после того как не останется возможности его использования в текущем процессе. Это осуществляется определением достижимости этого объекта по указателям от корневых объектов. В отличие от этого в ядре Cerebrum сборка мусора в оперативной памяти осуществляется, когда исчерпана память допустимая для размещения объектов. В этом случае ненужные объекты вытесняются на устройство долговременного хранения. Первая подсистема сборки мусора встроена в Microsoft .NET Framework. Она используется в Cerebrum для сборки non-persistent пользовательских объектов. Для persistent объектов эта подсистема блокируется путем установки на такой объект ссылки из ядра ООБД. Вторая и третья подсистемы реализованы в ядре ООБД. Вторая подсистема сборки мусора служит для сохранения не используемых на данный момент экземпляров пользовательских persistent объектов. Эта подсистема работает на основе Win32 API размещения блоков памяти. Она отслеживает инстанциированные объекты и количество их блокировок. При блокировке/разблокировке обновляется список last recently used объектов. При превышении заданного количества размещенных блоков или максимального размера выделенной памяти эта подсистема пытается выгрузить в дисковое хранилище незаблокированные объекты. В первую очередь производится попытка выгрузить объекты, попавшие в хвост списка наиболее часто используемых объектов. Эта система размещения работает только для объектов ядра, сопровождающих пользовательские экземпляры. Инициировать сохранение пользовательских объектов вручную не нужно.

Наименее часто используемые объекты автоматически вытесняются на систему долговременного хранения, освобождая оперативную память. Поэтому в любой момент возможно принудительное вытеснение и разрушение любого незаблокированного пользовательского объекта. Если пользователь получил указатель на некоторый объект и не провел операцию блокировки, то сборщик мусора Cerebrum может посчитать этот объект неиспользуемым и принудительно вытеснить его из оперативной памяти. В результате по этому указателю в памяти будет находиться разрушенный экземпляр объекта. Для предотвращения такого явления вместо указателей на экземпляры пользовательских объектов при разадресации идентификатора возвращается указатель на объект-оболочку IConnector. В конструкторе объекта-оболочки производится увеличение счетчика блокировок объекта, в деструкторе - уменьшение счетчика блокировок. Пока хоть одна оболочка находится в памяти, счетчик блокировок не равен 0 и соответствующий этой оболочке объект защищен от разрушения. Это позволяет предотвратить вытеснение пользовательского экземпляра во время его использования. Использовать указатели на пользовательский экземпляр без сохранения указателя на оболочку IConnector нельзя. Важной особенностью данной системы является необходимость вызова метода  Dispose у всех объектов-оболочек для предотвращения чрезмерного расхода памяти.

У объекта оболочки IConnector есть свойство Component, через которое доступен пользовательский экземпляр. В большинстве случаев паттерн работы с объектом выглядит следующим образом:

using(IComposite composite =

   this.m_Connector.Workspace.AttachConnector(h))

{

   ISomeInterface node =

     (ISomeInterface)composite.Component;

   result = node.SomeMethod(connector, …);

  

}

При разадресации по идентификатору h объекта в методе this.m_Connector.Workspace.AttachConnector возвращается его оболочка IConnector. После завершения работы с объектом эту оболочку необходимо разрушить, вызвав метод Dispose. Директивы языка C# using() нужны, чтобы гарантировать удержание объекта в памяти во время вызова его методов, а затем гарантировать вызов Dispose после окончания работы с объектом. По выходу из using автоматически вызывается Dispose и разрушает объект-оболочку. При разрушении объект-оболочка уменьшит счетчик блокировок. Когда все оболочки будут разрушены и счетчик блокировок достигнет 0 экземпляр пользовательского объекта станет доступным для вытеснения из оперативной памяти. Если же по каким то причинам using не применим, и пользователь забыл или не смог провести вызов Dispose то сам .NET Framework вызовет Dispose в процессе сборки мусора. В результате утечки памяти не возникнет даже при наличии ошибок программиста.

Третья подсистема сборки мусора рассчитана на удаление persistent объектов из хранилища. Работа этой подсистемы основана на счетчике ссылок. В каждом persistent объекте есть счетчик входящих указателей. Когда на объект не указывает ни одного persistent указателя, объект удаляется из системы по завершению транзакции или при сборке мусора, если он вне транзакции. При изменении объекта в пределах транзакции на этот объект создается указатель из объекта текущей транзакции. Пока на объект существует хоть одна ссылка, он будет существовать в хранилище. Установка дополнительной ссылки на объект из объекта транзакции позволяет задержать физическое удаление объекта до окончания транзакции и при необходимости позволить отменить это удаление. Если все пользовательские ссылки с объекта были сняты, и в конце транзакции с объекта была снята ссылка из объекта транзакции, то объект помечается специальным флагом. Этот флаг действует в пределах оперативной памяти. Выгрузка объекта из оперативной памяти осуществляется, если у объекта не осталось блокировок. При выгрузке объекта из оперативной памяти на основе этого флага принимается решение, будет ли объект уничтожен окончательно. Это позволяет сначала удалить все ссылки на данный экземпляр объекта в хранилище, оставив его в оперативной памяти. Затем, воспользовавшись указателем на объект в оперативной памяти, установить с этим объектом ссылку из другого объекта, не допустив его физического удаления. В связи с наличием в Cerebrum только операций установки / снятия ссылок на объект и отсутствием принудительного удаления объектов, логических парадоксов не возникает.

Сборка persistent мусора на основе подсчета ссылок имеет недостаток: невозможность детектировать недостижимые из корня базы данных циклы объектов. Таким недостатком так же обладают другие, успешно эксплуатирующиеся системы, со сборкой мусора, основанной на подсчете ссылок, например Microsoft COM. Разработка в таком случае требует особой аккуратности при удалении ссылок на объекты. Программист обязан избегать циклических ссылок недостижимых из корня базы данных. В перспективе в СООБЗ Cerebrum возможно сделать четвертую подсистему сборки мусора, которая будет работать на основе достижимости объекта из корня базы данных. В связи с очень большими вычислительными затратами на такой механизм сборки мусора его следует запускаться во время "сна" или бездействия системы.

Модель данных

Модель данных в СООБЗ Cerebrum представляет собой граф с раскрашенными ребрами, узлы графа являются объектами. Объект так же может представлять собой граф с раскрашенными ребрами в узлах которого находятся другие объекты. Каждое ребро имеет только один "цвет". Цвет не является объектом, цвет имеет тот же тип что и идентификатор объекта (Cerebrum.Runtime.NativeHandle). Цвет ребра соответствует типу связи между узлами. Если необходимо сопоставить цвет ребра с каким либо объектом, нужно создать некоторый объект и взять его NativeHandle в качестве “цвета” для раскраски ребра. Таким образом, можно раскрасить ребра в "цвета" экземпляров объектов. Или другими словами: создавать объекты, соответствующие цветам ребер. Если нужно имитировать раскраску ребра множеством цветов, то надо делать несколько ребер, каждое разного "цвета".

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

Узел в Cerebrum является агрегатом нескольких объектов. Во-первых, это объект ядра Kernel Object. Тип объекта ядра KernelObjectClass определяет роль данного узла в модели данных. Kernel Object представляет собой native VNPI Object реализованный на языке C. У прикладного разработчика непосредственный доступ к этому объекту отсутствует. Работа с Kernel Object осуществляется посредством объекта-оболочки. Тип объекта-оболочки, возвращаемого при разадресации, зависит от типа объекта ядра. Непосредственно в Cerebrum.Runtime.dll для использования доступны 3 различные типа объектов ядра. Это Scalar, Stream и Warden. Scalar объекты служат для создания узлов, хранящих скалярные значения, например System.Int32 или System.String. Такие узлы не могут вступать в связь с другими узлами в качестве родительских объектов. Или, что то же самое, такие узлы не могут являться источниками связей. Узлы типа Scalar могут выступать только в качестве дочерних объектов. Узлы типа Stream похожи на узлы Scalar, но в место скалярных значений они хранят потоки байт по аналогии с полем BLOB в РСУБД.

Узлы типа Warden могут быть связанны с другими узлами с помощью однонаправленных связей. Каждой связи должен быть назначен идентификатор. Из узла источника связи возможно обнаружить связанный с ним экземпляр. Однако из узла, на который указывает связь, невозможно определить ни узлы, их которых исходят связи, ни сам факт наличия связи. Можно сказать, что узел источник связи является родительским объектом, а узел приемник связи – дочерним. При этом нельзя для некоторого конкретного объекта определить родительский объект. Таких родительских узлов у каждого экземпляра может быть несколько. Для совместимости с паттерном flyweight в узлах в Cerebrum не храниться ссылки на родительские узлы, и также невозможно определить идентификатор текущего объекта из внутреннего контекста этого объекта.

Вторым объектом в агрегате является экземпляр, реализующий интерфейс IConnector. Экземпляр этого объекта создается и предоставляется СООБЗ. Этот экземпляр передается в пользовательский объект при его инициализации. Через свойство IConnector.Workspace пользовательский объект имеет доступ к экземпляру, реализующему интерфейс IWorkspace.

Третьим объектом в агрегате является экземпляр пользовательского persistent объекта. Особые ограничения на этот объект не накладываются. Он может быть экземпляром любого класса среды .NET Framework унаследованного от System.Object. В случае если пользовательский объект является reference type то будет рационально реализовать в этом объекте интерфейсы IComponent и при необходимости IPersistent/IDiscovery. Рекомендуется наследовать пользовательские reference type объекты от Cerebrum.Integrator.GenericComponent. Если родительский объект получил по идентификатору адрес объекта оболочки дочернего объекта, то экземпляр дочернего пользовательского объекта доступен через свойство IConnector.Component.

Для того чтобы получить указатель на экземпляр пользовательского объекта необходимо вызвать метод AttachConnector в контексте родительского объекта, передав в качестве параметра идентификатор экземпляра, адресующий дочерний объект в пределах родительского контекста. В результате вызова данного метода система вернет новый экземпляр объекта-оболочки, реализующей интерфейсы IConnector и IComposite. Тип объекта оболочки зависит от типа Kernel Object находящегося в данном узле. Объект-оболочка также предоставляет прикладному программисту интерфейсы к функциональности Kernel Object. В случае если в качестве объекта ядра был задан Warden объект оболочка дополнительно реализует и интерфейс IContainer.

В сети нет четкого понятия иерархии. В БД любой объект может выступать как родительский и как дочерний, мало того, объекты могут быть своими собственными родительскими и дочерними объектами. Так же разрешается иметь циклы когда объект А является родительским у объекта B и объект B является родительским у объекта A. Это приводит к затруднению в определении «начала» БД с которой необходимо начать работу непосредственно после запуска системы. Для этого в БД реализован специальный корневой экземпляр объекта - Sector. Sector представляет собой отдельный экземпляр объекта ядра Warden. При необходимости указатель на его оболочку можно получить как IWorkspace.GetSector() однако для удобства и повышения эффективности его интерфейс IContainer совмещен с интерфейсом IWorkspace и доступен через IWorkspace напрямую.

Для удобства работы в Cerebrum реализованы коллекции объектов, называемые таблицами[2]. Таблица представляет собой две коллекции объектов - атрибутов и пользовательских экземпляров. Она автоматизирует процесс присвоения объектам значений атрибутов на основе идентификаторов описателей атрибутов. При создании атрибутов создаются экземпляры объектов AttributeDescriptor как дочерние объекты корневого объекта базы данных. Этим объектам присваиваются уникальные в пределах корневого объекта базы значения идентификаторов, получаемые с помощью sector.NextSequence(). Пользуясь этими идентификаторами как именами, у пользовательских объектов создаются экземпляры атрибутов, имеющие идентификаторы равные соответствующим идентификаторам дескрипторов атрибутов.

Выводы

Предложенный способ идентификации экземпляров объектов включает в себя общепринятый в ООБД как частный случай и позволяет избавиться от некоторых проблем, присущих существующим ООБД. Поддержка сетевой модели данных в ядре Cerebrum позволяет на ее основе реализовать такие модели как иерархические семантические сети и семантические сети фреймов. Поддержка методов у сохраняемых объектов позволяет реализовать активные семантические сети и искусственные нейронные сети. Благодаря наличию автоматической сборки мусора, управление временем жизни объектов и ресурсами берет на себя СУБЗ. Разработчику остается инициализировать БД и далее сосредоточиться на решении поставленной задачи. Это делает среду сетевой объектно-ориентированной базы знаний/данных Cerebrum очень удобным и перспективным инструментом для разработок систем искусственного интеллекта.