Регулярная аппроксимация КС-языков

Материал из Викиконспекты
Версия от 09:19, 20 декабря 2016; Ateuhh (обсуждение | вклад) (Псевдокод)
Перейти к: навигация, поиск


Определения

Определение:
Контекстно-свободная грамматика G=N,Σ,P,S называется самоприменимой (англ. self-embeded), если AN:AαAβ, αεβε .


Определение:
Нетерминал AN в грамматике G=N,Σ,P,S называется рекурсивным (англ. recursive), если α,β(ΣN):AαAβ .


Определение:
Нетерминалы A,BN в грамматике G=N,Σ,P,S называются взаимно рекурсивными (англ. mutual recursive), если α1,β1,α2,β2(ΣN):Aα1Bβ1Bα2Aβ2 .


Алгоритм преобразования грамматики в конечный автомат

Лемма:
Не самоприменимая контекстно-свободная грамматика генерирует регулярный язык.
Доказательство:
В качестве конструктивного доказательства приведем алгоритм построения конечного автомата по грамматике. Также приведем ссылку на формальное доказательство[1].

Идея алгоритма

Пусть, N множество рекурсивных нетерминалов из N. Пусть, P={N1,N2,,NK} разбиение N на k дизъюнктных множеств взаимно рекурсивных нетерминалов, N1N2Nk=Ni Ni.

bool isLeftType(Ni: nonterminal): 
    return (AαBβ)P[ANiBNiαε]

bool isRightType(Ni: nonterminal): 
    return (AαBβ)P[ANiBNiβε]

Определим функцию getTheTypeOfMutualRecursiveSet(Ni):P{left,right,self,cycle}:

function getTheTypeOfMutualRecursiveSet(Ni: nonterminal):
   if !isLeftType(Ni) and isRightType(Ni) 
       return left
   if isLeftType(Ni) and !isRightType(Ni) 
       return right
   if isLeftType(Ni) and isRightType(Ni) 
       return self
   if !isLeftType(Ni) and !isRightType(Ni) 
       return cyclic
Когда функция getTheTypeOfMutualRecursiveSet(Ni)=left,Ni состоит только из лево-рекурсивных нетерминалов.
Аналогично для getTheTypeOfMutualRecursiveSet(Ni)=right.
Когда функция getTheTypeOfMutualRecursiveSet(Ni)=cyclic,Ni состоит только из правил, участвующих в рекурсии.
Функция getTheTypeOfMutualRecursiveSet(Ni)=self, для такого i, при котором грамматика самоприменима.

Заметим, что i getTheTypeOfMutualRecursiveSet(Ni)self, т.к в противном случае грамматика будет самоприменима. В основе алгоритма будет рекурсивный обход грамматики. Спускаемся по грамматике до тех пор не приходим в нетерминал или символ алфавита:

  1. Символ алфавит или ε — добавляем новое правило в автомат;
  2. Нерекурсивный нетерминал — запускаемся от всех правых частей правил, который терминал порождает;
  3. Рекурсивный нетерминал — в зависимости от типа рекурсивного нетерминала, продолжаем рекурсию (будет ясно из пседокода).

Псевдокод

Q — множество состояний ДКА.

Δ — множество переходов ДКА.

T — множество допускающих состояний.

function createFA(G: grammar):              // G=N,Σ,P,S 
    Q
    Δ
    s = createState
    f = createState
    F{f}
    return makeFA(s,S,f)
     
function makeFA(q0: vertex, a: char, q1: vertex):
   if a == ε or a Σ             // пришли в лист дерева разбора
        Δ=Δ{(q0,a,q1)}
        return
   if a == Xβ where X(NΣ)β(NΣ)|β|>0  
        q = createState
        makeFA(q0,X,q1)
        makeFA(q,β,q1)
        return
    if exist Ni where aNi  
         foreach b in Ni 
            qb = createState
         if getTheTypeOfMutualRecursiveSet(Ni) == left 
            foreach C in Ni where CX1XmX1,XmNi
               makeFA(q0,X1Xm,qC)             
            foreach C,D in Ni where CDX1XmX1,XmNi
               makeFA(qD,X1Xm,qC)
               Δ=Δ{(qa,ε,q1)}
          else                      // рекурсивный нетерминал right или cyclic   
            foreach C in Ni where CX1XmX1,XmNi
               makeFA(qC,X1Xm,q1)             
            foreach C,D in Ni where CDX1XmX1,XmNi
               makeFA(qD,X1Xm,qC)
               Δ=Δ{(q0,ε,qa)} 
             return
    foreach p in P where p == aβ
       makeFA(q0,β,q1)

Аппроксимации самоприменимой грамматики

В данном разделе покажем методы апроксимации: RTN (recursive transition network) аппроксимацию и MN (Mohri and Nederhof's) аппроксимацию — самоприменимой контекстно-свободной грамматики G=N,Σ,P,S к регулярной грамматике. Для удобства будем считать, что грамматика представлена в НФХ.

Автоматы TA,TB для грамматики AaBbAcABdAeBf

RTN аппроксимация

Построим, по данной грамматике аппроксимирующий ее конечный автомат.

Конечный автомат для грамматики AaBbAcABdAeBf
  1. Для каждого нетерминала A в грамматике, создадим новый конечный автомат TA, добавим в него два состояния qA и qA.
  2. Для каждого правила грамматике (AX1Xm)P, введм новые состояния в автомат этого нетерминала qA0qAm, а также добавим новые правила перехода в Δ: (qA,ε,q0),(qA0,X1,qA1),,(qAm1,Xm,qAm),(qAm,ε,qA).
  3. Таким образом мы построили множество конечных автоматов T = {TAAN} для каждого нетерминала A. Теперь объединим все в один автомат. Объединим все состоянии автоматов из T в множество Q. Скопируем все переходы каждого автомата из T в Δ. Далее для каждого перехода вида (q,A,p),AN, вместо него добавим два новых перехода: (q,ε,qA),(qA,ε,p).

MN аппроксимация

Построим по данной самоприменимой контекстно-свободной грамматике G регулярную грамматику G.

  1. Для каждого нетерминала AN из G, добавим нетерминалы A и A в G.
  2. Для каждого правила Aα0B1α1B2α2Bmαm, где B1,,BmNαiΣ. Добавим в G нетерминалы B1Bm,B1Bm и следуюшие правила: {Aα0B1B1α1B2BmαmA.
(Если m=0, тогда добавим правило Aα0A).

В итоге Gправоконтекстная грамматика, эквивалентная конечному автомату, который задает регулярный язык.

Пример

G={AαBαBβA|βG={AαBAB|εBβA|βBBαA|ε

Исходная грамматика G генерирует язык: {(ab)nann>0}. Результирущая грамматика G генирирует регулярный язык: (ab)+a.

Сравнение двух методов

Ясно, что оба языка, генерируемых конечным автомат для первого метода и апрокисимируещей граматикой для второго метода, содержат в себе язык генерируемый исходной грамматикой. Привлекателным свойством MN аппроксимации по сравнению с RTN, то, что она можеть быть применима к большим грамматикам: для каждого нетерминала грамматике G, добавляется не более одного нового нетерминала в G и размер результирующий грамматики максимум в 2 раза больше, чем размер исходной. Так как для RTN апроксимации грамматики G=N,Σ,P,S, количество состаяний апроксимируещего автомата в худшем случаи может составлять O(|N|2), что может быть критично для аппроксимации больших грамматик. Также,еще несколько эффекивных методов аппрокимации можно найти в статьях, приведенных в ссылках.

См. также

Примечания

Источники информации