Опубликован: 06.08.2007 | Доступ: свободный | Студентов: 1899 / 1053 | Оценка: 4.45 / 4.29 | Длительность: 18:50:00
Специальности: Программист
Лекция 3:

Языки и их представление

< Лекция 2 || Лекция 3: 123456 || Лекция 4 >
Аннотация: В данной лекции рассматривается понятие языков и их представление. Приведены такие определения, как алфавит, цепочка, грамматика, машина Тьюринга. Также приведены примеры практической реализации основных понятий в теории программирования.

Алфавиты, цепочки и языки

Алфавит, или словарь - это конечное множество символов. Для обозначения символов мы будем пользоваться цифрами, латинскими буквами и специальными литерами типа \sharp, \$

Пусть V - алфавит. Цепочка в алфавите V - это любая строка конечной длины, составленная из символов алфавита V . Синонимом цепочки являются предложение, строка и слово. Пустая цепочка (обозначается e) - это цепочка, в которую не входит ни один символ.

Конкатенацией цепочек x и y называется цепочка xy. Заметим, что xe = ex = x для любой цепочки x.

Пусть x, y, z - произвольные цепочки в некотором алфавите. Цепочка y называется подцепочкой цепочки xyz. Цепочки x и y называются, соответственно, префиксом и суффиксом цепочки xy. Заметим, что любой префикс или суффикс цепочки является подцепочкой этой цепочки. Кроме того, пустая цепочка является префиксом, суффиксом и подцепочкой для любой цепочки.

Пример 2.1. Для цепочки abbba префиксом является любая цепочка из множества L_1 = \{e, a, ab, abb, abbb, abbba\} суффиксом является любая цепочка из множества \{e, a, ba, bba, bbba, abbba\} подцепочкой является любая цепочка из множества L_1 \bigcup L_2

Длиной цепочки w (обозначается |w| ) называется число символов в ней. Например, |abababa| = 7, а |e| = 0. Язык в алфавите V - это некоторое множество цепочек в алфавите V.

Пример 2.2. Пусть дан алфавит V = {a, b}. Вот некоторые языки в алфавите V:

  1. L_1={\O} — пустой язык;
  2. L_2 = \{e\} - язык, содержащий только пустую цепочку (заметим, что L_1 и L_2 - различные языки)
  3. L_3 - язык, содержащий цепочки из a и b, длина которых не превосходит 2
  4. L_4 - язык, включающий всевозможные цепочки из a и b, содержащие четное число a и четное число b
  5. L_5 = \{a^{n^2}|n>0\} - язык цепочек из a, длины которых представляют собой квадраты натуральных чисел.

Два последних языка содержат бесконечное число цепочек.

Введем обозначение V^* для множества всех цепочек в алфавите V, включая пустую цепочку. Каждый язык в алфавите V является подмножеством V^*. Для обозначения множества всех цепочек в алфавите V , кроме пустой цепочки, будем использовать V^+.

Пример 2.3. Пусть V=\{0,1\}. Тогда V^*=\{e, 0, 1, 00, 01, 10, 11, 000, \ldots\}, V^+=\{0, 1, 00, 01, 10, 11, 000, \ldots\}

Введем некоторые операции над языками.

Пусть L_1 и L_2 - языки в алфавите V. Конкатенацией языков L_1 и L_2 называется язык L_1L_2 = \{xy|x \in L_1, y \in L_2\}.

Пусть L - язык в алфавите V. Итерацией языка L называется язык L^*, определяемый следующим образом:

L^0=\{|e\} ( 1)
L^n = LL^{n-1}, n \geq1 ( 2)
L^*=\bigcup\limits^\infty_{n=0} L^n ( 3)

Пример 2.4. Пусть L_1 = \{aa, bb\} и L_2 = \{e, a, bb\}. Тогда

L_1L_2=\{aa, bb, aaa, bba, aabb, bbbb\}, и

L^*_1=\{e, aa, bb, aaaa, aabb, bbaa, bbbb, aaaaaa, \ldots\}

Большинство языков, представляющих интерес, содержат бесконечное число цепочек. При этом возникают три важных вопроса.

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

Во-вторых, для любого ли языка существует конечное представление? Можно предположить, что ответ отрицателен. Мы увидим, что множество всех цепочек над алфавитом счетно. Язык - это любое подмножество цепочек. Из теории множеств известно, что множество всех подмножеств счетного множества несчетно. Хотя мы и не дали строгого определения того, что является конечным представлением, интуитивно ясно, что любое разумное определение конечного представления ведет только к счетному множеству конечных представлений, поскольку нужно иметь возможность записать такое конечное представление в виде строки символов конечной длины. Поэтому языков значительно больше, чем конечных представлений.

В-третьих, можно спросить, какова структура тех классов языков, для которых существует конечное представление?

Представление языков

Процедура - это конечная последовательность инструкций, которые могут быть механически выполнены. Примером может служить машинная программа. Процедура, которая всегда заканчивается, называется алгоритмом.

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

Такой метод представляет язык с точки зрения распознавания. Язык можно также представить методом порождения. А именно, можно дать процедуру, которая систематически порождает в определенном порядке цепочки языка.

Если мы можем распознать цепочки языка над алфавитом V либо с помощью процедуры, либо с помощью алгоритма, то мы можем и генерировать язык, поскольку мы можем систематически генерировать все цепочки из V^*, проверять каждую цепочку на принадлежность языку и выдавать список только цепочек языка. Но если процедура не всегда заканчивается при проверке цепочки, мы не сдвинемся дальше первой цепочки, на которой процедура не заканчивается. Эту проблему можно обойти, организовав проверку таким образом, чтобы процедура никогда не продолжала проверять одну цепочку бесконечно. Для этого введем следующую конструкцию.

Предположим, что V имеет p символов. Мы можем рассматривать цепочки из V^* как числа, представленные в базисе p, плюс пустая цепочка e. Можно занумеровать цепочки в порядке возрастания длины и в "числовом" порядке для цепочек одинаковой длины. Такая нумерация для цепочек языка \{a; b; c\}^* приведена на рис. 2.1, а.

Пусть P - процедура для проверки принадлежности цепочки языку L. Предположим, что P может быть представлена дискретными шагами, так что имеет смысл говорить об i -ом шаге процедуры для любой данной цепочки. Прежде чем дать процедуру перечисления цепочек языка L, дадим процедуру нумерации пар положительных чисел.

Все упорядоченные пары положительных чисел (x, y) можно отобразить на множество положительных чисел следующей формулой:

z = (x + y - 1)(x + y - 2)/2 + y

Пары целых положительных чисел можно упорядочить в соответствии со значением z ( рис. 2.1, б).

< Лекция 2 || Лекция 3: 123456 || Лекция 4 >