Лабораторная работа 9
Работа со сложноструктурированными базами данных
1. Задание на лабораторную работу
Требуется разработать информационно-запросную систему для некоторой предметной области. В качестве примера можно использовать приведенное ниже описание логической модели данных предметной области "семья". Для решения поставленной задачи необходимо:2. Описание логической модели данных
Данная лабораторная работа развивает навыки представления структурных объектов данных и управления ими. Она показывает, что Пролог является естественным языком запросов к базе данных и как с его помощью переходить к формированию простейших баз знаний.Семья(Муж, Жена, Дети)Поскольку количество детей в разных семьях может быть разным, то объект Дети целесообразно представить в виде списка, состоящего из произвольного числа элементов:
Дети = [ Ребенок!, Ребенок2, . . . , РебенокN ]Каждого члена семьи в свою очередь можно описать структурой, состоящей из четырех компонент: имени, фамилии, даты рождения и вила деятельности. Т.е. представить в виде:
ЧленСемьи(Имя , Фамилия, ДатаРождения, Деятельность)При этом дата рождения также представляется структурой, объединяющей в своем составе три компоненты: число, месяц и год рождения:
Дата(Число, Месяц, Год)Особый интерес представляет информация о виде деятельности, которая может содержать сведения о том работает, учится или не работает какой-либо член семьи. Причем в том случае, если человек работает, следует иметь данные о месте его работы, должности и окладе. Если учится, то следует указать место учебы. Если не работает, то надо иметь об этом информацию. Таким образом, вид деятельности для каждого из членов семьи может быть описан одной из возможных структур:
Работает(Где, Кем, Оклад) или УчитсяГде) или НеРаботаетГрафически информацию о каждой семье можно представить в виде структуры, приведенной на рис.6
Тогда БД будет состоять из последовательности фактов, подобных этому, и описывать все семьи, представляющие интерес для нашей программы.семья ( членсемьи( Иван. Ким, дата(8,март, 1949), работает(АО,шеф,500) ). членсемьи( Лена, Ким, дата(3,май, 1951), неработает), [ членсемьи( пат,фокс, дата(5,май,1973), неработает), членсемьи( Саша, Ким, дата(1,июнь,1983), учится(школа) ) ] ).
семья( членсемьи( _, Иванов, _, _ ), _, _ )Символы подчеркивания означают различные анонимные переменные, значения которых нас не заботят. Ссылаться на все семьи с тремя детьми позволяет терм:
семья( _, _, [_,_, _] )Чтобы найти всех замужних женщин, имеющих по крайней мере троих детей, можно задать вопрос:
семья( __, членсемьи(Имя,Фамилия,_,_),[_,_,_ |_]).Основным моментом в этих примерах является то, что указывать интересующие нас объекты можно не только по их содержимому, но и по их структуре.
3. Получение структурированной информации из базы данных
Можно создать набор процедур, который делал бы взаимодействие с нашей БД более удобным. Такие процедуры являлись бы частью пользовательского интерфейса. Вот некоторые полезные процедуры для рассматриваемой БД:Этими процедурами можно воспользоваться, например в следующих запросах в базе данных:муж( X) :- семья( X, _, _). жена( X) :- семья (_, X, _). ребенок( X) :- семья( _,_, Дети),принадлежите X, Дети). /* принадлежит элемент списку */' существует (Членсемьи) :- муж( Членсемьи); /* Любой член семьи в БД к/ жена( Членсемьи); ребенок ( Членсемьи). датарождения(Членсемьи(_,_Дата,_)Дата). доход( Членсемъи(_,_,_,работает(_,S) ),S) :- !. /* Доход работающего */ доход( Членсемьи( _,_,_,_), 0). /* Доход неработающего */ принадлежите (X, [X п L ]. принадлежит (X, [Y п L ] :- принадлежит( X, L).
Для подсчета общею дохода семьи полезно определить сумму доходов людей из некоторого списка в виде двухаргументного отношения:
Запрос Цель Найти имена и фамилии всех людей из базы данных существует( членсемьи( Имя, Фамилия, _, _)). Найти всех детей, родившихся в 1983 году ребенок(X), датарождения( X, дата( _,_, 1983) ). Найти всех работающих жен. жена( членсемьи( Имя, Фамилия,_, работает(_,_))). Найти имена и фамилии людей, которые не работают и родились до 1963 года существует( членсемьи( Имя, Фамилия,дата(_,_,Год) неработает)).Год < 1963. Найти людей, родившихся до1950 года, чей доход меньше, чем 1000 существует( Членсемьи), датрождения( Членсемьи,дата(_,_,Год)). Год < 1950.доход(Членсемьи. Доход).Доход <1000. Найти фамилии людей, имеющих по крайней мере трех детей семья(членсемьи(_, Фамилия,_,_), _,[_,_,_|_]).
общий( Список_Людей, Сумма_их_доходов)для которого можло написать процедуру вида:
Теперь общие доходы всех семей могут быть найдены с помощью запроса:общий( [], 0). /* Пустой список людей +/ общий([Человск 1 Список], Сумма) :- доход(Человек, S), /* S - доход 1-ого человека */ общий( Список, Sn), /* Sn - сумма доходов оста:1ьных */ Сумма is S + Sn.
семья( Муж, Жена, Дети), общий( [Муж, Жена, Дети], Доход).Пусть отношение длина подсчитывает количество элементов списка, как это было в работе, посвященной спискам. Тогда мы можем найти все семьи, которые имеют доход на члена семьи, меньший, чем 2000, при помощи запроса:
семья( Муж, Жена, Дети), общий( [Муж, Жена п Дети], Доход), длина([Муж, Жена пДети], N), Доход/N < 2000.Задание 1.
4. Абстракция данных и построение баз знаний
Абстракцию данных можно рассматривать как процесс организации различных фрагментов информации в единые логические единицы. При этом каждой такой логической единице придается некоторая концептуально осмысленная форма. Любая информационная единица должна быть легко доступна в программе. В идеальном случае все детали реализации исходной структуры должна быть невидимы пользователю. И самое главное - дать ему возможность использовать информацию не думая о деталях ее действительного представления.Отец(ИмяРебенка,ИмяОтца), МатыИмяРебенка, ИмяМатсри), Сестра-Брат(Имя1, Имя2).Используя эти отношения, а также знания о родственных связях между людьми в обществе, можно сформировать базу знаний о родственниках, которая, например может содержать следующий набор отношений:
Родитель(ИмяРебенка, ИмяРодителя), Бабушка( ИмяВнука, ИмяБабушки). Дедушка(ИмяВнука, ИмяДедушки),Задание 2.
...
Предок( Кто, Чей).