Rogério Reis


Err and err and err again, but less and less and less.

Aula 13

Gramáticas Independentes de Contexto (CFG)

Da mesma forma que estudamos diferentes representações formais para linguagens regulares, autómatos finitos e expressões regulares, para as CFL também vamos usar diferentes forma de representação. Uma outra forma (que iremos mostrar equivalente) de representar CFLs é a das Gramática Independentes de Contexto (CFG).

Definição

Uma gramática independente de contexto é um quadruplo \(\langle V,\Sigma, P, S\rangle,\) em que

  • \(V\) é um conjunto finito chamado de conjunto das variáveis ou conjunto dos símbolos não terminais.

  • \(\Sigma\) é o alfabeto da linguagem ou conjunto dos símbolos terminais, também finito.

  • \(P\) é o conjunto (finito) de produções \[P\subseteq V\times (V\cup\Sigma)^\star;\]

  • \(S\) (\(S\in V\)) é o símbolo inicial (ou de topo) da gramática.

Normalmente agrupam-se as produções com o mesmo símbolo não terminal como primeiro elemento da seguinte forma: em vez de escrever \[\{(U,\alpha_1),(U,\alpha_2),\cdots,(U,\alpha_n)\}\] escrevemos \[U\rightarrow\alpha_1\mid \alpha_2\mid\cdots\mid\alpha_n.\]

Dizemos que \(\alpha U\beta\Rightarrow_G \alpha\gamma\beta\), se em \(G\) existir uma produção \(U\rightarrow\gamma\). Assim, dizemos que \(w\) é aceite pela gramática \(G=\langle V,\Sigma,P,S\rangle\) se \(S\Rightarrow^\star w\). Portanto \[\mathcal{L}(G)=\{w\mid S\Rightarrow^\star w\}.\]

Exemplo

A seguinte gramática reconhece a linguagem \(\{a^nb^n\mid n\in\mathbb{N}\}\): \[\langle \{S\},\{a,b\},\{(S,aSb),(S,\varepsilon)\},S\rangle,\] ou seja \[S\rightarrow aSb\mid \varepsilon.\] Para a palavra \(aaabbb\) temos \[S\Rightarrow aSb\Rightarrow aaSbb\Rightarrow aaaSbbb\Rightarrow aaabbb.\] Portanto \(aaabbb\in \mathcal{L}(G)\).

Exemplo

A seguinte gramática \(G\) reconhece a linguagem \[L_2=\{w\in\{0,1,2\}^\star\mid |w|_0=|w|_1+|w|_2\}:\] \[S\rightarrow 0S1\mid 1S0\mid 0S2\mid 2S0\mid SS\mid \varepsilon.\] Demonstração: Primeiro mostremos que \(\mathcal{L}(G)\subseteq L_2\). Seja \(w\in \{0,1,2\}^\star\) tal que \(S\Rightarrow^\star w\), ou seja, \(\exists n\; S\Rightarrow^n w\). Então podemos mostrar por indução sobre \(n\) que \(w\in L_2\).

Se \(n=1\), então a única produção que pode ter sido usada é \(S\rightarrow\varepsilon\), porque é a única cuja componente direita não contém variáveis, e portanto \(w=\varepsilon\in L_2\).

Suponhamos agora que para todo o inteiro \(k<n\) e \(w\in\{0,1,2\}^\star\), se \(S\Rightarrow^k w\) então \(w\in L_2\). Basta, então, mostrar que se \(S\Rightarrow^n w\) também se tem que \(w\in L_2\).

Se \(S\Rightarrow^n w\) com \(n>1\) então a primeira produção usada não pode ser \(S\rightarrow\varepsilon\), portanto tem que ser uma das outras cinco. Se for uma das primeiras quatro, por exemplo \(S\rightarrow 0S1\), temos \[S\Rightarrow 0S1\Rightarrow ^{n-1}w.\] Portanto \[S\Rightarrow^{n-1}w'.\] Mas então, pela hipótese de indução, \(w'\in L_2\), o que é equivalente a dizer que \(|w'|_0=|w'|_1+|w'|_2\). Mas como \[w = 0w'1,\] isso implica que \[|w|_0=|w'|_0+1=|w'|_1+|w'|_2+1=|w|_1+|w|_2.\] Logo \(w\in L_2\). Para as outras três produções semelhantes a demonstração é exactamente a mesma.

Se a primeira produção usada for \(S\rightarrow SS\), isso significa que \[w=w'w''\text{ com } S\Rightarrow^{m'}w'\land S\Rightarrow^{m''}w''\land m'+m''=n-1.\] Portanto, mais uma vez aplicando a hipótese de indução, temos \[|w'|_0=|w'|_1+|w'|_2\land |w''|_0=|w''|_1+|w''|_2,\] pelo que \[w=w'w''\in L_2.\] Mostremos agora que para qualquer \(w\in L_2\) se tem \(S\Rightarrow^\star w\). Como \(|w|_0=|w|_1+|w|_2\) temos que \(|w|=2n\), para algum natural \(n\). Podemos, então, proceder por indução sobre \(n\).

Se \(n=0\), então \(w=\varepsilon\) e \(S\Rightarrow\varepsilon\). Suponhamos que para todas as palavras \(w\in L_2\) com \(|w|\leq 2n\) se tem \(S\Rightarrow^\star w\). Seja então \(w\in L_2\) com \(|w|=2n\). Há duas hipóteses a considerar. Se \(w\) tem como caracteres extremos de um lado um \(0\) e do outro um caracter diferente, então \[w = 0w'1\text{ (por exemplo)}\] com \(w'\in L_2\) e \(|w'|=2n-2\). Então por hipótese de indução \(S\Rightarrow^\star w'\) e como \(0w'1=w\) temos \(S\Rightarrow0S1\Rightarrow^\star0w'1=w\). Se pelo contrário \(w\) começa e acaba com o caracter \(0\) (a demonstração é idêntica se começa e acaba com um caracter não \(0\)) então consideremos o seguinte. Seja \(w=w_1w_2\cdots w_{2n}\) e consideremos a seguinte função \(f:\{1,\ldots,2n\}\rightarrow \mathbb{N}\), com \(f(k)=2|w_1\cdots w_k|_0-k\). A função \(f\) corresponde à diferença do número dos caracteres \(0\) até à posição \(k\) e do correspondente número de caracteres não \(0\). Como estamos a supor que \(w\) começa e acaba em \(0\), temos \(f(1)=1\). Mas, da mesma forma, como \(w\in L_2\), portanto \(f(2n)=0\), temos que ter \(f(2n-1) = -1\). Portanto em algum ponto intermédio a função deve ter valor nulo. Ou seja \(w\) tem que se poder escrever como concatenação de duas palavras não nulas, \(w'\) e \(w''\), tais que \(w=w'w''\) com \(w',w''\in L_2\). Como \(|w|=|w'|+|w''|\), estas duas palavras têm tamanho menor que \(2n\) pelo que podemos aplicar a hipótese de indução, garantindo que \[S\Rightarrow^\star w'\land S\Rightarrow^\star w''.\]Portanto \[S\Rightarrow SS\Rightarrow^\star w'w''=w.\]

Teorema

As CFL são fechadas para:

  • a união;

  • a concatenação;

  • o fecho de Kleene;

  • a reversão.

Demonstração: Sejam \(L_1=\mathcal{L}(G_1)\) e \(L_2=\mathcal{L}(G_2)\), com \(G_1=\langle V_1,\Sigma,P_1,S_1\rangle\) e \(G_2=\langle V_2,\Sigma,P_2,S_2\rangle\), suponhamos ainda que \(V_1\cap V_2=\emptyset\) e \(S\notin V_1\cup V_2\).

\(L_1\cup L_2=\mathcal{L}(G)\), com \(G=\langle V_1\cup V_2\cup\{S\},\Sigma,P_1\cup P_2\cup\{S\rightarrow S_1\mid S_2\},S\rangle\).

\(L_1L_2=\mathcal{L}(G)\) com \(G=\langle V_1\cup V_2\cup\{S\},\Sigma,P_1\cup P_2\cup\{S\rightarrow S_1S_2\},S\rangle\).

\(L_1^\star=\mathcal{L}(G)\) com \(G=\langle V_1\cup\{S\},\Sigma,P_1\cup\{S\rightarrow S_1S\mid \varepsilon\},S\}\).

Seja \(P^R_1\) o conjunto de produções que se obtêm de \(P_1\) do seguinte modo: se em \(P_1\) constam as produções em \(U\), \(U\rightarrow \alpha_1\mid \alpha_2\mid\cdots\mid\alpha_n\), em \(P^R_1\) passam a constar as produções \(U\rightarrow \alpha^R_1\mid \alpha^R_2\mid\cdots\mid\alpha^R_n\). Então \(L_1^R=\mathcal{L}(G)\) com \(G=\langle V_1,\Sigma,P^R_1,S_1\rangle\). ◻

A classe das linguagens regulares está contida na classe das linguagens independentes de contexto. A escrita de uma CFG (linear à direita) que simule o comportamento de um DFA é muito simples. Um exemplo ilustra bem este método. Consideremos \(L\) a linguagem definida pelo seguinte DFA

image

A gramática que simula este autómato é dada por \[\begin{array}{l} Q\rightarrow 0Q\mid 1S\\ S\rightarrow 0S\mid 1Q\mid \varepsilon. \end{array}\]

Assim se temos um DFA \(\langle Q,\Sigma,\delta,q_0,F\rangle\), construímos uma gramática \(\langle Q,\Sigma,P,q_0\rangle\) em que o conjunto de variáveis é o conjunto de estados do DFA, o símbolo inicial é o estado inicial do autómato e cuja produções, para cada estado são \[q\rightarrow aq',\] se \(\delta(q,a)=q'\). No caso de \(q\in F\) acrescenta-se a produção \[q\rightarrow \varepsilon.\]