Quindi lezione scorsa di una settimana
fa che abbiamo fatto? Abbiamo fatto
macchine, esercitazione su macchine
multinastro. Ok, quindi avevamo visto
sto modello di macchine multinastro,
abbiamo visto che
sono equivalenti alle macchine mononast,
no?
e che quindi possiamo usarle
invece delle macchine mononastri, ok?
Quindi tutto ciò che è calcolabile da
una macchina multinastro è anche
calcolabile da una macchina monastro.
Quindi noi usiamo le macchine
multilastro perché perché sono più
facili da programmare. Ok? Perché adesso
dovremmo iniziare a vedere un po' di
cose e sapere di avere una macchina a
più nastri ci semplifica un po' anche
Ok?
Che altro?
Ma questo abbiamo visto che la
simulazione,
questo qua è importante, la simulazione
di una macchina antinastro su una
macchina mononastro ci costa quadratico,
il che significa che rallentiamo sì, ma
non è così sconvolgente, ok? Non
cambiamo ordine di complessità. Per voi
che avete fatto algoritmi e strutture
dati,
sapete, insomma, che ci sono algoritmi
polinomiali, algoritmi esponenziali. Non
so se vi è mai capitato di vedere
algoritmi doppiamente esponenziali,
triplamente esponenziali, no?
Doppiamente esponenziale non è 2^ 2 * n,
doppiamente esponenziale è 2^ 2^ n, cioè
è è una cosa mastodontica. Adesso, se
noi facciamo il quadrato di queste
funzioni, un quadrato di un polinomio
rimane un un polinomio, il quadrato di
un esponenziale rimane esponenziale, il
quadrato di un doppiamente esponenziale
rimane nella famiglia dei doppiamenti
esponenziali. Cioè, quindi avere più una
strone
che ci fa ci sconvolge così la vita al
punto tale per cui se noi siamo
interessati raff sulla complessità di
alcuni algoritmi sapere è polinomiale, è
esponenziale, è doppiamente
esponenziale, una cosa del genere,
lavorare su macchine multinastro non ci
modifica sostanzialmente il risultato,
di conseguenza le usiamo perché perché è
pratico. Ok, tutto qua. Quello che
andiamo a introdurre oggi è il modello
che useremo per il resto del nostro
corso. Perché? Perché è pratico.
Allora, vi faccio un primo esempio e
cerchiamo di capire che ha di strano
questa macchina. Ok, assumiamo di avere
questa macchina qua. Quello sta
registrando.
Y
no.
Ok,
alloraamo
qui 0 come primo stato.
Leggiamo zero, scriviamo uno e andiamo
avanti.
Qua ci sta uno,
leggiamo uno, scriviamo zero e andiamo
indietro.
Qua c'è un altro.
C'è uno. Lasciamo uno e andiamo
indietro. C'è zero, lasciamo zero e
andiamo indietro. Questa è una
semplicissima macchina monastro. Eh,
c'è zero, lascio zero e vado avanti.
C'è uno, lascio uno e vado avanti.
C'è blank, lascio blank e vado avanti. E
andiamo in
Q2. Ok, questa è una semplicissima
macchina monastro. C'ha tre stati, il
solito stato iniziale, stato finale,
bla, etichette, archi, eccetera, cose
che abbiamo sempre visto. Ok.
Che ha di strano questa macchina?
Chi chi? Ok.
Dove?
In Q1. In cosa?
Perché se legge zero può ciclare zero,
può ciclare esattamente. Questa macchina
ha la peculiarità
di essere non deterministica, cioè
questa macchina
per una particolare coppia,
simbolo, letto,
stato in cui sono, abbiamo più di una
scelta, ok? Cioè questa macchina
potrebbe transire o, come dice il nostro
collega, rimanere in Q1
o muoversi in Q0. Ok?
Questi questa macchina è sostanzialmente
differente dalle altre macchine che
abbiamo visto finora, perché ora ne
abbiamo viste di varie varianti,
mononastro,
multitraccia, multinastro, eccetera, ma
tutte quelle macchine erano tutte
deterministiche, cioè per qualsiasi
coppia, simbolo in input o simboli
input, se era multitraccia o
multinastro, è stato in cui mi trovo
Nuovo.
La macchina ha una sola un solo
possibile next step, cioè la macchina sa
che fare. Questa macchina qua è un po'
peculiar perché
qui ha un del non determinismo, cioè in
quel punto se la macchina legge 0 e sta
in Q1 potrebbe andare in Q0 o potrebbe
rimanere in Q1. Ok?
il fatto che questo ve lo sottolineo,
guardate queste label, questa qua e
questa qua, ok?
Il fatto che qui leggiamo 0 e scriviamo
zero e qui leggiamo 0 e qui scriviamo
zero sia lo stesso da tutte e due le
parti, è semplicemente un caso. Qui
potevamo trovare leggo 0 e scrivo 1 e
qui leggo 0 e scrivo 0. Ok? c'è
completamente
scorrelato, ci può essere qualsiasi
cosa. L'unica cosa che le accomuna è
questo stato
simbolo letto che è lo stesso. E quando
la macchina si trova qua e legge zero in
linea di principio può fare due mosse.
Ok?
Adesso, prima di buttarci a capire che
faccia questa macchina su una stringa di
esempio, a questo punto, siccome noi
sicuramente ci ricordiamo le definizioni
formali di macchina di Touring,
deterministica, introduciamo quella non
deterministica, ok? Rivediamola assieme.
Allora, N è una macchina di touring non
deterministica.
È una tupla caratterizzata da, vi
ricordate da cosa è caratterizzata una
macchina di Touring deterministica?
Alfabeti. Ok. Abbiamo sigma che è
l'alfabeto di dei simboli
leggere input dei simboli input è
l'alfabeto dei simboli che possiamo
trovare sul nastro quando la macchina
viene accesa. Ok? Però la macchina a
parte leggere e scrivere quella roba,
può leggere e scrivere altro, cioè c'ha
i suoi simboli, le X, i cancelletti, le
casette, ok? Quindi ha la possibilità di
accedere a un altro alfabeto che noi
chiamiamo gamma che è l'alfabeto di
nastro, cioè è l'insieme di tutti i
simboli che la macchina può maneggiare
sul nastro. Ok? Ovviamente eh sigma è un
sottinsieme di gamma,
un sottinsieme stretto perché tra i
simboli
che ci stanno in gamma abbiamo blank, il
simbolo di bianco che è eh identifica
quando una cella del nastro della nostra
del nostro nastro è vuoto. Ok? Alright.
Quindi due alfabeti, un simbolo di
bianco. Poi cosa c'avevamo nelle
definizioni?
Abbiamo l'insieme
degli stati. Ok, quindi ci stanno. Ma
guardiamo la il disegno. C'abbiamo i
palletti. I palletti che sono i
palletti? Sono sono gli stati. Quindi
abbiamo Q. Lo chiamiamo Q per
convenzione, lo potevamo chiamare pure
Pippo. Ok? L'importante è che ci sia un
insieme degli stati. Q lo chiamiamo Q.
Fra tutti gli stati ce n'è uno che
identifichiamo come stato iniziale che è
Q0. Nella nostra grafica lo scato
iniziale c'ha la freccetta entra in quel
modo e quello ci identifica con lo stato
iniziale.
Tra tutti gli stati Q abbiamo
l'insieme degli stati finali che possono
essere in linea di principio Q1. Ok?
Non abbiamo, a differenza di altre
definizioni, voi le troverete su altri
libri, gli stati rejecting noi non li
abbiamo. Abbiamo definito il reject in
un altro modo, è totalmente equivalente,
cioè queste definizioni si
intertraducono.
Una cosa che può fare la macchina lo può
fare anche l'altra. Ok?
E dopodiché c'era un'ultima cosa, la
funzione di transizione, cioè il
programma di questa macchina che è
sostanzialmente gli archi e le etichette
di questo grafo. E l'avevamo chiamato
delta. Ok?
Questa cosa qua,
la funzione di transizione per una
macchina non deterministica è una cosa
un po' particolare. Ok? Vi ricordate?
deterministica.
Vi ricordate per una macchina
deterministica com'era definita la
funzione di transizione?
Delta è una funzione che va che mappa
che cosa?
Ok, siamo in uno stato, leggiamo un
simbolo e ce ne andiamo dove?
in uno stato. In uno stato scriviamo
scriviamo un certo simbolo e
e ce ne andiamo o a sinistra o a destra.
Ok? Questa era la definizione per
macchine deterministiche. Ok.
Sì.
Cal Ah, sì, sì, sì, sì,
giusto, giusto. Corret.
Alri,
primo, no, perché in linea di principio
noi potremmo aver letto cose che abbiamo
scritto prima e quindi c'abbiamo simboli
strani su cui processare. Ok? Se in
passato vi ho scritto sigma era
sbagliato e e gamma.
Ok?
Quindi questa è la definizione di
funzione di transizione, cioè è il
programma di una macchina
deterministica,
il programma di una macchina non
deterministica, cioè quindi la
definizione per una macchina non
deterministica finora è praticamente la
stessa cosa. Abbiamo sigma, abbiamo
gamma, abbiamo il simbolo di bianco,
abbiamo Q, abbiamo Q0, abbiamo l'insieme
degli stati finali e abbiamo delta.
Delta per una macchina non
deterministica
è una cosa un po' più sofisticata perché
data una coppia stato simbolo noi
possiamo avere un insieme di di prossimi
passi, ok? E questa cosa va modellata
per una macchina non deterministica.
Noi abbiamo che delta è una funzione
così fatta, è una funzione che mappa
le coppie stato
simbolo
verso l'insieme delle parti
delle triple stato simbolo direzione.
Che simbolo?
2^ Q 2^ Q lo usiamo per indicare tutti i
possibili sottoinsiemi da quel dominio.
Ok?
Questa è la differenza. Cioè
questa funzione alcuni preferiscono
definirla come una relazione o si può
definire in questo modo, cioè che
mappiamo da uno stato e un simbolo a un
insieme di prossime mosse oppure
mettiamo una relazione è la stessissima
cosa tale per cui su alcuni testi
troverete che delta per le macchine non
deterministiche è una
relazione di transizione e non una
funzione di transizione, ma il senso è
quello, cioè quindi il programma per una
macchina non deterministica è la stessa
cosa di una macchina deterministica.
Quello che cambia è che in alcune
circostanze,
ok, questa funzione può specificare
più possibili next steps. Ok? Questa è
l'unica differenza. Prima cosa da
sottolineare, è necessario che la
funzione di transizione di una macchina
non deterministica sia non
deterministica su tutte le possibili
coppie, no? Come possiamo vedere
nell'esempio che ci siamo fatti, il non
deteriorerminismo sta solo qua, fra
l'altro solamente su un simbolo
soltanto, no? Anche qui, eh, pure su
uno, uno, eccetera. Ok? Quindi
la macchina non è necessaria che sia
tutta non deterministica,
basta che abbia parte della funzione o
della relazione di transizione che mappi
verso un insieme di cardinalità maggiore
di uno. Ok? In quel momento la macchina
diventa non deterministica. altre
definizioni equivalenti di questa
macchina che potreste trovare in giro
su altri testi se li se li consultate.
Dico il testo di Aurora le definisce in
un modo un po' differente, però sono
equivalenti, eh non cambia assolutamente
niente. Io preferisco questa perché è
più semplice.
Nel testo di Aurora la macchina non
deterministica è definita
con due funzioni di transizione,
una che chiama delta 0 e l'altra che
chiama delta 1. E non determinismo
deriva dal fatto che ogni volta che la
macchina si trova in un certo stato e un
certo simbolo, potrebbe prendere la
prossima prossimo passo o da delta 0 o
da delta 1. Ok? si può dimostrare che è
la stessissima cosa. Noi facciamo
riferimento a questo perché è più
semplice, anche perché il testo, il
primo che vi ho consigliato, è quello di
Opcroft. Usa questa qua, è quello
classico, continuiamo a usare questo, va
benissimo. Ok.
Alright.
Quindi mh mh
cosa vedete? Vedete, ad esempio, per
l'esempio
qua, quello lo vedete? Sì, lo vedete? Ad
esempio, se noi abbiamo, per l'esempio
che ci siamo scritti in alto delta di
Q10,
che cos'è?
è un insieme. È un insieme, quindi ci
pacchiamo una bella
parentesi che raffa, ok? Un insieme che
contiene cosa? Contiene triple, ok? Un
insieme di triple. Triple che ci dicono
che dobbiamo fare. Ok? La prima tripla è
com'è?
Q0 Q0
wait again. Un uno.
Ah, ok. Stai andando su quello. No, no,
no, no. Attenzione,
sono in Q1 e leggo zero. Ok. Ah, sì, sì.
Zero. E poi
sinistra. Sinistra. Ok? E questa è la
prima tripla. L'altra tripla
Q1, eh Q1 0 destra. Ok? Quindi la
funzione di transizione per quella
coppia specifica ci sta dando due
possibilità. Ok? Quindi è questo. Quando
noi diciamo che mappiamo verso l'insieme
delle parti è perché noi abbiamo che
questa funzione Qua c'è spazio. Sì. che
questa funzione, ok,
applicata su degli input particolari può
dare origine a due risultati,
ok? Cioè che sono gli insiemi che fanno
parte di questa cosa qua. Ok?
Avete ricopiato la macchina?
Ok, perché ci dobbiamo spostare per
farvi un esempio. Alri.
Vi ricordate quello che ci interessa ora
è
vedere come questa macchina computa su
un particolare input che gli diamo
impasto, ok? Per vedere che genere di
giri inizia a fare.
Chiaro?
Vi ricordate che concetto abbiamo
utilizzato
sulle macchine deterministiche per
catturare lo stato di avanzamento della
della computazione
e configurazioni, ok? Le avevamo
chiamate configurazioni o descrizioni
istantanea, instantaneous description.
Ehm Ok. E vi ricordate com'erano fatte?
erano delle stringhe che contenevano che
cosa?
Attenzione, attenzione.
Lei stava. Supponiamo che la macchina
Ok, riarriviamoci assieme. Supponiamo
che la macchina sta girando. Tr tra tr.
Arriva a un certo punto la corrente se
ne va. Supponiamo che vogliamo farla
ripartire, cioè si dimentica tutto.
Vogliamo farla ripartire da uno stesso
punto. Che informazioni ci servono?
Lo stato in cui era. Ok, e questa è
un'informazione che ci serve.
Quello che ci stava sul nastro, ok? La
parte non blanca del nastro, perché
ovviamente senò serve una cosa infinita,
ok? Quindi la parte non blanca del
nastro e poi e dov'è la testino? E
dov'era la testina? Ok? Quindi noi
abbiamo questo genere di informazioni ci
permettono di far ripartire la macchina
da dove è rimasta. Ok? Questa è una
metafora. Ovviamente per noi una
configurazione sono le informazioni per
capire fin dove è arrivata la macchina.
Ok? Noi non memorizziamo nella
configurazione la sua funzione di
transizione, ok? È solo una questione di
dove sta computando in quel momento. E
vi ricordo che praticamente la
configurazione era la stringa del
contenuto del nastro.
più il simbolo dello Stato che appariva
in mezzo agli altri per dirci dov'è che
stava la testina. Questa è la
configurazione. Ok? E noi avevamo detto
che la computazione per una macchina
deterministica,
ok? era praticamente la sequenza di
configurazioni, cioè la sequenza di
fotografie che la macchina attraversa
nel momento in cui viene avviata e
arriva fino in fondo. Ok? Poi c'era se
era parziale, non era parziale, se
arriva in fondo, se non arriva in fondo,
avevamo fatto tutto quel gran casino,
insomma, per dare un po' di definizione.
Ok? Quello che vogliamo fare ora è
vedere la sequenza delle configurazioni
di questa macchina non deterministica su
un particolare input. Supponiamo di
avere input la stringa 01.
Ok?
Qua c'abbiamo spazio. Sì, qua vedete più
o meno. Alr
Ok. Allora, configurazione iniziale
della macchina. Qual è?
Vi ricordo che la configurazione in cui
la macchina viene accesa, quindi la
macchina è nello stato iniziale che è
Q0.
Cosa ci sta sul nastro?
La string input che è 01 perché abbiamo
deciso così. Ok, quindi noi vogliamo
vedere adesso che succede. Ok?
Alri,
qual è la configurazione successiva?
Quindi siamo, prendete il grafo della
vostra macchina,
indisiamo in Q0,
leggiamo zero che dobbiamo fare?
Mh.
Scriviamo 1, andiamo avanti e rimaniamo
in Q0. Quindi questo 0 qua deve
diventare 1. Quindi la configurazione
successiva è 1.
Stiamo andando avanti, quindi la
testina apparirà qua e poi qui avrò
zero. Ok? Il nuovo stato è Q1, quindi lo
Q0, cioè Q0 e qui abbiamo 1. Ok? Quindi
questa è la nuova configurazione. Ok.
Prossimo passo.
Mh. Fare Q.
Andiamo in Q1. E che facciamo?
0. Ok, quindi andiamo in Q1
1 0. Ok, questo uno qui è diventato zero
qua perché ci abbiamo scritto di Ok,
siamo in Q1 0 dopo.
Che succede là?
Come? Scus.
Ok, quindi lì la macchina ha due scelte
e noi mettiamo
e noi lì mettiamo due branch,
uno di qua e uno di qua. Ok. Primo
branch. Quale volete considerare?
Mh.
Quello che va in zero. Quello che vengo
zero. Ok.
Allora, siamo in uno, leggiamo zero,
scriviamo zero e andiamo dietro.
Eh, no, leggiamo uno. Siamo in Q1,
leggiamo uno e andiamo dietro. Allora,
andiamo in questa configurazione qui. Q0
blank
1 0.
Dov'era questo?
Questo uno viene sovrascritto da questo
stesso uno. Poi, siccome stiamo
spostando la testina dietro, qui
introduciamo blank per sottolineare che
la testina sta leggendo il primo blank
prima del degli altri. Ok?
Dall'altro lato invece
eh sì
1
Q1
0. Ok.
Alright. Focalizziamoci sulla
configuration di sinistra. Prossimo
passo. Non c'è non c'è. Ok, quindi
questa è una configurazione finale o no?
Sì, secondo la nostra definizione una
configurazione finale quando non c'è un
prossimo passo. Quindi questa è una
configurazione finale. Ok, sto
riutilizzando un po' di definizioni. Poi
questa configurazione finale è
accettante o rigettante?
Non è accettante, quindi ci mettiamo una
bella X. Ok? Quindi vuol dire che se la
macchina processa dall
si va a bloccare da una parte dove
risponde di no. Ok?
Andiamo avanti.
Vediamo questo ora. Ok.
Siamo in Q1 e leggiamo 0.
Quali sono Qual è la possibile mossa
successiva?
Mh,
scusi,
ma quante ce ne stanno? Uno o due? Ce ne
stanno due.
Ok. Ok. Quindi mettiamo doppio branch.
Ok.
Facciamo quella di Q0, ad esempio.
Quindi leggiamo 0, lasciamo 0 e andiamo
indietro e ci muoviamo in Q0. Quindi è
Q0 1 0.
Dall'altro lato
è che leggiamo 0,
lasciamo Z0,
rimaniamo in Q1 e stiamo leggendo il
primo blank dopo il testo, cioè dopo la
stringa che sta su nastro. Ok, di nuovo
focalizziamoci ora su questa qua. Siamo
in Q0,
leggiamo
1,
quindi sovrascriviamo l'uno con lo 0 e
andiamo in Q1, ci muoviamo a sinistra,
quindi è q1 blank 0.
Dall'altro lato
abbiamo
eh dove siamo in Q1 e leggiamo blank.
Lasciamo il blank lì dov'è, andiamo
avanti e ci spostiamo in Q2. Quindi
abbiamo 1 0 blank Q2 blank. Ok,
consideriamo questo.
Siamo in Q1. Leggiamo blank. Che
facciamo?
Ci scriviamo blank di sopra, spostiamo
la testina avanti e transiamo verso Q2,
quindi è Q2 0.
Focalizziamoci su questa. Siamo in Q2 e
leggiamo blank. Che facciamo?
Mamo,
ci fermiamo, ci fermiamo. Quindi è una
configurazione finale. Questa
configurazione
ha uno stato accettante o no? Sì, di
conseguenza questa è una configurazione
accettante per noi. Ok,
andiamo a guardare quest'altra che era
rimasta appesa.
Q2 00. Siamo in Q2 e leggiamo zero. Che
facciamo?
Ci blocchiamo. È una configurazione
finale. Sì. Lo stato Q2 è uno stato
accettante. Sì. Quindi questa è una
configurazione accettante. Ok? Quindi
questa macchina
Ok,
ha un modo per rifiutare e due modi per
accettare. Ok?
intuitivamente,
poi diamo la definizione più precisa
dopo, una macchina non deterministica
accetta il suo input se ha un modo per
farlo. Ok? Questa è la definizione di
macchina, di condizione di accettazione
di macchina in tuning. Poi la rivediamo
un attimo più ritoccata. Ok?
Alright.
Quindi in questo esempio specifico,
siccome c'è una sequenza di passi che la
macchina può compiere al fine di
rispondere sì, questa macchina risponde
sì. Ok?
Supponiamo
quindi che abbiamo questa bella macchina
sul tavolo qua,
gli diamo 01 input. Questa macchina deve
accettare, ok? Perché per definizione
questa macchina deve accettare.
Abbiamo scritto 01 sul nastro, glielo
stiamo dando input. La prima macchina la
i primi passi della macchina. Primo
passo, la macchina fa questo.
Secondo passo, la macchina fa questo.
Ok. Terzo passo, la macchina deve fa
qualcosa. Ok.
Cosa ci aspettiamo di osservare sulla
macchina che sta computando?
Mh.
Eh, quale
conta
che deve accettare? Eh,
potrebbe scegliere una delle due per
fare backing.
Potrebbe scegliere una delle due e fare
backtracking. Quindi, come terzo passo
la macchina noi potremmo osservare che
la macchina fa uno dei due passi, poi in
caso di problemi torna dietro e e fa
l'altra strada. Ok, questa è una
possibilità. altre
un'altra è ha una palla di cristallo e
sceglie direttamente quella giusta. Ok,
gli abbiamo inserito questa
scheda magic. Ok, arrivato là la
macchina non sa che fare, consulta
l'oracolo, gli dice "Vai da quel lato è
meglio". E la macchina segue questa
cosa. Ok. Altro?
La macchina potrebbe tirare la monetina,
la butta al cazzo, tira la monetina in
base a quello che esce la macchina fa
una strada l'altra e se poi arriva da
una cosa sbagliata, eh, torna dietro,
fixa tutto e continua.
Oppure potrebbe rimanere incastrato in
uno stato piùante. Altro,
l'altro è la macchina si sdoppia.
Da un lato prova una strada, da un lato
prova l'altra. Ok? Queste sono tutte
cose che la macchina potrebbe fare. Ok?
Ma quale di questa fis
come non esiste.
Sei accogli? No, non esiste. Cioè non
può esistere una macchina che la
macchina non così non esiste la macchina
non fa niente di tutto ciò. Ok. Non fate
ritrar.
Quelle che abbiamo detto sono tutte
metafore che nei libri potreste trovare.
La macchina va a casa, la macchina le
prove tutte contemporaneamente, la
macchina va in backtracking fino a
trovare la strada. La macchina sente da
dove deve andare e si butta di là. Ok.
La macchina sa che fare, so tutte
metafore. Niente di tutto ciò è ciò che
la macchina fa, perché una macchina del
genere fisicamente non esiste. Ok?
Quindi tutto il discorso che è partito
era fallace dall'inizio quando vi ho
detto supponiamo di avere la macchina su
questo tavo. No, questa macchina sul
tavolo non la possiamo avere. Questo
genere di macchine,
così come sono definite non esistono.
Allora, perché mai ci dovremmo occupare
di studiare roba che non esiste?
Perché è più facile e cioè quella è
sempre quella la ragione perché è più
semplice.
Le macchine inuring non deterministiche
sono state introdotte come modello
astratto di calcolo, no? Perché a quel
tempo si cercava di capire quali sono le
funzioni calcolabili, quali sono le
funzioni non calcolabili e si vide che
se si utilizzava questo stratagemma
della macchina non deterministica si
potevano semplificare tutta una serie di
cose, ok? Tale per cui conveniva usarla.
Quindi noi che facciamo? Noi utilizziamo
il modello della macchina di touring non
detergico,
sebbene non esista
perché è più semplice ragionarci sopra.
Ok? Vedremo dopo la pausa o prima della
pausa, no, dopo la pausa vedremo che in
realtà, cioè questo non è un salto che
facciamo nel vuoto. Noi possiamo fare
questa assunzione di lavorare sulle
macchine non deterministiche perché
abbiamo dei modi per gestirle, per
simularle.
Ad esempio, tutto quello che avete detto
in qualche cioè tutto no, però la strada
del back trading è una strada fattibile.
Voi che avete fatto algoritmi e
strutture, avete visto gli algoritmi in
background, non l'avete fatto?
E ci metteranno, però di principio se
può fa', cioè io ci provo, arrivo,
rifiuto m cazzarola. Va, vado al punto
di scelta precedente, vediamo che cosa
cavolo era successo. Provo ad andare.
Ok, esploro questo albero, sbatchiamo la
testa contro il muro, non va bene,
risaliamo.
Che avevo scelto, non va. Proviamo
l'altra strada, sbattiamo di nuovo,
torniamo indietro. Quindi, insomma, via
back trading se può fare, ok? Cioè,
quindi è una cosa fattibile.
Focalizziamoci per il momento sulle
definizioni formali adesso di questo
modello di calcolo, poi ci lavoreremo un
po' meglio dopo la pausa, però prima
formalizziamo tutto.
Le configurazioni
per le macchine non deterministiche sono
equivalenti alle configurazioni delle
macchine non deterministiche. Ok? Quindi
una configurazione per una macchina non
deterministica, come abbiamo visto, è la
stessima cosa, una sequenza di simboli
che ci dice il corrente contenuto del
nastro, qual è lo stato, dove sta la
testina e usiamo lo stesso formalismo.
Ok?
Una configurazione iniziale per una
macchina non deterministica è la stessa
cosa, Q0 seguito dall dalla sequenza dei
simboli della scriv input. Ok?
Configurazioni finali per le macchine
non deterministiche uguali. Una
configurazione per una macchina non
deterministica è finale se non ammette
configurazioni successive.
Ok? Una configurazione finale è
accettante, se lo stato che appare è
accettante. Una configurazione finale è
non accettante, se lo stato che appare è
non accettante. Ok? Questo è tutta roba
stessa, identica, spiccicata alle
macchine deterministiche. Non stiamo
cambiando niente. L'unica cosa che
cambia sulle macchine non
deterministiche è che una data
configurazione
può avere più legal successo. Questa è è
la è l'unica differenza. Ok? Per le
macchine deterministiche, data la
configurazione, se noi conosciamo la
funzione di transizione, abbiamo una
sola possibile prossima configurazione
sulle macchine non deterministiche.
Questo non è detto. Come potete vedere
nell'esempio sopra, non è che noi a ogni
step non sappiamo dove andare, cioè ci
sono pezzi di computazione
deterministica, ci sono pezzi di
computazione non deterministica e così
via. Quindi la differenza è che i legals
accessor di una configurazione per una
macchina non deterministica
possono essere più due. Ok?
E come abbiamo visto in questo esempio
qua,
la sequenza delle configurazioni,
più che essere disposte su una lista,
come facevamo per una macchina, no, su
una macchina deterministica,
la sequenza delle configurazioni per una
macchina non deterministica noi la
possiamo organizzare in un albero, ok?
E quindi introduciamo un concetto che
non avevamo introdotto per le macchine
deterministiche, ma solo perché era
farlottocco, eh, non perché non si può
fare. Il concetto di computation 3,
albero della computazione.
Cos'è un computation 3 per una macchina
non deterministica?
E definiamo la schiena, guardiamo il
disegno, è un albero
e quindi come gli alberi è costituito da
nodi, rami, uno di questi nodi è la
radice, ci saranno alcune foglie. Ok?
Quindi un computation 3 per una macchina
non deterministica su una specifica
stringa di input,
sostanzialmente deve catturare quali
sono tutte le possibili computazioni che
la macchina potrebbe in linea di
principio fare su una determinata
stringa di input. Quindi o computation 3
per una macchina M su una stringa W
è un albero
i cui nodi
sono tutte le possibili
configurazioni
in cui
la macchina M
può mai trovarsi
mentre processa
la stella W.
Ok? Quindi quali sono i nodi di questo
albero? sono tutte, cioè le possibili
configurazioni
della macchina in cui la macchina si può
mai trovare
mentre processa la stringa do B. Ok?
Questo caso perché non deve essere a
perché se abbiamo per esempio
diciamo prima
se la macchina ruffa c'è noi laamo di là
è l'albero è l'albero
Sì, sì. L'albero C. Bene. Se c'è un lupo
scrivere e noi abbiamo un rato se c'è un
gruppo. Ok.
infinito, cioè abbiamo r infinito,
abbiamo alberi, sono robe strane queste
compri, ok?
Tanto non lo dobbiamo, come vedremo, non
lo dobbiamo rappresentare è una cosa che
ci serve solo a noi per per ragionare.
Ok?
La radice di questo albero è la
configurazione iniziale della macchina M
su w, quindi c'è uno solo, cos'è? È Q0
con la W.
E c'è dobbiamo definire adesso gli
archi. C'è un arco da una configurazione
alfa a una configurazione beta,
se beta è uno dei successo real. Ah,
finito. Questa è la definizione di
computation 3 per una macchina di tuning
deterministica.
Alfa beta.
Dati due nodi alfa e beta dentro il
configuration il computation 3 alfa è
collegato a beta
se c quindi c'è un link da alfa verso
beta se beta è uno dei legal successo di
alfa. Ok? Quindi abbiamo semplicemente
formalmente definito quello che ci stava
là. Ok?
Chiaro?
Alri.
una macchina di touring,
una macchina di touring M non
deterministica accetta il proprio input
w
se all'interno del computation 3 di m su
w appare una configurazione accettabilis
accetta una stringa B
se e solo se
nel computation 3 di M su w
compare
da qualche parte, non ci interessa dove,
né ci interessa come arrivare là.
Accetta se nel computation 3 compare una
configurazione accettante,
quindi basta che esiste.
La macchina per accettare basta che
abbia un modo, ne basta uno. Eh,
può avere un milione di miliardi di
computazioni diverse e una sola di
quelle accettante. La macchina risponde
di sì su questo ok? E per rispondere no,
che deve fare? Che deve succedere?
Non ci devono essere. Cioè tutte le
computazioni
dentro
il computation 3 o vanno a sbattere
verso configurazioni finali non
accettanti o non terminano mai. Cioè son
cose lunghissime.
Ok, vediamo se vi devo dire altro prima
della pausa.
La domanda la domanda ve l'ho fatta.
La macchina accetta se c'è un brzo
accettante. No, ci possiamo fermare.
Facciamo 10 minuti applauso.
Ok, cool.
Ok, quindi prima abbiamo detto che
noi ci interessiamo del modello macchine
di touring non deterministiche
perché è più semplice. Questo sì è vero,
che ci dà più libertà nella
programmazione delle macchine. Così è
vero, ma questa cosa sarebbe usata
solamente
se una macchina di touring non
deterministica.
Meglio questa cosa sarebbe sensata
solamente se una macchina di Touring non
deterministic
se una macchina di Touring
deterministica
fosse in grado di fare ciò che la
macchina non terministi fa. Ok? Cioè,
quindi noi c perché ah è bello avere
questo modello così potente che però poi
non siamo in grado di costruire. Alcuni
di voi la volta scorsa mi hanno chiesto
"Ma le macchine di Touring non
deterministiche sono le macchine
quantistiche?" No, una macchina di
Touring non deterministica
ha un potere particolare che una
macchina quantistica non ha. Ok?
Allora,
perché mai ci dovremmo concentrare, no,
su questo modello astratto di calcolo,
se poi non lo possiamo costruire, magari
tramite una macchina non deterministica
siamo in grado di fare cose che una
macchina deterministica no,
non è in grado di fare e anche con
grazie al cioè che facciamo? ci dobbiamo
un attimo
verificare che non ci stiamo muovendo
verso territori che ci portano verso
strade che non vorremmo
battere. Ok?
Allora, la domanda ora è: è vero o no
che tutto ciò che siamo in grado di fare
meglio, poniamola meglio, è vero, no,
che tutti i linguaggi
accettati da macchine
non deterministiche
possono essere accertate da macchine
deterministiche,
perché se questo è il caso. Allora, il
gioco è fatto perché noi, almeno in
questa prima parte del corso, ci
interesserà studiare la calcolabilità
dei problemi, cioè se una cosa ammette
un algoritmo o non ammette un algoritmo.
Quindi, nel momento in cui noi siamo in
grado di dire, guarda
che questo, cioè tutto ciò che fai con
una macchina non deterministica, lo fai
anche con una macchina deterministica.
Allora, possiamo usare il modello del
non determinismo perché abbiamo
degli option anche sulle macchine
deterministi che non abbiamo, cioè siamo
in grado di definire una computazione
tramite una macchina non deterministica
in maniera molto più semplice. Però per
fare questo ci serve questo passo
internello. Dobbiamo stabilire se sia
così o meno. Cioè, è vero che se io ho
una macchina non deterministica che
accetta,
guys, sottolineo qua, accetta e non
semplicemente decide. Eh, è vero, no,
che se io ho una macchina non
deterministica che accetta
un certo linguaggio L,
allora ne esisterà una deterministica
che accetta lo stesso linguaggio L.
Questa è la questione. Se fa o non se
fa? Secondo voi si può fa'?
Sì. Sì, è così come
Allora, certo. Senò non ti sentono già
non ti sento. Ma po io sono mezzo
influenzato, quindi
vai. Devo scrivere una nuova conzione
sopra.
Ok. Ok. Così stai scendendo però nel
dettaglio sta scendendo nel dettaglio di
come fare a livello intuitivo che
dobbiamo fare questa macchina
deterministica
back trading. Ok? Cioè era l'idea che
abbiamo avuto prima, la macchina
deterministica, se progettata in maniera
sensata,
magari tramite backtracking,
allora noi siamo in grado di progettare
una macchina deterministica
che accetta lo stesso linguaggio della
macchina, non determistico. Magari lo
farai in un modo un po' diverso, però
l'importante è che dia le stesse
risposte che se la macchina non
deterministica accetta,
la macchina deterministica deve
accettare pure. E se la macchina non
deterministica non accetta,
allora la macchina deterministica deve
pure non accettare. Ok? Quindi dobbiamo
adesso inventarci, non entreremo troppo
nei dettagli, però vedremo il principio
che ci sta dietro.
Qualche trucco per riuscire a far
accettare a una macchina deterministica
il lo stesso linguaggio di una macchina
non deterministica.
Ok? Supponiamo di avere Sì.
Supponiamo di avere una macchina non
deterministica N.
Questa è non deterministica
per semplicità è monodonastro.
Sappiamo da tutto quello che abbiamo
visto nelle lezioni precedenti, che noi
possiamo ricondurre tutto a macchine
mononastro e la stessa cosa si può fare
per le macchine non deterministiche.
Quindi, pure che fossimo partiti da una
macchina di touring non deterministica
multinastro, abbiamo modi per tradurla e
farla diventare una macchina non
deterministica, mononastro. Quindi
supponiamo che N sia una macchina non
deterministica
mononastro,
la trasformiamo in una macchina M
deterministica multinastro. Ok?
Poi per quello che sappiamo pure la
macchina M, essendo
multinastro può essere riconvertita a
una macchina standard mononas. Ok?
Stiamo facendo questa cosa semplicemente
perché vogliamo essere certi che da ora
in poi noi possiamo utilizzare il
modello non deterministico per stabilire
se un dato problema è risolvibile o non
risolvibile. Ok? Quindi questa,
supponiamo che la computazione della
macchina n
su un certo input sia così. Ha un certo
ID0.
Da questo c'ha un ID one.
Primo.
Ah, ID one secondo.
Da questi abbiamo ID2 tu primo.
L'albero di computazione della macchina.
Sì. ID tu. secondo
ID
2/3 e questi continuano. Ok? E questo
continua, ok? Supponiamo che la macchina
sta computando in computerebbe in questo
modo su una certa
string input, ok? Cioè che quindi può
branciare in varie cose. Ok? Adesso
quello che noi facciamo
utilizzare una macchina di touring
deterministica
per esplorare l'albero di computazione.
Sostanzialmente dobbiamo fare il back
train. Ok?
La macchina M è una macchina
multinastro con due nastri.
Primo nastro,
secondo nastro. Ok.
Ci sono vari modi per simularli, eh
questo è uno dei tanti, preso dal libro
Opgroft. Ok? Allora, che fa sta
macchina? Sta macchina deve
sostanzialmente
esplorare in maniera sistematica i rami
di computazione che stanno qua dentro.
Questa è la cosa, ok? E lo dobbiamo fare
in maniera sistematica.
Perché noi dobbiamo accettare
M deve accettare se solo se N accetta.
Ok? Quindi dobbiamo stare attenti a non
fare fesseria.
Alri? Allora, la macchina funziona così.
Come prima cosa noi ci scriviamo,
siccome noi conosciamo qual è la
funzione di transizione della macchina N
a partire dalla funzione di transizione
della macchina N di Napoli, stiamo
producendo il programma della macchina
M, quindi noi mentre progettiamo la
macchina M noi lo sappiamo com'è fatta
la funzione di transizione o la più
precisamente la relazione di transizione
di n. Quindi quella cosa la possiamo
sfruttare. Ok? Quindi come prima cosa
questa macchina scrive la macchina M
scrive sul primo nastro ID0, cioè la
configurazione iniziale. Ok?
ci mette un bell'asterisco qua,
dopodiché fa questo, ricopia
i D0
su secondo nastro. Ok?
Dopodiché
come senza asterisco. Sì, sì, sì, sì. La
copia asterisco è perché ci serve a
separare delle cose, eh.
Dopodiché qui inizia la parte
trucchettosa, ok? M è una macchina che
stiamo progettando a valle della
conoscenza di N, quindi noi sappiamo n
che cosa come si comporta, cioè quali
sono i suoi possibili next step in
dipendenza del simbolo che legge. Ok?
Quindi, se in un particolare per la
lettura di un particolare simbolo noi
sappiamo che la macchina ha due
possibilità, supponiamo che la relazione
di transizione abbia due possibilità e
questo numero due è fissato perché sta
nella relazione di transizione. Eh, vi
ricordo che la relazione di transizione
di una macchina, cioè il suo programma è
hard coded nella macchina, non è che è
una cosa che cambia a tempo di
computazione. Ok? Allora, se sappiamo
che ha due possibilità, noi facciamo due
copie di ID0
sul primo nastro
ID0. Mettiamo l'asterisco ID0. Ok,
chiaro? Scusa, lo sto usando solo per
separare. Solo per separare. Sì, sì, sì.
Quindi in gamma non lo mettiamo solo Sì,
sì. fa parte di gamma. È una cosa che ci
serve per separare configurazioni. Eh,
quando scrivo D0 là significa che io sto
scrivendo dei simboli della
configurazione, cioè io mi scrivo
proprio la configurazione sul nastro.
Ok? Interessanto. Sì, sì, sì. Scrivo
configurazione perché stiamo esplorando
l'albero. Ok.
Al posto dell'asterisco ci metto una
bella X, così là mi segno dove sono
arrivata. Ok.
A quel punto che cosa faccio io? Qui mi
ero fatto due copie di di zero perché
sapevo che c'erano, è un esempio, eh,
potevano essere tre copie, no? Se ci
stanno tre passi possibili,
vado a modificare
le copie che ho fatto in modo da
riflettere i possibili passi. Ok? Quindi
questo ID0 e quest'altro ID0 verranno
cambiati in maniera tale che qua c'ho
ID1 primo e qua c'ho ID1 secondo.
Chiaro?
Fatto ciò, cancello questo.
Ritorno sul primo nastro. Vado a vedere
dove sta la X. sta qua, quindi vuol dire
che mi devo concentrare da questo in poi
e faccio la stessima cosa. La prima cosa
che mi chiedo è ma non è che ID prim1'
è accettante? Se accettante accetto.
Senò che faccio? Lo ricopio qua
e poi faccio lo stesso giochino. Siccome
la funzione di transizione la conosco e
so quanti possono essere i possibili
next states, next configurations,
vi faccio le possibili cose. Quindi qua
c'ho ID,
ID e ID. Ok?
Capito? Quindi questi qua me ne faccio
tre copie. Dopodiché queste qui le
prendo e le modifico in maniera tale che
siano il du primo, il D2 secondo, il D2
terzo. Ok, qua sono fuori il bordo. È
chiaro? Quello è il principio?
E vado avanti così.
Fatto ciò, metto una X qua, così so che
fin lì l'ho considerato. Cancello questo
e vado avanti.
Verifico questo ID primo, ID1 secondo.
Mi chiedo è accettante o no?
Se è accettante accetto. Se non è
accettante lo copio sotto e faccio lo
stesso lavoro. Ok?
È chiaro? per tutti come funziona?
Vi è evidente che stiamo esplorando
l'albero?
Ok.
In che modo stiamo esplorando questo
albero? Bread first. Breadf. Questa è
una ricerca in ampiezza, ok?
E non è a caso. Perché non facciamo una
ricerca in profondità? Perché non
facciamo un vero e proprio backtracking?
Sì, potrebbe andare avanti più. Sì,
perché se uno di questi rami è non
accettante perché luppa.
Se facciamo una ricerca in profondità,
la macchina simulante, la macchina M,
quella simula e non si ferma mai, quando
magari a dei livelli più alti da
un'altra parte c'era una configurazione
accettante e avrebbe invece dovuto dire
sì. Ok? Vedi, questa è la ragione per
cui
noi facciamo una ricerca in ampiezza.
Facciamo la ricerca bread first per
essere sicuri che noi non ci perdiamo.
Perché la proprietà che noi vogliamo
ottenere, un attimo, la proprietà che
noi vogliamo ottenere è che m accetta se
solo se n accetta.
E quindi non possiamo rischiare che
nella nostra simulazione ci andiamo a
infognare
in un branch infinito. Ok? Questa è la
ragione per cui noi dobbiamo purtroppo
procedere livello per livello. Al primo
livello dove la macchina M
trova una configurazione accettante lì
si ferma e accetta. Se il computation 3n
non ha configurazioni accettanti,
allora nemmeno la simulazione di M
accetterà. Ok? Quindi il linguaggio
accettato da M è lo stesso linguaggio
accettato da N. Ok? Prego. E se invece
sono una strutturazione finale, ma non
accettante, cioè il fatto che io ho
voglia di non accettare quando n accetta
è la stessa cosa, cioè nel momento in
cui si arriva a una ID arriviamo lì,
questa configurazione è accettante.
Ah, è accettante. No, la ricopio sotto.
Poi vi dico quali sono i next state,
nessuno. finisce là, vado avanti. Quindi
in coda io non aggiungo nient'altro. A
un certo punto questa coda si esaurisce,
non avrò lasciato nulla in coda e lì mi
fermo in uno stato non accettante. Ok,
chiaro?
Ok.
La domanda ora per noi è quanto costa
questa simulazione?
Ok? Perché quando abbiamo simulato con
un nastro solo le macchine multinastro
avevamo che il costo era
all'incirca quadratico. Ok? Ma quanto
costa simulare una macchina non
deterministica?
Ok.
Ora,
dopo
un passo della macchina non
deterministica,
a che livello siamo nel computation 3?
Mh,
contiamo la radice zer quindi quello là
non ci siamo mossi. Dopo un passo,
a che livello siamo nel computation 3?
Siamo a livello uno e dopo due passi
a livello due e dopo tre passi a livello
3, dopo Lsiello
N. Ok? Però quest'albero nel frattempo
cresce e cresce e cresce. Ok? Nella
peggiore delle ipotesi noi abbiamo un
branching factor uguale su ogni
configurazione. Ok? Supponiamo che
la
funzione di transizione per m n abbia,
che ne so, m
No,
abbia C, chiamiamolo C,
senò si confonde con l'altro M. Ok?
Abbia C figli. Ok?
Se vogliamo simulare
n passi della macchina di touring non
deterministica,
dovremmo esplorare n livelli di questo
albero di computazione.
Quanti sono le configurazioni in questi
n livelli?
possibile m² o m³? No, attenzione, sono
molte di più. Eh, n
Allora, noi ci stiamo scendendo di
ragioniamoci assieme. Primo livello, ok?
Al primo livello c'abbiamo i di 0, ok?
È chiaro?
Alo zereso livello c'abbiamo il di0. Al
primo livello quanti figli ce ne
abbiamo? C
Ognuno di Andiamo al secondo livello.
Ognuno di questi c figli di primo
livello, quanti sottofigli avranno? C.
Quanti quindi figli abbiamo al secondo
livello? C alla seconda. C alla seconda
e al terzo livello?
c alla terza e al quarto livello c alla
quarta e all'ennesimo livello c^ n.
La macchina
deterministica
per simulare la macchina non
deterministica
ha una crescita di tempo di esecuzione
di O * C^ N. C a la M. Ok? C è una
costante, può essere 2, può essere 3,
può essere 1000. Quindi questa è una
funzione polinomiale,
no? È una funzione esponenziale, ok?
Perché n, il numero dei passi che è
legato, insomma, alla taglia dell'input
e compare all'esponente. Ok? Quindi, che
cosa abbiamo?
Abbiamo che
una macchina non deterministica, il
linguaggio accettato, qualsiasi
sia un linguaggio accettato da una
macchina non deterministica,
può essere accettato da una macchina
deterministica, il che questo ci toglie
le patate dal fuoco perché fino a quando
siamo interessati a stabilire dire se un
certo problema sia risolvibile o meno e
non ci interessa sapere se
efficientemente o no, ma siamo
all'inizio semplicemente interessati a
stabilire, ma questo problema io sono
interessato a capire, ma si risolve o
non si risolve
siccome tutto quello che è risolvibile,
decidibile, accettabili da macchine non
deterministiche e anche accettabili da
macchine deterministiche
Allora, per stabilire se un certo
problema, un certo linguaggio può essere
accettato in generale, cioè se ammette
un algoritmo per la sua soluzione,
quello che posso fare è vedere se ci sta
un algoritmo non deterministico,
perché perché è più facile, perché noi
abbiamo a valle di questo teorema la
garanzia che se lo so risolvere in
maniera non deterministica
esisterà sicuramente anche un modo
deterministico per risolverlo, ok?
E se non lo so risolvere con una
macchina non deterministica,
può essere risolto da una macchina
deterministica,
ma qua non lo sappiamo. Qui iniziamo a
muoverci in un reame di una cosa che
affronteremo fra qualche minuto. Quello
che voglio sottolineare prima è questa
cosa del costo della simulazione. Ok?
Noi abbiamo che il costo di questa
simulazione, quindi se noi abbiamo che
un certo linguaggio è accettato da una
macchina di Touring non deterministica,
noi lo possiamo accettare tramite una
macchina in touring deterministica.
Ragazzi, quando io parlo di macchine di
Touring, voi pensate algoritmo non
deterministico, algoritmo
deterministico, perché al finale quello
è. Vedremo che le macchie di di tuning
sono compiute. Tra qualche lezione
vedremo che hanno il potere dei computer
allora
se noi riusciamo ad accettare un certo
problema, a decidere un certo problema
tramite una macchina di due non
deterministica, questo teorema ci
garantisce che riusciamo a fare la
stessa cosa, riusciamo ad accettare lo
stesso linguaggio tramite una macchina
detistica. La pearità della macchina
deterministica è che è fisicamente
costruibile, ok? Quindi possiamo
costruire un device fisico che esiste
che è in grado di risolvere la cosa. Ok?
Questo teorema però ci dice anche che il
costo della simulazione è di tipo
esponenziale. Significa che una macchina
deterministica in linea di principio è
molto ma molto più lenta di una macchina
non deterministica, ok? Cioè c'è un gap
esponenziale qua. Non stiamo parlando
come la traduzione da multinastro a
monastro nel quale abbiamo un gap di
tipo poligoniale e il quadrato finisce
là. No, qui il g è veramente enorme. Ci
stiamo spostando di classe, stiamo
andando da un polinomio, ad esempio, a
un esponenziale. Oppure se la macchina
di non deterministica ci metteva tempo
esponenziale, la macchina deterministica
simulandola ci mette doppio
esponenziale, che sono funzioni che
crescono velocissime. Ok?
Allora, la domanda che io vi faccio è:
esiste o no un modo più furbo di questo
di quello che abbiamo visto per simulare
il funzionamento della macchina non
deterministica?
È chiara la domanda? Cioè, noi abbiamo
visto che la macchina non deterministica
si può simulare in questo modo
e che questo modo ci possa esponenziale.
Ma abbiamo un modo migliore di questo?
C probabilmente dipende dal problema,
cioè se fosse un problema in cui una
macchina diistica
può dipendere dal problema, sì, ma in
generale supponiamo, no, che sono di
quei problemi proprio tosti, no?
Abbiamo un modo migliore di simularla
in generale, no? Ok. Altri avevo visto
altre mani? Sì.
avreiuto quasi un Luca Ed, cioè NCO
non si taglia più di tanto in quel modo,
ma abbiamo alcuni in generale no, quello
non taglia un granché. Allora, questa è
il fatto che questa
simulazione che abbiamo visto ora, costi
esponenziali, ci garantisce che non
esistono simulazioni più veloci?
No. Ok,
questo è uno dei problemi fondamentali
dell'informatica teorica che aperto da
80 anni, probabilmente nessuno lo sa,
nessuno sa esista una simulazione
migliore di questa. Ok?
In tutto questo tempo nessuno è mai
riuscito a trovare una simulazione più
efficiente,
ma questo non significa che non esista.
Però non abbiamo nemmeno una
dimostrazione che una simulazione più
efficiente non ci sta.
Cioè, quindi da un lato noi non sappiamo
meglio di non sappiamo far meglio di
così, dall'altro non abbiamo nemmeno la
garanzia che meglio di così non si possa
fare, cioè semplicemente non si sa,
nessuno lo sa, ci hanno sbattuto la
testa le menti più grandi che
l'informatica teorica abbia visto negli
ultimi decenni e nessuno è mai riuscito
a risolvere la questione. c'è un premio
da 1 milione di dollari per chiunque sia
in grado di risolvere questa faccenda in
una qualsiasi delle direzioni. Eh,
una volta vabbò questo è legato, poi lo
vedremo, alle classi versus n dove
focalizziamo tutto su classi
polinomiali, deterministiche e non
deterministiche, ok? lì poi il problema
è stanziato là sopra. Però di fatto la
questione fondamentale qui è ma per
simulare una macchina non deterministica
posso far meglio di un gap esponenziale
o non posso far meglio di questo? Questa
è la questione e nessuno lo sa, nessuno
c'è mai riuscito né a ottenere una
simulazione più efficiente né a
dimostrare che non è possibile una
soluzione più efficiente. Ok? Questo da
un lato, scusi. Eh sì, un attimo. Posto
simulazione. Eh sì, ok. Sì. Una domanda.
Eh, ma se riuscismo a risolvere questo
gap, siccome i computer seguono comunque
un determinismo termino, cioè avremo
seguono un determinismo al momento. Sì.
Eh, avremo un incremento della
concezione di computer che
prevetterebbero dei calcoli in maniera
molto più veloce. Assolutamente. Se
fossimo in grado di simulare in tempo
polinomiale una computazione non
deterministica, saremmo in grado di
risolvere problemi sostanzialmente
irrisolibili al momento che sono di un
qualità utilità fantastica, che ne so,
determinare la forma delle proteine
tridimensionali, quello è un problema
tostissimo. Se noi riuscissimo a
risolvere questa cosa, una macchina non
deterministica è in grado di farlo in
maniera abbastanza efficiente, però il
costo di quella simulazione per noi è
esponenziale. Noi non siamo in grado al
momento di fare questo genere di
calcoli.
Ma tecnologie come computer quantistici
fanno colmare diciamo questo g in altra
maniera?
No, allora non è la mia area di ricerca,
quindi non le so dire nello specifico.
Qui entriamo nel reame di che cos'è
efficientemente risolvibile e che cosa
non è efficientemente risolvibile.
Da macchine quantistiche rendono
efficientemente risolvibile
qualcosa un po' di più di quello che al
momento per noi è efficientemente
risolvibile, ma non
hanno il potere delle macchine
mondeteriche, perché le macchine
quantistiche, che io sappia, sono
comunque legate ad alcune leggi della
fisica, tale per cui la computazione
deve avere delle alcune proprietà
fisiche specifiche che mi pare siano
legate all'entropia.
Quindi non è che su una macchina
quantistica abbiamo una reale macchina
non deterministica, cioè la computazione
che può fare in maniera efficiente
è di più di quello che riusciamo a fare
ora, però non è quello che è
efficientemente fattibile una macchina
non meteristica, poi lo vedremo quando
parleremo di complessità, però
uso la sua domanda per muoverci agli
ultimi due topic che affrontiamo prima
di salutare.
oggi che è questo.
Ma allora che cosa è in grado di fare
una macchina quantistica?
Che cosa è in grado di fare una macchina
non detergentistica? Quindi abbiamo
visto macchine m abbiamo visto macchine
multitraccia e le macchine multitraccia
non erano più potenti delle macchine
standard. Abbiamo viste macchine
multinast, quando dico più potenti, qui
intendo che sono in grado di calcolare
cose incalcolabili dagli altre, ok? A
parte l'ospidità, qua stiamo parlando
sola solo di feible feasible, ok? Quindi
le macchine multitraccia non sanno fare
che cosa delle macchine standard. Poi ci
siamo spostati sulle macchine
multinastro e abbiamo visto che le
macchine multinastro non sono in grado
di fare più cose delle macchine
standard. Possono essere più veloci,
però fanno sanno fare le stesse cose.
Ora stiamo guardando le macchine non
deterministiche. Le macchine non
deterministiche sanno fare più cose
nelle macchine standard? No, abbiamo
appena visto che sì, possono essere più
veloci, ma sanno fare le stesse cose.
Macchine quantistiche. Le macchine
quantistiche possono fare cose più cose
delle macchine standard? Ve lo dico io,
no? Non sono in grado di fare cose più
cose delle macchine di standard. Ma
allora che sta succedendo qua? Noi
stiamo aggiungendo orpelli su orpelli ai
nostri modelli di calcolo L multi
moltiracce, L multilastro e eh il
noneterminismo, ma non siamo al momento
in grado di schiodarci da quello che è
in grado di fare una macchina di turn. E
qui ci andiamo proprio a posizionare al
limite della calcolabilità.
A parte questi modelli, altri modelli di
calcolo erano noti negli anni 30, cioè
le macchine di Turing sono cose venute
fuori negli anni 30 per riuscire a
risolvere alcune questioni provenienti
dal mondo della matematica e a quel
tempo c'erano altri modelli di calcolo,
c'erano i sistemi di post, si chiamano i
lamp da calcolo, eccetera, eppure quelli
sono equivalenti a macchine di touring.
Quello che si può fare con il lamb da
calcolo si fa anche con macchine di
touring standard. Quello che si fa con i
sistemi di post si fa anche con macchine
di touring standard. Di conseguenza la
gente ha iniziato a pensare che tutto
quello che è possibile calcolare su
quell'estaterra è calcolabile da
macchine di touring standard. E questa è
la tesi di chargeing. Tesi di charge
com
così.
Tesi di
Charchy
George era Alonso Charch matematico che
era l'advisor di dottorato di Alan.
Quindi cè tesi di charge theoring è
molto semplice.
Tutto ciò che è calcolabile
è calcolabile da una macchina diing.
Ok? Chiara?
Tesì.
Tutto ciò che è calcolabile è
calcolabile da una macchina doing
aggiungerei standard, eh, perché abbiamo
visto che tutto si riconduce alle
macchine standard. Sì, tutto sono
standard, cioè sono anche macchine non
standard oppure sono tutte tutte le cose
che la gente si è inventata non è più
potente delle macchine diing monastro
deterministica.
Nessuno è mai riuscito a inventarsi
niente, né a costruire un aggeggio che
abbia un potere di calcolo che vada
oltre quello di una macchina di
deterministica monopast.
Da cui hanno iniziato a pensare "Ma vuoi
vedere che tutto ciò che è calcolabile
si può calcolare sulla maturing normale?
Perché la chiamiamo tesi di charge
Touring e non teorema di charge touring?
Perché purtroppo questa affermazione è
un po' self preferencia, ok? Perché non
è che stiamo specificando che cos'è
calcolabile, non è che noi stiamo
definendo la calcolabilità di una
funzione o di un problema a prescindere
e poi diciamo le macchine di Touring
sanno fare quello, no? Stiamo dicendo
che ciò che è calcolabile è quello che
si calcola tramite macchine,
però al momento nessuno è mai riuscito a
trovare qualcosa che sia più potente
delle macchining, quindi riteniamo che
questa cosa sia vera. Ok?
E quindi per le domande che ci facevamo
all'inizio, no, alle primissime
versioni, ma è possibile che da qualche
altra parte dell'universo gli alieni
abbiano delle macchine di calcolo che
facciano cose che le nostre non sanno
fare? Per quello che noi riteniamo
loro è così, cioè tutto ciò che è
calcolabile si calcola con
questo con questi modelli. Ok?
A questo punto possiamo introdurre e con
questo concludiamo due classi di
calcolabilità.
Ok?
Classi
di calcolabilità.
Ok. Cos'è una classe, in questo caso di
calcolabilità? Poi vedremo le classi di
complessità. Una classe di calcolabilità
è semplicemente un insieme di linguaggi,
ok?
e un insieme di linguaggi
e in particolare ne identifichiamo due.
Questa classe qua fuori che denotiamo R
è E adesso vi dico che cos'è
e questa classe è qua dentro che
denotiamo R.
La classe, partiamo da quella dentro che
è la più semplice, la classe R si chiama
R
perché là dentro ci stanno i linguaggi o
le funzioni ricorsive.
Uno potrebbe chiedersi, ma perché mai
ricorsive? Perché quando agli albori di
questa scienza le persone si occupavano
di che cosa fosse calcolabile e che cosa
non fosse calcolabile, a quel tempo si
riteneva calcolabile ciò che era
esprimibile tramite funzioni ricorsive.
Quindi il nome viene da lì, è rimasto
per questioni storiche, ok? Quindi la
classe R, che è la classe dei problemi o
dei linguaggi ricorsivi,
contiene tutti quei linguaggi
per i quali
esiste una macchina di Touring che li
decide.
Ok?
Quindi in R ci stanno tutti quei
linguaggi per i quali noi possiamo
progettare
a questo punto macchine di touring non
deterministiche, visto che possiamo
giocarcela.
Però se noi abbiamo macchine di touring,
che siano deterministiche, che siano non
deterministiche, per noi non fa molta
differenza dopo quello che abbiamo visto
stamattina.
Quindi un linguaggio L sta dentro R. Se
esiste una macchina di Touring qualsiasi
che lo decide e vi ricordo che una
macchina di Touring decide un certo
linguaggio L
se si arresta ogni volta e ci risponde o
sì o no. Ok?
Quindi questi sono i ricorsi.
R è un sovrainsieme di Redinsieme
dei linguaggi o problemi,
problemi di decisione. Eh, quando
parliamo di linguaggi e problemi, qua ci
stiamo riferendo ai problemi di
decisione, eh.
Il linguaggio re e il lingu e sì,
la classe re è la classe dei linguaggi
ricorsivamente
enumerabili,
si chiama così, sempre per ragioni
storiche,
enumerabili,
ricorsivamente
enumerabili
ed è l'insieme di tutti i linguaggi.
Ho problemi di decisione
per i quali esiste una macchina di
touring
di qualsiasi tipo
che li accetti.
È chiaro?
qualche altra nomenclatura e poi
chiudiamo. Quindi R sono i problemi che
possono essere decisi da qualche
macchina di Touring o linguaggi che
possono essere decisi da qualche
macchina di Touring e reinguaggi che
possono essere accettati da qualche
macchina di Turing. Vi ricordo la
differenza. Eh, accettati significa che
rispondiamo sì in tempo finito. Per il
no non diamo garanzie, ok? Però non
possiamo dire minchiate, nel senso che
se la risposta è no, non è che ci
fermiamo e diciamo sì, se la risposta è
no, o ci fermiamo e rispondiamo no o non
ci fermiamo proprio. Ok? La risposta
sbagliata non è contemplata.
Siccome R è l'insieme dei linguaggi
decisi dalle macchine di Touring,
noi chiamiamo i linguaggi in R anche i
linguaggi o i problemi decidibili per
ragioni ovvie.
Quello che non sta in R lo chiamiamo
indecciibile.
Ok?
Quindi qualcosa che sta in re
ma non in R per noi è indecidibile.
Perché è indecidibile? Perché se non c'è
un algoritmo che ci dia garanzia di
risposta nel caso di risposta negativa
è un po' un problema per noi perché se
noi gli diamo un input a questo
algoritmo, questo inizia a girare,
passano 10 giorni e non ci ha ancora
dato risposta, che facciamo? Aspettiamo
la risposta, ma la risposta potrebbe non
arrivare,
ok? E quindi siamo lasciati in un limbo
per i problemi in R e ma non in R che se
la risposta tarda ad arrivare noi non
sappiamo che farci con quella cosa. Se
invece il linguaggio è decidibile e la
macchina du mesi non ha risposto, noi
siamo sicuri che prima o poi sta
risposta arriva. Ok? Sui problemi non in
R questa garanzia non ce l'abbiamo. Ecco
perché i problemi fuori da R li
chiamiamo indecisibili.
A volte introduciamo una
differenziazione
e chiamiamo linguaggi re che non sono in
R, li chiamiamo semidecidibili,
giusto per dare un po' di
differenziazione, ma sempre indecidis.
Ok? Quali sono? Quelli in re che non
stanno in R.
quelli in R che non stanno in R noi li
chiamiamo anche semidecidibili, però i
semidecidibili hanno questo problema che
l'algoritmo non avendo garanzia di
terminazione per noi non è che sia
proprio utile, eh cioè perché non
sappiamo che farci quando la risposta
tarda ad arrivare quella potrebbe non
arrivare mai. Quindi e che facciamo?
Aspettiamo ancora.
Chiaro? No, ma quindi quelli
indecidibili sono fuori che stanno in R
e non in R perché stanno fuori? No, in R
ci stanno indecidibili.
Quello che non è in R è indecisibile.
Quello che non è in R, ma è in re,
qualcuno li chiama semidecciibili, ma
sempre problemi un po' rognosi sono,
cioè è molto meglio che i nostri
problemi siano decidibili, cioè nel
senso che st'algoritmo prima o poi si
arresta e ci dà la risposta. Ok? Chiaro
per tutti? E con questo per oggi
chiudiamo. Buona serata.