- •Лабораторная работа № 4 Работа со списками
- •3.1 Длина строки
- •3.2 Конкатенация строк
- •3.3. Создание подстрок
- •3.4. Преобразование данных
- •3.5. Преобразования, определяемые пользователем
- •3.6 Создание символьных префиксов
- •3.7. Преобразование строк
- •3.8. Формирование атомов из строк
- •Лабораторная работа № 5 Работа с файлами
- •4.1.Предикаты для работы с файлами
- •Описание файлового домена
- •Запись в файл
- •Чтение из файла
- •Модификация существующего файла
- •Дозапись в конец уже существующего файла
- •Лабораторная работа № 6 Структуры
- •Абстракция данных
Дозапись в конец уже существующего файла
Возможность записать новые данные в конец уже существующего файла обеспечивается в Турбо-Прологе предикатом openappend. Когда файл открывается для дозаписи, указатель файла смещается в его конец.
Следующие шаги необходимо предпринять для добавления новых данных в конец файла:
Открытие файла
openappend(datafile1."FILE1.DAT")
Переадресация вывода в файл
writedevice(datafile1).
Дозапись в файл новых данных при помощи соответствующих правил.
Использование произвольных предикатов и правил, отвечающих целям программы.
Закрытие файла
closefile(datafilel)
Например,
openappend(datafi1e1,"FILE1.DAT"),
writedevice(datafilel).
< любые правила для дозаписи в файл >,
< любые другие правила или предикаты >
closefile(datafile1).
Задание.
Разработать программу для формирования базы данных с клавиатуры и записи в файл. После ввода слова «list», вывести все содержимое файла на экран (таблица.5).
Таблица 5
Вариант |
Предметная область |
Количество объектов |
Количество параметров объекта |
1 |
Города |
10 |
3 |
2 |
Автомобили |
9 |
4 |
3 |
Компьютеры |
10 |
3 |
4 |
Дома |
7 |
4 |
5 |
Самолеты |
8 |
3 |
6 |
Страны |
7 |
4 |
7 |
Студенты |
7 |
3 |
8 |
Партии |
7 |
4 |
9 |
Сотрудники |
9 |
3 |
10 |
Вакансии |
8 |
4 |
11 |
Операционные системы |
7 |
3 |
12 |
Книги |
7 |
4 |
13 |
Телефонный справочник |
7 |
3 |
14 |
Предприятия |
8 |
4 |
15 |
Автобусные маршруты |
8 |
3 |
Лабораторная работа № 6 Структуры
Структуры данных вместе с сопоставлением, автоматическими возвратами и арифметикой представляют собой мощный инструмент программирования.
База данных может быть представлена на Прологе в виде множества фактов. Например, в базе данных о семьях каждая семья может описываться одним предложением. На рис. 28 показано, как информацию о каждой семье можно представить в виде структуры.
Каждая семья состоит из трех компонент: мужа, жены и детей.
Поскольку количество детей в разных семьях может быть разным, то их целесообразно представить в виде списка, состоящего из произвольного числа элементов. Каждого члена семьи в свою очередь можно представить структурой, состоящей из четырех компонент: имени, фамилии, даты рождения и работы. Информация о работе - это либо «не работает», либо указание места работы и оклада (дохода). Информацию о семье, изображенной на рис.28, можно занести в базу данных с помощью предложения:
семья(
членсемьи(том,фокс,дата(7,май,1950),
работает(bbс, 15200)),
[членсемьи(знн, фокc, дата(9, май, 1951),
неработает),
[членсемьи(пат, фокc, дата(5, май, 1973),
неработает),
членсемьи(джим, фокc, дата(5, май, 1973),
неработает)]).
Рис. 28. Структурированная информация о семье
Тогда база данных будет состоять из последовательности фактов, подобных этому, и описывать все семьи, представляющие интерес для нашей программы. ; В действительности Пролог очень удобен для извлечения необходимой информации из такой базы данных. Здесь можно ссылаться на объекты, не указывая в деталях всех их компонент. Можно задавать только структуру интересующих вас объектов и оставлять конкретные компоненты без точного описания или лишь с частичным описанием. На рис. 29 приведено несколько примеров. Так, в запросах к базе данных можно ссылаться на всех Армстронгов с помощью терма
семья(членсемьи( , армстронг, _,_),_,_)
Символы подчеркивания обозначают различные анонимные переменные, значения которых нас не заботят. Далее можно сослаться на все семьи с тремя детьми при помощи терма:
семья( _, _, [_, _ , _])
Чтобы найти всех замужних женщин, имеющих по крайней мере троих детей, можно задать вопрос:
- семья(_,членсемьи(Имя, Фамилия, _,_),[_,_,_| ).
Главным моментом в этих примерах является то, что указывать интересующие нас объекты можно не только по их содержимому, но и по их структуре. Мы задаем одну структуру и оставляем ее аргументы в виде слотов (пропусков).
Рис. 29. Описания объектов по их структурным свойствам;
а — любая семья Армстронгов; б — любая семья, имеющая ровно трех детей; с — любая семья, имеющая по крайней мере три ребенка. Структура (с) дает возможность получить имя в фамилию жены конкретизацией переменных Имя и Фамилия
Можно создать набор процедур, который служил бы утилитой, делающей взаимодействие с нашей базой данных более удобным. Такие процедуры являлись бы частью пользовательского интерфейса. Вот некоторые полезные процедуры для нашей базы данных:
муж(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 + Остальные.
Теперь общие доходы всех семей могут быть найдены с помощью вопроса:
- семья( Муж, Жена, Дети),
общий( [Муж, Жена | Дети], Доход).
Пусть отношение длина подсчитывает количество элементов списка. Тогда мы можем найти все семьи, которые имеют доход на члена семьи, меньший, чем 2000, при помощи вопроса:
- семья(Муж, Жена, Дети),
общий([ Муж, Жена \ Дети], Доход),
длина([ Муж, Жена | Дети], N),
Доход/N < 2000.
