Формальные языки
Лемма о накачке для КС-языков
Как доказать что язык НЕ является контекстно-свободным? Это похоже на задачу доказательства отсутствия: нельзя просто показать что грамматика не работает. Нужен универсальный инструмент - и это лемма о накачке.
- **Теория компиляторов**: доказательство что C не является КС (из-за scope rules) объясняет почему C компиляторы имеют отдельную фазу symbol table lookup вместо чистого parsing
- **Трансформеры и формальные языки**: работы Hahn et al. (2020), Bhattamishra et al. (2020) показывают что attention механизм теоретически превосходит КС - это частично объясняет способность GPT к синтаксическому анализу
- **Биоинформатика**: RNA структурирование (вторичная структура) описывается КС-грамматиками, третичная структура - уже за пределами КС. Лемма о накачке применялась для доказательства этих границ
Лемма о накачке: структура длинных строк
Язык $\{a^n b^n c^n | n \geq 0\}$ не является контекстно-свободным. Как это доказать? Не существует алгоритма, который проверяет три счётчика одновременно без памяти. Но это интуиция, не доказательство. Лемма о накачке даёт формальный инструмент.
Идея: если КС-язык бесконечен, то в нём есть 'повторяющаяся структура'. В длинных строках обязательно найдётся место для 'накачки' - повторения части строки любое число раз с сохранением принадлежности языку. Если такого места нет - язык не КС.
Откуда берётся разбиение uvwxy? Из parse tree! Для длинной строки дерево разбора должно быть высоким. По лемме о пути в дереве: если высота > |V| (число нетерминалов), какой-то нетерминал повторяется на пути от корня до листьев. Это повторение и создаёт 'накачиваемый' цикл. Точно как в регулярных автоматах - повторяющееся состояние.
Почему в parse tree для достаточно длинных строк обязательно найдётся повторяющийся нетерминал на пути от корня до листа?
Лемма Огдена: более сильный инструмент
Лемма Огдена (1968) - усиление pumping lemma. Можно 'пометить' позиции в строке и гарантировать, что накачиваемые части v и x содержат хотя бы одну помеченную позицию. Это делает некоторые доказательства значительно проще - там, где pumping lemma даёт слишком свободный выбор разбиения.
Пример: язык $\{a^i b^j c^k | i = j$ или $j = k\}$. Доказать не-КС обычной леммой сложно из-за двух условий (disjunction). Огден позволяет сосредоточиться на b-позициях, которые должны участвовать в накачке, и получить противоречие с одним из условий.
В чём главное преимущество леммы Огдена перед стандартной леммой о накачке?
Примеры не-КС языков
Три канонических языка, которые не являются КС: $\{a^n b^n c^n\}$ (три счётчика), $\{ww | w \in \Sigma^*\}$ (удвоение строки), $\{a^{n^2}\}$ (квадраты). Все они требуют одновременного отслеживания зависимостей, которые КС-грамматика не может выразить.
Связь с ML: attention mechanism в трансформерах теоретически моделирует языки класса выше КС. В 2019-2022 годах появились работы доказывающие, что одно-слойные трансформеры с одной head эквивалентны Star-Free regular languages. Multi-head attention достигает класса выше КС - это частично объясняет почему трансформеры распознают синтаксические зависимости через произвольные дистанции.
Почему язык {ww | w in {a,b}*} (конкатенация строки с собой) не является КС?
Свойства замкнутости КС-языков
КС-языки замкнуты относительно: объединения (L1 U L2), конкатенации (L1 L2), итерации Клини (L*), гомоморфизма, обращения. Не замкнуты относительно: пересечения (L1 ∩ L2), дополнения. Это принципиально важно для построения парсеров - нельзя 'пересекать' грамматики произвольно.
Практическое следствие: многие реальные языки программирования не являются контекстно-свободными. Переменные должны быть объявлены до использования - это пересечение двух условий. Решение: разделить на KS-синтаксис (парсинг) и semantic analysis (type checking, scope resolution). Rust ownership rules вообще требуют более выразительных формализмов.
Пересечение КС-языка с регулярным языком - КС. Это важно: можно использовать регулярные выражения для 'фильтрации' КС-языка без выхода за класс. Например, подмножество Python с только простыми выражениями (без циклов) остаётся КС. В компиляторах - lexer (регулярный) + parser (КС) работают совместно именно на этом основании.
Если язык программирования задан KS-грамматикой в BNF, весь язык является КС
BNF описывает только синтаксис. Семантические ограничения (типизация, scope, ownership) выходят за класс КС и проверяются отдельным анализатором
Например, проверка что переменная объявлена до использования - это пересечение КС-языка с условием на контекст. По незамкнутости пересечения - это уже не обязательно КС. Именно поэтому в компиляторах parsing и semantic analysis - отдельные фазы
Почему пересечение двух КС-языков не является обязательно КС?
Связанные темы
Лемма о накачке завершает теорию КС-языков:
- Pumping Lemma для регулярных языков — Более простая версия - предшественник КС леммы
- CYK алгоритм — Parse tree структура, используемая в доказательстве леммы
- Разрешимость — Понимание границ КС ведёт к вопросам что вообще разрешимо
Ключевые идеи
- **Pumping Lemma для CFG**: для бесконечного КС-языка любая длинная строка s=uvwxy накачивается (uv^i wx^i y in L). |vwx|<=p, |vx|>=1.
- **Источник разбиения**: повторяющийся нетерминал в parse tree (по принципу Дирихле на длинном пути). Аналог повторяющегося состояния в регулярном автомате.
- **Лемма Огдена**: усиление - позволяет 'помечать' позиции и гарантировать их попадание в накачиваемые части. Полезна для сложных дизъюнктивных условий.
- **Замкнутость**: КС замкнуты по объединению, конкатенации, Клини. НЕ замкнуты по пересечению и дополнению. Следствие: синтаксис != семантика в компиляторах.
Вопросы для размышления
- Язык {a^n b^n} - КС. {a^n b^n c^n} - не КС. Где именно проходит граница? Что определяет 'мощность' грамматики?
- Attention в трансформерах теоретически превосходит КС. Означает ли это что GPT 'понимает' синтаксис лучше традиционных парсеров?
- Языки программирования намеренно проектируются КС-парсируемыми. Какие синтаксические ограничения существуют именно из-за этого требования?
Связанные уроки
- fl-11-pumping-lemma — Регулярная лемма о накачке - более простой аналог для регулярных языков
- fl-22-decidability — Понимание границ КС-языков ведёт к вопросам разрешимости
- alg-22-backtracking — Доказательство через лемму о накачке - это структурированный backtracking на противнике
- fl-15-cyk — CYK и parse trees необходимы для понимания pumping lemma для CFG
- ml-02