Sei sulla pagina 1di 92

Lezione dell’1 Marzo 2022

Docente: Palano Beatrice


homepage: palano.di.unimi.it
email: palano@unimi.it

Ariel
Sugli avvisi in bacheca abbiamo il link per le lezioni del martedì e del
giovedì. Le slide e le registrazioni le troviamo in “Contenuti > Lezioni e
materiali didattici”.
Appunti in formato PDF e lezioni dell’anno scorso. Abbiamo anche la
sezione “Esercizi svolti” con 3 temi d’esame svolti.
Su “Informazioni sul corso” abbiamo gli appelli e le modalità d’esame
(no parziali).
Com’è fatto l’esame?
Prova scritta + prova orale (raramente, a discrezione del docente).
Allo scritto potranno esserci domande aperte di teoria.
Per accedere all’esame bisogna essere iscritti al SIFA (chiedere alla
segreteria didattica).
Su Ariel abbiamo il programma totale e lezione per lezione. Sotto
“informazioni del corso” abbiamo anche le dispense del corso.

Nel corso vedremo l’informatica dal punto di vista teorico


Programma del corso
Linguaggi formali (grammatiche) e automi
Linguaggio: insieme di frasi per la comunicazione tra entità diverse
Esempi:
- Linguaggio naturale (italiano, inglese, ecc…) per la comunicazione
tra le persone ;
- Linguaggio di programmazione (Java, C, C++, Python, Go) per la
comunicazione tra uomo e macchina ;
- Codice morse (codifica di una parole con punti e linee) .

Per conoscere un linguaggio ho bisogno di:


- Vocaboli o parole ;
- Sintassi, cioè le regole per costruire le frasi o i programmi .

Formali: considero questi concetti in maniera precisa utilizzando la


matematica.
Vantaggio: uso di dispositivi elettronici per l’automatizzazione delle
operazioni.

Esempi positivi:
- compilatori = traduzione dei programmi con la creazione di un
eseguibile ;
- interpreti = per l’esecuzione dei programmi prendendo i
programmi e mandandoli in esecuzione .
Esempi negativi:
- traduzione di linguaggi naturali, molto sconveniente dato che
esso può essere diviso in linguaggio parlato (rappresentato da un
segnale continuo) e in linguaggio scritto (con caratteri divisi da
spaziatura).
Il linguaggio naturale è molto vasto, ma se prendiamo sottolinguaggi
(esempio, messaggi delle stazioni ferroviarie) diventa più semplice
analizzarli.
Per l’intero linguaggio abbiamo un problema di ambiguità (ad esempio
pèsca e pésca).
Per trattarlo dobbiamo risolvere questo problema.
Per specificare un linguaggio ho bisogno di un sistema formale:
- Sistemi generativi, formati da vocaboli e regole che producono le
“grammatiche” ;
- Sistemi riconoscitivi, formati da macchine a stati finiti che
producono gli “automi” .

Altra visione
Possiamo pensare a un linguaggio come un problema:
Linguaggio formale = Problema di decisione con risposta SI/NO
1) Concetti base della teoria dei linguaggi.
Elementi della teoria della calcolabilità:
- Linguaggi ricorsivi ;
- Linguaggi ricorsivamente enumerabili ;
- Esistenza di un problema non trattabile ;
- Grammatiche = classificazione di Chomsky .
2) Linguaggi regolari:
- G di tipo 3 ;
- Automi a stati finiti ;
- Espressioni regolari ;
- Minimizzazione di automi ;
- Non determinismo .
3) Linguaggi acontestuali:
- G di tipo 2 ;
- Automi a pila ;
- Ambiguità ;
- Pumping lemma .

Concetti centrali nella teoria dei linguaggi formali


Alfabeto: insieme finito di simboli
Σ = {𝑎1, 𝑎2, ... , 𝑎𝑛}
Parola su Σ, sequenza finita di simboli
Esempi di alfabeti Parole

Σ = {𝑎} a, aa, aaaa

Σ = {0, 1} 0, 1, 000, 010110

Σ = {𝐴, 𝐶, 𝐺, 𝑇} (basi azotate) DNA 10


6

Σ =⊘ (caso particolare) ε parola vuota

Lunghezza di una parola, numero di simboli nella parola

Parola Lunghezza

ω |ω|

Esempio
001011 |001011|=6
Qual’è la lunghezza di ε ?
|ε| = 0
*
Σ = insieme delle parole su Σ compresa ε
+
Σ = insieme delle parole su Σ esclusa ε
+ *
Σ = Σ − {ε}

Concatenazione o “Prodotto di giustapposizione”


+
Date 𝑥, 𝑦 ∈ Σ si dice prodotto la parola 𝑧 = 𝑥𝑦 = 𝑥1𝑥2... 𝑥𝑘𝑦1𝑦2... 𝑦𝑘 dove
𝑥 = 𝑥1𝑥2... 𝑥𝑘 e 𝑦 = 𝑦1𝑦2... 𝑦𝑘
Proprietà del prodotto
+
- chiuso rispetto a Σ ;
- associativo, perchè (𝑥𝑦)𝑧 = 𝑥(𝑦𝑧) ;
- elemento neutro ε .
Domande
1) Lunghezza del prodotto?
|𝑥𝑦| = |𝑥| + |𝑦|
2) Chi è l’elemento neutro?
𝑒 : 𝑒𝑥 = 𝑥𝑒 = 𝑥
𝑥= ε
+
Allora (Σ , ·, ε) è un monoide
+
- Σ insieme di parole
- · operazione binaria associativa
- ε elemento neutro
Esempi
(ℵ, +, 0)
(ℵ, ·, 1)
Differenza? proprietà commutativa
∀𝑥, 𝑦 𝑥 𝑜𝑝 𝑦 = 𝑦 𝑜𝑝 𝑥
+
mentre in (Σ , ·, ε) no
Infatti 𝑥𝑦 ≠ 𝑦𝑥
𝑥 = 𝑙𝑎 e 𝑦 = 𝑔𝑜
𝑥𝑦 = 𝑙𝑎𝑔𝑜 𝑦𝑥 = 𝑔𝑜𝑙𝑎
La prossima lezione sarà sulla suddivisione delle parole.

Lezione dell’8 Marzo 2022

Scomposizione di parole
Esempio:
“incatenare”
Prefisso
Fattore
Suffisso
*
Definizione formale: dati 𝑤, 𝑥 ∈ Σ
- Prefisso
Data 𝑤, 𝑥 è prefisso di 𝑤?
Si dice che 𝑥 è prefisso di 𝑤 quando 𝑤 = 𝑥𝑦 per una qualche parola 𝑦
*
con 𝑦 ∈ Σ .
- Suffisso
Data 𝑤, 𝑥 è suffisso di 𝑤?
Si dice che 𝑥 è suffisso di 𝑤 quando 𝑤 = 𝑦𝑥 per una qualche parola 𝑦
*
con 𝑦 ∈ Σ .
- Fattore
Si dice che 𝑥 è fattore di 𝑤 quando 𝑤 = 𝑦𝑥𝑧 per delle date parole 𝑦, 𝑧 con
*
𝑦, 𝑧 ∈ Σ .
Ci sono delle parole che possono essere contemporaneamente prefisso,
suffisso e fattore di 𝑤?
- ε parola vuota, può essere sia prefisso, suffisso e fattore di 𝑤 ;
- 𝑤 parola stessa, può essere sia prefisso, suffisso e fattore di se
stesso (𝑤) .

Definizione di linguaggio formale


*
Un linguaggio 𝐿 è un qualunque sottoinsieme di Σ :
*
𝐿 ⊆Σ
Casi particolari
- Linguaggio vuoto 𝐿 =⊘ ;
- Linguaggio della parola vuota 𝐿 = {ε} .

*
I linguaggi 𝐿 ⊆ Σ si dividono in finiti e infiniti, i quali possono
determinare la cardinalità.

Esempi di linguaggi finiti:


- Linguaggio vuoto, cardinalità = 0 ;
- Linguaggio con parola vuota, cardinalità = 1 ;
𝑛
- Σ = {𝑎} 𝐿𝑛 = {ε, 𝑎, 𝑎𝑎, 𝑎𝑎𝑎, ... , 𝑎... 𝑎(𝑛 𝑙𝑒𝑡𝑡𝑒𝑟𝑒 𝑎)(𝑞𝑢𝑖𝑛𝑑𝑖 𝑎 }
|𝐿𝑛| = 𝑛 + 1 ;
- Vocabolario dell’italiano Σ = {𝑎, 𝑏, 𝑐, ... , 𝑧}
𝑉 = {𝑎, 𝑎𝑏𝑎𝑐𝑜, ... , 𝑧𝑢𝑧𝑧𝑒𝑟𝑒𝑙𝑙𝑜𝑛𝑒, 𝑧𝑧𝑧} |𝑉| ≃ 200000 .

Esempi di linguaggi infiniti:


𝑛 * * 𝑛
- Σ = {𝑎} 𝐿 = {ε, 𝑎, 𝑎𝑎, 𝑎𝑎𝑎, ... , 𝑎 , ...} = Σ = {𝑎} = {𝑎 | 𝑛 ∈ ℵ} con
0
𝑎 = ε;
- Espressioni booleane 𝐸 .
Σ = {0, 1, ∧, ∨, ¬, (, )}
𝐸 è così definito (per induzione)
● 0, 1 ∈ 𝐸 ;
● Se 𝑥, 𝑦 ∈ 𝐸 allora
○ (𝑥 ∧ 𝑦) ∈ 𝐸 ;
○ (𝑥 ∨ 𝑦) ∈ 𝐸 ;
○ ¬𝑥 ∈ 𝐸, ¬𝑦 ∈ 𝐸 ;
● Nient’altro appartiene ad 𝐸.
Esempi
¬0 (0 ∧ 1) (0 ∨ 1)
Le parole che creiamo possiamo essere inserite all’interno di 𝑥 e 𝑦.
Esempio
(¬0 ∧ 1)
Esempi:
Parole in 𝐸
0, 1, (0 ∧ 1)
((0 ∧ 1) ∨ 0)
¬((0 ∧ 1) ∨ 0)
Osservazione mia:
Le parole in 𝐸 è come se fossero le fbf del corso di logica matematica
Parole non in 𝐸
ε, (, (011
(01
((...)...
(00 ∧ 10)
Ogni volta che abbiamo una parentesi aperta bisogna avere un’altra
parentesi chiusa, e dobbiamo avere solo 1 valore tra {0, 1} vicini tra loro.

Operazioni sui linguaggi


*
Insiemistiche: 𝐴, 𝐵 ⊆ Σ
- Unione
*
𝐴 ∪ 𝐵 = {𝑤 ∈ Σ | 𝑤 ∈ 𝐴 ∨ 𝑤 ∈ 𝐵}
- Intersezione
*
𝐴 ∩ 𝐵 = {𝑤 ∈ Σ | 𝑤 ∈ 𝐴 ∧ 𝑤 ∈ 𝐵}
- Complemento
𝑐 *
𝐴 = {𝑤 ∈ Σ | 𝑤 ∉ 𝐴}

Esercizi
1) 𝐴 = numeri binari escluso lo 0 = parole binarie con prefisso 1
*
-𝐴 = 1{0, 1} ;
*
-𝐵 = 0{0, 1} ;
*
-𝐶 = {0, 1} 0 ;
* *
𝐴 ∪ 𝐵 = 1{0, 1} ∪ 0{0, 1}
* *
𝐴 ∪ 𝐵 è uguale a Σ , {0, 1} ??
+ +
ε non appartiene né a 𝐴 né a 𝐵, quindi 𝐴 ∪ 𝐵 = Σ = {0, 1}
𝐴 ∩ 𝐵 =⊘
* * *
𝐴 ∪ 𝐶 = 1{0, 1} ∪ {0, 1} 0 = 1{0, 1} 0
𝑐 *
𝐴 = 𝐵 ∪ {ε} = 0{0, 1} ∪ {ε}
* 𝑛 *
2) 𝐴 = 𝑎 = {𝑎 | 𝑛 ∈ ℵ} = {𝑎}
𝑐
𝐴 = ?
Con Σ = {𝑎}
𝑐 *
𝐴 = {𝑤 ∈ {𝑎} | 𝑤 ∉ 𝐴} =⊘
* 𝑐
Se 𝐴 = Σ allora 𝐴 =⊘
Con Σ = {𝑎, 𝑏}
𝑐
𝐴 = {𝑡𝑢𝑡𝑡𝑒 𝑙𝑒 𝑝𝑎𝑟𝑜𝑙𝑒 𝑐ℎ𝑒 ℎ𝑎𝑛𝑛𝑜 𝑎𝑙𝑚𝑒𝑛𝑜 𝑢𝑛𝑎 𝑏}
* *
{𝑎, 𝑏} \{𝑎}
* *
Proviamo con 𝑏{𝑎, 𝑏} ∪ {𝑎, 𝑏} così escludiamo “𝑎𝑏𝑎”
* *
Per risolvere usiamo {𝑎, 𝑏} 𝑏{𝑎, 𝑏} parole che contengono almeno una 𝑏
Lezione del 10 Marzo 2022

Operazioni tipiche sui linguaggi:


- Prodotto
*
𝐴 · 𝐵 = {𝑥𝑦 ∈ Σ | 𝑥 ∈ 𝐴 𝑒 𝑦 ∈ 𝐵}
Prodotto di concatenazione preso sui linguaggi, prendendo ogni parola
di 𝐴 e facendo il prodotto di giustapposizione con le parole di 𝐵. Questo
prodotto è sempre non commutativo, 𝑥𝑦 ≠ 𝑦𝑥.
- Potenza
*
𝐿 ⊆Σ
𝑘
𝐿 = 𝐿 · 𝐿 · 𝐿 · ... · 𝐿 𝑘 volte
Si prende una parola di 𝐿 e la si moltiplica con una parola del
linguaggio 𝐿, 𝑘 volte.
0
𝐿 = {ε} linguaggio con parola vuota
𝑘 𝑘−1
𝐿 = 𝐿· 𝐿 definizione ricorsiva
- Chiusura di Kleene: *, +
Prendendo un linguaggio 𝐿 ,

* 0 1 2 𝑘 𝑘
𝐿 = 𝐿 ∪ 𝐿 ∪ 𝐿 ∪ ... ∪ 𝐿 ∪ ... = ⋃ 𝐿
𝑘=0

+ 1 2 𝑘 𝑘
𝐿 = 𝐿 ∪ 𝐿 ∪ ... ∪ 𝐿 ∪ ... = ⋃ 𝐿
𝑘=1
La potenza di solito ha un indice finito
La differenza tra le due chiusure è la parola vuota.
* +
Σ e Σ derivano proprio dalla chiusura di Kleene.

Esercizio
+ *
𝐿 =? 𝐿 \{ε}
*
(In teoria no, dovrebbe essere 𝐿 meno il linguaggio con la parola vuota.

Esercizi
1) 𝐴 = {𝑚𝑜, 𝑠𝑒}
𝐵 = {𝑟𝑎, 𝑟𝑒}
𝐴 · 𝐵 = {𝑚𝑜𝑟𝑎, 𝑚𝑜𝑟𝑒, 𝑠𝑒𝑟𝑎, 𝑠𝑒𝑟𝑒}
𝐵 · 𝐴 = {𝑟𝑎𝑚𝑜, 𝑟𝑎𝑠𝑒, 𝑟𝑒𝑚𝑜, 𝑟𝑒𝑠𝑒}
𝐴 · 𝐵 ≠ 𝐵 · 𝐴 il prodotto di due linguaggi non è commutativo perchè
neanche il prodotto di due parole lo è (giustapposizione).
2) Numeri binari:
*
1{0, 1}
*
𝐴 = {1} e 𝐵 = {0, 1}
Il linguaggio 𝐴 contiene solo il simbolo 1 mentre il linguaggio 𝐵 contiene
tutte le parole del linguaggio.
* *
𝐴 · 𝐵 = {1}{0, 1} = 1{0, 1} (la seconda formula è un abuso di notazione)
Così otteniamo i numeri binari.
3) 𝐿 = {𝑎, 𝑏}
𝑘 *
𝐿 = 𝐿 · 𝐿 · 𝐿 · ... · 𝐿 = {𝑤 ∈ {𝑎, 𝑏} | |𝑤| = 𝑘}
𝑘
Concatenazione delle parole del linguaggio data una potenza 𝐿 , ad
3 𝑘
esempio data 𝐿 , 𝑎𝑏𝑎, 𝑎𝑎𝑎, 𝑎𝑎𝑏, 𝑒𝑐𝑐... appartengono a 𝐿 , mentre ad
𝑘
esempio ε, 𝑎, 𝑏𝑎, 𝑎𝑏 non appartengono a 𝐿 .

*
Σ =? 𝑖𝑛𝑠𝑖𝑒𝑚𝑒 𝑑𝑒𝑙𝑙𝑒 𝑝𝑎𝑟𝑜𝑙𝑒 𝑠𝑢 Σ 𝑐𝑜𝑚𝑝𝑟𝑒𝑠𝑎 ε
Inizialmente lo abbiamo considerato come dogma.

* 𝑘
Consideriamo la precedente chiusura di Kleene, Σ = ⋃ Σ
𝑘=0
𝑘
Σ = parole su Σ con lunghezza 𝑘, lo abbiamo già fatto con il nostro
esempio 𝐿 = {𝑎, 𝑏} , il quale rappresentava un alfabeto. Quindi le
chiusure di Kleene funzionano anche sui Σ alfabeti.
𝑘 𝑘 𝑘 𝑘
= Σ ∪ Σ ∪ Σ ∪ ... ∪ Σ ∪ ...
2 𝑘
({ε} ∪ {𝑤 ∈ Σ | |𝑤| = 1} ∪ {𝑤 ∈ Σ | |𝑤| = 2} ∪ ... ∪ {𝑤 ∈ Σ | |𝑤| = 𝑘} ∪ ...)
Quindi l’uguaglianza è vera!!

Esercizi
- 𝐴 = {𝑏𝑏} Σ = {𝑏}
* 2𝑛
𝐴 = {𝑤 ∈ {𝑏} | |𝑤| = 2𝑛, 𝑛 ≥ 0} = {𝑏 | 𝑛 ∈ ℵ}
- 𝐴 = {𝑏𝑏, 𝑏}
*
(𝐴 , linguaggio formato dalle parole composte dalle parole del
linguaggio di 𝐴, in qualsiasi ordine con una lunghezza finita)
* * + +
𝐴 = {𝑏} e 𝐴 = {𝑏}
Osservazione:
*
Consideriamo una parola appartenente a 𝐴 , ad esempio 𝑏𝑏𝑏, la
domanda da farci è: “In quanti modi posso scomporre la parola con le
parole del linguaggio {𝑏𝑏, 𝑏}?”
Infatti è uguale a “𝑏 · 𝑏 · 𝑏” , “𝑏𝑏 · 𝑏” , “𝑏 · 𝑏𝑏”
Decomposizione in 𝐴
+
Se una parola in 𝐴 ammette più scomposizioni per la stessa parola,
allora il linguaggio non sarà un codice.

Concetto di codice
Possiamo costruire dei codici come dei linguaggi formali, soprattutto
*
utilizzando il + della chiusura di Kleene (quindi 𝐿 ). Per avere un codice
ho bisogno di una proprietà fondamentale, cioè se dato un linguaggio
+
𝐴 , una qualsiasi parola in 𝐴 possiede un, ed un solo, modo per essere
scomposta.
Un codice è, e deve essere un linguaggio finito.
Definizione
Un linguaggio 𝐿 è un codice quando:
+
Ogni parola in 𝐿 è decomponibile in un unico modo in parole di 𝐿.

Esempio:
𝐿 = {𝑎𝑎, 𝑎𝑏, 𝑏}
E’ un codice
Prendiamo ad esempio
+
𝑎𝑏|𝑎𝑎|𝑏|𝑎𝑎|𝑎𝑏 ∈ 𝐿
Questa parola può essere decomposta in un unico modo attraverso il
nostro linguaggio, quindi 𝐿 è un codice.

Definizione
𝐿 è un codice Prefisso o Istantaneo quando:
- è un codice ;
- ogni parola di 𝐿 non è prefisso di altre parole di 𝐿 .

Proprietà dei codici prefissi:


Ammettono un algoritmo di decodifica on-line (mentre sto leggendo la
parola stessa posso decodificare man mano che procedo), quindi è
istantaneo.

Esempi
{𝑎𝑎, 𝑎𝑏, 𝑏} è un codice prefisso
{0, 01} non è un codice prefisso, dato che la parola “0” è prefisso della
parola “01”

Codice ASCII esteso


Codifica ogni carattere della tastiera
{𝐴, ... , 𝑍, 𝑎, ... , 𝑧, 0, 1, ... , 9, ... , {, |, ...}
In sequenze di 8 bit:
*
𝐶𝐴 = {𝑥 ∈ {0, 1} | |𝑥| = 8}
+
Chi è 𝐶𝐴 ?
+
𝐶𝐴 = "𝑓𝑖𝑙𝑒 𝑏𝑖𝑛𝑎𝑟𝑖"
Perchè è importante che 𝐶𝐴 sia un codice?
Risposta:
𝑆𝐴𝐿𝑉𝑂 𝑅𝐼𝐴𝑃𝑅𝑂
File a caratteri →(𝑐𝑜𝑑𝑖𝑓𝑖𝑐𝑎) file binario →(𝑑𝑒𝑐𝑜𝑑𝑖𝑓𝑖𝑐𝑎) file a caratteri originario

(non accadrebbe se 𝐶𝐴 non fosse un codice, quindi non otterremmo lo


stesso file originale durante la decodifica)
𝐶𝐴 è prefisso (o istantaneo):
- Perchè la decodifica non deve impiegare troppo tempo ;
- Perchè le parole di 𝐶𝐴 hanno tutte la stessa lunghezza, quindi è
impossibile che una di quelle parole sia prefisso di un'altra (una
parola è prefisso solo di se stessa).

L’algoritmo di decodifica on-line avviene attraverso il taglio del file ogni


8 bit.

Lezione del 15 Marzo 2022

Riprendiamo la definizione di codice.


+
Un linguaggio 𝐿 è un codice se ogni parola in 𝐿 è un codice
decomponibile in un unico modo in parole di 𝐿.

Esempio negativo
𝐿 = {𝑎, 𝑏, 𝑎𝑏}
+
𝑎𝑏𝑎𝑏 ∈ 𝐿
Può essere scomposta come:
- 𝑎 · 𝑏 · 𝑎 · 𝑏;
- 𝑎𝑏 · 𝑎𝑏 ;
- 𝑎 · 𝑏 · 𝑎𝑏 ;
- 𝑎𝑏 · 𝑎 · 𝑏 .
Quindi non è un codice

Esempio positivo
𝐿 = {𝑎𝑎, 𝑎𝑏, 𝑏}
+
𝑎𝑏|𝑎𝑎|𝑏|𝑏 ∈ 𝐿
𝐿 è un codice

Si dice che un codice 𝐿 prefisso o istantaneo se ogni parola di 𝐿 non è


prefisso delle altre parole di 𝐿.

Esempio negativo
𝐿 = {0, 01}
Codice non prefisso siccome "0" è prefisso di "01"

Esempio positivo
𝐿 = {𝑎𝑎, 𝑎𝑏, 𝑏} ogni sua parola non è prefisso di nessun’altra

Codice ASCII esteso


Codifica i caratteri della tastiera in sequenze di 8 bit.
*
𝐶𝐴 = {𝑥 ∈ {0, 1} | |𝑥| = 8}
+
𝐶𝐴 = "𝑓𝑖𝑙𝑒 𝑏𝑖𝑛𝑎𝑟𝑖"
Perchè è importante che 𝐶𝐴 sia un codice?
Risposta
Stiamo lavorando sul nostro file a caratteri, salvando il file esso viene
codificato in una serie di caratteri in codice ASCII in un file binario. Ad
un certo punto riapro per apportare altre modifiche, avviene la
decodifica di questo file. Se 𝐶𝐴 non fosse un codice otterremmo un file
diverso da quello originario.
𝑆𝐴𝐿𝑉𝑂 𝑅𝐼𝐴𝑃𝑅𝑂
File a caratteri →(𝑐𝑜𝑑𝑖𝑓𝑖𝑐𝑎) file binario →(𝑑𝑒𝑐𝑜𝑑𝑖𝑓𝑖𝑐𝑎) file a caratteri originario
Ma visto che 𝐶𝐴 è un codice otteniamo il file originario.
● 𝐶𝐴 è prefisso perchè ogni parola ha lunghezza di 8 bit e hanno
almeno 1 bit di differenza tra loro.
● Dato che è prefisso ammette un algoritmo di decodifica on-line
(linea per linea), il quale taglia il file binario ogni 8 bit e converte
carattere per carattere.

Un carattere può essere visto come un problema


Definizione di linguaggi
1) 𝐿 = {𝑤1, 𝑤2, ... , 𝑤𝑛} (definizione possibile solo con linguaggi finiti)
definizione estensiva ;
*
2) 𝐿 = {𝑤 ∈ Σ | 𝑃(𝑤) = 1} Dove la proprietà 𝑃 viene soddisfatta solo se
= 1 , definizione intensiva (si può usare anche con i linguaggi
infiniti) .

Fatto:
Ad ogni 𝐿 è associato il problema 𝑃𝐿
* *
Linguaggio 𝐿 = {𝑤 ∈ Σ | 𝑃(𝑤) = 1}⇔ Problema 𝑃𝐿 con Input: 𝑤 ∈ Σ e
Output: 𝑤 soddisfa la proprietà 𝑃? SI / NO (Problema di decisione)

Dato 𝑃𝐿 siamo interessati a:


1) Sapere se 𝑃𝐿 ammette una soluzione automatica ;
2) Se 𝑃𝐿 ammette un algoritmo, se si trova quello migliore .
Tutto questo si traduce nella teoria dei linguaggi in:
1) Sapere se 𝐿 ammette un sistema formale, che può essere un

Sistema generativo Sistema riconoscitivo

Genera le parole di 𝐿 Stabilisco se una parola 𝑤


appartiene a 𝐿 oppure no

2) Se 𝐿 ammette un sistema riconoscitivo, trovare quello migliore .

Esempi
Consideriamo 𝐼 = 𝑙𝑖𝑛𝑔𝑢𝑎𝑔𝑔𝑖𝑜 𝑑𝑒𝑔𝑙𝑖 𝑖𝑛𝑑𝑖𝑟𝑖𝑧𝑧𝑖 𝑖𝑛𝑡𝑒𝑟𝑛𝑒𝑡
* *
= {𝑥 ∈ {0, 1, . } | 𝑥 = 𝑥1. 𝑥2. 𝑥3. 𝑥4 𝑑𝑜𝑣𝑒 𝑥𝑖 ∈ {0, 1} ∧ |𝑥𝑖| = 8}
Software in rete si chiedono se un indirizzo è corretto, cioè se 𝑥 ∈ 𝐼 ⇒
Trovare un sistema riconoscitivo per 𝐼.

Altro esempio
Linguaggio 𝑃 = 𝑙𝑖𝑛𝑔𝑢𝑎𝑔𝑔𝑖𝑜 𝑑𝑒𝑙𝑙𝑒 𝑝𝑎𝑠𝑠𝑤𝑜𝑟𝑑 𝑑𝑖 𝑢𝑛 𝑠𝑖𝑡𝑜 𝑤𝑒𝑏
* *
= {𝑤 ∈ {𝑎, ... , 𝑧, 𝐴, ... , 𝑍, 0, 1, ... , 9} | |𝑤| = 8 ∧ ∃𝑖 : 𝑥𝑖 ∈ {𝐴, ... , 𝑍} ∧
*
∃𝑗 : 𝑥𝑗 ∈ {0, 1, ... , 9} }
Si richiede che queste password vengano generate in maniera
automatica, o sistematica ⇒ Trovare un sistema generativo per 𝑃

Domanda: tutti i problemi di decisione ammettono una soluzione


automatica?
La risposta è stata data nella teoria di calcolabilità (NO, risultato
indipendente dalla tecnologia).
Per mostrare il risultato abbiamo bisogno di alcuni concetti base:
- Procedura = sequenza finita di istruzioni che possono portare a
un risultato ;
- Algoritmo = procedura che termina su ogni input .
Stabiliamo il concetto di programma:
*
1) Aspetto sintattico, un programma è una parola binaria 𝑤 ∈ {0, 1}
grazie al codice ASCII ;
2) 2) Aspetto semantico, un programma associa a degli input, degli
output. Quindi è una legge che allo stesso input associa sempre lo
stesso output. Quindi essa è definibile come una funzione. 𝐹𝑤
programma con 𝐹𝑤(𝑠) = risultato di 𝑤 su input 𝑥 .
Osservazione
*
Un qualsiasi input 𝑥 per il programma 𝑤 è binario : 𝑥 ∈ {0, 1} , ma anche
*
𝑤 ∈ {0, 1} ⇒ Quindi anche 𝑤 può essere visto come un dato e essere
passato ad un altro programma in input.

Limitazione sui programmi


- O i programmi non terminano ;
- O se terminano, danno in uscita o 1 o 0 (Uscita a 1 bit, problemi di
decisione) .
Notazione
𝐹𝑤(𝑥) ↑ 𝑤 su input 𝑥 non termina
𝐹𝑤(𝑠) ↓ 𝑤 su input 𝑥 termina quindi 𝐹𝑤(𝑥) = 1 ∨ 𝐹𝑤(𝑥) = 0 (Output
uguale a 0 o uguale a 1)

Esempio
Problema: calcolare la parità dei numeri binari positivi.
*
Quindi la parità di stringhe della forma 𝑥 ∈ 1{0, 1}
Programma
*
𝑏𝑖𝑛 − 𝑝𝑎𝑟𝑖𝑡à (𝑥 = 𝑥1𝑥2... 𝑥𝑛 ∈ {0, 1} ) (cifre del numero binario 𝑥)
{𝑖𝑓(𝑥1 = 1) 𝑡ℎ𝑒𝑛 𝑟𝑒𝑡𝑢𝑟𝑛 ¬𝑥𝑛 ;
𝑙𝑜𝑜𝑝 ;
}

{
1 se 𝑥 è binario pari

𝐹𝑣(𝑥) = 0 se 𝑥 è binario dispari

↑ se 𝑥 non è binario

{
*
1 se 𝑥 ∈ 1{0, 1} 0
𝐹𝑣(𝑥) = *
0 se 𝑥 ∈ 1{0, 1} 1 ∪ {1}
*
⊥ se 𝑥 ∈ 0{0, 1} ∪ {ε}

*
𝐹𝑣: {0, 1} → {0, 1, ⊥}
Associazione Input/Output
Lezione del 17 Marzo 2022

Definizione
La funzione caratteristica di 𝐿 è:

{
1 se 𝑥 ∈ 𝐿
χ𝐿(𝑥) =
0 se 𝑥 ∉ 𝐿

Esiste sempre per ogni 𝐿!

Definizione
Un linguaggio 𝐿 è detto ricorsivo quando esiste un algoritmo 𝑤 tale che:

{
1 se 𝑥 ∈ 𝐿
𝐹𝑤(𝑥) =
0 se 𝑥 ∉ 𝐿

La differenza consiste nel fatto che la prima è una funzione, mentre la


seconda è un algoritmo che supporta una funzione simile alla funzione
caratteristica. Infatti la seconda tira in ballo una funzione, quindi un
algoritmo. Nel primo caso la funzione c’è per ogni linguaggio, mentre
per il secondo abbiamo bisogno dell’esistenza di un algoritmo di
risoluzione. L’algoritmo non fa altro che calcolare la funzione
caratteristica, la quale nel caso dei linguaggi ricorsivi verrà descritta
come un algoritmo.

Inoltre
Se 𝐿 è ricorsivo allora:
- 𝑃𝐿 è detto decidibile (possiamo associare la parola “ricorsivo”,
proprietà che appartiene al linguaggio, con “decidibile”, proprietà
che appartiene al problema del linguaggio) ;
- 𝐿 ammette un sistema riconoscitivo (parliamo di un sistema
formale per riconoscere gli elementi) .

Esempi
Problemi decidibili:
- numeri pari ;
- numeri primi ;
Linguaggi ricorsivi:
* *
- 𝑎𝑏 ;
𝑛 𝑛
- {𝑎 𝑏 | 𝑛 > 0} .
Definizione
Un linguaggio 𝐿 è ricorsivamente enumerabile quando esiste una
procedura 𝑤 tale che:

{
1 se 𝑥 ∈ 𝐿
𝐹𝑤(𝑥) =
↑ se 𝑥 ∉ 𝐿

Il programma può anche non terminare.


(Non si può dire che non appartiene).
Se 𝐿 è ricorsivamente enumerabile allora:
- 𝑃𝐿 è detto semidecidibile ;
- 𝐿 ammette un sistema generativo .

Relazione:
L’insieme dei linguaggi ricorsivi è un sottoinsieme dei linguaggi
ricorsivamente enumerabili. Dire che è ricorsivamente enumerabile
significa che l’algoritmo ha anche uno stato (o meglio “ramo”) di loop.

Teorema
Se 𝐿 è ricorsivo ⇒ 𝐿 è ricorsivamente enumerabile
Dimostrazione
Per ipotesi esiste un algoritmo 𝐴 per 𝐿:
devo dimostrare l’esistenza di una procedura 𝑃 :
(prendendo l’algoritmo precedente e peggiorarlo nel ramo 0)

Procedura 𝑃(𝑥):
{
𝑦 = 𝐴(𝑥); //𝐴 𝑒𝑠𝑖𝑠𝑡𝑒 𝑝𝑒𝑟𝑐ℎè 𝐿 è 𝑟𝑖𝑐𝑜𝑟𝑠𝑖𝑣𝑜
𝑖𝑓(𝑦 == 1) 𝑡ℎ𝑒𝑛 𝑟𝑒𝑡𝑢𝑟𝑛 (1) ;
𝑙𝑜𝑜𝑝 ;
}

Dimostrazione di correttezza
𝑥 ∈ 𝐿 ⇒ 𝐴(𝑥) = 1 ⇒ 𝑦 = 1 ⇒ 𝑃(𝑥) = 1
𝑥 ∉ 𝐿 ⇒ 𝐴(𝑥) = 0 ⇒ 𝑦 = 0 ⇒ 𝑃(𝑥) ↑
segue che 𝐿 è ricorsivamente enumerabile

Domanda: è vero il viceversa? NO, intuitivamente non sempre si può


trasformare una procedura in un algoritmo.

Teorema
𝑐
Se 𝑙 è ricorsivo ⇒ 𝐿 è ricorsivo
(se so riconoscere un linguaggio, so riconoscere anche cosa non è di
quel linguaggio)

Dimostrazione
Per ipotesi ho:
𝑐
devo quindi costruire un algoritmo 𝐴' per 𝐿

(in pratica prendiamo 𝐴 e invertiamo gli output)

Risultati importanti della teoria della calcolabilità

Conseguenze di questi risultati:


● Non è possibile verificare per via automatica la correttezza dei
programmi (Teorema di Rice, 1950) oppure non è possibile
verificare per via automatica l’equivalenza di due programmi cioè:
*
dati 𝑣 e 𝑤 verificare che ∀𝑥 ∈ {0, 1} 𝐹𝑣(𝑥) = 𝐹𝑤(𝑥) ;
● Non è possibile verificare per via automatica la terminazione dei
programmi cioè:
○ Problema dell’arresto:
Input: programma 𝑤 , dato 𝑥
Output: 𝐹𝑤(𝑥) ↓?
questo problema è indecidibile! (Turing, 1936)
● Ci sono “Teoremi” matematici non dimostrabili (Risultato di
incompletezza di Goedel, 1930) .
Interprete, programma "𝑢"
In input passiamo ad 𝑢 la coppia (programma, dato) e in uscita ho il
risultato dell’esecuzione del “programma” sul “dato”

{
𝐹𝑤(𝑥) se 𝑤 è un
*
𝐹𝑢(𝑤 $ 𝑥, 𝑒𝑛𝑡𝑟𝑎𝑚𝑏𝑖 ∈ {0, 1} ) = programma

⊥ altrimenti

Lezione del 22 Marzo 2022

Linguaggi Ricorsivi o Ricorsivamente Enumerabili


- Un linguaggio si dice Ricorsivo (𝐿) quando esiste un algoritmo 𝑤
tale che:

{
1 se 𝑥 ∈ 𝐿
χ𝐿(𝑥) =
0 se 𝑥 ∉ 𝐿
Problemi decidibili, grazie ai quali riesco a discriminare le parole
che appartengono al linguaggio da quelle che non gli
appartengono.
- Un linguaggio si dice Ricorsivamente Enumerabile (𝐿) quando
esiste una procedura implementata da un programma 𝑤 tale che:

{
1 se 𝑥 ∈ 𝐿
𝐹𝑤(𝑥) =
↑ se 𝑥 ∉ 𝐿

Queste sono 2 classi di linguaggi.

Ricorsivo → Ricorsivamente Enumerabile


Posso dimostrarlo
Per il linguaggio Ricorsivo posso prendere un algoritmo e trasformarlo
in una procedura (che va in stato di loop invece di restituire 0).
𝐷 è Ricorsivamente Enumerabile ma non Ricorsivo (devo dimostrarlo
esibendo un linguaggio).
𝐷 ← Linguaggio dell’arresto, che dato in input un programma e un dato
ci dice se esso termina o no, in questo caso esso è semidecidibile ma
non decidibile.

*
Interprete: è un programma “𝑢” ∈ {0, 1}
Input: passiamo la coppia (programma, dato)
Output: il risultato del programma su quel determinato dato

{
𝐹𝑤(𝑥) quando 𝑤 è un programma
𝐹𝑢(𝑤$𝑥) =
⊥ altrimenti

*
Dove 𝑢 è l’interprete, 𝑤 è il programma, 𝑥 è il dato e 𝑤$𝑥 ∈ {0, 1}

Definiamo il linguaggio 𝐷
*
𝐷 = {𝑥 ∈ {0, 1} | 𝐹𝑢(𝑥$𝑥) ↓}
*
Insieme delle parole su {0, 1} che passate sia come dato che come
programma all’interprete fanno in modo che esso termini.
*
𝑥$𝑥 ∈ {0, 1} è quindi lecito passarlo ad 𝑢 interprete.
𝐷 è detto linguaggio dell’arresto ristretto (perchè testa solo 𝑥$𝑥).
𝐶 *
𝐷 = {𝑥 ∈ {0, 1} | 𝐹𝑢(𝑥$𝑥) ↑}

Teorema
1) 𝐷 è un linguaggio Ricorsivamente Enumerabile ;
2) 𝐷 non è ricorsivo ;
𝐶
3) 𝐷 non è ricorsivamente enumerabile.

Dimostrazione del punto 1


Devo esibire per 𝐷 una procedura 𝑃 tale che

{
1 se 𝑥 ∈ 𝐷 ∗
𝐹𝑃(𝑥) =
↑ se 𝑥 ∉ 𝐷 •

∗ quando 𝐹𝑢(𝑥$𝑥) ↓
• quando 𝐹𝑢(𝑥$𝑥) ↑
*
Posso costruire la seguente procedura 𝑅𝐼𝐶𝑁𝑈𝑀(𝑥 ∈ {0, 1} )
{
𝑦 = 𝐹𝑢(𝑥$𝑥) ; \\ istruzione eseguibile, dato che "𝑢" esiste
sempre e quindi posso richiamarlo
𝑟𝑒𝑡𝑢𝑟𝑛 (1) ;
}
(Non termina se 𝐹𝑢(𝑥$𝑥) non termina)
𝑅𝐼𝐶𝑁𝑈𝑀 è proprio la procedura 𝑃 che cercavamo.
Dimostrazione di correttezza di 𝑅𝐼𝐶𝑁𝑈𝑀:
- 𝑥 ∈ 𝐷 ⇒ 𝐹𝑢(𝑥$𝑥) ↓⇒ viene eseguita l’istruzione
𝑦 = (𝑑𝑖 𝑎𝑠𝑠𝑒𝑔𝑛𝑎𝑚𝑒𝑛𝑡𝑜) ⇒ 𝑟𝑒𝑡𝑢𝑟𝑛(1) ⇒ 𝑅𝐼𝐶𝑁𝑈𝑀(𝑥) = 1 GIUSTO!!
- 𝑥 ∉ 𝐷 ⇒ 𝐹𝑢(𝑥$𝑥) ↑⇒ 𝑅𝐼𝐶𝑁𝑈𝑀 va in loop all’istruzione
𝑦 = (𝑑𝑖 𝑎𝑠𝑠𝑒𝑔𝑛𝑎𝑚𝑒𝑛𝑡𝑜) ⇒ 𝑅𝐼𝐶𝑁𝑈𝑀(𝑥) =↑ GIUSTO!!
𝑅𝐼𝐶𝑁𝑈𝑀(𝑥) è la procedura 𝑃 che cercavamo che mostra che 𝐷 è un
linguaggio Ricorsivamente Enumerabile.

Dimostrazione del punto 2


𝐷 non è ricorsivo
Tecnica dell’assurdo
Supponendo che 𝐷 sia Ricorsivo, quindi posso costruire un programma
che mi porterà ad una contraddizione.
*
Procedura 𝐴𝑆𝑆𝑈𝑅𝐷𝑂𝐴(𝑥 ∈ {0, 1} )
{
𝑖𝑓 𝑥 ∈ 𝐷 𝑡ℎ𝑒𝑛 𝑟𝑒𝑡𝑢𝑟𝑛 (1 − 𝐹𝑢(𝑥$𝑥)) ;
𝑒𝑙𝑠𝑒 𝑟𝑒𝑡𝑢𝑟𝑛 0 ;
}
Programma fattibile
Posso testare 𝑥 ∈ 𝐷 perché sto supponendo che sia ricorsivo. Tutte le
istruzioni sono implementabili. ⇒ Esiste "𝑒" codice binario per la codifica
*
di 𝐴𝑆𝑆𝑈𝑅𝐷𝑂𝐴(𝑥) con 𝑒 ∈ {0, 1}
Allora passo ad 𝐴𝑆𝑆𝑈𝑅𝐷𝑂𝐴 il codice binario di "𝑒".
Quanto vale 𝐴𝑆𝑆𝑈𝑅𝐷𝑂𝐴(𝑒) ?
Secondo alcune considerazioni ottengo la seguente risposta:
𝐴𝑆𝑆𝑈𝑅𝐷𝑂𝐴(𝑒) = 𝐹𝑒(𝑒) per definizione di "𝑒" è vero.
(#) 𝐴𝑆𝑆𝑈𝑅𝐷𝑂𝐴(𝑒) = 𝐹𝑒(𝑒) = 𝐹𝑢(𝑒$𝑒) per definizione di "𝑒" e di "𝑢"
Ottenendo così 𝐴𝑆𝑆𝑈𝑅𝐷𝑂𝐴(𝑒) = 𝐹𝑢(𝑒$𝑒)
Esiste un altro modo per mostrare quanto vale 𝐴𝑆𝑆𝑈𝑅𝐷𝑂𝐴(𝑒) ,
considerando il valore stesso del codice:
- Caso 𝑒 ∈ 𝐷 ⇒ 𝐹𝑢(𝑒$𝑒) ↓ per definizione di 𝐷 (uguale a 1 o a 0) , quindi
𝐴𝑆𝑆𝑈𝑅𝐷𝑂𝐴(𝑒) = 1 − 𝐹𝑢(𝑒$𝑒) ma per la proprietà precedente
𝐹𝑢(𝑒$𝑒) = 1 − 𝐹𝑢(𝑒$𝑒) ottenendo così 1 = 0 o 0 = 1, quindi
ottenendo un ASSURDO!! ;
- Caso 𝑒 ∉ 𝐷 ⇒ 𝐹𝑢(𝑒$𝑒) ↑ per definizione di 𝐷, quindi 𝐴𝑆𝑆𝑈𝑅𝐷𝑂𝐴(𝑒) = 0 ,
che diventa poi 𝐹𝑢(𝑒$𝑒) = 0 ⇒ ↑ = 0 ottenendo un ASSURDO!!
Quindi "𝑒" non esiste e non è il codice di un programma.
Dato che "𝑒" non esiste, quindi non posso fare 𝑥 ∈ 𝐷 , il programma non
termina (non avendo un linguaggio ricorsivo) e quindi 𝐷 non è ricorsivo.

Lezione del 24 Marzo 2022

Linguaggio dell’arresto ristretto


*
𝐷 = {𝑥 ∈ {0, 1} | 𝐹𝑢(𝑥$𝑥) ↓}
𝐶
In 𝐷 ci sono sia i “non programmi”, sia i programmi che non terminano
su loro stessi.
Parte 3 del teorema
𝐶
- 𝐷 non è ricorsivamente enumerabile.

Adesso dimostriamo il punto 3 del teorema


𝐶 *
𝐷 = {𝑥 ∈ {0, 1} | 𝐹𝑢(𝑥$𝑥) ↑}
Non è Ricorsivamente Enumerabile
Dimostrazione per assurdo
𝐶
Suppongo che 𝐷 sia Ricorsivamente enumerabile ⇒ esiste una
procedura 𝑧 tale che:
Inoltre anche 𝐷 è ricorsivamente enumerabile (per il punto 1 del
teorema) e pertanto esiste una procedura 𝑦 tale che:

Idea
Adesso prendo 𝑥

Sembra un algoritmo Ricorsivo che farebbe diventare a sua volta 𝐷


ricorsivo.
*
Programma 𝐴𝑆𝑆𝑈𝑅𝐷𝑂𝐵(𝑥 ∈ {0, 1} )
{
𝑘 = 1; \\ numero di passi
𝑤ℎ𝑖𝑙𝑒(𝑧(𝑥) 𝑛𝑜𝑛 𝑡𝑒𝑟𝑚𝑖𝑛𝑎 𝑖𝑛 𝑘 𝑝𝑎𝑠𝑠𝑖 ∧ 𝑦(𝑥) 𝑛𝑜𝑛 𝑡𝑒𝑟𝑚𝑖𝑛𝑎 𝑖𝑛 𝑘 𝑝𝑎𝑠𝑠𝑖){
𝑘 = 𝑘 + 1;
}
// quando esco dal while significa che una delle due ha terminato,
ma non sappiamo quale, dato che restituiscono entrambe 1
𝑖𝑓 (ℎ𝑎 𝑡𝑒𝑟𝑚𝑖𝑛𝑎𝑡𝑜 𝑦) 𝑡ℎ𝑒𝑛 𝑟𝑒𝑡𝑢𝑟𝑛 (1) ;
𝑒𝑙𝑠𝑒 𝑟𝑒𝑡𝑢𝑟𝑛 (0) ;
}
Domanda: cosa fa 𝐴𝑆𝑆𝑈𝑅𝐷𝑂𝐵(𝑥) ?
- Se 𝑥 ∈ 𝐷 sono nel caso in cui 𝑦 termina e esiste un
𝑘 : 𝑦(𝑥) ↓⇒ 𝑟𝑒𝑡𝑢𝑟𝑛 (1) ⇒ 𝐴𝑆𝑆𝑈𝑅𝐷𝑂𝐵(𝑥) = 1 ;
- Se 𝑥 ∉ 𝐷 sono nel caso in cui 𝑧 termina e esiste un
𝑘 : 𝑧(𝑥) ↓⇒ 𝑟𝑒𝑡𝑢𝑟𝑛 (0) ⇒ 𝐴𝑆𝑆𝑈𝑅𝐷𝑂𝐵(𝑥) = 0 .

𝐴𝑆𝑆𝑈𝑅𝐷𝑂𝐵(𝑥) è un algoritmo per 𝐷 ⇒ 𝐷 è ricorsivo ⇒ ASSURDO!!


Contraddizione perchè il codice non può esistere, dobbiamo trovare
l’errore ma tutte le procedure e funzioni sono vere tranne la nostra
𝐶
supposizione 𝑧 ⇒ 𝐷 non è Ricorsivamente Enumerabile.
Abbiamo dimostrato tutti i punti del Teorema.

Domanda: esiste un problema che non ammette soluzione algoritmica ?


Esiste un problema indecidibile ?
Risposta: SI!
Problema dell’arresto o della fermata
Input: 𝑤$𝑥
Output: Risposta alla domanda 𝐹𝑤(𝑥) ↓ ?
*
𝐴 = {𝑤$𝑥 ∈ {0, 1} | 𝐹𝑤(𝑥) ↓}
Linguaggio dell’arresto
*
𝐷 = {𝑥 ∈ {0, 1} | 𝐹𝑢(𝑥$𝑥) ↓}
*
𝐴 = {𝑤$𝑥 ∈ {0, 1} | 𝐹𝑤(𝑥) ↓}

Teorema
𝐴 non è ricorsivo
Dimostrazione per assurdo
Suppongo 𝐴 Ricorsivo e pertanto esiste 𝑦 :
Allora posso costruire un programma che chiameremo 𝐴𝑆𝑆𝑈𝑅𝐷𝑂𝐶(𝑥)
*
𝑥 ∈ {0, 1} → 𝑥$𝑥 → 𝑦(𝑥$𝑥) → 1 se 𝐹𝑢(𝑥$𝑥) ↓ quindi se 𝑥 ∈ 𝐷 e 0 se 𝐹𝑢(𝑥$𝑥) ↑
quindi se 𝑥 ∈ 𝐷
*
Programma 𝐴𝑆𝑆𝑈𝑅𝐷𝑂𝐶(𝑥 ∈ {0, 1} )
{
𝑖𝑓 𝑥$𝑥 ∈ 𝐴 𝑡ℎ𝑒𝑛 𝑟𝑒𝑡𝑢𝑟𝑛 (1) ;
𝑒𝑙𝑠𝑒 𝑟𝑒𝑡𝑢𝑟𝑛 (0) ;
}
Cosa fa 𝐴𝑆𝑆𝑈𝑅𝐷𝑂𝐶(𝑥) ?
Se 𝑥 ∈ 𝐷 ⇒ 𝐹𝑢(𝑥$𝑥) ↓⇒ 𝑥$𝑥 ∈ 𝐴 ⇒ 𝐴𝑆𝑆𝑈𝑅𝐷𝑂𝐶(𝑥) = 1 ;
Se 𝑥 ∉ 𝐷 ⇒ 𝐹𝑢(𝑥$𝑥) ↑⇒ 𝑥$𝑥 ∉ 𝐴 ⇒ 𝐴𝑆𝑆𝑈𝑅𝐷𝑂𝐶(𝑥) = 0 .
Il test 𝑥$𝑥 ∈ 𝐴 però è fattibile solo nel momento in cui 𝐴 sia ricorsivo.
𝐴𝑆𝑆𝑈𝑅𝐷𝑂𝐶 è un algoritmo per 𝐷 ⇒ assurdo ⇒ 𝐷 non è ricorsivo ⇒ anche 𝐴
non è ricorsivo.
Il problema dell’arresto è indecidibile e indipendente dalla tecnologia.

Lezione del 29 Marzo 2022

In questa lezione iniziamo a occuparci dei sistemi formali per


l’automatizzazione per risolvere i problemi di decisioni. Lo facciamo
attraverso i linguaggi formali. Il primo sistema che può essere
automatizzato per ottenere risultati nei problemi di decisione sono i
sistemi generativi.

Un particolare sistema generativo:


La grammatica
Si parla delle regole sintattiche (o di produzione) attraverso le quali
ottengo le parole del linguaggio.

Consideriamo un sottolinguaggio dell’italiano: gli annunci ferroviari in


stazione
Se abbiamo → stiamo considerando delle regole
< 𝑠𝑜𝑝𝑝𝑟𝑒𝑠𝑠𝑖𝑜𝑛𝑒 >→ 𝐼𝑙 𝑡𝑟𝑒𝑛𝑜 𝑆 < 𝑛𝑢𝑚 > 𝑑𝑒𝑙𝑙𝑒 < 𝑜𝑟𝑎𝑟𝑖𝑜 > è 𝑠𝑜𝑝𝑝𝑟𝑒𝑠𝑠𝑜
La soppressione mi permette di generare la frase in stazione in maniera
automatica, la quale verrà poi annunciata dagli altoparlanti.
< 𝑛𝑢𝑚 >→ 1 | 2 | ... | 13
Numero di passanti dei treni di Milano.
< 𝑜𝑟𝑎𝑟𝑖𝑜 >→ < 𝑜𝑟𝑒 > 𝑒 < 𝑚𝑖𝑛𝑢𝑡𝑖 >
< 𝑜𝑟𝑒 >→ 1 | 2 | ... | 24
Le ore e i minuti corrispondono a quelle reali correnti.
< 𝑚𝑖𝑛𝑢𝑡𝑖 >→ 00 | 01 | ... | 60
<... > viene chiamato “variabile” o “metasimbolo” (deve essere sostituito)
𝑛𝑜𝑛 <... > viene chiamato “terminale” (ed è fisso, non è sempre vero)
< 𝑠𝑜𝑝𝑝𝑟𝑒𝑠𝑠𝑖𝑜𝑛𝑒 > è il simbolo generale detto “assioma” (porta il nome
della frase che vogliamo generale)
... →... è una regola detta di “produzione”
⇒ indica l’applicazione di una regola ed è chiamato “passo di
derivazione” (quando applichiamo una regola della grammatica, nel
nostro esempio non sono stati ancora applicate le regole della
grammatica)
*
⇒ è l’applicazione di più regole detto “derivazione in zero o più passi”
(più passi di derivazione insieme

Esempio:
< 𝑠𝑜𝑝𝑝𝑟𝑒𝑠𝑠𝑖𝑜𝑛𝑒 >⇒ 𝐼𝑙 𝑡𝑟𝑒𝑛𝑜 𝑆 < 𝑛𝑢𝑚 > 𝑑𝑒𝑙𝑙𝑒 < 𝑜𝑟𝑎𝑟𝑖𝑜 > è 𝑠𝑜𝑝𝑝𝑟𝑒𝑠𝑠𝑜
⇒ 𝐼𝑙 𝑡𝑟𝑒𝑛𝑜 𝑆6 𝑑𝑒𝑙𝑙𝑒 < 𝑜𝑟𝑎𝑟𝑖𝑜 > è 𝑠𝑜𝑝𝑝𝑟𝑒𝑠𝑠𝑜
*
⇒ 𝐼𝑙 𝑡𝑟𝑒𝑛𝑜 𝑆6 𝑑𝑒𝑙𝑙𝑒 < 𝑜𝑟𝑒 > 𝑒 < 𝑚𝑖𝑛𝑢𝑡𝑖 > è 𝑠𝑜𝑝𝑝𝑟𝑒𝑠𝑠𝑜 ⇒
𝐼𝑙 𝑡𝑟𝑒𝑛𝑜 𝑆6 𝑑𝑒𝑙𝑙𝑒 10 𝑒 20 è 𝑠𝑜𝑝𝑝𝑟𝑒𝑠𝑠𝑜
Questa è una derivazione per la generazione di una frase degli annunci
ferroviari.

Formalizziamo
Definizione:
Una grammatica è una quadrupla:
𝐺 = (Σ, 𝑀, 𝑆, 𝑃) dove
- Σ insieme finito dei simboli terminali ;
- 𝑀 insieme dei <... > metasimboli con Σ ∩ 𝑀 =⊘ ;
- 𝑆 è un simbolo in 𝑀 , 𝑆 ∈ 𝑀 ed è l’Assioma (start symbol) ;
- 𝑃 è l’insieme finito delle regole di produzione .

Definizione di regola di produzione


+ *
α → β dove : α ∈ (Σ ∪ 𝑀) e β ∈ (Σ ∪ 𝑀)
Σ ∪ 𝑀 unione di due alfabeti, ottenendo un nuovo alfabeto
Esempio
𝑆 → ε ma non ε → 𝑆

Definizione di passo di derivazione


Si dice che 𝑤 è derivabile da 𝑧 in un passo e si scrive 𝑧 ⇒ 𝑤
(Applicazione di una regola appartenente a 𝑃)
Quando:
𝑧 = 𝑥α𝑦 e 𝑤 = 𝑥β𝑦 e α → β ∈ 𝑝
Allora 𝑥α𝑦 ⇒ 𝑥β𝑦
Definizione di derivazione in zero o più passi
*
Si dice che 𝑤 è derivabile da 𝑧 in zero o più passi e si scrive 𝑧⇒ 𝑤
Quando:
esiste 𝑘 ∈ ℵ\{0} e esistono le parole 𝑤1 , 𝑤2 , ... , 𝑤𝑘 tali che
𝑧 ⇒ 𝑤1 ⇒ 𝑤2 ⇒ ... ⇒ 𝑤𝑘 ⇒ 𝑤
Oppure
𝑤= 𝑧

Definizione
Il linguaggio generato da 𝐺 è:
* *
𝐿(𝐺) = {𝑤 ∈ Σ | 𝑆⇒ 𝑤}
(Tutte le parole generate dall’assioma principale)
Osservazioni:
● Un linguaggio può ammettere più grammatiche che lo generano ;
● Due grammatiche 𝐺1 e 𝐺2 si dicono equivalenti se 𝐿(𝐺1) = 𝐿(𝐺2) .

Esempi
Esempio 1.
𝐺 = ({𝑎}, {𝑆}, 𝑆, {𝑆 → 𝑎𝑆 𝑆 → 𝑎})
𝐿(𝐺)?
𝑆⇒𝑎
* 𝑛−1 𝑛
𝑆 ⇒ 𝑎𝑆 ⇒ 𝑎𝑎𝑆 ⇒ 𝑎𝑎𝑎𝑆⇒ 𝑎 𝑆⇒𝑎
+
𝐿(𝐺) = 𝑎
Esempio 2.
2𝑛
Se 𝐿 = {𝑎 | 𝑛 ≥ 1}
Qui possiamo derivare due grammatiche
𝐺1
𝑆 → 𝑎𝑎
𝑆 → 𝑎𝑎𝑆
𝐺2
𝑆 → 𝑎𝐴
𝐴 → 𝑎𝑆
𝐴→𝑎
𝐺1 e 𝐺2 sono equivalenti
Esempio 3.
𝑛 𝑛
𝐿 = {𝑎 𝑏 | 𝑛 > 0}
𝑆 → 𝑎𝑏
𝑆 → 𝑎𝑆𝑏
𝑛−1 𝑛−1 𝑛 𝑛
𝑆 ⇒ 𝑎𝑆𝑏 ⇒ 𝑎𝑎𝑆𝑏𝑏 ⇒ 𝑎 𝑆𝑏 ⇒𝑎 𝑏
Esempio 4.
Σ = {0, 1}
𝑟 +
Palindrome: 𝑃 = {𝑤𝑤 | 𝑤 ∈ {0, 1} }
𝑤 = 𝑤1𝑤2... 𝑤𝑛
𝑤𝑟 = 𝑤𝑛... 𝑤2𝑤1
Regole:
𝑆 → 00 𝑆 → 11 𝑆 → 0𝑆0 𝑆 → 1𝑆1

Lezione del 31 Marzo 2022

Continuiamo con gli esempi della volta precedente


Esempio 5.
+
{𝑤 ∈ {0, 1} | #1(𝑤) = #0(𝑤)}
#α(𝑤) = numero di simboli α in 𝑤
0101 : #0 = #1 = 2
1101 : #1 = 3 mentre #0 = 1 quindi non appartiene al linguaggio
𝑆 → 𝑧𝑆𝑢 𝑆 → 𝑧𝑢 𝑧→0 𝑢→1 𝑧𝑢 = 𝑢𝑧 (con questo
spostiamo l’ordine dopo aver creato una parola simmetrica)
Esempio 6.
𝑛 𝑛 𝑛
{𝑎 𝑏 𝑐 | 𝑛 > 0}
𝑆 → 𝑎𝑆𝐵𝐶
𝑆 → 𝑎𝐵𝐶
𝐶𝐵 → 𝐵𝐶
𝐵→𝑏
𝐶→𝑐
Queste sono espressioni libere da contesto, sono più difficili da
utilizzare perchè per trasformare 𝐵 e 𝐶 bisognerebbe utilizzare
espressioni dipendenti dal contesto (con simboli terminali all’inizio)
quindi useremo:
𝑎𝐵 → 𝑎𝑏
𝑏𝐵 → 𝑏𝑏
𝑏𝐶 → 𝑏𝑐
𝑐𝐶 → 𝑐𝑐
* *
𝑆 ⇒ 𝑎𝑆𝐵𝐶 ⇒ 𝑎𝑎𝑆𝐵𝐶𝐵𝐶 ⇒ 𝑎𝑎𝑎𝐵𝐶𝐵𝐶𝐵𝐶⇒ 𝑎𝑎𝑎𝐵𝐵𝐵𝐶𝐶𝐶⇒ 𝑎𝑎𝑎𝑏𝑏𝑏𝑐𝑐𝑐

Domanda:
Tutti i linguaggi formali ammettono una grammatica?
Non tutti, infatti abbiamo il seguente teorema
Teorema
𝐿 è ricorsivamente enumerabile ⇔ 𝐿 è generato da 𝐺
Dimostrazione (solo ⇐)
Data la grammatica 𝐺 per 𝐿 posso costruire una procedura di 𝑤 tale che

{
1 se 𝑥 ∈ 𝐿
𝐹𝑤(𝑥) =
↑ se 𝑥 ∉ 𝐿

Definizioni:
𝐹𝑖 = {𝑝𝑎𝑟𝑜𝑙𝑒 𝑑𝑖 𝑠𝑖𝑚𝑏𝑜𝑙𝑖 𝑡𝑒𝑟𝑚𝑖𝑛𝑎𝑙𝑖 𝑒 𝑣𝑎𝑟𝑖𝑎𝑏𝑖𝑙𝑖 𝑜𝑡𝑡𝑒𝑛𝑢𝑡𝑒 𝑑𝑎 𝑆 𝑖𝑛 "𝑖" 𝑝𝑎𝑠𝑠𝑖 𝑑𝑖 𝑑𝑒𝑟𝑖𝑣𝑎𝑧𝑖𝑜𝑛𝑒}
𝑇𝑖 = {𝑝𝑎𝑟𝑜𝑙𝑒 𝑑𝑖 𝑠𝑜𝑙𝑖 𝑠𝑖𝑚𝑏𝑜𝑙𝑖 𝑡𝑒𝑟𝑚𝑖𝑛𝑎𝑙𝑖 𝑜𝑡𝑡𝑒𝑛𝑢𝑡𝑒 𝑑𝑎 𝑆 𝑖𝑛 "𝑖" 𝑝𝑎𝑠𝑠𝑖 𝑑𝑖 𝑑𝑒𝑟𝑖𝑣𝑎𝑧𝑖𝑜𝑛𝑒}
Nota : 𝑇𝑖 ⊆ 𝐹𝑖
(Quelle con variabili e simboli terminali sono contenute in 𝐹𝑖 mentre
quelle con solo simboli terminali 𝑇𝑖)

Fatto: 𝐿(𝐺) = ⋃ 𝑇𝑖
𝑖
Infatti:
*
1) 𝑥 ∈ 𝐿(𝐺) ⇒ ℎ𝑜 𝑆⇒ 𝑥 ⇒ ∃ 𝑖 : 𝑖 è il numero di passi di derivazione in
*
𝑆 ⇒ 𝑥 ⇒ 𝑥 ∈ 𝑇𝑖 ⇒ 𝑥 ∈ ⋃ 𝑇𝑖 (𝐿(𝐺) ⊆ ⋃ 𝑇𝑖);
𝑖 𝑖

*
2) 𝑥 ∈ ⋃ 𝑇𝑖 ⇒ ∃ 𝑖 : 𝑥 ∈ 𝑇𝑖 ⇒ ℎ𝑜 𝑆 ⇒ 𝑥 in “𝑖” di derivazione
𝑖

*
⇒ ℎ𝑜 𝑆 ⇒ 𝑥 ⇒ 𝑥 ∈ 𝐿(𝐺) (⋃ 𝑇𝑖 ⊆ 𝐿(𝐺)) .
𝑖

Formalizzo 𝐹𝑖 e 𝑇𝑖 :
*
𝐹𝑖 = {γ ∈ (Σ ∪ 𝑀) | η ⇒ γ 𝑒 η ∈ 𝐹𝑖−1} (formalizzazione ricorsiva)
*
𝑇𝑖 = {𝑥 ∈ Σ | 𝑥 ∈ 𝐹𝑖}

Inizialmente costruisco la procedura 𝐸𝐿𝐸𝑁𝐶𝐴 che genera tutte le parole

di 𝐿(𝐺) = ⋃ 𝑇𝑖
𝑖
𝐸𝐿𝐸𝑁𝐶𝐴 stampa:
𝑇1
𝑇2
𝑇3
...
*
Procedura 𝐸𝐿𝐸𝑁𝐶𝐴() ← 𝑥 ∈ Σ
{
𝐺 = (Σ, 𝑀, 𝑃, 𝑆) ; // fisso 𝐺
𝐹𝑜 = {𝑆} ;
𝑖 = 1;
𝑤ℎ𝑖𝑙𝑒(𝑖 > 0) 𝑑𝑜
{
𝐹𝑖 = 𝐶𝑜𝑠𝑡𝑟𝑢𝑖𝑠𝑐𝑖𝐹(𝐹𝑖−1, 𝐺) ;
𝑇𝑖 = 𝐶𝑜𝑠𝑡𝑟𝑢𝑖𝑠𝑐𝑖𝑇(𝐹𝑖, 𝐺) ;
𝑂𝑢𝑡𝑝𝑢𝑡(𝑇𝑖) ;
𝑖 = 𝑖 + 1;
}
}

Funzioni di 𝐸𝐿𝐸𝑁𝐶𝐴 :
𝐶𝑜𝑠𝑡𝑟𝑢𝑖𝑠𝑐𝑖𝐹 (𝐹𝑖−1 , 𝐺)
{
𝐹𝑖 =⊘ ;
𝑓𝑜𝑟 𝑒𝑎𝑐ℎ η ∈ 𝐹𝑖−1 𝑑𝑜
𝑓𝑜𝑟 𝑒𝑎𝑐ℎ α → β ∈ 𝑃 𝑑𝑜
*
𝑓𝑜𝑟 𝑒𝑎𝑐ℎ 𝑥, 𝑦 ∈ (Σ ∪ 𝑀) : η = 𝑥α𝑦 𝑑𝑜
𝐹𝑖 = 𝐹𝑖 ∪ {𝑥β𝑦} ;
𝑟𝑒𝑡𝑢𝑟𝑛 (𝐹𝑖) ;
}

𝐶𝑜𝑠𝑡𝑟𝑢𝑖𝑠𝑐𝑖𝑇 (𝐹𝑖 , 𝐺)
{
𝑇𝑖 =⊘ ;
𝑓𝑜𝑟 𝑒𝑎𝑐ℎ 𝑤 ∈ 𝐹𝑖 𝑑𝑜
*
𝑖𝑓(𝑤 ∈ Σ ) 𝑡ℎ𝑒𝑛
𝑇𝑖 = 𝑇𝑖 ∪ {𝑤} ;
𝑟𝑒𝑡𝑢𝑟𝑛 (𝑇𝑖) ;
}

Adesso trasformiamo 𝐸𝐿𝐸𝑁𝐶𝐴 nella procedura 𝑤 :


1 modifica :
*
Passo 𝑥 ∈ Σ in input ad 𝐸𝐿𝐸𝑁𝐶𝐴

2 modifica :
Sostituisco 𝑂𝑢𝑡𝑝𝑢𝑡(𝑇𝑖) con 𝑖𝑓(𝑥 ∈ 𝑇𝑖) 𝑡ℎ𝑒𝑛 𝑟𝑒𝑡𝑢𝑟𝑛 (1) ;

Correttezza della procedura 𝐸𝐿𝐸𝑁𝐶𝐴 modificata:


𝑥 ∈ 𝐿(𝐺) ⇒ ∃ 𝑖 : 𝑥 ∈ 𝑇𝑖 ⇒ verrà eseguito 𝑟𝑒𝑡𝑢𝑟𝑛(1) ⇒ 𝐸𝐿𝐸𝑁𝐶𝐴(𝑥) = 1

𝑥 ∉ 𝐿(𝐺) ⇒ 𝑥 ∉ ⋃ 𝑇𝑖 ⇒ ∀ 𝑖 ∈ ℵ 𝑥 ∈ 𝑇𝑖 ⇒ il ciclo andrà in loop ⇒ 𝐸𝐿𝐸𝑁𝐶𝐴(𝑥) ↑


𝑖

Linguaggio delle espressioni booleane = 𝐿 su ∧ e ∨


Definizione
● 0, 1 ∈ 𝐿 ;
● 𝑥, 𝑦 ∈ 𝐿 ⇒ (𝑥 ∧ 𝑦) ∈ 𝐿 𝑜 (𝑥 ∨ 𝑦) ∈ 𝐿 ;
● nient’altro appartiene ad 𝐿 .

Grammatica di 𝐺 :
Σ = {0, 1, (, ), ∧, ∨}
𝑀 = {𝐸}
𝐸
𝑃 = {𝐸 → 0, 𝐸 → 1, 𝐸 → (𝐸 ∧ 𝐸), 𝐸 → (𝐸 ∨ 𝐸)}
𝑤 = (0 ∧ (1 ∨ 0)) ∈ 𝐿
*
𝐸 ⇒ (𝐸 ∧ 𝐸) ⇒ (0 ∧ 𝐸) ⇒ (0 ∧ (𝐸 ∨ 𝐸))⇒ (0 ∧ (1 ∨ 0))

Lezione del 5 Aprile 2022

Introduciamo il linguaggio delle espressioni booleane e la sua


grammatica in modo da costruire e dare una definizione dell’albero di
derivazione.

Linguaggio delle espressioni booleane su ∧ e su ∨ = 𝐿


Definizione
● 0, 1 ∈ 𝐿 ;
● 𝑥, 𝑦 ∈ 𝐿 ⇒ (𝑥 ∨ 𝑦) ∈ 𝐿 e (𝑥 ∧ 𝑦) ∈ 𝐿 ;
● Nient’altro appartiene ad 𝐿 .
Grammatica del linguaggio 𝐺
● Σ = {0, 1, (, ), ∨, ∧} ;
● 𝑀 = {𝐸} ← variabile ;
● 𝐸 ← assioma ;
● 𝑃 = {𝐸 → 0, 𝐸 → 1, 𝐸 → (𝐸 ∧ 𝐸), 𝐸 → (𝐸 ∨ 𝐸)} .
Prendiamo adesso ad esempio la parola 𝑤 = (0 ∧ (1 ∨ 0)) ∈ 𝐿
Si parte con l’operazione più esterna.
*
𝐸 ⇒ (𝐸 ∧ 𝐸) ⇒ (𝐸 ∧ (𝐸 ∨ 𝐸)) ⇒ (0 ∧ (𝐸 ∨ 𝐸))⇒ (0 ∧ (1 ∨ 0))
Posso rappresentare la derivazione di 𝑤 attraverso il suo albero di
derivazione:

Esso è un oggetto ben preciso con alla radice l’assioma della


grammatica, i nodi sono le variabili della grammatica e le foglie sono i
simboli terminali tali che se letti da sinistra verso destra ottengo 𝑤 ∈ 𝐿 .
I sottoalberi sono quelli delle regole di derivazione.

⇔ 𝐴 → 𝐵1, 𝐵2, 𝐵3, ... 𝐵𝑘 ∈ 𝑃 di 𝐺


Osservazione
Per avere alberi di derivazione, 𝐺 deve essere almeno di tipo 2 (non
ancora introdotto), vuol dire che le regole in testa devono avere una
sola variabile.
Classificazione delle grammatiche
(versione preliminare)
I tipi si differenziano per le regole. Ci sono 4 tipi in funzione di esse:
- Tipo 0. Non abbiamo nessun vincolo sulle regole di produzione ;
- Tipo 1. Sono ammesse solo le regole α → β con |α| → |β| (quindi non
possono produrre ε) ;
- Tipo 2. Sono ammesse regole della forma 𝐴 → β dove 𝐴 ∈ 𝑀 e
+
β ∈ (Σ ∪ 𝑀) ;
- Tipo 3. Sono ammesse regole della forma 𝐴 → 𝑦𝐵 e 𝐴 → 𝑥 dove 𝐴 e 𝐵
* +
sono delle variabili, 𝑦 ∈ Σ e 𝑥 ∈ Σ .
Si va dalla più complessa alla più semplice (meno regole → più
complicata).

Fatto: Una grammatica di tipo 𝑘 lo è anche di tipo 𝑘 − 1 (per 𝑘 = 3, 2, 1


ed è ricorsivo come fatto).

Definizione
Un linguaggio si dice di tipo 𝑘 se ammette una grammatica di tipo 𝑘
(0, 1, 2, 3).

Definizione
*
𝑅𝑘 = {𝐿 ∈ Σ | 𝐿 è 𝑑𝑒𝑙 𝑡𝑖𝑝𝑜 𝑘} (classi di linguaggi di tipo 𝑘, ce ne sono 4)
𝑅3 = linguaggi regolari
𝑅2 = linguaggi liberi da contesto
𝑅1 = linguaggi definiti da contesto
𝑅0 = linguaggi ricorsivamente enumerabili

Vediamo esempi di grammatiche


(del tipo 3, 2, 1 mentre per il tip 0 va bene qualsiasi grammatica)
* *
Tipo 3: 𝐴 → 𝑦𝐵 𝐵 → 𝑥 con 𝐴, 𝐵 ∈ 𝑀 e 𝑦 ∈ Σ , 𝑥 ∈ Σ
2𝑛
● 𝑆 → 𝑎𝑎𝑆 𝑆 → 𝑎𝑎 per {𝑎 | 𝑛 > 0} ;
+ +
● 𝐴 → 𝑎𝐴 𝐴 → 𝑎𝐵 𝐵 → 𝑏𝐵 𝐵 → 𝑏 per {𝑎 𝑏 } .
*
Tipo 2: 𝐴 → β con 𝐴 ∈ 𝑀 e β ∈ (Σ ∪ 𝑀)
𝑛 𝑛
● 𝑆 → 𝑎𝑆𝑏 𝑆 → 𝑎𝑏 per {𝑎 𝑏 | 𝑛 > 0} ; (Osservazione: 𝑆 → 𝑎𝑆𝑏 ≠ 𝑆 → 𝑎𝑆
del tipo 3) ;
● 𝐵 = 𝑝𝑎𝑟𝑜𝑙𝑒 𝑑𝑖 𝑝𝑎𝑟𝑒𝑛𝑡𝑒𝑠𝑖 𝑏𝑒𝑛 𝑓𝑜𝑟𝑚𝑎𝑡𝑒 𝑆 → (𝑆)𝑆 𝑆 → (𝑆) 𝑆 → ()𝑆
𝑆 → ()
Tipo 1: α → β con |α| → |β|
𝑛 𝑛 𝑛
● Per il linguaggio {𝑎 𝑏 𝑐 | 𝑛 > 0} con 𝑆 → 𝑎𝑆𝐵𝐶 𝑆 → 𝑎𝐵𝐶 𝐶𝐵 → 𝐵𝐶
𝑎𝐵 → 𝑎𝑏 𝑏𝐵 → 𝑏𝑏 𝑏𝐶 → 𝑏𝑐 𝑐𝐶 → 𝑐𝑐 .

Esempio concreto di 𝐺 di tipo 2 , i DTD (grammatica del tipo 2) dei


documenti XML (linguaggio di tipo 2)

Documenti XML
Documenti composti da “testo” e “tag”. Il testo può essere arbitrario
mentre il tag deve rispettare alcune regole.
Tag= marcatore di testo che consente di dargli informazioni semantiche.
Esempio
< 𝑟𝑢𝑏𝑟𝑖𝑐𝑎 >
< 𝑛𝑜𝑚𝑒 > 𝑉𝑒𝑟𝑑𝑖 < /𝑛𝑜𝑚𝑒 >
< 𝑡𝑒𝑙𝑒𝑓𝑜𝑛𝑜 > 02487251 < /𝑡𝑒𝑙𝑒𝑓𝑜𝑛𝑜 >
< 𝑡𝑒𝑙𝑒𝑓𝑜𝑛𝑜 > 349501234 < /𝑡𝑒𝑙𝑒𝑓𝑜𝑛𝑜 >
< 𝑛𝑜𝑚𝑒 > 𝑅𝑜𝑠𝑠𝑖 < /𝑛𝑜𝑚𝑒 >
< 𝑡𝑒𝑙𝑒𝑓𝑜𝑛𝑜 > 04517677 < /𝑡𝑒𝑙𝑒𝑓𝑜𝑛𝑜 >
< /𝑟𝑢𝑏𝑟𝑖𝑐𝑎 >

< 𝑟𝑢𝑏𝑟𝑖𝑐𝑎 >< /𝑟𝑢𝑏𝑟𝑖𝑐𝑎 > indicano inizio e fine della rubrica, per ogni tag
aperto <... > ci deve essere un tag chiuso corrispondente < /... >

Formalizziamo le regole
Tag aperto: < 𝑡 >: 𝑡
Tag chiuso:< /𝑡 >: 𝑡
Condizioni che un documento deve soddisfare sono:
1) Deve esistere un unico tag che contiene tutto il documento 𝑠 ... 𝑠
nell’esempio avevamo 𝑟𝑢𝑏𝑟𝑖𝑐𝑎 ... 𝑟𝑢𝑏𝑟𝑖𝑐𝑎 ;
2) Ogni tag aperto deve essere seguito dal corrispondente chiuso ;
3) I tag devono essere innestati correttamente (𝑥 ... 𝑦 ... 𝑦 ... 𝑥).

Definizione
Un documento per il quale valgono le condizioni 1, 2, 3 si dice “corretto”.
DTD = definisce come i tag possono essere innestati tra di loro

Esempio:
Nel documento “rubrica” il tag < 𝑡𝑒𝑙 > non può stare dentro al tag
< 𝑛𝑜𝑚𝑒 >.

Definizione
Un documento XML è valido secondo un certo DTD se è generato da
quel DTD (grammatica di tipo 2). Le regole di un DTD sono della forma:
𝐴 → 𝑎𝑅𝑎𝑎 dove 𝑅𝑎 = espressione di variabili con le operazioni
+ (𝑢𝑛𝑖𝑜𝑛𝑒), ·, *

Creiamo un DTD:
*
𝑆 → 𝑠𝐶 𝑠 < 𝑠𝑡𝑢𝑑𝑒𝑛𝑡𝑖 >
*
𝐶 → 𝑐𝑀𝑁(𝐸𝑉) 𝑐 < 𝑐𝑢𝑟𝑟𝑖𝑐𝑢𝑙𝑢𝑚 >
𝑀 → 𝑚𝑚 < 𝑚𝑎𝑡𝑟𝑖𝑐𝑜𝑙𝑎 >
𝑁 → 𝑛𝑛 < 𝑛𝑜𝑚𝑒 >
𝐸 → 𝑒𝑒 < 𝑒𝑠𝑎𝑚𝑒 >
𝑉 → 𝑣𝑣 < 𝑣𝑜𝑡𝑜 >
Anche questo DTD è della forma 𝐴 → 𝑎𝑅𝑎𝑎

Lezione del 7 Aprile 2022

Teorema sugli 𝑅𝑘 :
𝑅3 ⊂ 𝑅2 ⊂ 𝑅1 ⊂ 𝑅0

⊂ = “sottoinsieme di” o “inclusione propria” ≠ ⊆ (si esclude la


possibilità che le classi siano uguali tra di loro, ci sarà un linguaggio
appartenente a 𝑅𝑘 ma non a 𝑅𝑘−1 con 𝑘 ∈ {3, 2, 1})
𝑅𝑘 classe di linguaggio con tipo di grammatica associato
𝑅3 linguaggi regolari
𝑅2 liberi da contesto
𝑅1 dipendenti da contesto
𝑅0 linguaggi ricorsivamente enumerabili
Dimostrazione
Separiamo la dimostrazione dell’inclusione da quella dell’esistenza di
𝐿0 , 𝐿1 e 𝐿2.
● L’inclusione tra gli 𝑅𝑘 segue dal FATTO che abbiamo dato sui tipi
di 𝐺 : 𝑡𝑖𝑝𝑜 𝑘 ⇒ 𝑡𝑖𝑝𝑜 𝑘 − 1 ;
● dimostriamo che l’inclusione è propria ;
𝑛 𝑛
○ esiste 𝐿2 ∈ 𝑅2 ma 𝐿2 ∉ 𝑅3 ad esempio 𝐿2 = {𝑎 𝑏 | 𝑛 > 0} . Infatti
esso ammette 𝐺 di tipo 2 𝑆 → 𝑎𝑆𝑏, 𝑆 → 𝑎𝑏 e inoltre ∉ 𝑅3 perchè
non ammette un automa a stati finiti che lo riconosce ;
𝑛 𝑛 𝑛
○ esiste 𝐿1 ∈ 𝑅1 ma 𝐿1 ∉ 𝑅2 ad esempio 𝐿1 = {𝑎 𝑏 𝑐 | 𝑛 > 0}. Infatti
esso ammette 𝐺 di tipo 1 e ∉ 𝑅2 perchè non soddisfa il
pumping lemma per i linguaggi liberi da contesto ;
○ esiste 𝐿0 ∈ 𝑅0 ma 𝐿0 ∉ 𝑅1 ad esempio
*
𝐿0 = 𝐷 = {𝑥 ∈ {0, 1} | 𝐹𝑢(𝑥$𝑥) ↓} che ammette 𝐺 di tipo 0 ma
∉ 𝑅1 .
Dimostrazione
Passo 1. 𝑅1 ⊆ 𝑅𝑖𝑐𝑜𝑟𝑠𝑖𝑣𝑖
Passo 2. 𝐷 non è ricorsivo ⇒ 𝐷 ∉ 𝑅1 e 𝐷 è ricorsivamente enumerabile
⇒ 𝐷 ∈ 𝑅0

Abbiamo dimostrato (ovvio) il passo 2 ma non il passo 1


Dobbiamo definire un programma creato con grammatica di tipo 1 per
mostrare che sia ricorsivo.
*
Definizione di 𝐺𝑅(𝑥) con 𝑥 ∈ Σ programma per i grafi.
𝐺𝑅(𝑥) =< 𝑉𝑥 , 𝐸𝑥 > dove:
*
𝑉𝑥 = {𝑦 ∈ (Σ ∪ 𝑀) | |𝑦| ≤ |𝑥|} (in generale gli archi sono coppie di vertici)
𝐸𝑥 = {(𝑦, 𝑦') | 𝑦 ⇒ 𝑦'}
*
Algoritmo 𝑤(𝑥 ∈ Σ )
{
𝐶𝑂𝑆𝑇𝑅𝑈𝐼𝑆𝐶𝐼 𝐺𝑅(𝑥) ; // serve 𝐺
𝑖𝑓 (𝑒𝑠𝑖𝑠𝑡𝑒 𝑢𝑛 𝑐𝑎𝑚𝑚𝑖𝑛𝑜 𝑆. →. 𝑥)
𝑡ℎ𝑒𝑛 𝑟𝑒𝑡𝑢𝑟𝑛 (1);
𝑒𝑙𝑠𝑒 𝑟𝑒𝑡𝑢𝑟𝑛 (0);
}
Osservazioni:
Il problema della generazione di 𝑥 si trasforma nella ricerca di un
cammino in un grafo. Il tempo dell’algoritmo 𝑤 è esponenziale, richiesto
da 𝐶𝑂𝑆𝑇𝑅𝑈𝐼𝑆𝐶𝐼 𝐺𝑅(𝑥).

Correttezza di 𝑤:
𝑥 ∈ 𝐿(𝐺) ⇒ esiste una derivazione in 𝐺
𝑆 ⇒ 𝑧1 ⇒ 𝑧2 ⇒ ... ⇒ 𝑧𝑘 ⇒ 𝑥 tale che
per ogni 𝑖 abbiamo che |𝑧𝑖| ≤ |𝑧𝑖+1| , |𝑧𝑖| ≤ |𝑥| e 𝑧𝑖 ∈ 𝑉𝑥 inoltre abbiamo che
𝐹𝑤(𝑥) = 1
𝑥 ∉ 𝐿(𝐺) ⇒ 𝐹𝑤(𝑥) = 0

Lezione del 12 Aprile 2022

In questa lezione vedremo la classificazione di Chomsky definitiva.


Il motivo per cui quella precedente va bene è per la parola vuota ε (che
per adesso è generata solo dalle grammatiche di tipo 0).
Data la classificazione di Chomsky provvisoria:
Se 𝐿 è di tipo 𝑘 , di che tipo è 𝐿 ∪ {ε} ?
Avrei bisogno di 𝑆 → ε (regola che permette di generarla) consentita solo
dal tipo 0.
Quindi 𝐿 ∪ {ε} è del tipo 0.
Se abbiamo un linguaggio di altro tipo e aggiungo ε cambia? Se
cambia, questa classificazione non è ragionevole perchè una singola
parola non può cambiare il tipo del linguaggio. Pertanto apportiamo 2
modifiche.
𝐼 modifica:
Riguardo le grammatiche di tipo 𝑘 = 3, 2, 1 applichiamo la seguente
modifica.
(𝑆) ← 𝑚𝑜𝑑𝑖𝑓𝑖𝑐𝑎
E’ ammessa la regola 𝑆 → ε a patto che:
- 𝑆 sia l’assioma ;
- 𝑆 non compaia sulla destra di altre regole.
FATTO 𝐼 :
Se 𝐿 è di tipo 𝑘 , allora anche 𝐿 ∪ {ε} è di tipo 𝑘.
Dimostrazione
Ho 𝐺 grammatica per 𝐿 di tipo 𝑘 e devo costruire 𝐺' per 𝐿 ∪ {ε}
mantenendo il tipo.
Introduco 𝑆' (nuovo assioma) in 𝐺' e le regole 𝑆' → 𝑆 e 𝑆' → ε.
𝑆' non è presente alla destra di altre regole.
La grammatica 𝐺' rispetta la nostra modifica ed è dello stesso tipo di 𝐺.
𝐼𝐼 modifica:
Per le grammatiche di tipo 𝑘 = 3, 2 ammetto regole della forma 𝐴 → ε
dove 𝐴 è una variabile arbitraria.
Cancellando la variabile posso accorciare la parola in corso di
derivazione (permettendo una derivazione decrescente).
FATTO 𝐼𝐼:
Se ho 𝐺 di tipo 𝑘 = 3, 2 con regole 𝐴 → ε arbitrarie, posso ottenere 𝐺'
equivalente di tipo 𝑘 che rispetta (𝑆).
Esempio
𝑆 → 0𝑆0
𝑆 → 1𝑆1
𝑆→ε
Questa grammatica è di tipo 𝑘 = 2 e non rispetta (𝑆) (perchè 𝑆 compare
alla destra della prima e della seconda regola).
Applico 𝑆 → ε alle altre regole:
𝑆 → 00
𝑆 → 11
Aggiungo queste regole e elimino 𝑆 → ε (perchè le regole appena inserite
simulano 𝑆 → ε).
Manca la possibilità di iniziare generando ε. Per generare la parola
vuota ho di nuovo bisogno di 𝑆' → 𝑆 e di 𝑆' → ε .
Quindi 𝐺' :
𝑆 → 0𝑆0 𝑆 → 1𝑆1 𝑆 → 00 𝑆 → 11 𝑆' → 𝑆 𝑆→ε
Il tipo 𝑘 = 2 è preservato e in più la nuova 𝐺 grammatica rispetta (𝑆).

Classificazione di Chomsky definitiva


- Tipo 0: regole arbitrarie ;
- Tipo 1: regole della forma
α → β con |α| → |β| con l’eccezione 𝑆 → ε se :
- 𝑆 è l’assioma ;
- 𝑆 non compare sulla destra di altre regole.
*
- Tipo 2: regole della forma 𝐴 → β con 𝐴 ∈ 𝑀 e β ∈ (Σ ∪ 𝑀) invece di
+
includendo quindi anche ε ;
*
- Tipo 3: regole nella forma 𝐴 → 𝑥𝐵 𝐴 → 𝑦 con 𝐴, 𝐵 ∈ 𝑀 e 𝑥, 𝑦 ∈ Σ
(quindi adesso è compresa anche ε per 𝑦) .

Teorema sugli 𝑅𝑘
𝑅3 ⊂ 𝑅2 ⊂ 𝑅1 ⊂ 𝑅0 continua a valere grazie al FATTO 𝐼𝐼

Teorema 𝑅1 ⊆ 𝑅𝑖𝑐𝑜𝑟𝑠𝑖𝑣𝑖
Continua a valere perchè la frase (𝑆) preserva la lunghezza non
decrescente delle derivazioni.

Forme equivalenti per il tipo 3:


(𝑖) 𝐴 → σ𝐵 𝐴→σ 𝐴 → ε dove 𝐴, 𝐵 ∈ 𝑀 variabili e σ ∈ Σ
caratteri terminali ;
(𝑖𝑖) 𝐴 → σ𝐵 𝐴 → ε dove 𝐴, 𝐵 ∈ 𝑀 variabili e σ ∈ Σ ;
(𝑖𝑖𝑖) 𝐴 → σ𝐵 𝐴 → σ dove 𝐴, 𝐵 ∈ 𝑀 variabili e σ ∈ Σ solo se ε ∉ 𝐿 .

Posso passare dalla forma (𝑖) a (𝑖𝑖) eliminando le regole della forma
𝐴 → σ.
- Introduco una variabile 𝑋 ;
- Per ogni regola 𝐴 → σ introduco 𝐴 → σ𝑋 e 𝑋 → ε ;
- Cancello le regole del tipo 𝐴 → σ .

Posso passare da (𝑖) a (𝑖𝑖𝑖) eliminando le regole della forma 𝐴 → ε.


- Per ogni regola della forma 𝐴 → σ𝐵 aggiungo regole della forma
𝐴 → σ se 𝐵 → ε ∈ 𝑃 ;
- Cancello le regole della forma 𝐴 → ε .

E’ possibile mostrare la seguente equivalenza:


𝐴 → 𝑥𝐵 𝐴 → σ𝐵
𝐴→𝑦 𝐴→σ
𝐴, 𝐵 ∈ 𝑀 𝐴→ε
* ⇔ 𝐴, 𝐵 ∈ 𝑀
𝑥, 𝑦 ∈ Σ
*
(forma lineare a destra) σ ∈Σ
(caso particolare della lineare a
destra)

⇐ ) Facile perchè 𝑥 = 𝑦 = σ
⇒ ) Trasformazione da mostrare
Esempio
𝐴 → 𝑎𝑏𝑐𝐵 con 𝑎, 𝑏, 𝑐 ∈ Σ simboli terminali
Prendo 𝑋 = 𝑏𝑐𝐵
𝐴 → 𝑎𝑋 𝑋 → 𝑏𝑐𝐵
Prendo 𝑌 = 𝑐𝐵
𝑋 → 𝑏𝑌 𝑌 → 𝑐𝐵
Abbiamo trovato regole 𝐴 → 𝑥𝐵 con |𝑥| > 0 rendendole 𝐴 → σ𝐵

*
Per le regole della forma 𝐴 → 𝑦 con 𝑦 ∈ Σ utilizziamo la stessa tecnica
Ad esempio
𝐴 → 𝑎𝑏𝑐 con 𝑎, 𝑏, 𝑐 ∈ Σ lettere terminali
Prendo 𝑋 = 𝑏𝑐
𝐴 → 𝑎𝑋 𝑋 → 𝑏𝑐
Prendo 𝑌 = 𝑐
𝑋 → 𝑏𝑌 𝑌→𝑐

Caso non trattato


Le regole della forma 𝐴 → 𝑥𝐵 con |𝑥| = 0 cioè 𝐴 → 𝐵 .
Posso sempre eliminarle aggiungendo regole della forma 𝐴 → σ𝐵 e 𝐴 → σ
(La prova non la facciamo)

Lezione del 21 Aprile 2022

Teoria degli automi a stati finiti


Applicazioni: HW e SW
● HW: progettazione di circuiti elettronici modellando semplici
sistemi ;
● SW: costruzione di analizzatori lessicali che fanno da soluzione a
problema di ricerca nei testi o modellare pagine web.

Un sistema da modellare con automi:


- Abbiamo un Robot che si muove su una griglia ;
- Il Robot è telecomandato da segnali che indicano la direzione ;
- Il comportamento del Robot può essere modellato da un automa.
Postazioni nella griglia → stati dell’automa.
Segnali inviati al Robot → simboli di input dell’automa: 𝑁 , 𝑆 , 𝐸 , 𝑂
(direzionali)
Questo ci porta al seguente automa:

Da cosa dipende la posizione del Robot?


Caratteristica principale:
La posizione prossima del Robot dipende:
- dalla posizione attuale ;
- dal simbolo inviato.
Osservazione:
Un percorso diventa una parola (sequenza ordinata di simboli).

Grazie all’automa posso studiare a tavolino problemi legati al sistema


- Individuare una parola che mi porta da 𝐴 a 𝐵 ;
- Individuare una parola che mi porta da 𝐴 a 𝐵 passando attraverso
𝐶 (o evitando di passare attraverso 𝐶) ;
- Individuare tutte le parole prive di cicli che mi portano da 𝐴 a 𝐵;
- Tra queste ultime individuare la parola più corta.

Automi a stati finiti come riconoscitori di linguaggi formali


In prima approssimazione si presenta così:
Un esperimento consiste in:
*
- passare 𝑤 ∈ Σ in input ;
- osservare l’uscita, se essa sarà uguale a 1 allora 𝑤 ∈ 𝐿 mentre se
sarà uguale a 0 allora 𝑤 ∉ 𝐿.
Il comportamento di 𝐴 è dato dall’insieme dalle parole che 𝐴 accetta =
Linguaggio accettato ⇒ 𝐴 è un riconoscitore di linguaggi, in particolare
gli automi a stati finiti riconoscono i linguaggi di tipo 3.

In dettaglio:
● In ogni istante di tempo 𝑡 l’automa si trova in un particolare stato.
Inizialmente 𝐴 si trova in uno stato iniziale 𝑞0 ;
● In funzione del simbolo letto e dello stato attuale 𝐴 cambia stato,
quindi chiameremo δ la funzione di transizione:
○ δ(𝑞 , σ) = stato prossimo di 𝐴 essendo in 𝑞 e leggendo σ ;
● Una volta letta l’intera parola 𝑤 , 𝐴 raggiunge uno stato 𝑝 e l’uscita
dipende da 𝑝:
○ λ(𝑝) = 0 o 1 se 𝑝 è uno stato finale, funzione λ di uscita.

Formalizziamo:
Definizione
Un automa a stati finiti è una tupla
𝐴 =< Σ , 𝑄 , 𝑞0 , δ, λ (𝑙𝑎 𝑞𝑢𝑎𝑙𝑒 𝑐𝑖 𝑑𝑎𝑟à 𝑢𝑛 𝑖𝑛𝑠𝑖𝑒𝑚𝑒 𝑑𝑖 𝑠𝑡𝑎𝑡𝑖 𝑓𝑖𝑛𝑎𝑙𝑖 𝐹) >
Dove:
Σ = alfabeto di input
𝑄 = insieme degli stati (se 𝑄 è finito allora 𝐴 è a stati finiti)
𝑞0 = stato iniziale di partenza
δ = funzione di transizione
δ: 𝑄 × Σ → 𝑄
λ = funzione di uscita
λ: 𝑄 → {0 , 1}
oppure
𝐹 ⊆ 𝑄 stati finali o accettanti

Osservazione:
- Data λ posso avere 𝐹 come 𝐹 = {𝑞 ∈ 𝑄 | λ(𝑞) = 1} ;
- Dato 𝐹 posso avere λ come λ(𝑝) = 1 se 𝑝 ∈ 𝐹 mentre sarà = 0 se
𝑝∉𝐹

Rappresentazioni di δ:
Esempio:
𝑄 = {𝑞0 , 𝑞1}
Σ = {𝑎 , 𝑏}
𝑞0 iniziale
𝐹 = {𝑞0}

δ 𝑎 𝑏

𝑞0 𝑞1 𝑞0

𝑞1 𝑞0 𝑞1

Diagramma degli stati


Esempio grafico:

Una parola è accettata se partendo da 𝑞0 = stato iniziale, induce un


cammino che termina in uno stato finale.
Esempi di parole:
𝑏𝑏𝑏 è accettata
𝑏𝑎𝑏 è rifiutata
2𝑛 𝑛
𝑎 è accettata, se fosse stato 𝑎 sarebbe stata accettata solo con 𝑛 pari

Formalizzo il concetto di linguaggio riconosciuto


*
Introduciamo la δ che è la δ estesa alle parole:
* *
δ :𝑄 × Σ → 𝑄
Definizione induttiva:

{
*
δ (𝑞 , ε) = 𝑞

* *
δ (𝑞 , 𝑤σ) = δ(δ (𝑞 , 𝑤) , σ)

*
dove 𝑤 ∈ Σ e σ ∈ Σ

𝐿(𝐴) = linguaggio riconosciuto da 𝐴


* *
= {𝑤 ∈ Σ | δ (𝑞0 , 𝑤) ∈ 𝐹}
* *
= {𝑤 ∈ Σ | λ(δ (𝑞0 , 𝑤)) = 1}
Esempio:
*
𝐿(𝐴) = {𝑤 ∈ {𝑎 , 𝑏} | |𝑤|𝑎 = 2𝑛 , 𝑛 ≥ 0}
|𝑤|σ = numero di σ in 𝑤

Lezione del 26 Aprile 2022

Automi a stati finiti


Li indichiamo con 𝐴 =< Σ , 𝑄 , 𝑞0 , δ , 𝐹/λ >
Dove:
- Σ è l’alfabeto ;
- 𝑄 è l’insieme degli stati ;
- 𝑞0 è lo stato iniziale ;
- δ è la funzione per la transizione tra stati, essa ha due parametri
prendendo uno stato e un simbolo e restituisce uno stato, quindi
δ: 𝑄 × Σ → 𝑄 e quindi δ(𝑞, σ) restituisce lo stato successivo a 𝑞
* * *
dopo aver letto il simbolo σ (δ : 𝑄 × Σ → 𝑄 con δ (𝑞, 𝑤) è lo stato
raggiunto da 𝑞 dopo aver letto la parola 𝑤) ;
- 𝐹 insieme degli stati finali ;
- λ output degli stati finali .
* *
𝐿(𝐴) = {𝑤 ∈ Σ | δ (𝑞0 , 𝑤) ∈ 𝐹}

Diagramma degli stati di 𝐴

Stati particolari
● Stato trappola: 𝑞 è uno stato trappola se vale che
∀σ ∈ Σ ⇒ δ(𝑞 , σ) = 𝑞 e 𝑞 ∉ 𝐹 (di solito assorbe le parole rifiutate) ;
● Stato osservabile: 𝑝 è uno stato osservabile se
* *
∃𝑤 ∈ Σ : δ (𝑞0 , 𝑤) = 𝑝 (è osservabile se è raggiungibile dallo stato
iniziale) .

Esempio:
Si può notare che 𝑞1 è uno stato osservabile grazie ad "𝑎" es è anche
uno stato trappola perchè non esce da 𝑞1 e non è uno stato finale.
Lo stato 𝑞0 è osservabile partendo sempre da 𝑞0 con la parola "𝑏" o con
la parola vuota ε (δ(𝑞 , ε) = 𝑞) , ma non è uno stato trappola perchè è
finale e con "𝑎" vado in 𝑞1.
Lo stato 𝑞2 è non osservabile perchè da 𝑞0 non è raggiungibile (questo
stato si può eliminare).

Definizione
Stati indistinguibili
* * *
𝑞 e 𝑝 si dicono indistinguibili quando ∀𝑤 ∈ Σ : λ(δ (𝑞 , 𝑊)) = λ(δ (𝑝 , 𝑤))

Stati distinguibili
* * *
𝑞 e 𝑝 si dicono distinguibili quando ∃𝑤 ∈ Σ : λ(δ (𝑞 , 𝑊)) ≠ λ(δ (𝑝 , 𝑤))
(quindi sono distinti per almeno una parola).

Notazione
𝑞 ≈ 𝑝 indistinguibili
𝑞 𝑛𝑜𝑡 ≈ 𝑝 distinguibili

Esempio
non posso eliminare alcuno stato
*
𝐿(𝐴) = {𝑎, 𝑏} 𝑎
(nello stati finale entrano le frecce etichettate con "𝑎")
(tutte le frecce etichettate con "𝑏" mi portano in stati che non
appartengono a 𝐹)

Considero la coppia 𝑞0 , 𝑞1 e mi chiedo se sono indistinguibili.


Leggendo "𝑎" vanno entrambe nello stato finale, leggendo "𝑏" vengono
mandate entrambe in uno stato ∉ 𝐹 però sono distinguibili per ε dato
che 𝑞0 viene rifiutato mentre 𝑞1 va in uno stato finale.
Vale lo stesso per 𝑞1 , 𝑞2.
E per 𝑞0 , 𝑞2 per la parola "𝑎" vanno entrambe in 𝑞1 mentre per "𝑏" e per ε
vengono rifiutate.

Come sfruttare questa relazione per ridurre gli stati dell’automa


≈ : relazione binaria sull’insieme 𝑄
Proprietà:
● Riflessiva ∀𝑞 ∈ 𝑄 ⇒ 𝑞 ≈ 𝑞 ;
● Simmetrica ∀𝑞, 𝑝 ∈ 𝑄 con 𝑝 ≈ 𝑞 ⇒ 𝑞 ≈ 𝑝 ;
● Transitiva ∀𝑞, 𝑝, 𝑟 ∈ 𝑄 𝑐𝑜𝑛 𝑞 ≈ 𝑝 𝑒 𝑝 ≈ 𝑟 ⇒ 𝑞 ≈ 𝑟 ;
* * *
● ∀𝑞, 𝑝 ∈ 𝑄 se vale che 𝑞 ≈ 𝑝 ⇒ ∀𝑧 ∈ Σ : δ (𝑞, 𝑧) ≈ δ (𝑝, 𝑧) ;
(se parto da due stati indistinguibili e leggo una qualsiasi parola
raggiungo 2 stati indistinguibili)
≈ relazione di equivalenza
Quindi essendo una relazione di equivalenza indica una partizione su 𝑄
(𝑄/ ≈ classi di equivalenza di stati)
Partizione in classi:
- ∀𝑖 𝑐𝑖 ≠⊘ ;
- ∀𝑖, 𝑗 𝑠𝑒 𝑖 ≠ 𝑗 ⇒ 𝑐𝑖 ∩ 𝑐𝑗 =⊘ ;
- ⋃ 𝑐𝑖 = 𝑄 .
𝑖

Dato 𝐴 =< Σ , 𝑄 , 𝑞0 , δ , 𝐹/λ >


Posso costruire 𝐴≈ che ha come stati le classi di equivalenza di 𝑄/ ≈
Formalmente
𝐴≈ =< Σ , 𝑄/ ≈ , [𝑞0]≈ , δ≈ , 𝐹≈ >
Dove:
- 𝐹≈ = {[𝑝]≈ | 𝑝 ∈ 𝐹} ;
*
- δ : 𝑄/ ≈ × Σ → 𝑄/ ≈ definito come δ([𝑞]≈ , σ) = [δ(𝑞 , σ)]≈ .
Esempio:
Prendiamo l'automa precedente e costruiamo 𝐴≈

𝑄/ ≈= {𝑠0 , 𝑠1}
𝐴≈ =<
Σ = {𝑎, 𝑏}
𝑄/ ≈= {𝑠0 , 𝑠1}
[𝑞0]≈ = 𝑠0 stato iniziale
δ≈ da costruire
𝐹≈ = {𝑠1}
>
Definiamo δ≈ :

δ≈ 𝑎 𝑏

𝑠0 𝑠1 𝑠0

𝑠1 𝑠1 𝑠0

δ≈(𝑠0 , 𝑎) = δ≈([𝑞0]≈ , 𝑎) = [δ(𝑞0 , 𝑎)]≈


Vediamo il diagramma degli stati di 𝐴≈

*
𝐿(𝐴≈) = {𝑎, 𝑏} 𝑎
𝐴≈ è equivalente ad 𝐴 ma cambia il numero di stati 𝐴 = 3 stati e 𝐴≈ = 2
stati.
Nella prossima lezione vedremo stati minimi e massimi per un automa.

Lezione del 28 Aprile 2022

Problema di sintesi degli automi


Abbiamo in input un linguaggio 𝐿 e dobbiamo trovare un automa 𝐴 per
𝐿. Per questo automa ricaveremo automa massimo e attraverso due
metodi successivamente ricaveremo l’automa minimo.
In particolare vedremo:
1) Com’è fatto l’automa massimo per 𝐿 ;
2) Come ottenere l’automa minimo per 𝐿 .

Automa massimo = automa con il maggior numero di stati possibili.


Automa minimo = automa con il minor numero di stati possibili.

Dall’automa massimo otteniamo l’automa minimo (nostro obiettivo).

Punto 1
Automa massimo: 𝐺𝐿
Desideriamo che quando leggo una parola l'automa mi porti in uno
stato diverso. L’idea è: per ogni parola in input raggiungo uno stato
diverso.
*
∀𝑤, 𝑤' ∈ Σ δ(𝑞0 , 𝑤) ≠ δ(𝑞0 , 𝑤') ⇒ 𝑄 = Σ (ogni parola ha il suo stato)
Inoltre, per non perdere stati, tutti gli elementi di 𝑄 devono essere
osservabili.
∀𝑞 ∈ 𝑄 ∃𝑤 : 𝑞 = δ(𝑞0 , 𝑤)
(definizione di stato osservabile)

Definizione
*
𝐺𝐿 =< Σ , 𝑄 = Σ , [ε] , δ𝐺 , 𝐹𝐺 >
𝐿 𝐿

dove
[ε] etichetta dello stato iniziale come la parola vuota ε
δ𝐺 ([𝑤] , σ) = [𝑤σ]
𝐿

𝐹𝐺 = {[𝑤] ∈ 𝑄 : 𝑤 ∈ 𝐿}
𝐿

Vediamo un esempio di automa massimo 𝐺𝐿 per il linguaggio


𝑛 𝑚
𝐿 = {𝑎 𝑏 : 𝑛, 𝑚 > 0}

Si può continuare potenzialmente all’infinito.


Punto 2
Automa minimo: 𝑀𝐿
Abbiamo due tecniche per trovare questo automa:
1) Si usa l’automa massimo 𝐺𝐿 (introdotto solo ai fini dell’automa
minimo) ;
2) Si usa un automa a stati finiti per 𝐿 e poi si trova quello
equivalente.

Prima tecnica:
Teorema
𝐺𝐿≈ è l’automa minimo per 𝐿. Cioè 𝐺𝐿≈ = 𝑀𝐿 .
Quindi devo mostrare che se ho un automa 𝐴 per 𝐿 allora |𝐴| ≥ |𝐺𝐿≈|
(numero di stati di 𝐴 è maggiore del numero di stati di 𝐺𝐿≈ ).
Per prima cosa mostriamo un fatto.
FATTO: gli stati distinguibili in 𝐺𝐿≈ sono stati distinti in 𝐴. Infatti siano [𝑥]
*
e [𝑦] due stati di 𝐺𝐿 distinguibili in esso, cioè: [𝑥] 𝑛𝑜𝑡 ≈ [𝑦] ⇒ ∃𝑤 ∈ Σ :

Allora in 𝐴:
δ(𝑞0 , 𝑥) ≠ δ(𝑞0 , 𝑦) altrimenti

Contraddizione perchè così abbiamo 𝑥𝑤 e 𝑦𝑤 appartengono o non


appartengono entrambi a 𝐿 (quindi l’automa non li riconosce).
Ora
Siano [𝑥1]≈ , [𝑥2]≈ , [𝑥3]≈ , ... gli stati di 𝐺𝐿≈ , allora gli stati [𝑥1] , [𝑥2] , [𝑥3] , ...
sono stati distinguibili in 𝐺𝐿 . In virtù del precedente fatto (appena
dimostrato) δ(𝑞0 , 𝑥1) , δ(𝑞0 , 𝑥2) , δ(𝑞0 , 𝑥3) , ... sono stati distinti in 𝐴 (dove 𝐴
è un generico automa per 𝐿) ⇒ 𝐴 ha almeno tanti stati quanti 𝐺𝐿≈
|𝐴| ≥ |𝐺𝐿≈| e quindi 𝐺𝐿 è minimo per il linguaggio 𝐿 attraverso ≈.

Seconda tecnica:
Teorema
Sia 𝐴 un automa a stati finiti per 𝐿 tale che gli stati di 𝐴 siano:
- tutti osservabili ;
- tutti distinguibili .
Allora 𝐴 è minimo per 𝐿.
Corollario
𝐴≈ è minimo per 𝐿 se 𝐴 ha tutti gli stati osservabili.
Dimostrazione del teorema
Siano {𝑞1 , 𝑞2 , ... , 𝑞𝑛} gli stati di 𝐴 (dove 𝑞1 sarà lo stato iniziale).
Vale che:
- sono tutti osservabili ;
- sono tutti distinguibili .

Sono osservabili:
Allora esistono parole {𝑤1 , 𝑤2 , ... , 𝑤𝑛} tale che ∀𝑖 𝑞𝑖 = δ(𝑞1 , 𝑤𝑖).
Sono distinguibili:
Allora esistono parole 𝑥𝑖𝑗 che distinguono gli stati

Sia 𝐴' un automa per 𝐿 con meno stati di 𝐴 (meno di 𝑛 numero di 𝐴).
(tecnica per assurdo)
Diamo in input ad 𝐴' le parole {𝑤1 , 𝑤2 , ... , 𝑤𝑛} (parole date in precedenza
ad 𝐴) si ha
Dato che ho meno stati, due parole raggiungono lo stesso stato dato
che |𝐴'| ≤ 𝑛
Secondo il principio della piccionaia (se abbiamo più piccioni che
gabbie avremo almeno una gabbia con due piccioni).
Siano 𝑤𝑖 e 𝑤𝑗 queste parole che mi portano nello stesso stato. In 𝐴'
dunque accade che:

Così ottengo che 𝑤𝑖𝑥𝑖𝑗 e 𝑥𝑗𝑥𝑖𝑗 sono entrambe ∈ 𝐿 o ∉ 𝐿 quindi 𝐴' non
riconosce parole in 𝐿 (Assurdo!!!) e infine non esiste in automa in 𝐿 con
meno stati di 𝐴

Lezione del 3 Maggio 2022

Algoritmi di sintesi ottima di automi

Sintesi ottima di automi


- Dato un linguaggio 𝐿, trovare l’automa minimo per 𝐿.
Abbiamo due tecniche:
1) Se ho 𝐴 per 𝐿 (𝐴 ha stati finiti):
a) eliminare gli stati non osservabili ;
b) costruire 𝐴≈ ;
2) Se non ho 𝐴 per 𝐿:
a) costruisco 𝐺𝐿 automa massimo ;
b) costruisco 𝐺𝐿≈ = 𝑀𝐿 .

Algoritmi
1. E’ possibile confrontare gli stati seguendo un ordine casuale ;
2. Devo applicare un algoritmo sui confronti ben preciso .

Algoritmo per 𝐺𝐿≈


● Si parte dalla radice e si visitano i nodi (stati) in ampiezza ;

● La visita di un nodo consiste nel confrontare il nodo attuale con


tutti quelli precedenti, verificando se sono indistinguibili oppure
no ;
*
● Sia [𝑤σ] (con 𝑤 ∈ Σ , σ ∈ Σ) il nodo attuale. Se accade che [𝑤σ] è
indistinguibile dal nodo [𝑥] allora:
○ cancello [𝑤σ] e il suo sottoalbero ;
○ resta pendente l'arco uscente da [𝑤] etichettato con σ .
Ridireziono l’arco verso [𝑥] .
Osservazioni:
- Lo stato iniziale resta [ε] ;
- Gli stati finali sono i sopravvissuti etichettati con parole di 𝐿 .

Due prove di esecuzione:


𝑛 𝑚
● Per 𝐿 = {𝑎 𝑏 | 𝑎, 𝑚 > 0} otteniamo un automa a stati finiti: 𝑀𝐿 per il
teorema dimostrato ;
𝑛 𝑛
● Per 𝐿 = {𝑎 𝑏 | 𝑛 > 0} otteniamo un automa con infiniti stati,
𝑛 𝑛
conseguenza: 𝑎 𝑏 non è un linguaggio regolare.

𝑛 𝑚
Costruzione di 𝐺𝐿≈ per 𝐿 = {𝑎 𝑏 | 𝑎, 𝑚 > 0} con correzioni secondo
l’algoritmo
Applicazione dell’algoritmo. Visite:
● [ε] resta ;
● [𝑎] :
○ [𝑎] 𝑛𝑜𝑡 ≈ [ε] a causa della parola "𝑏" (partendo da [𝑎] , "𝑏"
viene accettata ma non accade il viceversa);
● [𝑏] :
○ [𝑏] 𝑛𝑜𝑡 ≈ [ε] a causa della parola "𝑎𝑏" (partendo da [ε] , "𝑎𝑏"
viene accettata ma non accade il viceversa);
○ [𝑏] 𝑛𝑜𝑡 ≈ [𝑎] a causa della parola "𝑏" (partendo da [𝑎] , "𝑏"
viene accettata ma non accade il viceversa) ;
● [𝑎𝑎] :
○ [𝑎𝑎] 𝑛𝑜𝑡 ≈ [ε] a causa della parola "𝑏" (partendo da [𝑎𝑎] , "𝑏"
viene accettata ma non accade il viceversa) ;
○ [𝑎𝑎] ≈ [𝑎] indistinguibile perchè le parole lette da entrambi
gli stati vengono rifiutate o accettate allo stesso modo,
quindi cancello lo stato ed il suo sottoramo e collego l’arco
allo stato indistinguibile precedente ;
● [𝑎𝑏] :
○ è inutile confrontare uno stato finale con gli stati non finali,
dato che ci sarà sempre la parola "ε" a differenziarli ;
● [𝑏𝑎] e [𝑏𝑏] :
○ sono due stati che vengono rifiutati perchè partono da [𝑏] ,
sono indistinguibili da [𝑏] quindi essi possono essere
eliminati e i loro archi spostati verso di esso ;
● [𝑎𝑏𝑎] :
○ [𝑎𝑏𝑎] viene rifiutata a prescindere, quindi è indistinguibile da
[𝑏] (stesso procedimento di prima) ;
● [𝑎𝑏𝑏] :
○ stato indistinguibile con [𝑎𝑏] (in quanto finale) e in quanto
con "𝑏" le parole vengono accettate mentre con "𝑎" vengono
rifiutate in entrambi gli stati .

𝑛 𝑛
Costruzione di 𝐺𝐿≈ per {𝑎 𝑏 | 𝑛 > 0}
(Sono stati rimossi gli stati trappola, e quindi abbiamo solo i cammini
per gli stati terminali)

𝑛 𝑛
Da questo grafico capisco che 𝐺𝐿≈ ha stati infiniti e quindi 𝑎 𝑏 non è
regolare. Avremo quindi un ramo infinito con "𝑎" ed un ramo infinito con
"𝑏".

FATTO
𝑛 𝑛
𝑎 𝑏 non è regolare
Dimostrazione
𝑛 𝑛
- L’automa minimo 𝐺𝐿≈ per 𝑎 𝑏 ha infiniti stati ;
𝑛 𝑛
- Allora 𝑎 𝑏 non ammette un automa a stati finiti ;
- vista l’equivalenza tra automi finiti e grammatiche di tipo 3, esso
non è regolare.
Lezione del 5 Maggio 2022

Teorema
𝐿 è generato da 𝐺 di tipo 3 ⇔ 𝐿 è riconosciuto da 𝐴 a stati finiti

Dimostrazione 1
Da 𝐴 ricavo 𝐺
Sia 𝐴 = (Σ , 𝑄 , 𝑞0 , δ , 𝐹), posso definire
𝐺 = (𝑇 = Σ (insieme dei simboli terminali)
𝑉 = 𝑄 (insieme delle variabili)
𝑆 = 𝑞0 (assioma)
𝑃 (regole di produzione) :
- 𝑞 → ε ⇔ 𝑞 ∈ 𝐹 (per ogni stato finale dell’automa) ;
- 𝑞 → σ𝑝 ⇔ δ(𝑞, σ) = 𝑝 (posso mettere una regola di questo tipo se e
solo se dando σ a 𝑞 ottengo 𝑝, quindi nel diagramma degli stati,
per ogni arco possiamo inserire una regola di questo tipo).)

Correttezza della costruzione


Proprietà:
*
δ(𝑞0 , 𝑤) = 𝑝 ⇔ 𝑞0⇒ 𝑤𝑝
si dimostra per induzione
Caso base:
*
δ(𝑞0 , ε) = 𝑞0 ⇔ 𝑞0⇒ ε · 𝑞0 = 𝑞0 Vero
La prima situazione è sempre vera nell’automa mentre la seconda è
vera se consideriamo zero passi di derivazione
Passo induttivo:
Suppongo vera la proprietà per 𝑛 e lo dimostro per 𝑛 + 1.
Si consideri 𝑤σ , con |𝑤| = 𝑛 e σ ∈ Σ , quindi |𝑤σ| = 𝑛 + 1
δ(𝑞0 , 𝑤σ) = 𝑝 ⇔ δ(δ(𝑞0 , 𝑤) , σ) = 𝑝 ⇔ δ(𝑞0 , 𝑤) = 𝑞 e δ(𝑞 , σ) = 𝑝 (la prima
* *
per ipotesi e la seconda per costruzione) ⇔ 𝑞0⇒ 𝑤𝑞 e 𝑞 → σ𝑝 ⇔ 𝑞0⇒ 𝑤σ𝑝
Dimostrata

Adesso facciamo vedere l’equivalenza:


𝑤 ∈ 𝐿(𝐴) ⇔ ∃𝑞 ∈ 𝐹 e δ(𝑞0 , 𝑤) = 𝑞
*
⇔ 𝑞 → ε e 𝑞0⇒ 𝑤𝑞 ⇔
*
𝑞0⇒ 𝑤 ⇔ 𝑤 ∈ 𝐿(𝐺) quindi infine
𝐿(𝐴) = 𝐿(𝐺)
Esempio:

da 𝐴 ricavo 𝐺 di tipo 3:
𝑇 = {𝑎 , 𝑏} , 𝑉 = {𝑞0 , 𝑞1} , l’assioma è 𝑞0 ,
𝑃={
● 𝑞1 → ε ;
● 𝑞0 → 𝑎𝑞0 ;
● 𝑞0 → 𝑏𝑞1 ;
● 𝑞1 → 𝑏𝑞1 ;
● 𝑞1 → 𝑎𝑞0.
}
esempio
𝑎 𝑏 𝑏
𝑞0→ 𝑞0→ 𝑞1→ 𝑞1 (𝐴)
𝑞0 ⇒ 𝑎𝑞0 ⇒ 𝑎𝑏𝑞1 ⇒ 𝑎𝑏𝑏𝑞1 ⇒ 𝑎𝑏𝑏 (𝐺)

Dimostrazione 2
Da 𝐺 di tipo 3 ad 𝐴:
- si inverte la costruzione precedente ;
- ma 𝐺 deve essere nel formato:
- 𝐴→ε;
- 𝐴 → σ𝐵 ;
Data 𝐺 =< 𝑇 (𝑞𝑢𝑒𝑙𝑙𝑜 𝑐ℎ𝑒 𝑝𝑟𝑖𝑚𝑎 𝑐ℎ𝑖𝑎𝑚𝑎𝑣𝑎𝑚𝑜 Σ), 𝑉 , 𝑆 , 𝑃 > definisco 𝐴:
𝐴 = (Σ = 𝑇 simboli terminali
𝑄 = 𝑉 variabili
𝑞0 = 𝑆 assioma
δ è così definita:
δ(𝐴 , σ) = 𝐵 ⇔ 𝐴 → σ𝐵
𝐹 = {𝐴 | 𝐴 → ε ∈ 𝑃}
)

Esempio:
𝐺 = (𝑇 = {𝑎 , 𝑏} , 𝑉 = {𝑞1 , 𝑞2 , 𝑞0} , 𝑆 = {𝑞0} , 𝑃 =
{𝑞0 → 𝑎𝑞1 , 𝑞1 → 𝑎𝑞1 , 𝑞1 → 𝑏𝑞1 , 𝑞1 → 𝑏𝑞2 , 𝑞2 → ε} )

δ(𝑞1 , 𝑏) = ? = 𝑞1 𝑜 𝑞2 ?
NOTA: δ non può essere più considerata una funzione, quindi 𝐴 non è
un automa DETERMINISTICO (DFA) ma è NON DETERMINISTICO (NFA)

Automi a stati finiti non deterministici (NFA)


Definizione
Un NFA è un sistema
𝐴 = (Σ , 𝑄 , 𝑞0 , 𝑅 , 𝐹) dove 𝑅 è la relazione di transizione
𝑅: 𝑄 × Σ × 𝑄 → {0 , 1}
σ
𝑅(𝑞 , σ , 𝑝) = { 1 𝑠𝑒 𝑞→ 𝑝 ; 0 𝑎𝑙𝑡𝑟𝑖𝑚𝑒𝑛𝑡𝑖
esempio

Interpretazione:
𝐴 sceglie non determinatamente di transitare σ in 𝑞1 o in 𝑞2

Osservazione:
Data una parola 𝑤 in input ad 𝐴 , è possibile che induca più di un
cammino possibile
Esempio
Dove 𝑇 è uno stato trappola

Definizione
Linguaggio riconosciuto da un 𝑁𝐹𝐴: 𝐴
● 𝑤 è accettata se ammette un cammino che porta in uno stato
finale ;
● il linguaggio riconosciuto è dato dalle parole che soddisfano il
criterio di accettazione.

Lezione del 10 Maggio 2022

𝐿(𝐷𝐹𝐴) = 𝐿(𝑁𝐹𝐴)
Semplici applicazioni:
● con un 𝐷𝐹𝐴 riconosco facilmente una parola ;
● con un 𝑁𝐹𝐴 riconosco testi che contengono una certa parola.

Esempio:

(Il secondo riconosce interi testi che contengono la parola)


Esecuzioni:
- “La gatta” è accettata ;
- “Il gatto” è rifiutato (una volta arrivati al secondo stato “t” vengo
portato in uno stato trappola) ;
- “Il gatto della gatta” è accettato.
𝐿(𝐷𝐹𝐴) = la classe dei linguaggi accettati da 𝐷𝐹𝐴
𝐿(𝑁𝐹𝐴) = la classe di linguaggi accettati da 𝑁𝐹𝐴

Nota: I 𝐷𝐹𝐴 sono un caso particolare di 𝑁𝐹𝐴


Esiste 𝐿 tale che 𝐿 è accettato da un 𝑁𝐹𝐴 , ma non esiste un 𝐷𝐹𝐴 che lo
riconosce?
La risposta alla seguente domanda è NO!
In realtà entrambi i tipi di automi sono equivalenti

Teorema
Per ogni 𝐿 riconosciuto da un 𝑁𝐹𝐴 esiste un 𝐷𝐹𝐴 che lo riconosce (è
equivalente)

Corollario
𝑅3 = 𝐿(𝑁𝐹𝐴) = 𝐿(𝐷𝐹𝐴)

Dimostrazione del teorema


𝑄
Dato 𝐴 = (Σ , 𝑄 , 𝑞0 , 𝑅 , 𝐹) 𝑁𝐹𝐴 costruisco 𝐴' deterministico 𝐴'(Σ , 2
(l’insieme dei sottoinsiemi di 𝑄) , {𝑞0} , δ𝑅 , 𝐹') dove:
𝑄
𝐹' = {𝑌 ∈ 2 | 𝑌 ∩ 𝐹 ≠⊘}
𝑄 𝑄
δ𝑅 = 2 × Σ → 2 che soddisfa δ𝑅(𝑋 , σ) = ⋃ {𝑝 ∈ 𝑄 | 𝑅(𝑞 , σ , 𝑝) = 1} (Prendo
𝑞∈𝑋
𝑄
prima un elemento di 2 , sottoinsieme di 𝑄, poi cerco tra i suoi elementi
gli stati raggiunti dai propri elementi)

Esercizio

(Quando manca la transizione nel primo automa in teoria andremo in


uno stato trappola, per convenzione poi lo chiameremo come l’insieme
vuoto)
Trasformazione 𝑁𝐹𝐴 → 𝐷𝐹𝐴 con incremento esponenziale degli stati

𝑁𝐹𝐴 𝐴 il quale ha 𝑛 = 3 stati


(Questo automa si potrebbe ingrandire all’infinito)

Input: 1 0 1 0
Viene accettata
*
Nota: Data 𝑤 ∈ Σ il percorso nel 𝐷𝐹𝐴 indotto da 𝑤 simula tutti i cammini
possibili di 𝑤 nell’𝑁𝐹𝐴

Lezione del 12 Maggio 2022

Altro formalismo per i linguaggi regolari


Espressioni regolari (ER)
Questo è un altro formalismo per definire questi linguaggi, essi sono
espressioni fatte di simboli e operazioni che servono per denotare un
linguaggio. Ci sono le operazioni di prodotto e di * (Chiusura di Kleene).
Definizione
(Forma induttiva)
Una espressione regolare su Σ è:
- ⊘;
- ε;
- σ ∈ Σ.
(ER base)
Se 𝑝 e 𝑞 sono espressioni regolari allora:
- 𝑝 + 𝑞 (unione);
- 𝑝 · 𝑞;
*
- 𝑝 .
(ER complesse)
Sono espressioni regolari.

Le ER denotano dei linguaggi:

𝐸𝑅 denota Linguaggio

⊘ ⊘

ε {ε}

σ {σ}

Date le ER 𝑝 , 𝑞 che denotano 𝐿𝑝 e 𝐿𝑞 allora:

𝑝+𝑞 𝐿𝑝 ∪ 𝐿𝑞

𝑝·𝑞 𝐿𝑝 · 𝐿𝑞

* *
𝑝 𝐿𝑝

Esempi:
* *
- (𝑎 + 𝑏) 𝑎 denota {𝑎 , 𝑏} {𝑎} ;
*
- 𝐺𝑜𝑜𝑜 𝑔𝑙𝑒 denota {𝐺𝑜𝑜𝑔𝑙𝑒 , 𝐺𝑜𝑜𝑜𝑔𝑙𝑒 , 𝐺𝑜𝑜𝑜𝑜𝑔𝑙𝑒 , ...}
- Identificatori di variabili, devono rispettare una serie di regole, in
questo caso abbiamo scelto la regola “non si può iniziare il nome
della variabile con una cifra”
*
(𝐴 , 𝐵 , ... , 𝑎 , ... , 𝑧)(𝐴 , 𝐵 , ... , 𝑍 , 𝑎 , ... , 𝑧 , 0 , ... , 9) (con “,”=”+”) ;
* 2
- Importo in euro > 0 (1 + 2 +... + 9)(0 + 1 +... + 9) , (0 + 1 +... + 9) .

Teorema di Kleene
𝐿 è denotato da una ER ⇔ 𝐿 è riconosciuto da un 𝐷𝐹𝐴

(Dimostrazione costruttiva)
Dimostrazione 1
Data un'espressione regolare, creiamo un automa a stati finiti
deterministico che riconosce tale linguaggio, attraverso una
dimostrazione per induzione.
𝐿 denotato da ER ⇒ 𝐿 ammette un 𝐷𝐹𝐴
Tecnica: per induzione
Caso base
Esistono 𝐷𝐹𝐴 per ER base

Nell’automa a stati finiti per il linguaggio vuoto abbiamo un solo stato,


che qualsiasi cosa gli venga dato come input, non viene accettato, per i
simboli finisce in uno stato trappola mentre per ε rimane in uno stato
non finale.
Nel secondo caso avviene lo stesso per i simboli, mentre con epsilon si
rimane nello stato iniziale che in questo caso è anche stato finale.
Nel terzo caso abbiamo uno stato iniziale e finiamo in uno stato finale
unicamente con il simbolo σ dell’alfabeto Σ (per via dell’arco etichettato
con il suddetto simbolo).
Passo induttivo
Se esistono 𝐷𝐹𝐴 per ER 𝑝 e 𝑞 allora dimostro che esistono 𝐷𝐹𝐴 per:
- 𝑝 + 𝑞;
- 𝑝 · 𝑞;
*
- 𝑝 .
In realtà useremo le grammatiche di tipo 3
Per dimostrare questo schema dobbiamo far vedere come si
compongono 𝐺1 , 𝐺2 𝑒 𝐺3 per poi ricavarne gli automi 𝐷𝐹𝐴.
Abbiamo 2 grammatiche di tipo 3 (in una forma particolare):
𝐴 → σ𝐵
𝐴 → σ NO
𝐴→ε
𝐺' = (𝑇' , 𝑉' , 𝑆' , 𝑃')
𝐺'' = (𝑇'' , 𝑉'' , 𝑆'' , 𝑃'')
che generano
*
𝐿(𝐺') = {𝑥 ∈ 𝑇' | 𝑆' ⇒ 𝑥}
*
𝐿(𝐺'') = {𝑦 ∈ 𝑇'' | 𝑆'' ⇒ 𝑦}
𝑇' = 𝑇'' = Σ (caso particolare di queste due grammatiche)
1) Costruisco 𝐺1 per 𝐿(𝐺') ∪ 𝐿(𝐺'')
*
𝐿(𝐺') ∪ 𝐿(𝐺'') = {𝑤 ∈ Σ | 𝑤 ∈ 𝐿(𝐺') 𝑜 𝑤 ∈ 𝐿(𝐺'')}

Richiesta 𝑉' ∩ 𝑉'' =⊘


𝐺1 = (Σ , 𝑉' ∪ 𝑣'' = {𝑆1} , 𝑆1 , 𝑃' ∪ 𝑃'' ∪ {𝑆1 → 𝑆' , 𝑆1 → 𝑆''})
𝐺1 è di tipo 3?
Si, è lineare a destra:
𝐴 → 𝑥𝐵
𝐴→𝑦
*
𝑥, 𝑦 ∈ Σ
2) Costruisco 𝐺2 per 𝐿(𝐺') · 𝐿(𝐺'')
𝐿(𝐺') · 𝐿(𝐺'') = {𝑥𝑦 | 𝑥 ∈ 𝐿(𝐺') 𝑒 𝑦 ∈ 𝐿(𝐺'')}
Esempio:
𝐴 → 𝑎𝐵 𝐵 → 𝑏𝐶 𝐶 → 𝑐𝐷 𝐷 → ε
𝐴 ⇒ 𝑎𝐵 ⇒ 𝑎𝑏𝐶 ⇒ 𝑎𝑏𝑐𝐷 ⇒ 𝑎𝑏𝑐

Adesso creiamo 𝐺2
𝐺2 = (Σ , 𝑉' ∪ 𝑉'' , 𝑆' , 𝑃'\{𝐴 → ε | 𝐴 ∈ 𝑉'} ∪ 𝑃'' ∪ {𝐴 → 𝑆'' | 𝐴 → ε ∈ 𝑃'})
𝐺2 è di tipo 3?
Si!
*
3) Costruisco 𝐺3 per 𝐿(𝐺')

𝑖 +
𝐿(𝐺') = ⋃ 𝐿(𝐺') = {ε} ∪ 𝐿(𝐺')
𝑖=0

𝐺3 = (Σ , 𝑉' , 𝑆' , 𝑃' ∪ {𝐴 → 𝑆' | 𝐴 → ε ∈ 𝑃'})


+
Quella che abbiamo costruito è una grammatica per 𝐿(𝐺')
+
Se ε ∉ 𝐿(𝐺') allora dovremo aggiungere
𝑆3 → ε 𝑆3 → 𝑆'

Lezione del 17 Maggio 2022

Seconda parte della dimostrazione del teorema di Kleene


𝐿 è denotato da un’espressione regolare ⇔ 𝐿 è riconosciuto da un
automa a stati finiti
Dimostrazione di: da un 𝐷𝐹𝐴 a una ER
Dato il 𝐷𝐹𝐴 𝐴 = (Σ , 𝑄 , 𝑞0 , δ , 𝐹) , sia 𝑄 = {𝑞0 , 𝑞1 , 𝑞2 , ... , 𝑞𝑘} allora posso
associare ad 𝐴 i seguenti 𝐷𝐹𝐴 :
𝐴0 = (Σ , 𝑄 , 𝑞0 , δ , 𝐹) ,
𝐴1 = (Σ , 𝑄 , 𝑞1 , δ , 𝐹) ,
𝐴2 = (Σ , 𝑄 , 𝑞2 , δ , 𝐹) ,

𝐴𝑘 = (Σ , 𝑄 , 𝑞𝑘 , δ , 𝐹)
(Gli altri elementi sono uguali, cambia solo lo stato iniziale, cambiando
così il linguaggio riconosciuto)
● Ognuno di questi 𝐷𝐹𝐴 riconosce un linguaggio.
Sia 𝑋𝑖 il linguaggio riconosciuto da 𝐴𝑖.
Pertanto 𝐿(𝐴) = 𝐿(𝐴0) = 𝑋0

Esempio:

Vediamo subito che 𝑞2 sia uno stato trappola e che grazie a 𝑞1 per far si
che si accetti una parola abbiamo bisogno che quando compare una
𝑎 , compaia al suo seguito un’altra 𝑎 . Se ci fosse una 𝑏 in mezzo
finiremmo in uno stato trappola.
Non è facile, di base, elaborare un’espressione regolare dai seguenti
stati. A questo automa associamo 3 stati, uno per stato (il quale diventa
lo stato iniziale).
Il linguaggio che verrà riconosciuto da 𝑞2 stato trappola sarà il
linguaggio vuoto ⊘ , però noi per trovarlo useremo una serie di
procedimenti automatici.
● Adesso cerchiamo di esprimere ogni linguaggio in funzione degli
altri.
Per ottenere una ER per 𝑋0 cerco di esprimerla in funzione delle altre.
Esempio
Posso esprimere 𝑤 come σ𝑧 dato che ε non può appartenere a 𝑋1 (dato
che non è finale). Questo σ può essere sia 𝑎 , sia 𝑏.

La parola 𝑎𝑧 grazie ad 𝑎 andiamo nello stato 𝑞0 , per poi attraverso 𝑧


arrivare ad uno stato finale (quindi in pratica è come se 𝑧 appartenesse
al linguaggio 𝑋0), lo stesso vale per 𝑏𝑧 .

In generale:
𝑋𝑖 = +σ∈Σ σ𝑋𝑗 (𝑡𝑎𝑙𝑒 𝑐ℎ𝑒 δ(𝑞𝑖 , σ) = 𝑞𝑗) [+ ε (𝑠𝑜𝑙𝑜 𝑠𝑒 𝑞𝑖 ∈ 𝐹)]
Il primo simbolo è una sommatoria, con un simbolo all’inizio con il
linguaggio corrispondente allo stato raggiunto con il suddetto simbolo,
ed infine abbiamo un + ε solo se lo stato iniziale è uno stato finale.

Adesso per trovare l’espressione regolare dell’automa precedente


mettiamo a sistema il risultato dell’applicazione della formula
precedente nei tre linguaggi.

{
𝑋0 = 𝑎𝑋1 + 𝑏𝑋0 + ε

𝑋1 = 𝑎𝑋0 + 𝑏𝑋2

𝑋2 = 𝑎𝑋2 + 𝑏𝑋2
● Si ricava un sistema con 𝑘 + 1 (numero di stati di 𝐴) equazioni e
𝑘 + 1 incognite 𝑋𝑖 ;
● Per risolvere il problema devo ricorrere a equazioni del tipo:
𝑋 = 𝐴𝑋 + 𝐵 (𝑋 è l’incognita mentre 𝐴 e 𝐵 sono linguaggi) la cui
*
soluzione è 𝑋 = 𝐴 𝐵 , se ε ∉ 𝐴 allora la soluzione è unica mentre se
*
ε ∈ 𝐴 allora 𝐴 𝐵 è la minima soluzione.

Verifica della soluzione


*
𝑋 = 𝐴𝑋 + 𝐵 sostituisco ad 𝑋 : 𝐴 𝐵
* *
𝐴 𝐵 = 𝐴(𝐴 𝐵) + 𝐵

𝑖
= 𝐴(( ⋃ 𝐴 )𝐵) + 𝐵
𝑖=0

𝑖+1
= (⋃ 𝐴 )𝐵 + 𝐵
𝑖=0

𝑖
= ( ⋃ 𝐴 )𝐵 + {ε}𝐵
𝑖=1

𝑖
= ( ⋃ 𝐴 + (𝑠𝑎𝑟𝑒𝑏𝑏𝑒 ∪){ε})𝐵
𝑖=1

𝑖 *
= ( ⋃ 𝐴 )𝐵 = 𝐴 𝐵
𝑖=0
Verificato!!!

Adesso che abbiamo verificato il risultato, lo applichiamo all’ultima


equazione, la quale può essere riscritta così:
𝑋2 = (𝑎 + 𝑏)𝑋2 +⊘
Dove 𝐴 = (𝑎 + 𝑏) e 𝐵 =⊘ quindi
* *
𝑋2 = 𝐴 𝐵 = (𝑎 + 𝑏) ·⊘=⊘
Elimino quindi una variabile dal sistema sostituendo l’espressione
ricavata:
𝑋2 =⊘
𝑋1 = 𝑎𝑋0 + 𝑏𝑋2 = 𝑎𝑋0 + 𝑏 ·⊘= 𝑎𝑋0
𝑋1 = 𝐴𝑋1 + 𝐵
Dove 𝐴 =⊘ e 𝐵 = 𝑎𝑋0
* *
𝑋1 = 𝐴 𝐵 = ⊘ · 𝑎𝑋0 = ε · 𝑎𝑋0 = 𝑎𝑋0 (Qualsiasi potenza del vuoto, eccetto
la potenza 0, mi da il vuoto. Il vuoto alla zero, è un linguaggio alla zero,
che da sempre la parola vuota, quindi l’unione di tutte le potenze mi da
ε)
Adesso prendiamo la prima equazione
𝑋0 = 𝑎𝑋1 + 𝑏𝑋0 + ε
𝑋0 = 𝑎𝑎𝑋0 + 𝑏𝑋0 + ε
𝑋0 = (𝑎𝑎 + 𝑏)𝑋0 + ε
Dove 𝐴 = (𝑎𝑎 + 𝑏) e 𝐵 = ε
* * *
𝑋0 = 𝐴 𝐵 = (𝑎𝑎 + 𝑏) · ε = (𝑎𝑎 + 𝑏)
*
𝑋1 = 𝑎(𝑎𝑎 + 𝑏)

Chiusura dei linguaggi regolari


Data la classe dei linguaggi regolari, quali sono le operazioni chiuse
verso di esse?

Rispetto al complemento otteniamo sempre linguaggi regolari perchè se


abbiamo un automa a stati finiti per un linguaggio regolare, l’automa
complemento avrà stati finali e non finali invertiti, ciò non cambia lo
status del linguaggio complementato 𝐹 = 𝑄 − 𝐹 .
L’intersezione è chiusa sui linguaggi regolari dato che per la legge di De
𝑐 𝑐 𝑐 𝑐 𝑐
Morgan ((𝐴 ∪ 𝐵) ) diventa (𝐴 ∪ 𝐵 ) il quale è regolare dato che sono
solo operazioni chiuse su linguaggi regolari.

Lezione del 19 Maggio 2022


Linguaggi liberi dal contesto e grammatiche di tipo 2

Problema dell’ambiguità
Esempio in italiano:
“Il prof. dice lo studente è un asino.”
Se letta in maniera diversa possiamo intuire che il professore sia un
asino (dipende tutto dalla punteggiatura e dalla pronuncia).
Se viene letta senza entrambe non si capisce chi dei due sia un asino.

Definizione di 𝐺 ambigua:
Una grammatica è ambigua quando genera una parola ambigua, cioè
quando la parola ammette due alberi di derivazione diversi.
Nota: l’albero di derivazione dà significato alla parola (il concetto sta in
un albero che descrive la derivazione della parola, sulle foglie abbiamo
la parola, i nodi sono i metasimboli, i sottoalberi sono definiti da regole
di produzione e come radice abbiamo l’assioma).

Esempio di 𝐺 ambigua:
Grammatica per un linguaggio di programmazione “giocattolo” (atti alla
didattica).
𝑃 → 𝑖(𝑥) 𝐶 𝑜(𝑥)
Simbolo iniziale 𝑃 di programma che produce 𝑖(𝑥) input, 𝐶 comando e
𝑜(𝑥) output. In questi programmi abbiamo solo la variabile 𝑥.
𝐶 → 𝐴|𝐼|𝐸
I comandi possibili sono 3:
1) 𝐴 di assegnamento ;
2) 𝐼 comando 𝐼𝑓() 𝑇ℎ𝑒𝑛() senza 𝐸𝑙𝑠𝑒, quindi esegue un comando
verificando la condizione, nel caso sia falsa non accade nulla ;
3) 𝐸 comando 𝐼𝑓() 𝑇ℎ𝑒𝑛() 𝐸𝑙𝑠𝑒() con due comandi a seconda dei casi
possibili.
𝐴 → 𝑥 =− 1 · 𝑥
Abbiamo la sostituzione 𝑥 =− 1 · 𝑥 , quindi viene cambiato il segno alla
variabile e viene assegnata ad essa.
𝐼 → 𝑖𝑓(𝑇) 𝐶
In questo comando 𝑇 ha la funzione di “Test”
𝐸 → 𝑖𝑓(𝑇) 𝐶 𝑒𝑙𝑠𝑒 𝐶
In quest’altro caso abbiamo due comandi a seconda dei casi.
𝑇→𝑥 < 0
Unico test possibile
𝐺 genera la seguente parola: (programmino)
𝑖(𝑥) 𝑖𝑓(𝑥 < 0) 𝑖𝑓(𝑥 < 0) 𝑥 =− 1𝑥 𝑒𝑙𝑠𝑒 𝑥 =− 1𝑥 𝑜(𝑥)
La quale ammette due alberi di derivazione per due programmi
differenti α e β .
Programma α
Programma β

Il primo programma ha come primo comando un 𝐼𝑓() 𝐸𝑙𝑠𝑒() mentre nel


secondo il primo comando è 𝐼𝑓() (Abbiamo un'inversione tra 𝐼 ed 𝐸).
Proviamo ad inserire come input una 𝑥 positiva e una negativa a
entrambi i programmi:
- Caso α :
- 𝑥 positiva, eseguo il secondo ramo del primo comando,
quindi 𝑥 diventa negativa ;
- 𝑥 negativa, eseguo il primo ramo del primo comando, viene
eseguito il test (di nuovo) e viene eseguito di nuovo il
comando per rendere 𝑥 negativa ;
- Caso β :
- 𝑥 positiva, entriamo nel primo controllo del primo comando,
dato che il test non va a buon fine il programma da in
output 𝑥 senza cambiamenti;
- 𝑥 negativa, entriamo nel primo controllo, dato che viene
verificato entriamo nel secondo controllo, il quale trasforma
la 𝑥 e la fa diventare negativa.

L’albero dà significato alla parola, in questo caso associa la funzione


calcolata dal programma.

In conclusione il programma è ambiguo e 𝐺 è ambigua.

Definizione
Una grammatica 𝐺 è non ambigua se ogni parola generata non è
ambigua.
Osservazione
A volte è possibile disambiguare una grammatica.
Nel nostro caso possiamo usare una convenzione:
“L’else è associato all’if più vicino”.
A volte no!

Definizione
Un linguaggio si dice “Inerentemente ambiguo” quando ogni 𝐺 che lo
genera è ambigua.
Esempio:
𝑖 𝑗 𝑘
{𝑎 𝑏 𝑐 | 𝑖 = 𝑗 𝑜 𝑗 = 𝑘}
Nota: è di tipo 2
Idea:

𝑛 𝑛 𝑛
𝑎 𝑏 𝑐 ammetterà due alberi di derivazione diversi.
Non c'è modo di trovare una grammatica per generare una grammatica
con regole di produzione diverse e non ambigua.

Domanda:
Un linguaggio regolare può essere inerentemente ambiguo?
Risposta:
NO
Dimostrazione
Ad ogni 𝐿 regolare corrisponde un 𝐷𝐹𝐴. Da tale 𝐷𝐹𝐴 si ricava una 𝐺 di
tipo 3 che è non ambigua.

Derivazioni leftmost
Dato un albero di derivazioni (con più derivazioni associate), attraverso
questo metodo di derivazione viene espanso per primo il metasimbolo
più a sinistra.

Esempio
𝑎𝑏𝑏𝐴𝑎𝐵𝐶
Espandiamo prima 𝐴 poi 𝐵 e infine 𝐶 (se 𝐴 contiene altri metasimboli
espandiamo quello più a sinistra al proprio interno).
Ad ogni albero di derivazione è associata un'unica derivazione leftmost,
quindi si può in qualche modo eludere l’ambiguità.

Forme normali per 𝐺 di tipo 2 (senza ε)

A seconda di come è fatto β variano tra le due classificazioni


𝐹𝑁𝐶 𝐹𝑁𝐺

𝐴 → 𝐵𝐶 𝐴 → σ𝑊

𝐴→σ

𝐴, 𝐵, 𝐶 ∈ 𝑉 𝐴∈𝑉

σ∈𝑇 σ∈𝑇
*
𝑊 ∈𝑉

La forma normale di Chomsky serve per dimostrare il Pumping Lemma


(ultima lezione) mentre quella di Greibach serve per dimostrare
l’equivalenza degli automi a pila (prossima lezione).

Esempio
𝐺 =< {𝑥 , 𝑦 , + , ( , )} , {𝐸} , 𝑃 , 𝐸 > dove
𝑃 = {𝐸 → (𝐸 + 𝐸) | 𝑥 | 𝑦}
Ricaviamo FNC e FNG
FNG:
𝐸 → 𝑥 ok
𝐸 → 𝑦 ok
𝐸 → (𝐸 + 𝐸) NO!!!
𝐸 → (𝐸𝑃𝐸𝐷 ok
𝑃 → + ok
𝐷 →) ok
FNC:
𝐸 → 𝑥 ok
𝐸 → 𝑦 ok
𝐸 → (𝐸 + 𝐸) NO!!!
𝐶 → ( ok
𝑃 → + ok
𝐷 →) ok
𝐸 → 𝐶𝐸𝑃𝐸𝐷 NO!!!
𝑋 → 𝐶𝐸 ok
𝑌 → 𝑃𝐸 ok
𝐸 → 𝑋𝑌𝐷 NO!!!
𝑍 → 𝑋𝑌 ok
𝐸 → 𝑍𝐷 ok

Lezione del 24 Maggio 2022

Riconoscitori a pila
Automi a pila per i linguaggi di tipo 2.
Sono un dispositivo composto da 2 parti hardware, nella prima
abbiamo la parola da controllare inserita in un nastro di input simbolo
per simbolo. Questo nastro è suddiviso in celle con in ognuna un
simbolo appartenente all’alfabeto di input Σ. Su questo nastro abbiamo
anche una testina di lettura che scandisce la parola e si sposta tra i
simboli.

La seconda parte di hardware è costituita da una memoria, indicata da


una pila (dispositivo di memoria dove gli elementi vengono messi uno
sopra l’altro). Nella memoria abbiamo un altro alfabeto 𝐾. L’elemento
più in basso è 𝑧 e quello più in alto è 𝑥. Quando si legge nella pila, si
parte da quello più in alto (in questo caso 𝑥).
Definizione di Pila
Memoria ad accesso limitato (con una serie limitata di elementi
dell’alfabeto 𝐾), con politica di accesso: LIFO (last in first out). L’ultimo
elemento inserito è il primo da leggere e da rimuovere dalla pila. Si
discosta dalla politica FILO (first in last out) per le memorie a coda.

Notazione:
Disegnare la pila se possibile e descriverne il contenuto.

Operazioni di modifica della pila:


PUSH

POP

Formalizzo:
𝑃𝑈𝑆𝐻(𝑃 , 𝑋) = 𝑋𝑃
L'immagine di questa funzione è la pila modificata con a capo
l’elemento rimosso. Come variabili abbiamo la pila e l’elemento più in
alto.
𝑃𝑂𝑃(𝑃) = 𝑊 se 𝑃 = 𝑋𝑊 mentre 𝑃𝑂𝑃(𝑃) =⊥ se 𝑃 = ε
Come variabili abbiamo solo la pila. L’immagine è ciò che rimane dalla
pila dopo l’estrazione, è 𝑤 se nella pila avevamo il carattere 𝑥 seguito da
una serie di caratteri 𝑤, mentre l’operazione non va a buon fine se la
pila era vuota.

Operazioni di interrogazione della pila:


TOP

ISEMPTY

Formalizzo:
𝑇𝑂𝑃(𝑃) = 𝑋 se 𝑃 = 𝑋𝑊 mentre 𝑇𝑂𝑃(𝑃) =⊥ se 𝑃 = ε
Prende come variabile la pila e restituisce l’elemento più in alto. Se la
pila è vuota non va a buon fine.
𝐼𝑆𝐸𝑀𝑃𝑇𝑌(𝑃) = 1 se 𝑃 = ε mentre 𝐼𝑆𝐸𝑀𝑃𝑇𝑌(𝑃) = 0 se 𝑃 ≠ ε
Prende in input una pila e restituisce 1 se essa è vuota, mentre
restituisce 0 se non lo è.

Definizione di riconoscitore a pila


(Usiamo i riconoscitori invece che gli automi a pila perchè sono più
semplici e più funzionali per il riconoscimento di grammatiche di tipo 2)
Un riconoscitore a pila è una tupla:
𝐴 = (Σ , 𝐾 , 𝑆 , δ) dove:
- Σ è l'alfabeto di input ;
- 𝐾 è l’alfabeto della pila (Σ ∩ 𝐾 =⊘);
- 𝑆 è il simbolo iniziale della pila ;
*
𝐾
- δ funzione di evoluzione della pila δ: 𝐾 × Σ → 2 (parole con
*
elementi di 𝐾 ) con la scrittura:
*
- δ(𝑋, σ) = {𝑊1 , 𝑊2 , ... , 𝑊𝑠} con 𝑊𝑖 ∈ 𝐾
Con questa scrittura si indica che:
● 𝑋 è letto in cima alla pila (TOP) ;
● σ è letto sul nastro di input ;
● 𝑋 viene cancellato dalla pila (POP) ;
● viene scelto un 𝑊𝑖 NON DETERMINISTICAMENTE da inserire nella
pila (PUSH);

Grafo di computazione dovuto a


𝑥 = 𝑥1𝑥2... 𝑥𝑛 ←Input

Abbiamo la pila iniziale, una volta inseriti man mano i simboli della
parola del nastro la pila viene modificata in tutti i modi possibili
secondo la funzione δ. Possiamo considerare le pile secondo i “livelli” ,
cioè il numero di simboli inseriti. Il modo in cui cambiano le pile è
attraverso una scelta non deterministica.
La computazione secondo la parola è una delle pile del livello finale.
La parola 𝑥1𝑥2... 𝑥𝑛 è accettata oppure no?

Criterio di accettazione
La parola 𝑥 si dice accettata se nel grafo di computazione di 𝑥 esiste un
cammino che partendo dalla pila 𝑆 mi porta ad una pila vuota (ε).
Controlleremo tramite ISEMPTY.
Formalizzo:
Configurazione
𝑃𝐼𝐿𝐴 · 𝐼𝑁𝑃𝑈𝑇 (parte di input ancora da leggere)
Esempi
𝑆 · 𝑥 configurazione iniziale
ε · ε configurazione finale accettante (finale perchè ho ε al posto di 𝑥 e
accettante perchè ho ε al posto di 𝑆)

Passo di computazione
Configurazione | − configurazione successiva
Scriveremo:
𝑋𝑊 · σ𝑤| − Υ𝑊 · 𝑤 ⇔ Υ ∈ δ(𝑋 , σ)

Linguaggio riconosciuto da 𝐴
* *
𝐿(𝐴) = {𝑥 ∈ Σ | 𝑆 · 𝑥| − ε · ε}
dove
*
| − è: zero o più passi di derivazione

Esempio:
𝑅
Linguaggio: 𝑤𝑤 ← palindrome
𝑤 = 𝑤1𝑤2... 𝑤𝑛
𝑅
𝑤 = 𝑤𝑛𝑤𝑛−1... 𝑤1
es: 𝑎𝑏𝑏𝑏𝑏𝑎
Idea:
Quando raggiungo la metà della parola, confronto la seconda con i
simboli nella pila cancellandoli man mano.
Problema:
Come riconoscere il centro della parola in input?
Risposta:
Si usa il non determinismo

Cima della pila


𝑆: siamo nella prima fase, ovvero inserimento dei simboli nella pila
𝐴 , 𝐵: siamo nella seconda fase ovvero confronto dei simboli di input con
il contenuto della pila.

δ 𝑎 𝑏

𝑆 {𝑆𝐴 , 𝐴} {𝑆𝐵 , 𝐵}

𝐴 ε -

𝐵 - ε

Dove - sta per “errore”

Grafo di computazione di 𝑎𝑏𝑏𝑎.


Lezione del 26 Maggio 2022

Domanda:
Qual’è la classe dei linguaggi riconosciuti dai riconoscitori a pila?
Risposta:
I linguaggi di tipo 2.
Attenzione:
Il modello dei riconoscitori a pila deve essere NON DETERMINISTICO:
*
𝐾 *
δ: 𝐾 × Σ → 2 e non 𝐾 |
Infatti:
Teorema
𝐿 è generato da 𝐺 di tipo 2 ⇔ 𝐿 è riconosciuto da un riconoscitore a pila.
Lo stesso vale per gli automi a pila, con un riconoscitore a stati che
muove la testina di input cambiando ogni volta lo stato corrente, alla
fine il riconoscitore può decidere di accettare o a pila vuota o
controllando se lo stato raggiunto sia finale.
La dimostrazione di questo teorema è costruttiva in entrambi i sensi.

Dimostrazione 1
Da 𝐴 riconoscitore a pila a 𝐺 di tipo 2
Sia 𝐴 = (Σ , 𝐾 , 𝑆𝐴 , δ) posso costruire 𝐺 di tipo 2:
𝐺 = (𝑇 = Σ
𝑉=𝐾
𝑆 = 𝑆𝐴
𝑃 contiene la regola:
𝑋 → σ𝑊 ⇔ 𝑊 ∈ δ(𝑋 , σ)
)

Esempio:
𝑅
𝐿 = 𝑤𝑤 su Σ = {𝑎 , 𝑏}
𝐴 = ({𝑎 , 𝑏} , {𝐴 , 𝐵 , 𝑆} , 𝑆 , δ)
dove

δ 𝑎 𝑏

𝑆 {𝑆𝐴 , 𝐴} {𝑆𝐵 , 𝐵}

𝐴 ε -

𝐵 - ε
𝐺 = (𝑇 = {𝑎 , 𝑏}
𝑉 = {𝐴 , 𝐵 , 𝑆}
𝑆 è l’assioma
𝑃 = {𝑆 → 𝑎𝑆𝐴 , 𝑆 → 𝑎𝐴 , 𝑆 → 𝑏𝑆𝐵 , 𝑆 → 𝑏𝐵 , 𝐴 → 𝑎 , 𝐵 → 𝑏}
)
La 𝐺 ottenuta è la forma normale di Greibach di:
𝑆 → 𝑎𝑆𝑎 , 𝑆 → 𝑎𝑎 , 𝑆 → 𝑏𝑆𝑏 , 𝑆 → 𝑏𝑏

Dimostrazione 2
Da 𝐺 di tipo 2 ad 𝐴 riconoscitori a pila.
Avendo una 𝐺 di tipo 2 dobbiamo per prima cosa trasformarla in forma
normale di Greibach:
𝐺 → 𝐺' = (𝑇 , 𝑉 , 𝑆𝐺' , 𝑃).
Costruisco 𝐴 = (Σ = 𝑇
𝐾=𝑉
𝑆 = 𝑆𝐺'
δ così definita:
δ(𝑋 , σ) = {𝑊 | 𝑋 → σ𝑊 ∈ 𝑃}
)

Esempio
𝑛 𝑛
𝐿 = {𝑎 𝑏 | 𝑛 > 0}
𝐺 per 𝐿 : 𝑆 → 𝑎𝑆𝑏 , 𝑆 → 𝑎𝑏
Trasformo 𝐺 in 𝐺' di Greibach:
𝑆 → 𝑎𝑆𝑏 diventa:
𝑆 → 𝑎𝑆𝐵 e 𝐵 → 𝑏
𝑆 → 𝑎𝑏 diventa:
𝑆 → 𝑎𝐵 con la regola 𝐵 → 𝑏 già esistente
Definisco
𝐴 = ({𝑎 , 𝑏} , {𝑆 , 𝐵} , 𝑆 , δ)
dove

δ 𝑎 𝑏

𝑆 {𝑆𝐵 , 𝐵} -

𝐵 - ε

𝑛 𝑛
Attenzione: non è il miglior riconoscitore per 𝑎 𝑏 (dato che quello che
abbiamo trovato è non deterministico), infatti ne esiste uno
deterministico:
𝐴' = ({𝑎 , 𝑏} , {𝑆 , 𝐴 , 𝐵} , 𝑆 , δ) dove
δ 𝑎 𝑏

𝑆 𝐴 -

𝐴 𝐴𝐵 ε

𝐵 - ε

Note:
𝐴 in cima:
sono nella prima metà e inserisco in cima una 𝐵
𝐵 in cima:
sono nella seconda metà e cancello le 𝐵 dalla pila
Esempio: 𝑎𝑎𝑎𝑏𝑏𝑏

Osservazione:
senza il simbolo 𝐴 , 𝑎𝑎𝑎𝑏𝑏𝑎𝑏𝑏 verrebbe accettata!
𝑛 𝑛
#𝑎 = #𝑏 ma non nel formato 𝑎 𝑏

Riassumendo:
Dimostrazione, idea
𝐿 ∈ 𝑅3 → esiste 𝐴 𝐷𝐹𝐴 → simulo 𝐴 usando la pila: metto lo stato nella pila*
*”ISEMPTY” viene sostituito da “ISFINALSTATE”!

Alberi binari
Forma normale di Chomsky
𝐴 → 𝐵𝐶
𝐴→σ
si hanno alberi di derivazione binari
es: 𝑆 → 𝐴𝐵 𝑆 → 𝐶𝐵 𝐶 → 𝐴𝑆 𝐴 → 𝑎 𝐵 → 𝑏

Albero di derivazione per 𝑎𝑎𝑏𝑏

Relazione:
𝑛 = numero di foglie
ℎ = altezza

In generale ho:

𝑛 ≤ 2 da cui:
𝑙𝑜𝑔𝑛 ≤ ℎ
Questa relazione ci servirà per dimostrare la correttezza del PUMPING
LEMMA

Lezione del 31 Maggio 2022

Pumping Lemma
Strumento utile per dimostrare che i linguaggi non sono di una
determinata grammatica. Ne abbiamo uno per linguaggi regolari ed
uno per i linguaggi liberi da contesto. Vedremo solo quelli per i
linguaggi di tipo 2.
Esprime una condizione necessaria (non sufficiente, quindi non
possiamo dire che 𝐿 sia di tipo 2 ma possiamo verificare che non lo sia)
per i linguaggi di tipo 2.

Nota:
- 𝐿 non soddisfa il lemma ⇒ 𝐿 non è di tipo 2 ;
- 𝐿 soddisfa il lemma ⇒ 𝐿 può essere di tipo 2 (non certo).

Enunciato
Per ogni 𝐿 di tipo 2 esiste una costante 𝐻 > 0 tale che:
per ogni 𝑧 ∈ 𝐿 con |𝑧| > 𝐻 esiste una scomposizione in
𝑢𝑣𝑤𝑥𝑦 = 𝑧 (scompone la parola di una certa lunghezza del linguaggio in
5 fattori con 𝑤 fattore centrale)
che soddisfa:
1) |𝑣𝑥| ≥ 1 (se prendo il secondo ed il penultimo fattore e li metto
vicini essi devono avere lunghezza ≥ 1 , quindi almeno uno dei
due è un simbolo) ;
2) |𝑣𝑤𝑥| ≤ 𝐻 (la lunghezza della parte centrale della scomposizione
deve essere minore o uguale ad 𝐻) ;
𝑘 𝑘
3) ∀ 𝑘 > 0 𝑢𝑣 𝑤𝑥 𝑦 ∈ 𝐿 (abbiamo tante parole simili nella seguente
forma nel linguaggio) .

Dimostrazione
Per dimostrarlo prendiamo ogni frase e dettaglio dell’enunciato e
vediamo le implicazioni.
- “Per 𝐿 di tipo 2 esiste 𝐻 > 0” ;
Se 𝐿 è di tipo 2 allora ammette una 𝐺 in forma normalizzata di Chomsky.
ℎ+1
Fisso quindi 𝐻 = 2 dove ℎ = numero di variabili in 𝐺.
- “per ogni 𝑧 ∈ 𝐿 tale che |𝑧| > 𝐻” ;
Dato che 𝐿 è di tipo 2, allora 𝑧 viene creato da un albero binario e quindi
segue le regole descritte nella lezione precedente:
𝑛 = numero di foglie
ℎ = altezza

𝑛 ≤ 2 da cui:
𝑙𝑜𝑔𝑛 ≤ ℎ
Quindi:

𝑎𝑙𝑡𝑒𝑧𝑧𝑎 ≥ 𝑙𝑜𝑔 |𝑧| ≥ 𝑙𝑜𝑔 𝐻 = ℎ + 1


- “esiste una scomposizione di 𝑧 in 𝑢𝑣𝑤𝑥𝑦” ;
si ricava dall’albero di derivazione per 𝑧 :

Sui rami non trovo più 𝑧 ma direttamente la scomposizione in 5 fattori.


● considero
○ il ramo più lungo dell’albero ;
● risalgo
○ dal fondo di ℎ + 1 nodi (etichettati da variabili, ma dato che
le variabili sono ℎ e risalgo fino al nodo ℎ + 1 esimo troverò
almeno una ripetizione) ;
● per il principio della piccionaia due nodi sono etichettati con la
stessa variabile che chiameremo: "𝐴" ;
● la scomposizione si ricava da questi due nodi, la prima e la
seconda occorrenza di 𝐴 (𝐴 𝐼 𝑒 𝐴 𝐼𝐼) , staccando il primo sottoalbero
con radice 𝐴 𝐼 ottengo sulle foglie 𝑤𝐴 𝐼𝑦 mentre staccando il
secondo sottoalbero con radice 𝐴 𝐼𝐼 ottengo un sottoalbero con
foglie 𝑣𝐴 𝐼𝐼𝑥 ed infine i simboli che compongono 𝑤 sono generati
da 𝐴 𝐼𝐼 .

- “la scomposizione soddisfa 1) 2) 3)” :


Condizione 1
|𝑣𝑥| ≥ 1 𝑣 e 𝑥 non possono essere contemporaneamente ε perchè 𝐴 𝐼 e
𝐴 𝐼𝐼 sono distinti (vero per come abbiamo composto l’albero di
derivazione in modo da rendere quelle due variabili non sovrapponibili
e distinte).
Condizione 2
|𝑣𝑤𝑥| ≤ 𝐻
si ha:
ℎ' ℎ+1
|𝑣𝑤𝑥| ≤ 2 (ℎ' altezza del sottoalbero) ≤ 2 = 𝐻
Verificata.
Condizione 3
𝑘 𝑘
∀ 𝑘 ≥ 0 𝑢𝑣 𝑤𝑥 𝑦 ∈ 𝐿
Ritaglio dell’albero

* * *
𝑆⇒ 𝑢𝐴𝑦 𝐴⇒ 𝑣𝐴𝑥 𝐴⇒ 𝑤

Caso 𝑘 = 0 :
devo mostrare che 𝑢𝑤𝑦 ∈ 𝐿
* *
𝑆⇒ 𝑢𝐴𝑦⇒ 𝑢𝑤𝑦

Caso 𝑘 > 0
devo mostrare che 𝑢𝑣𝑣... 𝑣𝑤𝑥𝑥... 𝑥𝑦 ∈ 𝐿 (𝑣 e 𝑥 si ripetono 𝑘 volte)

* * * * * 𝑘 𝑘 * 𝑘 𝑘
𝑆⇒ 𝑢𝐴𝑦⇒ 𝑢𝑣𝐴𝑥𝑦⇒ 𝑢𝑣𝑣𝐴𝑥𝑦⇒ ... ⇒ 𝑢𝑣 𝐴𝑥 𝑦⇒ 𝑢𝑣 𝑤𝑥 𝑦

Applicazione del pumping lemma


Fatto:
𝑛 𝑛 𝑛
𝑎 𝑏 𝑐 non è di tipo 2
Dimostrazione
Considero la parola
𝐻 𝐻 𝐻
𝑧 = 𝑎 𝑏 𝑐 , |𝑧| = 3𝐻 > 𝐻 e faccio vedere che qualunque sua
scomposizione in 𝑢𝑣𝑤𝑥𝑦 non soddisfa contemporaneamente 1) , 2) , 3) .
𝑧 = 𝑎𝑎... 𝑎𝑏𝑏... 𝑏𝑐𝑐... 𝑐
Prendiamo come 𝑣𝑤𝑥 =... 𝑎𝑏𝑏... 𝑏𝑐...
Per 𝑣𝑤𝑥 si hanno i seguenti casi:
● 𝑣𝑤𝑥 contiene sia 𝑎 , 𝑏 , 𝑐 ;
● 𝑣𝑤𝑥 contiene 𝑎 , 𝑏 o 𝑏 , 𝑐 (non consideriamo la seconda opzione per
simmetria) ;
● 𝑣𝑤𝑥 contiene 𝑎 o 𝑏 o 𝑐 (non consideriamo la seconda e la terza
opzione per simmetria) ;
Studiamo i casi:
Primo caso
𝑣𝑤𝑥 = 𝑎𝑏𝑏... 𝑏𝑐 quindi |𝑣𝑤𝑥| > 𝐻
La condizione 2 è falsa
Secondo e terzo caso
In entrambi questi casi sia che contenga 𝑎 , 𝑏 , sia che contenga 𝑎 esso
non contiene le "𝑐"
Considero:
𝑘 𝑘
𝑢𝑣 𝑤𝑥 𝑦 ∈ 𝐿
(Cioè che la condizione 3 sia vera)
𝑘 𝑘
allora |𝑢𝑣 𝑤𝑥 𝑦| (dato che il numero di "𝑐" è 𝐻) = 3𝐻 (dato che
𝐻 𝐻 𝐻
𝑢𝑣𝑤𝑥𝑦 = 𝑎 𝑏 𝑐 ) = |𝑢𝑣𝑤𝑥𝑦|
da cui si ottiene che non vale la condizione 1 dato che in questo caso
𝑣 = 𝑥 = ε per far si che si verifichi la condizione 3 e la formula espressa
precedentemente.

Potrebbero piacerti anche