Формирование и анализ атомов
Часто желательно иметь возможность представлять в программе в виде атомов информацию, считанную как последовательность символов. Для этой цели может применяться встроенный предикат 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 из этого раздела, откорректированную соответствующим образом).