Вывод литер

Ввод и вывод литер

Ввод термов

Предикат readчитает следующий терм, набираемый пользователем на клавиатуре терминала. После вводимого терма должны следовать точка '.' и непечатаемая литера, такая как пробел или RETURN. Если переменная X не конкретизирована, то целевое утверждение read(X)приведет к вводу следующего терма и этот терм будет присвоен в качестве значения переменной X, Как и другие предикаты ввода-вывода, с которыми мы уже сталкивались, предикат readвыполняется лишь один раз. Если в момент рассмотрения целевого утверждения read(X)его аргумент конкретизирован, то попытка доказать согласованность этого целевого утверждения с базой данных вызовет чтение следующего терма и попытку сопоставления его с аргументом, заданным в read.Согласованность цели с базой данных зависит от результата этого сопоставления.

Используя предикаты readи phh,как они были определены выше, мы можем написать программу для печати краткого содержания исторических событий, хранящихся в базе данных, с помощью фактов с предикатом событие.Эта программа имеет вид:

 

обращение:-

phh(['Какая',дата,вас,'интересует?'!),read(D),coбытиe(D,S),pph(S).

 

Мы определили предикат обращение,не имеющий аргументов. Когда мы обращаемся к системе с вопросом

 

?- обращение.

 

Пролог напечатает

 

Какая дата вас интересует?

и будет ждать ответа. Предположим, что мы ввели с клавиатуры

1523.

 

Обратите внимание на то, что после 1523 необходимо ввести точку, так как этого требует предикат read.И, как обычно, мы должны нажать клавишу RETURN, чтобы сообщить ЭВМ, что мы закончили ввод строки текста. После этого Пролог ответит

 

Кристиан II покинул Данию

 

Обратите внимание, что в первой строке тела правила обращениеиспользуется предикат phh,хотя в этом случае печатается не краткое содержание исторического события. Это просто показывает, что phhвполне подходит для печатипроизвольного списка атомов независимо от того, откуда он взялся.

Наименьшей единицей данных, которая может участвовать в операциях ввода-вывода, является литера. Мы уже знаем, что литеры интерпретируются как небольшие целые числа в соответствии с кодом ASCII. В Прологе имеется несколько встроенных предикатов для ввода и вывода литер.

Если переменная X имеет в качестве значения некоторую литеру (ее код ASCII), то эта литера будет напечатана при обработке целевого утверждения put(X).Предикат putвсегда выполняется и не может быть пересогласован (это приводит к неудаче). В качестве «побочного эффекта» putпечатает литеру на дисплее терминала. Например, мы можем напечатать слово helloдовольно необычным способом:

 

?- put(104),put(101),put(108),put(108),put(111).

hello

 

Результатом такой конъюнкции целей является печать Прологом литер h, е, l, l, онепосредственно под вопросом, как показано выше. Мы уже видели, что имеется возможность начать печать текста с начала следующей строки, использовав для этого предикат без аргументов nl. В действительности nl «печатает» некоторые управляющие литеры, что вызывает перевод курсора на дисплее терминала на начало следующей строки. Вопрос

 

?- put(104),put(105),nl,put(116),put(104),put(101),put(114), put(1O1).

 

вызвал бы следующую печать:

 

hi

there

 

Другой предикат, с которым мы уже познакомились, - это tab(X),печатающий X пробелов (ASCII код равен 32). Разумеется, переменной X должно быть присвоено целое число. Отметим, что предикат tab(X)мог бы быть определен так:

 

tab(0):- !.

tab(N):- put(32), M is N-1, tab(M).

 

Теперь мы можем определить предикат, который мы назовем печать_строки. Если значением переменной X является список кодов литер (строка), то целевое утверждение печать_строкинапечатает этот список (строку), используя put для печати каждого элемента списка. Как и во всех подобных программах, граничным условием является появление пустого списка. Это условие мы и используем для завершения рекурсии. При непустом списке с помощью put печатается голова списка, а затем используем печать_строки – хвост списка:

 

печать_строки([]).

печать_строки([Н|Т]):- put(H), печать_строки(Т).

?- печать_строки(«Чарлз V отрекся от престола в Брюсселе»).

Чарлз V отрекся от престола в Брюсселе

 

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