Теперь можно проверить ряд методов, использование которых, возможно, позволит справиться с трудностями, перечисленными в начале этой главы. Предположим, что надо создать базу данных для хранения информации, приведенной в табл. 3.1. Один из возможных путей заключается в объединении всей информации о каждой личности в список и использовании для работы с этим списком специального отношения, названного, например, stat. Заметим, что в принципе можно использовать любое другое имя,
но лучше выбрать такое имя, которое мнемонически отражает смысл отношения. В нашем случае stat - сокращение status (общественное положение) или statistics (статистика). Ниже приведено описание отношения на языке Пролог:
Alan stat (15 0 500 0 2 7)
Bill stat (32 butcher 12000 23 19 7)
Colin stat (28 teacher 9850 7 3 2)
Diana stat (30 nurse 6500 5 7 5)
Eve stat (12 0004 12)
Frances stat (32 doctor 11500 5 2 2)
Таблица 3.1
В отношении присутствуют 36 единиц информации (или в случае учета имен 42 единицы).
Шесть строк нашего отношения в принципе заменяют 36 строк, которые были бы необходимы, если бы для представления каждой единицы информации использовалось отдельное утверждение. Но, правда, нужно учесть, что несколько дополнительных утверждений потребуется для того, чтобы иметь возможность выделить из списка нужный элемент данных. Приведенные ниже отношения как раз используются для этой цели.
X aged Y if
X stat(Y|Z)
X job Y if
X stat (ZY|x) and
not X stat (Z∅|x)
X earns Y if
X stat(ZxY|y)
X years-at Y if
X stat(ZxyY|z)
X house Y if
X stat(ZxyzY|X1)
X years-in Y if
X stat(ZxyzX1Y|Y1)
Эта программа, без сомнения, более компактна и проще поддается изменениям, чем аналогичная программа, описанная в конце гл. 2. Достаточно легко, например, добавить к ней новые элементы данных. Для этого надо поместить их в конец списка и предусмотреть новое правило для их извлечения. Забегая немного вперед, скажем, что утверждения типа
Alan stat (15 ∅ 5 ∅ ∅ ∅ 2 7)
в теории баз данных называются записями. Все элементы данных, входящие в список, носят названия полей; а имя человека, составляющего вместе со списком отношение, ключом записи.
В том случае, когда к какой-нибудь записи добавляются поля, необходимо модифицировать все имеющиеся записи данного типа, невзирая на то, что новые поля могут не входить в состав одной или нескольких записей. Именно по этой причине значениями некоторых полей в программе являются нули. Пролог сопоставляет переменные с константами с учетом их позиций в списке. Образец должен быть тоже определен, если позиция переменной Y, представляющей требуемое поле, сравнивается с позицией искомой информации в отношении stat. Например, предложения
Bill stat (32 butcher 12∅∅∅ 23 19 7)
и
Н job Y if X stat (Z У|x)
используются для сопоставления Y с butcher в ответ на запрос
which (x: Bill job x)
В последнем правиле программы используется stat (Zхуz X1 Y|Y1), а не stat (Zхуz X1|Y), несмотря на то, что последняя конструкция также позволяет извлечь нужную информацию. Дело в том, что первая конструкция будет работать даже при добавлении к записи новых полей, а вторую - в этом случае потребуется модифицировать. Важно обеспечить программе гибкость; недостаток предусмотрительности может привести либо к ошибкам при извлечении информации из базы данных, либо к необходимости проведения дополнительных работ по перепрограммированию уже написанных компонентов.
Упражнение 3.3
Составьте запросы, с помощью которых можно получить:
а)всю информацию из базы данных;
б)название профессии Билла;
в)фамилии, профессии и годовой доход тех, кому больше 30 лет;
г)всю информацию о Фрэнсисе;
д)фамилии и число лет проживания в доме тех, кто одинаковое время жил в одном и том же доме.
Рекомендуем проверить правильность Ваших ответов на ЭВМ. Предупреждаем, что задание не такое простое, как кажется на первый взгляд.
Тонкость последнего задания упражнения 3.3 заключается в том, что гораздо легче получить больше информации, чем требуется. Первая попытка выполнить упражнение может быть такой:
all (X Y Z: X years-in Z and Y years-in Z)
Другими словами, ищутся X и Y такие, которые прожили в своих домах одинаковое число лет Z.
В качестве ответа на этот запрос получим
Alan Alan 7
Alan Bill 7
Bill Bill 7
и т. д.
Повторение одного и того же имени объясняется тем, что Пролог-система "не знает", что X и Y не должны принимать одно и то же значение. Кроме того, одним из возможных ответов будет
Bill Alan 7
в принципе дублирующий ответ
Alan Bill 7
С точки зрения формальной логики вполне справедливы следующие утверждения: Алан живет в своем доме столько же лет, сколько Билл живет в своем; если Алан живет в своем доме то же самое время, что и Билл живет в своем, то Билл живет в своем доме столько же лет, сколько Алан живет в своем.
Из всего написанного выше ясно, что необходимо, во-первых, чтобы X и Y отличались друг от друга и, во-вторых, чтобы информация (X Y) считалась тождественной информации (Y X). Да, воистину логика иногда раздражающе логична. Запрос же теперь можно составить так:
all (X Y Z: X years-in Z and Y years-in Z and X LESS Y)
Ответами на этот запрос будут
Alan Bill 7
и
Colin Frances 2
Напомним, что с помощью отношения LESS можно сравнивать строки символов в соответствии с кодами символов в ASCII. Это свойство очень полезно для сортировки.
Упражнение 3.4
Дополните описанные выше записи о людях следующими данными:
а)главным увлечением;
б)типом автомобиля;
в)названием любимого музыкального жанра;
г)составьте новые отношения, которые позволяли бы извлекать только что указанную информацию.