Алгоритм Эрли, доказательство оценки O(n^2) для однозначной грамматики — различия между версиями
Kirelagin (обсуждение | вклад) (→Алгоритм) |
Kirelagin (обсуждение | вклад) (→Время работы для однозначной грамматики) |
||
Строка 47: | Строка 47: | ||
|proof= | |proof= | ||
Ситуацию <tex>[A \rightarrow \alpha \cdot \beta, i]</tex> можно включить в <tex>I_j</tex> только по правилам <tex>(1)</tex> (если последний символ <tex>\alpha</tex> — терминал) и <tex>(2)</tex> (если нетерминал). В первом случае результат очевиден. Во втором случае допустим, что <tex>[A \rightarrow \alpha'B \cdot \beta, i]</tex> включается в <tex>I_j</tex>, когда рассматриваются две различные ситуации <tex>[B \rightarrow \eta_1 \cdot, k_1]</tex> и <tex>[B \rightarrow \eta_2 \cdot, k_2]</tex>. Тогда ситуация <tex>[A \rightarrow \alpha' \cdot B\beta, i]</tex> должна оказаться одновременно в <tex>I_{k_1}</tex> и в <tex>I_{k_2}</tex>. Таким образом, получаем: | Ситуацию <tex>[A \rightarrow \alpha \cdot \beta, i]</tex> можно включить в <tex>I_j</tex> только по правилам <tex>(1)</tex> (если последний символ <tex>\alpha</tex> — терминал) и <tex>(2)</tex> (если нетерминал). В первом случае результат очевиден. Во втором случае допустим, что <tex>[A \rightarrow \alpha'B \cdot \beta, i]</tex> включается в <tex>I_j</tex>, когда рассматриваются две различные ситуации <tex>[B \rightarrow \eta_1 \cdot, k_1]</tex> и <tex>[B \rightarrow \eta_2 \cdot, k_2]</tex>. Тогда ситуация <tex>[A \rightarrow \alpha' \cdot B\beta, i]</tex> должна оказаться одновременно в <tex>I_{k_1}</tex> и в <tex>I_{k_2}</tex>. Таким образом, получаем: | ||
− | * <tex>\alpha' \Rightarrow^* a_{i+1} \ldots a_{k_1}</tex> и <tex>\alpha' \Rightarrow^* a_{i+1} \ldots a_{k_2}</tex> | + | * <tex>\alpha' \Rightarrow^* a_{i+1} \ldots a_{k_1}</tex> и <tex>\alpha' \Rightarrow^* a_{i+1} \ldots a_{k_2}</tex>, |
− | * <tex>\eta_1 \Rightarrow^* a_{k_1+1} \ldots a_j</tex> и <tex>\eta_2 \Rightarrow^* a_{k_2+1} \ldots a_j</tex> | + | * <tex>\eta_1 \Rightarrow^* a_{k_1+1} \ldots a_j</tex> и <tex>\eta_2 \Rightarrow^* a_{k_2+1} \ldots a_j</tex>. |
− | Следовательно | + | Следовательно, <tex>\alpha' \eta_1 \Rightarrow^* a_{i+1} \ldots a_j</tex> и <tex>\alpha' \eta_2 \Rightarrow^* a_{i+1} \ldots a_j</tex>.<br/> |
− | + | Заметим, что <tex>S \Rightarrow^* \gamma A \delta \Rightarrow^* a_1 \ldots a_i A \delta \Rightarrow a_1 \ldots a_i \alpha' B \beta \delta</tex>. Предположим, что <tex>\beta \delta \Rightarrow^* w'</tex> (ведь в грамматике нет непорождающих нетерминалов). Тогда <tex>S \Rightarrow^* a_1 \ldots a_i \alpha' \eta_1 w'</tex> и аналогично <tex>S \Rightarrow^* a_1 \ldots a_i \alpha' \eta_2 w'</tex>.<br/> | |
− | Заметим, что <tex>S \Rightarrow^* \gamma A \delta \Rightarrow^* a_1 \ldots a_i A \delta \Rightarrow a_1 \ldots a_i \alpha' B \beta \delta</tex>. Предположим, что <tex>\beta \delta \Rightarrow^* w'</tex>. Тогда | + | Таким образом, если <tex>k_1 \ne k_2</tex>, то подстрока <tex>a_{i+1} \ldots a_j</tex> выводится двумя различными способами из <tex>\alpha' \eta_1</tex> и <tex>\alpha' \eta_2</tex> (поскольку в первом случае <tex>\alpha' \Rightarrow^* a_{i+1} \ldots a_{k_1}</tex>, а во втором <tex>\alpha' \Rightarrow^* a_{i+1} \ldots a_{k_2}</tex>), то есть у строки <tex>a_1 \ldots a_jw'</tex> есть два различных вывода, что противоречит однозначности грамматики. Если же <tex>k_1 = k_2</tex>, то <tex>\eta_1 \ne \eta_2</tex>, что приводит к аналогичному противоречию. |
− | |||
− | Таким образом, если <tex>k_1 \ne k_2</tex>, то подстрока <tex>a_{i+1} \ldots a_j</tex> выводится двумя различными способами из <tex>\alpha' \eta_1</tex> и <tex>\alpha' \eta_2</tex>, то есть у строки <tex>a_1 \ldots a_jw'</tex> есть два различных вывода, что противоречит однозначности грамматики. Если же <tex>k_1 = k_2</tex>, то <tex>\eta_1 \ne \eta_2</tex>, что приводит к аналогичному противоречию. | ||
}} | }} | ||
Версия 08:08, 20 января 2012
Алгоритм
Для начала модифицируем алгоритм Эрли.
Будем рассматривать грамматику без ε-правил и бесполезных символов.
= # Правило (0) — инициализация useful_loop(0) for i = 1..n for ∪= # Правило (1) useful_loop(j)
function useful_loop(j):while for # (*) for ∪= # Правило (2) for # (**) for ∪= # Правило (3) ∪=
В циклах, помеченных while
. Данная модификация является корректной.
- Рассмотрим цикл . Если в текущей ситуации этого цикла , то во внутреннем цикле просматривается список с меньшим индексом, в который новые ситуации больше не добавляются. Поэтому после первого просмотра этого списка будут добавлены все ситуации, удовлетворяющие условию, и больше ситуацию в цикле рассматривать не нужно. Если же , то , что возможно, только если . Тогда во внутреннем цикле не будет добавлено ни одной ситуации, так как не встречается в правых частях правил.
- Теперь рассмотрим цикл . Так как для каждой ситуации в список добавляется новая ситуация, соответствующая правилу из грамматики, а грамматика фиксирована, то после первого просмотра будут добавлены все возможные ситуации для .
Таким образом, во все списки будут добавлены ситуации, которые были бы добавлены в ходе обычного алгоритма. Очевидно, что лишних ситуаций добавлено не будет, так как в циклах
и просматривается подмножество полного списка. Значит этот алгоритм эквивалентен оригинальному.Время работы для однозначной грамматики
Лемма (1): |
в списке находится ситуаций. |
Доказательство: |
Так как грамматика фиксирована, то | количество ситуаций вида не больше некоторой константы. Таким образом, поскольку в находятся ситуации, у которых , всего в будет ситуаций.
Лемма (2): |
Пусть — однозначная КС-грамматика без непорождающих нетерминалов и — цепочка из . Тогда алгоритм Эрли пытается включить в не более одного раза, если . |
Доказательство: |
Ситуацию можно включить в только по правилам (если последний символ — терминал) и (если нетерминал). В первом случае результат очевиден. Во втором случае допустим, что включается в , когда рассматриваются две различные ситуации и . Тогда ситуация должна оказаться одновременно в и в . Таким образом, получаем:
Следовательно, |
Теорема: |
Если входная грамматика однозначна, то время выполнения алгоритма Эрли для слова длины составляет . |
Доказательство: |
Орагнизуем каждый список разбора таким образом, чтобы по любому символу , можно было за получить список тех и только тех ситуаций, содержащихся в , которые имеют вид .Время построения не зависит от входной строки.Рассмотрим .
|
Литература
- А. Ахо, Дж. Ульман. Теория синтакcического анализа, перевода и компиляции. Том 1. Синтакcический анализ.