Внутренняя база данных
4.6. Работа с файлами
Рассмотрим пример работы с файлами в языке Visual Prolog. В приведенной ниже программе на вход подается имя текстового файла. Определяется способ его кодировки, Unicode или нет, а затем создаются два ANSI-файла. В один из них записываются четные по номеру строки из исходного файла, а в другой — нечетные.
class facts
n : positive := 0.
class predicates
type: (string FileName, stream::mode Mode) procedure (i,o).
rewrite: (string, stream::mode, string File1, string File2)
determ (i,o,i,i).
clauses
type(FileName, stream::unicode()):-
file::isUnicode(FileName),
!.
type(_, stream::ansi(ansi())).
rewrite(FileName, Mode, FileName1, FileName2):-
file::existFile(FileName),
type(FileName, Mode),
Input = inputStream_file::openFile(FileName, Mode),
F1 = outputStream_file::create8(FileName1),
F2 = outputStream_file::create8(FileName2),
std::repeat(),
Str = Input:readLine(),
n := 1 - n,
if n = 1 then
F1:write(Str), F1:nl
else
F2:write(Str), F2:nl
end if,
Input:endOfStream(),
!,
Input:close(),
F1:close(),
F2:close().
run():-
FileName = "mytest.txt", File1 = "test1.txt", File2 = "test2.txt",
rewrite(FileName, Mode, File1, File2),
writef("FileName %\nMode: %\nЧисло строк = %\n",
FileName, Mode, n),
writef("Нечетные строки в файле %, а четные в файле %\n",
File1, File2),
write(file::readString(FileName, _)), % счит. файл в string
fail;
_ = readLine().
Пример
4.4.
Перезапись из текстового файла в ANSI-файлы
Предикат isUnicode проверяет, используется ли для файла кодировка символов Юникод. Конструктор openFile открывает файл для чтения, предикат close закрывает файл. Предикат create8 создает ANSI-файл для записи. Предикат endOfStream проверяет, достигнут ли конец файла. Предикат readString считывает файл в строку.
4.7. Атрибуты текста в консоли. Очередь событий
В системе Visual Prolog имеются средства, которые позволяют использовать в консольных приложениях цвет, события мыши, события нажатия клавиши и др. Программа, приведенная ниже, создает в окне консоли цветную полосу, состоящую из "квадратов" (шириной в два пробельных символа), цвет которых генерируется случайным образом в процессе repeat-цикла. Задействовано 15 цветов, черный цвет не используется. Перед появлением каждого "квадрата" делается небольшая пауза. Цикл прекращается после щелчка мыши, когда курсор находится в произвольном месте окна консоли (рис. 4.1).
В комментарии указано, как остановить цикл посредством нажатия определенной клавиши.
open core, console, console_native
class predicates
getAttribute: (unsigned16 ЦветФона, unsigned16 ЦветТекста)
-> unsigned16.
clauses
getAttribute(BgColor, TextColor) =
bit::bitOr(bit::bitLeft(BgColor, 4), TextColor).
class predicates
stop: () determ.
process: ().
clauses
stop():-
L = getEventQueue(),
% key(_, _, _, _, 'k', _) = list::getMember_nd(L),
mouse( _, _, 1, _, 0) = list::getMember_nd(L),
!.
process():-
std::repeat(),
N = 1 + math::random(15),
setTextAttribute(bit::bitLeft(N, 4)), % или (N * 16)
write(" "), % два пробельных символа
programControl::sleep(100),
stop(),
!.
process().
run():-
setLocation(coord(20, 10)),
setTextAttribute(getAttribute(3, 15)),
write("Движение прекратится по щелчку мыши"),
programControl::sleep(3000), % 3 сек
clearOutput(), % очищает буфер вывода
setLocation(coord(0, 1)),
process(),
_ = readLine().
Пример
4.5.
"Цвета в консоли"
Предикат getEventQueue возвращает для окна консоли список текущих событий. Предикат getMember_nd недетерминированно возвращает произвольный элемент списка. Предикат setTextAttribute устанавливает в консоли атрибуты текста. Предикат setLocation помещает курсор в точку с заданными координатами. Началом координат в окне консоли является его левый верхний угол, ось абсцисс направлена вправо, а ось ординат — вниз. Единицей измерения по оси абсцисс является ширина одного символа (все они имеют одинаковую ширину), а по оси ординат — высота строки. Предикат random генерирует целое неотрицательное случайное число. Если его аргумент равен R, то генерируется число в пределах от 0 до R – 1 включительно.
Упражнения
- Решите ребус:
. В этой записи разным буквам соответствуют разные цифры, причем первая цифра в записи чисел отлична от нуля. - Создайте базу данных, в которой для каждого сотрудника хранятся фамилия, должность и оклад. Определите средний размер оклада у программистов.
-
Создайте базу данных "Мое расписание", в которой хранятся факты для описания отношения расписание вида:
расписание(время(пт, 1), предмет("Интеллектуальные системы", лекция), преп("Аншаков О.М.", профессор), место(416, 2)).Факты должны содержать следующие сведения: день недели и номер пары; предмет — название и вид занятия (лекционное и т. д.); фамилия и инициалы преподавателя, его должность; аудитория и корпус.
Найдите ответы на следующие вопросы.
- Кто ведет "Английский язык"?
- Когда и где проходят занятия по курсу "Экспертные системы"?
- В каких аудиториях проводятся занятия по вторникам и средам?
- В какие дни недели ровно три пары?
- По какие предметам лабораторные занятия ведет только лектор.
- Найдите количество строк в файле.
- Запишите в новый файл поочередно строки то из одного файла, то из другого.
- Реализуйте вывод цветной полосы "змейкой".
- Напишите программу, которая генерирует случайным образом 15 попарно различных точек плоскости с целыми координатами в пределах от 0 до 79 по оси абсцисс и от 0 до 22 по оси ординат. Найдите все тройки точек, которые образуют треугольники максимальной площади. Отобразите точки в окне консоли. Вершины найденных треугольников выделите цветом.
- Напишите программу для тестирования учащихся по какому-либо предмету. Тест состоит из n вопросов. Приводятся варианты ответов, среди которых один правильный. Тестируемый должен указать номер правильного ответа. За каждый правильный ответ ему начисляется m баллов. Результатом теста является сумма полученных баллов.
