Docsity
Docsity

Prepara i tuoi esami
Prepara i tuoi esami

Studia grazie alle numerose risorse presenti su Docsity


Ottieni i punti per scaricare
Ottieni i punti per scaricare

Guadagna punti aiutando altri studenti oppure acquistali con un piano Premium


Guide e consigli
Guide e consigli


Linguaggi e Computabilità - appunti, Appunti di Tecniche E Linguaggi Di Programmazione

Il testo discute concetti avanzati di teoria della computazione, includendo automi a pila e macchine di Turing. Esplora proprietà indecidibili dei linguaggi ricorsivamente enumerabili. Descrive la struttura di automi a pila e definisce le relazioni di transizione. Illustra come macchine a pila siano equivalenti a grammatiche context-free. Introduce il concetto di descrizione istantanea e stabilisce teoremi sulla computazione delle macchine a pila. Sottolinea il legame tra macchine a pila e grammatiche context-free. Infine, tratta delle macchine di Turing universali e dimostra il teorema di Rice sulla indecidibilità delle proprietà non banali dei linguaggi ricorsivamente enumerabili.

Tipologia: Appunti

2022/2023

In vendita dal 26/01/2024

silvia-cambiago
silvia-cambiago 🇮🇹

4.7

(3)

8 documenti

1 / 13

Toggle sidebar

Questa pagina non è visibile nell’anteprima

Non perderti parti importanti!

bg1
Linguaggi e Computabilità
1
Cambiago Silvia Anno Accademico 2022-2023 Prof. Alberto Ottavio Leporati
LINGUAGGI
In generale, con linguaggio si intende la capacità d'uso e l'uso stesso di un qualunque sistema
di simboli adatti a comunicare. Quando si analizza un linguaggio, è necessario riconoscere:
à Riconoscitori (es. automi): sono in grado di riconoscere gli elementi del linguaggio e
di distinguere stringhe appartenenti al linguaggio da quelle che non ne fanno parte;
à Generatori (es. grammatiche): stabiliscono le regole formali del linguaggio e generano,
sulla base di esse, tutte le parole del linguaggio in modo sistematico.
Quando si va a costruire un linguaggio, si deve necessariamente partire dal suo alfabeto (che
si indica con
Σ
o, alternativamente, con
Γ
), definito come un insieme non vuoto di simboli a
partire dai quali si possono formare stringhe, ossia sequenze finite di tali simboli.
Dato un qualsiasi numero n, l’insieme di stringhe di lunghezza n si indica con
Σ
n, mentre
l’insieme di tutte le stringhe ottenibili riarrangiando i simboli dell’alfabeto si indica con
Σ
*.
Un linguaggio L (su un alfabeto
Σ
) è un sottoinsieme di
Σ
*. In simboli:
𝐿 Σ
La dicitura
Σ
+ indica invece tutte le stringhe contenute in
Σ
, meno la stringa vuota,
rappresentata con
𝜀
. Quindi
Σ
+ =
Σ
\ {
𝜀
}.
GRAMMATICHE
Una grammatica è una quadrupla G = <V, T, P, S> dove:
à V è l’insieme delle variabili, simboli che possono essere sostituiti ad altre espressioni;
à T è l’insieme dei simboli terminali (i caratteri letterali che possono apparire nelle regole
di produzione);
à P è l’insieme delle regole di produzione, dove una produzione è una coppia <u,v> con
u
V+ e v
V* e si indica con u ® v (u può diventare v);
à S
V è lo start symbol, ossia la variabile dalla quale si comincia a generare la stringa.
Le grammatiche vengono implementate mediante software che, dato un linguaggio del tipo
L = {w | w soddisfa una data regola di produzione} generano tutte le possibili stringhe w (che,
ovviamente, possono anche essere infinite).
I CFLs (context free languages), ovvero linguaggi liberi dal contesto, che presentano una
definizione ricorsiva, hanno regole del tipo A ®
γ
, con A
V e
𝛾
(V
T)*.
GERARCHIA DI CHOMSKY
Noam Chomsky, nel 1956, stilò un insieme di grammatiche formali per la generazione di
linguaggi. Tale insieme è governato da regole gerarchiche e se ne individuano quattro livelli,
con grado crescente di specificità e differenziati sulla base delle regole di produzione:
à Tipo 0:
α
®
β
con
α
,
β
(V
T)*
Nella testa della regola di produzione (
α
) ci può essere una sequenza qualsiasi di
simboli terminali e non terminali, così come nel corpo (
β
). Tali linguaggi sono detti
pf3
pf4
pf5
pf8
pf9
pfa
pfd

Anteprima parziale del testo

Scarica Linguaggi e Computabilità - appunti e più Appunti in PDF di Tecniche E Linguaggi Di Programmazione solo su Docsity!

Linguaggi e Computabilità

Cambiago Silvia Anno Accademico 202 2 - 2023 Prof. Alberto Ottavio Leporati

LINGUAGGI

In generale, con linguaggio si intende la capacità d'uso e l'uso stesso di un qualunque sistema

di simboli adatti a comunicare. Quando si analizza un linguaggio, è necessario riconoscere:

à Riconoscitori (es. automi): sono in grado di riconoscere gli elementi del linguaggio e

di distinguere stringhe appartenenti al linguaggio da quelle che non ne fanno parte;

à Generatori (es. grammatiche): stabiliscono le regole formali del linguaggio e generano,

sulla base di esse, tutte le parole del linguaggio in modo sistematico.

Quando si va a costruire un linguaggio, si deve necessariamente partire dal suo alfabeto (che

si indica con Σ o, alternativamente, con Γ), definito come un insieme non vuoto di simboli a

partire dai quali si possono formare stringhe, ossia sequenze finite di tali simboli.

Dato un qualsiasi numero n , l’insieme di stringhe di lunghezza n si indica con Σ

n

, mentre

l’insieme di tutte le stringhe ottenibili riarrangiando i simboli dell’alfabeto si indica con Σ

* .

Un linguaggio L (su un alfabeto Σ) è un sottoinsieme di Σ

*

. In simboli: 𝐿 ⊆ Σ

La dicitura Σ

+ indica invece tutte le stringhe contenute in Σ

∗ , meno la stringa vuota,

rappresentata con 𝜀. Quindi Σ

+ = Σ

∗ \ {𝜀}.

GRAMMATICHE

Una grammatica è una quadrupla G = dove:

à V è l’insieme delle variabili, simboli che possono essere sostituiti ad altre espressioni;

à T è l’insieme dei simboli terminali (i caratteri letterali che possono apparire nelle regole

di produzione);

à P è l’insieme delle regole di produzione, dove una produzione è una coppia con

u ∈ V

e v ∈ V

e si indica con u ® v (u può diventare v);

à S ∈ V è lo start symbol, ossia la variabile dalla quale si comincia a generare la stringa.

Le grammatiche vengono implementate mediante software che, dato un linguaggio del tipo

L = {w | w soddisfa una data regola di produzione} generano tutte le possibili stringhe w (che,

ovviamente, possono anche essere infinite).

I CFLs (context free languages), ovvero linguaggi liberi dal contesto, che presentano una

definizione ricorsiva, hanno regole del tipo A ® γ, con A ∈ V e 𝛾 ∈ (V ∪ T)

.

GERARCHIA DI CHOMSKY

Noam Chomsky, nel 1956, stilò un insieme di grammatiche formali per la generazione di

linguaggi. Tale insieme è governato da regole gerarchiche e se ne individuano quattro livelli,

con grado crescente di specificità e differenziati sulla base delle regole di produzione:

à Tipo 0: α ® β con α, β ∈ (V ∪ T)

Nella testa della regola di produzione (α) ci può essere una sequenza qualsiasi di

simboli terminali e non terminali, così come nel corpo (β). Tali linguaggi sono detti

ricorsivamente enumerabili e gli automi che li accettano e li riconoscono sono le

macchine di Turing deterministiche e non deterministiche;

à Tipo 1: α "

A𝛼

® α "

, dove A ∈ qV e α "

, β ∈ (V ∪ T)

Si dicono linguaggi contestuali, in quanto prevedono la presenza di una variabile A che

viene sostituita da una stringa 𝛽 di simboli terminali e non terminali, ma solo nel caso

in cui prima di A vi sia una sequenza α "

specifica e dopo A un’ulteriore sequenza 𝛼

anch’essa esplicitata, quindi A può essere sostituita solo se si trova nel contesto corretto.

Questi linguaggi sono accettati da macchine di Turing con nastro lineare;

à Tipo 2: A ® γ, con A ∈ V e 𝛾 ∈ (V ∪ T)

La variabile A può essere sostituita dalla sequenza indipendentemente dal contesto,

quindi da ciò che viene prima e dopo. Tali linguaggi si dicono CFLs (context free

languages). Sono riconosciuti da automi a pila (implemetano quindi stack) non

deterministici;

à Tipo 3: A ® aB oppure A ® a (o, alternativamente, A ® Ba oppure A ® a)

Si dicono linguaggi regolari e sono riconosciuti da automi a stati finiti, automi

deterministici e non deterministici.

DERIVAZIONE IN ZERO O PIÙ PASSI

Quando si effettuano una sostituzione in linea con le regole imposte dalla grammatica del

linguaggio si attua una derivazione in zero o più passi, che si indica con Þ* e si definisce

ricorsivamente come di seguito:

BASE: α Þ* α vero ∀ α ∈ (V ∪ T)

in quanto α è sempre derivabile in se stessa in zero passi

PASSO: se α Þ* β e β Þ 𝛾 allora α Þ* 𝛾

Data una grammatica G = posso definire il linguaggio generato da G come:

L(G) = {w ∈ T* | S Þ* w}

Se G è una CFG (context free grammar) allora L è un CFL.

Per definire la grammatica di un linguaggio si fa uso di espressioni scritte in forma sentenziale,

ovvero espressioni α tali per cui S Þ* α.

LEFTMOST/RIGHTMOST DERIVATION

Per ridurre il numero di scelte possibili nella derivazione di una stringa, si impone che a ogni

passo si sostituisca la variabile all’estrema sinistra con il corpo di una delle sue produzioni.

Tale derivazione viene detta derivazione a sinistra (leftmost derivation) e si indica con ⟹

$%

Alternativamente, si può procedere a rimpiazzare ogni volta la variabile più a destra con il

corpo di una delle sue regole. Tale derivazione viene detta derivazione a destra (rightmost

derivation) e si indica con ⟹

&%

OPERAZIONI TRA LINGUAGGI

à Unione: dati due linguaggi L e M, l’unione L ∪ M è un linguaggio composto dalle

parole di L e di M. Ad esempio, dati L = {001, 10, 111} e M = { 𝜀, 001}, la loro unione

L ∪ M = { 𝜀, 001, 10, 111}. L’unione è sia commutativa che associativa;

à Concatenazione: Dati due linguaggi L e M, la concatenazione LM è un linguaggio

composto dalla concatenazione delle parole del primo con le parole del secondo. Ad

esempio, dati L = {001, 10, 111} e M = { 𝜀, 001}, la loro unione L ∪ M = {001, 10,

à Chiusura di Kleene: La chiusura di Kleene L* è la chiusura riflessiva e transitiva

dell'operazione di concatenazione. Di fatto, corrisponde all’unione delle concatenazioni

degli elementi di L. Dato un linguaggio L, la chiusura L* = L

0

∪ L

1

∪ L

2

,…, ∪ L

n

. Con

la scrittura L

2 si intende LL.

ESPRESSIONI REGOLARI

È possibile definire mediante induzione le espressioni che definiscono i linguaggi di tipo 3,

dette espressioni regolari, come di seguito:

BASE:

à 𝜀 e ∅ sono espressioni regolari: L(𝜀) = {𝜀}; L(∅) = ∅;

à Se a ∈ Σ, allora a è un’espressione regolare: L(a) = {a};

à Le variabili che rappresentano linguaggi sono espressioni regolari: L(L) = {L} (il

linguaggio denotato dall’espressione regolare rappresentata da L è L).

PASSO INDUTTIVO:

à Se E, F sono espressioni regolari, allora E + R è un’espressione regolare, dove E + R

rappresenta l’unione di E ed R: L(E + F) = L(E) + L(F);

à Se E, F sono espressioni regolari, allora ER è un’espressione regolare, dove ER

rappresenta la concatenazione di E ed R: L(EF) = L(E) ⋅ L(F);

à Se E è un’espressione regolare, allora E* è un’espressione regolare, dove E*

rappresenta la chiusura di E: L(E) = (L(E));

à Se E è un’espressione regolare, allora (E) è un’espressione regolare: L((E)) = L(E);

PROPRIETÀ ALGEBRICHE DELLE ESPRESSIONI REGOLARI

Siano L, M e N delle espressioni regolari. Le principali proprietà algebriche dell’unione sono:

à L + M = M + L (commutatività di +)

à (E + F) + G = E + (F + G) (associatività di +)

à E + E = E (idempotenza di +)

à (LM)N = L(MN) (associatività di +)

à ∅ + L = L + ∅ = L (∅ è identità per +)

Date L, M e N come espressioni regolari, le principali proprietà algebriche della

concatenazione sono:

à E𝜀 = 𝜀E = E (𝜀 è identità per ⋅)

à L∅ = ∅L = ∅ (∅ annichila ⋅)

à L(M + N) = LM + LN (distributività sinistra di ⋅ su +)

à (L + M)N = LN + MN (distributività destra di ⋅ su +)

Siano L, M e N delle espressioni regolari. Le principali proprietà algebriche dell’unione sono:

à (L) = L* (idempotenza di *)

à ∅* = 𝜀

à 𝜀* = 𝜀

à L(∅*) = {𝜀}

à L(𝜀*) = {𝜀}

à (L + M)* = (LM)*

AUTOMA A STATI FINITI DETERMINISTICO (DFA)

Un DFA è una quintupla A = (Q, Σ, 𝛿, q 0 , F) dove:

à Q è l’insieme finito e non vuoto degli stati;

à Σ è l’alfabeto delle stringhe in input;

à 𝛿 è la funzione di transizione degli stati;

à q 0 ∈ Q è lo stato iniziale;

à F ⊆ Q è l’insieme degli stati finali.

La funzione di transizione 𝛿 viene in generale estesa. Viene quindi definita un’altra funzione

: Q ´ Σ* ® Q, in maniera ricorsiva, come di seguito:

BASE: Se |w| = 0, cioè se w = 𝜀, allora 𝛿

(q, w) = 𝛿(q, 𝜀) = q

PASSO: Se |w| > 0, allora w = ax, con a ∈ Σ e x ∈ Σ* e 𝛿

(q, w) = 𝛿

(q, ax) = 𝛿

(q, a), x)

Data una DFA A = (Q, Σ, 𝛿, q 0 , F), il linguaggio accettato da A è:

L(A) = {w ∈ Σ* | 𝛿

(q0, w) ∈ F}

AUTOMA A STATI FINITI NON DETERMINISTICO (NFA)

Un NFA è una quintupla N = (Q, Σ, 𝛿, q 0 , F) dove:

à Q è l’insieme finito e non vuoto degli stati;

à Σ è l’alfabeto delle stringhe in input;

à 𝛿 è la funzione di transizione degli stati;

à q 0 ∈ Q è lo stato iniziale;

à F ⊆ Q è l’insieme degli stati finali.

La funzione di transizione è definita come:

𝛿: Q ´ Σ* ® Q = 2

Q , dove 2

Q è l’insieme potenza di Q. 𝛿 è una funzione parziale.

Data una NFA N = (Q, Σ, 𝛿, q 0 , F), il linguaggio accettato da N è:

L(N) = {w ∈ Σ* | 𝛿

(q 0 , w) ∩ F ¹ ∅}

Dato che, negli automi non deterministici, applicando la funzione 𝛿 su un input costituito da

uno stato ed una stringa si può ottenere un insieme di stati (e non uno solo come nei DFA), è

prevista la presenza di un oracolo esterno che sia a conoscenza dello stato in cui l’automa finirà.

MINIMIZZAZIONE DI DFA

Dato un DFA A = (Q, Σ, 𝛿, q 0 , F) può verificarsi che più stati siano equivalenti.

Due stati p, q ∈ Q sono equivalenti (p ≈ q) se:

∀ w ∈ Σ* vale 𝛿

(p, w) ∈ F Û 𝛿

(q, w) ∈ F

La relazione ≈ gode delle seguenti proprietà:

à Riflessività: ∀ p ∈ Q, p ≈ p;

à Simmetria: ∀ p, q ∈ Q, p ≈ q ® q ≈ p;

à Transitività: ∀ p, q, r ∈ Q, p ≈ q e q ≈ r ® p ≈ r.

Conseguentemente, ≈ è una relazione di equivalenza.

Se due stati non sono equivalenti, allora sono distinguibili (≈).

Due stati sono distinguibili se:

∃ w ∈ Σ* | 𝛿

(p, w) ∈ F ∧ 𝛿

(q, w) ∉ F oppure ∃ w ∈ Σ* | 𝛿

(p, w) ∉ F ∧ 𝛿

(q, w) ∈ F

Per individuare un eventuale testimone, ossia una stringa che provi che due stati sono

distinguibili, si utilizza il metodo induttivo.

BASE: se p ∈ F e q ∉ F, allora p ≈ q.

PASSO: se, preso un carattere a ∈ Σ*, 𝛿(p, a) ≈ 𝛿(q, a), allora p ≈ q

Su questo principio si basa l’algoritmo per determinare se due stati sono distinguibili o meno.

L’applicazione dell’algoritmo porta al riempimento di una tabella come la seguente:

dove verranno riempite le caselle che individuano una coppia di

stati distinguibili. Per quanto riguarda la complessità

dell’algoritmo, detta n = |Q|, esso considera tutte le coppie diverse

di stati, che sono:

,

!

  • ,

,(,-")

, che è quindi il numero di celle.

Nel caso peggiore, viene riempita solo una cella per iterazione,

quindi il numero di iterazioni diventa pari al numero di celle,

portando il tempo di calcolo a T(𝑛) = 𝑂(𝑛

0 ).

Dati due DFA AL = (QL, Σ, 𝛿L, qL, FL) e AM = (QM, Σ, 𝛿M, qM, FM), per capire se accettano lo

stesso linguaggio devo costruire un nuovo DFA A = (QL ∪ QM, Σ, 𝛿, qL, FL ∪ FM), applicare

l’algoritmo sopra descritto (riempi-tabella) e verificare che qL ≈ qM, in quanto, nel caso in cui

lo siano, a partire da qL e qM verrebbero accettate le stesse stringhe, quindi gli automi

accetterebbero lo stesso linguaggio.

L’algoritmo riempi-tabella funziona unicamente con gli automi deterministici.

PUMPING LEMMA

Il pumping lemma si utilizza per dimostrare che determinati linguaggi non sono regolari.

Sia L un linguaggio regolare. Esiste una costante n ∈ ℕ (dipendente da L), tale che ∀ w ∈ L

con |w| ≥ n, w può essere scomposta come w = xyz tali che:

à y ¹ 𝜀;

à |xy| ≤ n;

à ∀ k ≥ 0, la stringa xy

k z ∈ L.

AUTOMI A PILA

Gli automi a pila (pushdown automata, PDA) sono costituiti da una pila (stack) e da un 𝜀-NFA.

Come gli 𝜀-NFA ha un controllo a stati finiti, accetta in input una stringa w ∈ Σ* e potrà

accettarla o rifiutarla, ovviamente dipendentemente dal fatto che l’automa si trovi o meno in

uno stato finale quando viene consumato l’ultimo carattere della stringa.

Nella pila vengono eseguite le procedure PUSH() e POP() su simboli dell’alfabeto. La pila non

deve mai essere vuota, ma è sempre presente in essa un simbolo speciale, z 0 , che impedisce

all’automa di bloccarsi. Quando contiene unicamente quest’ultimo è logicamente vuota, ma

non fisicamente, condizione che si verifica quando nella pila non è presente nemmeno z 0.

In un dato istante, l’automa si troverà in un determinato stato q, e la pila conterrà un certo

numero di simboli. Quando legge una stringa, considera il primo carattere della stessa e, in un

passo di computazione, esegue tre operazioni:

à Consuma il simbolo considerato, quindi il primo della stringa;

à Rimuove (POP()) il simbolo della pila più in alto;

à Esegue la PUSH() di uno o più simboli nella pila e cambia stato.

La funzione 𝛿 riceve in ingresso lo stato corrente, il carattere consumato e quello rimosso dalla

pila, e restituirà in output il nuovo stato e la sequenza di simboli da immettere nella pila. Questo

è il motivo per cui l’automa si blocca se la pila è fisicamente vuota: manca un parametro in

input per la funzione 𝛿.

Un automa a pila è una settupla P = (Q, Σ, Γ, 𝛿, q 0 , z 0 , F) dove:

à Q è l’insieme finito e non vuoto di stati;

à Σ è l’alfabeto dei simboli di input;

à Γ è l’alfabeto dei simboli di stack;

à 𝛿: Q ´ (Σ ∪ {𝜀}) ´ Γ ® P(Q ´ Γ*); P = insieme delle parti

à q 0 ∈ Q è lo stato iniziale;

à z 0 ∈ Γ è il simbolo inizialmente presente nello stack;

à F ⊆ Q è l’insieme degli stati finali.

DESCRIZIONI ISTANTANEE (ID)

Una descrizione istantanea (ID o configurazione) è una tripla (q, w, γ), dove:

à q ∈ Q è lo stato attuale;

à w ∈ Σ* è l’input residuo (ciò che resta da leggere);

à γ ∈ Γ* è il contenuto attuale della pila.

Una mossa, invece, viene definita come di seguito:

Sia P = (Q, Σ, Γ, 𝛿, q 0 , z 0 , F) un PDA. Si suppone che (p, a) ∈ 𝛿(q, a, x). Allora:

∀ w ∈ Σ* e ∀ β ∈ Γ* (q, aw, xβ) ⊢P (p, w, αβ) ⊢P = prossima configurazione

⊢P definisce una mossa del PDA. Se P è chiaro, si scrive ⊢ invece di ⊢P.

⊢P è una relazione binaria tra coppie di configurazioni.

Si può inoltre definire in maniera induttiva la relazione ⊢*P (passaggio di configurazione in

zero o più mosse), scrivibile come ⊢* se P è chiaro.

BASE: I ⊢* I ∀ ID I

PASSO: I ⊢* J se ∃ ID K | I ⊢* K e K ⊢* J

DA STATI FINALI A PILA VUOTA

Se L = L(PF) (L è accettato per stati finali) per un PDA PF = (Q, Σ, Γ, 𝛿F, q 0 , z 0 , F) allora esiste

un PDA PN tale che L = N(PN).

PN = (Q ∪ {p 0 , p}, Σ, Γ ∪ {X 0 }, 𝛿N, p 0 , X 0 ) dove p è uno stato che svuota la pila (presenta un

self-loop che toglie passaggio dopo passaggio tutti i caratteri rimasti nella pila).

DA CFG A PDA PER PILA VUOTA

Data G = (V, T, Q, S), si può costruire il PDA per pila vuota P = ({q}, T, V ∪ T, 𝛿, q, S) che

accetta tale grammatica. Vale anche la relazione inversa. La funzione 𝛿 si compone di due casi:

à ∀ a ∈ V, 𝛿(q, 𝜀, A) = {(q, β) | A ® β è una produzione di G}

à ∀ a ∈ T, 𝛿(q, a, a) = {(q, 𝜀)}

PDA DETERMINISTICO E NON DETERMINISTICO

Un PDA P = (Q, Σ, Γ, 𝛿 , q 0 , z 0 , F) è deterministico (DPDA - Deterministic Pushdown

Automata) se valgono entrambe le seguenti condizioni:

à | 𝛿(q, a, X) | ≤ 1 ∀ q ∈ Q, ∀ a ∈ Σ ∪ {𝜀}, ∀ X ∈ Γ

à Se | 𝛿(q, a, X) | ¹ 0 per qualche a ∈ Σ, allora | 𝛿(q, 𝜀, X) | = 0

Se L è regolare, allora ∃ un PDA PF (non deterministico) tale che L = L(PF). Inoltre, ∃ un PDA

PN (non deterministico) tale che L = N(PN). Infatti, un PDA non deterministico è un 𝜀-NFA che

impiega una pila.

Se L è regolare, ∃ inoltre un DPDA per stati finali PF tale che L = L(PF). Infatti, un DPDA per

stati finali è assimilabile ad un DFA che implementa una pila.

Non è però detto che ∃ un DPDA per pila vuota PN tale che L = N(PN).

PROPRIETÀ DEL PREFISSO

Un linguaggio L ha la proprietà del prefisso (è prefix-free) se:

∄ x, y ∈ L | x ¹ y e x è prefissa di y

TEOREMA

Un linguaggio L è N(P) per un DPDA P se e solo se L ha la proprietà del prefisso ed è L(P’)

per un DPDA P’, il che vuol dire che un linguaggio è accettato da un DPDA per pila vuota se

e solo se è prefix-free.

TEOREMA

Se L = N(P) per un DPDA P, allora L ha una CFG non ambigua (vedi definizione di grammatica

ambigua).

TEOREMA

Se L = L(P) per un DPDA P, allora L ha una CFG non ambigua (vedi definizione di grammatica

ambigua).

MACCHINA DI TURING

Una macchina di Turing è definita come una settupla M = (Q, Σ, Γ, 𝛿, q 0 , B, F), dove:

à Q è l’insieme finito e non vuoto di stati;

à Σ è l’alfabeto finito dei simboli di input;

à Γ è l’alfabeto finito dei simboli del nastro;

à 𝛿: Q ´ Γ ® Q ´ Γ ´ {L, R} è la funzione (parziale) di transizione;

à q 0 ∈ Q è lo stato iniziale;

à B ∈ Γ ´ Σ è il simbolo di blank;

à F ⊆ Q è l’insieme degli stati finali.

Il linguaggio L(M) accettato dalla macchina di Turing è definito come:

L(M) = {w ∈ Σ* | M accetta w}

ed è detto ricorsivamente enumerabile (tipo 0) se ∃ una macchina di Turing M | L = L(M).

La funzione 𝛿 prende in input lo stato corrente ed il simbolo che si trova nella testina

attualmente puntata e restituisce il prossimo stato in cui finisce il controllo finito, il simbolo

che deve scrivere la testina e {L, R} (left e right) per spostare la testina di una posizione a

destra e sinistra.

TEOREMA

Ogni linguaggio accettato da una macchina di Turing standard M 2 è accettato anche da una

macchina di Turing a nastro semi-infinito M 1 con i seguenti vincoli:

à La testina di M 1 non va mai a sinistra della posizione iniziale (q 0 è in corrispondenza

della cella più a sinistra);

à M 1 non scrive mai B (blank).

MACCHINE MULTI-STACK

Una macchina multi-stack è un DPDA + k pile. Prevede quindi un controllo a stati finiti (come

ogni DPDA) che prende in input una stringa w ∈ Σ* e la può accettare o rifiutare a seconda di

quale sia lo stato finale. Possiede anche più pile con z 0 in fondo a ciascuna. La funzione di

transizione è del tipo 𝛿(q, a, 𝜀, x 1 , x 2 , …, xn).

Accetta i linguaggi ricorsivamente enumerabili, infatti se un linguaggio L è accettato da una

macchina di Turing, allora L è accettato anche da un DPDA con 2 stack.

TEOREMA

Ogni linguaggio ricorsivamente enumerabile è accettato da una macchina a 3 contatori.

Se L ∈ RE, allora è accettato da un DPDA con 2 stack, con |Γ| = r – 1.

Se lo stack contiene gli elementi X 1 , X 2 , …, Xn, allora si può scrivere un numero intero in base

r: Xn ⋅ (r - 1) + … + X 2 ⋅ r + X 1 , che si può mettere in un contatore. Le due pile sono quindi

sostituite da un contatore. Per eseguire la POP() si divide per r: il quoziente è ciò che rimane

nella pila ed il resto è l’elemento tolto. Per la PUSH() si moltiplica per r e si somma il valore

corrispondente al simbolo da immettere.

Non è possibile stabilire a priori se la macchina, dato un certo input, si fermerà oppure no. Tale

problema è quindi indecidibile.

MACCHINA DI TURING UNIVERSALE E LINGUAGGIO UNIVERSALE

Una macchina di Turing universale è una macchina U che prevede due input: una macchina Mi

ed una stringa wj. Restituisce una risposta positiva se wj ∈ L(Mi) e negativa (oppure continua

la computazione all’infinito) se wj ∉ L(Mi). Queste sono fondamentalmente le stesse risposte

che fornirebbe Mi con wj in input, in quanto lo scopo di U è quello di simulare la macchina Mi.

U simula infatti ogni macchina di Turing ed è quindi detto simulatore universale.

Il linguaggio universale Lu accettato dalla macchina di Turing universale è RE (in quanto

accettato da una macchina di Turing) ma non ricorsivo (perché deve poter rappresentare anche

le macchine che non si fermano mai).

Lu = {(Mi, wj) | wj ∈ L(Mi)} = {cod(Mi)111wj | wj ∈ L(Mi)}

La macchina prevede in realtà un solo input, la codifica della macchina Mi, concatenata a 111 ,

sequenza che non compare mai prima, concatenata a wj.

Una proprietà dei linguaggi ricorsivamente enumerabili è un insieme di linguaggi

ricorsivamente enumerabili, ossia un insieme di macchine di Turing.

Una proprietà è banale se è l’insieme vuoto oppure se è tutto RE.

TEOREMA DI RICE

Ogni proprietà non banale di linguaggi ricorsivamente enumerabili è indecidibile.