Скачиваний:
57
Добавлен:
01.05.2014
Размер:
930.3 Кб
Скачать

Глава 2 Программирование баз данных

Имеются два основных применения логических программ: построение логической базы данных и работа со структурами данных. В этой главе обсуждается программирование баз данных. Логическая база данных строится из множества фактов и правил. Мы покажем, как множество фактов может определять отношения, так же как в реляционных базах данных. Мы покажем, как правила могут определять сложные реляционные вопросы, также как в реляционной алгебре. Таким образом, функциональные зависимости, связанные с реляционными базами данных, могут выражаться логическими программами, составленными из фактов и правил весьма ограниченного вида.

2.1. Простые базы данных

Начнем с повторного рассмотрения программы 1.1, библейской базы данных и ее расширения правилами, задающими семейные отношения. В самой базе данных имеются четыре основных предиката: отец/2, мать/2, мужчина/1 и женщина/1. Мы примем соглашение из теории баз данных и снабдим каждое отношение реляционной схемой которая указывает роль каждой позиции в отношении (каждого аргумента в цели). Реляционными схемами для этих четырех предикатов будут соответственно отец (Отец, Ребенок), мать (Мать, Ребенок), мужчина (Человек) и женщина (Человек). Принятые мнемонические имена говорят сами за себя.

Будем придерживаться типографского соглашения о курсивном выделении реляционных схем. В правилах переменным даются содержательные имена, в то время как в вопросах - имена Х или Y. Многословные имена используются по-разному для переменных и предикатов. В случае переменной каждое слово начинается с прописной буквы, например: ПлемянницаИлиПлемянник; в случае имен функций и предикатов слова соединяются нижней чертой, например: конфликт_расписания.

Новые отношения строятся из этих основных отношений с помощью определе­ния подходящих правил. Соответствующими реляционными схемами для отношений, введенных в предыдущей главе, являются сын (Сын, Родитель), дочь (Дочь, Родитель), родитель (Родитель, Ребенок) и внук (Внук, ДедИлиБабушка). С точки зрения логики несущественно, какие отношения определяются с помощью фактов, а какие-с помощью правил. Например, если соответствующая база данных содержит факты родитель, мужчина и женщина, то правила, определяющие отношения сын и дочь, остаются в силе. Для отношений, более не определяемых фактами, например отец и мать, следует ввести новые правила. Подходящими правилами будут

отец(Папа, Ребенок)  родитель (Папа, Ребенок), мужчина (Папа).

мать(Мама, Ребенок)  родитель(Мама, Ребенок), женщина (Мама).

Интересные правила могут появиться при превращении отношений, неявно присутствующих в базе данных, в явные. Например, поскольку нам известны отец и мать ребенка, то нам известно, у каких пар был потомок, или известны, в терминах Библии, прародители. Это отношение не задано явно в базе данных, однако простое правило может выявить эту информацию. Реляционная схема - прародители (Мужчина, Женщина).

прародители (Мужчина,Женщина) 

отец(Мужчина,Ребенок), мать (Женщина, Ребенок).

Правило означает: «Мужчина и Женщина являются прародителями, если есть ребенок, отцом которого является Мужчина, а матерью - Женщина».

Другим примером извлечения информации из более простых сведений является отношение «быть детьми одних родителей» - братья и сестры. Дадим правило для брат (Брат, Дети Одних Родителей).

брат (Брат, ДетиОднихРодителей) 

родитель (Родитель, Брат),

родитель (Родитель, ДетиОднихРодителей),

мужчина (Брат).

Однако такое правило означает: «Брат является братом ДетейОднихРодителей, если Родитель является родителем Брата и ДетейОднихРодителей и Брат является мужчиной».

Определение отношения брат приводит к некоторой проблеме. Вопрос брат (Х,Х)? выполняется для любого ребенка Х мужского пола, что не согласуется с нашим пониманием отношения брат.

Для того чтобы исключить подобные утверждения из значения программы, введем предикат  (Терм1,Терм2). Удобнее записывать этот предикат в обычном (инфиксном) виде. Таким образом. Терм1 Терм2 истинно, если Терм1 и Терм2 различны. Ограничимся пока примером термов, являющихся константами. В принципе этот предикат может быть определен с помощью таблицы Х Y для каждой пары различных индивидов -X и Y из интересующей области. Рис. 2.1 представляет собой такую таблицу для программы 1.1.

авраам  исаак. авраам  аран. авраам  лот.

авраам  милка. авраам  иска. исаак  аран.

исаак  лот. исаак  милка. исаак  иска.

аран  лот. аран  милка аран  иска.

лот  милка. лот  иска. милка  иска

Рис 2.1 Определение неравенства.

Новое правило для отношения брат:

брат (Брат, ДетиОднихРодителей) 

родитель (Родитель, Брат),

родитель (Родитель, ДетиОдних Родителей),

мужчина(Брат),

Брат  ДетиОднихРодителей.

Чем больше отношений уже введено, тем проще определять новые сложные понятия. Программа 2.1 определяет отношения дядя(Дядя,ПлемянницаИлиПлемянник), дети_одних_родителей(ДетиОднихРодителей1, ДетиОднихРодителей2) и родственник(Родственник1, Родственник2). Дополнительные примеры приведены в качестве упражнения в конце раздела.

Другое отношение, неявно содержащееся в семейной базе данных, - является ли женщина матерью. Это отношение определяется с помощью отношений мать/2.Новой реляционной схемой является мать(Женщина), которая определяется правилом

мать(Женщина) мать(Женщина, Ребенок)

Это означает: ”Женщина является матерью, если у нее есть Ребенок». Заметим, что

дядя(Дядя,Субъект) 

брат(Дядя,Родитель), родитель(Родитель,Субъект).

дети_одних_родителей(ДетиОднихРодителей1 .ДетиОднихРодителей2) 

родитель(Родитель, ДетиОднихРодителей1).

родитель(Родитель,ДетиОднихРодителей2), ДетиОднихРодителей1  ДетиОдних

Родителей2.

родственник(Родственник1 ,Родственник2) 

родитель(Родитель1, Родственник1),

родитель(Родитель2,Родственник2),

детн_одних_родителей(Родитель1,Родитель2).

Программа 2.1.Определение семейных отношений.

одно и то же предикатное имя мать используется для описания двух разных отношений мать. Предикат мать имеет в этих двух случаях различное число аргументов, т. е. различную арность. В общем случае одно и то же предикатное имя с различными арностями описывает различные отношения.

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

База данных, приведенная в программе 2.2, представляет собой упрощенное описание логического вентиля “И”, изображенного на рис. 2.2. Факты изображают связи между отдельными резисторами и транзисторами, входящими в схему. Реляционная схема резистора - resistor (Вывод1,Вывод2), Канального транзистора - transistor (Затвор, Исток, Сток).

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

Рис. 2.2-Логическая схема.

Правила, относящиеся к функциональным компонентам схемы, описывают работу отдельных групп резисторов и транзисторов Схема описывает вентиль “И”, в котором выходной сигнал является логическим “и” двух входных сигналов. Один из способов построения такого вентиля состоит в последовательном соединении вентиля “И-НЕ” и инвертора. Такой способ и использован в данной схеме. Реляционные схемы для этих трех компонентов - and_gate(Input1,Input2,Output), nand_gate(Input1,Input2, Output) и inverter (Input,Output).

Чтобы понять программу 2.2, давайте разберем правило для инвертора. Оно утверждает, что инвертор строится из транзистора с заземленным истоком и резистора, один вывод которого присоединен к источнику питания. Затвор транзистора является входом инвертора, а свободный вывод резистора следует соединить со стоком транзистора, - это соединение образует выход инвертора. Общие переменные используются для описания общих соединений.

Рассмотрим вопрос and_gate(Inl,In2,Out)? относительно программы 2.2. Имеется решение {In1 = n3,In2 = n5,0ut = п1}. Это решение подтверждает, что факты действительно описывают вентиль “И”, и указывает входы и выход вентиля.

resistor(power, n1).

resistor(power, n2).

transistor(n2,ground,nl).

transistor(n3,n4,n2).

transistor(n5,ground,n4).

inverter (Input,Output)

Output является инверсией Input.

inverter(Input,Output) 

transistor(Input,ground,Output), resistor(power,0utput).

nand-gate( Input1,lnput2,Output)

Output является логическим “И-НЕ” Input1 и Input2.

nand_gate(Inputl,Input2,Output) 

transistor(Input1 ,X, Output),

transistor(lnput2, ground,X),

resistor(power, 0utput).

and_gate( Input 1,Input2,Output)

Output является логическим “И” Input1 и Input2.

and_gate(Inputl,[nput2,Output) 

nand_gate (Input1, Input2,X),

inverter(X,Output).

Программа 2.2. Схема логического вентиля “И”.

Рис 2.3 Вентиль ИЛИ

Упражнения к разд. 2.1

1. Измените правило для отношения брат, чтобы описать отношение сестра, правило для отношения дядя, чтобы описать отношение племянница, и правило для отношения дети_одних_родителей, чтобы ему удовлетворяли только родные братья и сестры, т.е. те, у которых общие и мать, и отец.

2. Используя предикат супруги (Жена, Муж), опишите отношения теща, шурин и зять.

3. Напишите логическую программу, подобную программе 2.2, описывающую логическую схему вентиля “ИЛИ”. Схема изображена на рис. 2.3. Добавив инвертор, расширьте программу до вентиля “ИЛИ-НЕ”.

Соседние файлы в папке 1-13