Читаем Программирование на языке пролог полностью

<p>5.2.2. Ввод литер</p>

Для ввода литер, набираемых на клавиатуре терминала, могут быть использованы предикаты get0(X)и get(X). Эти предикаты всегда согласуются с базой данных, если их аргументы неконкре-тизированы, а попытка повторного согласования всегда неудачна. При обработке целей, включающих эти предикаты, ЭВМ ожидает до тех пор, пока пользователь не наберет на клавиатуре какую-либо литеру. Указанные предикаты немного различаются тем, что get0(X)присвоит Xлюбую набранную на клавиатуре литеру независимо от ее вида. Напротив, get(X)пропустит все управляющиелитеры и присвоит Xв качестве значения первую печатаемую литеру. Как отмечалось в гл. 2, печатаемая литера – это литера, которая визуализируется на дисплее терминала.

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

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

<p>5.3. Ввод предложений</p>

Вэтом разделе мы представим программу, которая вводит предложение с терминала и преобразует его в список атомов языка Пролог. В программе определяется предикат ввести,имеющий один аргумент. Программа должна уметь определять, где заканчивается одно вводимое слово и начинается следующее. Поэтому предположим, что слово состоит из нескольких букв, цифр или специальных литер. Буквы и цифры уже были представлены в разд. 2.1. Мы будем рассматривать одиночную кавычку ''' и дефис '-' как специальные литеры. Литеры

, ; : ? ! .

будут рассматриваться как отдельные слова. Все другие литеры являются разделителями между словами. Предложение считается законченным, когда встречается одно из слов '.', '!' или '?'. Прописные буквы автоматически преобразуются в строчные, так что одно и то же слово всегда превращается в один и тот же атом. В результате такого определения программа будет поддерживать диалог с пользователем, подобный следующему:

?- ввести(S).

The man, who is very rich, saw John's watch.

S = [the,man,',',who,is,very,rich,',',saw,'John's',watch,'.']

В действительности мы вставили в представление предложения дополнительные одинарные кавычки, чтобы выделить некоторые атомы.

Программа использует предикат get0для ввода литер с терминала. Затруднение, связанное с предикатом get0, состоит в том, что если литера прочитана с терминала этим предикатом, то она «ушла навсегда» и никакое другое целевое утверждение get0или попытка вновь доказать целевое утверждение get0не позволит получить доступ к этой литере вновь. Поэтому следует избегать возврата за точку использования get0, если мы хотим избежать «потери» литеры, которую он читает. Например, следующая программа, которая должна вводить литеры и печатать их снова, заменяя литеры ана b(код литеры 97на код 98), не будет работать:

выполнить:- заменить_литеру, выполнить.

заменить_литеру:- get0(X) = 97,!, put(98).

заменить_литеру:- get0(X), put(X).

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

Перейти на страницу:
Нет соединения с сервером, попробуйте зайти чуть позже