После загрузки системы Пролог пользователю становится досту­пен ряд системных предикатов. Они определяются с помощью либо самого Пролога, либо языка низшего уровня, используемого для реа­лизации Пролога.

Описание предикатов и способы их применения содержатся в до­кументации по конкретной реализации Пролога. При доказательстве некоторых предикатов имеет место так называемый побочный эф­фект. Благодаря ему обеспечивается интерфейс с пользователем и обработка файлов. Предикаты, обладающие побочным эффектом. обычно реализуются не на Прологе, а на языке низкого уровня, на­пример Ассемблере, либо на языке высокого уровня, таком, как Пас­каль.

Встроенные предикаты не могут быть изменены пользователем, а попытка заменить их, применяя предикаты assert и retract, приведет к сообщению об ошибке.

Программная среда Пролога состоит из двух частей:

программный модуль Пролога;

база данных Пролога.

Программный модуль включает интерпретатор Пролога (в неко­торых реализациях и компилятор), драйвер ввода/вывода и, кроме того, системные процедуры. Пользователь обычно не имеет возмож­ности изменять программный модуль.

База данных Пролога содержит набор основных, заранее опре­деленных предикатов. Кроме того, резервируется пространство для добавления предикатов, которые будут объявлены пользователем. Механизмы добавления, удаления и обновления утверждений, за­данных пользователем, классифицируются следующим образом:

1) добавление и удаление утверждений;

2) добавление утверждений из файла и замена имеющихся ут­верждений на утверждения, находящиеся в файлах для того же само­го предиката (ввод программ и повторный ввод программ).

НЕ нашли? Не то? Что вы ищете?

Файл Пролога состоит из утверждений. Утверждение есть факт или правило. Утверждения обрабатываются интерпретатором (ком­пилятором) Пролога и потому должны удовлетворять синтаксиче­ским определениям.

Добавление и удаление утверждений

Как уже говорилось, в Прологе имеется набор встроенных преди­катов, позволяющих добавлять или удалять утверждения из базы данных. В гл.7 мы ввели предикаты asserta, assertz и retract, служа­щие для обновления базы данных. Подытожим ранее сказанное и рассмотрим встроенные предикаты retractall и abolish.

assertz(X)

X должен быть конкретизирован термом, не являющимся пере­менной. Терм интерпретируется как утверждение и добавляется в базу данных Пролога. Утверждение помещается в конец базы дан­ных, или если существует процедура с теми же функтором и арно­стью, то добавляется к этой процедуре. (В некоторых реализациях Пролога допустимы исключения из приведенного правила, потому необходимо обратиться к руководству по конкретной системе.)

asserta(X)

Определяется аналогично предикату assertz(X), но новое утвер­ждение становится первым утверждением в процедуре с теми же функтором и арностью.

retract (X)

X должен быть конкретизирован составным термом. В базе данных осуществляется поиск утверждения, голова и тело которого сопоставляются с термом X. Первое такое утверждение затем уда­ляется.

retractall(X)

Удаляет из базы данных все утверждения, функтор и арность ко­торых сопоставимы с X.

abolish(P,A)

Удаляет из базы данных все утверждения для процедуры Р с ар­ностью А.

Описанные предикаты служат для обновления базы данных Про­лога во время выполнения программы.

Возможность динамического обновления программы довольно ча­сто применяется в Прологе. После удаления части базы данных с по­мощью предикатов retract и abolish необходимо запустить механизм «сборки мусора» для восстановления памяти. Алгоритм, выбранный для чистки памяти, зависит от реализации Пролога.

Считывание утверждений в базу данных

Для того чтобы добавить новые утверждения в базу данных, пользователь вводит

:- consult(user).

Такая команда Пролог-системы вызывает считывание утвержде­ний с терминала пользователя до тех пор, пока не встретится символ конец_файла. Типичная последовательность имеет вид:

?- consult(user). /* начало считывания

/* утверждений

: утверждение 1 /* Обратите внимание, что

/* использован другой знак

/* приглашения системы

: утверждение 2

:$ /* символ конец_файла

?- /* снова появилось обычное

/* приглашение системы

Утверждения 1 и 2 добавлены к базе данных и будут выбраны при попытке Пролога доказать цель с теми же функтором и арностью.

Более короткий вариант записи consult(user):

?- [user].

В данном случае используется тот же символ конца файла $.

Пользователю будет нелегко вводить одни и те же предикаты при каждом новом сеансе работы. Для устранения нежелательной ситуа­ции в Прологе реализован механизм, позволяющий считывать груп­пы предикатов или программы пользователя. Пусть мой-файл - файл пользователя. Утверждение

?- consult(мой-файл).

считывает содержимое файла мой-файл. Целевое утверждение consult(X) всегда выполняется успешно. В результате утверждения из файла мой-файл добавляются в базу данных Пролога. Если при чтении одного из утверждений обнаруживается синтаксическая ошибка, выдается сообщение об этом утверждении, но обработка ос­тавшихся утверждений продолжается до тех пор, пока не будет най­ден конец файла. Целевое утверждение consuIt(X) нельзя передока­зать. Если X не является именем реально существующего файла или файл не может быть открыт, то выдается сообщение об ошибке. При вводе программы из файла в ней иногда встречаются команды или директивы, относящиеся к системе Пролог. Они отличаются от ут­верждений, добавляемых в базу данных, тем, что им предшествует оператор?- или:-.

Целевое утверждение consult(F) добавляет утверждения из фай­ла F в конец существующей базы данных. Пролог пытается сопоста­вить цель с добавленным утверждением только в том случае, если при прямом доказательстве попытка согласования существующего утверждения закончилась неудачей. Допускается замена новым ут­верждением утверждения, ранее записанного в базу данных, для чего используется встроенный предикат reconsult. Он работает анало­гично предикату consult, но утверждения, считываемые в базу данных, замещают ранее записанные утверждения с теми же функтором и арностью.

В качестве аргументов предикатов consult и reconsult могут вы­ступать списки файлов. Например:

consult([‘F1’,’F2’,...]).

reconsult([‘F1’,’F2’,...]).

Предикаты сохранения и восстановления

После добавления новых утверждений в базу данных пользова­тель имеет возможность сохранить копию текущего состояния систе­мы и в следующем сеансе продолжить работу, начиная с записанного состояния. Для этого применяется предикат save. Утверждение

save('мой-файл').

сохраняет текущее состояние базы данных Пролога в файл, называе­мый мой-файл. Целевое утверждение save(X) нельзя передоказать. В случае, если не существует файла с именем X или если его невоз­можно открыть, то выдается сообщение об ошибке.

Успешно выполнив сохранение текущего состояния базы данных Пролога в файл, мы можем вернуться к прежнему состоянию, ис­пользуя предикат restore:

геstоrе('мой-файл').

Чтение символов

Системные предикаты get(X), get0(X), skip(X) служат для ввода символов с терминала пользователя. Коды символов различаются в зависимости от используемой реализации Пролога. В микрокомпью­терах в основном применяется код ASCII*, а в больших ЭВМ (таких, как ICL2900) - код EBDIC**.

Перечисленные предикаты определяются следующим образом.

get0(X)

Предикат вызывает считывание одного символа с клавиатуры. Если переменная X неконкретизирована, то X принимает значение кода символа. Если же переменная X конкретизирована, то вводи­мый символ сопоставляется с X. Целевое утверждение будет успешно доказано только в том случае, если символ сопоставим с X.

get(X)

Предикат вызывает считывание одного или нескольких символов с клавиатуры до тех пор, пока не будет считан символ пробела. Если переменная X неконкретизирована, то код символа отождествляется с X и доказательство утверждения заканчивается успехом. Если же переменная X конкретизирована, целевое утверждение будет дока­зано только в случае, если вводимый символ сопоставим с X.

skip(X)

Предикат считывает символы с клавиатуры или из текущего входного файла, пока не встретится символ с кодом X, тогда доказа­тельство цели заканчивается успешно. Переменная X может быть целочисленным выражением.

Запись символов

Для вывода символов используются системные предикаты: put(X), tab(X) nl. Они определяются следующим образом.

put(X)

Символ с кодом X записывается на терминал. Допускается, что­бы X был целочисленным выражением. Доказательство целевого ут­верждения put(X) всегда заканчивается успехом. X может быть ко­дом как управляющего, так и алфавитно-цифрового символа.

tab(X)

На терминал выводится X пробелов. X может быть целочислен­ным выражением.

nl

Происходит переход на новую строку терминала.

Рассмотрим примеры:

put(65) на терминал выводится символ А

(подразумевается ASCII код)

put(66+32) выходится символ b

put('C') выводится символ С

put([100]) выводится символ d

put(‘e’+’A’-‘a’) выводится символ Е

put(a(b)) выдается сообщение об ошибке

Считывание термов

Предикаты

read(X), readb(X) и read(X, Y)

служат для считывания термов. Приведем их определение.

read(X)

Если переменная неконкретизирована, то она означивается тер­мом, считанным с терминала. Попытка пользователя напечатать вы­ражение, не являющееся термом, приведет к ошибке. Вводимая ин­формация должна заканчиваться точкой. В случае, если переменная X конкретизирована термом, попытка доказать целевое утверждение заканчивается успехом только при условии, что вводимый с терми­нала терм сопоставим с X. В противном случае попытка доказатель­ства завершается неудачей.

readb(X)

Данный предикат аналогичен предикату read(X), но вводимый терм не должен заканчиваться точкой.

read(X,Y)

Доказательство предиката завершается успехом, если считывае­мый терм отождествляется с X, и неудачей в противном случае. При успешном доказательстве переменная Y становится списком, состоя­щим из имен переменных, входящих в терм X. Пролог переименовы­вает переменные, встретившиеся в вводимом терме. Таким образом, когда попытка доказать целевое утверждение read(X,Y) заканчива­ется успехом, список Y содержит внутренние имена переменных, входящих в терм X. Как и при использовании предиката read(X), по­сле вводимого терма должна стоять точка.

readb(X,Y)

Предикат аналогичен предикату read(X,Y). Различие состоит в том, что пользователь не должен печатать точку после ввода терма.

Примеры:

После запроса:

?-read(X).

система ожидает ввода. Если пользователь напечатает:

test (5).

то в результате переменная X получит значение

Х - test (5)

Задав вопрос

?- read (джек (мужчина)).

и введя терм

test.

получим ответ:

нет.

При запросе:

?-read(X, Y).

вводим терм

fred(P, a(Q)).

в результате получаем

X = fred(_55,a(_57))

Y=[[P |_55],[Q | _57]]

где _55 - внутреннее имя переменной Р, а _57 - внутреннее имя пере­менной Q.

Запись термов

Рассмотрим предикаты, служащие для записи термов.

write(X)

Данный предикат выводит терм на экран. Если X содержит конк­ретизированные переменные, то на экране отображаются термы, ко­торыми эти переменные конкретизированы. Если X содержит некон­кретизированные переменные, они выводятся как уникальные цело­численные переменные. Сцепленные переменные, входящие в X, отображаются в виде одного и того же целого значения. Например, в ответ на запрос

?- write(cyммa(N, S,N+l)).

на экране появится

сумма (_35,_36 is_35+l ) .

writeq(X)

Предикат аналогичен предикату write(X) кроме случая, когда X содержит атом или функторы, которые в программе следует заклю­чать в кавычки. Предикат writeq записывает такие величины на эк­ране в кавычках. Например, в результате запроса

?- writeq('fred. txt').

на экране появится

'fred. txt'

display (X)

Предикат выводит терм X в стандартной скобочной префиксной

форме записи. Например, запрос

?- display (X+Y).

вызовет появление на экране записи:

+ (X, Y)

Описанные выше предикаты ввода/вывода осуществляют считы­вание и запись на терминал. Клавиатура связывается со стандарт­ным входным потоком, а экран - со стандартным выходным потоком. Входной и выходной потоки могут осуществлять связь с различными файлами пользователя, требующимися во время сеанса работы с Пролог-системой. Для этого файл объявляется в качестве стандарт­ного входного потока, и рассмотренные выше предикаты для ввода производят считывание из файла, а не с клавиатуры. Подобным об­разом файл назначается в качестве стандартного выходного потока. В таком случае приведенные предикаты для вывода осуществляют запись в файл, а не на экран.

Для переопределения стандартных потоков используются следу­ющие предикаты.

see(F)

Определяет в качестве стандартного входного потока файл F.

seen(F)

Предикат переопределяет стандартный входной поток с файла F на клавиатуру. Прежде чем с помощью предиката see(F2) опреде­лить в качестве стандартного входного потока файл F2, следует с по­мощью предиката seen(F1) отменить связь файла F1 со стандартным входным потоком.

tell(F)

Целевое утверждение определяет стандартным выходным пото­ком файл F.

told(F)

Целевое утверждение переопределяет стандартный выходной по­ток с файла F на экран. Перед тем как с помощью предиката tell(F2) определить в качестве выходного потока новый файл F2, необходимо с помощью предиката told(F1) переключить текущий выходной по­ток с файла F1.

Помимо перечисленных в Прологе есть два предиката, позволяю­щие выяснить, с какими файлами связаны стандартные потоки.

Из за большого объема этот материал размещен на нескольких страницах:
1 2 3 4 5 6 7 8