Формирование и анализ атомов

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

name [ A, L)

принимает истинное значение, если L — список кодов символов ASCII в имени атома

А. Например, предикат

name( zx232, [122,120,50,51, 50]]

принимает истинное значение. Ниже описаны две типичные области применения предиката name.

1. Если дано имя атома, разбить его на отдельные символы.

2. Если дан список символов, объединить его в имя атома.

Примером приложения первого вида может служить программа, которая касается заказов, такси и водителей. Предположим, что эти понятия представлены в про­грамме с помощью примерно таких атомов: orderl, order 2, driver l, driver 2, taxial, taxilux

Предикат taxi! X! проверяет, представляет ли атом X информацию о такси:

taxi{ X) :-

name ( х, xlist},

name! taxi, Tlist),

cone! Tlist, _, Xlist!. % Является ли слово 'taxi' префиксом X7

Предикаты order и driver можно определить аналогичным образом. Следующий пример демонстрирует использование способа объединения символов в атомы. Определим предикат

getsenter.ee ( Mordlist)

который считывает текст на естественном языке в произвольной форме и конкрети­зирует список Wordlist значениями некоторого внутреннего представления этого текста. Наиболее приемлемым вариантом внутреннего представления, позволяющим обеспечить дальнейшую обработку текста, является следующий: каждое слово во входном тексте представляется как атом Prolog, а весь текст преобразуется в список атомов. Например, если текущий входной поток имеет вид Mary was pleased to see the robot fail.

то цель getsentence [Sentence) вызовет такую конкретизацию: Sentence = [ 'Mary1, was, pleased, to, see, the, robot, fail]

Для простоты предположим, что текст всегда завершается точкой и в нем отсут­ствуют знаки препинания.

Соответствующая программа приведена в листинге 6.1. Процедура getsentence вначале считывает текущий входной символ Char, а затем передает этот символ в процедуру getrest для завершения работы. Процедура getrest должна выполнять свои действия с учетом описанных ниже трех случаев.

144 Часть I. Язык Prolog


1. Символ Cher представляет собой точку. В этом случае чтение текста закончено. ■ 2. Символ Char является пробелом. Игнорировать его и перейти к выполнению процедуры get sentence на остальной части ввода.

3. Символ Char представляет собой букву. Вначале прочитать слово Word, кото­рое начинается с символа Char, затем использовать процедуру getsentence для чтения остальной части текста и формирования списка Wordlist. Сум­марным результатом является список [Word | Wordlist].

Листинг 6.1. Процедура преобразования текста в список атомов

I*

Процедура getsentence считывает предложение и преобразовывает слова в список атомов. Например,

getsentence ( Wordlist)

создает список

Wordlist = [ -магу', was, pleased, to, see, the, robot, fail]

при получении на входе предложения

Mary was pleased to see the robot fail.

V

getsentence! Wordlist) :-getOt Char], getrestt Char, Wordlist).

getrestf 46, [] ) :- !. % Конец предложения; 46 - код ASCII для '.'

getrest! 32, Wordlist) ;- !, % 32 - код ASCII для пробела
getsentence; Wordlist). % Пропустить пробел

getrestf Letter, (Word | wordlist) ) :-getletterst Letter, Letters, Nextchar), % Прочитать буквы текущего слова

getletterst 46, [], 46) :- !. % Конец слова; 46 - код точки

getletterst 32, [], 32) :- !. % Конец слова; 32 - пробел

getletterst Let, [Let | Letters], Nextchar) :-getO ( Char), getletterst Char, Letters, Nextchar) .

Процедурой, которая считываетсимволы одного слова, является следующая: getletters! Letter, Letters, Haxtchar)

Три параметра этой процедуры описаны ниже.

1. Letter - это текущая буква (уже считанная) считываемого слова.

2. Letters - это список букв (начиная с Letter) вплоть до конца слова.

3. Next char — это входной символ, который непосредственно следует за считан­ным словом. Next char должен быть небуквенным символом.

Дополним этот пример комментарием, касающимся возможного применения про­цедуры getsentence. Она может использоваться в программе для обработки текста на естественном языке. Тексты, представленные в виде списков слов, находятся в форме, подходящей для дальнейшей обработки на языке Prolog. Одним из простых


Глава 6. Ввод и вывод



 


примеров является поиск определенных ключевых слов во входном тексте. Гораздо более сложной задачей может явиться понимание этого текста, иными словами, из­влечение из него смысла, представленного в виде некоторой заранее выбранной фор­мальной структуры. Это важное направление исследований в области искусственного интеллекта представлено в главе 2\.

Упражнения

6.4. Определите отношение

starts С Atom, Character)

чтобы проверить, начинается ли имя атома Atom с символа Character.

6.5. Определите процедуру plural, которая преобразует форму существительных в
единственном числе в форму во множественном числе, например, следующим
образом:

7- plural( table, X) X - tables

е.6. Напишите процедуру

search С Keyword, Sentence)

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