Języki, automaty i obliczenia/Wykład 10: Lemat o pompowaniu dla języków bezkontekstowych. Własności języków bezkontekstowych. Problemy rozstrzygalne: Różnice pomiędzy wersjami

Z Studia Informatyczne
Przejdź do nawigacjiPrzejdź do wyszukiwania
Matiunreal (dyskusja | edycje)
m Zastępowanie tekstu – „,...,” na „,\ldots,”
 
(Nie pokazano 91 wersji utworzonych przez 5 użytkowników)
Linia 1: Linia 1:
; Wprowadzenie
Wprowadzimy  i udowodnimy najprostszą wersję lematu o pompowaniu dla języków bezkontekstowych.
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


==1. Lemat o pompowaniu==
==Lemat o pompowaniu==


Istotną cechą języków regularnych jest własność pompowania, którą  ustaliliśmy
Istotną cechą języków regularnych jest własność pompowania, którą  ustaliliśmy
Linia 13: Linia 10:
dostatecznie długiego słowa w gramatyce.
dostatecznie długiego słowa w gramatyce.


{{lemat|1||
{{lemat|1.1||
(o pompowaniu) Dla dowolnego języka bezkontekstowego <math>\displaystyle L \subset A^*</math> istnieją liczby
(o pompowaniu) Dla dowolnego języka bezkontekstowego <math>L \subset A^*</math> istnieją liczby
naturalne <math>\displaystyle N,M \geqslant 1</math> takie, że każde słowo <math>\displaystyle w \in L</math> o długości <math>\displaystyle |w| > N</math> można
naturalne <math>N,M \geqslant 1</math> takie, że każde słowo <math>w \in L</math> o długości <math>|w| > N</math> można
przedstawić w formie <math>\displaystyle w=u_1w_1uw_2u_2</math>, gdzie  <math>\displaystyle w_{1,}w_{2},v_{1},v_{2},u\in A^{*} </math> ,
przedstawić w formie <math>w=u_1w_1uw_2u_2</math>, gdzie  <math>w_{1,}w_{2},v_{1},v_{2},u\in A^{*}</math> oraz
oraz
# <math>|w_1uw_2| \leqslant M</math>
# <math>\displaystyle |w_1uw_2| \leqslant M</math>
# <math>w_1w_2 \neq 1</math>
# <math>\displaystyle w_1w_2 \neq 1</math>
# <math>u_1w_1^iuw_2^iu_2 \in L</math> dla <math>i=0,1,.</math>..  
# <math>\displaystyle u_1w_1^iuw_2^iu_2 \in L</math> dla <math>\displaystyle i=0,1,...</math>   


}}
}}


Zanim przeprowadzimy  dowód lematu zobaczmy jak stosuje się ten lemat do języka  generowanego
Zanim przeprowadzimy  dowód lematu, zobaczmy jak stosuje się ten lemat do języka  generowanego
przez gramatykę <math>\displaystyle (\{v_0,v_1,v_2 \},\{a,b\},v_0,P)</math>, <br>
przez gramatykę <math>(\{v_0,v_1,v_2 \},\{a,b\},v_0,P)</math>, <br>
gdzie <math>\displaystyle P: v_0 \rightarrow v_1v_2, \;v_1 \rightarrow av_2 b  , v_2 \rightarrow b\;|\;v_0b</math><br>
gdzie <math>P: v_0 \rightarrow v_1v_2, \;v_1 \rightarrow av_2 b  , v_2 \rightarrow b\;|\;v_0b</math>.<br>


<font color=red>ANIMACJA ja-lekcja10-w-anim1-opis</font>
[[File:ja-lekcja10-w-anim1.mp4|250x250px|thumb|center|Animacja 1]]


{{dowod|||
{{dowod|||
Załóżmy, bez utraty ogólności rozważań (dlaczego?), że język bezkontekstowy <math>\displaystyle L</math>
Załóżmy, bez utraty ogólności rozważań (dlaczego?), że język bezkontekstowy <math>L</math>
nie zawiera słowa pustego i jest
nie zawiera słowa pustego i jest
generowany  przez gramatykę <math>\displaystyle G=(V_N,V_T,v_0,P)</math>
generowany  przez gramatykę <math>G=(V_N,V_T,v_0,P)</math>
w&nbsp;normalnej postaci Chomsky' ego.
w&nbsp;normalnej postaci Chomsky'ego.
Rozważmy dowolne wyprowadzenie w <math>\displaystyle G</math>
Rozważmy dowolne wyprowadzenie w <math>G</math>
<center><math>\displaystyle w_0 \mapsto w_1 \mapsto ... \mapsto w_r</math></center>
<center><math>w_0 \mapsto w_1 \mapsto ... \mapsto w_r</math></center>


o długości <math>\displaystyle r \geqslant 1</math> i <math>\displaystyle w_0 \in V_N</math>. Niech  najdłuższa ścieżka
o długości <math>r \geqslant 1</math> i <math>w_0 \in V_N</math>. Niech  najdłuższa ścieżka
w drzewie binarnym <math>\displaystyle T</math> tego wyprowadzenia ma długość <math>\displaystyle k</math>
w drzewie binarnym <math>T</math> tego wyprowadzenia ma długość <math>k</math>
(jako długość przyjmujemy tutaj liczbę
(jako długość przyjmujemy tutaj liczbę
wierzchołków, przez które przechodzi ścieżka). Indukcyjne ze względu na  <math>\displaystyle k </math>  łatwo jest
wierzchołków, przez które przechodzi ścieżka). Indukcyjne ze względu na  <math>k</math>  łatwo jest
uzasadnić, że <center><math>\displaystyle |w_r| \leqslant 2^{k-1}.</math></center>
uzasadnić, że <center><math>|w_r| \leqslant 2^{k-1}</math>.</center>
Załóżmy teraz, że zbiór <math>\displaystyle V_N</math> ma <math>\displaystyle p</math> elementów i
Załóżmy teraz, że zbiór <math>V_N</math> ma <math>p</math> elementów i
przyjmijmy <math>\displaystyle N=2^p</math> oraz <math>\displaystyle M=2^{p+1}</math>. Niech <math>\displaystyle w \in L(G)</math> będzie słowem, którego długość jest
przyjmijmy <math>N=2^p</math> oraz <math>M=2^{p+1}</math>. Niech <math>w \in L(G)</math> będzie słowem, którego długość jest
większa od <math>\displaystyle N</math>.
większa od <math>N</math>.
Zatem najdłuższa ścieżka <math>\displaystyle S</math> w drzewie wyprowadzenia <math>\displaystyle T</math> będącego
Zatem najdłuższa ścieżka <math>S</math> w drzewie wyprowadzenia <math>T</math> będącego
wyprowadzeniem słowa <math>\displaystyle w</math> w
wyprowadzeniem słowa <math>w</math> w
gramatyce <math>\displaystyle G</math> ma długość co najmniej <math>\displaystyle p+2</math>. A więc przechodzi przez co najmniej <math>\displaystyle p+2</math>
gramatyce <math>G</math> ma długość co najmniej <math>p+2</math>. A więc przechodzi przez co najmniej <math>p+2</math>
wierzchołków. Stąd, że
wierzchołków. Stąd, że
wierzchołki maksymalne drzewa wyprowadzenia mają etykiety terminalne wnioskujemy,
wierzchołki maksymalne drzewa wyprowadzenia mają etykiety terminalne, wnioskujemy, że w <math>S</math> występują dwa różne wierzchołki <math>s_1, s_2</math> etykietowane przez ten sam symbol nieterminalny <math>v</math>. Przyjmijmy, że wierzchołek <math>s_1</math> jest bliższy wierzchołka początkowego drzewa wyprowadzenia niż <math>s_2</math>. Wierzchołki <math>s_1, s_2</math> można tak dobrać, aby podścieżka ścieżki <math>S</math> o początku w wierzchołku <math>s_1</math> miała długość równą
że w <math>\displaystyle S</math> występują dwa różne
co najwyżej <math>p+2</math>. Zauważmy teraz, że żadna ścieżka poddrzewa <math>T_1</math>, którego wierzchołkiem początkowym jest <math>s_1</math>,
wierzchołki <math>\displaystyle s_1, s_2</math> etykietowane przez ten sam symbol nieterminalny <math>\displaystyle v</math>.
nie ma długości większej niż <math>p+2</math>. Jeśli więc <math>\overline w</math> jest słowem
Przyjmijmy, że wierzchołek <math>\displaystyle s_1</math> jest
określonym przez liście <math>T_1</math>, to
bliższy wierzchołka początkowego drzewa wyprowadzenia niż <math>\displaystyle s_2</math>.
Wierzchołki <math>\displaystyle s_1, s_2</math> można tak dobrać,
aby podścieżka ścieżki <math>\displaystyle S</math> o początku w wierzchołku <math>\displaystyle s_1</math> miała długość równą
co najwyżej <math>\displaystyle p+2</math>.
Zauważmy teraz, że żadna ścieżka poddrzewa
<math>\displaystyle T_1</math>, którego wierzchołkiem początkowym jest <math>\displaystyle s_1</math>,
nie ma długości większej niż <math>\displaystyle p+2</math>. Jeśli więc <math>\displaystyle \overline w</math> jest słowem
określonym przez liście <math>\displaystyle T_1</math>,
to


<math>\mbox{(1)}</math><center><math>\displaystyle
<math>\mbox{(1)}</math>
|\overline{w}|\leqslant 2^{(p+2)-1}=M.
<center><math>
</math></center>
|\overline{w}|\leqslant 2^{(p+2)-1}=M</math></center>


Rozważmy teraz poddrzewo <math>\displaystyle T_2</math> drzewa <math>\displaystyle T</math> o wierzchołku początkowym w <math>\displaystyle s_2</math>
Rozważmy teraz poddrzewo <math>T_2</math> drzewa <math>T</math> o wierzchołku początkowym w <math>s_2</math>
i niech <math>\displaystyle u</math> będzie słowem określonym
i niech <math>u</math> będzie słowem określonym
przez liście <math>\displaystyle T_2</math>. Wtedy <math>\displaystyle \overline w= w_1uw_2</math> dla pewnych <math>\displaystyle w_1, w_2 \in V_T^*</math>.
przez liście <math>T_2</math>. Wtedy <math>\overline w= w_1uw_2</math> dla pewnych <math>w_1, w_2 \in V_T^*</math>.
W połączeniu z nierównością [[##lp1|Uzupelnic lp1|]]
W połączeniu z nierównością <math>\mbox{(1)}</math> uzyskujemy pierwszą własność postulowaną w lemacie. Co więcej, <math>w_1w_2 \neq 1</math>,
uzyskujemy pierwszą własność postulowaną w lemacie. Co więcej, <math>\displaystyle w_1w_2 \neq 1,</math>
ponieważ pierwsza produkcja wyprowadzenia
ponieważ pierwsza produkcja wyprowadzenia
<math>\displaystyle v\mapsto^{*}\overline{w} </math>  jest postaci <math>\displaystyle v \rightarrow v_1v_2</math> dla pewnych
<math>v\mapsto^{*}\overline{w}</math>  jest postaci <math>v \rightarrow v_1v_2</math> dla pewnych
<math>\displaystyle v_{1},\, v_{2}\in V_{N} </math> , a w gramatyce nie
<math>v_{1},\, v_{2}\in V_{N}</math> , a w gramatyce nie
ma produkcji wymazującej. Zatem dla pewnych <math>\displaystyle u_1, u_2 \in V^*_T</math> jest
ma produkcji wymazującej. Zatem dla pewnych <math>u_1, u_2 \in V^*_T</math> jest


<center><math>\displaystyle v_{0}\mapsto^{*}u_{1}vu_{2}\mapsto^{*}u_{1}uu_{2}</math></center>
<center><math>v_{0}\mapsto^{*}u_{1}vu_{2}\mapsto^{*}u_{1}uu_{2}</math></center>


lub <center><math>\displaystyle v_0 \mapsto^* u_1vu_2 \mapsto^* u_1w_1vw_2u_2 \mapsto^* u_1 w_1 uw_2 u_2 = w</math></center>
lub <center><math>v_0 \mapsto^* u_1vu_2 \mapsto^* u_1w_1vw_2u_2 \mapsto^* u_1 w_1 uw_2 u_2 = w</math></center>
lub
lub


<center><math>\displaystyle v_{0}\mapsto^{*}u_{1}vu_{2}\mapsto^{*}u_{1}w_{1}vw_{2}u_{2}\mapsto^{*}u_{1}w^{i}_{1}vw^{i}_{2}u_{2}\mapsto^{*}u_{1}w^{i}_{1}uw^{i}_{2}u_{2}</math></center>
<center><math>v_{0}\mapsto^{*}u_{1}vu_{2}\mapsto^{*}u_{1}w_{1}vw_{2}u_{2}\mapsto^{*}u_{1}w^{i}_{1}vw^{i}_{2}u_{2}\mapsto^{*}u_{1}w^{i}_{1}uw^{i}_{2}u_{2}</math></center>


dla  <math>\displaystyle i=1,2,\ldots   </math>  
dla  <math>i=1,2,\ldots</math>  


W konsekwencji <math>\displaystyle u_1w_1^iuw_2^iu_2 \in L</math> dla dowolnego <math>\displaystyle i=0,1,...</math>. Lemat zatem został
W konsekwencji <math>u_1w_1^iuw_2^iu_2 \in L</math> dla dowolnego <math>i=0,1,.</math>... Lemat zatem został
udowodniony.
udowodniony.


<math>\displaystyle \diamondsuit</math>  }}
}}


Analogicznie jak w przypadku języków regularnych, lemat o pompowaniu dla języków bezkontekstowych
Analogicznie jak w przypadku języków regularnych, lemat o pompowaniu dla języków bezkontekstowych
stosuje się najczęściej do uzasadnienia,
stosuje się najczęściej do uzasadnienia,
że pewne języki nie należą do rodziny  <math>\displaystyle \mathcal{L}_{2} </math> .
że pewne języki nie należą do rodziny  <math>\mathcal{L}_{2}</math>.
Takie właśnie zastosowanie przedstawione jest poniżej, na przykładzie
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ęzyka, o którym pó{z}niej udowodnimy, że jest kontekstowy, czyli należy do rodziny języków  <math>\mathcal{L}_{1}</math>.
języków  <math>\displaystyle \mathcal{L}_{1} </math> .


{{przyklad|1||
{{kotwica|prz.1.1|}}{{przyklad|1.1||
Niech <math>\displaystyle L=\{a^nb^nc^n : n \geqslant 1 \}</math>. Przeprowadzając rozumowanie nie wprost, a więc
Niech <math>L=\{a^nb^nc^n : n \geqslant 1 \}</math>. Przeprowadzając rozumowanie nie wprost, a więc
zakładając  bezkontekstowość
zakładając  bezkontekstowość
tego języka, z lematu o pompowaniu uzyskujemy odpowiednie stałe <math>\displaystyle M, N</math>.
tego języka, z lematu o pompowaniu uzyskujemy odpowiednie stałe <math>M, N</math>.
Niech <math>\displaystyle k > \frac{N}{3}</math> i rozważmy słowo <math>\displaystyle x_1=a^kb^kc^k</math>. Zatem
Niech <math>k > \frac{N}{3}</math> i rozważmy słowo <math>x_1=a^kb^kc^k</math>. Zatem
istnieje rozkład <math>\displaystyle x_1=u_1w_1uw_2u_2</math>, <math>\displaystyle w_1w_2 \neq 1</math> oraz <math>\displaystyle x_i=u_1w_1^iuw_2^iu_2 \in L</math>
istnieje rozkład <math>x_1=u_1w_1uw_2u_2</math>, <math>w_1w_2 \neq 1</math> oraz <math>x_i=u_1w_1^iuw_2^iu_2 \in L</math>
dla <math>\displaystyle i=0,1,...</math> .
dla <math>i=0,1,.</math>..
Z postaci słów języka <math>\displaystyle L</math> oraz z faktu <math>\displaystyle w_1w_2 \neq 1</math> wnioskujemy, że słowa <math>\displaystyle w_1, w_2</math>
Z postaci słów języka <math>L</math> oraz z faktu <math>w_1w_2 \neq 1</math> wnioskujemy, że słowa <math>w_1, w_2</math>
są potęgami
są potęgami
jednej z liter <math>\displaystyle a,b,c</math> oraz że <math>\displaystyle |x_i| \longrightarrow \infty</math> o ile <math>\displaystyle i \longrightarrow \infty</math>.
jednej z liter <math>a,b,c</math> oraz że <math>|x_i| \longrightarrow \infty</math>, o ile <math>i \longrightarrow \infty</math>.
A to wyklucza możliwość
A to wyklucza możliwość
zachowania własności określajacej  język <math>\displaystyle L</math>. Otrzymana sprzeczność prowadzi do wniosku, iż
zachowania własności określającej język <math>L</math>. Otrzymana sprzeczność prowadzi do wniosku, iż
język <math>\displaystyle \{a^nb^nc^n : n \geqslant 1 \}</math> nie jest bezkontekstowy.
język <math>\{a^nb^nc^n : n \geqslant 1 \}</math> nie jest bezkontekstowy.
 
}}


Lemat o pompowaniu wykorzystywany bywa również w dowodach rozstrzygalności pewnych
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
problemów w rodzinie języków rozpoznawalnych. Zagadnieniem tym zajmiemy się w
dalszej części tego wykładu.
dalszej części tego wykładu.
}}


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


Przedstawimy teraz podstawowe własności rodziny języków bezkontekstowych
Przedstawimy teraz podstawowe własności rodziny języków bezkontekstowych
Linia 125: Linia 109:
z&nbsp;problemami jednoznaczności.
z&nbsp;problemami jednoznaczności.


{{twierdzenie|1||
{{kotwica|tw.1|}}{{twierdzenie|2.1||


Rodzina języków bezkontekstowych  <math>\displaystyle \mathcal{L}_{2} </math>  jest zamknięta ze względu
Rodzina języków bezkontekstowych  <math>\mathcal{L}_{2}</math>  jest zamknięta ze względu
na następujące działania:
na następujące działania:
#  sumę mnogościową,
#  sumę mnogościową,
#  katenację i operację iteracji <math>\displaystyle  *</math>
#  katenację i operację iteracji <math>*</math>,
#   przecięcie (iloczyn mnogościowy) z językiem regularnym
# przecięcie (iloczyn mnogościowy) z językiem regularnym,
#  homomorfizm
#  homomorfizm.


}}
}}


{{dowod|||
{{dowod|||
{}


[[##dom:s|Uzupelnic dom:s|]]. Niech <math>\displaystyle G_i = (V^i_N ,V_T,v^i_0,P_i)</math> będą gramatykami bezkontekstowymi,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1. Niech <math>G_i = (V^i_N ,V_T,v^i_0,P_i)</math> będą gramatykami bezkontekstowymi dla <math>i=1,2</math> takimi, że <math>V^1_N \cap V^2_N = \emptyset</math> oraz <math>L_i = L(G_i)</math>. Język <math>L = L_1 \cup L_2</math> jest generowany przez gramatykę bezkontekstową określoną w następujący sposób: <center><math>G= (V^1_N \cup V^2_N \cup \{v_0\},V_T,v_0,P^1 \cup P^2 \cup \{ v_0 \rightarrow v^1_0 , v_0 \rightarrow {v_0}^2 \})</math>.</center>
dla <math>\displaystyle i=1,2</math>, takimi,
że <math>\displaystyle V^1_N \cap V^2_N = \emptyset</math> oraz <math>\displaystyle  L_i = L(G_i)</math>. Język <math>\displaystyle L = L_1 \cup L_2</math> jest
generowany
przez gramatykę bezkontekstową określoną w następujący sposób:
<center><math>\displaystyle G= (V^1_N \cup V^2_N \cup \{v_0\},V_T,v_0,P^1 \cup P^2 \cup \{ v_0 \rightarrow v^1_0 , v_0 \rightarrow {v_0}^2 \}).</math></center>


[[##dom:i|Uzupelnic dom:i|]]. Przy powyższych oznaczeniach, język <math>\displaystyle L = L_1 \cdot L_2</math> jest generowany przez
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;2. Przy powyższych oznaczeniach, język <math>L = L_1 \cdot L_2</math> jest generowany przez gramatykę bezkontekstową: <center><math>G= (V^1_N \cup V^2_N \cup \{ v_0 \},V_T,v_0,P^1 \cup P^2 \cup \{ v_0 \rightarrow v^1_0 v^2_0 \})</math>.</center>
gramatykę bezkontekstową:
Jeśli <math>L = L(G)</math>, dla <math>G = (V_N ,V_T,v_0,P)</math> gramatyki bezkontekstowej, to <math>L^* = L(\overline{G})</math> dla gramatyki <center><math>\overline{G} = ( V_N \cup \{\overline{v}_0 \} , V_T , \overline{v}_0,P \cup \{ \overline{v}_0 \rightarrow 1 , \overline{v}_0 \rightarrow \overline{v}_0 v_0 \}</math>,</center> która jest również gramatyką bezkontekstową.<br>
<center><math>\displaystyle G= (V^1_N \cup V^2_N \cup \{ v_0 \},V_T,v_0,P^1 \cup P^2 \cup \{ v_0 \rightarrow v^1_0 v^2_0 \})</math></center>


Jeśli <math>\displaystyle L = L(G)</math>, dla <math>\displaystyle G = (V_N ,V_T,v_0,P)</math> gramatyki bezkontekstowej, to
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;3. Niech <math>R</math> będzie dowolonym językiem rozpoznawanym przez pewien automat skończenie stanowy  <math>\mathcal{A} =(S,f,s_0,T)</math>. Język ten możemy przedstawić w postaci sumy <math>R=\bigcup_{i=1}^k R_i</math>, w której każdy język <math>R_i</math> jest rozpoznawany przez automat <math>\mathcal{A}</math> , w którym jako stan końcowy przyjmujemy <math>t_i \in T</math>. Rodzina języków bezkontekstowych jest zamknięta ze względu na sumę mnogościową i oczywista jest równość <math>L \cap R= \bigcup _{i=1}^k (L \cap R_i)</math>. Wystarczy zatem udowodnić, że język <math>L \cap R_i</math> jest bezkontekstowy. Załóżmy, że <math>T=\{t \}</math> oraz <math>L</math> jest językiem generowanym przez gramatykę bezkontekstową <math>G = (V_N ,V_T,v_0,P)</math> w normalnej postaci Chomsky'ego. Bez utraty ogólności rozważań można także założyć, że  <math>1\notin L</math>. Konstruujemy gramatykę <center><math>H=(S \times (V_N \cup V_T) \times S,V_T,(s_0,v_0,t),P_H)</math>,</center> dla której <math>P_H</math> zawiera następujące produkcje:
<math>\displaystyle L^* = L(\overline{G}),</math> dla
* <math>(s_1,v_1,s_2) \rightarrow (s_1,v_2,s_3)(s_3,v_3,s_2)</math> dla <math>s_i \in S</math>, <math>v_i \in V_N</math> jeśli <math>v_1\rightarrow v_2v_3 \in P</math>,
gramatyki <center><math>\displaystyle \overline{G} = ( V_N \cup \{\overline{v}_0 \} , V_T , \overline{v}_0,P \cup \{ \overline{v}_0 \rightarrow 1 , \overline{v}_0 \rightarrow \overline{v}_0 v_0 \},</math></center>
* <math>(s_1,v_1,s_2) \rightarrow (s_1,a,s_2)</math> dla <math>s_i \in S</math>, <math>a \in V_T</math> jeśli <math>v_1\rightarrow a \in P</math>,
* <math>(s_1,a,s_2)\rightarrow a</math> dla <math>s_i \in S</math>, <math>a \in V_T</math> jeśli <math>f(s_1,a)=s_2</math>.
Bezpośrednio z konstrukcji wynika, że gramatyka <math>H</math> jest bezkontekstowa. Łatwo również zauważyć, że język generowany przez gramatykę <math>H</math> jest równy <math>L \cap R</math>.


która jest również gramatyką bezkontekstową.
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;4. Niech <math>h: A^* \longrightarrow B^*</math> oznacza dowolny homomorfizm, a <math>L \subset A^*</math> językiem bezkontekstowym generowanym przez gramatykę <math>G = (V_N ,A,v_0,P)</math>. Rozszerzamy homomorfizm <math>h</math> do wolnych monoidów <math>(A \cup V_N)^*</math> i <math>(B \cup V_N)^*</math>, przyjmując, że <math>h</math> na zbiorze  <math>V_N</math> jest równe identyczności. Łatwo zauważyć, że język <math>h(L)</math> jest generowany przez gramatykę bezkontekstową <math>G = (V_N, B, v_0, P_h)</math>, w której <center><math>P_h=\{ v \rightarrow h(w) : v \rightarrow w \in P \}</math>.</center>


[[##dom:h|Uzupelnic dom:h|]]. Niech <math>\displaystyle R</math> będzie dowolonym językiem rozpoznawanym przez pewien automat skończenie
}}
stanowy  <math>\displaystyle \mathcal{A} \displaystyle =(S,f,s_0,T)</math>. Język ten możemy przedstawić w postaci sumy
<math>\displaystyle R=\bigcup_{i=1}^k R_i</math>, w której
każdy język <math>\displaystyle R_i</math> jest rozpoznawany przez automat  <math>\displaystyle \mathcal{A}  </math> , w którym jako stan
końcowy przyjmujemy <math>\displaystyle t_i \in T</math>. Rodzina
języków bezkontekstowych jest zamknięta ze względu na sumę mnogościową i
oczywista jest równość <math>\displaystyle L \cap R= \bigcup _{i=1}^k (L \cap R_i)</math>.
Wystarczy zatem udowodnić, że język <math>\displaystyle L \cap R_i</math> jest
bezkontekstowy. Załóżmy, że <math>\displaystyle T=\{t \}</math> oraz <math>\displaystyle L</math> jest językiem generowanym przez gramatykę
bezkontekstową <math>\displaystyle G = (V_N ,V_T,v_0,P)</math> w normalnej postaci Chomsky' ego.
Bez utraty ogólności rozważań
można także założyć, że  <math>\displaystyle 1\notin L  </math> . Konstruujemy gramatykę
<center><math>\displaystyle H=(S \times (V_N \cup V_T) \times S,V_T,(s_0,v_0,t),P_H),</math></center>
dla której <math>\displaystyle P_H</math>
zawiera następujące produkcje
* <math>\displaystyle (s_1,v_1,s_2) \rightarrow (s_1,v_2,s_3)(s_3,v_3,s_2)</math> dla <math>\displaystyle s_i \in S</math>, <math>\displaystyle v_i \in V_N</math> jeśli <math>\displaystyle v_1\rightarrow v_2v_3 \in P</math>
* <math>\displaystyle (s_1,v_1,s_2) \rightarrow (s_1,a,s_2)</math> dla <math>\displaystyle s_i \in S</math>, <math>\displaystyle a \in V_T</math> jeśli <math>\displaystyle v_1\rightarrow a \in P</math>
* <math>\displaystyle (s_1,a,s_2)\rightarrow a</math> dla <math>\displaystyle s_i \in S</math>, <math>\displaystyle a \in V_T</math> jeśli <math>\displaystyle f(s_1,a)=s_2.</math>
 
Bezpośrednio z konstrukcji wynika, że gramatyka <math>\displaystyle H</math> jest bezkontekstowa.
Łatwo również zauważyć, że język
generowany przez gramatykę <math>\displaystyle H</math> jest równy <math>\displaystyle L \cap R</math>.
 
[[##dom:j|Uzupelnic dom:j|]]. Niech <math>\displaystyle h: A^* \longrightarrow B^*</math> oznacza dowolny homomorfizm, a
<math>\displaystyle L \subset A^*</math> językiem bezkontekstowym
generowanym przez gramatykę <math>\displaystyle G = (V_N ,A,v_0,P)</math>. Rozszerzamy homomorfizm <math>\displaystyle h</math> do wolnych
monoidów
<math>\displaystyle (A \cup V_N)^*</math> i <math>\displaystyle (B \cup V_N)^*</math>, przyjmując, że <math>\displaystyle h</math> na zbiorze  <math>\displaystyle V_N</math> jest równe
identyczności. Łatwo zauważyć, że język <math>\displaystyle h(L)</math> jest generowany przez gramatykę
bezkontekstową <math>\displaystyle G = (V_N, B, v_0, P_h)</math>, w której
<center><math>\displaystyle P_h=\{ v \rightarrow h(w) : v \rightarrow w \in P \}.</math></center>


<math>\displaystyle \diamondsuit</math>  }}
Z równości  <math>L\setminus R=L\cap \overline{R}</math> ,
 
zamkniętości klasy  <math>\mathcal{L}_{3}</math>  ze względu na uzupełnienie
Z równości  <math>\displaystyle L\setminus R=L\cap \overline{R} </math> ,
oraz z punktu 3 udowodnionego powyżej twierdzenia wynika następujący
zamkniętości klasy  <math>\displaystyle \mathcal{L}_{3} </math>  ze względu na uzupełnienie
oraz z punktu [[##dom:h|Uzupelnic dom:h|]] udowodnionego powyżej twierdzenia wynika następujący
wniosek.
wniosek.


{{wniosek|1||
{{wniosek|2.1||
Niech <math>\displaystyle L \subset A^*</math> będzie dowolonym językiem bezkontekstowym, a
Niech <math>L \subset A^*</math> będzie dowolonym językiem bezkontekstowym, a
<math>\displaystyle R \subset A^*</math> regularnym. Wtedy <math>\displaystyle L \setminus R</math> jest
<math>R \subset A^*</math> regularnym. Wtedy <math>L \setminus R</math> jest
językiem bezkontekstowym.
językiem bezkontekstowym.


Linia 205: Linia 152:
języków bezkontekstowych.
języków bezkontekstowych.


{{fakt|1||
{{fakt|2.1||
Rodzina języków bezkontekstowych  <math>\displaystyle \mathcal{L}_{2} </math>  jest zamknięta ze
Rodzina języków bezkontekstowych  <math>\mathcal{L}_{2}</math>  jest zamknięta ze
względu na podstawienie
względu na podstawienie
regularne i przeciwobraz przez homomorfizm.
regularne i przeciwobraz przez homomorfizm.
Linia 217: Linia 164:
bezkontekstowych jest suma mnogościowa.
bezkontekstowych jest suma mnogościowa.


{{twierdzenie|2||
{{twierdzenie|2.2||


Rodzina języków bezkontekstowych  <math>\displaystyle \mathcal{L}_{2} </math>  nie jest zamknięta ze względu na
Rodzina języków bezkontekstowych  <math>\mathcal{L}_{2}</math>  nie jest zamknięta ze względu na:
# iloczyn mnogościowy
# iloczyn mnogościowy,
# uzupełnienie
# uzupełnienie.


}}
}}


{{dowod|||
{{dowod|||
Dla <math>\displaystyle i=1,2 </math> niech <math>\displaystyle G_i = (\{ v_0 , v_1\},\{ a,b,c\},{v_0},P_i)</math> będą gramatykami
Dla <math>i=1,2</math> niech <math>G_i = (\{ v_0 , v_1\},\{ a,b,c\},{v_0},P_i)</math> będą gramatykami
o następujących zbiorach praw:
o następujących zbiorach praw:


<center><math>\displaystyle \begin{array} {l}
<center><math>\begin{array} {l}


P_1 = \{ v_0 \rightarrow v_0 c, \; v_0 \rightarrow v_1 c, \; v_1 \rightarrow ab, \; v_1 \rightarrow a v_1 b \} \\
P_1 = \{ v_0 \rightarrow v_0 c, \; v_0 \rightarrow v_1 c, \; v_1 \rightarrow ab, \; v_1 \rightarrow a v_1 b \}, \\


P_2 = \{ v_0 \rightarrow a v_0 , \; v_0 \rightarrow a v_1 , \; v_1 \rightarrow bc, \; v_1 \rightarrow b v_1 c \}.
P_2 = \{ v_0 \rightarrow a v_0 , \; v_0 \rightarrow a v_1 , \; v_1 \rightarrow bc, \; v_1 \rightarrow b v_1 c \}.


\end{array} </math></center>
\end{array}</math></center>


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


<center><math>\displaystyle L(G_{1})=\left\{ a^{n}b^{n}c^{m}:n,m\geqslant 1\right\} \in \mathcal{L}_{2}</math></center>
<center><math>L(G_{1})=\left\{ a^{n}b^{n}c^{m}:n,m\geqslant 1\right\} \in \mathcal{L}_{2}</math>,</center>


<center><math>\displaystyle L(G_{2})=\left\{ a^{n}b^{m}c^{m}:n,m\geqslant 1\right\} \in \mathcal{L}_{2}.</math></center>
<center><math>L(G_{2})=\left\{ a^{n}b^{m}c^{m}:n,m\geqslant 1\right\} \in \mathcal{L}_{2}</math>.</center>


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


<center><math>\displaystyle L(G_{1})\cap L(G_{2})=\left\{ a^{n}b^{n}c^{n}\, :\, n\geqslant 1\right\} \notin \mathcal{L}_{2}</math></center>
<center><math>L(G_{1})\cap L(G_{2})=\left\{ a^{n}b^{n}c^{n}\, :\, n\geqslant 1\right\} \notin \mathcal{L}_{2}</math></center>


jest językiem istotnie kontekstowym.
jest językiem istotnie kontekstowym.


Z udowodnionej właśnie własności  oraz z praw de'Morgana
Z udowodnionej właśnie własności  oraz z praw de'Morgana
wynika, że rodzina  <math>\displaystyle \mathcal{L}_{2} </math>  nie jest też domknięta ze względu na uzupełnienie.
wynika, że rodzina  <math>\mathcal{L}_{2}</math>  nie jest też domknięta ze względu na uzupełnienie.


<math>\displaystyle \diamondsuit</math>  }}
}}


==3. Jednoznaczność języków bezkontekstowych==
==Jednoznaczność języków bezkontekstowych==


Omówimy teraz, dość ogólnie zresztą, problem występujący w niektórych
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 niepożą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.
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|1||
{{definicja|3.1||
Niech <math>\displaystyle G = (V_N,V_T,v_0,P)</math> będzie gramatyką bezkontekstową.
Niech <math>G = (V_N,V_T,v_0,P)</math> będzie gramatyką bezkontekstową. '''Lewostronnym''' ('''prawostronnym''') '''wyprowadzeniem''' słowa <math>w \in {V_T}^*</math> w gramatyce <math>G</math> nazywamy wyprowadzenie <center><math>v_0 \mapsto w_1 \mapsto \ldots.. \mapsto w_n = w</math></center> takie, że dla każdego <math>i=0,\ldots,n-1, \;\; w_{i+1}</math> jest generowane bezpośrednio z <math>w_i</math> przez zastąpienie pierwszego z lewej (prawej) symbolu nieterminalnego występującego w&nbsp;słowie <math>w_i</math>.
'''Lewostronnym'''
('''prawostronnym''')
'''wyprowadzeniem''' słowa <math>\displaystyle w \in {V_T}^*</math> w gramatyce <math>\displaystyle G</math> nazywamy
wyprowadzenie <center><math>\displaystyle v_0 \mapsto w_1 \mapsto \ldots.. \mapsto w_n = w</math></center>
takie,
że dla każdego <math>\displaystyle  i=0,\ldots,n-1, \;\; w_{i+1} </math> jest
generowane bezpośrednio z <math>\displaystyle w_i</math> przez zastąpienie pierwszego z lewej (prawej)
symbolu nieterminalnego występującego w&nbsp;słowie <math>\displaystyle w_i</math>.


}}
}}


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


<center><math>\displaystyle v_{0}\mapsto_{L}^{*}w,\; v_{0}\mapsto_{P}^{*}w</math></center>
<center><math>v_{0}\mapsto_{L}^{*}w,\; v_{0}\mapsto_{P}^{*}w</math>.</center>


Każde wyprowadzenie słowa w gramatyce bezkontekstowej
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
można tak uporządkować, by sekwencja produkcji
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&nbsp;teorii, jak i zastosowaniach - gramatyki bezkontekstowe jednoznaczne, których definicję podajemy poniżej.
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&nbsp;teorii, jak i zastosowaniach gramatyki bezkontekstowe jednoznaczne,
których definicję podajemy poniżej.


{{definicja|2||
{{definicja|3.2||
Gramatyka bezkontekstowa <math>\displaystyle G</math> jest '''jednoznaczna''',
Gramatyka bezkontekstowa <math>G</math> 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 <math>L</math> nazywamy jednoznacznym, jeśli istnieje jednoznaczna gramatyka bezkontekstowa generująca ten język.
wtedy i&nbsp;tylko wtedy,
gdy każde słowo generowane przez tę gramatykę ma dokładnie jedno wyprowadzenie
lewostronne (prawostronne).
Język bezkontekstowy <math>\displaystyle L</math> nazywamy jednoznacznym, jeśli istnieje
jednoznaczna gramatyka bezkontekstowa generująca
ten język.


}}
}}


Jednoznaczność gramatyki oznacza istnienie
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
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
bezkontekstowych, na przykład dla klasy języków ograniczonych, to znaczy takich
<math>\displaystyle L\subset A^{*} </math> , że  <math>\displaystyle L\subset w_{1}^{*}...w_{n}^{*} </math>  dla pewnych
<math>L\subset A^{*}</math> , że  <math>L\subset w_{1}^{*}...w_{n}^{*}</math>  dla pewnych słów  <math>w_{1},\ldots,w_{n}\in A^{*}</math> .
słów  <math>\displaystyle w_{1},...,w_{n}\in A^{*} </math> .


{{przyklad|1||
{{przyklad|3.1||
Język  <math>\displaystyle \left\{ a^{n}b^{n+m}c^m\, :\, n,m>0\right\}   </math>  
Język  <math>\left\{ a^{n}b^{n+m}c^m\, :\, n,m>0\right\}</math>  
generowany przez gramatykę  <math>\displaystyle G=(V_{N},V_{T},v_{0},P) </math> , gdzie  <math>\displaystyle V_{N}=\{v_{0},v_{1}\} </math> ,
generowany przez gramatykę  <math>G=(V_{N},V_{T},v_{0},P)</math> , gdzie  <math>V_{N}=\{v_{0},v_{1}\}</math> ,
<math>\displaystyle V_{T}=\{a,b,c\} </math>  oraz<br>
<math>V_{T}=\{a,b,c\}</math>  oraz<br>
<math>\displaystyle P= v_{0}\rightarrow v_1 v_2 , \;\; v_1 \rightarrow av_{1}b\;|ab, \;\; v_2 \rightarrow  bv_2c,  \;|bc   </math> <br>
<math>P= v_{0}\rightarrow v_1 v_2 , \;\; v_1 \rightarrow av_{1}b\;|ab, \;\; v_2 \rightarrow  bv_2c,  \;|bc</math> <br>
jest, jak łatwo sprawdzić, językiem jednoznacznym.<br>
jest, jak łatwo sprawdzić, językiem jednoznacznym.<br>


}}
}}


Mówimy, że język  <math>\displaystyle L\in \mathcal{L}_{2} </math>  jest '''niejednoznaczny''',
Mówimy, że język  <math>L\in \mathcal{L}_{2}</math>  jest '''niejednoznaczny''',
jeśli nie jest jednoznaczny, czyli nie istnieje gramatyka jednoznaczna
jeśli nie jest jednoznaczny, czyli nie istnieje gramatyka jednoznaczna generująca ten język. Przykładem języka niejednoznacznego jest
generująca ten język. Przykładem języka niejednoznacznego
jest


<center><math>\displaystyle L=\left\{ a^{n}b^{n}c^{m}d^m\, :\, m,n\geqslant 1\right\} \cup \left\{ a^{n}b^{m}c^{m}d^n\, :\, m,n\geqslant 1\right\}. </math></center>
<center><math>L=\left\{ a^{n}b^{n}c^{m}d^m\, :\, m,n\geqslant 1\right\} \cup \left\{ a^{n}b^{m}c^{m}d^n\, :\, m,n\geqslant 1\right\}</math>.</center>


Uzasadnienie tego faktu jest dosyć żmudne i dlatego zostało tutaj pominięte.
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,
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
że każdy język regularny (ale nie każda gramatyka regularna) jest
jest bowiem gramatyka otrzymana z automatu deterministycznego generującego ten język.
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
Jednoznaczny jest również język bezkontekstowy, który jest iloczynem <math>L\cap R</math> , gdzie  <math>L\in \mathcal{L}_{2}</math>  i jest językiem jednoznacznym, a  <math>R\in \mathcal{L}_{3}</math> . Gramatyka tego języka, skonstruowana w punkcie [[#prz.3|3]] w twierdzeniu [[#tw.1|2.1]] jest jednoznaczna, co wynika stąd, że automat rozpoznający  <math>R</math>  jest deterministyczny.
<math>\displaystyle L\cap R </math> , gdzie  <math>\displaystyle L\in \mathcal{L}_{2} </math>  i jest językiem jednoznacznym,
a  <math>\displaystyle R\in \mathcal{L}_{3} </math> . Gramatyka tego języka, skonstruowana
w punkcie [[##p1|Uzupelnic p1|]] w twierdzeniu [[##tw 2|Uzupelnic tw 2|]] jest jednoznaczna, co wynika stąd, że automat
rozpoznający  <math>\displaystyle R </math>  jest deterministyczny.


==4. Problemy rozstrzygalne algorytmicznie==
==Problemy rozstrzygalne algorytmicznie==


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


{{twierdzenie|1||
{{twierdzenie|4.1||
W rodzinie j{e}zyków bezkontekstowych  <math>\displaystyle \mathcal{L}_{2} </math>  nast{e}puj{a}ce
W rodzinie języków bezkontekstowych  <math>\mathcal{L}_{2}</math>  następujące
problemy s{a} rozstrzygalne:
problemy rozstrzygalne:
# problem niepustości języka, <math>\displaystyle L\neq \emptyset   </math>  
# problem niepustości języka, <math>L\neq \emptyset</math>  
# problem nieskończoności języka,  <math>\displaystyle card\, L=\aleph _{0} </math>  
# problem nieskończoności języka,  <math>card\, L=\aleph _{0}</math>  
# problem należenia słowa <math>\displaystyle w</math> do języka <math>\displaystyle L</math>
# problem należenia słowa <math>w</math> do języka <math>L</math>.


}}
}}


{{dowod|||
{{dowod|||
Aby udowodnić  punkt 1 wykorzystamy następującą równoważność:
Aby udowodnić  punkt 1, wykorzystamy następującą równoważność:
 
<center><math>\displaystyle L\neq \emptyset \; \Longleftrightarrow \; \exists w\in L\, :\, |w|\leqslant N, </math></center>


Uzasadnienie tej równoważności polega
<center><math>L\neq \emptyset \; \Longleftrightarrow \; \exists w\in L\, :\, |w|\leqslant N</math>.</center>


na rozk{}adzie s{}owa <math>\displaystyle w </math>  spe{}niaj{a}cego warunek  <math>\displaystyle N<|w| </math>  
Uzasadnienie tej równoważności polega na rozkładzie słowa <math>w</math>  spełniającego warunek  <math>N<|w|</math> (zgodnie z oznaczeniami i tezą lematu o pompowaniu) i zastąpieniu go słowem
(zgodnie z oznaczeniami i tezą lematu o pompowaniu) i zastąpieniu go s{}owem
<math>u_{1}uu_{2}</math> , które jest istotnie krótsze. Po skończonej ilości takich skracających kroków  dostaniemy słowo należące do języka <math>L</math>  i spełniające warunek  <math>|w|\leqslant N</math> .
<math>\displaystyle u_{1}uu_{2} </math> , 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
<math>\displaystyle L </math>  i spe{}niaj{a}ce
warunek  <math>\displaystyle |w|\leqslant N </math> .


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


<center><math>\displaystyle card\, L=\aleph _{0}\Longleftrightarrow \; \exists w\in L\, :\, N<|w|\leqslant N+M, </math></center>
<center><math>card\, L=\aleph _{0}\Longleftrightarrow \; \exists w\in L\, :\, N<|w|\leqslant N+M</math></center>


gdzie  <math>\displaystyle M,N </math>  są stałymi z lematu o pompowaniu.
gdzie  <math>M,N</math>  są stałymi z lematu o pompowaniu.


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


Implikacja w przeciwną stronę ( <math>\displaystyle \Leftarrow   </math> ) wynika bezpo{s}rednio
Implikacja w przeciwną stronę ( <math>\Leftarrow</math> ) wynika bezpośrednio
z lematu o pompowaniu. Istnieje mianowicie niesko{n}czony zbiór słów w postaci
z lematu o pompowaniu. Istnieje mianowicie nieskończony zbiór słów w postaci


<center><math>\displaystyle u_{1}w_{1}^{i}uw_{2}^{i}u_{2}\in L</math></center>
<center><math>u_{1}w_{1}^{i}uw_{2}^{i}u_{2}\in L</math></center>


dla  <math>\displaystyle i=0,1,2,...</math>  
dla  <math>i=0,1,2,...</math>.


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


<center><math>\displaystyle \diamondsuit</math></center>}}
}}


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


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


Linia 432: Linia 319:


Algorytm CYK działa w oparciu o ideę programowania dynamicznego
Algorytm CYK działa w oparciu o ideę programowania dynamicznego
. Rozważmy słowo <math>\displaystyle w=a_1a_2...a_n</math> oraz gramatykę <math>\displaystyle G</math>.
. Rozważmy słowo <math>w=a_1a_2...a_n</math> oraz gramatykę <math>G</math>.
Niech zbiór <math>\displaystyle V_i^j</math> zawiera wyłącznie te symbole nieterminalne, z których można wywieść
Niech zbiór <math>V_i^j</math> zawiera wyłącznie te symbole nieterminalne, z których można wywieść
słowo <math>\displaystyle a_ia_{i+1}...a_{i+j-1}</math>, czyli
słowo <math>a_ia_{i+1}...a_{i+j-1}</math>, czyli
<center><math>\displaystyle V_i^j=\{v \in V_N: v \Rightarrow^*_G a_i a_{i+1}... a_{i+j-1} \}.</math></center>
<center><math>V_i^j=\{v \in V_N: v \Rightarrow^*_G a_i a_{i+1}... a_{i+j-1} \}</math>.</center>
 
Mamy zatem następującą równoważność: <center><math>\displaystyle w \in L(G) \Leftrightarrow
v_0 \in V_1^n.</math></center>
 
{{algorytm|||
 
{''Cocke-Younger-Kasami'' - sprawdza, czy dane słowo
należy do języka generowanego przez gramatykę bezkontekstową}
 
[1]


Wejście: <math>\displaystyle G=(V_N, V_T, P, v_0)</math>, <math>\displaystyle w \in V_T^*</math> - gramatyka
Mamy zatem następującą równoważność: <center><math>w \in L(G) \Leftrightarrow
bezkontekstowa i słowo <math>\displaystyle w=a_1a_2...a_n</math> o długości <math>\displaystyle n</math>
v_0 \in V_1^n</math>.</center><br>


Wyjście: TAK lub NIE - odpowiedź na pytanie, czy <math>\displaystyle w \in
{{algorytm|''Cocke-Younger-Kasami'' - sprawdza, czy dane słowo
należy do języka generowanego przez gramatykę bezkontekstową||
  1  Wejście: <math>G=(V_N, V_T, P, v_0)</math>, <math>w \in V_T^*</math> - gramatyka bezkontekstowa i słowo<br> <math>w=a_1a_2...a_n</math> o długości <math>n</math>.
  2  Wyjście: TAK lub NIE - odpowiedź na pytanie, czy <math>w \in
L(G)</math>.
L(G)</math>.
 
  3  <math>G \leftarrow</math>''PostaćNormalnaChomsky'ego''<math>(G)</math>;
<math>\displaystyle G \leftarrow </math>''PostaćNormalnaChomsky'ego''<math>\displaystyle (G)</math>;
  4  '''for''' <math>i=1,\ldots,n</math> '''do'''
 
  5    <math>V_i^1 \leftarrow \{v \in V_N: (v \rightarrow a) \in P, a \in V_T\ \wedge\ a_i=a \}</math>;
'''for''' <math>\displaystyle i=1,...,n\displaystyle V_i^1 \leftarrow \{v \in V_N:\ (v \rightarrow a) \in P, a
  6  '''end for'''
\in V_T\ \wedge\ a_i=a \}</math>;
  7  '''for''' <math>j=2,\ldots,n</math> '''do'''
 
  8    '''for''' <math>i=1,\ldots,n-j+1</math> '''do'''
'''end for'''
  9        <math>V_i^j \leftarrow</math>;
 
  10        '''for''' <math>k=1,\ldots,j-1</math> '''do'''
'''for''' <math>\displaystyle j=2,...,n</math>  
  11          <math>V_i^j \leftarrow V_i^j \cup \{v \in V_N: (v \rightarrow wy) \in P,\ w \in V_i^k,\ y \in V_{i+k}^{j-k}\}</math>;
 
  12        '''end for'''
'''for''' <math>\displaystyle i=1,...,n-j+1\displaystyle V_i^j \leftarrow </math>;
  13    '''end for'''
 
  14  '''end for'''
'''for''' <math>\displaystyle k=1,...,j-1\displaystyle V_i^j \leftarrow V_i^j \cup \{v \in V_N:\ (v \rightarrow wy)
  15  '''if''' <math>v_0 \in V_1^n</math>  
\in P,\ w \in V_i^k,\ y \in V_{i+k}^{j-k}\}</math>;
  16    '''return''' '''TAK''', <math>w \in L(G)</math>;
 
  17  '''else'''
'''end for'''
  18    '''return''' '''NIE''', <math>w \not \in L(G)</math>;
 
  19  '''end if'''
'''end for'''
 
'''end for'''
 
'''if''' <math>\displaystyle v_0 \in V_1^n</math>  
 
'''return''' '''TAK''', <math>\displaystyle w \in L(G)</math>;
 
'''else'''
 
'''return''' '''NIE''', <math>\displaystyle w \not \in L(G)</math>;
 
'''end if'''
 
}}
}}


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


{{przyklad|1||
{{przyklad|4.1||
Zbadamy, czy słowo <math>\displaystyle w=bbaaaa</math> należy do języka generowanego
Zbadamy, czy słowo <math>w=bbaaaa</math> należy do języka generowanego
gramatyką:
gramatyką:


<center><math>\displaystyle \aligned \nonumber v & \rightarrow & wx\ |\ yz \\
<center><math>\begin{align}  v & \rightarrow & wx\ |\ yz \\
\nonumber w & \rightarrow & wy\ |\ xx\ |\ a \\
w & \rightarrow & wy\ |\ xx\ |\ a \\
\nonumber x & \rightarrow & wz\ |\ b \\
x & \rightarrow & wz\ |\ b \\
\nonumber y & \rightarrow & xy\ |\ zz\ |\ a \\
y & \rightarrow & xy\ |\ zz\ |\ a \\
\nonumber z & \rightarrow & yy\ |\ b
z & \rightarrow & yy\ |\ b
\endaligned</math></center>
\end{align}</math></center>


gdzie <math>\displaystyle v</math> jest symbolem początkowym.
gdzie <math>v</math> jest symbolem początkowym.
}}
}}


Poniższa animacja ilustruje działanie algorytmu CYK.
Poniższa animacja ilustruje działanie algorytmu CYK.


<font color=red>ANIMACJA ja-lekcja10-w-anim2.jpg. Opis animacji w pliku
[[File:ja-lekcja10-w-anim2.mp4|250x250px|thumb|center|Animacja 2]]
ja-lekcja10-w-anim2-opis.</font>

Aktualna wersja na dzień 21:57, 15 wrz 2023

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

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 1.1

(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 1

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

(1)

|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ą (1) 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 udowodnimy, że jest kontekstowy, czyli należy do rodziny języków 1.

Przykład 1.1

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ślającej 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 2.1

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

     1. 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}).
     2. 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ą.
     3. 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.

     4. 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 3 udowodnionego powyżej twierdzenia wynika następujący wniosek.

Wniosek 2.1

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 2.1

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 2.2

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 niepożą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 3.1

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 3.2

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 3.1

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 3 w twierdzeniu 2.1 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 uzasadnienia rozstrzygalności pewnych problemów. Dla rodziny języków bezkontekstowych mamy następujące twierdzenie.

Twierdzenie 4.1

W rodzinie języków bezkontekstowych 2 następujące problemy są 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ą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ńczonej ilości takich skracających kroków dostaniemy słowo należące do języka L i spełniają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ęzyk L jest nieskończony, wnioskujemy, że istnieją w tym języku słowa dowolnie długie. Niech wL i |w|>N . Jeśli w nie spełnia warunku |w|N+M , to stosujemy lemat o pompowaniu dla i=0 , uzyskując słowo u1uu2 należące do języka i istotnie krótsze od w . Z warunku |w1w2||w1uw2|M (punkt 1 tezy lematu o pompowaniu) wynika, iż różnica długości tych słów nie może być wieksza niż stała M . Zatem po skończonej ilości kroków uzyskujemy słowo należące do języka i spełniające żądany warunek.

Implikacja w przeciwną stronę ( ) wynika bezpośrednio z lematu o pompowaniu. Istnieje mianowicie nieskoń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. 2 Wyjście: TAK lub NIE - odpowiedź na pytanie, czy wL(G). 3 GPostaćNormalnaChomsky'ego(G); 4 for i=1,,n do 5 Vi1{vVN:(va)P,aVT  ai=a}; 6 end for 7 for j=2,,n do 8 for i=1,,nj+1 do 9 Vij; 10 for k=1,,j1 do 11 VijVij{vVN:(vwy)P, wVik, yVi+kjk}; 12 end for 13 end for 14 end for 15 if v0V1n 16 return TAK, wL(G); 17 else 18 return NIE, w∉L(G); 19 end if

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 4.1

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

vwx | yzwwy | xx | axwz | byxy | zz | azyy | b

gdzie v jest symbolem początkowym.

Poniższa animacja ilustruje działanie algorytmu CYK.

Animacja 2