Студопедия.Орг Главная | Случайная страница | Контакты | Мы поможем в написании вашей работы!  
 

Получение структурированной информации из базы данных



Это упражнение развивает навыки представления структурных объектов данных и управления ими. Оно показывает также, что Пролог является естественным языком запросов к базе данных.

База данных может быть представлена на Прологе в виде множества фактов. Например, в базе данных о семьях каждая семья может описываться одним предложением. На рис. 4.1 показано, как информацию о каждой семье можно представить в виде структуры. Каждая семья состоит из трех компонент: мужа, жены и детей. Поскольку количество детей в разных семьях может быть разным, то их целесообразно представить в виде списка, состоящего из произвольного числа элементов. Каждого члена семьи в свою очередь можно представить структурой, состоящей из четырех компонент: имени, фамилии, даты рождения и работы. Информация о работе — это либо "не работает", либо указание места работа и оклада (дохода). Информацию о семье, изображенной на рис. 4.1, можно занести в базу данных с помощью предложения:

семья(членсемьи(том, фокс, дата(7, май, 1950),

работает(bbс, 15200)),

членсемьи(энн, фокс, дата(9, май, 1951), неработает),

[членсемьи(пат, фокс, дата(5, май, 1973), неработает),

членсемьи(джим, фокс, дата(5, май, 1973), неработает) ]).

Рис. 4.1. Структурированная информация о семье.

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

В действительности Пролог очень удобен для извлечения необходимой информации из такой базы данных. Здесь хорошо то, что можно ссылаться на объекты, не указывая в деталях всех их компонент. Можно задавать только структуру интересующих нас объектов и оставлять конкретные компоненты без точного описания или лишь с частичным описанием. На рис. 4.2 приведено несколько примеров. Так, а запросах к базе данных можно ссылаться на всех Армстронгов с помощью терма

семья(членсемьи(_, армстронг, _, _), _, _)

Символы подчеркивания обозначают различные анонимные переменные, значения которых нас не заботят. Далее можно сослаться на все семьи с тремя детьми при помощи терма:

семья(_, _, [ _, _, _ ])

Чтобы найти всех замужних женщин, имеющих по крайней мере троих детей, можно задать вопрос:

?- семья(_, членсемьи(Имя, Фамилия, _, _), [ _, _, _ | _ ]).

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

Рис. 4.2. Описания объектов по их структурным свойствам: (а) любая семья Армстронгов; (b) любая семья, имеющая ровно трех детей; (с) любая семья, имеющая по крайней мере три ребенка. Структура (с) дает возможность получить имя и фамилию жены конкретизацией переменных Имя и Фамилия.

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

муж(X):- % X - муж

семья(X, _, _).

жена(X):- % X - жена

семья(_, X, _).

ребенок(X):- % X - ребенок

семья(_, _, Дети),

принадлежит(X, Дети).

принадлежит(X, [X | L ]).

принадлежит(X, [Y | L ]):-

принадлежит(X, L).

существует(Членсемьи):-

% Любой член семьи в базе данных

муж(Членсемьи);

жена(Членсемьи);

ребенок(Членсемьи).

дата рождения(Членсемьи(_, _, Дата, _), Дата).

доход(Членсемьи(_, _, _, работает(_, S)), S).

% Доход работающего

доход(Членсемьи(_, _, _, неработает), 0).

% Доход неработающего

Этими процедурами можно воспользоваться, например, в следующих запросах к базе данных:

• Найти имена всех людей из базы данных:

?- существует(членсемьи(Имя,Фамилия, _, _)).

• Найти всех детей, родившихся в 1981 году:

?- ребенок(X), датарождения(X, дата(_, _, 1981)).

• Найти всех работающих жен:

?- жена(членсемьи(Имя, Фамилия, _, работает(_, _))).

• Найти имена и фамилии людей, которые не работают и родились до 1963 года:

?- существует членсемьи(Имя, Фамилия, дата(_, _, Год), неработает)),

Год < 1963.

• Найти людей, родившихся до 1950 года, чей доход меньше, чем 8000:

?- существует(Членсемьи),

датарождения(Членсемьи, дата(_, _, Год)),

Год < 1950,

доход(Членсемьи, Доход),

Доход < 8000.

• Найти фамилии людей, имеющих по крайней мере трех детей:

?- семья(членсемьи(_, Фамилия, _, _), _, [ _, _, _ | _ ]).

Для подсчета общего дохода семья полезно определить сумму доходов людей из некоторого списка в виде двухаргументного отношения:

общий(Список_Людей, Сумма_их_доходов)

Это отношение можно запрограммировать так:

общий([], 0). % Пустой список людей

общий([ Человек | Список], Сумма):-

доход(Человек, S),

% S - доход первого человека

общий(Список, Остальные),

% Остальные - сумма доходов остальных

Сумма is S + Остальные.

Теперь общие доходы всех семей могут быть найдены с помощью вопроса:

?- семья(Муж, Жена, Дети),

общий([Муж, Жена | Дети], Доход).

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

?- семья(Муж, Жена, Дети),

общий([ Муж, Жена | Дети], Доход),

длина([ Муж, Жена | Дети], N),

Доход/N < 2000.





Дата публикования: 2015-10-09; Прочитано: 175 | Нарушение авторского права страницы | Мы поможем в написании вашей работы!



studopedia.org - Студопедия.Орг - 2014-2024 год. Студопедия не является автором материалов, которые размещены. Но предоставляет возможность бесплатного использования (0.007 с)...