
6. 5. Ввод программ: consult, reconsult
Передавать программы пролог-системе можно при помощи двух встроенных предикатов: consult и reconsult. Чтобы система считала программу из файла F, нужно поставить цель
?- consult( F).
В результате все предложения программы, содержащейся в F, будут использованы пролог-системой при ответе на дальнейшие вопросы пользователя. Если позже в том же сеансе произойдет "консультация" с другим файлом, предложения этого нового файла будут просто добавлены в конец текущего множества предложений.
Для того, чтобы запустить программу, не обязательно записывать ее в файл, а затем "консультироваться" с ним. Вместо чтения файла система может принимать программу прямо с терминала, который соответствует псевдофайлу user. Добиться этого можно так:
?- consult( user).
После этого система будет ожидать ввода предложений программы с терминала.
В некоторых пролог - системах применяется сокращенная запись для чтения программ из файлов. Файлы, из которых предстоит чтение, просто помещаются в список и этот список используется в качестве цели. Например:
?- [файл1, файл2, файл3].
Это в точности эквивалентно следующим трем целям:
?- соnsult( файл1), соnsult( файл2), соnsult( файл3).
Встроенный предикат reconsult аналогичен consult. Цель
?- reconsult( F).
даст тот же эффект, что и consult( F) с одним исключением. Если в F есть предложения, касающиеся отношений, которые уже были определены ранее, старые определения заменяются на новые из F. Разница между consult и reconsult в том, что consult всегда добавляет новые предложения, в то время как reconsult переопределяет ранее введенные определения. Однако reconsult не произведет никакого эффекта на те отношения, о которых в F ничего не сказано.
Упражнения
6. 1. Пусть f - файл термов. Определите процедуру
найтитерм( Терм)
которая выводит на терминал новый терм из f, сопоставимый с Терм'ом.
6. 2. Пусть f - файл термов. Напишите процедуру
найтивсетермы( Терм)
которая выводит на экран все термы из f, сопоставимые с Tepм'ом. Обеспечьте при этом, чтобы во время поиска Терм не конкретизировался (это могло бы помешать ему сопоставиться с другими термами дальше по файлу).
6. 3. Обобщите процедуру сжатие на случай запятых. Все пробелы, стоящие непосредственно перед запятой, нужно убрать, а после каждой запятой нужно поместить единственный пробел.
6. 4. Определите отношение
начинается( Атом, Символ)
для проверки, начинается ли Атом с символа Символ.
6. 5. Определите процедуру plural, которая преобразует английские существительные из единственного числа во множественное, добавляя к слову окончание s. Например:
?- plural( table, X).
Х = tables
6. 6. Напишите процедуру
поиск( Ключслово, Предложение)
которая при каждом вызове находит в текущем входном файле предложение, содержащее заданное ключевое слово Ключслово. Предложение в своей исходной форме должно быть представлено в виде последовательности символов или в виде атома (процедуру читпредложение из данного раздела можно соответственно модифицировать).
Ответы
6. 1
найтитерм( Терм) :- % Пусть текущий входной поток - это файл f read( Терм), !, % Текущий терм из f сопоставим с Терм'ом? write( Терм); % Если да - вывести его на терминал найтитерм( Терм). % В противном случае - обработать
6. 2
найтитермы( Терм) :- read( ТекущийТерм), обработать( ТекущийТерм, Терм).
обработать( end_of_file, _ ) :- !.
обработать( ТекущийТерм, Терм) :- ( not( ТекущийТерм = Терм), !; % Термы несопоставимы write( ТекущийТерм), nl), % В противном случае вывести текущий терм найтивсетермы( Терм). % Обработать оставшуюся часть файла
6. 4
начинается( Атом, Символ) :- name( Символ, [ Код]), name( Атом, [Код | _ ]).
6. 5
plural( Существительное, Существительные) :- name( Существительное, СписокКодов), name( s, КодS), конк( СписокКодов, КодS, НовыйСписокКодов), name( Существительные, НовыйСписокКодов).