При этом существенным и интересным является то, что различным поверхностным структурам (в данном случае, двум) может соответствовать лишь одна глубинная структура.
Рассмотрим пример очень простого фрагмента русского языка. В этом фрагменте в роли «агентов» и «объектов» некоторых
действий (например, любить, купить) выступают только личные местоимения (например, я, ты, меня, тебя, мною, тобою).
Входные цепочки типа
[он, любит, ее] или [она, любима, им]
должны быть преобразованы в одну глубинную структуру:
любить(он, она).
Отметим, что даже в таком ограниченном фрагменте языка может присутствовать довольно много различных форм местоимений и глаголов. Местоимения различаются по роду, числу, лицу и падежу. Глаголы могут быть в активном (действительном) и пассивном (страдательном) залоге, а также различаться по роду, числу, лицу. И хотя мы ограничимся рассмотрением только трёх падежей
– именительного, винительного и творительного (а всего в русском языке их шесть), становится очевидным, что хранение всех этих форм непосредственно в программе анализатора нецелесообразно.
Поэтому организуем специальные текстовые файлы с указанными данными и процедуру поиска нужной словоформы в том или ином файле непосредственно в ходе синтаксического анализа.
Использование словарей в виде текстовых файлов
Каждая запись файла-словаря будет представлять собой структуру Пролога вида
<Каноническая форма>: <Контекст>: <Список словоформ>.
Например:
купить: zalog(пассив):
[куплен, куплена, куплено, куплены]. любить: zalog(актив):
[люблю, любишь, любит, любим, любите, любят].
96
Ниже представлена программа такого анализатора (код 7.1), в текст которого включено определение предиката fid/4 – это процедура поиска в словаре (аббревиатура от find in dictionary).
Аргументы данного определения таковы:
1.X – исходная словоформа,
2.XC – каноническая форма слова,
3.K – контекст,
4.File – имя файла-словаря.
|
Код 7.1 |
% |
Поиск словоформы в словаре. |
:-op(200, xfy, ':'). |
|
fid(X, XC, K, File) :-
see(File), cycle(X, XC, K, R), seen, !, R = yes.
cycle(X, XC, K, R) :- repeat,
read(L), condition(X, XC, K, L, R), !.
condition(X, XC, K, XC:K:L, yes) :- member(X, L), !.
condition(_, _, _, L, no):-
L= end_of_file, !.
%Анализатор активных и пассивных форм. an_phrase(Y, zalog(актив)) -->
an_mest(X1, pad(именит)), an_glag(X2, zalog(актив)), an_mest(X3, pad(винит)), {Y=..[X2, X1, X3]}.
an_phrase(Y, zalog(пассив)) --> an_mest(X1, pad(именит)), an_glag(X2, zalog(пассив)), an_mest(X3, pad(творит)), {Y=..[X2, X3, X1]}.
97
an_mest(XC, K) -->
[X], {fid(X, XC, K, 'dic_mest')}.
an_glag(XC, K) --> [X], {fid(X, XC, K, 'dic_gl')}.
test1([ты, любишь, ее]). test2([она, любима, вами]). test3([оно, куплено, им]). test4([мы, купили, их]).
Содержимое файлов-словарей dic_mest и dic_gl
(коды 7.2 – 7.3):
Код 7.2
% |
Словарь местоимений. |
я: pad(именит): [я]. |
|
я: pad(винит): [меня]. |
|
я: pad(творит): [мной, мною]. |
|
ты: pad(именит):[ты]. |
|
ты: pad(винит): [тебя]. |
|
ты: pad(творит): [тобой, тобою]. |
|
он: pad(именит): [он]. |
|
он: pad(винит): [его]. |
|
он: pad(творит): [им]. |
|
она: pad(именит): [она]. |
|
она: pad(винит):[ее]. |
|
она: pad(творит): [ей, ею]. |
|
оно: pad(именит): [оно]. |
|
оно: pad(винит): [его]. |
|
оно: pad(творит): [им]. |
|
мы: pad(именит): [мы]. |
|
мы: pad(винит): [нас]. |
|
мы: pad(творит): [нами]. |
|
вы: pad(именит): [вы]. |
|
вы: pad(винит): [вас]. |
|
вы: pad(творит): [вами]. |
|
они: pad(именит):[они]. |
|
они: pad(винит): [их]. |
|
они: pad(творит): [ими]. |
|
98 |
|
|
Код 7.3 |
% |
Словарь глаголов. |
любить: zalog(актив): |
|
[люблю, любишь, любит, любим, любите, любят]. любить: zalog(пассив):
[любим, любима, любимо, любимы]. купить: zalog(актив):
[купил, купила, купило, купили]. купить: zalog(пассив):
[куплен, куплена, куплено, куплены].
После отработки целевых утверждений
?-test1(L), |
an_phrase(Res, K, L, []). |
?-test2(L), |
an_phrase(Res, K, L, []). |
?-test3(L), |
an_phrase(Res, K, L, []). |
?-test4(L), |
an_phrase(Res, K, L, []). |
будут возвращены следующие значения переменной Res и K:
Res = любить(ты, она) Res = любить(вы, она) Res = купить(он, оно) Res = купить(мы, они)
K = zalog(актив) K = zalog(пассив) K = zalog(пассив) K = zalog(актив)
2. Морфологический анализ слов ОЕЯ
Рассмотрим пример, который относится к так называемому морфологическому анализу (разбору слов русского языка) – выделению приставок (префиксов), суффиксов, окончаний и т.д.
Для простоты рассмотрим лишь задачу отделения окончания слова от его «основы», то есть от оставшейся части слова без окончания. Например, разбор прилагательных красивый и прекрасная должен дать такие структуры:
morf(osnova(красив), okonch(pril: pad(именит): rod(муж), ый))
morf(osnova(прекрасн), okonch(pril: pad(именит): rod('жен'), ая))
Всевозможные окончания прилагательных будем хранить в словаре (файле dic_ocon). Фрагмент словаря представлен кодом 7.4.
99
|
Код 7.4 |
% |
Словарь окончаний. |
_: (pril: pad(именит): rod(муж)): |
[ый, ий]. |
_: (pril: pad(именит): rod(жен)): [ая, яя]. _: (pril: pad(именит): rod(сред)): [ое, ее].
_: (pril: pad(именит): chislo(множ)): [ые, ие]. _: (pril: pad(родит): rod(муж)): [ого, его].
_: (pril: pad(родит): rod(жен)): [ой, ей].
_: (pril: pad(родит): rod(сред)): [ого, его]. _: (pril: pad(родит): chislo(множ)): [ых, их].
Здесь присутствуют лишь данные об окончаниях прилагательных в двух падежах – именительном и родительном. Анонимная переменная в левой части структуры говорит о том, что канонической формы у окончаний нет.
Программа указанного морфологического анализа (код 7.5):
Код 7.5
:-op(200, xfy, ':').
an_morf(Result, InpL, RestL):-
reverse(InpL, L),
an_morf1(Result, L, RestL).
an_morf1(morf(Osn, Okon)) -->
an_okon(Okon), an_osn(Osn, [], C).
an_okon(okonch(K, X)) --> |
% Анализ окончания. |
[B1, B2, B3], |
|
{name(X, [B3, B2, B1]), |
fid(X, _, K, 'dic_okon')}. |
an_okon(okonch(K, X)) --> |
|
[B1, B2], |
|
{name(X, [B2, B1]), fid(X, _, K, 'dic_okon')}. an_okon(okonch(K, X)) -->
[B1],
{name(X, [B1]), fid(X, _, K, 'dic_okon')}. an_okon(okonch(void)) --> [].
100