Книга: Программирование на языке Пролог для искусственного интеллекта

6.4. Создание и декомпозиция атомов

6.4. Создание и декомпозиция атомов

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

name( A, L)

истинно, если L — список кодов ASCII, кодирующих атом. Например,

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

истинно. Существуют два типичных способа использования name:

(1) дан атом, разбить его на отдельные символы;

(2) дан список символов, объединить их в один атом.

Примером первого случая применения предиката является программа, которая имеет дело с заказами такси и водителями. Все это представлено в программе атомами

заказ1, заказ2, водитель1, водитель2, такси1, таксилюкс

Предикат

такси( X)

проверяет, относится ли атом X к тем атомам, которые представляют такси:

такси( X) :-
 name( X, Хспис),
 nаmе( такси, Тспис),
 конк( Тспис, _, Хспис).
конк( [], L, L).
конк( [А | L1], L2, [А | L3] ) :-
 конк( L1, L2, L3).

Предикаты заказ и водитель можно определить аналогично.

Наш следующий пример иллюстрирует применение объединения отдельных символов в один атом. Мы определим предикат

читпредложение( Списслов)

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

Мэри было приятно видеть неудачу робота.

то цель читпредложение( Предложение) вызовет конкретизацию

Предложение=['Мэри', было, приятно, видеть, неудачу, робота]

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

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

(1) Симв — точка, тогда все сделано.

(2) Симв — пробел, — игнорировать его и читпредложение от остального ввода.

(3) Симв — буква, — сначала считать слово Слово, которое начинается с Симв, а затем запустить читпредложение, чтобы считать оставшуюся часть предложения, породив при этом Списслов. Общим результатом этого будет список [Слово | Списслов].

Процедура, считывающая символы одного слова, такова:

читбуквы( Буква, Буквы, Сделсимв)

Ее три аргумента:

(1) Буква — текущая буква (уже считанная) читаемого слова.

(2) Буквы — список букв (начинающийся с буквы Буква), оставшихся до конца слова.

(3) Следсимв — входной символ, непосредственно следующий за читаемым словом. Следсимв не должен быть буквой.

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

/*
Процедура читпредложение считывает предложение
и из его слов создает список атомов. Например,
 читпредложение( Списслов)
порождает
 Списслов=['Мэри', было, приятно, видеть, неудачу, робота]
если входным было предложение
 Мэри было приятно видеть неудачу робота.
*/
читпредложение( Списслов) :-
 gеt0( Симв),
 читостальное( Симв, Списслов).
читостальное( 46, []) :- !.
  % Конец предложения: 46 = ASCII-код для '.'
 читостальное( 32, Списслов) :- !,
  % 32 = ASCII-код для пробела
 читпредложение( Списслов).
  % Пропустить пробел
читостальное( Буква, [Слово | Списслов]) :-
 читбуквы( Буква, Буквы, Следсимв),
  % Считать буквы текущего слова
 nаmе( Слово, Буквы),
  читостальное( Следсимв, Списслов).
читбуквы( 46, [], 46) :- !.
 % Конец слова: 46 = точка
читбуквы( 32, [], 32) :- !.
 % Конец слова: 32 = пробел
читбуквы( Бкв, [Бкв | Буквы], Следсимв) :-
 get0( Симв),
 читбуквы( Симв, Буквы, Следсимв).

Рис. 6.4. Процедура для преобразования предложения в список атомов.

Упражнения

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

начинается( Атом, Символ)

для проверки, начинается ли Атом с символа Символ.

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

?- plural( table, X).
X  =  tables

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

поиск( Ключслово, Предложение)

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

Оглавление книги


Генерация: 1.199. Запросов К БД/Cache: 3 / 1
поделиться
Вверх Вниз