Грамматический разбор предложений.
ЦЕЛЬ. Изучить основы обработки текста в среде Пролог.
Возможны два принципиальных подхода к обработке текста. С одной стороны, текст можно структурировать, выделив в нем причинно-следственные связи на основе модели <субъект(атрибуты)-объект(атрибуты)-действие(атрибуты)>. Такой структурированный текст можно представить в виде семантической сети. Семантическая сеть представляет, таким образом, текстовую базу знаний. Достоинство данного подхода состоит в возможности более эффективной обработки запросов к тексту, поскольку наличие структуры упрощает поиск информации.
Второй подход более «прямолинеен». Текст структурируется лишь по форме представления предложений. Нам потребуется задать базу данных. В ней мы выпишем существительные (noun), глаголы(verb), прилагательные(adj), образующие понятийный каркас текста. Ниже приведено примерное содержимое этой базы.
noun("уравнение")
noun("коэффициент")
noun("константа")
noun("взаимодействие")
noun("элемент")
noun("вид")
noun("продукт")
adj("гальванический")
adj("стехиометрический")
adj("реальный")
adj("термодинамический")
adj("прямая")
adj("обратная")
adj("начальный")
adj("стандартный")
adj("положительный")
adj("температурный")
verb("равно")
verb("равен")
verb("зависит")
verb("позволяет")
verb("соответствует")
verb("определяют")
verb("характеризует")
verb("является")
verb("имеет")
Структура предложения определяется грамматическими правилами следующего вида
ПРЕДЛОЖЕНИЕ:- <БЛОК СУЩЕСТВИТЕЛЬНОГО>
<БЛОК ГЛАГОЛА>
<БЛОК СУЩЕСТВИТЕЛЬНОГО>
БЛОК СУЩЕСТВИТЕЛЬНОГО:- <ПРИЛАГАТЕЛЬНОЕ>
<СУЩЕСТВИТЕЛЬНОЕ>
БЛОК СУЩЕСТВИТЕЛЬНОГО: - <СУЩЕСТВИТЕЛЬНОЕ>
<СУЩЕСТВИТЕЛЬНОЕ>
БЛОК СУЩЕСТВИТЕЛЬНОГО: - <СУЩЕСТВИТЕЛЬНОЕ>
БЛОК ГЛАГОЛА:- <НАРЕЧИЕ> <ГЛАГОЛ>
БЛОК ГЛАГОЛА:- <ГЛАГОЛ>
СУЩЕСТВИТЕЛЬНОЕ:-<любое слово Z - аргумент предиката noun(Z)>
ПРИЛАГАТЕЛЬНОЕ:- <любое слово Z – аргумент предиката adj(Z)>
ГЛАГОЛ:- <любое слово Z – аргумент предиката verb(Z)>
В качестве пояснения рассмотрим предложение:
"ЭДС характеризуется температурным коэффициентом"
Это предложение соответствует приведенной грамматике, что поясняется следующей схемой

Первый блок существительного можно определить как субъектный блок (блок субъекта, того, кто или что производит действие). Второй блок существительного можно определить как объектный блок, т.е. того, на кого или на что направлено действие или посредством кого или чего оно реализуется. В дальнейшем будем иметь в виду это определение блока существительного. Оно соответствует стандартной схеме: субъект – действие – объект.
Простую программу разбора можно реализовать таким образом:
predicates
nondeterm proc(string)
nondeterm nounB(string,string,string)
nondeterm verB(string,string,string)
nondeterm noun(string)
nondeterm verb(string)
nondeterm adj(string)
clauses
proc(X):-
nounB(X,NB,Rest),
verb(Rest,VB,NB2),
nl,
write("Noun Block=",NB),
nl,
write("Verb Block=",VB),
nl,
write("Noun Block2=",NB2),
readchar(_).
nounB(X,NB,Rest):-
fronttoken(X,NB,Rest),
noun(NB),!.
nounB(X,NB,Rest):-
fronttoken(X,Ad,R),
adj(Ad),
fronttoken(R,NB1,Rest),
noun(NB1),
concat(Ad," ",F),
concat(F,NB1,NB),
!.
verb(X,VB,Rest):-
fronttoken(X,VB,Rest),
verb(VB),!.
noun("cat").
noun("mouse").
noun("sofa").
noun("yard").
adj("black").
adj("clever").
adj("scraggy").
verb("lays").
verb("mews").
verb("runs").
verb("wanton").
goal
write("Input sentence->"),
readln(X),
proc(X).
Работу этой программы иллюстрирует следующий скриншот:

Важнейшую роль играет предикат fronttoken (X,Y,Z), который из предложения X извлекает первое слово Y и помещает в остаток Z, например,
X=”cat lays on the sofa”,
fronttoken(X,T,Rest),
дает T=”cat”, Rest=” lays on the sofa”.
(замечание: пробел между словами при отрывании слова сохраняется).
Теперь нетрудно понять логику программы: сначала вырываем блок существительного, затем – блок глагола, остаток – есть блок дополнения:
proc(X):-
nounB(X,NB,Rest),
verb(Rest,VB,NB2),
nl,
write("Noun Block=",NB),
nl,
write("Verb Block=",VB),
nl,
write("Noun Block2=",NB2),
readchar(_).
Рассмотрим формирование блока существительного:
(1) nounB(X,NB,Rest):-
fronttoken(X,NB,Rest),
noun(NB),!.
(2) nounB(X,NB,Rest):-
fronttoken(X,Ad,R),
adj(Ad),
fronttoken(R,NB1,Rest),
noun(NB1),
concat(Ad," ",F),
concat(F,NB1,NB),
!.
Правило (1) просто проверяет, что оторванное слово есть существительное (noun(NB)).
Правило (2) проверяет, что первое оторванное слово есть прилагательное (adj(Ad)), а следующее за ним – существительное. Итоговый результат дает соединение:
...
concat(Ad," ",F),
concat(F,NB1,NB),
...
ЗАДАНИЕ.
1. Добавьте правила так, чтобы можно было распознавать предложения типа
scraggy black cat lays on the sofa (тощий черный кот лежит на диване – два прилагательных подряд)
black cat stilly lays on the sof a (черный кот тихо лежит на диване – наречие+глагол в глагольном блоке)
2. Программа должна выдавать сообщение о том, какой блок написан неправильно, если таковой найдется. Например, пусть дано предложение:
scraggy black cat on the sofa
= = пропущен блок глагола ==
3. Добавьте в программу фильтры для отсева недопустимых комбинаций прилагательных и существительных, например,
радостный кот
фиолетовый кот
глупый кот
и т.п. (эти сочетания зависят от вашей базы).






