Логика и формальные языки: объясните, почему язык L = { a^n b^n c^n | n ≥ 0 } не является контекстно‑свободным, приведите доказательство с помощью леммы о накачке для КС‑языков, опишите класс автоматов, распознающих этот язык, и практические последствия для парсеростроения
Коротко: язык L = { a^n b^n c^n | n ≥ 0 } не является контекстно‑свободным. Ниже — стандартное доказательство с помощью леммы о накачке для КС‑языков, затем — какие автоматы его распознают и какие практические следствия для построения парсеров.
1) Лемма о накачке для контекстно‑свободных языков Bar‑HillelBar‑HillelBar‑Hillel
Существует число p постоянноедляданногоязыкапостоянное для данного языкапостоянноедляданногоязыка такое, что для любого слова s ∈ L с |s| ≥ p существует разбиение s = u v w x y, удовлетворяющее
|v w x| ≤ p,|v x| > 0, и для всех i ≥ 0 слово u v^i w x^i y ∈ L.
2) Доказательство, что L не контекстно‑свободен Предположим противное: L — КС‑язык, и пусть p — число из леммы. Возьмём s = a^p b^p c^p ∣s∣=3p≥p|s| = 3p ≥ p∣s∣=3p≥p. По лемме s = u v w x y, |v w x| ≤ p и |v x| > 0.
Так как длина фрагмента vwx ≤ p, этот фрагмент полностью лежит не более чем в двух соседних блоках символов: он не может одновременно содержать символы a, b и c. Иначе его длина была бы > p посколькукаждыйблокap,bp,cpимеетдлинуp,аvwxограниченpпоскольку каждый блок a^p, b^p, c^p имеет длину p, а vwx ограничен pпосколькукаждыйблокap,bp,cpимеетдлинуp,аvwxограниченp. Значит возможны пять случаев:
vwx находится полностью в блоке a^p;полностью в блоке b^p;полностью в блоке c^p;пересекает границу a^p и b^p т.е.содержиттолькоaиbт.е. содержит только a и bт.е.содержиттолькоaиb;пересекает границу b^p и c^p т.е.содержиттолькоbиcт.е. содержит только b и cт.е.содержиттолькоbиc.
Во всех случаях v и x состоят только из одного или двух типов символов, но не из всех трёх. По лемме для любого i у слова u v^i w x^i y должны быть равные количества a, b и c. Возьмём i = 0 удалимvиxудалим v и xудалимvиx. Тогда число символов одного типа илидвухтиповили двух типовилидвухтипов уменьшится, а число третьего типа останется прежним, поэтому соотношение a:b:c нарушится. Формально:
Если v и x содержат только a илитолькоb,илитолькоcили только b, или только cилитолькоb,илитолькоc, то при i = 0 уменьшится ровно число соответствующих символов, а два других остаются равными p, значит числа станут неравными.Если v и x содержат a и b границаa∣bграница a|bграницаa∣b, то при i = 0 уменьшатся числа и a, и b на одно и то же положительное значение, число c останется p — тогда a и b станут < p возможноравнымеждусобойвозможно равны между собойвозможноравнымеждусобой, но c = p, так что все три не равны.Аналогично для случая b и c.
Во всех вариантах u v^0 w x^0 y ∉ L, что противоречит лемме. Следовательно, L не является контекстно‑свободным.
Усиление:аналогичныйвыводможнодатьспомощьюлеммыОгдена—онамощнееидаёттежерезультаты.Усиление: аналогичный вывод можно дать с помощью леммы Огдена — она мощнее и даёт те же результаты.Усиление:аналогичныйвыводможнодатьспомощьюлеммыОгдена—онамощнееидаёттежерезультаты.
3) Класс автоматов, распознающий L
L не распознаёт ни детерминированный, ни недетерминированный одно‑стековый pushdown‑автомат PDAPDAPDA — это и есть факт «не КС‑язык».L распознаётся более мощными устройствами: PDA с двумя стеками илиодинPDA,укоторогоестьдванезависимыхстекаили один PDA, у которого есть два независимых стекаилиодинPDA,укоторогоестьдванезависимыхстека. Два стека эквивалентны машине Тьюринга по вычислительной мощности, поэтому с их помощью можно легко проверить a^n b^n c^n например:впервыйстекпушимa,причтенииbпоп‑аемизпервогоипушимввторой;причтенииcпоп‑аемизвторого—проверяемпустотунапример: в первый стек пушим a, при чтении b поп‑аем из первого и пушим в второй; при чтении c поп‑аем из второго — проверяем пустотунапример:впервыйстекпушимa,причтенииbпоп‑аемизпервогоипушимввторой;причтенииcпоп‑аемизвторого—проверяемпустоту.Линейно ограниченная машина LBA,т.е.машинаТьюрингаспамятью,ограниченнойвходнойдлинойLBA, т.е. машина Тьюринга с памятью, ограниченной входной длинойLBA,т.е.машинаТьюрингаспамятью,ограниченнойвходнойдлиной — язык контекстно‑чувствительный тип‑1виерархииХомскоготип‑1 в иерархии Хомскоготип‑1виерархииХомского. Для a^n b^n c^n существует детерминированный алгоритм LBA, который последовательно «маркирует» соответствующие тройки символов, проходя по ленте несколько раз.Формальные грамматики более высокого уровня например,indexed‑грамматикиАхо,TAGидр.например, indexed‑грамматики Ахо, TAG и др.например,indexed‑грамматикиАхо,TAGидр. могут генерировать такие языки.
4) Практические последствия для парсеростроения
Большинство синтаксических анализаторов LL,LR,GLRипрочиеLL, LR, GLR и прочиеLL,LR,GLRипрочие, используемых в компиляторах и инструментах, ориентированы на контекстно‑свободные грамматики. Они не могут выразить и распознать языки с «трёхсторонними» равенствами типа a^n b^n c^n чисто синтаксически.В практических языках такие строгие «счётные» зависимости встречаются редко на уровне чистого синтаксиса; если нужны комплексные семантические связи например,одинаковоеколичествочего‑товтрёхместахнапример, одинаковое количество чего‑то в трёх местахнапример,одинаковоеколичествочего‑товтрёхместах, их обычно проверяют в семантической фазе semanticanalysissemantic analysissemanticanalysis с использованием дополнительных структур данных счётчики,таблицысимволовсчётчики, таблицы символовсчётчики,таблицысимволов или в отдельных проходах.Если действительно требуется проверка вида a^n b^n c^n, есть практичные подходы: оставить синтаксис КС и добавить семантические действия в парсер встроенныесчётчики/стэкивдействиеприсворачивании/развёртываниивстроенные счётчики/стэки в действие при сворачивании/развёртываниивстроенныесчётчики/стэкивдействиеприсворачивании/развёртывании;сделать несколько проходов: синтаксический парсер распознаёт общую форму, затем отдельный алгоритм проверяет равенство чисел;использовать расширенные формализмы indexed‑грамматики,контекстно‑чувствительныеграмматикиindexed‑грамматики, контекстно‑чувствительные грамматикиindexed‑грамматики,контекстно‑чувствительныеграмматики или машину с двумя стеками, если это оправдано.Вывод для разработчика парсеров: если требование выразимо только в языке выше контекстно‑свободного уровня, не пытайтесь «заставить» CFG это сделать — лучше отделить синтаксис и семантику или расширить механизм парсера семантическими действиями/проверками.
Краткое резюме: L = { a^n b^n c^n } не КС — классический пример языка, доказываемого леммой о накачке; для распознавания нужны более мощные машины двестеки,LBAит.д.две стеки, LBA и т.д.двестеки,LBAит.д.; в практике парсеростроения такие зависимости обычно проверяют семантически, а не чисто синтаксически.
Коротко: язык L = { a^n b^n c^n | n ≥ 0 } не является контекстно‑свободным. Ниже — стандартное доказательство с помощью леммы о накачке для КС‑языков, затем — какие автоматы его распознают и какие практические следствия для построения парсеров.
1) Лемма о накачке для контекстно‑свободных языков Bar‑HillelBar‑HillelBar‑Hillel Существует число p постоянноедляданногоязыкапостоянное для данного языкапостоянноедляданногоязыка такое, что для любого слова s ∈ L с |s| ≥ p существует разбиение s = u v w x y, удовлетворяющее
|v w x| ≤ p,|v x| > 0,и для всех i ≥ 0 слово u v^i w x^i y ∈ L.
2) Доказательство, что L не контекстно‑свободен
Предположим противное: L — КС‑язык, и пусть p — число из леммы. Возьмём s = a^p b^p c^p ∣s∣=3p≥p|s| = 3p ≥ p∣s∣=3p≥p. По лемме s = u v w x y, |v w x| ≤ p и |v x| > 0.
Так как длина фрагмента vwx ≤ p, этот фрагмент полностью лежит не более чем в двух соседних блоках символов: он не может одновременно содержать символы a, b и c. Иначе его длина была бы > p посколькукаждыйблокap,bp,cpимеетдлинуp,аvwxограниченpпоскольку каждый блок a^p, b^p, c^p имеет длину p, а vwx ограничен pпосколькукаждыйблокap,bp,cpимеетдлинуp,аvwxограниченp. Значит возможны пять случаев:
vwx находится полностью в блоке a^p;полностью в блоке b^p;полностью в блоке c^p;пересекает границу a^p и b^p т.е.содержиттолькоaиbт.е. содержит только a и bт.е.содержиттолькоaиb;пересекает границу b^p и c^p т.е.содержиттолькоbиcт.е. содержит только b и cт.е.содержиттолькоbиc.Во всех случаях v и x состоят только из одного или двух типов символов, но не из всех трёх. По лемме для любого i у слова u v^i w x^i y должны быть равные количества a, b и c. Возьмём i = 0 удалимvиxудалим v и xудалимvиx. Тогда число символов одного типа илидвухтиповили двух типовилидвухтипов уменьшится, а число третьего типа останется прежним, поэтому соотношение a:b:c нарушится. Формально:
Если v и x содержат только a илитолькоb,илитолькоcили только b, или только cилитолькоb,илитолькоc, то при i = 0 уменьшится ровно число соответствующих символов, а два других остаются равными p, значит числа станут неравными.Если v и x содержат a и b границаa∣bграница a|bграницаa∣b, то при i = 0 уменьшатся числа и a, и b на одно и то же положительное значение, число c останется p — тогда a и b станут < p возможноравнымеждусобойвозможно равны между собойвозможноравнымеждусобой, но c = p, так что все три не равны.Аналогично для случая b и c.Во всех вариантах u v^0 w x^0 y ∉ L, что противоречит лемме. Следовательно, L не является контекстно‑свободным.
Усиление:аналогичныйвыводможнодатьспомощьюлеммыОгдена—онамощнееидаёттежерезультаты.Усиление: аналогичный вывод можно дать с помощью леммы Огдена — она мощнее и даёт те же результаты.Усиление:аналогичныйвыводможнодатьспомощьюлеммыОгдена—онамощнееидаёттежерезультаты.
3) Класс автоматов, распознающий L
L не распознаёт ни детерминированный, ни недетерминированный одно‑стековый pushdown‑автомат PDAPDAPDA — это и есть факт «не КС‑язык».L распознаётся более мощными устройствами:PDA с двумя стеками илиодинPDA,укоторогоестьдванезависимыхстекаили один PDA, у которого есть два независимых стекаилиодинPDA,укоторогоестьдванезависимыхстека. Два стека эквивалентны машине Тьюринга по вычислительной мощности, поэтому с их помощью можно легко проверить a^n b^n c^n например:впервыйстекпушимa,причтенииbпоп‑аемизпервогоипушимввторой;причтенииcпоп‑аемизвторого—проверяемпустотунапример: в первый стек пушим a, при чтении b поп‑аем из первого и пушим в второй; при чтении c поп‑аем из второго — проверяем пустотунапример:впервыйстекпушимa,причтенииbпоп‑аемизпервогоипушимввторой;причтенииcпоп‑аемизвторого—проверяемпустоту.Линейно ограниченная машина LBA,т.е.машинаТьюрингаспамятью,ограниченнойвходнойдлинойLBA, т.е. машина Тьюринга с памятью, ограниченной входной длинойLBA,т.е.машинаТьюрингаспамятью,ограниченнойвходнойдлиной — язык контекстно‑чувствительный тип‑1виерархииХомскоготип‑1 в иерархии Хомскоготип‑1виерархииХомского. Для a^n b^n c^n существует детерминированный алгоритм LBA, который последовательно «маркирует» соответствующие тройки символов, проходя по ленте несколько раз.Формальные грамматики более высокого уровня например,indexed‑грамматикиАхо,TAGидр.например, indexed‑грамматики Ахо, TAG и др.например,indexed‑грамматикиАхо,TAGидр. могут генерировать такие языки.
4) Практические последствия для парсеростроения
Большинство синтаксических анализаторов LL,LR,GLRипрочиеLL, LR, GLR и прочиеLL,LR,GLRипрочие, используемых в компиляторах и инструментах, ориентированы на контекстно‑свободные грамматики. Они не могут выразить и распознать языки с «трёхсторонними» равенствами типа a^n b^n c^n чисто синтаксически.В практических языках такие строгие «счётные» зависимости встречаются редко на уровне чистого синтаксиса; если нужны комплексные семантические связи например,одинаковоеколичествочего‑товтрёхместахнапример, одинаковое количество чего‑то в трёх местахнапример,одинаковоеколичествочего‑товтрёхместах, их обычно проверяют в семантической фазе semanticanalysissemantic analysissemanticanalysis с использованием дополнительных структур данных счётчики,таблицысимволовсчётчики, таблицы символовсчётчики,таблицысимволов или в отдельных проходах.Если действительно требуется проверка вида a^n b^n c^n, есть практичные подходы:оставить синтаксис КС и добавить семантические действия в парсер встроенныесчётчики/стэкивдействиеприсворачивании/развёртываниивстроенные счётчики/стэки в действие при сворачивании/развёртываниивстроенныесчётчики/стэкивдействиеприсворачивании/развёртывании;сделать несколько проходов: синтаксический парсер распознаёт общую форму, затем отдельный алгоритм проверяет равенство чисел;использовать расширенные формализмы indexed‑грамматики,контекстно‑чувствительныеграмматикиindexed‑грамматики, контекстно‑чувствительные грамматикиindexed‑грамматики,контекстно‑чувствительныеграмматики или машину с двумя стеками, если это оправдано.Вывод для разработчика парсеров: если требование выразимо только в языке выше контекстно‑свободного уровня, не пытайтесь «заставить» CFG это сделать — лучше отделить синтаксис и семантику или расширить механизм парсера семантическими действиями/проверками.
Краткое резюме: L = { a^n b^n c^n } не КС — классический пример языка, доказываемого леммой о накачке; для распознавания нужны более мощные машины двестеки,LBAит.д.две стеки, LBA и т.д.двестеки,LBAит.д.; в практике парсеростроения такие зависимости обычно проверяют семантически, а не чисто синтаксически.