Метод взаимодействия пользователя и программы, который применялся до сих пор, предусматривал ввод пользователем вопросов к программе и получение ответов программы в виде результатов конкретизации переменных. Такой метод обмена данными является простым и достаточным для обеспечения ввода и вывода информации. Тем не менее он часто является не совсем приемлемым, поскольку не обладает достаточной гибкостью. Поэтому этот основной метод обмена данными необходимо дополнить в следующих областях:
• ввод данных в форматах, отличных от вопросов, например в форме английских предложений;
• вывод информации в любом требуемом формате;
• ввод и вывод в любой компьютерный файл или на любое устройство, а не только на пользовательский терминал.
Состав встроенных предикатов, предназначенных для использования в качестве подобных расширений, зависит от реализации Prolog. В данной главе рассматривается простой и удобный набор соответствующих предикатов, который входит в состав многих реализаций Prolog. Тем не менее необходимо всегда обращаться к руководству по соответствующей реализации Prolog для ознакомления с подробными сведениями и характерными особенностями тех или иных средств. Во многих реализациях Prolog предусмотрены различные дополнительные средства, не описанные в данной главе. К ним относятся, в частности, средства работы с окнами, графические примитивы для рисования на экране, средства ввода информации с помощью мыши и т.д.
Вначале рассматривается тема, связанная с перенаправлением ввода и вывода информации в файлы, а затем показано, как можно обеспечить ввод и вывод данных в различных формах.
На рис, 6.1 показана общая ситуация, в которой программа Prolog осуществляет обмен данными с несколькими файлами. В принципе, программа может считывать данные из нескольких входных файлов, называемых также входными потоками, и выводить данные в несколько выходных файлов, которые называются выходными потоками. Данные, поступающие с пользовательского терминала, рассматриваются как еще один входной поток. Аналогичным образом, данные, выводимые на терминал, представляют собой один из выходных потоков. Эти потоки не фиксируются на жестком диске, но связаны с информационными структурами, аналогичными файлам (которые принято называть пстдофаилами) и известными под именем user. Имена других файлов могут быть выбраны программистом с учетом правил именования файлов в используемой компьютерной системе.
Пользовательский терминал
Пользователь! 1 Пользователь
Входные, потоки i Фаил 1
файл 2 ■
»ап i \ Выходные -файл 4
Рис, 6,1. Взаимодействие программы Prolog и нескольких файлов
В любой момент времени в ходе выполнения программы Prolog "активны" только два файла: один для ввода, а другой для вывода. Эти два файла, соответственно, называются текущим входным потоком и текущим выходным потоком. В начале выполнения программы эти два потока соответствуют пользовательскому терминалу. Текущий входной поток можно перевести в другой файл, Filename, с помощью следующей цели: see! Filename)
Эта цель достигается (если только не обнаружится какая-либо ошибка, связанная с переменой Filename) и вызывает в качестве побочного эффекта то, что ввод переключается с предыдущего входного потока на файл Filename. Поэтому типичным примером использования предиката see является приведенная ниже последовательность целей, которая обеспечивает чтение определенных данных из файла file!, a затем повторное переключение на терминал,
see(filel),
read from file) Information), see fuser),
Текущий выходной поток можно изменить с помощью цели, заданной в следующей форме:
tell! Filename)
Ниже приведена последовательность целей для вывода некоторой информации в файл f ile3, а затем перенаправления последующего вывода снова на терминал.
Глава 6. Вводи вывод
tell(file3),
write_on_file£ Information),
tell { -user),
Цель
seen
закрывает текущий входной файл, а цель
told
закрывает текущий выходной файл.
В данной главе предполагается, что файлы могут обрабатываться только последовательно, хотя во многих реализациях Prolog предусмотрена также обработка файлов с произвольным доступом. Последовательные файлы обрабатываются таким же образом, как и потоки на терминале. Каждый запрос на чтение определенной информации из входного файла вызывает чтение данных с текущей позиции в текущем вход-пом потоке. После чтения текущая позиция, безусловно, перемещается на следующий непрочитанный элемент. Поэтому выполнение следующего запроса на чтение начинается с чтения данных в этой новой текущей позиции. Если запрос на чтение выполняется в конце файла, то информация, возвращаемая таким запросом, представляет собой атом end_of_file.
Операции записи выполняются таким же образом; каждый запрос на вывод информации приводит к добавлению этой информации к концу текущего выходного потока. Возможность возвращаться назад и перезаписывать часть файла не предусмотрена.
В этой главе рассматриваются только тая называемые текстовые файлы, т.е. файлы, состоящие из символов. Символы представляют собой буквы, цифры и специальные символы. Некоторые из специальных символов называются непечатаемыми, поскольку после вывода их на терминал они не появляются на экране. Но эти символы могут оказывать иной эффект, например изменять интервалы между столбцами и строками на экране.
Файлы могут обрабатываться в языке Prolog двумя основными способами, в зависимости от формы представления в них информации. Один из способов состоит в том, что основным элементом файла является символ. В соответствии с этим один запрос на ввод или вывод вызывает чтение или запись единственного символа. В этой главе предполагается, что для этого служат встроенные предикаты get, getO и put.
Еще один способ обработки файлов состоит в том, что в качестве основных структурных блоков файла рассматриваются более крупные информационные единицы. Вполне естественно, что в качестве такой более крупной единицы принят терм Prolog. Поэтому при каждом запросе ввода-вывода такого типа из текущего входного потока или в текущий выходной поток передается, соответственно, целый терм. Предикатами для передачи термов являются read и write. Разумеется, в этом случае информация в файле должна находиться в форме, совместимой с синтаксисом термов.
Безусловно, выбор той или иной организации файла зависит от рассматриваемой задачи. Если спецификация задачи позволяет представить информацию естественным образом в синтаксической структуре термов, то следует использовать файл, состоящий из термов. В таком случае появляется возможность передавать целый осмысленный фрагмент информации с помощью одного запроса. С другой стороны, есть такие задачи, характер которых определяет необходимость использования некоторой другой организации файлов. В качестве примера можно назвать обработку предложений на естественном языке, например, для организации диалога на английском языке между системой и пользователем. В подобных случаях файлы должны рассматриваться как последовательности символов, которые нельзя непосредственно интерпретировать как термы.
Часть I. Язык Prolog