Опубликован: 10.12.2007 | Уровень: специалист | Доступ: платный
Лекция 11:

RDF

11.3 Введение в факты

В основе синтаксиса любых приложений XML лежит концепция элемента, который часто соответствует одному тегу. В основе RDF лежит понятие факта, специфичное для этого приложения XML. Факт соответствует одному элементу, но не всегда соответствует одному тегу. Что же такое факт, и чем он может быть полезен? Эти вопросы обсуждаются в данном разделе. Специалисты по логике предикатов и дедуктивным системам могут лишь бегло просмотреть этот материал.

Программист может получить первое представление о мире фактов по аналогии с известными технологиями, которые до некоторой степени "фактоподобны". В качестве примеров можно привести язык SQL и утилиту make. Управление записями в базе данных при помощи таких операторов SQL, как INSERT, DELETE и особенно SELECT до некоторой степени сходно с управлением фактами. Запрос к базе данных аналогичен запросу к системе обработки фактов. С другой стороны, правило командного файла утилиты make(1), на основе которого утилита определяет, какие файлы нуждаются в новой компиляции, также "фактоподобно". Правило из командного файла можно рассматривать как факт о файлах и "целях" ( target ) утилиты make. Еще один пример "фактоподобного" командного файла – конфигурационный файл программы sendmail, весьма сложный для чтения.

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

11.3.1 Факты и структуры данных

Факты используются для описания и моделирования данных. Программисты, как правило, используют для моделирования структуры данных. Те программисты, которым приходится заниматься проектированием, могут использовать для этого словари данных и диаграммы UML.

Пожалуй, простейший способ понять, чем факты отличаются от традиционных данных, – записать то и другое. Предположим, что мальчик и его собака играют с мячом на пляже. Описание этой ситуации, включающее четыре объекта реального мира (мальчик, пляж, собака, мяч), может храниться как структура данных или как факт. Начнем с обычных структур данных. В JavaScript эти данные можно сохранить в форме объекта1Boy – мальчик, dog – собака, ball – мяч, beach – пляж (англ.). (Прим. пер.) :

{boy:"Том", dog:"Спот", ball:"теннис", beach:"Уайкики"}

Эта запись довольно близка и к структурам данных в C/C++ ( struct ). Ту же информацию можно сохранить и в виде массива JavaScript:

[ "Том", "Спот", "теннис", "Уайкики" ]

Все наши данные имеют один и тот же тип – строка, что соответствует идее массива. Массив с этими данными можно было бы создать и в C/C++. В программе на Perl можно было бы использовать список:

( "Том", "Спот", "теннис", "Уайкики", )

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

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

< Том, Спот, теннис, Уайкики >

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

<- Том, Спот, теннис, Уайкики ->

Каждый из элементов кортежа называется терм. Позднее скобки в виде "птичьей лапки" будут напоминать нам о том, что некоторые кортежи (особенно интересные для нас) состоят из трех термов. Заключать термины в кавычки не нужно, поскольку это не язык программирования. Термы в кортеже считаются упорядоченными, но не пронумерованными (в отличие от массива), и не имеют заданных типов (в отличие от struct или класса). Смысл кортежа прост: эти термы связаны друг с другом. Каким именно образом они связаны – в общем случае неважно.

Использование угловых скобок < и > намекает на существенную разницу между кортежами и другими структурами данных. Разница состоит в том, что кортеж представляет собой декларацию, утверждение, подобно тегу XML или определению класса. Примеры с различными структурами данных представляют собой выражения разных языков. Выражение может быть вычислено и присвоено переменной. Но невозможно вычислить декларацию или присвоить ее переменной. Декларация просто существует.

Обработка декларации-кортежа состоит просто в том, что соответствующий факт признается истинным. Если кортеж для факта существует, то факт считается истинным, в противном случае – ложным. Значение для истинности факта нигде не хранится, оно вычисляется посредством сопоставления с существующими кортежами. Это позволяет не ограничивать заранее круг фактов, с которыми может работать система. Факты, для которых находится подходящий кортеж, признаются истинными, а все остальные – ложными.

Пример кортежа, приведенный выше, обеспечивает истинность следующего факта "Том, Спот, теннис и Уайкики связаны друг с другом". Отметим, что кортеж содержит не всю информацию, которая заключалась в исходном утверждении. Например, он не отражает того, что Том и Спот были на пляже Уайкики одновременно. Это типичная ситуация для любой работы по сбору информации – приходится отбирать для фиксации наиболее важные сведения.

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

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

var boy = { Pid:1, name:"Том", Did:null, Bid:null };
// name - имя
var dog = { Did:2, name:"Спот", Pid:null, Bid:null };
var ball = { Bid:5, type:"теннис", color:"зеленый" };
// type - тип, color - цвет
boy.Did = dog; // связать объекты друг с другом
boy.Bid = ball;
dog.Pid = boy;
dog.Bid = ball;
Листинг 11.1. Объекты, моделирующие ситуацию с мальчиком и собакой

Pid, Did, и Bid означают идентификаторы человека, собаки и мяча соответственно (Person-id, Dog-id и Ball-id). Эти идентификаторы должны сделать объекты уникальными – возможно, существуют две собаки по имени Спот, или у Тома есть пять зеленых мячей. Помимо создания объектов, между ними установлены связи. Том и Спот имеют отношение к одному и тому же мячу, Спот – собака Тома, Том – человек (хозяин) Спота.

Аналогичное моделирование может быть выполнено при помощи кортежей, как показано в листинге 11.2:

<- 1, Том, 2, 5 ->
<- 2, Спот, 1, 5 ->
<- 5, теннис, зеленый ->
Листинг 11.2. Кортежи, моделирующие ситуацию с мальчиком и собакой.

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

Обе попытки моделирования позволили описать некоторые существенные факты, но одновременно выявили ограниченность обоих подходов. Исходное описание ситуации таково: "Том и его собака Спот играют с мячом". Результаты двух попыток моделирования представлены в таблице 11.1:

Таблица 11.1. Информация, отраженная в моделях, основанных на объектах и кортежах
Модель с объектами Модель с кортежами
Объект для Тома Кортеж для Тома
Объект для Спота Кортеж для Спота
Объект для зеленого теннисного мяча Кортеж для зеленого теннисного мяча
Том связан со Спотом Том, 1, 2 и 5 связаны между собой
Спот связан с Томом Спот, 2, 1 и 5 связаны между собой
Том связан с зеленым теннисным мячом Зеленый теннисный мяч и 5 связаны между собой
Спот связан с зеленым теннисным мячом
(Можно вывести дополнительную информацию) (Можно вывести дополнительную информацию)

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

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

11.3.2 Предикаты и кортежи

Предикатами называется особая группа кортежей. Поскольку все кортежи являются фактами, предикаты тоже являются фактами. Предикаты содержат как термы, представляющие предметы, так и термы, представляющие отношения между ними. Прямолинейная попытка добавления отношений могла бы выглядеть так, как показано в листинге 11.3, который является развитием листинга 11.2:

<- 1, Том, хозяин, 2, играет-с, 5 ->
<- 2, Спот, принадлежит, 1, играет-с, 5 ->
<- 5, теннис, зеленый ->
Листинг 11.3. Добавление отношений к модели с кортежами

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

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

Описание ситуации в листинге 11.3 все же не идеально, поскольку некоторые кортежи содержат более одного терма, выражающего отношение. Если кортеж может содержать более одного терма-предиката, это существенно усложняет обработку фактов. Поэтому мы можем улучшить наш пример. В листинге 11.4 показано, как можно разбить некоторые кортежи на два, так чтобы в каждом кортеже остался только один предикат.

<- 1, Том, хозяин, 2 ->
<- 1, Том, играет-с, 5 ->
<- 2, Спот, принадлежит, 1 ->
<- 2, Спот, играет-с, 5 ->
<- 5, теннис, зеленый ->
Листинг 11.4. Модель, основанная на кортежах с одним предикатом

Ценой некоторого дублирования информации мы смогли разделить предикаты, и теперь наши кортежи еще удобнее читать. Эквивалентная процедура при проектировании баз данных называется нормализацией, а сходная операция над программным кодом – факторизацией. В любом случае, это управление информацией по принципу "разделяй и властвуй". Однако мы можем сделать наше описание еще более удобным для обработки. Для этого унифицируем кортежи так, чтобы каждый из них имел ровно три элемента (N = 3). Результат показан в листинге 11.5.

<- 1, имя, Том ->
<- 1, хозяин, 2 ->
<- 1, играет-с, 5 ->
<- 2, имя, Спот ->
<- 2, принадлежит 1 ->
<- 2, играет-с, 5 ->
<- 5, тип, теннис ->
<- 5, цвет, зеленый ->
Листинг 11.5. Модель, основанная на триплетах с одним предикатом

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

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

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

Факты об отношениях могут быть записаны различными способами. Например, в языке Prolog их можно записывать так:

предикат(субъект, объект)
plays-with(1,5) 
играет-с(1,5)

В языках Lisp или Scheme то же самое может быть записано как:

(предикат субъект объект)
(plays-with 1 5)
(играет-с 1 5)

Можно записывать такие факты и на естественном языке

субъект предикат объект
1 играет с 5

И, разумеется, факты об отношениях можно выразить на языке XML, для чего и был разработан формат RDF. Один из вариантов – записать факт в форме одного тега2Description – описание; about – о (англ.). (Прим. пер.) :

<Description about="субъект" предикат="объект"/>
<Description about="1" играет-с="5"/>

Наконец, для удобной и компактной записи фактов может использоваться нотация для кортежей, которую мы задействуем в этой лекции, а также еще более простой синтаксис без пунктуации, используемый некоторыми специалистами по RDF:

<- субъект, предикат, объект ->
субъект предикат объект

Если вы склонны придерживаться синтаксиса реального языка программирования, можете следовать простой и ясной нотации Prolog или Lisp, которая использовалась для записи и обработки фактов на протяжении десятков лет. Альтернативный вариант – применять RDF.

Рис. 11.1 Граф связей между кортежами
1 играет-с 5
5 тип теннис
1 имя Том
1 хозяин 2
2 принадлежит 1
2 имя Спот
5 цвет зеленый
2 играет-с 5
Дмитрий Гуменюк
Дмитрий Гуменюк
Россия, Звенигород
Konstantin Grishko
Konstantin Grishko
Россия, Москва, Московский финансово-промышленный университет "Синергия", Москва