Книга: Программирование на языке Пролог для искусственного интеллекта
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. Напишите процедуру
поиск( Ключслово, Предложение)
которая при каждом вызове находит в текущем входном файле предложение, содержащее заданное ключевое слово Ключслово
. Предложение
в своей исходной форме должно быть представлено в виде последовательности символов или в виде атома (процедуру читпредложение
из данного раздела можно соответственно модифицировать).
- 4. Создание новых предложений (20 % времени)
- Функциональная декомпозиция
- 7. Создание организации
- Декомпозиция
- Декомпозиция, основанная на объектах
- 7.2. Создание и декомпозиция термов: =.., functor, arg, name
- 4. Создание странички с рекламными материалами для партнеров
- Плоскость атомов
- Неведение атомов
- 6. Создание и сохранение желательной идентичности бренда
- 10. Создание стратегического партнерства
- 10. Создание команды