# Grammatiche: equivalenze, forme normali e trasformazioni

Introduciamo in questa lezione altri concetti delle grammatiche che ci aiutano a definire i linguaggi formali.

## Equivalenza di due grammatiche

Dividiamo l'equivalenza di due grammatiche in due tipi: equivalenza forte (detta anche equivalenza strutturale) e equivalenza debole.
    Due grammatiche $G$ e $G'$ sono debolmente equivalenti se generano lo stesso linguaggio $L(G)=L(G')$.
Si noti che con questa definizione le due grammatiche possono generare una stessa stringa attraverso due differenti alberi di derivazione. L'albero di derivazione utilizzato si dice assegnato a una stringa.
    Due grammatiche $G$ e $G'$ sono fortemente o strutturalmente equivalenti se sono debolmente equivalenti e gli alberi di derivazione condensati sono uguali.
Quindi alla luce delle definizioni, se una grammatica è fortemente equivalente è anche debolmente equivalente, ma non viceversa. Stabilire se due grammatiche sono debolmente equivalenti è un problema indecidibile, viceversa stabilire se due grammatiche sono fortemente equivalenti è un problema decidibile.

### Esempio

Vedi la pagina degli esercizi.

## Grammatiche in forma normale

Le forme normali sono regole che permettono di modificare una grammatica senza però variarne il linguaggio generato. Queste forme sono molto usate in teoria per semplificare dimostrazioni di teoremi. Tuttavia nella pratica non sono molto usate, perché introducono una forma prolissa e poco leggibile. L'importanza di queste forme sarà più chiara nelle prossime lezioni.
Nella prossima sezione vedremo come avvengono le trasformazioni, qui ci limitiamo a elencare le forme normali:
* grammatica senza termini annullabili: una grammatica che non presenta in nessuna regola (ad eccezione dell'assioma) un termine annullabile, ovvero non presenta $\epsilon$ nella sua definizione.
* grammatica non ricorsiva a sinistra: come dice il nome, è una grammatica che non presenta regole ricorsive a sinistra; le regole ricorsive si presenteranno tutte nella forma a destra $A\ \to \ \phi \ A\ |\ ...$
* grammatica in forma di Chmosky o binaria: le regole della grammatica si presentano solo in due forme:
** omogenea binaria: $A\ \to \ BC,\ \ \ B,C\in V$
** terminale con singleton a destra: $A\ \to \ a\in \Sigma$
* grammatica in forma real-time: ogni regola inizia con un terminale, cioè ogni regola è nella forma $A\ \to \ a\ \alpha$ con $a\in \Sigma ,\ \ \ \alpha \in \{\Sigma \cup V\}^{*}$
* grammatica in forma di Greibach: ogni regola inizia con un terminale seguito da uno o più non terminali, cioè ogni regola è nella forma $A\ \to \ a\ \alpha$ con $a\in \Sigma ,\ \ \ \alpha \in V^{*}$
Attraverso la forma di Chmosky, nell'albero di sintassi un nodo può avere come figli (di primo grado) solo due non terminali o un terminale.

## Trasformazioni di grammatiche

Definiamo inizialmente alcune operazioni che poi utilizzeremo per portare le grammatiche in forma normale.

### Espansione di un non terminale

Come dice il titolo, un'operazione molto semplice consiste nel sostituire ovvero espandere un nonterminale:
    $A\ \to \ \alpha B\gamma$
    $B\ \to \ \beta _{1}\ |\ \beta _{2}\ |\ \beta _{3}\ |\ ...$
Diventa:
    $A\ \to \ \alpha \beta _{1}\gamma \ |\ \alpha \beta _{2}\gamma \ |\ \alpha \beta _{3}\gamma \ |\ ...$
    $B\ \to \ \beta _{1}\ |\ \beta _{2}\ |\ \beta _{3}\ |\ ...$

### Eliminazione dell'assioma nella parte destra

Senza perdere di generalità è possibili eliminare tutti gli assiomi che compaiono nella parte destra di ogni regola semplicemente introducendo un nonterminale:
    $S_{0}\ \to \ S$
e poi sostituirlo a tutte le occorrenze dell'assioma.

### Costruzione della forma normale senza nonterminali annullabili

L'algoritmo per riportare una grammatica in forma normale senza nonterminali annullabili è rappresentato dai seguenti 4 passi:
* Calcolare l'insieme $null$ che rappresenta un sottoinsieme di $V$ (non terminabili), con la proprietà di essere annullabili;
* Per ogni regola $r\in P$ aggiungere un'alternativa ottenuta eliminando nella parte destra tutti i nonterminali annullabili;
* Rimuovere tutte le regole vuote nella forma $A\to \epsilon$ ad eccezione dell'assioma;
* Pulire la grammatica e rimuovere qualsiasi circolarità.
Esempio: Grammatica di partenza:
    $S\to SAB\ |\ AC$
    $A\to aA\ |\varepsilon$
    $B\to bB\ |\varepsilon$
    $C\to cCc\ |\ c$
Grammatica in forma normale:
    $S\to SAB\ |\ AC\ |\ SA\ |\ SB\ |\ C$
    $A\to aA\ |\ a$
    $B\to bB\ |\ b$
    $C\to cCc\ |\ c$

### Copia ed eliminazione di regole

Definiamo un insieme $Copy(A)\subseteq V$ come l'insieme dei non terminali in cui il non terminale $A$ può essere copiato, eventualmente transitivamente:
    $Copy(A):=\{B\in V\ |\ \exists {\text{ a derivation }}A{\overset {*}{\Rightarrow }}B\}$
La computazione di questo insieme può essere eseguita come:
    $A\in Copy(A)$
    $C\in Copy(A){\text{ if }}(B\in Copy(A))\land (B\to C\ \in P)$

### Forma normale di Chomsky

Si procede come segue:
* Se la stringa vuota appartiene al linguaggio si aggiunge $S\to \varepsilon$ all'insieme delle regole;
* Per ogni regola del tipo $A_{0}\to A_{1}A_{2}A_{3}...A_{n}$:
** si aggiunga una regola del tipo $A_{0}\to <A_{1}><A_{2}A_{3}...A_{n}>$ (dove i termini tra parentesi angolari sono nonterminali temporanei)
** si aggiunga un'altra regola $<A_{2}A_{3}...A_{n}>\to A_{2}A_{3}...A_{n}$
** infine se $A_{1}\in \Sigma$ si aggiunge $<A_{1}>\to A_{1}$

### Conversione delle ricorsioni

Questa operazione porta la ricorsione da sinistra a destra, per portare la grammatica nella relativa forma normale. Questa forma normale tornerà utile nel design dei parser top-down.
Spieghiamo con un esempio esplicativo:
Grammatica di partenza:
    $A\ \to \ A\beta _{1}\ |\ A\beta _{2}\ |\ ...A\beta _{h}$
    $A\ \to \ \gamma _{1}\ |\ \gamma _{2}\ |\ ...\gamma _{k}$
Si introduce un nuovo non terminale $A'$:
    $A\ \to \ \gamma _{1}\ |\ \gamma _{2}\ |\ ...\gamma _{k}|\gamma _{1}A'\ |\ \gamma _{2}A'\ |\ ...\gamma _{k}A'$
    $A'\ \to \ \beta _{1}A\ |\ \beta _{2}A\ |\ ...\beta _{h}A|\beta _{1}\ |\ \beta _{2}\ |\ ...\beta _{k}$
Non è sempre possibile riportare le grammatiche in questa forma normale.