Języki, automaty i obliczenia/Wykład 11: Automat ze stosem

Z Studia Informatyczne
Wersja z dnia 18:09, 22 sie 2006 autorstwa Arek (dyskusja | edycje)
(różn.) ← poprzednia wersja | przejdź do aktualnej wersji (różn.) | następna wersja → (różn.)
Przejdź do nawigacjiPrzejdź do wyszukiwania

{LEMAT O POMPOWANIU DLA JĘZYKÓW
BEZKONTEKSTOWYCH. Własności języków bezkontekstowych. Problemy rozstrzygalne}

Wprowadzenie
Wprowadzimy i udowodnimy najprostszą wersję lematu o pompowaniu dla języków

bezkontekstowych.

Słowa kluczowe
wyprowadzenie lewostronne i prawostronne , gramatyka jednoznaczna, język jednoznaczny

Lemat o pompowaniu

Istotną cechą języków regularnych jest własność pompowania, którą ustaliliśmy w lemacie o pompowaniu. Podobną, ale nie taką samą, cechę posiadają języki bezkontekstowe. O ile dla języków regularnych własność pompowania wynikała z istnienia pętli w grafie opisującym automat, to dla języków bezkontekstowych pompowanie jest wynikiem powtarzającego się symbolu nieterminalnego w wyprowadzeniu dostatecznie długiego słowa w gramatyce.

Lemat

(o pompowaniu) Dla dowolnego języka bezkontekstowego LA* istnieją liczby naturalne N,M1 takie, że każde słowo wL o długości |w|>N można przedstawić w formie w=u1w1uw2u2, gdzie w1,w2,v1,v2,uA* , oraz

  1. |w1uw2|M
  2. w1w21
  3. u1w1iuw2iu2L dla i=0,1,...

Zanim przeprowadzimy dowód lematu zobaczmy jak stosuje się ten lemat do języka generowanego przez gramatykę ({v0,v1,v2},{a,b},v0,P),
gdzie P:v0v1v2,v1av2b,v2b|v0b

ANIMACJA ja-lekcja10-w-anim1-opis

Dowód

Załóżmy, bez utraty ogólności rozważań (dlaczego?), że język bezkontekstowy L nie zawiera słowa pustego i jest generowany przez gramatykę G=(VN,VT,v0,P) w normalnej postaci Chomsky' ego. Rozważmy dowolne wyprowadzenie w G

w0w1...wr

o długości r1 i w0VN. Niech najdłuższa ścieżka w drzewie binarnym T tego wyprowadzenia ma długość k (jako długość przyjmujemy tutaj liczbę wierzchołków, przez które przechodzi ścieżka). Indukcyjne ze względu na k łatwo jest

uzasadnić, że
|wr|2k1.

Załóżmy teraz, że zbiór VN ma p elementów i przyjmijmy N=2p oraz M=2p+1. Niech wL(G) będzie słowem, którego długość jest większa od N. Zatem najdłuższa ścieżka S w drzewie wyprowadzenia T będącego wyprowadzeniem słowa w w gramatyce G ma długość co najmniej p+2. A więc przechodzi przez co najmniej p+2 wierzchołków. Stąd, że wierzchołki maksymalne drzewa wyprowadzenia mają etykiety terminalne wnioskujemy, że w S występują dwa różne wierzchołki s1,s2 etykietowane przez ten sam symbol nieterminalny v. Przyjmijmy, że wierzchołek s1 jest bliższy wierzchołka początkowego drzewa wyprowadzenia niż s2. Wierzchołki s1,s2 można tak dobrać, aby podścieżka ścieżki S o początku w wierzchołku s1 miała długość równą co najwyżej p+2. Zauważmy teraz, że żadna ścieżka poddrzewa T1, którego wierzchołkiem początkowym jest s1, nie ma długości większej niż p+2. Jeśli więc w jest słowem określonym przez liście T1, to

|w|2(p+2)1=M.

Rozważmy teraz poddrzewo T2 drzewa T o wierzchołku początkowym w s2 i niech u będzie słowem określonym przez liście T2. Wtedy w=w1uw2 dla pewnych w1,w2VT*. W połączeniu z nierównością Uzupelnic lp1| uzyskujemy pierwszą własność postulowaną w lemacie. Co więcej, w1w21, ponieważ pierwsza produkcja wyprowadzenia v*w jest postaci vv1v2 dla pewnych v1,v2VN , a w gramatyce nie ma produkcji wymazującej. Zatem dla pewnych u1,u2VT* jest

v0*u1vu2*u1uu2
lub
v0*u1vu2*u1w1vw2u2*u1w1uw2u2=w

lub

v0*u1vu2*u1w1vw2u2*u1w1ivw2iu2*u1w1iuw2iu2

dla i=1,2,

W konsekwencji u1w1iuw2iu2L dla dowolnego i=0,1,.... Lemat zatem został udowodniony.

Analogicznie jak w przypadku języków regularnych, lemat o pompowaniu dla języków bezkontekstowych stosuje się najczęściej do uzasadnienia, że pewne języki nie należą do rodziny 2 . Takie właśnie zastosowanie przedstawione jest poniżej, na przykładzie języka, o którym pó{z}niej pokażemy, że jest kontekstowy, czyli należy do rodziny języków 1 .

Przykład

Niech L={anbncn:n1}. Przeprowadzając rozumowanie nie wprost, a więc zakładając bezkontekstowość tego języka, z lematu o pompowaniu uzyskujemy odpowiednie stałe M,N. Niech k>N3 i rozważmy słowo x1=akbkck. Zatem istnieje rozkład x1=u1w1uw2u2, w1w21 oraz xi=u1w1iuw2iu2L dla i=0,1,... . Z postaci słów języka L oraz z faktu w1w21 wnioskujemy, że słowa w1,w2 są potęgami jednej z liter a,b,c oraz że |xi| o ile i. A to wyklucza możliwość zachowania własności określajacej język L. Otrzymana sprzeczność prowadzi do wniosku, iż język {anbncn:n1} nie jest bezkontekstowy.

Lemat o pompowaniu wykorzystywany bywa również w dowodach rozstrzygalności pewnych problemów w rodzinie języków rozpoznawalnych. Zagadnieniem tym zajmiemy się w dalszej części tego wykładu.

Własności rodziny języków bezkontekstowych

Przedstawimy teraz podstawowe własności rodziny języków bezkontekstowych związane z zamkniętością ze względu na działania oraz z problemami jednoznaczności.

Twierdzenie

Rodzina języków bezkontekstowych 2 jest zamknięta ze względu na następujące działania:

  1. sumę mnogościową,
  2. katenację i operację iteracji *
  3. przecięcie (iloczyn mnogościowy) z językiem regularnym
  4. homomorfizm

Dowód

{}

Uzupelnic dom:s|. Niech Gi=(VNi,VT,v0i,Pi) będą gramatykami bezkontekstowymi, dla i=1,2, takimi, że VN1VN2= oraz Li=L(Gi). Język L=L1L2 jest generowany przez gramatykę bezkontekstową określoną w następujący sposób:

G=(VN1VN2{v0},VT,v0,P1P2{v0v01,v0v02}).

Uzupelnic dom:i|. Przy powyższych oznaczeniach, język L=L1L2 jest generowany przez gramatykę bezkontekstową:

G=(VN1VN2{v0},VT,v0,P1P2{v0v01v02})

Jeśli L=L(G), dla G=(VN,VT,v0,P) gramatyki bezkontekstowej, to L*=L(G), dla

gramatyki
G=(VN{v0},VT,v0,P{v01,v0v0v0},

która jest również gramatyką bezkontekstową.

Uzupelnic dom:h|. Niech R będzie dowolonym językiem rozpoznawanym przez pewien automat skończenie stanowy 𝒜=(S,f,s0,T). Język ten możemy przedstawić w postaci sumy R=i=1kRi, w której każdy język Ri jest rozpoznawany przez automat 𝒜 , w którym jako stan końcowy przyjmujemy tiT. Rodzina języków bezkontekstowych jest zamknięta ze względu na sumę mnogościową i oczywista jest równość LR=i=1k(LRi). Wystarczy zatem udowodnić, że język LRi jest bezkontekstowy. Załóżmy, że T={t} oraz L jest językiem generowanym przez gramatykę bezkontekstową G=(VN,VT,v0,P) w normalnej postaci Chomsky' ego. Bez utraty ogólności rozważań można także założyć, że 1L . Konstruujemy gramatykę

H=(S×(VNVT)×S,VT,(s0,v0,t),PH),

dla której PH zawiera następujące produkcje

  • (s1,v1,s2)(s1,v2,s3)(s3,v3,s2) dla siS, viVN jeśli v1v2v3P
  • (s1,v1,s2)(s1,a,s2) dla siS, aVT jeśli v1aP
  • (s1,a,s2)a dla siS, aVT jeśli f(s1,a)=s2.

Bezpośrednio z konstrukcji wynika, że gramatyka H jest bezkontekstowa. Łatwo również zauważyć, że język generowany przez gramatykę H jest równy LR.

Uzupelnic dom:j|. Niech h:A*B* oznacza dowolny homomorfizm, a LA* językiem bezkontekstowym generowanym przez gramatykę G=(VN,A,v0,P). Rozszerzamy homomorfizm h do wolnych monoidów (AVN)* i (BVN)*, przyjmując, że h na zbiorze VN jest równe identyczności. Łatwo zauważyć, że język h(L) jest generowany przez gramatykę bezkontekstową G=(VN,B,v0,Ph), w której

Ph={vh(w):vwP}.

Z równości LR=LR , zamkniętości klasy 3 ze względu na uzupełnienie oraz z punktu Uzupelnic dom:h| udowodnionego powyżej twierdzenia wynika następujący wniosek.

Wniosek

Niech LA* będzie dowolonym językiem bezkontekstowym, a RA* regularnym. Wtedy LR jest językiem bezkontekstowym.

Bez dowodu podajemy dwie dalsze własności związane z zamkniętością rodziny języków bezkontekstowych.

Fakt

Rodzina języków bezkontekstowych 2 jest zamknięta ze względu na podstawienie regularne i przeciwobraz przez homomorfizm.

Rodzina języków bezkontekstowych nie jest zamknięta na wszystkie działania boolowskie. Jak wynika z poniższego twierdzenia, jedynym działaniem boolowskim nie wyprowadzającym poza rodzinę języków bezkontekstowych jest suma mnogościowa.

Twierdzenie

Rodzina języków bezkontekstowych 2 nie jest zamknięta ze względu na

  1. iloczyn mnogościowy
  2. uzupełnienie

Dowód

Dla i=1,2 niech Gi=({v0,v1},{a,b,c},v0,Pi) będą gramatykami o następujących zbiorach praw:

P1={v0v0c,v0v1c,v1ab,v1av1b}P2={v0av0,v0av1,v1bc,v1bv1c}.

Gramatyki te są bezkontekstowe i generują, odpowiednio, następujące języki:

L(G1)={anbncm:n,m1}2
L(G2)={anbmcm:n,m1}2.

Języki te są bezkontekstowe, lecz ich przecięcie

L(G1)L(G2)={anbncn:n1}2

jest językiem istotnie kontekstowym.

Z udowodnionej właśnie własności oraz z praw de'Morgana wynika, że rodzina 2 nie jest też domknięta ze względu na uzupełnienie.

Jednoznaczność języków bezkontekstowych

Omówimy teraz, dość ogólnie zresztą, problem występujący w niektórych gramatykach bezkontekstowych, a polegający na wielokrotnym wyprowadzeniu tego samego słowa. Z punktu widzenia języków programowania, których syntaktykę opisują, w pewnym zakresie, gramatyki bezkontekstowe taka nadmiarowość (niejednoznaczność parsingu) jest cechą wysoce nieporządaną. Gramatyki, które nie będą mieć takiej własności nazwiemy jednoznacznymi. Jednoznacznym nazwiemy też język dla którego istnieje gramatyka jednoznaczna.

Definicja

Niech G=(VN,VT,v0,P) będzie gramatyką bezkontekstową. Lewostronnym (prawostronnym) wyprowadzeniem słowa wVT* w gramatyce G nazywamy

wyprowadzenie
v0w1..wn=w

takie, że dla każdego i=0,,n1,wi+1 jest generowane bezpośrednio z wi przez zastąpienie pierwszego z lewej (prawej) symbolu nieterminalnego występującego w słowie wi.

Jeśli chcemy zaznaczyć, że wyprowadzenie jest lewostronne lub prawostronne, to posługujemy się zapisem

v0L*w,v0P*w

Każde wyprowadzenie słowa w gramatyce bezkontekstowej można tak uporządkować, by sekwencja produkcji tworzyła prawostronne lub lewostronne wyprowadzenie. Stąd wynika też fakt, że dowolne słowo generowane przez gramatykę bezkontekstową ma tyle samo wyprowadzeń lewostronnych, co prawostronnych. Ilość różnych wyprowadzeń danego słowa jest w niektórych zastosowaniach gramatyk bezkontekstowych dość istotna, choćby w problemach parsingu, czyli poszukiwania w gramatyce wyprowadzenia dla danego słowa. Ilość różnych wyprowadzeń słów w gramatyce stanowi pewną informację na temat nadmiarowości tej gramatyki. Bardzo istotną rolę odgrywają zarówno w teorii, jak i zastosowaniach gramatyki bezkontekstowe jednoznaczne, których definicję podajemy poniżej.

Definicja

Gramatyka bezkontekstowa G jest jednoznaczna, wtedy i tylko wtedy, gdy każde słowo generowane przez tę gramatykę ma dokładnie jedno wyprowadzenie lewostronne (prawostronne). Język bezkontekstowy L nazywamy jednoznacznym, jeśli istnieje jednoznaczna gramatyka bezkontekstowa generująca ten język.

Jednoznaczność gramatyki oznacza istnienie dokładnie jednego drzewa wywodu dla każdego generowanego słowa. W klasie gramatyk bezkontekstowych problem jednoznaczności jest nierozstrzygalny. W rozdziale poświęconym algorytmicznej rozstrzygalności wrócimy do tego zagadnienia. Oczywiście wobec powyższego nierozstrzygalny jest też problem jednoznaczności języka. Problem jednoznaczności gramatyki i języka jest rozstrzygalny w podklasach języków bezkontekstowych, na przykład dla klasy języków ograniczonych, to znaczy takich LA* , że Lw1*...wn* dla pewnych słów w1,...,wnA* .

Przykład

Język {anbn+mcm:n,m>0} generowany przez gramatykę G=(VN,VT,v0,P) , gdzie VN={v0,v1} , VT={a,b,c} oraz
P=v0v1v2,v1av1b|ab,v2bv2c,|bc
jest, jak łatwo sprawdzić, językiem jednoznacznym.

Mówimy, że język L2 jest niejednoznaczny, jeśli nie jest jednoznaczny, czyli nie istnieje gramatyka jednoznaczna generująca ten język. Przykładem języka niejednoznacznego jest

L={anbncmdm:m,n1}{anbmcmdn:m,n1}.

Uzasadnienie tego faktu jest dosyć żmudne i dlatego zostało tutaj pominięte.

Zauważmy na koniec tego krótkiego omówienia problematyki jednoznaczności gramatyk, że każdy język regularny (ale nie każda gramatyka regularna) jest jednoznaczny. Jednoznaczna jest bowiem gramatyka otrzymana z automatu deterministycznego generującego ten język.

Jednoznaczny jest również język bezkontekstowy, który jest iloczynem LR , gdzie L2 i jest językiem jednoznacznym, a R3 . Gramatyka tego języka, skonstruowana w punkcie Uzupelnic p1| w twierdzeniu Uzupelnic tw 2| jest jednoznaczna, co wynika stąd, że automat rozpoznający R jest deterministyczny.

Problemy rozstrzygalne algorytmicznie

Podobnie jak dla języków regularnych tak i w przypadku bezkontekstowych lemat o pompowaniu wykorzystuje się do uzasadnienie rozstrzygalności pewnych problemów. Dla rodziny języków bezkontekstowych mamy następujące twierdzenie.

Twierdzenie

W rodzinie j{e}zyków bezkontekstowych 2 nast{e}puj{a}ce problemy s{a} rozstrzygalne:

  1. problem niepustości języka, L
  2. problem nieskończoności języka, cardL=0
  3. problem należenia słowa w do języka L

Dowód

Aby udowodnić punkt 1 wykorzystamy następującą równoważność:

LwL:|w|N,

Uzasadnienie tej równoważności polega

na rozk{}adzie s{}owa w spe{}niaj{a}cego warunek N<|w| (zgodnie z oznaczeniami i tezą lematu o pompowaniu) i zastąpieniu go s{}owem u1uu2 , które jest istotnie krótsze. Po sko{n}czonej ilo{s}ci takich skracających kroków dostaniemy s{}owo nale{z}{a}ce do j{e}zyka L i spe{}niaj{a}ce warunek |w|N .

W uzasadnieniu punktu 2 wykorzystamy równoważność

cardL=0wL:N<|w|N+M,

gdzie M,N są stałymi z lematu o pompowaniu.

Przyjmując, iż j{e}zyk L jest niesko{n}czony, wnioskujemy, {z}e istnieją w tym języku słowa dowolnie d{}ugie. Niech wL i |w|>N . Je{s}li w nie spe{}nia warunku |w|N+M , to stosujemy lemat o pompowaniu dla i=0 , uzyskując s{}owo u1uu2 nale{z}{a}ce do j{e}zyka i istotnie krótsze od w . Z warunku |w1w2||w1uw2|M (punkt 1 tezy lematu o pompowaniu) wynika, i{z} ró{z}nica d{}ugo{s}ci tych s{}ów nie mo{z}e by{c} wi{e}ksza ni{z} sta{}a M . Zatem po sko{n}czonej ilo{s}ci kroków uzyskujemy s{}owo nale{z}{a}ce do j{e}zyka i spe{}niaj{a}ce {z}{a}dany warunek.

Implikacja w przeciwną stronę ( ) wynika bezpo{s}rednio z lematu o pompowaniu. Istnieje mianowicie niesko{n}czony zbiór słów w postaci

u1w1iuw2iu2L

dla i=0,1,2,....

Punkt 3 twierdzenia wymaga podania odpowiedniego algorytmu. Jego prezentacją i omówieniem zajmujemy się poniżej.

{Algorytm CYK - przynależność słowa do języka.}

Rozważmy problem przynależności słowa w do danego języka, generowanego przez gramatykę bezkontekstową G. Jest to problem rozstrzygalny. Bardzo łatwo podać algorytm, wykorzystujący postać normalną Greibach. Po sprowadzeniu gramatyki G do postaci normalnej Greibach prawa strona każdej produkcji rozpoczyna się symbolem terminalnym i jest to jedyny symbol terminalny. Zatem, jeśli w=a1a2...an, to należy zbadać wszystkie wywody w G, z symbolu początkowego S, o długości dokładnie |w|, to znaczy wywody złożone z dokładnie |w| kroków. Jeśli dla każdego symbolu nieterminalnego istnieje co najwyżej k produkcji w gramatyce G, w których pojawia się on po lewej stronie, to algorytm będzie działał w czasie O(k|w|). Metoda ta jest jednak bardzo nieefektywna. Czasochłonne jest też samo sprowadzenie gramatyki G do postaci normalnej Greibach.

Istnieje szybszy algorytm rozwiązujący problem przynależności do języka. Jest to algorytm Cocke'a-Youngera-Kasamiego, w skrócie CYK.

Algorytm CYK działa w oparciu o ideę programowania dynamicznego . Rozważmy słowo w=a1a2...an oraz gramatykę G. Niech zbiór Vij zawiera wyłącznie te symbole nieterminalne, z których można wywieść słowo aiai+1...ai+j1, czyli

Vij={vVN:vG*aiai+1...ai+j1}.

Mamy zatem następującą równoważność:

wL(G)v0V1n.

Algorytm



{Cocke-Younger-Kasami - sprawdza, czy dane słowo należy do języka generowanego przez gramatykę bezkontekstową}

[1]

Wejście: G=(VN,VT,P,v0), wVT* - gramatyka bezkontekstowa i słowo w=a1a2...an o długości n

Wyjście: TAK lub NIE - odpowiedź na pytanie, czy wL(G).

GPostaćNormalnaChomsky'ego(G);

for i=1,...,nVi1{vVN: (va)P,aVT  ai=a};

endfor

for j=2,...,n

for i=1,...,nj+1Vij;

for k=1,...,j1VijVij{vVN: (vwy)P, wVik, yVi+kjk};

endfor

endfor

endfor

if v0V1n

return TAK, wL(G);

else

return NIE, w∉L(G);

endif


Algorytm CYK działa w czasie |w|3, gdzie |w| jest długością słowa, o którego przynależność do języka pytamy.

Przykład

Zbadamy, czy słowo w=bbaaaa należy do języka generowanego gramatyką:

Parser nie mógł rozpoznać (nieznana funkcja „\aligned”): {\displaystyle \displaystyle \aligned \nonumber v & \rightarrow & wx\ |\ yz \\ \nonumber w & \rightarrow & wy\ |\ xx\ |\ a \\ \nonumber x & \rightarrow & wz\ |\ b \\ \nonumber y & \rightarrow & xy\ |\ zz\ |\ a \\ \nonumber z & \rightarrow & yy\ |\ b \endaligned}

gdzie v jest symbolem początkowym.

Poniższa animacja ilustruje działanie algorytmu CYK.

ANIMACJA ja-lekcja10-w-anim2.jpg. Opis animacji w pliku ja-lekcja10-w-anim2-opis.