Россия, Звенигород |
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 несколько приукрашивает ситуацию, поскольку учитывает подразумеваемое знание о назначении каждого объекта и кортежа. Тем не менее, она демонстрирует основную проблему обоих моделей – они отдают приоритет предметам (существительным), однако практически не могут отразить отношений между ними. В моделях не зафиксировано ни то, что Том является хозяином Спота, ни то, что Спот играет с мячом.
Традиционное решение этой проблемы – создать дополнительные таблицы, объекты и т.п. Решение, подходящее для мира фактов, – сделать каждое существующее отношение термом в кортеже. Такой кортеж называется предикатом.
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