







Studia grazie alle numerose risorse presenti su Docsity
Guadagna punti aiutando altri studenti oppure acquistali con un piano Premium
Prepara i tuoi esami
Studia grazie alle numerose risorse presenti su Docsity
Prepara i tuoi esami con i documenti condivisi da studenti come te su Docsity
Trova i documenti specifici per gli esami della tua università
Preparati con lezioni e prove svolte basate sui programmi universitari!
Rispondi a reali domande d’esame e scopri la tua preparazione
Riassumi i tuoi documenti, fagli domande, convertili in quiz e mappe concettuali
Studia con prove svolte, tesine e consigli utili
Togliti ogni dubbio leggendo le risposte alle domande fatte da altri studenti come te
Esplora i documenti più scaricati per gli argomenti di studio più popolari
Ottieni i punti per scaricare
Guadagna punti aiutando altri studenti oppure acquistali con un piano Premium
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
1 / 13
Questa pagina non è visibile nell’anteprima
Non perderti parti importanti!








Cambiago Silvia Anno Accademico 202 2 - 2023 Prof. Alberto Ottavio Leporati
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 Σ
+ = Σ
∗ \ {𝜀}.
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)
.
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: α "
® α "
, 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.
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 Þ* α.
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 ⟹
&%
à 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.
È possibile definire mediante induzione le espressioni che definiscono i linguaggi di tipo 3,
dette espressioni regolari, come di seguito:
à 𝜀 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).
à 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);
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)*
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}
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 , 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à.
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.
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.
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.
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.
PASSO: I ⊢* J se ∃ ID K | I ⊢* K e K ⊢* J
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).
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, 𝜀)}
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).
Un linguaggio L ha la proprietà del prefisso (è prefix-free) se:
∄ x, y ∈ L | x ¹ y e x è prefissa di y
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.
Se L = N(P) per un DPDA P, allora L ha una CFG non ambigua (vedi definizione di grammatica
ambigua).
Se L = L(P) per un DPDA P, allora L ha una CFG non ambigua (vedi definizione di grammatica
ambigua).
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.
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).
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.
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.
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.
Ogni proprietà non banale di linguaggi ricorsivamente enumerabili è indecidibile.