Postać normalna Greibach


Postać normalna Greibach w encyklopedii

Z Wikipedii, wolnej encyklopedii Przejdź do nawigacji Przejdź do wyszukiwania

Postać normalna Greibach to postać gramatyki bezkontekstowej, w której wszystkie reguły są postaci:

A a Y 1 . . . Y m , {\displaystyle A\rightarrow aY_{1}...Y_{m},}

gdzie a {\displaystyle a} to dowolny symbol terminalny, Y 1 . . . Y m {\displaystyle Y_{1}...Y_{m}} to (być może pusty) ciąg symboli nieterminalnych.

Specjalny przypadek produkcji gramatyki typu 1 i wyżej stanowi produkcja

S ε {\displaystyle S\rightarrow \varepsilon }

generująca wyraz pusty. Produkcja ta nie jest objęta formalną definicją gramatyki bezkontekstowej, która stwierdza, że prawa strona dowolnej produkcji nie może być krótsza niż lewa strona (monotoniczność), a co w tym konkretnym aspekcie ma miejsce. Produkcja ta jest dopuszczalna pod warunkiem, że symbol startowy S {\displaystyle S} nie występuje po prawej stronie żadnej produkcji danej gramatyki. W postaci normalnej Chomsky’ego, która stanowi podstawę dla postaci normalnej Greibach, produkcja ta zostaje przejęta bez zmian, ponieważ, wychodząc z założenia, że gramatyka nie zawiera symbolu startowego po prawej stronie, produkcja ta nie może zostać użyta w żadnej innej konfiguracji.

Nazwa wywodzi się od Sheili Greibach. W pierwotnym zamyśle w artykule definiującym tę postać normalną z roku 1965 autorka pisze:

Bezkontekstowy generator słów jest w postaci normalnej wtedy i tylko wtedy, gdy jego reguły są w postaci Z a Y 1 . . . Y m , {\displaystyle Z\rightarrow aY_{1}...Y_{m},} gdzie Z {\displaystyle Z} i Y i {\displaystyle Y_{i}} są symbolami pośrednimi, a a {\displaystyle a} jest symbolem końcowym, tak aby jeden symbol wejściowy był przetwarzany w każdym kroku...

skąd wynika, że ten specjalny przypadek produkcji nie jest zawarty w postaci. Niektóre definicje postaci obejmują jednak również i tę produkcję.

Każdą gramatykę bezkontekstową można przedstawić w postaci normalnej Greibach.

Spis treści

Konstrukcja | edytuj kod

Zakładając, że dana gramatyka bezkontekstowa znajduje się już w postaci normalnej Chomsky’ego, pokażemy jak można przetransformować ją do postaci normalnej Greibach. Najpierw, wszystkie symbole nieterminalne danej gramatyki ponumerujmy np. do formy A i , 1 i n , {\displaystyle A_{i}\,,1{\leq }i{\leq }n,} gdzie n {\displaystyle n} to liczba symboli nieterminalnych występujących w danej gramatyce. Postać normalną Greibach można uzyskać za pomocą dwóch operacji stosowanych w odpowiedniej kolejności:

Podstawienie za pierwszy symbol po prawej | edytuj kod

Aby zastosować tę operację, koncentrujemy naszą uwagę na pewnej regule, w której pierwszy symbol po prawej stronie jest symbolem nieterminalnym, nazwijmy go A i . {\displaystyle A_{i}.} Zastąpimy tę regułę wieloma regułami, po jednej dla każdej reguły mającej A i {\displaystyle A_{i}} po lewej stronie: w naszej oryginalnej regule wymieniamy to pierwsze A i {\displaystyle A_{i}} na rezultat zastosowania tej drugiej reguły. Przykładowo, jeśli wszystkie reguły z A 1 {\displaystyle A_{1}} po lewej stronie to A 1 A 2 A 3 {\displaystyle A_{1}\rightarrow A_{2}A_{3}} i A 1 a , {\displaystyle A_{1}\rightarrow a,} to regułę A 2 A 1 A 3 {\displaystyle A_{2}\rightarrow A_{1}A_{3}} możemy zastąpić regułami A 2 A 2 A 3 A 3 {\displaystyle A_{2}\rightarrow A_{2}A_{3}A_{3}} i A 2 a A 3 . {\displaystyle A_{2}\rightarrow aA_{3}.} Zwróćmy uwagę, że taka zamiana nie zmienia języka generowanego przez gramatykę.

Zastąpienie reguł lewostronnie rekursywnych | edytuj kod

Pod określeniem reguły lewostronnie rekursywnej rozumiane są tutaj produkcje, gdzie pierwszy symbol po prawej stronie jest taki sam jak symbol po lewej stronie. Ustalmy symbol nieterminalny A i {\displaystyle A_{i}} dla którego istnieją reguły lewostronnie rekursywne. Omawiana operacja pozbędzie się jednocześnie wszystkich reguł lewostronnie rekursywnych mających A i {\displaystyle A_{i}} po lewej stronie. Wprowadzamy nowy symbol nieterminalny, powiedzmy B i , {\displaystyle B_{i},} który nie jest jeszcze elementem danej gramatyki. Z każdej reguły lewostronnie rekursywnej mającej A i {\displaystyle A_{i}} po lewej stronie powstaną dwie produkcje:

produkcja 1: mająca nowo wprowadzony symbol B i {\displaystyle B_{i}} po lewej stronie, a po prawej pozostałość reguły rekursywnej bez pierwszego symbolu ( A i ) , {\displaystyle (A_{i}),} za to na samym końcu ten nowo wprowadzony symbol nieterminalny B i ; {\displaystyle B_{i};}

produkcja 2: jak produkcja pierwsza, ale bez ostatniego symbolu B i . {\displaystyle B_{i}.}

Reguła rekursywna zostaje przy tym usunięta z gramatyki. Do wszystkich innych (czyli tych, które nie są lewostronnie rekursywne) reguł posiadających po lewej stronie symbol A i {\displaystyle A_{i}} dodajemy dodatkowo reguły z nowo wprowadzonym symbolem B i {\displaystyle B_{i}} na samym końcu. Można zauważyć, że opisana operacja nie zmienia języka generowanego przez gramatykę.

Przykładowo, jeśli dla A 2 {\displaystyle A_{2}} mieliśmy w gramatyce reguły

A 2 A 2 A 3 A 3 | A 2 A 2 | a A 3 , {\displaystyle A_{2}\rightarrow A_{2}A_{3}A_{3}|A_{2}A_{2}|aA_{3},}

to zostaną one zastąpione przez:

B 2 A 3 A 3 B 2 | A 2 B 2 {\displaystyle B_{2}\rightarrow A_{3}A_{3}B_{2}|A_{2}B_{2}} (zgodnie z produkcją 1.). B 2 A 3 A 3 | A 2 {\displaystyle B_{2}\rightarrow A_{3}A_{3}|A_{2}} (zgodnie z produkcją 2.)

oraz

A 2 a A 3 {\displaystyle A_{2}\rightarrow aA_{3}} (pozostaje bez zmian), A 2 a A 3 B 2 {\displaystyle A_{2}\rightarrow aA_{3}B_{2}} (z dodanym B 2 {\displaystyle B_{2}} ).

Reguły rekursywne A 2 A 2 A 3 A 3 {\displaystyle A_{2}\rightarrow A_{2}A_{3}A_{3}} i A 2 A 2 A 2 {\displaystyle A_{2}\rightarrow A_{2}A_{2}} zostały usunięte.

Kolejność wykonywania operacji | edytuj kod

Przekształcanie gramatyki do postaci normalnej Greibach wykonujemy w dwóch etapach. Celem pierwszego etapu jest zapewnienie, że w gramatyce będą wyłącznie reguły, w których pierwszy symbol po prawej stronie jest symbolem nieterminalnym o indeksie wyższym niż indeks lewej strony, bądź jest symbolem terminalnym. Systematycznie przeszukujemy wszystkie reguły gramatyki, zaczynając od tego symbolu nieterminalnego po lewej stronie, który ma najniższy indeks, a kończąc na tym, którego indeks jest najwyższy. Przypuśćmy, że obsłużyliśmy już symbole od A 1 {\displaystyle A_{1}} do A i 1 , {\displaystyle A_{i-1},} natomiast dla A i {\displaystyle A_{i}} mamy regułę, w której pierwszy symbol po prawej stronie to jeden spośród A 1 , , A i 1 , {\displaystyle A_{1},\dots ,A_{i-1},} czyli niezgodnie z naszą docelową postacią. Wówczas w tej regule podstawiamy za pierwszy symbol po prawej stronie (pierwsza operacja powyżej). W wyniku tego dostajemy reguły, w których pierwszy symbol po prawej stronie jest terminalem bądź ma większy numer niż w oryginalnej regule. Powtarzając tę operację możemy zapewnić, że pierwszym symbolem po prawej stronie nie będzie żaden z symboli A 1 , , A i 1 . {\displaystyle A_{1},\dots ,A_{i-1}.} Nadal jednak może to być A i . {\displaystyle A_{i}.} Aby wyeliminować tę możliwość stosujemy drugą operację (zastąpienie reguł lewostronnie rekursywnych). Po jej zastosowaniu wszystkie reguły dla A i {\displaystyle A_{i}} mają jako pierwszy symbol prawej strony albo symbol terminalny albo symbol nieterminalny o numerze większym niż i ; {\displaystyle i;} możemy więc przejść do poprawiania reguł dla A i + 1 . {\displaystyle A_{i+1}.} Zwróćmy uwagę, że nowo wprowadzone symbole B i {\displaystyle B_{i}} nie pojawią na początku prawej strony żadnej reguły.

W przykładowej gramatyce o formie:

A 1 A 2 A 3 | a , {\displaystyle A_{1}\rightarrow A_{2}A_{3}|a,} A 2 A 1 A 3 | A 2 A 2 , {\displaystyle A_{2}\rightarrow A_{1}A_{3}|A_{2}A_{2},} A 3 A 2 A 1 | b . {\displaystyle A_{3}\rightarrow A_{2}A_{1}|b.}

najpierw podstawiamy za A 1 {\displaystyle A_{1}} w regule A 2 A 1 A 3 , {\displaystyle A_{2}\rightarrow A_{1}A_{3},} następnie eliminujemy reguły lewostronnie rekursywne dla A 2 , {\displaystyle A_{2},} a następnie podstawiamy za A 2 {\displaystyle A_{2}} w regule A 3 A 2 A 1 . {\displaystyle A_{3}\rightarrow A_{2}A_{1}.} Gramatyka przyjmie po tym etapie poniższą postać:

B 2 A 3 A 3 B 2 | A 2 B 2 | A 3 A 3 | A 2 , {\displaystyle B_{2}\rightarrow A_{3}A_{3}B_{2}|A_{2}B_{2}|A_{3}A_{3}|A_{2},} A 1 A 2 A 3 | a , {\displaystyle A_{1}\rightarrow A_{2}A_{3}|a,} A 2 a A 3 | a A 3 B 2 , {\displaystyle A_{2}\rightarrow aA_{3}|aA_{3}B_{2},} A 3 a A 3 A 1 | a A 3 B 2 A 1 | b . {\displaystyle A_{3}\rightarrow aA_{3}A_{1}|aA_{3}B_{2}A_{1}|b.}

W drugim etapie systematycznie zastępujemy wszystkie reguły zaczynające się po prawej stronie symbolem nieterminalnym. Zaczynamy przy tym od produkcji, które po lewej mają A n , {\displaystyle A_{n},} idąc poprzez A i {\displaystyle A_{i}} o coraz mniejszych numerach, a na koniec obsługując wszystkie B i . {\displaystyle B_{i}.} Gdy obsługujemy jakąś regułę, to numer pierwszego symbolu po prawej stronie jest większy niż numer lewej strony albo po lewej mamy B i , {\displaystyle B_{i},} a po prawej A i ) , {\displaystyle A_{i}),} czyli wszystkie reguły dla pierwszego symbolu po prawej stronie zostały już przetworzone i ich prawe strony zaczynają się od symbolu terminalnego. Zatem jednokrotne zastosowanie operacji podstawienia za pierwszy symbol po prawej stronie spowoduje, że dostaniemy wyłącznie reguły, których prawa strona zaczyna się od symbolu terminalnego. Po obsłużeniu w ten sposób wszystkich reguł dostajemy gramatykę w postaci normalnej Greibach.

W naszej przykładowej gramatyce reguły dla A 2 {\displaystyle A_{2}} i A 3 {\displaystyle A_{3}} są już w docelowej postaci. Pierwszą regułą, którą powinniśmy obsłużyć, jest A 1 A 2 A 3 . {\displaystyle A_{1}\rightarrow A_{2}A_{3}.} Zastępujemy ją przez

A 1 a A 3 A 3 | a A 3 B 2 A 3 | a . {\displaystyle A_{1}\rightarrow aA_{3}A_{3}|aA_{3}B_{2}A_{3}|a.}

Na koniec reguły dla B 2 {\displaystyle B_{2}} zastępujemy przez

B 2 a A 3 A 1 A 3 B 2 | a A 3 B 2 A 1 A 3 B 2 | b A 3 B 2 | a A 3 B 2 | a A 3 B 2 B 2 | a A 3 A 1 A 3 | a A 3 B 2 A 1 A 3 | b A 3 | a A 3 | a A 3 B 2 . {\displaystyle B_{2}\rightarrow aA_{3}A_{1}A_{3}B_{2}|aA_{3}B_{2}A_{1}A_{3}B_{2}|bA_{3}B_{2}|aA_{3}B_{2}|aA_{3}B_{2}B_{2}|aA_{3}A_{1}A_{3}|aA_{3}B_{2}A_{1}A_{3}|bA_{3}|aA_{3}|aA_{3}B_{2}.}

Gramatyka znajduje się w całości w postaci normalnej Greibach.

Zobacz też | edytuj kod

Bibliografia | edytuj kod

  • Sheila A. Greibach, A New Normal-Form Theorem for Context-Free Phrase Structure Grammars, Journal of the Association for Computing Machinery, 1965, Vol. 12, No.1, strony 42-52
  • Uwe Schöning, Theoretische Informatik – kurzgefasst, Spektrum Akademischer Verlag, 1994, ​ISBN 3-8274-1099-1​, strony 54-57
Na podstawie artykułu: "Postać normalna Greibach" pochodzącego z Wikipedii
OryginałEdytujHistoria i autorzy