Шрифт:
?- событие(_,L), принадлежит('Англия',L), phh(L).
Обратим внимание на использование механизма возврата для поиска в базе данных. Каждый раз, когда для целевого утверждения принадлежитне находится сопоставление, делается попытка найти новое сопоставление для целевого утверждения событие. В результате в поисках событий, в которых упоминается атом «Англия», будет целиком просмотрена сверху вниз вся база данных.
Предикат writeпечатает термы с некоторым «пониманием» того, что он делает, так как он учитывает, какие объявления операторов были сделаны. Например, если мы объявили некоторый атом как инфиксный оператор, то терм, имеющий этот атом в качестве функтора структуры с двумя аргументами, будет напечатан таким образом, что атом окажется между аргументами. Существует еще один предикат, который выполняет те же действия, что и write, за тем исключением, что он игнорирует все сделанные объявления операторов. Этот предикат называется display. Различие между writeи displayиллюстрирует следующий пример:
?- write(a+b*c*c),nl, display(a+b*c*c).
a+b*c*c
+(a,*(*(b,c),c))
да
Обратим внимание на то, что предикат displayобработал атомы + и * – точно так же, как и любые другие атомы, которые он печатает в этом терме. Как правило, нежелательно, чтобы печатаемые структуры выглядели подобным образом, так как наличие операторов обычно делает более понятными при чтении как вводимые, так и выводимые программой данные. Однако иногда, когда мы не совсем уверены в том, что знаем, каков приоритет операторов, использование предиката displayможет оказаться очень полезным.
5.1.2. Ввод термов
Предикат readчитает следующий терм, набираемый пользователем на клавиатуре терминала. После вводимого терма должны следовать точка '.' и непечатаемая литера, такая как пробел или
Используя предикаты readи phh,как они были определены выше, мы можем написать программу для печати краткого содержания исторических событий, хранящихся в базе данных, с помощью фактов с предикатом событие.Эта программа имеет вид:
обращение:-
phh(['Какая',дата,вас,'интересует?'!),read(D),coбытиe(D,S),pph(S).
Мы определили предикат обращение,не имеющий аргументов. Когда мы обращаемся к системе с вопросом
?- обращение.
Пролог напечатает
Какая дата вас интересует?
и будет ждать ответа. Предположим, что мы ввели с клавиатуры
1523.
Обратите внимание на то, что после 1523 необходимо ввести точку, так как этого требует предикат read.И, как обычно, мы должны нажать клавишу
Кристиан II покинул Данию
Обратите внимание, что в первой строке тела правила обращениеиспользуется предикат phh,хотя в этом случае печатается не краткое содержание исторического события. Это просто показывает, что phhвполне подходит для печати произвольногосписка атомов независимо от того, откуда он взялся.
5.2. Ввод и вывод литер
Наименьшей единицей данных, которая может участвовать в операциях ввода-вывода, является литера. Мы уже знаем, что литеры интерпретируются как небольшие целые числа в соответствии с кодом ASCII. В Прологе имеется несколько встроенных предикатов для ввода и вывода литер.
5.2.1. Вывод литер
Если переменная Xимеет в качестве значения некоторую литеру (ее код ASCII), то эта литера будет напечатана при обработке целевого утверждения put(X).Предикат putвсегда выполняется и не может быть пересогласован (это приводит к неудаче). В качестве «побочного эффекта» putпечатает литеру на дисплее терминала. Например, мы можем напечатать слово helloдовольно необычным способом: