?- вывспис2( [ [а, b, с], [d, e, f], [g, h, i] ] ).
а b с
d e f
g h i
Процедура, выполняющая эту работу, такова:
вывспис2( [ ]).
вывспис2( [L | LL] ) :-
строка( L), n1,
вывспис1( LL).
строка( [ ]).
строка( [X | L] ) :-
write( X), tab( 1),
строка( L).
Список целых чисел иногда удобно представить в виде диаграммы. Следующая процедура диагрвыводит список в такой форме (предполагается, что числа списка заключены между 0 и 80). Пример ее использования:
?- диагр( [3, 4, 6, 5] ).
***
****
******
*****
Процедуру диагрможно определить так:
диагр( [N | L]) :-
звездочки( N), n1,
диагр( L).
звеэдочки( N) :-
N > 0,
write( *),
Nl is N - 1,
звездочки( Nl).
звездочки( N) :-
N =< 80.
6. 2. 3. Формирование термов
Предположим, наша программа имеет дело с семьями, которые представлены в виде термов так, как это сделано в гл. 4 (рис. 4.1). Тогда, если, перемен-
родители
том фокс, датарожд 7 май 1950, работает bbс,
оклад 15200
энн фокс, датарожд 9 май 1951, неработает
дети
пат фокс, датарожд 5 май 1973, неработает
джим фокс, датарожд 5 май 1973, неработает
Рис. 6. 2. Улучшенный формат вывода термов, представляющих семью.
ная F конкретизирована термом, изображенный на рис. 4.1, то цель
write( F)
вызовет вывод этого терма в стандартной форме примерно так:
семья( членсемьи( том, фокс, дата( 7, май,1950),
работает( bbс, 15200)),
членсемьи( энн, фокс, дата( 9, май, 1951),
неработает),
[членсемьи( пат, фокс, дата( 5, май, 1973),
неработает),
членсемьи( джим, фокс, дата( 5, май, 1973),
неработает)])
Здесь содержится полная информация, однако форма представления легко может запутать, поскольку трудно проследить, какие ее части образуют самостоятельные семантические единицы. Поэтому обычно предпочитают выводить такую информацию в каком-либо формате, например так, как показано на рис. 6.2. Процедура
вывсемью( F)
с помощью которой это достигается, приведена на рис. 6.3.
вывсемью( семья ( Муж, Жена, Дети) :-
nl, write( родители), nl, nl,
вывчленсемьи( Муж), nl,
вывчленсемьи( Жена), nl, nl,
write( дети), nl, nl,
вывчленсемьи( Дети).
вывчленсемьи( членсемьи( Имя, Фамилия, дата( Д, М, Г), Работа) ) :-
tab(4), write( Имя),
tab(1), write( Фамилия),
write( ', дата рождения'),
write( Д), tab( 1),
write( M), tab( 1),
write( Г), write( ','),
вывработу( Работа).
вывсписчлсемьи( [ ]).
вывсписчлсемьи( [Р | L]) :-
вывчленсемьи( Р), nl,
вывсписчлсемьи( L),
вывработу( неработает) :-
write( неработает).
вывработу( работает Место, Оклад) ) :-
write(' работает '), write( Место),
write( ', оклад '), write( Оклад).
Рис. 6. 3. Программа, обеспечивающая вывод в формате, представленном на рис. 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( Терм),
Читать дальше