- •Язык программирования турбо пролог
- •4.4. Переопределение стандартного ввода-вывода
- •4.5. Работа с файлами
- •5. Внутренняя база данных турбо пролога
- •5.1. Объявление внутренней базы данных
- •5.2. Обновление внутренней базы данных
- •5.3. Занесение фактов во время исполнения.
- •5.4. Удаление фактов во время выполнения программы
- •506 Type Error: The functor does not belong to the domain (функтор не относится к данному домену)
- •5.5. Чтение новых фактов иэ файла во время выполнения программы
- •5.6. Сохранение базы данных во время работы программы
- •6. Трассировка и отладка пролог программ
- •6.1. Синтаксическая проверка
- •6.2. Трассировка
- •6.2.1. Директивы трассировки
- •6.2.2. Трассировка в режиме оптимизации: shorttrace
- •6. 2. 3. Трассировка предикатов
- •6.2.4. Предикат trace
- •6.2.5. Диалоговое управление трассировкой
- •6.3. Директивы компилятора и отладка
- •6.4. Сообщения об ошибках во время выполнения программы
- •6.5. Опции компилятора из меню
- •7.Заключение
- •8. Литература:
- •Содержание:
4.4. Переопределение стандартного ввода-вывода
. Домен file имеет три дополнительные опции: stdin, stdout, stderr. Преимущество этих файлов в том, что вы можете указать операционной системе ДОС на необходимость переназначения стандартного ввода-вывода в командной строке.
stdin
|
Стандартный ввод является файлом, доступным толькодля чтения. По умолчанию это клавиатура readdevice (stdin) назначает устройством ввода stdin. |
stdout.
|
Стандартный вывод является файлом, доступным,только для записи. По умолчанию это экран терминала.Writedevice (stdout) назначает устройством вывода stdout.
|
stderr
|
Стандартный вывод ошибок является файлом. Доступен только для записи. Это всегда экран терминала writedevice (stderr) назначает устройством для вывода сообщений об ошибках экран.
|
4.5. Работа с файлами
В этом разделе будет описано несколько других предикатов для работы с файлами. Это предикаты filepos, eof, flush, existfile,de-letefile, renamefile и disk.
Предикат filepos может управлять позицией, где производится чтение или запись. Он имеет формат:
filepos (SynbolicFileName, FilePosition, Mode) /*(i;i,i),(i,o,i) */
Если FilePosition - связанная переменная, предикат может изменить позицию чтения и записи для файла. Если при вызове FilePosition является свободной переменной, то SymbolicFileNan» возвращает текущую позицию в файле.
FilePosition должно иметь вещественное значение (любая дробная часть игнорируется).
Mode является целой и указывает, как значение должно интерпретироваться (согласно таблице 4.1.) значение FilePosition.
Когда возвращается FilePositson, filepos возвращает позицию относительно начала файла.
Замечание: При использовании filepos, новая строка 8 файле считается как два символа.
Таблица 4.1
Mode |
FilePosition |
0 |
Относительно начала файла. |
1 |
Относительно текущей позиции. |
2 |
Относительно конца файла. (Конец файла соответствует позиции 0.) |
Примеры. Следующая последовательность запишет значение Text в файл SOMEFILE. PRO (к которому Пролог обращается, _как к myfilе ), начиная с позиции 100 (относительно начала файла).
Text * "A text to be written in the file",
openmodiry(myfile,"somefile.pro")
writedevice (myfile),
filepos(myfile,100,0),
write(Text).
Используй filepos, можно проверить содержимое файла байт за байтом, как это сделано в следующей программе. Эта программа запрашивает имя файла, затем показывает содержимое позиций файла, причем номера позиций вводятся клавиатуры.
domains
file = input
predicates
inspect_positions goal
write("Which file do you want to work with?"),
readln(FileName),
openread( input,FileName),
inspect_positions. clauses
inspect_position :-readdevice(keyboard),
nl,write("Position No? ") , readreal(X),
readdevice( input), filepos(input, X,0),
readchar(Y),write("Char is:",Y), inspect_positions.
Предикат eof проверяет является ли позиция, полученная в процессе чтения, концом файла. В этом случае eof успешна. В противном случае он терпит неудачу. eof имеет вид:
eof (SymbolicFileName) /* (i) */
Предикат eof можно использовать для определения предиката repfile, который полезен при работе с файлами, repfile генерирует точку возврата до тех пор, пока не будет достигнут конец файла.
predicates
repfile(FILE) clauses
repfile(_).
repfile(F): -not(eof(F)(),repfile(F).
Следующая программа преобразует один файл в другой, все буквы которого являются прописными.
domains
file = input; output predicates
convertfille
repfile(FILE) goal
wite(Which file do you want convert ?"), readln(InputFileName),
wite(What is the name of the output file/"),
readln(OutputFileName),
openread (input,InputFileName), readdevice(input), openwrite (output,OutputFileName), writedevice(output), convertfile, closefile(input), closefile(output). clauses
convertfile: -
repfile(input),
readln(Ln),
upper_lower( LnInUpper,Ln),
/* перевод букв строки в заглавные*/_
write(LnInUpper),nl,
fail.
convertfile. repfile(_), repfile(F): -not(eof(F),repfile(F).
Предикат flush записывает содержимое внутреннего. буфера в названный файл. Имеет формат:
flush (SymbolicFileName) /*(i) */
Предикат flush полезен, когда вывод направляется на устройство печати, и вам необходимо выдать данные на печать до того, как буфер заполнится.
Замечание: После операции flush, так как ДОС перед
закрытием файла не запишет файловые буферы на диск, не
обеспечивается сохранность дисковых файлов. Единственный
путь гарантировать целостность дискового файла: это закрыть
его (и снова открыть, когда это будет необходимо).
Предикат existfile выполняется успешно, если файл DosFileName будет найден в каталоге ДОС на текущем дисковом уст ройстве. Формат его следующий:
existfile(DosFileName) /*(i) */
Предикат existfile терпит неудачу, если имя не найдено в каталоге или имя файла неправильно, или содержит глобальные символы поиска (например, MY*.PRO или ??PROJ.* ).
Для проверки того, что файл присутствует на диске, прежде чем открывать его вы можете использовать следующую последовательность:
open(File,Name): -
existfile(Name),£,
openread(File,Name). open(_,Name) : -
write("Error: the file ",Name," is not found").
Предикат deletefile удаляет файл, заданный его аргументом и имеет такой формат:
deletefile(DosFileName) /*(i) */
Предикат deletefile даст ошибку, если не сможет удалить файл.
Предикат renamefile переименовывает файл с именем OldDosFileName в NewDosFileName. Имеет формат:
renamefile(0ldDosFileName,NewDosFileName) /* (i,i) */
Предикат renamefile будет успешен, если файл с именем
NewDosFileName еще не существует, и оба имени являются допустимыми.
В противном случае будет выдана ошибка
Предикат disk используется для изменения текущего диска и каталога/подкаталога и имеет формат:
disk(DosPath) /*(i) (о) */
При вызове свободной переменной в качестве параметра disk возвратит текущий каталог.