Postać normalna Greibach

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

gdzie to dowolny symbol terminalny, to (być może pusty) ciąg symboli nieterminalnych.

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

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 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 gdzie i są symbolami pośrednimi, 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.

KonstrukcjaEdytuj

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   gdzie   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 prawejEdytuj

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

Zastąpienie reguł lewostronnie rekursywnychEdytuj

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   dla którego istnieją reguły lewostronnie rekursywne. Omawiana operacja pozbędzie się jednocześnie wszystkich reguł lewostronnie rekursywnych mających   po lewej stronie. Wprowadzamy nowy symbol nieterminalny, powiedzmy   który nie jest jeszcze elementem danej gramatyki. Z każdej reguły lewostronnie rekursywnej mającej   po lewej stronie powstaną dwie produkcje:

produkcja 1: mająca nowo wprowadzony symbol   po lewej stronie, a po prawej pozostałość reguły rekursywnej bez pierwszego symbolu   za to na samym końcu ten nowo wprowadzony symbol nieterminalny  

produkcja 2: jak produkcja pierwsza, ale bez ostatniego symbolu  

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   dodajemy dodatkowo reguły z nowo wprowadzonym symbolem   na samym końcu. Można zauważyć, że opisana operacja nie zmienia języka generowanego przez gramatykę.

Przykładowo, jeśli dla   mieliśmy w gramatyce reguły

 

to zostaną one zastąpione przez:

  (zgodnie z produkcją 1.).
  (zgodnie z produkcją 2.)

oraz

  (pozostaje bez zmian),
  (z dodanym  ).

Reguły rekursywne   i   zostały usunięte.

Kolejność wykonywania operacjiEdytuj

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   do   natomiast dla   mamy regułę, w której pierwszy symbol po prawej stronie to jeden spośród   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   Nadal jednak może to być   Aby wyeliminować tę możliwość stosujemy drugą operację (zastąpienie reguł lewostronnie rekursywnych). Po jej zastosowaniu wszystkie reguły dla   mają jako pierwszy symbol prawej strony albo symbol terminalny albo symbol nieterminalny o numerze większym niż   możemy więc przejść do poprawiania reguł dla   Zwróćmy uwagę, że nowo wprowadzone symbole   nie pojawią na początku prawej strony żadnej reguły.

W przykładowej gramatyce o formie:

 
 
 

najpierw podstawiamy za   w regule   następnie eliminujemy reguły lewostronnie rekursywne dla   a następnie podstawiamy za   w regule   Gramatyka przyjmie po tym etapie poniższą postać:

 
 
 
 

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ą   idąc poprzez   o coraz mniejszych numerach, a na koniec obsługując wszystkie   Gdy obsługujemy jakąś regułę, to numer pierwszego symbolu po prawej stronie jest większy niż numer lewej strony albo po lewej mamy   a po prawej   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   i   są już w docelowej postaci. Pierwszą regułą, którą powinniśmy obsłużyć, jest   Zastępujemy ją przez

 

Na koniec reguły dla   zastępujemy przez

 

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

Zobacz teżEdytuj

BibliografiaEdytuj

  • 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