Модификация существующего файла




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

Предикат

 

openmodify(datafilel,"FILE1.DAT")

 

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

Содержимое файла можно рассматривать как поток символов. Каждый символ находится в файле на какой-то позиции. Позиция определяется уда­ленностью от первого символа файла. Таким образом, первый символ в фай­ле занимает нулевую позицию, второй — первую и т. д. Вообразим себе те­перь невидимый указатель, который можно сместить на любую позицию файла. Этот указатель определяет позицию, из которой будет прочитан или в которую будет записан очередной символ.

Когда файл открывается для модификации, указатель помещается в на­чало файла. Турбо-Пролог позволяет смещать указатель при помощи преди­ката filepos, который будет подробно рассмотрен в разделе, посвященном файлам прямого доступа. В настоящий момент вам требуется знать лишь то, где будет располагаться указатель после вызова openmodify.

 

Модификацию файла можно разбить на следующие шаги:

1. Открытие файла

 

openwodify(datafilel."FILE1.DAT")

 

2. Переадресация вывода в файл

 

writedevice(datafilel)

3. Запись в файл новых данных.

4. Использование произвольных предикатов и правил, отвечающих целям программы.

5. Закрытие файла

 

closefile(datafilel)

 

Примером может служить

openmodify(datafile1."FILE1.DAT"),

wr1tedev1ce(datafilel),

< правила для выборочной записи в файл >,

< любые другие правила или предикаты >

closefile(datafilel).

 

Дозапись в конец уже существующего файла

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

Следующие шаги необходимо предпринять для добавления новых данных в конец файла:

1. Открытие файла

openappend(datafile1."FILE1.DAT")

2. Переадресация вывода в файл

writedevice(datafile1).

3. Дозапись в файл новых данных при помощи соответствующих правил.

4. Использование произвольных предикатов и правил, отвечающих целям программы.

5. Закрытие файла

 

closefile(datafilel)

Например,

openappend(datafi1e1,"FILE1.DAT"),

writedevice(datafilel).

< любые правила для дозаписи в файл >,

< любые другие правила или предикаты >

closefile(datafile1).

 

Задание.

Разработать программу для формирования базы данных с клавиатуры и записи в файл. После ввода слова «list», вывести все содержимое файла на экран (таблица.5).

Таблица 5

Вариант Предметная область Количество объектов Количество параметров объекта
  Города    
  Автомобили    
  Компьютеры    
  Дома    
  Самолеты    
  Страны    
  Студенты    
  Партии    
  Сотрудники    
  Вакансии    
  Операционные системы    
  Книги    
  Телефонный справочник    
  Предприятия    
  Автобусные маршруты    

 

Лабораторная работа № 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.

Абстракция данных

Абстракцию данных можно рассматривать как процесс 1 организации различных фрагментов информации в единые логические единицы (возможно, иерархически), придавая ей при этом некоторую концептуально ос­мысленную форму. Каждая информационная единица должна быть легко доступна в программе. В идеальном случае все детали реализации такой структуры должны быть невидимы пользователю этой структуры. Самое главное в этом процессе — дать программисту возможность использовать информацию, не думая о деталях ее действительного представления.

Обсудим один из способов реализации этого прин­ципа на Прологе. Рассмотрим снова пример с семьей. Каждая семья — это набор некоторых фрагментов информации. Все эти фрагменты объединены в естественные информационные единицы, такие, как «член семьи» или «семья», и с ними мож­но обращаться как с едиными объектами. Предположим опять, что информация о семье структурирована так же, как на рис. 117. Определим теперь некоторые отношения, с помощью которых пользователь может получать доступ к конкретным компонентам семьи, не зная деталей рис. 117. Такие отношения можно на­звать селекторами, поскольку они позволяют выби­рать конкретные компоненты. Имя такого отношения-селектора будет совпадать с именем компоненты, которую нужно выбрать. Отношение будет иметь два аргумента: первый — объект, который содержит ком­поненту, и второй - саму компоненту:

 

отношение_селектор(Объект,Выбранная_компонента)

 

Вот несколько cелекторов для структуры семья:

 

муж(семья Муж, _,), Муж).

жена(семья(,Жена,), Жена).

дети(семья(_, _, СписокДетей), СписокДетей).

 

Можно также создать селекторы для отдельных детей семьи:

 

первыйребенок(Семья, Первый):-

дети(Семья, [Первый | ù).

второйребенок(Семья, Второй):-

дети(Семья, [_, Второй | ù).

 

Можно обобщить этот селектор для выбора N-го ребенка:

 

n ребенок(N,Семья, Ребенок):-

дети(Семья, СписокДетей),

n _ элемент(N, СписокДетей, Ребенок)

/* N-й элемент списка */

 

Другим интересным объектом является «член семьи». Вот некоторые связанные с ним селекторы, соответ­ствующие рис. 28:

 

имя(членсемьи(Имя,_, _, _), Имя).

фамилия(членсемьи(_, Фамилия,,_), Фамилия).

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

Какие преимущества мы можем получить от использования отношений-селекторов? Определив их, мы можем теперь забыть о конкретном виде структуры представления информации. Для пополнения и обра­ботки этой информации нужно знать только имена отношений-селекторов и в оставшейся части програм­мы пользоваться только ими. В случае, если инфор­мация представлена сложной структурой, это легче, чем каждый раз обращаться к ней в явном виде. В частности, в нашем примере с семьей пользователь не обязан знать, что дети представлены в виде списка. Например, предположим, мы хотим сказать, что, Том Фоке и Джим Фоке принадлежат к одной семье и что Джим - второй ребенок Тома Используя приве­денные выше отношения -селекторы, мы можем опреде­лить двух человек, назовем их Человек1 и Человек2 и семью. Следующий список целей приводит к желае­мому результату:

имя(Человек1, том), фамилия(Человек1, фокc),

/* Человек1 - Том Фокc */

имя(Человек2, джим), фамилия(Человек1, фокc),

/* Человек2 - Джим Фокс */

муж(Семья, Человек1),

второйребенок(Семья, Человек2)

 

Использование отношений-селекторов облегчает также ипоследующую модификацию программ.

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

 

Задание.

Разработать базу данных с вложенной структурой, соответствующей заданной предметной области и глубины (таблица 6).

Таблица 6

Вариант Предметная область Глубина вложения
  Семья  
  Структура предприятия  
  Компьютеры  
  Структура локальной сети  
  Студенты  
  Автомобили  
  Корабли  
  Самолеты  
  Телефонный справочник  
  Страны  
  Структура сайтов  
  Структура книг  
  Футбольная команда  
  Квартиры  
  Структура фирмы  

 



Поделиться:




Поиск по сайту

©2015-2024 poisk-ru.ru
Все права принадлежать их авторам. Данный сайт не претендует на авторства, а предоставляет бесплатное использование.
Дата создания страницы: 2016-04-27 Нарушение авторских прав и Нарушение персональных данных


Поиск по сайту: