Анализ подхода на основе семантических сетей и шаблонного анализа
Требуется: по текстовому описанию геометрической задачи на естественном языке (русском) построить корректную иллюстрацию.
Практическая мотивация: автоматизация создания иллюстраций для электронных учебников и задачников снижает трудоёмкость подготовки материалов и позволяет динамически генерировать изображения для разных вариантов условий.
Исследовательская мотивация: задача требует формализации процесса визуализации, что представляет интерес для изучения связи языка и пространственного мышления.
Задача распадается на три независимых подзадачи, каждая из которых представляет самостоятельную область исследований:
Критическое замечание: наиболее сложной оказывается третья подзадача, так как она требует формализации неявных эвристик, которые человек применяет интуитивно.
Центральная сложность — определение корректной последовательности рисования геометрических объектов.
Граф зависимостей:
Следствие: необходимо построить DAG (направленный ациклический граф) зависимостей и определить топологический порядок обхода. Циклические зависимости указывают на некорректность или недоопределённость условия.
Проблема коллинеарности: если условие требует "прямая, проходящая через точки A, B, C", наивный подход (случайно сгенерировать три точки, затем построить прямую) приводит к вырожденному случаю.
Корректное решение:
Обобщение: для любого геометрического ограничения необходимо явно учитывать зависимости между объектами. Система должна различать первичные (independent) и вторичные (dependent) объекты.
Проект разбивается на три большие части:
Семантическая сеть — это граф, где узлы — понятия (точка, треугольник, прямая), а рёбра — связи между ними (принадлежит, перпендикулярен, является вершиной).
Чтобы построить её из текста, используется язык шаблонов:
<геометрический объект> <метка>
Примеры: «треугольник ABC», «отрезок MH», «точка X»
Результат: создаётся связь «ABC обозначает треугольник»
Текст разбивается на предложения, слова сопоставляются с понятиями (например, «вершина», «ортоцентр» → тип point), затем применяются шаблоны для поиска связей.
Полученная напрямую из текста сеть ещё сырая. Нужна «нормализация»:
Этот этап соответствует «мышлению» — обдумыванию условия перед рисованием.
Теперь самое интересное — алгоритм рисования. Вот его логика (упрощённо):
Аналогия с кроссвордом: сначала заполняем самое длинное слово, потом используем пересечения, чтобы вписать остальные.
Каждая геометрическая фигура — это класс с несколькими конструкторами, отражающими разные способы её построения:
Программа выбирает конструктор в зависимости от того, какие данные уже есть.
Когда точка не задана однозначно, программа оценивает её степень свободы:
Рисуем точки с минимальной степенью свободы — так меньше произвола.
Проект 2009 года, но идеи актуальны:
В 2009 году использовались шаблоны и графы. Сегодня, в эпоху больших языковых моделей:
Но! Базовые принципы остаются: понимание зависимостей, порядок построения, степени свободы. Нейросеть может «понять» текст лучше, но логика геометрического построения — та же.
Теперь перейдём к техническим деталям — как именно всё это было реализовано в коде.
Вместо полноценного NLP-парсера был разработан специализированный язык шаблонов. Это компромисс между простотой реализации и выразительностью.
Каждый шаблон состоит из двух частей:
Трафарет: <геометрический_объект> <обозначение>
Заготовка связи: обозначение.isSignOf(объект)
Найдёт: "отрезок MH", "точка X", "треугольник ABC"
Создаст: узлы для отрезка и обозначения "MH", связь между ними
Трафарет: прямую <sign1>, перпендикулярную <geom2> <sign2>
Заготовки:
sign1.isSignOf(line1) — первая прямаяsign2.isSignOf(geom2) — второй объектline1.isPerpedicularTo(geom2) — отношение перпендикулярностиНайдёт: "прямую l, перпендикулярную отрезку AB"
pointПреобразование текста в "помеченную" последовательность:
Исходный текст:
"Через H провели прямую, перпендикулярную отрезку MH, которая пересекла прямые AB и BC в точках X и Y."
После маркировки типов:
Через H-sign провели прямую-line, перпендикулярную отрезку-piece MH-sign, которая пересекла прямые-line AB-sign и BC-sign в точках-point X-sign и Y-sign.
Найденные понятия:
Семантическая сеть формализована как ориентированный граф:
Множество типов узлов:
NodeTypes = {sign, point, line, piece, triangle, square, circle, ...}
Множество типов связей:
LinkTypes = {isSignOf, belong, isVertex, isCenter, isPerpendicular, ...}
Узел: node := (id, nodeType), где id ∈ ℕ₀
Связь: link := (node₁, node₂, linkType)
Сеть: S := ({nodes}, {links})
Самая хитрая часть — превратить "сырую" сеть в удобную для рисования. Это трёхэтапный процесс:
Сложные понятия разбиваются на простейшие составляющие.
До декомпозиции:
(1, square)("ABCD", 1, isSignOf)После декомпозиции:
(2, point), (3, point), (4, point), (5, point)("A", 2, isSignOf), ("B", 3, isSignOf), ("C", 4, isSignOf), ("D", 5, isSignOf)(6, piece), (7, piece), (8, piece), (9, piece)Если встречаются понятия с одинаковыми обозначениями — они объединяются.
До унификации:
После унификации:
Удаляются узлы, которые были созданы на этапе декомпозиции, но не участвовали в унификации — они избыточны.
Каждая фигура — это класс, реализующий интерфейс IFigure с методом draw().
Point — точкаLine — прямаяRay — лучPiece — отрезокTriangle — треугольникSquare — четырёхугольникCircle — окружностьPerpendicular — перпендикулярParallel — параллельная прямаяMedian — медианаBisectrix — биссектрисаMiddlePerpendicular — срединный перпендикулярCorner — уголКлючевая идея: одна фигура может быть задана разными способами. Каждый способ — отдельный конструктор.
1. По центру и радиусу:
Circle(Point center, double radius)
2. По центру и точке на окружности:
Circle(Point center, Point pointOnCircle)
3. По трём точкам на окружности:
Circle(Point p1, Point p2, Point p3)
Все три способа однозначно определяют окружность! Программа выбирает конструктор в зависимости от доступных данных.
1. По трём вершинам:
Triangle(Point a, Point b, Point c)
2. По двум вершинам и углу:
Triangle(Point a, Point b, Angle angle)
while (не все фигуры нарисованы) {
// Ищем фигуры, для которых есть все опорные точки
for (каждая ненарисованная фигура F) {
constructor = найтиПодходящийКонструктор(F);
if (constructor && всеОпорныеТочкиЗаданы(constructor)) {
нарисоватьФигуру(F, constructor);
continue;
}
}
// Ищем точки, однозначно заданные нарисованными фигурами
for (каждая ненарисованная точка P) {
if (P.принадлежитНарисованнойФигуре() &&
P.положениеОднозначноЗадано()) {
нарисоватьТочку(P);
continue;
}
}
// Если прогресс застопорился — рисуем случайную точку
if (нетПрогресса) {
P = найтиТочкуСМинимальнойСтепеньюСвободы();
нарисоватьТочкуСлучайно(P);
}
}
Когда точка не задана однозначно, программа вычисляет её степень свободы — количество независимых параметров.
0 степеней — точка задана однозначно:
1 степень — точка на линии:
2 степени — свободная точка:
Выбираем точку с минимальной степенью свободы — так результат меньше зависит от случайности.
Пакет geom — геометрические примитивы:
draw()Пакет semantic — ядро логики:
Word — слово в текстеAbstractNode — узел сетиAbstractLink — связь в сетиSemanticAnalyzer — построение сети из текстаNetworkNormalizer — декомпозиция/унификацияPictureBuilder — алгоритм рисованияПодпакет semantic.nodes — типы узлов:
SignNode — обозначениеPointNode — точкаLineNode — прямаяTriangleNode — треугольникПодпакет semantic.links — типы связей:
IsSignOfLink — отношение обозначенияBelongLink — принадлежностьIsVertexLink — "является вершиной"PerpendicularLink — перпендикулярностьПакет gui — интерфейс (Swing):
Проект использовал принципы, которые обеспечили чистоту и расширяемость кода:
draw()IFigureIFigure
Рабочий процесс:
Для визуализации семантической сети использовалась библиотека GraphViz:
.dot файл (текстовое описание графа)Это позволяло видеть, как программа понимает текст — бесценно для отладки!
Что не было реализовано (и почему это интересно):
Каждое ограничение — это отдельное исследование! Проект показал принципиальную возможность, но до «промышленной» системы ещё далеко.
Архитектура спроектирована с учётом мультиязычности:
geom, semantic) не зависит от языкаПример шаблона для английского:
<geometric_object> <label>
Matches: "triangle ABC", "segment MH", "point X"
Язык описывает мир, но геометрия показывает его. Перевод между ними — это не просто техническая задача, а моделирование того, как разум связывает символы с образами.
Проект исследует фундаментальный вопрос: как мы думаем о пространстве?
Когда вы читаете «биссектриса угла», в голове не возникают слова — возникает картинка. Зрительные образы — язык творческого мышления. Психологи утверждают: человек не может помыслить понятие, не визуализировав его.
Заставляя компьютер превращать текст в рисунок, мы:
Автоматическое построение иллюстраций к геометрическим задачам — это больше, чем просто «удобная фича» для учебников. Это:
«Моделирование умственной деятельности человека при построении геометрического изображения вполне реалистично» — но требует глубокого понимания того, как мы думаем о пространстве.
Проект 2009 года заложил фундамент. Современные технологии могут построить на нём небоскрёб. Но принципы — извлечение смысла, моделирование зависимостей, уважение к геометрической логике — останутся неизменными.
Техническая реализация: Java, Swing (GUI), собственный язык шаблонов для NLP, семантические сети на основе графов. Исходный код включал модули geom (геометрические примитивы), semantic (анализ и сеть), gui (интерфейс).
О дипломе: Работа защищена в 2009 году в Академическом физико-технологическом университете РАН (Санкт-Петербург). Научный руководитель — д.ф.-м.н., доцент А.В. Омельченко. Рецензент — к.ф.-м.н., доцент С.И. Николенко.
← Вернуться на главную