Назад | Содержание | Вперёд
Часто желательно информацию, считанную как последовательность символов, иметь в программе в виде атома. Для этой цели существует встроенный предикат name. Он устанавливает взаимосвязь между атомами и их кодировкой в ASCII. Таким образом,
name( A, L)
истинно, если L - список кодов ASCII, кодирующих атом. Например,
name( zx232, [122, 120, 50, 51, 50] )
истинно. Существуют два типичных способа использования name:
(1) дан атом, разбить его на отдельные символы;
(2) дан список символов, объединить их в один атом.
Примером первого случая применения предиката является программа, которая имеет дело с заказами такси и водителями. Все это представлено в программе атомами
заказ1, заказ2, водитель1, водитель2, такси1, таксилюкс
Предикат
такси( 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).
Х = tables
6. 6. Напишите процедуру
поиск( Ключслово, Предложение)
которая при каждом вызове находит в текущем входном файле предложение, содержащее заданное ключевое слово Ключслово. Предложение в своей исходной форме должно быть представлено в виде последовательности символов или в виде атома (процедуру читпредложение из данного раздела можно соответственно модифицировать).
Назад | Содержание | Вперёд