Allora, è tutto più o meno chiaro quello
che abbiamo fatto scorsa volta. Era
giusto un recapo velocissimo.
L'importante è che abbiate più o meno i
concetti, li rivediamo velocissimamente
oggi e poi introduciamo un concetto
nuovo. Ok?
Allora, come abbiamo detto
come abbiamo detto noi studieremo la
complessità non degli algoritmi ma dei
problemi. Ok? Questa è la differenza
sostanziale fra quello che avete visto
finora e quello che vedremo in questo
corso. Per questa ragione abbiamo
necessità di formalizzare i problemi.
Abbiamo detto che ci stanno problemi di
ricerca, che sono quei problemi per i
quali le risposte possono essere varie e
i problemi di decisione i quali hanno
come risposta solamente un buleano. Ok?
S no.
Abbiamo detto che praticamente eh i
problemi di decisione possono essere
vari, possono essere vari contesti, ci
possono essere matrici, grafi,
ipergrafi, qualsiasi qualsiasi cosa
viene in mente immagini, testo, bla, eh
tale per cui, insomma ehm
andarli ad analizzare da questo punto di
vista, cioè se non mettiamo delle
ipotesi di semplificazione di viene
tutto un po' indicato. Ok? Allora, noi
ci siamo andati a scegliere dei problemi
che avete già visto nella vostra
carriera, che è il problema di decidere
linguaggi. Ok? Perché facciamo questo?
Perché decidere in un linguaggio è un
problema di decisione. Vi ricordate cosa
significa decidere un linguaggio?
Verificare se una stringa appartiene o
meno Verificare se una stringa
appartiene o meno un dato linguaggio.
Quindi, qual è l'input?
una stringa.
Il linguaggio fa parte dell'input,
no? Ok, questo è importante. Ok, quindi
l'input
del problema di decidere un linguaggio è
dato una stringa e un linguaggio che in
qualche modo noi conosciamo, che ci
viene dato e definito all'interno del
problema. Noi dobbiamo decidere se
questa stringa fa parte di questo
insieme o meno. Ok?
Allora, poiché
noi abbiamo detto possiamo codificare,
no, con un codice opportuno
dentro i linguaggi varie cose,
sostanzialmente possiamo ricodificare,
ok, all'interno
di linguaggio opportuno i problemi e
decisioni a cui siamo interessati. Ok?
Chiaro per tutti come si fa? Perché noi
possiamo definire dei linguaggi appositi
su un alfabeto apposita, no? Tale per
cui le stringhe che fanno parte del
linguaggio sono, ok? Nel caso
nel caso dei problemi di decisione noi
abbiamo che nel linguaggio
fanno parte,
ok? Pensiamo a questo problema, il
problema dei grafi
totalmente connessi. Sapete cos'è il un
grafo completamente connesso, totalmente
connesso? Ok? È un grafo da cui da ogni
nodo si può arrivare a qualsiasi altro
nodo. Ok?
Supponiamo di avere questo problema. Ok?
Dato un grafo, stabilire se totalmente
connesso. Questo è un problema di
decisione, un problema di ricerca.
problema di decisione perché
perché la risposta in buuleano, cioè ci
danno un grafo, noi dobbiamo dire sì,
no. Poi, ok, può richiedere che ci
inventiamo varie cose prima di dire sì
no, però la risposta alla fine è o sì o
no. Quello fa sì che il problema sia di
decisione. Ok?
Se dobbiamo inventarci un linguaggio che
in qualche modo codifichi il problema di
decidere se un grafo è totalmente
connesso, che linguaggio potremmo
inventarci?
Ecco,
puoi dire un po' più adatto. Cioè, il
linguaggio stammina.
Esatto. Cioè, noi ci possiamo inventare
una codifica su dei simboli opportuni
tale per cui le stringhe che fanno parte
di questo linguaggio sono solamente
le stringhe che secondo la nostra
codifica
codificano un linguaggio, un grafo
totalmente connesso. Ok, è chiaro?
Supponiamo di ricevere input una stringa
stramba
che non codifica un grafo secondo la
nostra codifica. Ok? Questa stringa fa
parte del linguaggio? No, no. Ok? Perché
del linguaggio fanno parte solamente le
stringhe sensate, cioè che codificano i
grafici e che sono totalmente connessi.
Ok? Quindi da un lato
noi abbiamo che eh i problemi di
decisione possono essere reincoded in
linguaggi opportuni, tale per cui sulle
stringue per le quali noi dobbiamo
rispondere sì, sono le stringhe che
appartengono al linguaggio. Le stringhe
che codificano roba strana, per
definizione nostra, non stanno dentro
questo linguaggio. Ok? Ma questa cosa
ovviamente si può anche estendere ai
problemi di ricerca. Mh, pensiamoci un
po' assieme. Supponiamo che dobbiamo
codificare dentro un opportuno
linguaggio un problema di ricerca. Come
possiamo fare?
Il problema di decis, cioè risolve il
problema di decisione. Problema di
ricerca. Noi vogliamo codificare in un
linguaggio un problema di ricerca. Eh,
la mia risposta sarebbe stata prima
risolvo quello di decisione e lo trovo e
una volta che l'ho trovato lo leggo e mi
dà quella No, vogliamo codificare in un
linguaggio opportuno le stringhe che mi
codificano un problema di ricerca. Che
cos'è un problema di ricerca? Cos'è un
problema in generale?
Eh, è una una relazione che sono c
string di è una relazione binaria, sono
coppie, ok? Ricordatevi un problema sono
coppie di stringhe, input output, ok?
Solo che noi perché parliamo a che cos'è
l'input, che cos'è l'output, qual è la
relazione? Se in realtà un problema è un
insieme di coppie, perché i problemi che
ci interessano hanno una lista infinita
di coppie, quindi non è che possiamo
metterci a scriverle tutte. Allora, ci
dobbiamo inventare un modo per
descrivere in maniera finita una
relazione infinita. Quindi lo
descriviamo. Dice questo è l'input,
questo è l'output. La relazione fra
input e output è questa. Però di fondo
un problema di ricerca è una relazione
binaria tra stringer che associa input
ad output. Ok? Supponiamo noi volessimo
codificare dentro un linguaggio un
problema di ricerca. Che possiamo fare?
secondo, eh, vediamo se c'è qualche voce
nuova. Voci nuove. Niente, eh. Ok,
prego.
Mettere una
puoi alzare la forare una stringa in cui
è codificato grafo input e il grafo. Il
grafica input e il corso
ma tu stai suppendo, lei sta supponendo
che stiamo un problema di ricerca sul
graso.
Ok, riformuliamo. Quindi è un linguaggio
in cui abbiamo le stringhe che
codificano
input e l'output. Ok? Cioè noi abbiamo
in un linguaggio per ehm
codificare un problema di ricerca
abbiamo delle codifiche opportune su un
alfabeto opportuno
della relazione input output, ok? E in
quel linguaggio che ci stanno? Ci stanno
tutte le stringhe che codificano,
secondo la nostra codifica, le coppie
input output del problema in questione.
Ok?
Quindi a quel punto decidere quel tipo
di linguaggio
richiederà per noi sostanzialmente
calcolare la soluzione, anche se non è
propriamente così, lo vedremo poi nelle
lezioni a venire, ok?
E quelle coppie le cui la cui stringa di
input è una cosa stran linguaggio o no?
No. Quelle stringhe che non codificano
coppie ci stanno nel linguaggio, no? No.
Ok? Cioè, quindi noi possiamo sempre
codificare all'interno di un linguaggio
i problemi che a cui noi siamo
interessati, però per semplicità noi ci
focalizziamo sui problemi di decisioni e
di conseguenza siccome un problema di
decisione come risposte si no è un
linguaggio a di uccidere un linguaggio
ha come risposta sino la codifica al
linguaggio di un problema decisione è il
linguaggio che contiene tutte le istanze
sì di quel particolare. problema. Ok?
Così è unistanza sì, è un'istanza, cioè
una stringa che fa parte di quel
linguaggio o un input per quel problema,
la tua risposta è sì.
È chiaro? Quindi noi possiamo fare
sempre questo genere di di giochino.
Facciamo questa cosa perché perché ci
semplifica la vita. Ok?
Dopodiché abbiamo introdotto,
siccome noi vogliamo stabilire se un
determinato linguaggio sia decidibile o
meno e per noi intuitivamente, poi
vedremo più nel dettaglio questo che
significa, ma intuitivamente una cosa è
risolvibile se c'è un algoritmo che la
risolve, allora noi ci dovevamo
inventare degli algoritmi che
decidessero linguaggi. Allora, che
facciamo? Li facciamo in Java, li
facciamo in Python, li facciamo in
Gobble. Ok? Vien detto, per evitare di
impelarci, impantanarci nella sintassi
dei linguaggi, noi utilizziamo un
formalismo che è molto più asciutto, che
è il formalismo degli automa. Quindi noi
abbiamo che un certo linguaggio è
decidibile se esiste un automa che lo
decide. Ok? Oggi faremo differenza fra
automi che accettano e automi che
decidono. Ok?
Che cosa abbiamo visto? Abbiamo visto
due classi di autommi così
velocissimamente e poi che avete fatto i
linguaggi li avete sicuramente studiati
in maniera più approfondita, però due
due classi di automi molto semplici sono
gli automi deterministici a stati finiti
e gli automi non deterministici a stati
finiti, pure quelli. Ok?
l'intuizione che avevamo dato e quindi
riprendiamo questa perché oggi
lavoreremo su questa qua. L'intuizione
per un automa stati finiti, che sia
deterministico o sia non deterministico,
è questo.
L'automa ha un input.
L'input di quest'automa è un lungo
scontrino, è un nastro, ok? sui quali
vengono scritti dei simboli.
Sono i simboli dell'alfabeto su cui il
linguaggio è definito.
Chiaro? Sto andando troppo veloce.
Ok. L'automa che fa? Ogni volta che
legge un simbolo e si trova in un certo
stato di funzionamento,
transisce verso un nuovo stato e butta
via il simbolo, cioè va avanti sul
nastro. La caratteristica di questi
automi è che una volta che la macchina
supera un simbolo, va, porta avanti il
lettore, diciamo, quel simbolo è perso,
cioè non possiamo andare indietro a
guardarlo. Ok? Quindi questa è una
macchina che ogni volta che vedo un
simbolo deve tra virgolette fare
l'operazione giusta perché indietro non
torna. Ok,
abbiamo introdotto poi delle macchine
strane che erano delle macchine non
deterministiche. In cosa consisteva il
nondeterminismo? Il nonismo di queste
macchine consisteva nel fatto che questi
automi in presenza di un certo simbolo e
un certo stato interno di funzionamento,
non avevano una scelta obbligata su cosa
fare, ma potevano transire verso più
stati successivi. Ok? Quindi le macchine
non deterministiche avevano scelte, le
macchine deterministiche non hanno
scelte. Ok, ci siamo fatti questa
metafora. Allora, abbiamo detto che
formalmente una macchina accetta, una
macchina deterministica accetta se la
sua computazione deterministica va a
finire in uno stato accettante,
consumando tutto l'input. Una macchina
non deterministica accetta se ha un modo
di accettare il proprio input, ok?
Perché avendo varie scelte potrebbe
computarle in vari modi. Alcuni che
accettano, altri che non accettano.
Allora, ci siamo detti, ma se ci sono
modi per accettare e modi per non
accettare, la macchina dice sì o no? La
macchina dice sì ogni volta che c'è
almeno un modo per accettare. Ok,
chiaro? E ci sono classi strane in cui
la maggioranza delle computazioni deve
essere Sì, ma quelle forse alla fine se
abbiamo tempo le guarderemo.
Al momento facciamo il modello standard.
La macchina accetta se esiste almeno un
modo per accettare. Ok?
Risultato interessante che abbiamo
menzionato ma non dimostrato è che
le macchine non deterministiche, sebbene
sembrano sembrano più furbe delle
macchine deterministiche, in realtà
hanno lo stesso potere di calcolo, cioè
sanno fare le stesse cose, non sanno
fare più cose e in particolare non lo
sanno fare nemmeno più velocemente
perché si può dimostrare che automi non
deterministici
a Stati finiti possono essere
trasformati in automi deterministi già
Stati finiti equivalenti, cioè che
riconoscono lo stesso linguaggio e la
performance è la stessa, cioè il tempo
che la macchina ci mette a decidere una
stenda è sempre lineare perché guarda un
simbolo per volta, che sia non
deterministico, che sia deterministico,
ok? Cioè, quindi le macchine non
deterministiche, gli automi non
deterministici che abbiamo visto finora,
non hanno nulla di più potente di quello
che abbiamo. Sono più facilmente
programmabili rispetto alle macchine
deterministiche. Tutto qua. Perché ce le
siamo inventate? Perché progettare
automi non deterministici è più facile.
Poi lo diamo impasto a un compilatore,
ci mette in mano e tira fuori la
macchina deterministica. Ok? Noi non ci
siamo cervellati per capire come fare
una macchina deterministica. Ok?
Una cosa che abbiamo notato e ci siamo
lasciati con questo esempio la scorsa
volta era il linguaggio
delle
parentesi, a volte si chiama comunque
questo qua.
Allora, avevamo definito
avevamo definito
il linguaggio
delle stringhe sull'alfabeto AB tale per
cui abbiamo prima una sequenza di A, poi
una sequenza di B e il numero di B deve
essere uguale al al numero di A. Ok?
Questo era il constraint. Abbiamo visto
intuitivamente perché questa cosa non
può funzionare, cioè non ci può essere
un automa stati finiti in grado di
riconoscere questo linguaggio, né
deterministico né non deterministico. E
l'intuizione dietro era che la macchina,
cioè che l'automa Stati Uniti è troppo
semplice, non è in grado di contare. Ok?
Eppure noi abbiamo l'esperienza che in
Python, in Java eccetera. Noi siamo in
grado di riconoscere quel genere di
linguaggio. Ok? Allora, la cosa è che un
automa stati finiti è troppo semplice,
cioè non ha un potere di calcolo
sufficientemente forte da essere in
grado di contare le cose. Ok?
Introduciamo giusto questa notazione
perché ci serve poi che sono la
notazione dei linguaggi
regolari.
Allora, sia a sigma
un alfabeto,
un linguaggio regolare su sigma
è un linguaggio che si può ottenere
tramite
concatenazioni di simboli in sigma
e
altre parole. Ok?
Allora, una un linguaggio regolare è un
linguaggio le cui stringhe vengono
caratterizzate da quelle che si chiamano
espressioni regolari.
Le espressioni regolari sono un modo
compatto di esprimere linguaggi su
sull'alfabeto. Allora,
se alfa è un simbolo appartenente a
sigma,
allora alfa è un'espressione regolare.
Ad esempio, se noi abbiamo, che ne so,
sigma che è 0,
allora
solamente 0 o solamente 1 sono delle
espressioni regolari, ok?
Dopodiché abbiamo che se alfa e beta
sono
espressioni regolari,
allora
anche la concatenazione
alfa beta oplà è una espressione
regolare.
Ok? Quindi se noi avevamo che 0 e 1 come
simboli distinti sono espressioni
regolari, allora per questa ragione 00
sarà un'espressione regolare. 0 1
1 1 1 1 e insomma. Ok? Tutti i modi di
agganciare i simboli su sigma sono
espressioni regolari.
Un'altra espressione regolare è la
disgiunzione.
Alfa e beta sono
espressioni regolari.
Allora,
alfa or beta
è
un'espressione
regolare.
Alfa or beta è una stringa. E che cavolo
su?
alfa o beta or beta è una stringa una è
quelle stringhe fatte o dal pezzo alfa o
dal pezzo beta, quindi che ne so 0 1 0
or 1 per dire. Questa è un'espressione
regolare che ci dice che le stringhe che
fanno parte di questo linguaggio
regolare sono o 0 oppure 1 1.
Ok?
Se alfa è un'espressione
regolare,
allora
alfa star è un'espressione
regolare.
Cos'è alfa star? Alfa Star è una
concatenazione,
ok, di 0 più volte alfa. Quindi se noi
abbiamo che ne so 1 0 star, questo qua è
il modo compatto di dire che tutte le
stringhe che appartengono a questa
espressione regolare o linguaggio
regolare è
1 10 oppure 1 10 1 10 e così via. Ok?
Al posto di star possiamo avere un altro
simbolo, l'introduco perché poi quando
vedremo macchine toring sta cosa ci
serve. Al posto di Star possiamo avere
un altro simbolo che è il simbolo più
dove ci dice che quel pezzo di
espressione, cioè di quel pezzo di
parola si deve ripetere almeno una
volta. Ok?
Risultato interessante è che
gli automi a stati finiti,
deterministici o non deterministici
sanno riconoscere, sanno decidere tutte
e solo le espressioni regolari, cioè le
espressioni regolari è il potere di
computazione degli automi a stati
finiti. Loro non sanno fare più di
quello. Ok? Cosa interessante è che
questo linguaggio qui, che è il
linguaggio della parentesizzazione,
non è esprimibile tramite un'espressione
regolare. Ok?
Però, come abbiamo detto, noi abbiamo
l'intuizione che questa cosa si può
risolvere e allora dobbiamo introdurre
un altro modello di calcolo. Sì, prego.
Scusi, però perché allora se alfa star è
combinazione di alfa è anch'essa
regolare e la concatenazione alfa beta
abbiamo detto regolare perché eh a^ b^ n
nonostamente perché lì si sta imponendo
un vincolo sulla lunghezza. Io posso
scrivere a star b star o a + b+, ma
quindi posso avere 5a e 8b.
Ok? Quando diciamo am BM è devono essere
proprio lo stesso numero, ok? E il
problema della degli automi a stati
finiti è che non sanno contare, cioè non
hanno, sostanzialmente non hanno la
memoria, questo è il problema. Ok?
Non sanno contare all'infinito, sapreo
contare se abbiamo un dominio finito.
Ok?
Ah ok. Allora, noi dobbiamo quindi
inventarci un modello di calcolo che sia
un po' più sofisticato. Per quelli che
hanno fatto linguaggi sanno che in
realtà non serve una macchina di
tingonoscere
AMBM.
Esiste un altro automa con una memoria
molto semplice che è la l'automa appila,
però ovviamente non ci buttiamo su
questo. Noi sfruttiamo AMBM per
introdurre le macchine di touring. Ok?
Allora, che cos'è una macchina di
touring? Una macchina di touring
non è la macchina che si vede nel film,
quella è un'altra cosa.
La macchina che si vede nel film
The Bomb che viene utilizzata per
decifrare Enigma. Se andate a Milton
Kins, quella macchina è là, la potete
visitare al museo lì. Quindi la macchina
di Turing non è quella. La macchina di
Turing. Che cos'è la macchina di
Touring? è una macchina astratta
per modellare il calcolo. Ok? è un'idea
che gli era venuta a Turing
negli anni 20-30 perché in quel a quel
tempo i matematici si chiedevano quali
funzioni fossero calcolabili in maniera
automatica e quale funzioni non fossero
calcolabili, quali teoremi potevano
essere dimostrati automaticamente e
quali teoremi non si potessero di
teoricamente.
L'idea di computazione a quel tempo
c'era già c'era
il modello di Charch di Alonso Charch
che era il lambda calcolo eccetera, però
Turing affrontò quei problemi in un
altro modo e si inventò questo modello
astratto di calcolo che noi ora
chiamiamo macchina di Touring. Lui non
aveva chiamato macchina mia, noi la
chiamiamo macchina di Touring. Qual è la
differenza tra una macchina di ting
stati finiti che abbiamo visto finora?
Esattamente come gli automi a stati
finiti, una macchina di tingo
stato interno, quindi ha al proprio
interno la codifica di un programma
tramite stati, essenzialmente come gli
automi stati finiti. Ok?
La differenza sta in quello che la
macchina di Turing può fare con il
nastro. Ok? Noi abbiamo che gli automi a
stati finiti possono fare una sola cosa,
leggere il simbolo,
andare avanti e perso. Ok? Una macchina
di touring ha la possibilità sul nastro
di fare una serie di cose. La macchina
di Touring
ha un nastro infinito in entrambe le
direzioni
e questo qua.
Questo nastro è diviso in celle,
esattamente come per gli automi a stati
finiti. Ok?
In queste celle ci stanno i simboli
della parola che vogliamo riconoscere,
ad esempio
A a A B. Ok?
Poiché la parola sta su questo nastro
infinito, noi dobbiamo delimitare dove
questa parola sia. Quindi abbiamo dei
simboli speciali sul nastro che ci
dicono che in quella cella non ci sta
niente, è il simbolo blanc. Ok? Quindi
la macchina di touring, esattamente come
gli automi a stati finiti, processa
tramite stati, ok? Quindi non ha cose
pensi eccetera. processa tramite stati,
esattamente come gli automi a stati
finiti. Le peculiarità di questa
macchina sono: il nastro su cui opera è
infinito,
la testina che la macchina
usa per leggere
non solo è in grado di leggere un
simbolo, ma è anche in grado di
scrivere.
Ok? Quindi abbiamo una testina che legge
simboli, la stessa testina è in grado di
sovrascrivere, ok? Quindi schiaffiamo
sopra simboli, ok?
Dopodiché la cosa importante è che in
una macchina di touring questa testina
può andare a destra e a sinistra. Ok?
Adesso vedremo un esempio. Quindi recap
una macchina di Touring è
sostanzialmente un automa con un numero
finito di stati. Il potere delle
macchine di touring sta nel fatto che la
macchina su un nastro può leggere e
scrivere e può spostare la testina
avanti e indietro.
Ok? Questa è la peculiarità di una
macchina di touring.
Quando definiamo un programma per la
macchina di Touring,
noi abbiamo, ok lo stato di controllo
funzione delta che controlla il
la testina. Ok.
La macchina di Touring ogni volta che
Allora l'automa stati finiti cosa aveva?
Io sono in un certo stato, leggo un
certo simbolo, transisco in un altro
stato, salto il simbolo. La macchina di
Touring fa un po' più di cose. Sono in
un certo stato, leggo un certo simbolo,
cosa faccio?
transisco in un altro stato e fino a mo
sono come le macchine, come gli automi a
stati finiti standard, però
scrivo anche una cosa sul nastro e
decido se spostare la testino a destra o
a sinistra. Ok? Quindi per ogni
transizione che la macchina fa,
indipendenza di quale stato mi trovo e
quale simbolo sto leggendo, allora
decido in quale altro stato spostarmi,
cosa scrivere sul nastro e dove spostare
la testina. Ok? Chiaro per tutti?
Adesso, prima di introdurle formalmente,
noi vogliamo definire una macchina di
touring che sia in grado di riconoscere
questo linguaggio qui. Ok?
Alright.
Ok. Supponiamo di avere questo sul
nastro. In input c'è A a Aa BB. Noi
vogliamo inventarci una macchina che sia
in grado di fare questo lavoro. Ok?
Ci sono ovviamente tante soluzioni
possibili.
La soluzione che vi propongo io è
questa.
Sì,
B sbarrato sta per blank, cioè c'è la
vuota. Cioè che sul nastro c'è un
bianco,
visto che il nastro è quindi noi abbiamo
scritto a e poi
infinito. Sì, infinito. Sì. E questo,
per esempio, è già una cosa molto più
potente dei computer reali perché i
computer reali non hanno una memoria
infinita. Ok?
Alright. Allora, ci sono mille mila modi
per riuscire a riconoscere questo
linguaggio.
Io ve ne propongo uno e vi suggerisco di
pensare così, che immagino che la
stragrande maggioranza di voi abbia,
visto gli studi che fate, un approccio
visivo alla soluzione del problema. Ok?
Se non lo processate visivamente non ci
riuscirete. Eh, ho potuto sperimentare
questo con gli studenti negli anni.
Quelli che non costruiscono immagini
nella propria testa non riescono a
risolvere questo tipo di problema.
Allora, che dovete fare nella vostra
testa?
Io faccio questo. Immagino che gran
parte di voi faccia così. Io guardo nel
nella mia testa, io mi faccio un filmato
di cosa deve succedere alla testina di
questa macchina di Touring. Io la vedo
andare avanti indietro
per fare il suo compito, ok? Dopodiché
si tratta di tradurre in un grafo di
transizione, in un programma delta,
questo andare avanti e indietro è la
testina. Però il passaggio veramente
importante qua è che voi questa cosa la
dovete vedere. Se non la vedete nella
testa, disegnatevela, ok? Cioè è l'unico
modo per riuscire a risolvere questa
cosa. Perché vi dico questo? Perché
negli anni, insomma, mi è capitato di
interagire con vari studenti. Ci sono
quelli che cercano di risolvere questa
cosa parlandosi dentro. Ok? si fanno
delle domande, ma non vedono niente.
Cioè, è difficile così.
Quindi io vi dico esplicitamente, voi vi
dovete costruire questa immagine. Che
cosa vedo io? Io vedo sto bello nastro
con la testina di sopra, ma può essere
qualsiasi cosa, una nuvoletta, un
quadratino come abbiamo fatto là, o una
freccetta, una cosa luminosa. Però
quello che dovete vedere è questa
testina che si sposta avanti e indietro
perché guardando questo filmato che
riuscirete a tirare fuori la funzione di
transizione. Ok?
Allora, soluzione per questo problema è
una soluzione, eh, non la soluzione. Una
soluzione per questo problema è questo
qua.
L'idea sostanzialmente è
la macchina di Touring all'avvio sarà
nello stato iniziale bla bla e la
testina sarà sul carattere sul simbolo
più a sinistra sul primo. Allora, l'idea
è io vedo questo, vedo che è una A, la
cancello, vado alla ricerca dell'ultima
B, la trovo, la cancello, torno
indietro. A questo punto questa A non ci
sarà più. andrò a prendere questa, la
meccio con quest'altra e vado avanti,
indietro, avanti, indietro, avanti,
indietro, fino a quando ho cancellato
tutto. Se il numero di A e di B era lo
stesso, arriverò che c'ho un nastro
vuoto e non c'ho residui strani. Ok? È
chiaro?
Questa cosa la dovete vedere nella
vostra testa funzionare. Dovete vedere
la testina che legge là. Là viene
cancellata, la testina viene spostata in
fondo. Andiamo sull'ultima B,
cancelliamo la B, andiamo sulla prima A,
cancelliamo la A, ultima B, prima A,
ultima B, prima A, ultima B. A un certo
punto il nastro si svuota e diciamo sì,
il numero di A e di B era lo stesso e
noi accettiamo. Prego. Però dobbiamo
assumere che l'utente non possa inserire
delle stringhe che contengono il blank.
Quello no, quello poi formalizziamo. Ok.
No, l'utente non dà blank strani, quindi
sono due alfabetti distinto. Sì. Ok.
Sì. rischiamo di accettare anche un po'
a
dipende come progettiamo la macchina.
Adesso la progettiamo assieme e vediamo
che questo rischio può essere evitato.
Ok? Allora, occhio occhio a alla stringa
di esempi. Ok? Vi ricordo che abbiamo in
testa una strategia visiva. Dobbiamo
vedere sta cosa che va avanti e
indietro. Ok?
Q0 primo stato. Questo è lo stato in cui
la macchina parte. Ok, diamo la
corrente, la macchina si accende in Q0,
testina sul primo simbolo. Ok?
Allora, noi siamo qui, stiamo leggendo
il primo simbolo.
Ok.
Stiamo leggendo il primo simbolo.
Allora, guardate questa transizione. La
prima ve la scrivo io, le altre le
facciamo assieme. Se sono in Q0
leggo A,
scrivo blank, quindi lo cancello,
e sposto la testina a destra. Ok, quindi
eravamo qui, lo stiamo cancellando,
spostiamo la testina qui. Ok, chiaro per
tutti il significato di questa etichetta
che abbiamo dato all'arco? Sull'arco
abbiamo qui lo stato iniziale, qui lo
stato finale e sull'etichetta dell'arco
stiamo dicendo cosa leggiamo, cosa
scriviamo, dove spostiamo la testina.
Con questo programmiamo le macchine di
turn. Sì. E quindi con0 stava indicando
il la
la posizione della tessina che è sulla
prima. Sì, è lo stato in cui parto e
quindi dovrei devo definirlo la stessa
cosa, no? Abbiamo uno stato nella
macchina che si chiama Q0. Potevamo
chiamarlo topolino, è la stessa cosa.
Ok. che che questo Q0 deve avere per
forza una interna. Sì, perché all'inizio
noi quasi lo vediamo dopo. All'inizio
noi ci aspettiamo un A, andiamo in Q1.
Dopodiché cosa fa, ragazzi? Adesso
facciamo questo esempio. Guardate il
nastro nella vostra mente. Ok? La
testina era lì, ha cancellato una A.
Dove dobbiamo spostare la testina?
Dove dobbiamo spostare la testina? sulla
destra. Sulla destra. Ok. Mentre la
spostiamo a destra, guardate il nastro.
Ok? Dovete vedere il nastro nella vostra
testa. C'è un primo pezzo di A. Magari
se non vedete le A, coloratele verdi e
il resto coloratelo rosso. Ok? Qualsiasi
cosa che vi permetta di distinguere le
cose, ok? Dobbiamo quindi portare la
testina a sin a destra. Questa è la
vostra destra. Quindi dobbiamo saltare
che cosa prima? Tutte le al
Tutte le A. E allora che facciamo? Eh,
dov'è lui?
Leggo A,
scrivo A, significa la lascio lì dov'è e
vado a destra. Ok?
Quindi, mentre siamo in Q1, la macchina
cosa fa? C'è una pam pam, salta. A un
certo punto la testina cosa incontra?
Guardate l'immagine la vostra testa.
B. Ok. Una volta che arriva alle B, la
macchina per come è definita ora le
supera o no?
Per comeè definita ora? No, no, perché
non c'è un arco che gli permetta di
saltare le B. Quindi che facciamo?
Aggiungiamo un'etichetta.
Leggo B, scrivo B, vado avanti.
Ok? Quindi in uno che stiamo facendo?
Stiamo prendendo la testina e la stiamo
spostando a destra. Ok,
ci siete? Guardate il filmato nella
vostra testa.
La vedete la testina che va verso
destra?
Dovete proprio costruire l'immagine.
Come facciamo a sapere che la testina è
arrivata in fondo?
Come fate a saperlo?
Perché lo vedi nella testa. Ok. Questa è
la cosa, se guardate l'immagine vostra
testa, a un certo punto ci sarà un
blank. Come faccio a sapere di essere in
fondo? Perché la testina è arrivata là.
Quindi che faccio?
Leggo blank, lascio blank e vado
indietro e vado in Q2. Ok.
Dove si trova ora la testina?
Attenzione,
secondo. Quelli dietro state seguendo?
Dove si trova la testina dopo tutto sto
gran casino?
Dove? All'ultima B. Ok, siamo
sull'ultima B. Che ci dobbiamo fare con
questa B?
Dobbiamo chi ha detto toglierla?
Dobbiamo cancellarla. Ok. Come si fa?
Leggo B, scrivo blank e andiamo avanti o
indietro?
Indietro.
E andiamo in Q3. Ok.
A fianco dipl che direzione? Ah, sì,
quello è scritta coi piedi, scusami.
Ok, da così. Ok, chiaro?
Ok, quindi adesso cosa abbiamo? La
testina a destra. Ok. Dobbiamo andare
dove?
prima wait. So che lo sai un attimo.
Qualcun altro che dobbiamo fare?
Guardate il filmato nella vostra testa.
Chi deve fare la testina?
Dobbiamo andare a sinistra. Quindi,
quali sono i primi caratteri che
incontriamo andando a sinistra?
C'è B. Scrivo B e vado dietro. Dopodiché
che troviamo? Eh, c'è, scrivo a e vado
dietro. Ok? A un certo punto arriveremo
al bordo sinistro. Ok, questa la tiriamo
indietro. La testina arriverà a un certo
punto. Ok, come ci accorgiamo di essere
in fondo a sinistra?
Abbiamo una Come? Abbiamo un a
cancellata? Eh, no, perché la A
cancellata non ci sta più. Cosa c'è là?
C'è un blank. Ok. A quale blank ci
dobbiamo fermare?
Al primo che incontriamo. Ok? Una volta
che incontriamo il primo il primo blank,
cioè quello più a sinistra, in quale
stato di funzionamento della macchina
dobbiamo andare?
Ripartiamo tutto da cavo perché dobbiamo
mappare una A su una B
e quindi semplicemente facciamo questo.
Leggo blank, scrivo blank e vado avanti.
Ok? Quindi questo pezzo di macchina cosa
fa? Cancella A e B uno a un. Ok?
Fino a un certo punto. Ok. E quand'è che
questa macchina si inceppa?
Quando in uscita da Q3 spostando che
abbiamo trovato un blank, lo spostiamo
avanti e la macchina trova nuovamente
blank. Vedetelo con gli occhi, vedetelo
con gli occhi. Il nastro si è svuotato.
C'è un blank, va avanti, c'è un altro
blank perché la parte verde e la parte
rossa si sono ridotte e non ci sta più
niente. Ok?
Quella per noi che cos'è? È il segnale
che c'erano tante A quanto B. In quel
momento noi accettiamo.
Eh.
Ah,
quindi andiamo in Q4
che è lo stato accettante. Leggo Blank,
scrivo blank e vado avanti.
Ok.
Per rispondere alla domanda del nostro
collega, questa macchina può accettare
stringhe strane tipo AB a AB?
No, perché
actually. Yes.
Sì, c'è un errore qua.
Sì.
Perché non le può fare così? M m m
Oplà. B interessante. Non ci avevo mai
pensato.
Blank blank dietro. Ok, questo è uno
stato aggiuntivo.
Come on, man.
Ok, interessante. Non ci avevo mai
pensato quella macchina, così come era
definita, poteva accettare cose strane
AB a AB.
Sì, perché siccome mettevamo
tutto eh come me lo segno qua tutto qui
m
doppia label lì, noi potevamo passare
una A e una B, quindi devono essere in
sequenza. Prima mi leggo le A, poi mi
leggo le B. Ok? Se mettiamo due
etichette là, è chiaro? Qua qua sto un
po' saltando veloce. È chiaro perché
prima era sbagliato?
Perché se mettiamo quell'atto con due
etichette A B, la macchina può vedere
una qualsiasi sequenza di A e B e
saltarle fino alla ricerca del primo
plan. Un attimo. Se io voglio che ci
siano prima tutte le A e poi tutte le B,
allora mi aspetto prima le A e poi le B.
Sì, ma cancellando gli estremi poi avrei
avuto una B in testa pro Beh, quello sì,
quello sì. Ok, è anche vero. Sì, sì, sì,
sì. Ahah.
Ma basta che lo fai una volta. Sì, sì,
sì. Cioè, se io mi inceppo all'andata,
mi incepperò al ritorno, quindi mi fermo
dove in uno dei dei due versi. Ok.
Ah, c'è altro? C'è altro? No, è chiaro
per tutti come funziona questa macchina.
Quindi la differenza rispetto agli
automi a stati finiti è che questa
macchina, a parte transire in un altro
stato, questa macchina scrive sul nastro
e sposta la testina in due direzioni.
Ok? Questa è la differenza sostanziale
di una macchina diuring rispetto ad
automati finiti.
Chiaro? Ok, adesso facciamo una pausa,
10 minuti, poi formalizziamo le macchine
di touring e la condizione di
accettazione.
Allora, cavolo.
Alright, guys, si riparte.
Ok, ritorno velocemente sulle due
macchine diing che abbiamo visto
all'inizio. Ok.
P
la modifica che ho fatto è solo per
avere la certezza che funzioni. Potrebbe
funzionare anche quella di prima, però
cioè mi ci devo mettere un attimo a
capire se i casi strambi li accetto, li
rifiuto, la variante sono più sicuro che
funzioni. Tutto qua. Alrght allora
questo è un modo più o meno, no,
intuitivo di come funzionano le macchine
di Touring. Quindi abbiamo visto che una
macchina di Turing ha nel suo programma
questa codifica. Dato lo stato corrente
è il simbolo che sto leggendo,
transisco in un altro stato, scrivo
qualcosa sul nastro e eh sposta la
testina a destra o a sinistra. Giusto
una nota.
Questo qui,
questo simbolino qua, non è B1, è una
virgola. Ok? Quindi è B/
Bola
freccetta. Ok?
Leggo B, scrivo B e mi muovo a destra.
Ok? Quindi quello non è B1 B' e virgola.
Ok? la mia virgola un po' strana. Alri,
quindi quello che noi dobbiamo fare ora
è formalizzare
la computazione di una macchina di
Touring
e dare le condizioni di accettazione.
Vi faccio notare che questa macchina, a
differenza degli esempi che vedrete per
esempio sulle lecture notes disponibili
online, questa macchina non ha uno stato
di rifiuto. Questa macchina rifiuta per
incco. Questa macchina si blocca in uno
stato non accettante e dice no. Ok? Ci
sono altri modelli in cui abbiamo degli
stati esplicitamente per il rifiuto.
Alcuni le definiscono così. È totalmente
equivalente. Le nostre macchine non
hanno stati espliciti di rifiuto. Una
macchina rifiuta se si inceppa, se si
ferma in uno stato che non eh che non è
accettante. Ok? La macchina si ferma in
un certo stato quando la funzione di
transizione non è definita per quella
particolare combinazione stato simbolo.
Sono in uno stato, leggo in un simbolo,
vado nella mia tabella, la mia tabella
non mi dice assolutamente nulla su cosa
debba fare per quello stato e quel
simbolo. Faccio mi fermo, la macchina si
inceppa e siccome si blocca in uno stato
non accettante, allora per noi la
risposta è no. Ok?
Allora, noi dobbiamo adesso formalizzare
la computazione di macchina di Touring,
che sarà semplicemente un'estensione di
cose che abbiamo visto la volta scorsa
per gli auteti finite, ok? Dobbiamo
semplicemente farle un pelino più
sofisticate, però cosa andremo a fare?
andremo un po' ad arricchire quello che
abbiamo già visto. Ok, partiamo
innanzitutto con la definizione di
macchina di Touring.
Una macchina di Touring, esattamente
come gli automi, è definita da alfabeti,
ste cose qui. Ok, quindi vediamo un po'
che cosa ci sta dentro.
Una macchina di Touring è caratterizzata
dall'alfabeto sigma
che chiamiamo alfabeto di input, cioè
sono i simboli che la stringa input può
avere.
Ci siete? Poi abbiamo un secondo
alfabeto
che chiamiamo gamma.
Gamma è l'alfabeto
di nastro.
Cioè sono tutti i simboli,
compresi i simboli dell'input, perché
noi abbiamo che gamma è un sovrazieme di
sigma. Sono tutti i simboli che possono
stare a un certo punto sul nastro.
contengono sia i simboli dell'input
che eventualmente altri simboli che la
macchina può scrivere. Perché, ad
esempio, nel problema AMBM, quello che
noi facciamo, prendiamo una A, la
cancelliamo, prendiamo una B, la
cancelliamo. Un'altra cosa che avremmo
potuto fare è prendiamo una A, ci
scriviamo una X di sopra, andiamo in
fondo, prendiamo una A e B, ci mettiamo
una Y di sopra, torniamo indietro. Ok?
Quindi A e B fanno parte dell'alfabeto
di input perché le stringhe in input
possono avere questi simboli, ma sul
nastro ci possono stare altri simboli
che sono quelli che la macchina è in
grado di scrivere, quindi X, Y, Z,
casetta, nuvoletta, ok? Qualsiasi cosa.
Prego.
Blank è in gamba.
Abbiamo quindi il simbolo blank che è il
simbolo di bianco che è un simbolo che
fa parte di gamma.
Ok?
Alright. Poi, come le gli automi a stati
finiti abbiamo Q l'insieme degli stati,
ok?
Quindi sono tutte le pallette del nostro
grafo di transizione sono gli stati di
funzionamento della macchina che sono
sostanzialmente come quelli degli aut
finiti. Q è sempre Dov'è? È lui. Q è un
insieme finito. La macchina ha un
insieme finito di stati, un insieme
finito di simboli input, un insieme
finito di simboli di nastro. Ok? sono
tutti insiemi finiti.
Dopodiché
c'è Q0.
Q0 è uno degli stati di Q che è
designato essere lo stato iniziale, cioè
lo stato in cui la computazione della
macchina parte.
Poi abbiamo F.
Fottinsieme
di Q.
sono l'insieme degli stati accettanti,
ok?
Possono essere più di uno. Ci sono
formalismi che dicono che lo stato
accettante è uno solo, che c'è uno stato
che rifiuta che è uno solo, è tutta roba
equivalente, ce la possiamo gestire come
vogliamo perché sono inter traslabili
ste cose. Si traslate, si traducono
dall'uno all'altro. Ok?
Quindi F è l'insieme degli stati
accettanti e poi abbiamo delta che è la
funzione di transizione, cioè che è il
programma della macchina. Ok?
Che cos'è delta?
Delta è una funzione parziale, cioè che
per alcune input potrebbe non essere
definita
che va da Q gamma
verso Q
gamma times sinistra destra.
Quindi delta
è una funzione che dati uno stato
corrente e il simbolo che sto leggendo
determina qual è lo stato successivo,
qual è il simbolo che scrivo sul nastro,
ok? E la direzione della testina, cioè
se se ne va o a destra o a sinistra.
È chiaro?
Adesso dobbiamo definire formalmente la
semantica delle macchine, cioè cos'è per
noi una computazione, cos'è per noi una
computazione accettante. Semplicemente
estenderemo
quello che abbiamo visto già per gli
automi a Stati finiti durante la scorsa
lezione. Ok.
Questo qua
per definire una computazione
di
una macchina di Touring dobbiamo
definire cos'è una configurazione
per M. Ok? Vi ricordate che per gli
atomi a stati finiti avevamo introdotto
questo concetto che era la
configurazione dell'automa.
Generalmente non si fa, l'abbiamo fatto
perché ci viene comodo ora perché
semplicemente dobbiamo estendere il
concetto. Ok? Che cos'è una
configurazione per una macchina di
Touring? Vi ricordate intuitivamente che
cos'era una configurazione per un automa
stati finiti?
Una stringa che aveva lo stato. A cosa
serviva?
atale la configurazione per un automa
stati definiti era
una stringa, ok? Che ci serviva a
descrivere lo stato corrente di
esecuzione della macchina, ok? Cioè,
volevamo capire mentre sta macchina sta
processando che sta facendo. Ok? E
quindi che cosa avevamo? Avevamo uno una
stringa che era formata da uno stato che
era lo stato corrente della macchina e
poi una serie di simboli che era la
parte residua dell'input che la macchina
stava processando. Ok?
Intuitivamente per le Turing machine una
configurazione è sostanzialmente la
stessa cosa, cioè è una fotografia
dello stato di avanzamento
dell'esecuzione di una Turing machine su
una certa strisca. Ok?
Adesso, se noi ci pensiamo
quali sono le informazioni che ci
servono per catturare
lo stato di avanzamento dei lavori di
una tinguring machine,
scusi. Posizione, ok? La posizione di
cosa?
Della testina. Ok. Quindi c'è una cosa
particolare, esattamente come gli automi
stati finiti, dobbiamo sapere in che
stato siamo, ok?
Dobbiamo sapere che c'è sul nastro ed è
simile agli automi a stati finiti.
Quella quella sequenza di simboli dopo
lo stato nella configurazione degli DFA
che che cos'era? era semplicemente
quello che rimaneva sul nastro da
processare. Quindi, esattamente come per
quelle automi, dobbiamo sapere in che
stato siamo,
che ci sta scritto sul nastro e dove sta
la testina.
Allora, quello che noi facciamo è
cambiare leggermente
la configurazione rispetto a un automa a
stati finiti. Negli automi a stati
finiti cosa facevamo? stato resto della
stringa. Allora, quello che noi facciamo
semplicemente che lo stato, adesso
facciamo qualche esempio, per le
tinguring machine noi non lo mettiamo
necessariamente all'inizio,
lo mettiamo in mezzo alla stringa per
dire dove sta la testina. Ok, tutto qua.
Cioè, le l'idea di configurazione che
abbiamo usato per gli automi stati
finiti la ampliamo leggermente in cui
diciamo lo stato invece di scriverlo
sempre all'inizio, lo scriviamo in mezzo
per dire cos'è che stiamo leggendo. Ok?
Ad esempio,
se riprendiamo la macchina di prima,
eccetera,
una configurazione per quella macchina
potrebbe essere
A Q1 BB.
Che cosa significa questo?
Questa configurazione qua ci sta dicendo
che sul nastro i simboli non blank sono
a B,
che lo stato della macchina è Q1
e che noi stiamo leggendo
questo simbolo,
ok? Cioè, quindi semplicemente inserendo
lo stato all'interno di questa stringa,
noi siamo in grado di dire dov'è
collocata la testina. Però l'idea è la
stessissima, eh, dobbiamo sapere in che
stato siamo, che cosa c'è rimasto sul
nastro e dove stiamo guardando. Ok,
questa informazione non serviva per il
DFA perché perché un automa stati finiti
leggeva sempre un solo simbolo che era
il primo di tutto, poi li scartava uno
dopo l'altro, no? Siccome qui possiamo
andare avanti e indietro dobbiamo
memorizzare un po' di cose. A parte lo
stato e che cosa c'è sul nastro,
dobbiamo memorizzare dove che siamo. Ok?
Questa cosa qua,
per esempio, è dov'è l'altro esempio?
Ok. E c
A B D
Q1
blanc.
Questa è un'altra configurazione
in cui stiamo dicendo che su un nastro
c'è ABB,
che lo stato è Q1
e che Q1 sta leggendo il primo blank
sulla sinistra. Ok? Quindi i blank nella
configurazione
li mettiamo solamente se sono
indispensabili. Ok?
Se scriviamo una cosa di questo tipo,
quest'altra configurazione, per esempio,
ci dice che la macchina si trova nello
stato Q1 che Sul nastro c'è DB, però noi
stiamo leggendo il primo blank alla
destra
di tutta la stringa. Ok? Quindi così noi
scriviamo le configurazioni. Nelle
configurazioni inseriamo il simbolo
blank solo se è indispensabile. Se non
ci serve non li inseriamo, ok? Perché si
assume che il resto del nastro è vuoto.
Ok?
Allora,
sì.
sta facendo riferimento sempre alla che
ha fatto prima. Sì e no, è giusto per
dire change template.
Oplà.
Allora,
adesso introduciamo un po' di
definizioni che è tutta quella lista di
cose che abbiamo fatto la volta scorsa.
configurazione, configurazione
accettante, computazione, computazione
parziale, tutte ste cose qua, in maniera
tale che blocchetto dopo blocchetto
arriviamo a definire che cos'è una
computazione per una macchina di
Touring. Ok?
Date
due
configurazioni
C1 e C2
per una macchina M.
Diciamo
che
C2 è,
come si dirà in italiano il legal
successor. Legal
Successor
di C1 rispetto
a M
e lo scriviamo così. C1,
questo simbolo MC2.
Se C2 è la configurazione
che
M raggiunge
partendo da C1
facendo un solo passo.
secondo
la funzione delta. Ok? Quindi noi
diciamo che date due configurazioni C1 e
C2 per una macchina M. C2 è il
successivo di C1 secondo la funzione di
transizione di M. Se C2 è la
rappresentazione
di
eh della configurazione successiva C1
secondo la funzione di transizione. Ad
esempio, per la macchina che abbiamo
visto prima, noi avevamo che ne so Q0 Aa
BB. Se questo per noi è C1, noi avremo
che C2
è
Q1B,
perché la prima A l'abbiamo cancellata,
siamo transiti in 1
e sul nastro è rimasto AB.
Ok?
Quindi questo è C2 e noi abbiamo che C2
segue C1.
Secondo M.
Scusate, se C2 è lazione successivao.
Ah, se C2 è la configurazione che M
raggiunge partendo
da C1,
da C1 facendo un solo passo secondo la
funzione di transizione delta. Ok?
Stiamo semplicemente complicando le
cose, però quand'è che C2 è il
successivo di C1 secondo la macchina M?
Quando C2 è una fotografia dello stato
di calcolo di M che descrive la
computazione di M un passo dopo C1. Ok?
Se è una cosa strana C2 non è successivo
di F di C1. Ok?
Chiaro?
Ok. Quindi questo è uno
altro
la configurazione iniziale. Ok,
definiamola prima parola e poi la la
scriviamo. Adesso noi dovremmo andare a
stabilire, a definire la semantica della
computazione. Quindi dovremmo dire che
la macchina parte nello stato
appropriato, che fa una sequenza di
passi appropriati, che arriverà in uno
una configurazione finale, quella
configurazione sarà accettante,
eccetera, ci dobbiamo inventare, perché
niente di tutto ciò è scolpito nella
pietra, dobbiamo inventare delle
definizioni che ci permettono di
formalizzare la definizione di
computazione accettante. Ok? Allora, fra
le varie cose che ci dobbiamo inventare,
siccome dobbiamo inventarci un modo per
descrivere una macchina che calcola,
partendo dall'inizio alla fine, quali
configurazioni dobbiamo
ci dobbiamo focalizzare
iniziale, quella iniziale, cioè ci
servirà descrivere la configurazione
iniziale. Allora, ci inventiamo una
definizione di configurazione iniziale.
la configurazione
iniziale
di m su
stringa
w che è fatta dai simboli V1 VN. Qual è
secondo voi?
Q0 Q0
V1 V1 VN.
Ok, abbiamo dato un nome a questa
configurazione. In teoria sinistro di ci
dovrebbe essere siccome non lo stiamo
leggendo e non è indispensabile non lo
scriviamo,
ok? Cioè li scriviamo solo quando li
stiamo guardando.
Ok? Quindi dobbiamo dovremo descrivere
la computazione di M. Sta m a un certo
punto si dovrà fermare. Ok? Quindi
dobbiamo definire cos'è una
configurazione finale, ok?
una configurazione
finale
per Migurazione.
Che
come la modellereste? Che che
caratteristica deve avere una
configurazione finale secondo voi? Qn e
poi accanto black. Attenzione,
attenzione attenzione attenzione. Il
fatto che la macchina di prima che
abbiamo fatto stesse cancellando roba,
non è detto che lo facciano tutte, eh,
perché un modo per decidere quel
linguaggio è scrivere X Y, poi andiamo a
vedere che è la stessa cosa, eccetera.
Eh, cioè, quindi la macchina si può
fermare che sul nastro c'è roba.
Ragazzi, configurazione finale, non
configurazione accettante. Cioè una
configurazione che arriva al finale
della computazione. Qual è l'ultimo
passo che fa la macchina?
Una configurazione finale è una
configurazione che non ammette
un successore secondo delta. Tutto qua.
È una configurazione che non ammette
un legal successor.
Come cavolo scritto? Legal.
Successor
secondo M.
Che cos'è? Prego. Quindi non per forza
raggiunge uno stampare, no? Perché la
macchina che abbiamo visto prima si
potrebbe inceppare. Non so se avete
visto quel film di Mazzio Capod Caponda,
si inceppa la macchina, si ferma e no.
Ok? La nostra è la nostra definizione.
Su tanti libri troverete che le macchine
di Turing hanno lo stato per dire no,
cioè che quando devono dire no si
spostano in quello stato, si fermano di
no. Per noi una la macchina di Touring
se si blocca da qualche parte spersa in
questa foresta e non sa che fare, quello
è no. Per dire sì, si deve arrestare
nello stato in uno stato accettante. Ok.
Secondo M. Sì. Ok. E delta fa parte di
M. Ok.
Alr.
Where is it? Where is it?
Delta.
Che sarà una configurazione accettante?
Configurazione finale che su accett una
configurazione accettante e una
configurazione finale.
Una confettante.
Prima o poi imparerò a scrivere su sto
coso. Una con accettante
è una confe.
Quato
è accettante.
Ok, stiamo costruendo
microblocchi, ok? Di definizioni, poi
le mettiamo assieme e tiriamo fuori il
senso, cioè la semantica della di una
computazione per una macchina di
Touring. Ok?
Alright. Quindi abbiamo varie cose
definite, sappiamo cos'è una
configurazione, sappiamo cosa è il legal
successor di una di una configurazione
secondo una certa macchina, perché se la
funzione di la funzione di transizione è
differente, il successore di una certa
configurazione sarà un altro. Macchine
differenti fanno cose differenti. Ok?
Poi abbiamo definito cos'è una
configurazione
iniziale, cos'è una configurazione
finale, cos'è una configurazione
accettante?
È una configurazione
finale non accettante o una
configurazione
rifiutante? Che sarà
finale
una configurazione finale il cui stato
non è fra quelli accettanti. Ok.
Definizione di computazione parziale.
una
computazione
parziale
di M è semplicemente una sequenza
di configurazioni.
C1
CM
talé
C1 è seguito secondo M da C2 che è
seguito secondo M da C3 bla bla bla fino
a CM. Ok?
Quindi una computazione parziale per la
macchina di Touring è semplicemente una
sequenza di fotografie del suo stato di
avanzamento, ok? In cui ogni ogni
fotografia
è sensata rispetto alla precedente. Ok?
Scusi, ma è parziale perché cm Sì, CM
non è configurazione finale perché non
lo stiamo ripetendo ancora. Ok. Ok.
Poi adesso definiamo che cos'è una
computazione.
Una computazione
totale, se volete,
o completa. Completa mi piace di più.
Come vedete me lo sto inventando, eh,
non è che sono cose eh t'ho detto di no.
completa
di M. A questo punto invece ci interessa
la stringa su cui sta processando.
Quindi una computazione di M su w
computazione parziale
D M
C1 bla bla bla bla CM.
tale che
che caratteristiche deve avere questa
computazione parziale per poterla
chiamare computazione di m su wigali.
Sì. Quindi C1
C1
è una configurazione
iniziale
di MU W e inoltre
CM CM è una configurazione finale. cm è
una
configurazione
finale.
Ci siete?
Alright.
Quant andate avanti? Così. Vabboh,
niente, vuoi far crescere
una computazione.
Una computazione di M su w è accettante.
Se
se è solo se
CM è una configurazione accettante. CM è
una configurazione accettante. CM è una
configurazione.
Ok. Noi diciamo, quindi,
se noi diamo in input una stringa W a
una macchina M, la macchina M accetta w
V
se la computazione di M su W
va a finire in una configurazione
accettata.
È chiaro? Quindi abbiamo messo tutti i
pezzettini per arrivare a dire quand'è
che una macchina di touring accetta.
Ok.
Sì, abbiamo configurazione parziale con
sequenza di configurazioni.
Configurazioni legali successive. Sì,
sì, qua l'ho messo. Eh, dai. Dov'è che
sta? In fondo.
Vedi? Ho messo il simbolo qua C1 seguito
da C2 seguito da C2. È quel simbolino là
che ci dice che è legale successivo. Sì.
Ok. Quindi abbiamo detto che una
macchina di Turing M accetto una stringa
W se dando impasto W ad m la
computazione di M va a parare in una
configurazione accettante. Ok?
Sì.
Cos'è il linguaggio
di una macchina di touring?
Il linguaggio di una macchina di Touring
M, che lo denotiamo LM,
è l'insieme di tutte le stringhe W
tali che Mentre processa W e lo scrive
in questo modo sputa fuori 1 y s. Ok?
Quindi cos'è il linguaggio di una
macchina di touring? Il linguaggio di
una macchina di Touring è l'insieme di
tutte le stringhe
sulla quale la macchina di Touring dice
di sì. Ok? Vi ricordo che la macchina di
Touring per dire sì su quelle stringhe
si deve fermare e fermare in uno stato
accettante, ok?
E se la macchina di Touring su una certa
stringa si arresta su uno stato non
accettante? La macchina sta dicendo sì o
sta dicendo no?
Sta dicendo no.
E se la macchina di Touring processando
una certa stringa non si ferma mai, che
cos'è? Sì o no?
Non appartiene al linguaggio. Non
appartiene al linguaggio perché perché
non risponde. Perché la macchina non
risponde. Cioè la macchina se non si
ferma per noi è no. Ok. Però è un no un
po' strano, vedremo poi nelle prossime
lezioni, perché non è che si ferma per
dirci di no, non si ferma mai, quindi
non lo sapremo mai. È un è un po' un
problema. Ok?
Noi diciamo e queste sono le ultime
definizioni, sia
L un linguaggio,
una macchina di Touring M
decide,
quindi vai che ve lo scrivo proprio.
M decide,
guardate la parola, il linguaggio
L.
Se e solo se per ogni stringa w
se W appartiene ad L, allora M
processando W si arresta e risponde 1. E
v appartiene a L, allora M processando W
si arresta e risponde zero. Quindi una
macchina decide un linguaggio.
Se su tutte le stringhe che appartengono
al linguaggio la macchina si ferma e
dice di sì. Su tutte le stringhe che non
appartengono al linguaggio la macchina
si ferma e dice di no.
Una macchina accetta un linguaggio L.
Se per tutte le stringhe che
appartengono al linguaggio la macchina
si ferma e dice di sì, sulle altre non
abbiamo garanzia. Ok, recup. Una
macchina di touring accetta un certo
linguaggio L.
Se quindi
M accetta
il linguaggio
L, se per ogni stringa
dei
se per ogni stringa proveniente da sigma
star accade che se V appartiene al
linguaggio L, allora la macchina si
arresta e dice di sì.
Se la macchina se la stringa non
appartiene ad L, allora la macchina non
dice di sì. Cioè la macchina potrebbe
dire di no, la macchina potrebbe non
fermarsi. Ok? Quindi il fatto che una
macchina decida un linguaggio ha una
proprietà più forte per noi, perché si
accetta ogni volta che deve dire si
accetta il linguaggio L, significa che
ogni volta che deve dire di sì, la
macchina si ferma e dice sì.
Se deve dire di no, la macchina potrebbe
fermarsi e dire di no, potrebbe non
fermarsi mai, eccetera. Se invece
diciamo che una macchina decide un certo
linguaggio L, allora questa per noi è
una garanzia un po' più forte perché
ogni volta che deve dire di sì si ferma
e dice di sì.
Ogni volta che deve dire di no, la
macchina si ferma e dice di no. È
chiaro? Quindi
il fatto che una macchina decida e non
semplicemente accetti un linguaggio per
noi è fonte di una certa garanzia,
perché ogni volta che noi diamo in input
una stringa alla macchina, la macchina
si fermerà per darci la risposta. Ok? Se
invece la macchina semplicemente accetta
un linguaggio L, non è che lo decide, ma
lo accetta, significa che ogni volta che
deve accettare, ecco perché usiamo
questa parola, quindi ogni volta che
deve dire di sì, la macchina si ferma e
dice sì. Quando la macchina deve dire di
no, non dà garanzia di risposta.
Potrebbe fermarsi e dire di no, potrebbe
non fermarsi.
Prego.
Se per una stringa
che risponde di sì che non appartiene a
L. Eh, quella è un'altra cosa.
Noi definiamo così, dato un linguaggio,
se esiste una macchina che ogni volta
che su tutte le stringhe che
appartengono a L si ferma e dice di sì e
tutte le stringhe che non appartengono a
L si ferma e dice di no. Allora, la
macchina diciamo che sta decidendo il
linguaggio. Se invece per un linguaggio
Lina
per le stringhe che appartengono al
linguaggio si ferma e dice di sì, ma per
le stringhe che non appartengono al
linguaggio la macchina non dà garanzia
di risposta. Sicuramente non sbaglia,
non si ferma e dice di sì. O non si
ferma proprio o si ferma e dice di no.
In quel caso diciamo che la macchina sta
accettando il linguaggio. Ok? Usiamo
questi due termini distinti per far
riferimento a queste due casistiche
perché ci saranno linguaggi che saranno
decidibili, cioè ci saranno ci sono
linguaggi per i quali avremo macchine
che ogni volta si fermano e ti dicono
sì, no. Ci sono linguaggi che mostreremo
essere accettabili ma non decidibili,
cioè linguaggi per i quali abbiamo un
algoritmo che se dobbiamo dire di sì lo
sappiamo fare in tempo finito, se
dobbiamo dire di no l'algoritmo potrebbe
non terminare mai e quelli ovviamente
sono problemi più tosti. Ok, prego. Si
può affermare che quindi con
noi stiamo a intendere che eh la
macchina di touring va a valutare la
classe di problemi, mentre con accetta
va a valutare un singolo problema. No,
no, no, no, no. Decidere un linguaggio e
accettare un linguaggio fa sempre
riferimento all'area semantica del
stabilire se una stringa appartiene o
meno a quel linguaggio. Quindi decidere
L, cioè una macchina decide L significa
che ogni volta che gli diamo una stringa
input alla macchina e la macchina deve
stabilire se la stringa sta dentro L o
meno. Se la macchina M decide L su
quella stringa W si fermerà sempre per
dire o sì o no. Se la macchina ML lo
accetta solamente, riceve in input W, la
macchina se deve rispondere di sì lo
farà in tempo finito. Se la macchina
deve rispondere di no, potrebbe non
rispondere mai.
Quindi noi entrambe, diciamo, eh vengono
accettate in input stringhe, soltanto
che il decidibile racchiude
l'accettazione e quindi essendo
indecidibile significa che la macchina
si ferma.
Se una macchina decide un certo
linguaggio L ti dà garanzia di risposta.
Ma è più potente come termine, tra
virgolette, la decisione o la citazione?
Dipende cosa definisci per potente. Tu
hai che i linguaggi accettabili sono un
sovrazieme dei linguaggi decidibili.
Adesso cosa definisci potente? E dipende
dalla tua definizione. Quello che ti sto
dicendo è che ci sono linguaggi per i
quali abbiamo macchine di touring che
sanno sanno fare il loro lavoro, cioè
per ogni stringa si fermano sempre e ti
dicono "Guarda, sì, guarda, no". Ci sono
linguaggi che sono talmente difficili da
da poter essere
risolti, ok? Mi serviva un'altra parola,
tale per cui là quello che al più una
macchina di Touring è in grado di fare è
che per le stringhe sulle quali deve
rispondere sì, si ferma e si dice sì,
questa stringa fa parte di L, però ci
potrebbero essere delle stringhe per le
quali la macchina di Turing le riceve in
input, dovrebbe dire di no. Adesso la
macchina di Turing non sbaglia. Cioè,
non è che ti dice sì per no, però non ti
risponde sì, nel senso che o si ferma e
dice no o non si ferma proprio. Ma qual
è il problema di queste macchine? Poi lo
vedremo nella prossima lezione.
Se noi abbiamo che un certo linguaggio è
solamente accettato da una macchina e
quello per noi è un po' un problema
perché ok, facciamo partire l'algoritmo,
sta girando da 2 anni, ancora non
abbiamo risposta e che facciamo?
aspettiamo. Cioè, quello tra un po' si
ferma e dice sì o non si fermerà mai.
Boh. Invece quando abbiamo la garanzia
che il linguaggio è deciso dalla
macchina,
la macchina sta computando e sono 2 anni
e lì noi sappiamo che prima o poi si
arresta.
Capite qual è la differenza? Quindi, in
conclusione, problemi decidibili sono un
sottoinsieme di problemi accettabili, sì
che quelli poi li chiameremo
semidecidibile, però son cose che
vedremo nelle lezioni successive. Ok?
Dopo l'introduzione delle macchine di
touring, prossima lezione faremo un po'
di esercizi su macchine di touring. Ok?
Buona serata.