1 X-gramatyki, Hierarchia Chomsky ego

Podobne dokumenty
2.2. Gramatyki, wyprowadzenia, hierarchia Chomsky'ego

JAO - Wprowadzenie do Gramatyk bezkontekstowych

Hierarchia Chomsky ego Maszyna Turinga

Imię, nazwisko, nr indeksu

Automat ze stosem. Języki formalne i automaty. Dr inż. Janusz Majewski Katedra Informatyki

Języki, automaty i obliczenia

Gramatyki, wyprowadzenia, hierarchia Chomsky ego. Gramatyka

Języki formalne i automaty Ćwiczenia 1

Matematyczne Podstawy Informatyki

JAO - lematy o pompowaniu dla jezykow bezkontekstowy

Maszyna Turinga języki

Hierarchia Chomsky ego

Matematyczne Podstawy Informatyki

Zadanie 1. Czy prawdziwa jest następująca implikacja? Jeśli L A jest językiem regularnym, to regularnym językiem jest też. A = (A, Q, q I, F, δ)

(j, k) jeśli k j w przeciwnym przypadku.

złożony ze słów zerojedynkowych o długości co najmniej 3, w których druga i trzecia litera od końca sa

Przykład: Σ = {0, 1} Σ - zbiór wszystkich skończonych ciagów binarnych. L 1 = {0, 00, 000,...,1, 11, 111,... } L 2 = {01, 1010, 001, 11}

Języki formalne i automaty Ćwiczenia 2

10110 =

Dopełnienie to można wyrazić w następujący sposób:

Matematyczna wieża Babel. 4. Ograniczone maszyny Turinga o językach kontekstowych materiały do ćwiczeń

Języki formalne i automaty Ćwiczenia 4

Języki, automaty i obliczenia

Rozwiązania około dwustu łatwych zadań z języków formalnych i złożoności obliczeniowej i być może jednego chyba trudnego (w trakcie tworzenia)

Analizator syntaktyczny

Języki, automaty i obliczenia

1 Automaty niedeterministyczne

Obliczenia inspirowane Naturą

3.4. Przekształcenia gramatyk bezkontekstowych

Języki formalne i automaty Ćwiczenia 9

LOGIKA I TEORIA ZBIORÓW

domykanie relacji, relacja równoważności, rozkłady zbiorów

Gramatyki rekursywne

Zadanie 1. (6 punktów) Słowo w nazwiemy anagramem słowa v jeśli w można otrzymać z v poprzez zamianę kolejności liter. Niech

Rodzinę F złożoną z podzbiorów zbioru X będziemy nazywali ciałem zbiorów, gdy spełnione są dwa następujące warunki.

1 Działania na zbiorach

Maszyna Turinga. Algorytm. czy program???? Problem Hilberta: Przykłady algorytmów. Cechy algorytmu: Pojęcie algorytmu

A i. i=1. i=1. i=1. i=1. W dalszej części skryptu będziemy mieli najczęściej do czynienia z miarami określonymi na rodzinach, które są σ - algebrami.

Języki formalne i automaty Ćwiczenia 7

Struktury danych i złożoność obliczeniowa Wykład 7. Prof. dr hab. inż. Jan Magott

Wykład 4. Określimy teraz pewną ważną klasę pierścieni.

Parsery LL(1) Teoria kompilacji. Dr inż. Janusz Majewski Katedra Informatyki

Indukcja. Materiały pomocnicze do wykładu. wykładowca: dr Magdalena Kacprzak

Metoda Tablic Semantycznych

Metody Kompilacji Wykład 8 Analiza Syntaktyczna cd. Włodzimierz Bielecki WI ZUT

Układy równań i nierówności liniowych

Zbiory, relacje i funkcje

0 + 0 = 0, = 1, = 1, = 0.

Wykład 1. Na początku zajmować się będziemy zbiorem liczb całkowitych

TEORETYCZNE PODSTAWY INFORMATYKI

Efektywność Procedur Obliczeniowych. wykład 5

GRAMATYKI BEZKONTEKSTOWE

Matematyka dyskretna. Andrzej Łachwa, UJ, /10

LX Olimpiada Matematyczna

Część wspólna (przekrój) A B składa się z wszystkich elementów, które należą jednocześnie do zbioru A i do zbioru B:

Metody Kompilacji Wykład 7 Analiza Syntaktyczna

n=0 Dla zbioru Cantora prawdziwe są wersje lematu 3.6 oraz lematu 3.8 przy założeniu α = :

F t+ := s>t. F s = F t.

Języki formalne i automaty Ćwiczenia 8

Sortowanie topologiczne skierowanych grafów acyklicznych

Logika Stosowana. Wykład 1 - Logika zdaniowa. Marcin Szczuka. Instytut Informatyki UW. Wykład monograficzny, semestr letni 2016/2017

Paradygmaty dowodzenia

Jaki język zrozumie automat?

Wykład 2. Drzewa zbalansowane AVL i 2-3-4

1 Funkcje uniwersalne

Matematyka dyskretna

Korzystając z własności metryki łatwo wykazać, że dla dowolnych x, y, z X zachodzi

Zasada indukcji matematycznej

1 Układy równań liniowych

Nierówność Krafta-McMillana, Kodowanie Huffmana

Rozdział 6. Ciągłość. 6.1 Granica funkcji

Monoidy wolne. alfabetem. słowem długością słowa monoidem wolnym z alfabetem Twierdzenie 1.

Języki, automaty i obliczenia

Wprowadzenie do analizy składniowej. Bartosz Bogacki.

Wykład z równań różnicowych

Języki i operacje na językach. Teoria automatów i języków formalnych. Definicja języka

Grafy (3): drzewa. Wykłady z matematyki dyskretnej dla informatyków i teleinformatyków. UTP Bydgoszcz

Wyrażenia regularne.

3. Macierze i Układy Równań Liniowych

1. Funkcje monotoniczne, wahanie funkcji.

Poprawność semantyczna

Wykład 5. Jan Pustelnik

Macierze. Rozdział Działania na macierzach

2 Rodziny zbiorów. 2.1 Algebry i σ - algebry zbiorów. M. Beśka, Wstęp do teorii miary, rozdz. 2 11

Jak należy się spodziewać, mamy. Zauważmy jednak, że nie zachodzi równość

Problemy Decyzyjne dla Systemów Nieskończonych

Metoda tabel semantycznych. Dedukcja drogi Watsonie, dedukcja... Definicja logicznej konsekwencji. Logika obliczeniowa.

Programowanie w Logice Gramatyki metamorficzne. Przemysław Kobylański na podstawie [CM2003] i [SS1994]

Modele Obliczeń. Wykład 1 - Wprowadzenie. Marcin Szczuka. Instytut Matematyki, Uniwersytet Warszawski

Andrzej Wiśniewski Logika II. Materiały do wykładu dla studentów kognitywistyki

10. Translacja sterowana składnią i YACC

ZŁOŻONOŚĆ OBLICZENIOWA ALGORYTMÓW

KATEDRA INFORMATYKI TECHNICZNEJ. Ćwiczenia laboratoryjne z Logiki Układów Cyfrowych. ćwiczenie 204

Gramatyki grafowe. Dla v V, ϕ(v) etykieta v. Klasa grafów nad Σ - G Σ.

Teoretyczne podstawy informatyki

Zadania do Rozdziału X

System BCD z κ. Adam Slaski na podstawie wykładów, notatek i uwag Pawła Urzyczyna. Semestr letni 2009/10

JAO - Języki, Automaty i Obliczenia - Wykład 2. JAO - Języki, Automaty i Obliczenia - Wykład 2

Krzywa uniwersalna Sierpińskiego

Transkrypt:

1 X-gramatyki, Hierarchia Chomsky ego 1.1 X-gramatyka i język przez nią wyznaczony Symbolem X dalej oznaczamy ustalony niepusty zbiór symboli terminalnych zwanych też tokenami. Definicja 1.1 X-gramatyką nazywamy czwórkę G =< X, V, P, S >, gdzie 1. V jest skończonym zbiorem zmiennych (symboli nieterminalnych) rozłącznym z X; 2. S V jest wyróżnionym symbolem generującym; 3. P (X V ) + (X V ) jest skończonym zbiorem produkcji gramatyki G; fakt (α, β) P zapisywać będziemy następująco α β. Literami alfabetu łacińskiego oznaczać będziemy ciągi symboli terminalnych, a greckiego formy zdaniowe, czyli słowa nad V X. Definicja 1.2 Niech G =< X, V, P, S > będzie gramatyką, a α, β (X V ) dowolnymi formami zdaniowymi. 1. Forma β jest bezpośrednio wyprowadzalna z formy α w gramatyce G: α G β, jeśli dla pewnych form β 1, β 2, γ, δ mamy α = β 1 γβ 2, β = β 1 δβ 2 i γ δ P. 2. Relację α G β pośredniego wyprowadzenia w gramatyce G definiujemy jako zwrotnio-przechodnie domknięcie relacji G. Będziemy stosować oznaczenie α i Gβ, aby zaznaczyć ilość kroków wyprowadzenia (długość wyprowadzenia), czyli ilość użycia produkcji. 3. Wtedy zbiór L(G) = {w X ; S Gw} nazywamu językiem generownym przez gramatykę G. Przykłady 1. język opisany wyrażeniem regularnym (01) jest generowany przez gramatykę G =< {0, 1}, {A}, {A ɛ, A 01A}, A >. Zwykle dużymi literami oznaczać będziemy elementy zbioru V. 1

2. Język {0 i 1 j ; 0 < i < j} jest generowany przez gramatykę o produkcjach S 0A1; A 0A1 1 B1; B 1 1B. 3. Język tych słów, które zawierają tyle samo zer i jedynek jest generowany przez gramatykę o produkcjach S 0J 1Z; J 1S 0JJ 1; Z 0S 1ZZ 0; W ostatnim przykładze należy myśleć, że S generuje słowa z języka, J te słowa, które mają o jedną jedynkę za dużo a Z te, które mają o jedno zero za dużo. Wtedy łatwo wykazać, że każde słowo wyprowadzane z S należy do języka. Trudniej iż każde słowo ma wyprowadzenie. Pierwsze ważne zagadnienie teoretyczne związane jest z klasyfikacją gramatyk. Definicja 1.3 Niech G =< X, V, P, S > będzie dowolną X-gramatyką. 1. G jest typu 1 lub kontekstowa wtw, gdy wszystkie jej produkcje α β spełniają warunek α β. 2. G jest typu 2 lub bezkontekstowa wtw, gdy wszystkie jej produkcje są postaci A β, gdzie A V, β (X V ). 3. G jest typu 3 lub regularna wtw, gdy jest prawostronnie lub lewostronnie liniowa. 4. G jest prawostronnie liniowa wtw, gdy wszystkie jej produkcje są postaci A w lub A wb dla pewnych w X, A, B V. 5. G jest lewostronnie liniowa wtw, gdy wszystkie jej produkcje są postaci A w lub A Bw dla pewnych w X, A, B V. Mówimy, że język jest kontekstowy, bezkontekstowy itp., gdy istnieje gramatyka kontekstowa, bezkontekstowa itp. generująca ten język. Nasuwa się od razu kilka pytań. Widzimy, że gramatyka regularna jest bezkontekstowa. Ale czy języki generowane przez gramatyki regularne to faktycznie języki regularne (czy nazwa wprowadzona w ostatniej definicji jest uprawniona)? Czy języki bezkontekstowe są kontekstowe? NA PYTANIA TE ODPOWIEMY W TYM ROZDZIALE. Wszystkie twierdzenia składają się na hierarchię Chomsky ego. Najogólniej i nie całkiem precyzyjnie wykażemy, że języki typu i+1 są językami typu i. Wykorzystamy w tych rozważaniach pewne proste obserwacje: 2

1. Jeśli G jest gramatyką kontekstową i α Gβ, to α β. 2. Dla dowolnej gramatyki G: α,β,γ (V X) α β αγ βγ; 3. Dla dowolnej gramatyki G: α,β,γ (V X) α β γα γβ; 4. Dla dowolnej gramatyki G: α,β,γ,δ (V X) α β γ δ γα δβ; Najpierw omówimy gramatyki (bez)kontekstowe. Zauważmy, że jedynymi produkcjami gramatyki bezkontekstowej G niedopuszczalnymi w definicji gramatyki kontekstowej są produkcje postaci A ɛ. Definicja 1.4 Niech G będzie bk-gramatyką. Produkcję postaci A ɛ nazywamy ɛ-produkcją. Symbol A V nazywamy zerowalnym, jeśli A Gɛ. Twierdzenie 1.5 Dla każdej bezkontekstowej gramatyki G =< X, V, P, S > istnieje kontekstowa gramatyka G =< X, V, P, S > taka, że L(G)\{ɛ} = L(G ). Dowód Najpierw wyznaczymy wszystkie symbole zerowalne G a następnie konstruujemy nową listę produkcji, na której nie pojawią się ɛ-produkcje. Skonstruowana gramatyka będzie dalej bezkontekstowa! Zbiór Y symboli zerowalne wyznaczymy przez prostą itercję. 1. Y := {A V ; A ɛ P }; 2. Y 1 := {B V ; α Y B α P }; 3. jeśli Y = Y 1 zatrzymaj się, w przeciwnym wypadku dokonaj podstawienia Y := Y Y 1 i powtórz krok 2.; Zbiór produkcji P konstruujemy następująco: dla każdej produkcji A X 1... X n P, X i V X włączamy wszystkie produkcje postaci A α 1... α n α i V X {ɛ}, które spełniają następujące w-ki: 1. Jeśli X i nie jest zerowalne, to X i = α i ; 2. Jeśli X i jest zerowalne, to α i = X i lub α i = ɛ; 3. Nie wszystkie α i są jednocześnie równe ɛ. 3

Pokażemy, że Dowód A V w X A G w w ɛ A Gw A V w X w ɛ A Gw A G w przeprowadzimy stosując indukcję po długości wyprowadzenia. Podstawa indukcji: jeśli A w P (A G w) i w ɛ, to A w P (A G w). Krok indukcyjny: weźmy i > 1. Wtedy wyprowazenie długości i można zinterpretować następująco A X 1... X n i 1 G w. Wtedy w jest konkatenacją słów w 1... w n takich, że X j G w j w co najwyżej i 1 krokach. Jeśli w j = ɛ, to X j jest zerowalne, w przeciwnym wypadku X j G w j. Usuwając z X 1... X n wszystkie symbole zerowalne w tym wyprowadzeniu otrzymujemy produkcję z G. Oczywiście nie wszystkie X j są zerowalne (w ɛ). Wyprowadzenie w G konstruujemy zaczynając od tej produkcji, dalej korzystając z założenia indukcyjnego bierzemy kolejny symbol niezerowalny X j i powtarzamy wyprowadzenie X j G w j w nowym kontekście. Dowód A V w X A G w w ɛ A Gw przeprowadzimy podobnie stosując indukcję po długości wyprowadzenia. Jeśli A G w, to w ɛ i istnieje produkcja A α P taka, że po usunięciu symboli zerowalnych z α otrzymujemy w, więc A Gw. Krok indukcyjny: weźmy i > 1. Wtedy wyprowazenie długości i można zinterpretowąc następująco A X 1... X n i 1 G w. Z definicji istnieje produkcja A α P taka, że po usunięciu symboli zerowalnych otrzymujemy X 1... X n. Zatem A GX 1... X n i słowo w jest konkatenacją w 1... w n taką, że X j G w j w mniej niż i krokach, więc można zastosować założenie indukcyjne. Obecnie wykorzystamy zadanie 1. do udowodnienia Lemat 1.6 Niech G =< X, V, P, S > będzie gramatyką kontekstową, Wtedy język L(G) jest rekurencyjny. Dowód Należy wskazać algorytm, który dla dowolnej X-gramatyki kontekstowej G i w X rozstrzyga, czy w L(G). Ponieważ każda forma α pojawiająca się w wyprowadzeniu w jest nie dłuższa niż w wystarczy sprawdzić, czy istnieje ciąg form takiej długości będący wyprowadzeniem w. Formalnie: 4

konstruujemy digraf, którego wierzchołkami są formy długości niewiększej niż w, krawędź z α do β prowadzimy, gdy α G β i sprawdzamy, czy istnieje droga z S do w. Uwaga 1. Podany algorytm ma wykładniczą złożoność czasową i pamięciową, więc nie ma znaczenia praktycznego. Gdy ograniczymy się do gramatyk bezkontekstowych specjalnej postaci (np. Chomsky ego) lub o specjalnych własnościach (LL(1)) problem staje się prostszy, znane są algorytmy wręcz liniowe dla tego problemu. Ma to duże znaczenie praktyczne. Uwaga 2. Wykorzystując metodę diagonalizacji można skonstruować język rekurencyjny, który nie jest kontekstowy. Nie powinno to być dla nas zaskoczeniem, ponieważ języki generowane przez gramatyki typu 0 to dokładnie języki rekurencyjnie przeliczalne (akceptowane przez maszyny Turinga), a pamiętamy z wykładu z PTO, że nie istnieje efektywne wyliczenie wszyskich funkcji (1-argumentowych) totalnych i obliczalnych (zbiorów rekurencyjnych). 1.2 Charakteryzacja języków skończenie akceptowalnych przy pomocy gramatyk typu 3 Twierdzenie 1.7 Niech L będzie X-językiem skończenie akceptowalnym. Istnieje gramatyka prawostronnie liniowa G, która generuje L. Dowód Załóżmy, że istnieje RS-automat A =< X, Q, F, δ, q 0 > akceptujący L. Wtedy gramatyka G =< X, Q, P, q 0 >, gdzie zbiór produkcji P powstaje przez zamianę instrukcji (p, a, q) δ na produkcję p aq oraz p a, gdy q F, generuje L. Zadanie 1. Wykaż, że dla dowolnej gramatyki prawostronnie liniowej G =< X, V, P, S > istnieje gramatyka (prawostronnie liniowa ) G =< X, Q, P, S > taka, że L(G) = L(G ) i wszystkie produkcje z P są postaci p aq lub p a, gdzie a X {ɛ}. 2. Wykaż, że jeśli język L jest skończenie akceptowalny, to język L R wszystkich słów będących odbiciem zwierciadlanym słów z L również jest skończenie akceptowalny. (Wykorzystaj twierdzenie Myhill a). 5

Twierdzenie 1.8 Dla każdej gramatyki prawostronnie liniowej G, język L(G) jest skończenie akceptowalny. Dowód(szkic) Z zadania wystarczy rozw ażyć gramatykę o produkcjach typu p aq lub p a. Każdą produkcję p aq należy uczynić instrukcją (p, a, q), należy też wprowadzić nowy stan (oprócz elementów zbioru symboli nieterminalnych V) s, który będzie końcowy; wtedy produkcja p a wyznacza instrukcję (p, a, s). Otrzymaliśmy, że języki regularne (w sensie definicji z poprzedniego rozdziału) pokrywają się z językami generowanymi przez gramatyki prawostronnie liniowe, a gramatyki regularne są lewo lub prawostronnie liniowe. Należy jeszcze udowonić: Twierdzenie 1.9 X-język L jest generowany przez gramatykę prawostronnie liniową wtw, gdy jest generowany przez gramatykę lewostronnie liniową. Dowód Niech G =< X, V, P, S > będzie dowolną gramatyką. Niech G R =< X, V, {A w R ; A w P }, S >. Wtedy L(G) R = L(G R ) i G jest prawostronnie liniowa wtw, gdy G R jest lewostronnie liniowa, co wobec domkniętości klasy języków skończenie akceptowalnych na odbicie zwierciadlane (patrz zadanie) kończy dowód. 1.3 Drzewa wyprowadzenia Obecnie ograniczymy się do gramatyk i języków bezkontekstowych. Zdefiniujemy akceptory dla takich języków, czyli automaty ze stosem. Te rozważania teoretyczne są ściśle powiązanie z praktycznym zadaniem przygotowania narzędzi pozwalających dla pewnych gramatyk bezkontekstowych przygotować program (zwany zwykle parserem lub analizatorem składniowym) roztrzygający problem należenia do języka generowanego przez podaną gramatykę. Gramatyki, które będziemy rozważać będą miały dwie ważne własności: 1. Będą jednoznaczne: każde słowo będzie miało co najwyżej jedno drzewo wyprowadzenia w tej gramatyce. 2. Zależnie od narzędzia, które będziemy omawiać, algorytm budowania tego drzewa techniką bottom-up (yacc) lub top-down (antlr) będzie poprawny. 6

Pojęcia drzewa wyprowadzenia i parsingu są również kluczowe w zrozumieniu technologii wykorzystujących XML. W rozdziale tym G =< X, V, P, S > jest ustaloną gramatyką bezkontekstową. Definicja 1.10 Symbolem α l β oznaczymy relację bezpośredniego wyprowadzenia lewostronnego definiowaną następująco: α l β X u P w X γ (X V ) α = wxγ β = wuγ oznacza zwrotnio-przechodnie domknięcie zdefiniowanej rela- Jak zwykle l cji. Intuicyjnie w wyprowadzeniu lewostronnym zawsze stosuje się produkcję do pierwszego z lewej symbolu nieterminalnego. Naszym celem jest dowód twierdzenia: Twierdzenie 1.11 x V w X X G w X l w W tym celu wykorzystamy pojęcie drzewa wyprowadzenia. Niech N oznacza zbiór wszystkich słów nad alfabetem liczb naturalnych. Jeśli v jest takim słowem, to słowo postaci vi nazywamy następnikiem v, o ile i N. Dla I N i v I przez succ(i, v) oznaczymy zbiór wszystkich następników v, które należą do I. Definicja 1.12 Niepusty zbiór T N nazywamy drzewem, o ile: T jest domknięty na prefiksy; dla v T zbiór succ(t, v) jest pusty, albo postaci {v1,..., vk} dla pewnego k N. Wtedy słowo puste nazywamy korzeniem, a te, których zbior następników jest pusty liśćmi. Przy takiej definicji łatwo jest przedstawić drzewo graficznie wypisując następniki każdego wierzchołka alfabetycznie. Wtedy przeglądanie takiego drzewa w głąb odpowiada wypisaniu jego wierzchołków również w porządku alfabetycznym. 7

Definicja 1.13 Niech E będzie niepustym zbiorem )etykiet). Drzewem etykietowanym nazywamy dowolną funkcję t : T E, gdzie T jest drzewem. Teraz łatwo wprowadzić pojęcie poddrzewa i podstawienia: 1. Dla drzewa etykietowanego t : T E i v T definiujemy t.v : T.v E następująco: T.v = {w : vw t}, t.v(w) = t(vw). 2. Dla drzewa t : T E, różnych liści v 1,..., v m i drzew etykietowanych t 1,..., t m definiujemy drzewo s : S E następująco: S = T m i=1 v i T i, s(w) = t(w) dla w T \{v 1,..., v m } i s(v i u) = t i (u) dla u T i. Definicja 1.14 Drzewo d : D X V {ɛ} nazywamy drzewem wyprowadzenia w bk-gramatyce G z symbolu nieterminalnego A, jeśli 1. d(ɛ) = A; 2. w D d(w) X {ɛ} succ(w) = ; 3. jeśli d(w) = B V, to albo w jest liściem, albo następniki w1,..., wk posiadają etykiety a 1,..., a k takie, że B a 1... a k jest produkcją gramatyki G. Wtedy plonem drzewa d nazywamy słowo y(d) powstające z etykiet liści wypisanych w porządku od lewej do prawej. Jełi słowo to nie zawiera symboli nieterminalnych, to drzewo nazywamy maksymalnym. Lemat 1.15 Niec A V oraz α X. Następujące warunki są równoważne: 1. A G α; 2. istnieje drzewo wyprowadzenia d w gramatyce G ze zmiennej A o plonie α. Szkic dowodu (1) (2) Niech A G α 1 G... α k 1 G α będzie wyprowadzeniem. Należy indukcyjnie zbudować drzewa d i, i = 0,... k o plonie α i i korzeniu etykietowanym A. Zaczynamy od drzewa d 0 : {ɛ} {A}. Aby skonstruować drzewo d i+1 należy w drzewie d i odszukać liść odpowiadający pozycji symbolu B V znikającego w i + 1-szym kroku oryginalnego 8

wyprowadzenia. W miejscu tym należy dokonać podstawienia drzewa odpowiadającego użytej w tym kroku produkcji. (2) (1) Należy skonstruować indukcyjnie wyprowadzenie LEWOSTRON- NE z drzewa wyprowadzenia d. Jeśli jest ono zerowej wysokości, to y(d) = A. W przeciwnym wypadku zbiór następników korzenia jest postaci 1,..., k dla pewnego k 1. Słowo d(1)... d(k) jest postaci α 0 Z 1 α 1 Z 2... Z m α m, gdzie Z i V a α j X. Jeśli d nie jest wysokości 0, to y(d) = α 0 y(d 1 )α 1 y(d 2 )... y(d m )α m, gdzie d i jest podrzewem wyznaczonym przez wierzchołek o etykiecie Z i. Z założenia indukcyjnego Z i l y(d i ) i otrzymujemy: A G α 0 Z 1 α 1 Z 2... Z m α m G α 0 y(d 1 )α 1 Z 2... Z m α m G... α 0 y(d 1 )α 1 y(d 2 )... y(d m )α m = y(d). Łatwo zauważyć, że otrzymane wyprowadzenie jest lewostronne. Intuicyjnie odpowiada ono przeglądaniu drzewa d w głąb. 1.4 Algorytmy decyzyjne dla języków bezkontekstowych Przypomnijmy, że zachodzi twierdzenie: Twierdzenie 1.16 Dla każdej bezkontekstowej gramatyki G =< X, V, P, S > istnieje kontekstowa gramatyka G =< X, V, P, S > taka, że L(G)\{ɛ} = L(G ). Dowód Najpierw wyznaczamy wszystkie symbole zerowalne G a następnie konstruujemy nową listę produkcji, na której nie pojawią się ɛ-produkcje. Skonstruowana gramatyka będzie dalej bezkontekstowa! Zbiór Y symboli zerowalne wyznaczymy przez prostą itercję. 1. Y := {A V ; A ɛ P }; 2. Y 1 := {B V ; α Y B α P }; 3. jeśli Y = Y 1 zatrzymaj się, w przeciwnym wypadku dokonaj podstawienia Y := Y Y 1 i powtórz krok 2.; Definicja 1.17 Produkcje postaci A B, A, B V bk-gramatyki G =< X, V, P, S > nazywamy jednostkowymi. Produkcje jednostkowe i ɛ-produkcje są mało interesujące, gdyż ich użycie powoduje, że tracimy kontrolę nad długością wyprowadzenia słowa w bkgramatyce. 9

Lemat 1.18 Dla dowolnej bk-gramatyki G =< X, V, P, S > istnieje bkgramatyka G =< X, V, P, S > bez ɛ-produkcji i produkcji jednostkowych taka, że L(G)\{ɛ} = L(G ). Dowód Z wcześniejszych twierdzeń możemy zakładać, że G nie ma ɛ-produkcji, więc ɛ L(G). Skonstruujemy nowy zbiór produkcji P : 1. Najpierw dolączamy wszystkie produkcje P, które nie są jednostkowe. 2. Dla każdych symboli nieterminalnych A, B takich, że A G B dodajemy wszystkie produkcje postaci A α, gdzie B α jest niejednostkową produkcją z P. Zauważmy, że wobec braku ɛ-produkcji krok drugi można efektywnie wykonać budując digraf, którego wierzchołkami są symbole nieterminalne a krawędziami produkcje jednostkowe i realizując przeglądanie np. w szerz poczynając od A. Niech G =< X, V, P, S >, Ponieważ A α P pociąga A G α otrzymujemy, że L(G ) L(G). Odwrotnie, jeśli w L(G), a ciąg S = α 0 G α 1... G α n = w jest wyprowadzeniem lewostronnym w G, to można z niego usunąć ciągi produkcji jednostkowych otrzymując wyprowadzenie w G. Jeśli α i G α i+1 przy użyciu produkcji niejednostkowej, to α i G α i+1. Jeśli została użyta produkcja jednostkowa, to α i pojawia się w ciągu tego typu wyprowadzeń. Rozważmy najdłuższy ciąg α k... α i... α j k i < j < n form powstających po zastosowaniu ɛ-produkcji. Z definicji P otrzymujemy, że α k G α j+1. Powyższy lemat wykorzystamy w dowodzie Twierdzenie 1.19 (O postaci normalnej Chomsky ego) Dowolny język bezkontekstowy nie zawierający słowa pustego jest generowany przez gramatykę, której wszystkie produkcje są postaci A BC lub A a, gdzie A, B, C są symbolami nietrminalnymi, natomiast a jest symbolem terminalnym. Dowód Możemy założyć, że dana jest bk-gramatyka G =< X, V, P, S > bez ɛ-produkcji i produkcji jednostkowych. Chcemy skonstruować gramatykę G generującą ten sam język. Przypuśćmy, że G ma produkcję postaci A X 1... X n, gdzie n 3 i 10

wszystkie symbole użyte są nieterminalne. Produkcję taką należy wyeliminować. Zamiast niej wprowadźmy nowe symbole nieterminalne Y 1... Y n 2 i produkcje: A X 1 Y 1, Y 1 X 2 Y 2,... Y n 2 X n 1 X n Otrzymana gramatyka H =< X, V {Y 1,..., Y n 2 }, P \{A X 1... X n } {A X 1 Y 1, Y 1 X 2 Y 2,..., Y n 2 X n 1 X n }, S >. Z określenia H mamy, że A H X 1... X n, więc każde wyprowadzenie w G ma odpowiadające wyprowadzenie w H, a to pociąga, że L(G) L(H). Aby uzasadnić inkluzję L(H) L(G) należy zauważyć, że użycie nowej produkcji w wyprowadzeniu prawostronnym A H w słowa w X wymusza użycie wszystkich wprowadzonych produkcji w ustalonej kolejności, co oznacza, że cały taki ciąg wyprowadzeń w H można zredukować do produkcji A X 1... X n w G. Widać, że stworzenie gramatyki G w postaci normalnej Chomsky ego generującej ten sam język co G można podzielić na dwa etapy: 1. W pierwszym należy skonstruować gramatykę I, której wszystkie produkcje są postaci A X 1... X n lub A a, gdzie A, X 1,..., X n są symbolami nietrminalnymi i a X, taką że L(G) = L(I) 2. W drugim usunąc kolejno z I wszystkie produkcje postaci A X 1... X n dla n 3 opisaną powyżej metodą. Otrzymana gramatyka G ma żądane własności. Konstrukcja gramatyki I polega na wprowadzeniu symboli niterminalnych X a ; a X i produkcji X a a i zastąpieniu każdej produkcji A X 1... X n takiej, że n 2 i nie wszyskie symbole X i są nieterminalne produkcją A X 1... X n, gdzie { Xi X X i = i V X i = a dla a X X a Powody, dla których rozważa się gramatyki w postaci normalnej np. Chomsky ego są przynajmniej dwa: 1. Długość wyprowadzenia słowa w takiej gramatyce jest liniowa; 2. Istnieją dla takich gramatyk algorytmy o wielomianowej złożoności obliczeniowej dla problemu w L(G); 11

Lemat 1.20 Niech G =< X, V, P, S > będzie gramatyką w postaci normalnej Chomsky ego. Dla dowolnego słowa w X i symbolu A V każde wyprowadzenie A G jest dokładnie długości 2 w 1. Dowód prowadzi się przez indukcję ze względu na długość słowa. Słowo a długości jeden można wygenerowć tylko, gdy A a jest produkcją G, bo G jest w postaci normalnej Chomsky ego. Z tego samego powodu wyprowadzenie słowa w długości większej od 1 musi rozpocząć się od produkcji A BC, gdzie B u, C v i w = uv. Jasne, że u, v są niepuste. Dalsze kontynuowanie wyprowadzenia w polega na odtworzeniu tych dwóch wyprowadzeń. Przedstawiony algorytm przekształcania gramatyki w postać normalną Chomsky ego powoduje duży wzrost ilości symboli nieterminalnych i produkcji. Lepiej jest stosować go po usunięci z G tzw. symboli bezużytecznych. Definicja 1.21 Symbol A V bk-gramatyki G =< X, V, P, S > nazywamy użytecznym, jeśli istnieje wyprowadzenie S G αaβ G w dla pewnych w X, α, β (X V ). W przeciwnym wypadku symbol nazywamy bezużytecznym. Z definicji usunięcie symboli bezużytecznych z gramatyki (i zawierających je produkcji) nie zmienia języka przez nią generowanego. Zajmiemy się teraz algortymem ich usuwania, gdyż zauważmy, że L(G) jest niepusty wtw, gdy S jest użyteczny. Proces ten rozbijemy na dwa etapy: 1. w pierwszym wyznaczymy te symbole nieterminalne A, dla których istnieje w X takie, że A G w i usuniemy pozostałe; 2. w drugim wyznaczymy te A, dla których S G αaβ dla pewnych form α, β i usuniemy pozostałe. Definicja 1.22 Mówimy, że dwie bk-gramatyki są równoważne, jeśli generują ten sam język. Lemat 1.23 Dla dowolnej bk-gramatyki G =< X, V, P, S > można efektywnie wyznaczyć gramatykę z nią równoważną G =< X, V, P, S >, gdzie V to zbiór tych symboli A V, dla których istnieje w X takie, że A G w. 12

Dowód Zbiór V wyznaczamy przez iterację a następnie do P zaliczamy te produkcje A α P, że α (V X). begin STAREV= ; NOWEV={A V ; A w P dla pewnego w X }; while STAREV NOWEV do begin STAREV := NOWEV; NOWEV := STAREV {A V ; A α P dla pewnego α (X ST AREV ) }; end V := NOWEV; Zauważmy, że język L(G) jest niepusty wtw gdy symbol generujący S należy do V. Wniosek 1.24 Problem, czy dla dowolnej bk-gramatyki G język L(G) jest niepusty jest rozstrzygalny. Zadanie 1. Opracuj algorytm, który dla dowolnej bk-gramatyki G wyznacza i usuwa te symbole nieterminalne A dla których nie istnieje forma zdaniowa postaci αaβ wyprowadzalna w G z symbolu generującego S. 2. Wykaż, że po zastosowaniu obu algorytmów w podanej kolejności otrzymamy gramatykę, której wszystkie symbole są użyteczne (i oczywiście równoważną z oryginalną gramatyką). Twierdzenie 1.25 Istnieje algorytm rozstrzygający czy dany język bezkontekstowy jest skończony czy nieskończony. Dowód Możemy zakładać, że dany język bezkontekstowy jest generowany prze gramatykę G =< X, V, P, S > w postaci normalnej Chomsky ego: język L jest nieskończony wtw, gdy język L\{ɛ} jest nieskończony. Możemy też zakładać, że G nie ma symboli bezużytecznych. Algorytm polega na zbudowaniu digrafu, którego wierzchołkami są symbole nieterminalne V, a krawędzie powstają po przejrzeniu listy produkcji: każda produkcja A BC wyznacza dwie krawędzie (A, B), (A, C). Udowodnimy, że 13

język L(G) jest nieskończony wtw, gdy skonstruowany digraf zawiera cykl. Załóżmy, że graf zawiera cykl A 0, A 1,..., A n, A 0. Wtedy mamy ciąg wyprowadzeń w G : A 0 α 1 A 1 β 1 α 2 A 2 β 2... α n A n β n α n+1 A 0 β n+1 taki, że α i, β i V i α i β i = i. Ponieważ G nie zawiera symboli bezużytecznych istnieją w, v X takie, że α n+1 G w i β n+1 G v. Wtedy wv n + 1 i oba słowa nie są jednocześnie puste. Z tych samych powodów istnieją wyprowadzenia S G ya 0 z, A 0 G x, gdzie x, y, z X. Wtedy S G ya 0 z G ywa 0 vz G yw i A 0 v i z dla każdego i 1. Pozostaje zauważyć, że z niepustości słowa wv wynika, że słowa postaci yw i xv i z są parami różne. Stąd zbiór {yw i xv i z; i N} jest nieskończonym podzbiorem L(G). Załóżmy, że graf nie zawiera cykli. Wykażemy, że L(G) jest skończony. Stopniem wierzchołka A V nazwiemy liczbę r(a) będącą długością najdłuższej ścieżki w grafie o początku A. Pojęcie to jest dobrze określone, bo graf nie zawiera cykli. Oczywiście A BC P pociąga r(b), r(c) < r(a). Pokażemy, że: A V w X A G w w 2 r(a) co zakończy dowód twierdzenia. Zastosujemy oczywiście indukcję ze względu na liczbę r(a), co jest prostym ćwiczeniem. Z dowodu powyższego twierdzenia można wywnioskowąc, że prawdziwy jest następujący lemat o pompowaniu dla języków bezkontekstowych; Lemat 1.26 Niech L będzie językiem bezkontekstowym. Wtedy istnieje stała n 1 taka, że dowolne słowo u L długości większej równej n można zapisać jako konkatenację u = ywxvz takich słów y, w, x, v, z, że: 1. wv 1; 2. wxv n; 3. i N yw i xv i z L. 14

Jedynie własność druga nie wynika bezpośrednio z dowodu twierdzenia! Mając na uwadze fakt, że każdy cykl jest złożeniem cykli prostych nie powinna nas ona dziwić. Można też rozważyć drzewo wyprowadzenia słowa u i rozpatrzyć w nim taką ścieżkę najbliżej liścia, w której dwa różne wierzchołki są etykietowane tym samym symbolem nieterminalnym. Przykład Lemat o pompowaniu wykorzystamy do udowodnienia Twierdzenie 1.27 Zbiór wszystkich X-języków bezkontekstowych dla każdego alfabetu X takiego, że X > 1 nie jest domknięty ani na przekroje ani na dopełnianie. W tym celu rozważmy język L = {a n b n a n ; n 1}, który jest przekrojem języków bezkontekstowych {a n b n a i ; i, n 1} {a i b n a n ; i, n 1}. Pokażemy, że nie jest on bezkontekstowy, więc przekrój języków bezkontekstowych nie musi być bezkontekstowy, co wobec prawa de Morgana A B = (A B ) pociąga, że dopełnienie języka bezkontekstowego nie musi być językiem bezkontekstowym. Do wykazania, że L nie jest bezkontekstowy wykorzystamy lemat o pompowaniu dla bk-języków. Weźmy n 1 i słowo u = a n b n a n. Przypuśćmy, że u = ywxvz i słowa y, w, x, v, z spełniają pierwsze dwa warunki. To pociąga, że wxv jest podsłowem jednego z podsłów a n b n, b n a n. Wtedy usunięcie w, v z u daje słowo, które nie należy do języka: w pierwszym wypadku ilość a, b na początku będzie mniejsza niż ilość a na końcu słowa, a w drugim? 1.5 Algorytm Cocke a, Youngera i Kasamiego (CYK) Postać normalą Chomsky ego gramatyk bezkontekstowych można też wykorzystać, do wykazania, że problem należenia słowa do języka bezkontekstowego należy do klasy P, czyli istnieją algorytmy o wielomianowej złożoności obliczeniowej dla tego problemu. Załóżmy, że dana jest gramatyka G =< X, V, P, S > w postaci normalnej Chomsky ego i słowo x długości n 1. Zdefiniujmy dla i, j takich, że i + j n + 1 zbiór V ij tych symboli nieterminalnych A, które generują podsłowo x ij długości j rozpoczynające się od i-tej pozycji x. Algorytm CYK polega na dynamicznym budowaniu tych zbiorów w oparciu o dwie własności: 1. Dla j = 1 słowo x i1 jest po prostu i tą literą x. Ponieważ gramatyka jest w PNC A G x i1 wtw, gdy A x i1 jest produkcją gramatyki G. 15

2. Jeśli j > 1, to A G x ij wtw, gdy istnieje produkcja A BC gramatyki G i pewne k, 1 k < j takie, że B wyprowadza pierwsze k symboli słowa x ij, a C pozostałe j k symboli. Algorytm CYK Wejście: gramatyka G w PNC i słowo x długości n (1) for i:=1 to n do (2) V i1 := {A; A a P i a jest i-tym symbolem x}; (3) for j:=2 to n do (4) for i:=1 to n-j+1 do begin (5) V ij = ; (6) for k:=1 to j-1 do (7) V ij := V ij {A : A BC P B V ik C V i+k,j k } end Wyjście S V 1n. Nietrudno zauważyć, że (przy ustalonej gramatyce) złożoność tego algorytmu jest rzędu O(n 3 ). Co prawda w podanej postaci wynikiem działania algorytmu CYK nie jest drzewo wyprowadzenia słowa (oczywiście, gdy ono istnieje), ale przeglądając wszystkie zbiory V ij można zbudować wszystkie drzewa wyprowadzenia! Istotą tego algorytmu jest pojęcie pozycji lub stanu w wyprowadzeniu słowa; pozycja [A, i, j] pojawia się w wyprowadzeniu słowa x wtw, gdy A V ij. Podobną metodę zastosował Earle y w swym algorytmie, który był pierwszym o wielomianowej czasowej złożoności obliczeniowej dla probemu parsingu dowolnej gramatyki bezkontekstowej. 1.6 Automaty ze stosem - akceptory dla języków bezkontekstowych Przypomnijmy, że X-automatem nazywamy system A =< X, Σ, Q, F, δ, q 0, # l, # r > gdzie X, Σ, Q są skończonymi i parami rozłącznymi zbiorami symboli, wejściowych, pomocniczych i stanów; 16

F Q jest wyróżnionym zbiorem stanów końcowych; q 0 Q jest wyróżninym stanem początkowym; # l, # r X Σ Q są znacznikami lewego i prawego końca słowa, a δ jest skończonym zbiorem par (apb, xqy), gdzie p, q Q, a, b X Σ {# l, # r, ɛ}, x, y (X Σ {# l, # r, }), zwanych instrukcjami. Definicja 1.28 X-automat A nazywamy automatem ze stosem, jeśli wszystkie jego instrukcje są postaci (apb, xq) lub (# l pb, # l xq) oraz a (X Σ), b X {ε}, x (X Σ). Znów nieistotny jest znacznik # r. Intuicyjny model A opiera się na pomyśle rozdzielenia taśmy na stos (na lewo od głowicy) i wejście (na prawo od głowicy). W konfiguracji #αpβ# słowo α opisuje zawartość stosu (ostatnia litera to wierzch stosu), a β opisuje wejście. Przypomnijmy, że język akceptowany przez A to zbiór L(A) = {x X ; s F y (X Σ) # l q 0 x# r # l ys# r }. Przykład automatu ze stosem dla niepustych palindromów parzystej długości o stanie końcowym s 2 : #s 0 a #as 1 #as 0, a X bs 0 a bas 0 bas 1, a, b X as 1 a s 1, a X #s 1 #s 2 Czy stan s 2 jest potrzebny? W stan ten automat wchodzi przy pustym stosie! Co oznacza opróżnienie stosu i wejścia? oznacza, że słowo na wejściu było palindromem. Jeśli uczynimy s 1 stanem końcowym, to A będze akceptować słowa, których jakiś sufiks jest niepustym palindromem parzystej długości. Oznacza to, że zbiór N(A) = {x X ; s F # l q 0 x# r # l s# r } jest zwykle właściwym podzbiorem L(A). Definicja 1.29 Zbiór N(A) nazywamy językiem akceptowanym przez automat ze stosem A przy pustym stosie. Jeśli w przykładzie s 1 uznamy za stan końcowy, to palindromy będą tymi słowami, które są akceptowane przy pustym stosie. 17

Uwaga! Definicja języka akceptowanego przy pustym stosie stwarza możliwość odrzucenia zbioru stanów końcowych, czym nie będziemy się tutaj zajmować. Twierdzenie 1.30 Dla każdego automatu ze stosem A 1. istnieje automat ze stosem A taki, że N(A) = L(A ); 2. istnieje automat ze stosem A taki, że L(A) = N(A ). Dowód (1)Tak jak w przykładzie dla AZS A =< X, Σ, Q, F, δ, q 0, # l, # r > definiujemy automat A =< X, Σ, Q, F, δ, q 0, # l, # r > tak, że Q = Q {s } gdzie s jest nowym stanem; s jest jedynym stanem końcowym, gdyż δ = δ {{#s #s ; s F }. (2) Niech A =< X, Σ, Q, F, δ, s 0, # >, gdzie Q = Q {s }, F = {s } i δ = δ {as s ; s F, a V Σ} {as s ; a X Σ} {#s s ; s F }. Dowód, że N(A ) = L(A) pozostawiamy jako ćwiczenie. Głównym celem tego podrozdziału jest omówienie twierdzenia Twierdzenie 1.31 Dla każdej gramatyki bezkontekstowej G =< X, V, P, S > istnieje automat ze stosem A taki, że L(G) = N(A). Dowód Niech A =< X, V, {s 0, s}, F, δ, s 0, # > będzie automatem takim, że F = {s}, gdy ɛ L(G) a F = {s 0, s} w przeciwnym wypadku. Zbiór instrukcji δ składa się z następujących grup: 1. #s 0 #Ss; 2. As x R s dla każdej produkcji A x P ; 3. asa s dla każdego a X. Chcemy wykazać, że A jest poszukiwanym automatem. Zauważmy, że wobec definicji instrukcji grupy drugiej anutomat może poprawnie interpretować symbole nieterminalne, które są na wierzchu stosu, czyli pierwsze od lewej w wyprowadzeniu w G. Wykorzystamy więc twierdzenie 1.11 z poprzedniego podrozdziału. 18

Ponieważ słowo puste jest akceptowane przez A przy pustym stosie wtw, gdy jest ono generowane w G ograniczymy się do słów niepustych. Niech x L(G) ma wyprowadzenie lewostronne: S x 1 A 1 y 1 x 1 z 1 y 1 = x 1 x 2 A 2 y 2 x 1 x 2 z 2 y 2 = x 1 x 2 x 3 A 3 y 3... x 1 x 2 x 3... x n A n y n x 1 x 2 x 3... x n x n+1 y n = x gdzie x i, y n X, A i V, z i, y i (x V ). Ciąg ten można wykorzystać do zbudowania następującego łańcucha konfiguracji A #s 0 x# #Ssx# = #Ssx 1... x n+1 y n # #y R 1 A 1 x R 1 sx 1... x n+1 y n # #y R 1 A 1 sx 2... x n+1 y n # #y R 1 z R 1 sx 2... x n+1 y n # = #y R 2 A 2 x R 2 sx 2... x n+1 y n #... #y R n A n x R n sx n x n+1 y n # $y R n A n x n+1 y n # #y R n x R n+1sx n+1 y n # #s# prowadących do zaakceptowania x przy pustym stosie. Niech x N(A) będzie niepustym słowem, a q 0, q 1,..., q n ciągiem konfiguracji prowadzących do zaakceptowania x. Niech q i1,..., q ik będzie podciągiem konfiguracji powstających po zastosowaniu{ instrukcji grupy drugiej (odpowiadających produkcjom G). Niech x y = z x = yz ɛ gdy y nie jest prefiksem x. Wtedy istnieją słowa u 1,..., u k (X V ), x 1,..., x k 1 X takie, że q ij = #u R j s(... (x x 1 ) x 2...) x j 1 # i S Gx 1... x j 1 u j (1) co dowodzimy przez indukcję po j. Z opisu instrukcji wynika, że u k X równe jest (... (x x 1 ) x 2...) x k 1, więc S Gx 1... x k 1 u k = x Na koniec odnotujmy też twierdzenie odwrotne. Twierdzenie 1.32 Niech < X, Σ, Q, F, δ, q 0, # > będzie automatem ze stosem. Wtedy istnieje X-gramatyka bezkontekstowa G taka, że L(G) = N(A). Szkic dowodu Niech G =< X, Σ, P, [#q 0 ] > będzie bk-gramatyką, gdzie: Σ = {[as i, s j ] : a X Σ s i, s j Q} {[#s] : s Q} a produkcje G dzielimy na cztery grupy: 1. [#s] b[a n s, s n ][a n 1 s n, s n 1 ]... [a 1 s 2, s 1 ][#s 1 ] dla każdej instrukcji #sb a 1... a n s i każdego ciągu stanów s 1... s n ; 19

2. [as, s 1 ] b[a n s, s n ][a n 1 s n, s n 1 ]... [a 1 s 2, s 1 ] dla każdej instrukcji asb a 1... a n s i każdego ciągu stanów s 1... s n ; 3. [as, s ] b dla każdej instrukcji asb s ; 4. [#s] ɛ dla każdego s F. Uwagi do definicji: 1. Literę b umieszcza się po prawej, bo usuwanie z wejścia A powinno odpowiadać generowaniu w G. 2. Zawartość stosu musi być wykorzystana przy genarowaniu (4). 3. Produkcje gramatyki są definiowane tak, że symbol [as, s ] wyprowadza słowo x wtw, gdy x powoduje, że A wymazuje a ze stosu w wyniku ciągu ruchów rozpoczynającego się w stanie s i kończącego w stanie s. 1.7 Algorytm Earley a Niech G =< X, V, P, S > będzie bk-gramatyką. Ponumerujmy produkcje G kolejnymi liczbami naturalnymi 1,..., d 1 i przyjmijmy, że kolejna jest postaci D p C p1... C pp dla 1 p d 1. Dodajmy produkcję o numereze 0 : D 0 S, gdzie D 0, to nowe symbole (nieterminalny i terminalny). Definicja 1.33 Stanem (lub pozycją) gramatyki G nazywamy czwórkę (p, j, f, α), gdzie p, j, f N są takie, że 0 p d 1, 0 j p a α X jest słowem długości k. Stan nazywamy końcowym, gdy j = p. Algorytm Earley a polega na wyznaczeniu dla słowa x X długości n zbiorów stanów S i tak, że (p, j, f, α) S i wtw, gdy istnieje wyprowadzenie S x 1... x i γ, które wykorzystuje produkcję p i wiadomo już, że prefiks β prawej strony tej produkcji o długości j generuje podsłowo x od pozycji f. Słowo α pełni rolę pomocniczą: porównanie dalszych liter wejścia z α decyduje o kontynuowaniu (lub nie) obliczeń. Zdefiniujmy dla γ (V N) i ustalonej liczby k H k (γ) = {α X ; α = k β (V N) γ αβ} 20

Algorytm EARLEY Wejście: gramatyka G słowo x długości n i liczba k 0 (1) for i:=1 to k +1 do x n+i := (2) for i:=0 to n +1 do S i := (3) S 0 := S 0 {(0, 0, 0, k )} (4) for i:=0 to n +1 do begin Analizuj wszystkie stany s = (p, j, f, α) S i wykorzystując jedną z operacji (5) Przewidywanie: Jeśli s nie jest końcowy i C pj+1 nie jest terminalny, to dla każdej produkcji q takiej, że D q = C pj+1 i każdej formy β H k (C pj+2... C pp α) dodaj do S i stan (q, 0, i, β). (6) Uzupełnianie: Jeśli s jest końcowy i α = x i+1... x i+k, to dla każdego stanu (q, l, g, β) S f takiego, że C ql+1 = D p dodaj do S i stan (q, l + 1, g, β). (7) Skanowanie: Jeśli s nie jest końcowy, a C pj+1 jest terminalny i równy x i+1, dodaj (p, j + 1, f, α) do S i+1. Wyjście Jeśli S i+1 jest pusty, przerwij analizę odrzucając słowo. Jeśli i = n i S i+1 = {(0, 2, 0, k )}, to zaakceptuj słowo. end Wiemy już, że stosowane w praktyce algorytmy parsingu nie mają tylko na celu ustalenie, czy słowo ma wyprowadzenie (patrz algorytm CYK), ale też zbudowanie pewnego drzewa wyprowadzenia, które pozwala na wykonanie jakiejś akcji czyli nadanie semantyki słowu. Definicja 1.34 Mówimy, że X-gramatyka bezkontekstowa G jest jednoznaczna, gdy każde słowo w X ma co najwyżej jedno drzewo wyprowadzenia w gramatyce G. Język bezkontekstowy L nazywamy jednoznacznym, gdy istnieje jednoznaczna gramatyka bezkontekstowa generująca ten język. Jednoznaczność jest równoważna istnieniu dokładnie jednemu wyprowadzeniu np. lewostronnemu. Pytanie Czy każdy język bezkontekstowy jest jednoznaczny? Okazuje sę, że istnieją języki bezkontekstowe, dla których każda bk-gramatyka je generująca nie jest jednoznaczna. Takim językiem jest np. język {a n b n c m d m ; n, m 1} {a n b m c m d n ; n, m 1} 21

2 LL(k) i LR(k): dwie klasy gramatyk stosowanych w praktyce Na koniec wprowadzimy dwie klasy bk-gramatyk, które są jednozanczne i stanowią teoretyczne podstawy używanych przez nas narzędzi. Najpierw rozszyfrujmy pierwszy skrót LR(k)- Left to Right parsing with a k letters look ahead Dane słowo nad alfabetem terminalnym jest analizowane przez czytanie od lewej do prawej z podglądaniem k liter na przód, w celu wyznaczenia jedynej produkcji, która może być użyta, bez powrotu do wcześniej podjętych decyzji w celu odtworzenia wyprowadzenia prawostronnego. Naszym celem jest określenie gramatyk dla których taki algorytm jest poprawny. Zanim podamy formalną definicję pewne oznaczenie: Niech k N, a α będzie dowolnym słowem: { α α < k k : α = prefiks α długości k α k Definicja 2.1 Niech k 0 a G =< X, V, P, S > będzie bk-gramatyką. G jest LR(k) jeśli nie zawiera produkcji S S, dla wszystkich słów α, α, β, β (X V ), γ, γ X i A, A V warunki: S r αaγ r αβγ S r α A γ r α β γ ( αβ + k) : αβγ = ( αβ + k) : α β γ pociągają α = α, A = A, β = β. Język jest LR(k) gdy istnieje LR(k) gramatyka go generująca. Twierdzenie 2.2 1. Każda LR(k) gramatyka jest jednoznaczna, gdyż każde słowo ma co najwyżej jedno wyprowadzenie prawostronne. 2. Istnieje algorytm rozstrzygający, czy bk-gramatyka jest LR(k). 22

Mając na uwadze drzewo wyprowadzenia definicja ta pociąga bottom-up parsing, czyli budowę drzewa ol liści do korzenia. Top-down parsing polega na próbie generowania słowa z symbolu S wykorzystując wyprowadzenie lewostronne w kierunku left-right. Zauważmy, że już w poprzedniej definicji parsing jest deterministyczny, gdyż w danym kroku istnieje co najwyżej jedna produkcja, która może być zastosowana. Jest to silniejsza własność, niż żądanie jednoznaczności. Definicja 2.3 Niech k 0 a G =< X, V, P, S > będzie bk-gramatyką. G jest LL(k) jeśli dla wszystkich słów β, β, γ, γ (X V ), α, δ, δ X i A V warunki: S l αaγ l αβγ l αδ S l αaγ l αβ γ l αδ k : δ = k : δ pociągają β = β. Język jest LL(k) gdy istnieje LL(k) gramatyka go generująca. Inaczej: dla każdego słowa w L(G) każda produkcja w wyprowadzeniu lewostronnym może być wyznaczona przez analizowanie od lewej do prawej na k symboli za pierwszy od lewej następnik produkcji. Skrót LL(k) oznacza, że parsing polega na czytaniu od lewej do prawej w celu odtworzenia wyprowadzenia lewostronnego z podglądem wejścia na k symboli na przód. Twierdzenie 2.4 1. Każda gramatyka LL(k) jest LR(k). 2. Istnieje algorytm rozstrzygający, czy dana bk-gramatyka jest LL(k). 3. Isnieje algorytm rozsrzygający, czy dwie LL(k) gramatyki są równoważne. Aby dobrze zrozumieć różnice pomiędzy podanymi definicjami rozważmy dwie gramatyki 1. lista : NUMBER lista, NUMBER; 2. lista : NUMBER NUMBER, lista; 23

Obie gramatyki definiują ten sam język regularny: list traktowanych jako skończone ciągi liczb oddzielonych przecinkiem. Pierwsza gramatyka jest lewostronnie liniowa, druga prawostronnie liniowa. Ustalmy k = 1. Wtedy obie gramatyki są LR(1), więc można się nimi posłużyć używając yacca. Jeśli jednak rozważymy drzewa wyprowadzenia dowolnej listy długości przynajmniej trzy zauważymy, że gramatyka pierwsza daje lepszy parser. Gramatyka druga jest odpowiednia dla antlr, o ile k zwiększymy do 2, co więcej w parserach opartych o LL(k) gramatyki lewa rekursja jest zabroniona, więc nie można użyć pierwszej gramatyki. Ostatnie stwierdzenie jest bezpośrednim wnioskiem z definicji gramatyki: lewa rekursja pociąga, że gramatyka nie jest LL(k) dla żadnego k. Na zakończenie należy nadmienić, że yacc poprawnie analizuje gramatyki mniejszej klasy niż LR(1), mianowicie LALR(1); natomiast antlr dysponuje dodatkowymi mechanizmami (predykaty), które pozwalają na modyfikację algorytmu parsingu w celu poszerzenia klasy języków poprawnie analizowanych. 3 Problem odpowiedniości Posta i nierozstrzygalne problemy dla języków bezkontekstowych Klasa jzyków bezkontekstowych jest bardzo ważna w zastosowaniach. Zwykle języki programowania są bezkontekstowe, a analiza danych dla programów w tych językach sprowadza się do parsingu języka bezkonteksowyego. (np. wyrażenia arytmetyczne). Na szczęście mamy do czynienia z językami rekurencyjnymi, dla których należenie do języka rozstrzygane może być w czasie wielomianowym (CYK, Earley), a często i liniowym. Choć klasa bkjęzyków równa jest klasie języków regularnych dla alfabetów jednoliterowych, to problemy równości, inkluzji, niepustości przekroju itp. są dla dowolnych języków bezkontekstowych nierozstrzygalne. Aby to wykazać wykorzystamy problem odpowiedniości Posta, POP: Dane są dwie listy uporządkowane A = w 1,..., w n, B = x 1,..., x n słów nad alfabetem X. Pytamy, czy istnieje ciąg i 1,... i m liczb ze zbioru {1,..., n} taki, że w i1... w im = x i1... x im. 24

Wtedy ciąg i 1,... i m nazywamy rozwiązaniem dla wystąpienia (A, B) POP. Przykład 1. i A B 1 1 111 2 10111 10 3 10 0 Wtedy ciąg 2, 1, 1, 3 jest POP dla podanej listy, gdyż: Przykład 2. 10111 1 1 10 = 10 111 111 0 i A B 1 10 101 2 011 11 Jasne jest, że każde rozwiązanie tego wystąpienia POP musi spełniać warunek i 1 = 1, i 2 = 1: tylko w 1 jest prefiksem x 1, a powstały sufiks to 1: 10 10 = 101 0 i jest błąd na czwartej pozycji. Będziemy też potrzebować zmodyfikowanej wersji POP, ZPOP, w której pytamy tylko o rozwązanie takie, że i 1 = 1 Pokażemy, że gdyby POP był rozstrzygalny, to ZPOP również, wskazując redukcję. Lemat 3.1 Problem ZPOP redukuje się do POP. Dowód Niech A = w 1,..., w n, B = x 1,..., x n oraz, będą literami spoza X. Należy stworzyć parę list (C, D) dla której POP będzie miał rozwiązanie wtw, gdy ZPOP ma rozwiązanie dla (A, B). Niech C = y 0,..., y n+1 i D = z 0,..., z n+1, a y i, i = 1,... n powstaje z w i przez wstawienie po każdej literze, a z i z x i przez wstawienie przed każdą literą oraz y 0 = y 1 z 0 = z 1 y n+1 = z n+1 = Nietrudno zauważyć, że jeśli 1, i 1,... i m jest rozwiązaniem ZPOP dla (A, B), to 0, i 1,... i m, n + 1 jest rozwiązaniem POP dla (C, D). Natomiast rozwiązanie i 1,..., i m POP dla (C, D) musi spełniać i 1 = 0, bo y 0 i z 0 są jedynymi słowani z list o tej samej literze na początku, oraz podobnie i m = n + 1. Wybierając najmniejszą liczbę r taką, że i r = n + 1 otrzumujemy ciąg i 1,..., i r 25

będący rozwiązaniem dla (A, B). W ostatnim twierdzeniu wykorzystamy dwa języki bezkontekstowe stowarzyszone z listą A = w 1,..., w n. Przykład 3. Rozważmy bk-gramatykę, nad alfabetem X {a 1,..., a n }, gdzie a i są nowymi literami, z jednym symbolem nieterminalnym S i o produkcjach S w i a i w i Sa i dla i = 1,..., n Symbolem L A oznaczamy język generowany przez tę gramatykę, zwany językiem listy A. Jest to zbiór wszystkich słów postaci w i1... w im a im... a i1. Ważne jest, że koduje się indeksy elementów listy A, z kórych składa się prefiks w i1... w im. Ponieważ a i są nowymi literami łatwo zbudować deterministyczny automat ze stosem, który rozpoznaje ten język wchodząc w stan akceptujący np. f. Automat M przepisuje litery z X na stos. Gdy natrafi na a i na wejściu powinien usuwać wi R ze stosu, gdy mu się to uda będzie już tylko oczekiwał na wejściu liter ze zbioru {a 1,..., a n } i ponawiał próbę usunięcia odpowiedniego słowa ze stosu. Dokładniej widząc literę a i na wejściu będzie wchodził w stan s i, w którym będzie wykonywał ciąg ε-instrukcji (nie będzie czytał wejścia!) prowadzących do wymazania wi R ze stosu. Jeśli mu się to uda, wróci do stanu, nazwijmy go s, w którym będzie oczekiwał litery ze zbioru {a 1,..., a n }, Jeśli w stanie s stos będzie pusty wykonuje przejście w stan akceptujący f. Przykład 4. Jak wiemy zbiór wszystkich JBK nie jest domknięty na dopełnianie. Ciekawe jest więc pytanie, czy dopełnienie języka listy L A jest bk-językiem. Okazuje się, że tak. Nie jest to zbyt zaskakujące, bo zbiór bkjęzyków rozpoznawanych przez deterministyczne automaty ze stosem jest domknięty na dopełnienia. Dowód tego faktu prześledzimy na przykładzie automatu M dla języka L A. Po pierwsze, niezależnie, czy rozważamy język akceptowany przy pustym stosie, czy nie, musimy pamiętać, że jednym z warunków akceptowania jest przeczytanie całego wejścia. W szczególności podmiana stanów akceptujących przez dopełnienie nie sprawdza się m.in. z tego powodu. W ogólności deterministyczny AZS może wykonywać nieskończone obliczenie na pewnym wejściu. Jak? Wykonując ciąg ε-instrukcji poczynając od symbolu a na stosie, który nie zostanie w tym procesie wymazany i 26

nastąpi powrót do niego (dokłaniej do tego wystąpienia a na stosie??). Automat dla L A nie generuje takich obliczeń: w stanie s i wykonuje instrukcje, które usuwają kolejne litery w i ze stosu, co nie może doprowadzić do takiej sytuacji. Zauważmy jednak, że takie pary (a, q) automatu A, które generują nieskońzone ε=obliczenia można efektywnie wyznaczyć. Aby zbudować automat M dla dopełnienia L A wystarczy zmuśić A do obejrzenia całego wejścia. Wprowadzamy nowy stan d i dla każdego słowa aqb b X {a 1,..., a n }, dla którego A nie wykonuje ε-instrukcji dodajemy instrukcję aqb ad oraz dla symbolu stosu a i wejścia b adb ad. Wtedy zamieniając zbiór stanów końcowych F na sumę {d} i dopełnienia F otrzymujemy automat dla dopełnienia L A. Czas najwtższy na głowne twierdzenie: Twierdzenie 3.2 POP jest nierozstrzygalny. Dowód Pokażemy, że ZPOP jest nierozstrzygaly, a że redukuje się on do POP, ten drugi też musi być nierozstrzygalny. Metoda dowodu: sprowadzenie problemu stopu dla (deterministycznych) maszyn Turinga do zmodyfikowanego problemu Posta. W tym celu dla każdej takiej maszyny M =< X, Q, F, δ, q 0 > i wejścia w wyznaczymy instancję (A, B) zmodyfikowanego problemu Posta, która ma rozwiązanie wtw, gdy M akceptuje w. Będziemy zakładać,że w stanie akceptującym M nie wykonuje żadnych instrukcji. Opis list A, B podzielimy na cztery grupy zakładając, że pierwszą parą jest: Grupa I Dla każdego a X A B # #q 0 w# A B a a # # Grupa II Dla każdego q Q \ F, p Q, a, b, c X A B qa bp jeśli qa brp δ cqa pcb jeśli qa blp δ q# bp# jeśli qb brp δ cq# pcb# jeśli qb blp δ 27

Grupa III Dla każdego q F, a, b X A aqb aq qb B q aq q Grupa IV Dla każdego q F A B q## # Ponieważ interesują nas rozwiązania zaczynające się od jeden ( pary (#, #q 0 w)), drugi wyraz musi odpowiadać jakiejś instrukcji, czyli być parą grupy II. Następnie trzeba użyć pary z grupy I, aby wygenerować pozostałe litery słowa w. W ten sposób otrzymamy parę (#q 0 w#, #q 0 w#α 1 q 1 β 1 #), gdzie α 1 q 1 β 1 jest konfiguracją powstałą po wykonaniu wybranej instrukcji. W ten sposób każde obliczenie będące ciągiem konfiguracji q 0 w, α 1 q 1 β 1,..., α k q 1 β k wyznacza tzw. częściowe rozwiązanie problemu: ciąg indeksów wyznaczający parę słów: (#q 0 w#α 1 q 1 β 1 #... #α k 1 q k 1 β k 1, #q 0 w#α 1 q 1 β 1 #... #α k 1 q k 1 #α k q 1 β k #) Wtedy dla stanu końcowego q k można użyć par grupy III i I, a na koniec pary z grupy czwartej, aby uzyskać rozwiązanie ZPOP. Odwrotnie, rozwiązanie zaczynające się od pierwszej pary musi na drugim miejscu mieć parę z grupy II, potem pary grupy I, więc pewnien prefiks opisuje wykonanie instrukcji i prejście od konfiguracji początkowej, do powstałej po jej wykonaniu. Przchodzenie to musi ustać, bo odpowiada rozwiązaniu ZPOP, ale to jest możliwe tylko, gdy wystąpi stan końcowy, czyli w będzie akceptowane przez M. Wróćmy do języków bezkontekstowych. Twierdzenie 3.3 Niech G 1, G 2 będą dowolnymi bk=gramatykami, a r dowolnym wyrażeniem regularnym. Wtedy następujące problemy są nierozstrzygalne: 1. Czy L(G 1 ) L(G 2 ) =? 2. Czy L(G 1 ) = L(G 2 )? 28

3. Czy L(G 1 ) = L(r)? 4. Czy L(G 1 ) = X? 5. Czy L(G 1 ) L(G 2 )? 6. Czy L(r) L(G 1 )? Dowód Wykorzystamy nierozstrzygalność POP i języki listy L A oraz ich dopełnienia L A, które są bezkontekstowe. Przykładowo: jeśli L(G 1 ) = L A i L(G 2 ) = L A B, to L(G 1 ) L(G 2 ) = wtw, gdy POP dla (A, B) nie ma rozwiązania. Natomiast L A L B również jest językiem bezkontekstowym, a równość L A L B = Z dla odpowiedniego alfabetu Z, też oznacza, że POP dla (A, B) nie ma rozwiązania. 29