Sei sulla pagina 1di 8

La Bibbia di LFA

(Autori: Mafidyuz, Palmastizio, Mongermonkey)

Alfabeto: Insieme finito di simboli Σ={a1, a2, … , an}

Parola: (o stringa) su un alfabeto Σ è una sequenza finita di simboli appartenenti a Σ

Σ* = Insieme delle parole su Σ compresa ε

Σ + = Insieme delle parole su Σ senza ε

Date le parole x, y diremo che x è prefisso di y se y=x·z per qualche z, x è suffisso di y se


y=zx per
qualche z, x è fattore di y se y=z·x·w per qualche z e w.

Linguaggio formale: Un linguaggio L sull’alfabeto Σ è un insieme di parole di Σ*, cioè un


qualunque sottoinsieme (finito o infinito) L ⊆ Σ*.

Operazioni tra linguaggi


Unione: A ∪ B = {w ∈ Σ* |  w ∈ A  ∨  w ∈ B}
Intersezione:A ∩ B = {w ∈ Σ* |  w ∈ A  ∧  w ∈ B}
Complemento: A c = {w ∈ Σ* |  w ∉ A}
Prodotto: dati i linguaggi L1 e L2 sull’alfabeto Σ , il loro prodotto è il linguaggio L1 · L2 =
{w ∈ Σ| w= xy , con x ∈ L1 e y ∈ L2 }
Potenza: Poiché il prodotto è associativo, possiamo definire la potenza L k, dove L0 = { ε }
e
Lk+1= Lk ⋅ L
Chiusura di Kleene: dato un linguaggio L, la sua chiusura è il linguaggio

L* = L 0 ∪ L 1 ∪ . . . ∪ L k ∪ . . . = ∪ L k
k=0

L+ = ∪ Lk
k=1
n n−1 0
dove L =L⋅L e, per convenzione, L = ε.

Codice: Un linguaggio L è un codice quando ogni parola in L +è ottenuta in un unico modo


come prodotto di parole di L

Codice prefisso: L è un codice prefisso quando è un codice e ogni parola in L non è


prefisso di altre parole in L

nota bene: il concetto di procedura è quello intuitivo: una procedura non è altro che una
sequenza finita di passi che può o meno terminare con un risultato.

La scrittura Fw(x) indica il risultato dell’esecuzione della procedura w su input x:


Fw(x) indica che la procedura w su input x termina;

In particolare, si ha il caso  Fw(x) = 1 se la procedura dà in uscita 1, mentre  Fw(x) = 0


se la procedura dà in uscita 0;
Fw(x) indica che la procedura w su input x genera una computazione che non termina
(un loop).

Algoritmo: un algoritmo è semplicemente una procedura w che su qualsiasi ingresso x


genera una computazione che termina (dando come risultato, nel nostro caso, 0 oppure
1).

Linguaggio ricorsivo: Un linguaggio L è detto ricorsivo(o decidibile) se esiste un algoritmo


w tale che
 Fw(x) = 1 se x ∈ L,  0 se x ∉ L; tale algoritmo è anche detto riconoscitore, e calcola
dunque la
Funzione caratteristica del linguaggio L, cioè la funzione χLtale che χL (x)= 1 se x ∈ L, 0
altrimenti. (ammette un sistema riconoscitivo: automa)

Linguaggio ricorsivamente numerabile: Un linguaggio L è detto ricorsivamente


numerabile(o semidecidibile) se esiste una procedura w tale che Fw(x) = 1 se x ∈ L,
mentre Fw(x) altrimenti. (ammette un sistema generativo: grammatica)

Teorema: L r icorsivo  ⇒ L c r icorsivo


Infatti, se L è ricorsivo esisterà un algoritmo w tale che Fw(x) = 1 se x ∈ L, mentre
Fw(x) = 0 se x ∉ L; possiamo costruire allora un algoritmo w2 tale che, su input x,
calcola Fw(x) e, se w ritorna 1, w2 ritorna 0, mentre se w ritorna 0, w2 ritorna 1.

Teorema: L r icorsivo  ⇒ L r icorsivamente numerabile


Infatti se L è ricorsivo esiste un algoritmo w che calcola la sua funzione caratteristica;
costruiamo ora una nuova procedura che prima simula w e poi, se l’uscita è 0, genera una
computazione che non termina. Questo prova che L è anche ricorsivamente numerabile.
Questo fa notare il fatto che un algoritmo può sempre essere peggiorato in una procedura.

L r icorsivamente numerabile  ⇒ L r icorsivo? NO


Infatti non è possibile sostituire una computazione che non termina con una che termina e
dà come risultato 0.
Dunque esistono linguaggi che sono ricorsivamente numerabili, ma non ricorsivi. Per dare
un esempio è necessario richiamare il concetto di interprete.

Interprete: un interprete è un programma u che accetta in ingresso due parole x, w ∈


{0,1}* (due parole binarie) e simula l’esecuzione della procedura codificata con w su input
x; in simboli:
Fu(x$w)  = Fw(x) se w è un program m a         Fu(x$w)  =   ⊥  altr imenti
Ciò è possibile in quanto w è sia un programma(semanticamente) sia una parola
binaria(sintatticamente).
nota bene: l’esempio di linguaggio ricorsivamente numerabile ma non ricorsivo fatto dalla
prof. Palano è il seguente: L = {x : Fu(x $ x) }
cioè il linguaggio L delle parole tali per cui l’esecuzione della procedura codificata
binariamente nella parola stessa, avendo in input la parola stessa, termina. Il linguaggio è
detto:

Linguaggio dell’arresto ristretto: D = {x ∈ {0,1}* |  Fu(x $ x) }

Il suo complemento: D c = {x ∈ {0,1}* |  Fu(x $ x) }


Proprietà:
● D è ricorsivamente enumerabile
● D non è ricorsivo
● D cnon è ricorsivamente enumerabile

Attenzione: ciò che segue è probabilmente inutile per l’esame


(confermato inutile)
Sistema Formale / Calcolo logico: Un Calcolo logico è dato da una funzione che permette
di “dimostrare” tutte e sole le affermazioni vere(f) di un linguaggio L; tali
dimostrazioni(d) devono necessariamente poter essere descritte da parole del linguaggio,
così da dare un senso(vero oppure falso) alla frase:
“d è la dimostrazione di f”.
Un Calcolo logico è dato quindi da una funzione V : Σ* × U* → {0,1}, calcolabile da un
algoritmo A (esiste cioè un algoritmo A che, avendo in ingresso le parole x e d, dà in uscita
1 se V(x,d) = 1, 0 se V(x,d) = 0 ), dove:
Σ* è l’insieme di tutte le parole costruibili sull’alfabeto Σ del linguaggio L;
U*è l’insieme delle potenziali dimostrazioni.
(L’esistenza dell’algoritmo A soddisfa la richiesta che sia possibile verificare in un numero
finito di passi se d è la dimostrazione di x oppure no.)

Calcolo logico corretto: dato un linguaggio L ⊆ Σ*, il calcolo logico V è detto corretto
per L
se V(x, d ) = 1  ⇒ x ∈ L.
Questa condizione viene detta correttezza del calcolo perché, se x ammette una
dimostrazione d nel
calcolo, allora x deve appartenere a L. (V fa quello che deve fare)

Calcolo logico completo: dato un linguaggio L ⊆ Σ*, Il calcolo logico V è detto completo
per L
se ∀x ∈ L    ∃d ∈ U* tale che V(x, d ) = 1.
Questa condizione viene detta completezza del calcolo perché garantisce che, quando
x∈L, è sempre
possibile trovarne una dimostrazione d nel calcolo. (lo fa per ogni parola)

Calcolo logico per il linguaggio L: dato un linguaggio L ⊆ Σ*, un calcolo logico per L è un
calcolo logico V corretto e completo per L. In tal caso sarà L = {x  |   ∃d  V(x, d )  =  1}.
Teorema: L am met te un calcolo logico  ⇔  L è r icorsivamente numerabile

Grammatica: una grammatica G è una quadrupla <Σ, Q, P, S> dove:


1. Σ e Q sono due alfabeti finiti disgiunti, rispettivamente di simboli terminali e
metasimboli;
2. P è un insieme finito di regole di produzione;
3. S è un elemento in Q, detto assioma o simbolo di partenza.
I simboli terminali (o semplicemente simboli) sono i simboli dei quali sono composte le
parole del linguaggio; i metasimboli, o simboli non terminali, sono invece i simboli
utilizzati per generare il linguaggio, ma che non fanno parte del linguaggio.
Una regola di produzione è una coppia α→β di parole con α∈( Σ ∪ Q)+ e β ∈( Σ ∪ Q)*.

Derivazione in un passo: data una grammatica G e due parole w,z∈( Σ ∪ Q)* diremo che z
è derivabile in G da w in un passo, scrivendow  ⇒ G z se w = xαy, z = xβy e α→β è una
regola in P.
Derivazione: una derivazione di z da w in G è una sequenza w  ⇒ G w1⇒G w2⇒G … ⇒G
wm⇒G z , per cui sia w⇒G w1 , ...., wi⇒G wi+1 .., wm ⇒G z .

Il linguaggio L(G) generato dalla grammatica G è l’insieme di parole sull’alfabeto Σ


derivabili
dall’assioma S, cioè:
L(G) = {w∈Σ* | S ⇒G* w },
Dove S ⇒G * w sta a indicare che esiste una derivazione di w da S in G.
Un linguaggio ammette più grammatiche che lo generano se è ricorsivamente numerabile.
Due grammatiche G1 e G2 sono dette equivalenti se generano lo stesso linguaggio, cioè se
L(G1)=L(G2).

Teorema:
Il lingu aggio L è generato d a un a gram m atica  ⇔  L è r icorsivamente numerabile .
Questo significa che, se per un linguaggio L esiste un calcolo logico corretto e completo,
allora L è generabile da una grammatica. Le grammatiche risultano dunque sistemi formali
per esprimere calcoli logici.

Classificazione delle grammatiche e gerarchia di Chomsky


● Grammatiche di tipo 0: le regole di produzione sono arbitrarie.
● Grammatiche di tipo 1: ogni regola di produzione α → β della grammatica deve
essere tale che l(β) ≥ l(α), dove l indica la lunghezza dell’espressione(numero di
simboli);
è permessa la regola S → ε, se S è l’assioma, a patto che S non compaia nella
parte destra di nessuna altra regola.
● Grammatiche di tipo 2: ogni regola di produzione α → β della grammatica è tale
che α è un metasimbolo.
● Grammatiche di tipo 3: ogni regola di produzione della grammatica è del tipo
A → σB,  A → σ oppure A → ε, dove A, B sono arbitrari metasimboli e σ un
arbitrario simbolo terminale.
Linguaggi di tipo k: Un linguaggio L è detto di tipo k (k=0,1,2,3) se esiste una grammatica
G di tipo k tale che L = L(G). Indichiamo con Rk la classe dei linguaggi di tipo k
(k=0,1,2,3).
Rk = {L ∈ Σ* |  L è di tipo k}
● R3= linguaggi regolari
● R2= linguaggi liberi da contesto (acontestuali)
● R1= linguaggi dipendenti da contesto
● R0= linguaggi ricorsivamente enumerabili

Teorema di inclusione degli Rk


R3 ⊂ R2 ⊂ R1 ⊂ R0
L’inclusione tra gli Rk segue dal fatto che abbiamo dato sui tipi di G:
tipo  k ⇒ tipo k − 1

Albero di derivazione: data una grammatica G = <Σ, Q, P, S> di tipo 2 che genera il
linguaggio L(G), un albero di derivazione della parola w∈L(G) in G è un albero ordinato i
cui nodi sono etichettati con simboli in S∪Q, così che:
● Ogni foglia è etichettata con un simbolo terminale, mentre ogni nodo interno è
etichettato con un metasimbolo;
● La radice è etichettata con l’assioma S;
● Se un nodo interno è etichettato col metasimbolo B e i suoi figli sono etichettati, in
ordine, coi metasimboli B1  . . .  Bm, allora B→B1  . . .  Bm è una regola di
produzione di G;
● Leggendo le foglie in ordine prefisso, la sequenza di etichette forma la parola w.

Derivazioni equivalenti: data una grammatica G, diremo che due derivazioni sono
equivalenti se hanno associato lo stesso albero di derivazione.

Grammatica ambigua / non ambigua: una grammatica G = <Σ, Q, P, S> di tipo 2 è detta
ambigua se esiste una parola w∈L(G) che ammette due diversi alberi di derivazione;
viceversa, una grammatica G = <Σ, Q, P, S> di tipo 2 è detta non ambigua se ogni parola
w∈L(G) ammette un unico albero di derivazione.

Automa a stati: Un automa a stati è un sistema A = < Q , Σ, δ, q0, F> dove:


1) Q è un insieme di stati;
2) Σ è un alfabeto finito;
3) δ: Σ × Q → Q è la funzione di transizione;
4) q0∈ Q è lo stato iniziale;
5) F ⊆ Q è l’insieme degli stati finali che definisce una funzione λ : Q →{ 0,1 } , dove: λ
(q) = 1 se q ∈ F, altrimenti λ (q) = 0.
Se l’insieme Q è finito, l’automa è detto a stati finiti.
Linguaggio riconosciuto da A:
L(A) = {w ∈ Σ* |  δ*(q0, w) ∈ F} = {w ∈ Σ* |  λ(δ*(q0, w)) = 1}in cui
δ*:  Q x Σ*  → Q è definita induttivamente δ*(q, ε) = q e δ*(q, wσ) = δ(δ*(q, w), σ)
ed è lo stato raggiunto da q leggendo wσ.

Stati trappola: Tutti i q tali cheq ∉ Fe ∀σ ∈ Σ  δ(q, σ) = q


Stati osservabili: Tutti i p se ∃w ∈ Σ* |  δ*(q0, w) = p
Stati indistinguibili: due stati q ≈ p  ∈ Q si dicono indistinguibili quando
∀w ∈ Σ*  λ(δ*(q, w)) = λ(δ*( p, w))
≈  è una relazione di equivalenza che induce una partizione su Q.
[q]≈ è la classe di equivalenza che contiene q.
A≈  = ( Σ,  Q/≈,  [q0]≈,  δ≈,  F≈) dove:
● F≈ = {[ p]≈  |  p ∈ F}
● δ≈ : Q/≈ × Σ → Q/≈ in cui δ≈([q]≈, σ) = [δ(q, σ)]≈

Automa massimo: GL(per ogni parola in input raggiungo uno stato diverso)
∀w, w′  δ(q0, w) ≠ δ(q0, w′) ⇒ Q = Σ*

Automa minimo: GL≈è l’automa minimo per L


A è minimo per L se A ha tutti gli stati osservabili e distinguibili tra loro, quindi
Aŏ minimo per L se A ha tutti gli stati osservabili

L è generato da una grammatica di tipo 3 ⇔ L è riconosciuto da un automa a stati finiti

Automa a stati finiti non deterministico (NFA): Un automa a stati finiti non
deterministico A è un sistema A  =   < Q , Σ, R, q0, F > con: insieme (finito) degli stati
Q , alfabeto(finito) Σ, relazione di transizione R: Q × Σ × Q → {0,1}, stato iniziale
q0∈ Q e F ⊆ Q come insieme degli stati finali.
R(q, σ, p)  =  1 se q →σ p, 0 altrimenti.

Automa a stati finiti deterministico (DFA): Un automa a stati finiti deterministico A è un


sistema A  = < Q , Σ, δ, q0, F > , dove Q è un insieme finito di stati, Σ è un alfabeto
finito,q0∈ Q è lo stato iniziale, F ⊆ Q è l’insieme degli stati finali, e δè la funzione di
transizione definita come segue: δ(q, σ) = p ⇔ R(q, σ, p) = 1.

Espressioni regolari: Un’espressione regolare su Σè definita induttivamente come segue:


● ⊘ è un’espressione regolare;
● ε è un’espressione regolare;
● σ ∈ Σè un’espressione regolare;
● Se ho p e q espressioni regolari(base), allora ( p + q), ( p ⋅ q) e ( p* o q*) sono
espressioni regolari(complesse).
Teorema di Kleene:
L è denotato da una espressione regolare ⇔L è riconosciuto da un automa a stati finiti

Teorema: Per ogni L riconosciuto da un NFA esiste un DFA che lo riconosce.

Parola ambigua: Una parola è ambigua se ammette due alberi di derivazione diversi.

Grammatica ambigua: Una grammatica G si dice ambigua se genera almeno una parola
ambigua.

Linguaggio inerentemente ambiguo: Un linguaggio si dice inerentemente ambigui se ogni


G che lo genera è ambigua.

Forma Normale di Chomsky (FNC): A → BC   A → σ con A, B, C ∈ V   e   σ ∈ T

Forma Normale di Greibach (FNG): A → σW con A ∈ V  ,    σ ∈ T    e   W ∈ V*

Pila: Memoria ad accesso limitato con politica (LIFO - Last in first out)

Riconoscitore a pila:
Un riconoscitore a pila è una tupla A = (Σ, K, S, δ ) dove:
● Σ alfabeto di input
● K alfabeto della pila Σ ∩ K = ⊘
● S simbolo iniziale della pila
● δ funzione di evoluzione della pila δ: K × Σ → 2k* δ(x, σ) = {w1, w2, . . . , ws}
con wj ∈ K*
Si indica che:
● X è letto in cima alla pila (TOP)
● σè letto sul nastro di input
● X viene cancellato dalla pila (POP)
● Viene scelto un Wj ∈ K* in maniera NON DETERMINISTICA da inserire nella pila
(PUSH)

Criterio di accettazione: La parola x si dirà accettata se nel grafo di computazione di x


esiste un cammino da S a ε

Teorema: L è generato da G di tipo 2 ⇔L è riconosciuto da un riconoscitore a pila.

Pumping Lemma: Esprime una condizione necessaria per i linguaggi di tipo 2.


L non soddisfa il lemma ⇒L non è di tipo 2.
L soddisfa il lemma ⇒L può essere di tipo 2 o no.
Per ogni L di tipo 2 esiste una costante H tale che per ogni z ∈ L con |z| > H esiste una
scomposizione in uv wx y  =  z che soddisfa:
1. | vx | ≥ 1
2. | v wx |   ≤ H
3. ∀k ≥ 0   uv k wx k y ∈ L