6.2.

6.2.4. Обработка произвольного файла термов

Типичная последовательность целей для обработки файла F от начала до конца будет выглядеть примерно так:

... , see( F), обработкафайла, sеe( user), ...

Здесь обработкафайла — процедура, которая читает и обрабатывает последовательно каждый терм файла F один за другим до тех пор, пока не встретится конец файла. Приведем типичную схему для процедуры обработкафайла:

обработкафайла :-

 read( Терм),

 обработка( Терм).

обработка( end_of_file) :- !.

 % Все сделано

обработка( Терм) :-

 обраб( Терм),

  % Обработать текущий элемент

 обработкафайла.

  % Обработать оставшуюся часть файла

Здесь обраб( Терм) представляет процедуру обработки отдельного терма. В качестве примера такой обработки рассмотрим процедуру, которая выдает на терминал каждый терм вместе с его порядковым номером. Назовем эту процедуру показфайла. У нее должен быть дополнительный аргумент для подсчета прочитанных термов:

показфайла( N) :-

 read( Терм),

 показ( Терм, N).

показ( Терм, N) :- !

 write( N), tab( 2), write( Терм),

 N1 is N + 1,

 показфайла( N1).

Вот другой пример программы обработки файлов, построенной по подобной схеме. Пусть есть файл с именем файл1, термы которого имеют форму

изделие( НомерИзд, Описание, Цена, ИмяПоставщика)

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

создатьфайл( Поставщик)

Например, если исходный каталог хранится в файле файл1, а мы хотим создать специальный каталог в файле файл2, содержащий всю информацию о том, что поставляет Гаррисон, тогда мы применим процедуру создатьфайл следующим образом:

?- seе( файл1), tеll( файл2), создатьфайл( гаррисон),

 see( user), tell( user).

Процедуру создатьфайл можно определить так:

создатьфайл( Поставщик) :-

 write( Поставщик), write( '.'), nl,

 создатьостальное( Поставщик).

создатьостальное( Поставщик) :-

 read( Изделие),

 обработать( Изделие, Поставщик).

обработать( end_ot_file) :- !.

обработать( Изделие( Ном, Опис, Цена, Поставщик),

 Поставщик) :- !,

 write( Изделие( Ном, Опис, Цена) ),

 write( '.'), nl,

 создатьостальное( Поставщик).

обработать ( _, Поставщик) :-

 создатьостальное( Поставщик).

Обратите внимание на то, что обработать вписывает точки между термами, чтобы впоследствии файл мог быть прочитан процедурой read.

Упражнения

6.1. Пусть f — файл термов. Определите процедуру

найтитерм( Терм)

которая выводит на терминал новый терм из f, сопоставимый с Терм'ом.

6.2. Пусть f — файл термов. Напишите процедуру

найтивсетермы( Терм)

которая выводит на экран все термы из f, сопоставимые с Tepм'ом. Обеспечьте при этом, чтобы во время поиска Терм не конкретизировался (это могло бы помешать ему сопоставиться с другими термами дальше по файлу).

6.3. Обработка символов

Символ записывается в текущий выходной поток при помощи цели

put( С)

где С — символ, который нужно вывести, в кодировке ASCII (число от 0 до 127), например, вопрос

?- put( 65), put( 66), put( 67).

породит следующий вывод:

АВС

65 — ASCII-код 'А', 66 — 'В', 67 — 'С'.

Одиночный символ можно считать из текущего входного потока при помощи цели

get0( С)

Она вызывает чтение символа из входного потока, и переменная С конкретизируется ASCII-кодом этого символа. Вариантом предиката get0 является get, который используется для чтения символов, отличных от пробела. Поэтому цель

get( С)

вызовет пропуск всех непечатаемых символов (в частности пробелов) от текущей позиции во

Добавить отзыв
ВСЕ ОТЗЫВЫ О КНИГЕ В ИЗБРАННОЕ

0

Вы можете отметить интересные вам фрагменты текста, которые будут доступны по уникальной ссылке в адресной строке браузера.

Отметить Добавить цитату