Главная · Поиск книг · Поступления книг · Top 40 · Форумы · Ссылки · Читатели

Настройка текста
Перенос строк


    Прохождения игр    
Demon's Souls |#13| Storm King
Demon's Souls |#11| Мaneater part 2
Demon's Souls |#10| Мaneater (part 1)
Demon's Souls |#9| Heart of surprises

Другие игры...


liveinternet.ru: показано число просмотров за 24 часа, посетителей за 24 часа и за сегодня
Rambler's Top100
Образование - Различные авторы Весь текст 991.22 Kb

Программирование в теоремах и задачах

Предыдущая страница Следующая страница
1 ... 73 74 75 76 77 78 79  80 81 82 83 84 85
вается выводимым, если существует вывод, который  им  кончается.
Множество всех выводимых слов (из терминальных символов) называ-
ется языком, порождаемым данной грамматикой.
     В  этой  и следующих главах мы будем ходить вокруг да около
такого вопроса: дана КС-грамматика; построить алгоритм,  который
по любому слову проверяет, выводимо ли оно в этой грамматике.

     Пример 1.   Алфавит:

            ( ) [ ] E

(четыре  терминальных  символа  и один нетерминальный символ E).
Начальный символ: e.
Правила:
                E -> (E)
                E -> [E]
                E -> EE
                E ->

(в последнем правиле справа стоит пустое слово).

     Примеры выводимых слов:

                     (пустое слово)
                ()
                ([])
                ()[([])]
                [()[]()[]]

     Примеры невыводимых слов:

                (
                )(
                (]
                ([)]

Эта грамматика встречалась в разделе 00 (где выводимость  в  ней
проверялась с помощью стека).

     Пример 2. Другая грамматика, порождающая тот же язык:

Алфавит: ( ) [ ] T E

Правила:
           E ->
           E -> TE
           T -> (E)
           T -> [E]

Начальным символом во всех приводимых далее примерах будем  счи-
тать  символ,  стоящий  в  левой части первого правила (в данном
случае это символ T), не оговаривая этого особо.

     Для каждого нетерминального символа можно рассмотреть  мно-
жество всех слов из терминальных символов, которые из него выво-
дятся (аналогично тому, как это сделано для начального символа в
определении выводимости в грамматике). Каждое правило грамматики
можно  рассматривать  как свойство этих множеств. Покажем это на
примере только что приведенной грамматики. Пусть SetT и  SetE  -
множества  слов (из скобок), выводимых из нетерминалов T и E со-
ответственно.  Тогда  правилам  грамматики  соответствуют  такие
свойства:

E ->            SetE содержит пустое слово
E -> TE         если слово A принадлежит SetT,
                слово B принадлежит
                SetE, то слово AB принадлежит SetE
T -> [E]        если A принадлежит
                SetE, то слово [A] принадлежит SetT
T -> (E)        если A принадлежит
                SetE, то слово (A) принадлежит SetT

Сформулированные  свойства множеств SetE, SetT не определяют эти
множества однозначно (например, они остаются верными, если в ка-
честве SetE и SetT взять множество всех слов). Однако можно  до-
казать,  что  множества,  задаваемые грамматикой, являются мини-
мальными среди удовлетворяющих этим условиям.

     13.1.1.  Сформулируйте точно и докажите это утверждение для
произвольной контекстно-свободной грамматики.

     13.1.2. Постройте грамматику, в которой выводимы слова
     (а) 00..0011..11 (число нулей равно числу единиц);
     (б) 00..0011..11 (число нулей вдвое больше числа единиц);
     (в) 00..0011..11 (число нулей больше числа единиц);
(и только они).

     13.1.3.  Доказать, что не существует КС-грамматики, в кото-
рой были бы выводимы слова вида  00..0011..1122..22,  в  которых
числа нулей, единиц и двоек равны, и только они.
     Указание. Докажите следующую лемму о произвольной  КС-грам-
матике:  для  любого  достаточно  длинного слова F, выводимого в
этой грамматике,  существует  такое  его  представление  в  виде
ABCDE,  что  любое  слово  вида AB..BCD..DE, где B и D повторены
одинаковое число раз, также выводимо  в  этой  грамматике.  (Это
можно  установить,  найдя  нетерминальный  символ, оказывающийся
своим собственным "наследником" в процессе вывода.)

     Нетерминальный символ можно рассматривать как "родовое имя"
для выводимых из него слов. В следующем примере для  наглядности
в   качестве   нетерминальных  символов  использованы  фрагменты
русских слов, заключенные в  угловые  скобки.  (С  точки  зрения
грамматики каждое такое слово - один символ!)

     Пример 3. Алфавит:

терминалы: + * ( ) x
нетерминалы: <выр>, <оствыр>, <слаг>, <остслаг>, <множ>
правила:

    <выр>     -> <слаг> <оствыр>
    <оствыр>  -> + <выр>
    <оствыр>  ->
    <слаг>    -> <множ> <остслаг>
    <остслаг> -> * <слаг>
    <остслаг> ->
    <множ>    -> x
    <множ>    -> ( <выр> )

Согласно этой грамматике, выражение  (<выр>)  -  это  последова-
тельность  слагаемых  (<слаг>), разделенных плюсами, слагаемое -
это последовательность множителей (<множ>), разделенных звездоч-
ками (знаками умножения), а множитель - это либо буква  x,  либо
выражение в скобках.

     13.1.4. Приведите пример другой грамматики, задающей тот же
язык.

     Ответ. Вот один из вариантов:
    <выр> -> <выр> + <выр>
    <выр> -> <выр> * <выр>
    <выр> -> x
    <выр> -> ( <выр> )

Эта  грамматика  хоть и проще, но в некоторых отношениях хуже, о
чем мы еще будем говорить.

     13.1.5. Дана произвольная КС-грамматика. Построить алгоритм
проверки принадлежности задаваемому ей языку, работающий полино-
миальное время (т.е. число действий не превосходит  полинома  от
длины проверяемого слова; полином может зависеть от грамматики).

     Решение. Заметим, что требование полиномиальности исключает
возможность решения, основанном на переборе всех возможных выво-
дов.  Тем не менее полиномиальный алгоритм существует. Поскольку
практического значения он не  имеет  (используемые  на  практике
КС-грамматики  обладают дополнительными свойствами, позволяющими
строить более эффективные алгоритмы), мы изложим лишь общую схе-
му решения.

     (1) Пусть в грамматике есть нетерминалы K1,...,Kn. Построим
новую грамматику с нетерминалами K1',...,Kn' так, чтобы выполня-
лось такое свойство: из Ki' выводятся (в новой грамматике) те же
слова, что из Ki в старой, за исключением пустого слова, которое
не выводится.
     Чтобы выполнить такое преобразование грамматики, надо выяс-
нить, из каких нетерминалов исходной грамматики выводится пустое
слово,  а  затем каждое правило заменить на совокупность правил,
получающихся, если в правой части опустить какие-либо из  нетер-
миналов, из которых выводится пустое слово, а у остальных поста-
вить штрихи. Например, если в исходной грамматике было правило

     K -> L M N,

причем  из L и N выводится пустое слово, а из M нет, то это пра-
вило надо заменить на правила

     K'-> L'M'N'
     K'->   M'N'
     K'-> L'M'
     K'->   M'

     (2) Итак, мы свели дело к грамматике, где ни из одного  не-
терминала не выводится пустое слово. Теперь устраним "циклы" ви-
да
     K -> L
     L -> M
     M -> N
     N -> K
(в правой части каждого правила один символ, и эти символы обра-
зуют  цикл  произвольной  длины): это легко сделать, отождествив
все входящие в цикл нетерминалы.

     (3) Теперь проверка принадлежности какого-либо слова языку,
порожденному  грамматикой,  может  выполняться  так: для каждого
подслова проверяемого слова и для каждого нетерминала  выясняем,
порождается ли это подслово этим нетерминалом. При этом подслова
проверяются  в порядке возрастания длин, а нетерминалы - в таком
порядке, чтобы при наличии правила K -> L нетерминал L проверял-
ся раньше нетерминала K. (Это возможно в  силу  отсутствия  цик-
лов.) Поясним этот процесс на примере.
     Пусть в грамматике есть правила
        K -> L
        K -> M N L
и других правил, содержащих K в левой части, нет. Мы  хотим  уз-
нать,  выводится  ли  данное слово A из нетерминала K. Это будет
так в одном из случаев: (1) если A выводится из L;  (2)  если  A
можно разбить на непустые слова B, C, D, для которых B выводится
из  M,  C выводится из N, а D выводится из L. Вся эта информация
уже есть (слова B, C, D короче A, а L рассмотрен до K).
     Легко  видеть, что число действий этого алгоритма полиноми-
ально. Степень полинома зависит от числа нетерминалов  в  правых
частях  правил и может быть понижена, если грамматику преобразо-
вать к форме, в которой правая часть каждого правила содержит  1
или  2  нетерминала (это легко сделать, вводя новые нетерминалы:
например, правило K -> LMK можно заменить на K -> LN и N ->  MK,
где N - новый нетерминал).

     13.1.6. Рассмотрим грамматику с  единственным  нетерминалом
K, нетерминалами 1, 2, 3 и правилами

     K -> 0
     K -> 1 K
     K -> 2 K K
     K -> 3 K K K

Как  проверить  выводимость слова в этой грамматике, читая слово
слева направо? (Число действий при прочтении одной буквы  должно
быть ограничено.)

     Решение.  Хранится целая переменная n, инвариант: слово вы-
водимо <-> непрочитанная часть представляет  собой  конкатенацию
(соединение) n выводимых слов.

     13.1.7. Тот же вопрос для грамматики

          K -> 0
          K -> K 1
          K -> K K 2
          K -> K K K 3

     13.2. Метод рекурсивного спуска.

     В отличие от алгоритма предыдущего раздела (представляющего
чисто теоретический интерес), алгоритмы на  основе  рекурсивного
спуска  часто используются на практике. Этот метод применим, од-
нако, далеко не ко всем грамматикам. Мы обсудим необходимые  ог-
раничения позднее.
     Идея  метода рекурсивного спуска такова. Для каждого нетер-
минала K мы строим процедуру ReadK, которая - в применении к лю-
бому входному слову x - делает две вещи:
     (1) находит наибольшее начало z слова x, которое может быть
началом выводимого из K слова;
     (2) сообщает, является ли найденное слово z выводимым из K.

     Прежде чем описывать этот метод более подробно, договоримся
о том, как процедуры получают сведения о входном слове и как со-
общают о результатах своей работы. Мы  предполагаем,  что  буквы
входного  слова  поступают к ним по одной, т.е. имеется граница,
отделяющая "прочитанную" часть от  "непрочитанной".  Будем  счи-
тать, что есть функция (без параметров)

     Next: Symbol

дающая  первый  непрочитанный  символ.  Ее значениями могут быть
терминальные символы, а также специальный  символ  EOI  (End  Of
Input  -  конец входа), означающий, что все слово уже прочитано.
Вызов  этой функции, естественно, не сдвигает границы между про-
читанной и непрочитанной частью - для этого есть процедура Move,
которая  сдвигает  границу  на один символ. (Она применима, если
Next <> EOI.) Пусть, наконец, имеется булевская переменная b.

     Теперь мы можем сформулировать наши требования к  процедуре
ReadK. Они состоят в следующем:
     (1)  ReadK  прочитывает  из  оставшейся  части слова макси-
мальное начало A, являющееся началом некоторого слова, выводимо-
го из K;
     (2) значение b становится истинным или ложным в зависимости
от того, является ли A выводимым из K или лишь невыводимым нача-
лом выводимого (из K) слова.

     Для удобства введем такую терминологию: выводимое из K сло-
во будем называть K-словом, а любое начало любого выводимого  из
K  слова - K-началом. Требования (1) и (2) вместе будем выражать
словами "ReadK корректна для K".

     Начнем с рассмотрения частного случая. Пусть правило
        K -> L M
является единственным правилом грамматики, содержащим K в  левой
части, пусть L, M - нетерминалы и ReadL, ReadM - корректные (для
них) процедуры.
     Рассмотрим такую процедуру:

     procedure ReadK;
     begin
     | ReadL;
     | if b then begin
     | | ReadM;
     | end;
     end;

     13.2.1.  Привести  пример, когда эта процедура будет некор-
ректной для K.
     Ответ. Пусть из L выводится любое слово вида 00..00, а из M
выводится лишь слово 01. Тогда из K выводится  слово  00001,  но
процедура ReadK этого не заметит.

     Укажем достаточноые условия корректности  процедуры  ReadK.
Для  этого нам понадобятся некоторые обозначения. Пусть фиксиро-
ваны КС-грамматика и некоторый  нетерминал  N  этой  грамматики.
Рассмотрим  N-слово A, которое имеет собственное начало B, также
являющееся N-словом (если такие есть). Для любой пары таких слов
A и B рассмотрим терминальный символ, идущий в A непосредственно
Предыдущая страница Следующая страница
1 ... 73 74 75 76 77 78 79  80 81 82 83 84 85
Ваша оценка:
Комментарий:
  Подпись:
(Чтобы комментарии всегда подписывались Вашим именем, можете зарегистрироваться в Клубе читателей)
  Сайт:
 
Комментарии (1)

Реклама