Лекция 1. Формальные языки
Last updated
Last updated
Цивилизация началась с создания языка. За два миллиона лет передний мозг первобытного человека увеличился, а челюсть уменьшилась настолько, что появилось существо, способное передавать сложные сообщения с помощью звука. Язык был огромным эволюционным преимуществом, которое позволило нашим далеким предкам координировать охоту и заложило основу для сложного общества, в котором мы живем сегодня.
С тех пор язык распространялся через долгий исторический процесс завоеваний, торговли и ассимиляции. Сегодня основные великие языки -- английский, хинди и китайский -- являются родными для более чем трех миллиардов человек, и это продукт тысячелетней социальной эволюции. Такие языки называются естественными, и все мы используем один или несколько естественных языков для различных целей: для занятий наукой, поэзией, для юмора или просто для того, чтобы провести время в беседе.
Формальные языки, напротив, обязаны своим существованием усилиям нескольких талантливых людей; в отличие от естественных языков, они созданы для четко определенной цели; и мы часто можем очень точно датировать их происхождение. Их структура намного проще, чем у естественных языков, а элементов в лексиконе гораздо меньше. Языки программирования -- это представители формальных языков; так что C (изобретенный Ричи и Томпсоном в 1973 году) и Fortran (изобретенный Бэкусом и его командой в 1957 году) являются примерами формальных языков.
Другой прекрасный класс формальных языков -- это языки математики и логики. Это формальные языки, предназначенные для выражения мыслей и ведения рассуждений. Математика из-за ее древнего появления в истории человечества не может быть датирована так же точно, как языки программирования. Мы знаем, что еще в 30 веке до нашей эры шумеры научились использовать арифметику для ведения торговых счетов. Мы можем датировать математические инновации, такие как арабская система счисления, средневековьем. Математика подобна древнему городу, который вырос благодаря усилиям многих великих строителей, а система обозначений, которая дошла до нас, была усовершенствована и улучшена поколениями мыслителей. Но, несмотря на всю свою древность, язык математики по-прежнему остается гораздо более простой и ограниченной системой обозначений, чем любой из естественных языков. Мы будем называть математику и логику формальными системами.
Большинство систем доказательств имеют четыре важных свойства, и их изучение займет большую часть этой книги.
Каждый формальный язык (и, следовательно, каждая система доказательств) имеет синтаксис, который однозначно определяет, какие элементы лексикона составляют значимые формулы, а какие бессмысленны. Например, в языке программирования BASIC выражение let X = 3
является допустимым утверждением. Но X let 3 =
недопустимо. В арифметике 3 + 1 = 5
допустимо (хотя и неверно), но 3 + 1 5 =
недопустимо. Именно синтаксис формального языка определяет, какие комбинации символов могут рассматриваться как часть языка, а какие недопустимы.
Система доказательств должна иметь семантику, которая определяет, как мы можем интерпретировать символы этой системы доказательств. Например, мы можем интерпретировать a
, b
, c
в a + b = c
как обозначающие 1, 2 и 3 соответственно, но не Тома, Дика и Гарри. Семантика алгебры запрещает такую интерпретацию.
В системе доказательства должны быть правила доказательства, которые определяют, что считается доказательством в системе, а что нет. В идеале правила доказательства должны позволять механическую проверку любого доказательства, чтобы гарантировать его точность. Например, в алгебре у нас есть правило доказательства, которое позволяет нам сократить общие члены с каждой стороны уравнения, поэтому из x + a = x + b
мы можем вывести a = b
.
Наконец, со временем в системе доказательств может появиться набор эвристик или практических правил, которые позволяют людям решать задачи, поставленные в этой системе. Опять же, довольно много в этой книге посвящено тому, как решать задачи.
Языки программирования имеют много общих черт, наиболее очевидной из которых является синтаксис. Раньше семантика компьютерных языков объяснялась в довольно объемных руководствах на естественном языке, но в настоящее время большинство специалистов по информатике используют более точные инструменты для выражения значения таких утверждений, как let X = 3
. В наши дни книги типа "How To" распространены в программировании (например, "Как стать мастером C ++ за 48 часов"), но (к сожалению) гораздо меньше представлены в математике и логике.
Языки программирования и системы доказательства пересекаются по части синтаксиса; ибо без точного синтаксиса не может быть формального языка.
Отец синтаксиса в информатике - Джон Бэкус.
Бэкус руководил разработкой первого языка программирования высокого уровня -- Fortran (Formula Translation Language -- язык перевода формул) в 1957 году и участвовал в разработке Algol 60.
Чтобы точно описать Algol, необходимо было использовать нотацию для выражения его синтаксиса. Бэкус дал свое имя нотации для синтаксиса, используемой сегодня большинством информатиков -- форме Бэкуса-Наура, или БНФ. Эта нотация была адаптацией более ранней работы по синтаксису Ноама Хомского.
Подстановки
Правило
<sentence>
a <sentence>
По правилу 2.
aa <sentence>
По правилу 2.
aaa
По правилу 1.
Упражнение 1.3. Какие символы используются в грамматике для терминалов? Какие не являются терминалами? Какие правила нашей грамматики рекурсивны?
Обычно считается, что естественные языки, такие как английский, не контекстно-свободные, хотя ученые спорят по этому вопросу. Такие языки называются контекстно-зависимыми. Несомненно, большая часть синтаксиса английского языка может быть описана с помощью контекстно-свободной грамматики, хотя такая грамматика состояла бы из тысяч правил. Задача синтаксического анализа и описания таких грамматик относится к области обработки естественных языков (Natural Language Processing, NLP).
В области формальных языков БНФ с небольшими расширениями почти всегда подходит в качестве нотации для описания синтаксиса; то есть формальные языки обычно контекстно-свободные.
Хомский (переиздание от 2002 г.) -- начало синтаксического анализа. Гоф (1988) анализирует формальные языки с точки зрения создания компилятора. Ахо и Ульман (1972) -- классический текст по компьютерному синтаксическому анализу.
Мы начнем изучение БНФ с синтаксиса очень простого формального языка . Этот язык состоит из строк различной длины, состоящих из символа . Это означает, что наш формальный язык включает следующие предложения:
Мы не можем описать все предложения, перечислив их, потому что количество допустимых предложений бесконечно. БНФ предлагает решение. Вместо того, чтобы пытаться перечислить бесконечный набор предложений, мы формулируем правила, которые определяют, когда что-то является предложением. В БНФ длятаких правил два:
Мы можем прочитать как "может состоять из". Первое правило, переведенное на естественный язык, гласит, что " может состоять из одной буквы ". Второе правило гласит: " может состоять из единственной буквы , соединенной с ". -- оператор конкатенации; это указывает на то, что задействованные объекты соединены вместе без пробелов.
Второе правило кажется бессмысленным, поскольку оно объясняет, что такое , ссылкой на . Эта форма определения называется рекурсивным определением, и бессмысленность эта кажущаяся, а не реальная. Используя эти два правила, мы можем доказать, что является предложением.
Начнем с в БНФ. Правило может применяться для расширения символа , если символ встречается слева от в . расширяется путем замены тем, что находится справа от в . Таким образом, мы можем развернуть в (по правилу 1) или в (по правилу 2). Покажем, что -- это предложение.
Как только мы получили , больше нет правил, которые можно было бы использовать для дальнейших подстановок. Следовательно, - это предложение .
Процесс доказательства того, что формула является предложением языка, использующего БНФ, начинается с символа (называемого особым символом) и продолжается с использованием правил для расширения этого символа до тех пор, пока:
будет получена и...
получив , мы не можем применить никаких правил для дальнейшего расширения .
Синтаксический анализ (англ. parsing) -- это процесс использования грамматики для языка , чтобы показать, что формула является предложением языка . Синтаксический анализ является фундаментальной техникой в информатике, а в синтаксическом анализе с использованием БНФ компьютеры показывают превосходные результаты. Всякий раз, когда вы даете команду компьютеру, она должна быть написана на каком-то формальном языке, и требуется некоторая форма синтаксического анализа, чтобы компьютер мог интерпретировать вашу инструкцию. Парсер -- это компьютерная программа, которая выполняет синтаксический анализ.
Упражнение 1.1. Какие из следующих последовательностей символов содержат символы, которые можно расширить в соответствии с нашими правилами для ?
Упражнение 1.2. Какие предложения будет содержать язык , если удалить символ ?
Набор правил, задающих синтаксис языка, называется грамматикой. Символ, который встречается только справа от , называется терминалом. Символ , который используется для доказательства того, что строка символов является предложением , называется особым символом. Правило, которое имеет символ справа от , а также слева от , называется рекурсивным.
Наша новая терминология позволяет нам дать сжатое определение того, что значит быть предложением .
Формула является предложением , когда может быть сгенерирована с использованием грамматики для из особого символа , а содержит только терминалы.
Когда может быть сгенерировано таким образом, мы можем сказать, что соответствует грамматике .
Упражнение 1.4. Язык состоит из строк, состоящих из символов , за которыми следуют символы . Грамматика для задается следующими правилами:
Докажите, что -- это предложение .
Упражнение 1.5. Какие символы в грамматике являются терминалами? Какие не являются? Какие правила нашей грамматики рекурсивны?
В различной литературе можно встретить грамматику в следующей форме:
Эта нотация является частью расширенной БНФ, которая предлагает удобное сокращение для введенной нами ограниченной нотации. определяет альтернативные расширения нетерминала слева от . Таким образом, второе правило выше говорит:
может быть расширено до или может быть присоединено к
Следовательно, черта позволяет одному правилу выполнять работу нескольких правил из ограниченной нотации.
Еще одна особенность, которую иногда можно встретить в расширенной БНФ, -- использование специального символа для пустого расширения. Правило означает, что нетерминал можно вообще исключить из итоговой строки. Пустое расширение полезно, когда мы имеем дело с языками, где символ может встречаться ноль или более раз. Например, предположим, что состоит из всех предложений, состоящих из одного или нескольких вхождений , за которыми следует ноль или более (без конкатенации). Мы можем записать грамматику в расширенной нотации как
Распространенное расширение -- использование надстрочного индекса для обозначения ноля или более вхождений символа и надстрочного индекса для обозначения одного или нескольких вхождений. Это позволяет сократить определение правил до одной строки:
Упражнение 1.6. Определите грамматику БНФ для языка, который генерирует все строки формы , где и -- одинаковое количество символов и . Таким образом, , , являются предложениями языка , а и -- нет.
Следующий пример взят из реально используемого формального языка. Это язык или арифметика для первого класса (символ -- это обычное компьютерное обозначение умножения). включает все равенства вида , где и -- арифметические значения, заключенные в скобки. Например, , .
Упражнение 1.7. Докажите, что является предложением .
Грамматики БНФ соответствуют тому, что Ноам Хомский назвал типом 2 или контекстно-свободными грамматиками в своей основополагающей работе "Синтаксические структуры". Языки, синтаксис которых может быть описан с помощью контекстно-свободных грамматик, называются контекстно-свободными языками. Из теории формальных языков известно, что существуют некоторые простые языки, которые нельзя описать с помощью контекстно-свободных грамматик. Один из самых простых -- язык , состоящий из предложений, содержащих одинаковое количество , и друг за другом.