Простые онтологические модели: индивидуальные объекты и свойства

Эта страница представляет собой главу из нашего методического пособия
"Введение в онтологическое моделирование" (нажмите для перехода к полной версии в формате PDF).

Как мы помним, основными элементами семантических моделей являются классы, индивидуальные объекты, и свойства. Рассмотрим создание индивидуальных объектов (иначе называемых экземплярами), определений свойств, и присвоение значений свойствам определенных экземпляров.

В Protégé сущности всех типов создаются похожим образом, только для этого используются разные закладки редактора:

  • Classes – классы,
  • Individuals – экземпляры,
  • Data properties – свойства-литералы,
  • Object properties – свойства-указатели на объекты.

Закладка Entities позволяет увидеть все эти элементы одновременно.

В RDF/XML полученные сущности будут отличаться типом, соответственно:

  • http://www.w3.org/2002/07/owl#Class
  • http://www.w3.org/2002/07/owl#NamedIndividual
  • http://www.w3.org/2002/07/owl#DatatypeProperty
  • http://www.w3.org/2002/07/owl#ObjectProperty

Например, триплет с объявлением индивидуального объекта может выглядеть так:

http://example.ru/sample#SecondClassObjecthttp://www.w3.org/1999/02/22-rdf-syntax-ns#typehttp://www.w3.org/2002/07/owl#NamedIndividual

Конечно, при создании индивидуального объекта обычно указывают, к каким классам он относится (мы помним, что объект может входить в несколько классов одновременно). В редакторе Protégé для этого нужно выбрать созданный объект на вкладке Individuals, и нажать кнопку "+" напротив слова Types (правое нижнее окно). Откроется диалоговое окно выбора класса. Результат выполнения этой операции выглядит так:

Индивидуальный объект – член класса в редакторе Protégé
Индивидуальный объект – член класса в редакторе Protégé

Кстати, обратите внимание, что для "Второго класса" Protégé показывает в своем интерфейсе значение его свойства label, а не уникальную часть идентификатора URI.

В RDF/XML факт вхождения объекта в класс отразится следующим образом:

    <owl:NamedIndividual rdf:about="http://example.ru/sample#SecondClassObject">
        <rdf:type rdf:resource="http://example.ru/sample#SecondClass"/>
    </owl:NamedIndividual>

Триплеты в этом случае будут выглядеть так:

http://example.ru/sample#SecondClassObjecthttp://www.w3.org/1999/02/22-rdf-syntax-ns#typehttp://www.w3.org/2002/07/owl#NamedIndividual
http://example.ru/sample#SecondClassObjecthttp://www.w3.org/1999/02/22-rdf-syntax-ns#typehttp://example.ru/sample#SecondClass

Обратите внимание на то, что определение свойства во втором столбце – одинаково в обоих триплетах! То есть, тот факт, что элемент модели SecondClassObject относится к предопределенному стандартом классу NamedIndividual, и является членом определенного в данной онтологии класса SecondClass, выражается при помощи одного и того же предопределенного стандартом свойства. Из этого следует, кстати, что код RDF/XML можно переписать так:

    <SecondClass rdf:about="http://example.ru/sample#SecondClassObject">
        <rdf:type rdf:resource="http://www.w3.org/2002/07/owl#NamedIndividual"/>
    </SecondClass>

Результат импорта этого кода в triple store будет точно таким же, как в предыдущем случае.

Перейдем к рассказу о том, как в модели задаются свойства и их значения. Определение свойства, значением для которого является литерал, происходит так. В редакторе Protégé нужно перейти на закладку Data Properties, создать новое свойство – кстати, обратите внимание, что у свойств может быть своя иерархия. После этого, используя правое нижнее окно, нужно задать два принципиально важных атрибута свойства: Domain и Range. Domain – это набор классов, к экземплярам которых применимо данное свойство. Range – это тип значений, которые свойство может принимать. Соответственно, значение для Domain выбирается из списка классов, существующей в нашей модели, а Range – из определенных стандартом типов данных (используются типы данных XSD). И Domain’ов, и Range у свойства может быть несколько. В окне редактора результат создания свойства выглядит так:

Свойство-литерал в редакторе Protégé
Свойство-литерал в редакторе Protégé

Аналогичным образом создаются свойства-указатели на объекты. Для этого используется закладка Object Properties. Range в этом случае также выбирается из числа классов, определенных в онтологии.

Для свойств обоих типов можно также задать ограничения на число значений, которые может иметь данное свойство для конкретного объекта (например, имен у человека может быть несколько, а дата рождения – только одна). Для этого используется понятие Cardinality. Чтобы создать ограничение, нужно нажать на кнопку "+" напротив слова Ranges, и перейти на закладку Object (или Data) Restriction creator в появившемся диалоговом окне. Здесь нужно выбрать свойство, на которое накладывается ограничение, затем класс(ы) или тип(ы) принимаемых значений; внизу окна выбирается тип ограничения – минимальное или максимальное количество значений, и вводится число. Например, если установить min cardinality = 1, это будет означать, что свойство должно иметь по меньшей мере одно значение для каждого объекта. По умолчанию любое свойство может иметь любое количество значений для каждого объекта.

Результат сохранения определения свойства-литерала в формат RDF/XML выглядит так:

    <owl:DatatypeProperty rdf:about="#shortName">
        <rdfs:domain rdf:resource="#OurFirstClass"/>
        <rdfs:range rdf:resource="&xsd;string"/>
    </owl:DatatypeProperty>

Для свойства-указателя на объект:

    <owl:ObjectProperty rdf:about="#ObjectProp">
        <rdfs:domain rdf:resource="#OurFirstClass"/>
        <rdfs:range rdf:resource="#SecondClass"/>
    </owl:ObjectProperty>

Конечно, для читаемости определениям свойств следует присваивать label.

Информацию об ограничениях на число значений Protégé сохраняет в RDF/XML не самым красивым образом:

    <owl:ObjectProperty rdf:about="#ObjectProp">
        <rdfs:domain rdf:resource="#OurFirstClass"/>
        <rdfs:range rdf:resource="#SecondClass"/>
        <rdfs:range>
            <owl:Restriction>
                <owl:onProperty rdf:resource="#ObjectProp"/>
                <owl:onClass rdf:resource="#SecondClass"/>
                <owl:minQualifiedCardinality rdf:datatype="&xsd;nonNegativeInteger">1</owl:minQualifiedCardinality>
            </owl:Restriction>
        </rdfs:range>
    </owl:ObjectProperty>

В триплетах такое определение создает пустой узел, соответствующий тегу owl:Restriction. Получается следующая картина:

_:b0
http://www.w3.org/1999/02/22-rdf-syntax-ns#type
http://www.w3.org/2002/07/owl#Restriction
_:b0
http://www.w3.org/2002/07/owl#minQualifiedCardinality
"1"^^<http://www.w3.org/2001/XMLSchema#integer>
_:b0
http://www.w3.org/2002/07/owl#onClass
http://example.ru/sample#SecondClass
_:b0
http://www.w3.org/2002/07/owl#onProperty
http://example.ru/sample#ObjectProp

Нам осталось научиться присваивать значения свойств индивидуальным объектам. В редакторе Protégé для этого предназначена область Property Assertions на странице просмотра индивидуального объекта. Нажатием кнопки "+" напротив Data property assertion и Object property assertion мы можем вызвать диалоговые окна, в которых нужно выбрать свойство, и ввести для него значение. Результат выполнения этой операции выглядит так:

Присвоение свойств индивидуальным объектам
Присвоение свойств индивидуальным объектам

В формате RDF/XML это будет выглядеть так:

    <owl:NamedIndividual rdf:about="#SecondClassObject">
        <rdf:type rdf:resource="#SecondClass"/>
        <shortName>Имя объекта</shortName>
        <ObjectProp rdf:resource="#SecondClassObject"/>
    </owl:NamedIndividual>

Для свойств-литералов можно (но не обязательно) задать тип значения. Например, если мы укажем явным образом, что значение свойства shortName является строкой – в файле это отразится так:

        <shortName rdf:datatype="&xsd;string">Имя объекта</shortName>

В триплетах, с учетом указания типа, значения свойств shortName и objectProp отразятся так:

http://example.ru/sample#SecondClassObject
http://example.ru/sample#shortName
"Имя объекта" ^^<http://www.w3.org/2001/XMLSchema#string>
http://example.ru/sample#SecondClassObject
http://example.ru/sample#ObjectProp
http://example.ru/sample#SecondClassObject

Обратите внимание на то, как преобразуется информация о типе значения при импорте в триплеты: суффикс ^^ добавляется к самому значению.

Следует отметить некоторые особенности программного обеспечения, работающего с семантическими моделями. Так, при отключенной машине логического вывода Protégé не выполняет проверок целостности модели - например, не проверяет, доступно ли свойство, значение которому мы пытаемся присвоить, для редактируемого объекта. В других продуктах, если такие проверки все же производятся – нет гарантии, что они учитывают наследование свойств от вышележащих классов к нижележащим. Решение подобных вопросов остается на усмотрение разработчиков каждого конкретного программного продукта.

Хранилища триплетов при отключенном reasoner'е также не производят никакой логической обработки содержимого модели, поэтому формализмы RDF и OWL не имеют для них ровным счетом никакого значения. Triple store спокойно примет ошибочные и абсурдные определения любых моделей. Вместо URI можно передавать произвольные строки – это является формальным нарушением стандарта, однако, triple store совершенно не беспокоит. Для него триплет – это тройственная структура, любой элемент которой может принимать любые значения.

Следующая глава: Простые онтологические модели: общая картина