Опубликован: 11.02.2005 | Уровень: специалист | Доступ: свободно
Лекция 6:

Сентенциальное программирование: PROLOG

< Лекция 5 || Лекция 6: 12345 || Лекция 7 >

Организация вычислений и ввода-вывода

Во многих случаях даже в поисковой программе необходимо производить вычисления. В языке PROLOG имеется способ вычисления значения по аргументам. Это так называемые встроенные функции, которые могут быть заменены на свое значение, если их аргумент известен. Такими функциями служат, в частности, числовые арифметические операции. Заметим, что даже встроенная функция не вычисляется, пока не будет дан явный сигнал. У Вас в программе может, скажем, накопиться в качестве значения переменной выражение 1 + 1 + 1, но оно не будет равно 3.

Для организации вычисления имеется специальное отношение X is E. В этом отношении Е является таким выражением, которое после подстановки текущих значений переменных конкретизируется6Здесь мы употребили термин конкретизация, поскольку используются именно текущие значения переменных, согласования не происходит. в композицию встроенных функций от константных аргументов. Эта композиция вычисляется, и переменная Х унифицируется как ее значение.

Таким образом, можно постепенно накапливать вычисления, а затем в подходящий момент их произвести. Смотрите пример.

?- assert(a(1+1)).
Yes
?- assert(b(2 * 2)).
Yes
?- a(X), b(Y), Z is X + Y.
X = 1+1
Y = 2*2
Z = 6

Внимание!

is не является присваиванием! Для того, чтобы убедиться в этом, исполните простейшее предложение языка PROLOG:

?- X is 1, X is X + 1.

Лучше всего и естественней всего вводятся в PROLOG -программу данные, полностью соответствующие синтаксису предложений и фактов языка. Если файл данных не очень велик, то для ввода достаточно воспользоваться уже описанным нами предикатом consult.

Конечно же, имеется и более традиционная система ввода-вывода. Опишем ее базовые возможности.

open(SrcDest, Mode, Stream, Options)

Открытие файла. SrcDes является атомом, содержащим имя файла в обозначениях системы Unix. Mode может быть read, write, append или update. Два последних способа открытия используются, соответственно, для дописывания в существующий файл и для частичного переписывания его. Stream либо переменная, и тогда ей присваивается целое число, которое служит для идентификации файла, либо атом, и тогда он служит внутри программы именем файла. Options могут быть опущены, среди них нам важна одна опция: type(binary), которая позволяет записать коды в двоичный файл. Опции образуют список.

Конечно же, имеется возможность вручную установить текущую позицию внутри файла:

seek(Stream, Offset, Method, NewLocation)

Method — это метод отсчета относительной позиции. bof отсчитывает ее с начала файла, current от нынешней точки, eof от конца. Переменная NewLocation унифицируется с новой позицией, отсчитываемой обязательно с начала.

Предикат close(Stream) комментариев не требует.

read(Stream, Term)

Переменная Term унифицируется с термом, прочитанным из потока Stream.

read_clause(Stream, Term)

Читается предложение. По умолчанию пользователя предупреждают о переменных, которые отсутствуют в голове и лишь однажды присутствуют в хвосте.

read_term(Stream, Term, Options)

Аналогично read, но позволяет установить целый ряд возможностей, регулирующих представление терма. Смотрите подробнее в документации конкретной PROLOG -системы.

writeq(Stream, Term)

Term пишется в Stream, вставляются кавычки и скобки, где нужно.

write_canonical(Stream, Term)

Term пишется в Stream таким способом, чтобы его однозначно прочитала любая PROLOG -программа, а не только Вы и Ваша программа на Вашей системе.

Есть способ читать и писать символы, а через них строки и прочее, но это настолько примитивно и уродливо, что можно дать практический совет:

Внимание!

Если Вам нужно ввести в PROLOG файл иноязычного или просто обычного формата либо вывести из него в предписанном Вам не укладывающемся в систему термов формате, напишите переходник на Рефале или на Perl.

Тем не менее вот минимальный (и практически полный) список предикатов символьного и двоичного ввода и вывода.

get_byte(Stream, Byte)

Byte рассматривается как целое число и унифицируется со следующим байтом входного потока. Конец файла читается как -1.

get_char(Stream, Char)

Аналогично, но следующий байт рассматривается как имя атома, состоящее из одного символа. Конец файла унифицируется с атомом end_of_file. Русские буквы, пробелы и прочие нестандартные символы могут вызвать неприятности.

get(Stream, Char)

Аналогично, но пропускаются невидимые символы.

skip(Stream, Char)

Пропускает все, пока не встретится символ Char либо конец файла. Само первое вхождение Char также будет пропущено.

put(Stream, Char)

Вывод одного символа либо байта. Char унифицируется либо как целое число из диапазона [0, 255], либо как атом с именем из одного символа.

nl(+Stream)

Вывести перевод строки.

< Лекция 5 || Лекция 6: 12345 || Лекция 7 >
Федор Антонов
Федор Антонов

Здравствуйте!

Записался на ваш курс, но не понимаю как произвести оплату.

Надо ли писать заявление и, если да, то куда отправлять?

как я получу диплом о профессиональной переподготовке?

Илья Ардов
Илья Ардов

Добрый день!

Я записан на программу. Куда высылать договор и диплом?