Внутренняя база данных
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 баллов. Результатом теста является сумма полученных баллов.