mi ha detto, cioè sempre
No, no,
[Musica]
ok, iniziamo.
Ok, veloce quello che abbiamo fatto
ieri.
[Musica]
Ok. Ok,
[Musica]
recap quello che abbiamo fatto ieri e
poi iniziamo gli argomenti per oggi che
continua a essere un recap.
Ehm, allora, velocissimo.
Problemi di ricerca. Noi siamo
interessati ai problemi di ricerca che
sono quelli più generici, ok? Problemi
di ricerca sono quei problemi in quali
la risposta può essere valida. Qual è il
prodotto tra questi due numeri? Qual è
l'idea la derivata di questa funzione?
Qual è il percorso minimo fra B? Ok,
problemi di
affiancate a questi problemi ci stanno i
problemi di decisione che sono quei
problemi nei quali la possibile risposta
sono solo due, sì o no? Ok?
I problemi di decisione sono anche dei
problemi di ricerca, ma non mi cioè i
problemi di decisione sono risolti
insieme. Abbiamo visto che c'è una certa
relazione fra problemi di decisione e
problemi di ricerca perché dato un
problema di ricerca ci possiamo
diventare un problema di decisione che è
molto simile tale per cui essere capaci
di risolvere uno ci dà sostanzialmente
la difficoltà
eh ci dà informazioni sulla difficoltà
di risolvere il problema di che cosa
facciamo? Quindi ci focalizziamo sui
problemi di decisione perché è più
semplice per noi da un punto di vista di
analisi. Ok? Quindi problemi di
decisione. Dopodiché abbiamo fatto un un
salto extra, abbiamo detto: "Ok, c'è un
problema abbastanza studiato in in
formatica teorica che è un problema di
decisione che sono i problemi di
decidere i linguaggi." Ok? Che cos'è un
linguaggio? Abbiamo detto che un
linguaggio è semplicemente un insieme di
stringhe.
Cosa significa decidere un linguaggio?
Significa data una stringa, stabilire se
quella stringa appartiene all'insieme
del linguaggio o meno. Le risposte sui
sui linguaggi, sul problema di decidere
un linguaggio sono due, sì, no? Quindi è
un problema di decisione. Noi leghiamo i
problemi di decisione a opportuni
linguaggi in maniera tale che risolvere
un problema di decisione è equivalente a
decidere uno specifico linguaggio.
Chiaro per tutti? Perché ci spostiamo
sui linguaggi? Perché i meccanismi, cioè
il formalismo che possiamo usare per
stabilire se linguaggio de cilber o
meno, invece che avere algoritmi asti,
scritti in Java, Python whatever, noi
utilizziamo il concetto di automa che è
più semplice e più formalmente
definibile e di questo e per questa
ragione ci focalizziamo su questo. Ok?
Domanda per voi. Supponiamo di avere un
linguaggio L, ok? Un linguaggio L e noi
ci vogliamo focalizzare sul problema di
decidere L. Ok?
Qual è l'input, qual è l'output?
L'input
è una stringa e l'output è un
alta. E l'input è una stringa e l'input
è volata. L'input è una stringa. Ok.
Decidere il linguaggio L. Il linguaggio
L non è input. È chiaro per tutti questo
passaggio? Cioè, stiamo attenti a non
confonderci qua. Decidere un linguaggio
L. L'input di questo problema è una
stringa, non gliaggio L. E dove compare
il linguaggio L in questo problema?
Nella relazione. Nella relazione, nella
definizione. Ok? Dobbiamo stare molto
attenti perché a un certo punto vedremo
problemi in cui avremo linguaggi input.
Ok? Quindi qua dobbiamo stare attenti.
Dato fissato un linguaggio L, il
problema di decidere il linguaggio L è,
data una stringa, stabilire se questa
stringa appartiene a L o meno. Ed L è
una cosa data, cioè fa parte della
definizione del problema, non sta
nell'input di questo problema, ok? non
abbiamo una rappresentazione del
linguaggio in ingresso, almeno per il
momento. Poi nelle lezioni future
vedremo problemi che prendono input,
linguaggi e fanno cosa sui linguaggi.
Ok? Però argomento ci focalizziamo su
questa cosa basica, cioè dato
fissato un linguaggio, prendiamo una
stringa, ci viene data una stringa, noi
dobbiamo essere in grado di stabilire se
quella stringa appartene al linguaggio o
meno. Ok? E poi ci siamo focalizzati
su questa cosa ieri
in cui praticamente volevamo riconoscere
l'insieme
delle stringhe binarie che quizano
numeri dispari. C'eravamo detti
praticamente che un semplicissimo Sì, ma
la stringa in input è la descrizione del
linguag
input, ok? Dipende dal problema. Se il
tuo problema è fisso L, devo decidere L,
la stringa input è una stringa
sull'alfabeto su cui LSO stesso è
definito. Ok? E di questa stringa io
devo dire se questa qua sta dentro
questo insieme o no. Ah, ok. Sì, sì, ok.
Sì, sì, sì. Nelle prossime lezioni
vedremo, però è inutile andarci ora, dei
problemi un po' più sofisticati nel
quale in input avremo stringhe che
descrivono linguaggi e ci chiederemo ah,
ma questo linguaggio ha questa proprietà
o cose di questo tipo? Ok? Però è quello
è proprio un altro livello semantico.
Qua siamo fissato un linguaggio, dato
una stringa, devo decidere se questa
stringa sta qua dentro o sta qua fuori.
Ok? Allora, ieri abbiamo visto questo
esempio della
del linguaggio delle stringhe binarie
che codificano numeri dispari e ci siamo
detti che praticamente quello che
dobbiamo andare a fare è andare a
guardare l'ultimo bit. Ok?
Ieri abbiamo usato questa metafora dei
segnali in ingresso all'automa. Una
cosa, un passaggio extra che possiamo
fare è questo qua. Pensare
che così ci iniziamo a poco a poco a
spostare verso le Turing machines che un
automa è un computer molto semplice che
ha input un nastro.
Ok? Vedete presenti gli scontrini? Ok,
abbiamo in input uno di questi
scontrini. Bello lungo. Ok. E su questo
scontrino ci stanno i simboli 0 1 0 1.
Quindi questa cosa qui, questa stringa
in input abbiamo che è codificata su uno
scontrino, su questo lungo nastro di
carta. l'automa o gli premiamo i
bottoni, come abbiamo detto ieri, oppure
un'altra metafora, perché di metafore
stiamo parlando, è che questo automa
abbia la capacità di leggere un simbolo
per volta da questo scontrino. Guarda
sullo scontrino, dice ah c'è un uno, ah,
c'è zero, eccetera. e la sua
computazione praticamente abbiamo visto
ieri che è oscillare fra questi due
stati. Lo stato Q1 che ha il significato
di l'ultimo simbolo che ho visto è un 1
e lo stato Q0 che significa l'ultimo
simbolo che ho visto non è uno. Ok?
Allora, come serve a niente questo coso?
Come funziona questa macchina?
Quando su nastro leggo uno, mi sposto
nello stato che significa l'ultima cosa
che ho visto è un uno quando io leggo su
nastro zero, mi sposto nello stato in
cui significa io l'ultima cosa che ho
visto è zero. Adesso se l'ultima cosa
che ho visto è zero e rileggo nuovamente
zero, rimango dove sono. Se l'ultima
cosa che ho visto è uno e eh leggo
nuovamente uno, rimango in quello stato
di esecuzione. Ok? Questa è una macchina
semplicissima, però è in grado di
svolgere questo compito. Date una
stringa binaria, è in grado di stabilire
se questa stringa rappresenta un numero
binario dispari. Ok? La cosa
interessante di questa macchina è che è
la caratteristica di questi atomi, come
sapete, è che la lettura dei simboli sul
nastro avviene un simbolo dopo l'altro,
cioè questo scontrino lo iniziamo a
tirare e una volta letto lo buttiamo,
ok? Non andiamo mai dietro. C'è questa
testina sullo scontrino che legge un
simbolo e va avanti, un altro simbolo e
va avanti e va avanti e va avanti.
Quello che è letto è perso, non si torna
indietro. Ok? Quindi questa macchina
deve in qualche modo fare la mossa
giusta nel momento in cui vede il
simbolo. Non ci può ripensare.
Ok? Questa è la caratteristica di questi
automi. Ok? Si legge, si butta. si
legge, si butta. Vedremo automi più
sofisticati in cui questa cosa non
avviene. Ok.
Allora, ovviamente noi abbiamo fatto una
descrizione
di eh
di queste macchine in maniera un po'
così chiacchiereccia. Quello che adesso
noi vogliamo fare è guardare una
definizione formale di queste macchine,
del loro della loro computazione,
del loro nozione di accettazione di
stringa, in maniera tale che su questo
iniziamo ad agganciarci i pezzi e
vedremo che la definizione di touring
machine non sarà molto simile da quello
che vediamo da queste macchine, cioè le
touring machines, come vedremo, saranno
automi come quelli che stiamo vedendo
ora, solo che riescono a fare qualcosina
in più. Quindi iniziamo a vedere le
definizioni formali di queste macchine
in maniera tale che a poco a poco ci
aggiungiamo pezzi fino a quando
arriveremo a costruire la definizione
formale di cos'è una machine. Ok?
Alrght.
Come si farà?
Ok.
Ok. Allora,
ragioniamo insieme come si possa fare
questa cosa. Allora, noi abbiamo detto
che un autonoma stati definiti
sostanzialmente ha varie modalità di
funzionamento
e graficamente noi le rappresentavamo
con quei nodi nel grafo. Ok?
Quindi per modellare un automa ci
servirà qualcosa per descrivere il la
modalità di funzionamento. Ok? Queste
modalità di funzionamento le chiamiamo
stati, quindi avremo necessità da
qualche parte di infilare degli stati.
Cioè una un autroma stati finiti è
caratterizzato da un certo numero di
stati. Ok? Stiamo modellando assieme
questa cosa. Se voi andate sui libri
trovate 1000 definizioni differenti. Io
ve ne propongo una e una che ragionevole
che ci stiamo inventando assieme. Ok?
Non è oro colato, si possono definire in
mille modi. Facciamo questa cosa assieme
per mostrarvi che il processo di
definire queste cose è una cosa che
possiamo fare anche noi. Pensiamo al
problema che stiamo modellando e ci
inventiamo così. Ok? è tutto inventato,
eh, niente scolpito nella pietra, poi ci
stanno cose inventate che funzionano
meglio di altre e quindi le
selezioniamo. Ok? Quindi noi abbiamo
queste macchine, hanno degli stati che
processano, quindi da qualche parte
nella formalizzazione di queste modelle
ci deve essere sto stato, devono esserci
stati. Ok? Poi abbiamo detto che la
macchina che fa? Legge che cosa?
simbol legge il nastro legge simboli sul
nastro, quindi questa macchina dovrà
avere associato un insieme di simboli
che è in grado di di distinguere. Ok?
Dopodiché che di che cosa è
caratterizzata la la macchina?
Da che cosa passa con adess? Ok? Quindi
c'è un pezzo proprio un pezzo della
definizione è cosa fa questa macchina,
cioè quindi il programma e il programma
qua dentro che cos'è?
Un grafo. È un grafo. Ma che cosa ci
dice questo grafo? Che genere di
informazioni ci dà?
Sulle stringhe accettate?
Come? Scusami? Cioè sulle stringhe
accettate dice eh ok. Però qua dentro
questo grafo che stiamo codificando
intuitivamente
il linguaggio è quello che noi
decidiamo. Però questo grafo che
informazione ci dà? Passaggio tra gli
stati. Come? Il passaggio tra gli stati.
Che il passaggio tra gli stati? Il
passaggio tra gli stati, cioè il
funzionamento. Cioè questo grafo ci sta
dicendo se siamo in questo stato e se
leggiamo questo simbolo ce ne andiamo di
là. Se siamo in quest'altro stato e
leggiamo quest'altro simbolo, facciamo
quest'altra cosa. Cioè, quindi il
programma è sostanzialmente codificato
negli negli edges che collegano le cose.
Quindi dentro la definizione di automa
ci andrà infilata pure questa cosa.
Quale altra caratteristica vediamo qua
dentro che potrebbe essere utile nella
definizione
di un automa? Stati iniziali, stati
finali? stado iniziale e stato finale.
Dobbiamo sapere quando accendiamo sta
macchinina dove si trova. Ok, quindi
andrà definito quello e ma la macchinina
quando si arresta come facciamo a
stabilire se dice sì o no? Ok. E quindi
ci serve quest'altra cosa. Quindi queste
sono tutte informazioni che abbiamo dato
qui intuitivamente. Adesso le dobbiamo
infilare in una definizione formale. Ok.
Alright.
avremo che
no
un automa stati finiti D
è caratterizzato da Abbiamo detto che
questo automa legge simboli da un
nastro. Di conseguenza ci serve
l'alfabeto sul quale questa macchina
lavora, quindi è caratterizzato da
sigma.
Sigma che cos'è? Sigma è un alfabeto.
Di cos'altro era fatto questo automa? Se
ripensiamo al grafo, riguardatelo nella
vostra vente. Che ci sta in questo
grafo.
Gli stati, le pallette. Ok. Quindi
abbiamo un insieme Q di stati.
Riguardate nella vostra mente o nei
vostri appunti quel grafo. C'erano stati
diversi dagli altri. Che cosa abbiamo?
lo stato iniziale. Quindi Q0
Q0 appartenente a Q è lo stato iniziale.
Poi abbiamo l'insieme F, che è un
sottoinsieme di tutti gli stati Q che
sono gli stati finali.
Riguardiamo nella nostra mente il grafo
che ci sta in questo grafo.
Ci stanno gli archi che è la codifica
del programma, ok? Che ci dicono come
sta macchina balla fra uno stato e
l'altro, ok?
La chiamiamo delta.
Delta è la funzione di transizione, ok?
Cioè, si chiama così perché ci dice come
la macchina transisce da uno stato
all'altro. Ok? Comeè definita questa
funzione? Qual è l'inputs di questa
funzione?
Stato è un simbolo. È un simbol. Questa
funzione ci dice se siamo in questo
stato e stiamo leggendo questa cosa,
quindi input della funzione
è una funzione che va dagli stati per i
simboli, quindi il prodotto cartesiano
degli stati e dei simboli. Quindi questa
cosa significa la funzione di
transizione. Se siamo in uno stato e
leggiamo un certo simbolo,
allora che informazione ci dà questa
funzione?
Lo stato successivo, cioè dove ci
spostiamo.
Q. Quindi delta
è una funzione
che va mappa coppie stato simbolo verso
il prossimo stato. Ok? Così si leggono
le funzioni. Ok? Questa è una funzione,
il che significa che per ogni
coppia
stato corrente
simbolo letto,
il prossimo stato è uno solo. Ok? Quindi
per questo è una funzione perché mappa
ogni singola coppia, ok?
Verso
un un solo stato successivo. Ok? Quindi
questa è la definizione
formale di automa stati finiti. Ok?
Questo è un automa stati finiti perché
l'insieme Q degli stati è un insieme a
cardinalità finita. Ok? Cioè quando noi
progettiamo un automa, ok?
questo automa Q
questo automa in cui decidiamo quali
sono gli stati, gli stati non possono
cambiare mentre la macchina esegue.
Cioè, non è che la macchina gira, vede
un simbolo e m qua mi aspettavo altro e
e tira fuori uno stato aggiuntivo, cioè
mi cresce una palletta extra nel grafo,
ok? Cioè il grafo è il programma della
macchina. La macchina segue per vedisse
nuovamente quello che c'è scritto nel
grafo. Il grafo non cambia
mentre la macchina esegue.
Ok?
Questo è importantissimo, eh, perché vi
dovrebbe già fare iniziare a pensare che
i computer sono un aggeggio un po'
strano
perché eseguono programmi differenti.
Ok, poi vedremo come questa cosa è
possibile, però ok, ma un automa ha un
programma fissato, ma io sul mio
computer ci riesco a mettere giochi
diversi, com'è che fa cose diverse? Ok,
vedremo
formalmente questa cosa come si ottiene.
Ok.
Alri. Questa è la definizione di
automa. Però ancora non abbiamo definito
formalmente come questo automa
computare. Ok?
Perché qua ancora non abbiamo letto come
avvengono i passaggi e che cos'è una
computazione accettante per l'automa.
Ok, qua vi viito un po' io perché è un
po' più tricky. Allora, pensiamo assieme
questa cosa qua.
Se noi vogliamo
catturare
il funzionamento di un automa stati
finiti, sostanzialmente noi dobbiamo in
qualche modo modellare
i passi che quest'utoma fa su una certa
stellino.
È chiaro per tutti? Cioè, se io devo
modellare il funzionamento della
macchina su una certa stringa input, io
devo in qualche modo catturare la
sequenza delle cose che succedono mentre
questa macchina gira sulla stringa
input. Ok?
Adesso, secondo voi, supponiamo che
stiamo studiando il funzionamento di
questa macchina su una string input e
che questa macchina staia già girando,
ok? e vogliamo catturare
lo stato di avanzamento dei lavori di
questa macchina a un certo punto in
mezzo alla computazione. Ok? Quindi è
chiaro, abbiamo questa macchina ha
ricevuto input, una stringa, questa
macchina sta iniziando a girare, legge
caratteri, abbiamo detto che questa
macchina che fa? Legge simboli, si muove
in un altro stato, butta quello che ha
detto. Ok? Questo è importante. Leggo un
simbolo, cambio stato, butto. Leggo
simbolo, cambio stato, butto. Ok?
Questa macchina processa passo dopo
passo in questo modo,
a un certo punto arriva a metà. Ma noi
vorremmo essere in grado di
caratterizzare lo stato di avanzamento
dei lavori questa macchina in mezzo alla
computazione. Di quale informazione
abbiamo bisogno per essere in grado di
stabilire cosa a che punto è la macchina
del del suo calcolo?
Ecco, non ho capito. Vogliamo capire se
la macchina si trova del Q0 Q1. Allora,
è una cosa che ci stiamo inventando. Noi
vogliamo modellare i passaggi della
macchina.
La mia domanda è: siccome noi vogliamo
capire i passi che la macchina fa per
arrivare fino a accettare o rifiutare,
noi dobbiamo inventarci delle, cioè ci
chiediamo quali sono le informazioni che
ci servono per stabilire in mezzo al
calcolo a che punto la macchina si
trova.
La fun, usiamo la funzione del tipo io
so la sfinga di input, quindi eh car,
cioè simbolo per simbolo, prendo poi
prendo l'output, sì. e lo uso come input
per il successivo simbolo. Sì, l'idea
c'è più semplice. Io voglio sapere in
mezzo al guado, stiamo attraversando
questo fiume da un arrivo all'altra,
dalla partenza all'arrivo, noi siamo in
mezzo all'acqua. Come Quali sono le
informazioni che mi servono per sapere
da lì in poi come la macchina procederà?
Stato corrente
input
un po' di più.
Allora, per sapere, stiamo attraversando
il fiume da una riva all'altra. Ok? La
macchina si trova in mezzo al guado.
Come faccio a sapere di quali
informazioni necessito per sapere come
evolverà la sua computazione da metà
verso la fine?
corrente, stringa rimesse, mi serve lo
stato corrente e il pezzo di stringa che
rimane. Quello è tutto ciò che mi serve
perché la funzione delta noi la
conosciamo dalla macchina. Quindi se io
so in quale stato sono e qual è la parte
rimanente di stringa, io posso stabilire
quali saranno tutti i passaggi
successivi della macchina. Ok? string e
non si perché se io voglio sapere quale
sarà il resto della computazione devo
sapere cosa mi rimane la leggere
però stato si bassa si bassa simili ma
se un conto è che io sono in uno stato e
una c'ho una sequenza di 3A un conto è
che c'ho uno stato, una a e una sequenza
di 3B, cioè cosa farà la macchina?
dipende da quello che leggo ora, ma i
suoi passi successivi dipende da quello
che leggerò poi.
Ok?
Questo non è oroato, ce lo stiamo
modellando come vogliamo noi.
Potete inventarvi altri modi,
l'importante è che funziona. Perché
facciamo così? Perché in questo modo
introduco un concetto che poi ci serve
per le macchine di ting. Ok?
Ecco perché ce la stiamo un po'
complicando, perché poi estendiamo sta
cosa le macchine during e siamo belli
rilassati. Ok? Allora, ci siamo detti
quindi che uno snapshot, cioè una
fotografia che ci permette di capire da
qui in avanti come la macchina si
comporterà sono due generi di
informazioni: lo stato corrente e la
parte di stringa residua. Ok? Noi a
questa informazione gli diamo il nome,
così lo possiamo utilizzare.
Una configurazione
per una macchina D.
intuitivamente è semplicemente
una sequenza di simboli il cui primo
simbolo è un certo stato Q, ok? E gli
altri simboli sono tipo C, bla bla bla e
il resto della stringa che deve leggere.
Ok? Adesso facciamo un esempino.
Ah! Ah! Voi i vostri appunti li avete
sott'occhio, più o meno, perché no, mi
servirebbe più roba.
Alright,
ripensiamo alla macchina precedente, la
macchina che è in grado di distinguere
stringhe dispari da stringhe pari, ok?
E vogliamo capire come funziona
la macchina sulla stringa
01.
Ok.
No, non mi piace.
Facciamo 001 001.
Ok, quindi abbiamo la macchina di prima
e input riceve
la stringa 001. Ok? Adesso noi vogliamo
per impratichirci con questa nozione di
configurazione vogliamo capire qual è la
sequenza delle configurazioni che la
macchina attraversa prima di arrivare a
dire sì o no. Ok?
Allora, la macchina parte in Q0 e
all'inizio ha su sul nastro 001. Ok?
Quindi la prima configurazione della
macchina è stato iniziale tutta la
stringa.
Ok?
Questa configurazione
è seguita da un'altra configurazione che
sostanzialmente è quella che la macchina
raggiunge una volta che legge il primo
simbolo. Ok? Vi ricordate? Quindi siamo
in Q0,
leggiamo questo 0 qui, ok? Che cosa
succede alla macchina? Siamo in Q0,
leggiamo 0,
rimaniamo in Q0 perché c'era
quell'anellino, quindi il nuovo stato
sarà Q0.
Ci siamo detti che il simbolo appena
letto è stracciato va a finire
nell'immondizia e quindi quello che
rimane in input è 01. Ok? Quindi questa
configurazione,
questa configurazione qui è la next
legal, la configurazione legale
successiva rispetto a questo e alla
funzione di transizione di D. Ok? Cioè,
quindi questa segue questa secondo
delta, ok? La delta della macchina che
stiamo considerando non una delta
generica, ok?
Alri,
siamo in Q0, leggiamo zero. Che fa con
la macchina?
Rimane in Q0 e all'input che succede?
diventa uno uno. Ok, questo è l'altro
stato, l'altra configurazione. Ok, sto
andando lento perché poi quando faremo
Turing machines queste cose le facciamo
più astratte e andiamo più veloci. Ok.
Alright. Quindi adesso siamo in Q0. La
macchina legge uno. Che cosa succede? La
macchina va in Q1. Che succede
all'input?
si svuota.
Segniamo epil. Ok.
E questa è l'ultima configurazione. Ok.
Che peculiarità ha l'ultima
configurazione
che non ha nessun cioè nessuna funzione
associata, cioè non ha nessuno scambio
di stato in questo non c'è nessuno
scambio di stato. Ok.
Poi c'è un'altra caratteristica. Cos'è
lo Stato?
stato accettando e lo state accettando.
Quanta parte di stringa è rimasta?
Nessuna. Ok, la stringa si è svuotata.
Ah, ok. Perché ci stiamo focalizzando su
questo? Perché la condizione di accept
reject di una macchina la possiamo
definire in tanti modi, ok? Basta che è
coerente. Su alcuni libri troverete un
modo, su altri libri troverete altro.
Questo è il modo che in genere uso io.
La macchina accetta
se e solo se
a fine computazione si trova in uno
stato accettante
e sul nastro non è rimasto niente.
Ok? M questa informazione ovviamente
adesso formalizzeremo il tutto, ok? Però
questa informazione, questa definizione
ci dà un'informazione importante.
La macchina per dire sì devono succedere
due cose.
Deve consumare l'input, cioè deve
arrivare che dell'input non ci rimane
niente e lo stato in cui si trova alla
fine deve essere uno stato accettabile.
Quindi due cose devono accaderebbe, non
una solo input finish, stato finale è
uno stato accettante. Ok?
La macchina accetta solo in presenza di
queste due condizioni. Di conseguenza,
quand'è che la macchina rifiuta?
quando ha finito di leggere non è un
stato finale. Una condizione è che
abbiamo finito di leggere e non siamo in
uno stato accettante
oppure
perché io a differenza di altre
definizioni non uso gli stati di
rifiuto. Ok? Quindi abbiamo una
definizione un po' più sofisticata.
Quindi
la macchina accetta se leggo tutto e
quando arriva alla fine e c sta cadiamo
in uno stato accettante. Ok? Due cose
devono succedere, basta che una delle
due non accade e quindi sto rifiutando.
Quindi la macchina rifiuta quando?
O arriviamo in fondo
e siamo piombati in uno stato non
categorizzato come accettante, cioè uno
degli altri stati oppure
finale completamente
oppure la macchina è arrivata a un punto
della computazione per le quali l'input
non è finito e la funzione di
transizione non stabilisce due prossime
mosse, quindi la macchina si va a
bloccare in un punto, ok? Nel quale
ah da lì non si schioda. Ok? Quindi un
automa stati finiti accetta perché
almeno nella definizione che usiamo qua,
ma vi ripeto ce ne sono 1000
equivalenti. Se andate a leggere in giro
ci saranno le definizioni che parlano
degli stati di reject, ok? io non lo
trovo particolarmente utile per le cose
che dovremmo fare poi. Quindi la
definizione che è che un automa stati
finiti accetta se consume il suo input e
termina in uno stato accettato. Quindi
se non consume il suo input o lo consuma
e va a finire in uno stato non tra
quelli accettanti, la macchina rifiuta.
Ok? E questa cosa adesso la
formalizziamo.
Quindi
partiamo, per definire questa cosa,
partiamo dal concetto di
ehm
configurazione. Ok?
Quindi è chiaro cos'è una
configurazione? è una sequenza di
simboli il cui il primo è lo stato in
cui la macchina si trova, l'automa si
trova e gli altri simboli sono la parte
residua della stringa da processare. Ok?
una
computazione parziale
per
un automa D
su una stringa
W caratterizzata dai simboli V1 1 VN
è
una sequenza
di
m + 1 via m + 1
configurazioni
con mug
n
e le configurazioni sono R0 V1 bla bla
VN
R1 V2
VN
bla bla bla R
+ 1 1 N.
Quindi cos'è una computazione parziale
per un automa stati finiti? È
semplicemente per noi una sequenza.
Ancora non ho finito la definizione, eh,
la sto solo ripetendo. Cos'è una
computazione parziale? Poi diremo cos'è
una computazione completa. Una
computazione parziale di un automa a
stati finiti
è semplicemente una sequenza di
configurazioni,
la zeresima, l'unesima, la seconda,
l'emmesima, ok?
in cui m
non è più grosso di n. Ovviamente non
possiamo fare un numero di passi più
grande dei simboli presenti sullo
scontrino, sul nastro, tale per cui
R0
è uguale a Q0, cioè quindi la prima
configurazione deve avere come stato lo
stato iniziale della macchina. Ok?
Quindi questo partenza corretta, start
correct.
Ok? E poi semplicemente dobbiamo dire
che da un passaggio all'altro
questa sequenza caratterizza mosse leite
per la macchina D. Come lo facciamo a
dire? semplicemente che lo stato al
passo i + 1 è quello che si ottiene
andando a guardare la funzione di
transizione
in cui lo stato la coppia R v + 1 viene
letta, ok? E questo deve essere vero per
tutti gli indici tra 0 e m - 1. Ok?
Allora, cosa abbiamo scritto
formalmente? Questo è un modo difficile
per
formalizzare quello che abbiamo detto
prima, cioè che una computazione di una
macchina è caratterizzata
da una sequenza di configurazioni
la cui prima configurazione ha com'è
stato lo stato iniziale della macchina,
cioè la prima configurazione della lista
deve rispecchiare il fatto che la
macchina viene accesa e c'è l'input.
Quindi la prima configurazione deve
essere stato iniziale
e poi tutti i simboli della stringa
tutti. Ok? Dopodiché la computazione noi
la modelliamo come una sequenza di
fotografie
in cui lo stato della fotografia al
passo i + 1 deve essere quello ottenuto
dall'applicazione della funzione di
transizione dello stato al passo
precedente e del simbolo letto in quel
momento. Ok? Cioè, noi asbiamo
semplicemente scritto in un modo
complicato che cosa? Che una
computazione parziale è una sequenza di
foto in cui la prima deve rispecchiare
la partenza della macchina e la sequenza
deve essere sensata.
Quindi a ogni passaggio, come vedete, 1
qua, qua partiamo da V1, qua c'è V2,
quindi a ogni passaggio un simbolo dallo
scontrino sparisce e R1 è ottenuto da R0
tramite l'applicazione della funzione di
transizione. Ok?
Chiaro per tutti?
Prof? Ma perché m - 1 e non è? Perché?
Perché l'ultimo stato è RM e quindi tu
lo applichi al passaggio N - 1.
Ah, ok. Sì, sì, sì, sì.
Ah,
alright. Stiamo andando più lento del
previsto. Ehm. Ok?
Quindi questa è la definizione di
computazione parziale.
Da questa deriviamo la definizione di
computazione, cioè la computazione
totale. Ok?
Cos'è una computazione?
una computazione,
dobbiamo semplicemente dire, adesso
facciamolo assieme,
dobbiamo una computazione sarà una
computazione parziale che non possiamo
estendere di più, ok? Questo è è il
senso che che non c'ha altri passi, cioè
è una lista completa, è una lista
massimale che altra roba in coda non si
ci può infilare. Allora, una
computazione è una computazione
parziale, quindi è una computazione è
una sequenza di di configurazioni che
rispetta queste proprietà che però ha
una proprietà aggiuntiva.
l'ultima configurazione della lista
o
non ammette passi successivi, cioè la
funzione di transizione applicata allo
stato dell'ultima configurazione,
mentre legge il simbolo che c'ha di
fronte, non c'è uno stato successivo,
quindi lì la macchina si impalla. Oppure
l'ultima configurazione
ha come stringa residua la stringa
vuota.
Ripeto,
una computazione. L'intuizione è questa.
Come otteniamo la definizione di
computazione dal dalla definizione di
computazione parziale? Una computazione
intuitivamente è una computazione
parziale che non possiamo tirare di più,
che non ci ci si può aggiungere roba.
Ok?
Quali sono le condizioni per le quali a
una computazione parziale non possiamo
aggiungere roba? Sono due: o l'ultima
configurazione non ammette una prossima
mossa perché non è definita, oppure la
stita. Ok, è chiaro?
Ci siamo quasi, dai.
Ok.
una computazione.
È chiaro per tutti come si definisce una
computazione partendo dalla computazione
parziale? Ok? Qua ovviamente la
computazione parziale su una stringa, la
computazione su una stringa non è che
esiste la computazione, ok? Una
computazione su una stringa w cos'è una
computazione parziale su W massimale?
Cioè che non ci appiccichiamo altre, ok?
una computazione,
una computazione su una stringa W
la chiamiamo accettante
se nella sua ultima configurazione
lo stato è accettante
e la stringa residua è vuota. Dopo Ok?
Scusate la sua configurazione,
cioè quindi se noi abbiamo tutta sta
lista di foto
è una computazione, quindi non una
computazione parziale, perché significa
che questa è una lista massimale, non
possiamo, cioè non succede altro, lì
arriva e lì si ferma. Andiamo a guardare
l'ultima foto. Se nell'ultima foto
abbiamo che lo Stato è accettante e di
stringa non c'è rimasta niente, allora
vuol dire che quella è ci sta
raccontando la storia di una
computazione che alla fine dice sì. Ok,
questo è il senso. Capito? Spiega nella
soluta configurazione quella di
Nell'ultima configurazione lo stato è
accettante, è uno degli stati accettanti
e il la stringa residua è ep è vuota.
Ok?
Ragazzi, vorrei solo sottolinearvi che
stiamo formalizzando cose di cui dovete
avere un'intuizione. Cioè, cos'è una
computazione? intuitivamente nella mia
testa cos'è una computazione? Perché se
iniziate a vedere i simboli impazziti,
cos'è nella mia testa una una
computazione? È una sequenza di foto di
foto che mi dicono lo stato di
avanzamento dei lavori della macchina.
Una computazione è una lista di foto che
non ci posso appiccicare niente dopo.
Ok?
Come faccio a stabilire se questa lista
di foto mi sta raccontando la storia di
una computazione accettante? E vado a
guardare l'ultima. Vado a guardare
l'ultima foto. Se la macchina ha finito
il suo input e si è fermata e non state
accettato, allora vuol dire che quella è
una computazione accettabile. Adesso
tutta sta simbologia che usiamo è solo
per formalizzare dell'intuizione che
abbiamo. Però dovete partire dallle
intuizione, senò è impossibile da capire
sta cosa. Cioè manipolare simboli in
testa senza avere un'intuizione viene
difficilissimo. Come faccio io, io vi
faccio queste immagini. Cos'è una
configurazione? una storia di foto. Ta
ta ta. Ok, cioè questa è la metafora che
uso. Prego. Potrei definire unazione una
conazione parziale in cui n uguale m Sì,
sì, sì, sì, sì, sì.
Eh, non sempre, perché tu pu potresti
avere si potrebbe avere il caso in cui
la macchina si arresta prima.
Allora, nell'esempio visto ieri nella
macchina di prima, quella macchina ha
una funzione che la funzione di
transizione ha la caratteristica di
essere una funzione totale, cioè per
ogni coppia stato simbolo so cosa fare.
Altre macchine e avrei voluto avere il
tempo di farvele vedere. La funzione è
parziale, cioè arrivo in uno stato e io
mi aspetto di leggere un certo simbolo.
Se leggo altro la macchina si ferma là,
non fa nient'altro. Quindi la sua
computazione potrebbe avere una
lunghezza inferiore se si è bloccata
prima. In quel caso non potremmo eh
distendere la funzione con dei cicli
o la fai la butti verso degli stati
spazzatura. Ognuno se la può definire
come vuole, ok? Cioè sono tutte
equivalenti, uno la definisce come
vuole. Di nuovo non è orocolato, cioè
noi abbiamo questa intuizione di come
funziona una macchina. La sua
formalizzazione può avvenire in tanti
modi. L'importante è che sia. Ok? le
ultime cose, quindi abbiamo detto che
una computazione accettante è una
computazione che termina di cui l'ultima
configurazione ci sta raccontando la
storia di una macchina che si è letta
tutto lì ed è finita nello stato
accettato. Ok?
Una macchina, un automa sta definita
accetta una stringa W.
Se la computazione
che parte dalla configurazione Q0W
[Musica]
termina in uno stato accettato.
che una macchina accetta una stringa W
se la configur se la computazione
la cui prima foto è quella della
macchina che parte nello stato iniziale
e legge tutta l'astenita W
è la prima foto di una sequenza che
arriverà a quella in cui la macchina si
è letto tutto e sta accettando. Ok?
Quindi la macchina accetta W. Se la
computazione che parte con la
configurazione in cui la macchina sta
leggendo W andrà a terminare in una
configurazione accettante.
È chiaro?
Scusi, ma le varie definizioni che
stiamo dando si intercambano tra di loro
oppure sono scresse? No, si costruiscono
una sull'altra perché quindi abbiamo al
piano al piano terra abbiamo
computazione parziale, poi computazione
che è costruita sopra una computazione
parziale. Poi abbiamo dato la
definizione di computazione accettante,
che è un sotto caso delle computazioni.
E che cosa diciamo? una macchina accetta
una stringa W se la computazione che
inizia con la lettura di W è una
computazione accettante, cioè arrivo in
fondo e accettiamo. Ma quella che
definiamo per ultimo che quindi tra
virgolette è solo stack nel primo punto
non si può definire se non abbiamo
definito i teatre no perché sono tuttef
specificazioni delle precedenti una
comput una computazione accettante è una
computazione. una computazione è una
computazione parziale, cioè perché noi
stiamo intuitivamente che stiamo
facendo? Stiamo aggiungendo aggettivi,
no? Quindi l'oggetto di analisi è sempre
lo stesso.
Ok? Stiamo restringendo l'insieme,
abbiamo l'insieme di tutte le
computazioni parziali. Tra tutte le
computazioni parziali ci sono quelle di
lunghezza massimale e quelle per noi le
chiamiamo computazioni, puoi chiamarle
totali? Computazioni totali. Tra tutte
le computazioni totali ci sono quelle
che vanno a finire in uno stato
accettante. Quelle per noi sono le
computazioni accettate parziali totali
computazioni accettiremo
quando un automa potrà eh risolvere o
meno un problema decidibile. Ci siamo.
L'ultimo passaggio.
Un automa. Sì. No, no. Volevo chiedere
di riprendere un attimo la definizione
di accettazione. No, ha detto un
automast accetta una stringa W se la
computazione la cui prima configurazione
è Q0 W va a terminare in una una
computazione in una configurazione
accettata. Ok? Cioè accetta W, cioè la
storia delle foto in cui la prima foto è
quella in cui la macchina sta leggendo W
va a finire Sì, sì, sì. con quella e
accetto. Ok? Cioè, poi ovviamente uno si
può dare anche altre cose, eh? Un
attimo, un attimo che sennò non
terminiamo. Quindi questa è la
definizione di accettazione.
La macchina rifiuta una stringa quando
questa cosa non è vera. Intuitivamente
la macchina rifiuta la stringa quando o
si impalla mentre la sta processando in
uno stato non accettante oppure arriva
alla fine, ma si è fermata in uno stato
non accettante. Ok?
E adesso la definizione che ci serve è
quella che ci chiedeva il nostro
collega, una macchina D.
Ho visto, ho visto. Stava registrando
l'audio. Questo I guess so. I hope so.
Ah,
dice che se
Ah, sì, penso di sì.
Ultimo passaggio. Un automa D
decide
un linguaggio L.
Se
ogni stringa W che appartiene ad L
è accettata da D?
E
ogni stringa W
che non appartiene ad L
è rifiutata da D.
Ok?
Chiaro per tutti questa definizione.
Quindi un auto, una macchina decide un
linguaggio. Qual è l'intuizione? Cioè,
ogni volta che gli diamo una stringa che
appartiene a L, quella ci dice sì. Ogni
volta che gli diamo input una stringa
che non appartiene a L, la macchina ci
dice no. Ok, chiaro per tutti? Vi ho
fracassato bene la testa. Facciamo un
po' di pausa 10
meno poi ho visto.
Ok, ripartiamo.
Avevo messo di far tutta una serie di
cose, vabboh, sono il minimo
indispensabile.
Ok, abbiamo visto cos'è un automa.
Abbiamo visto che ha stati infiniti,
significa che il numero delle pallette è
finito e non può crescere durante il
calcolo.
Ci sta lui.
What else? Abbiamo dato la definizione
formale, bla bla. Facciamo un salto.
Facciamo un salto verso un'altra cosa,
ok? Che ci introduce questo concetto che
poi ci serve per touring machines più
sofisticate per chi non avesse questi
concetti. Ok? Supponiamo di voler
riconoscere questo linguaggio.
Eh, certo,
[Musica]
lo scriviamo con un'espressione
regolare, così vediamo pure questo. La
spieghiamo senza.
Allora, vogliamo riconoscere questo
linguaggio. Il linguaggio delle stringhe
binarie in cui abbiamo una sequenza di
zeri o uni. All'inizio,
spiego un po' a chi non l'ha mai visto
prima.
Questa cosa qua significa che all'inizio
abbiamo una sequenza di 0 o questa linea
verticale dice o una sequenza di 0 o 1
ripetuta 0 o più volte, quindi può
essere 00
101 10 bla bla bla che potrebbe non
esserci perché c'è l'asterisco
e però si deve concludere con tre zeri
di fila. Ok?
Consideriamo questa macchina.
Siamo in Q0 è lo stato iniziale. Noi
partiamo da qua
e facciamo questo.
Se leggiamo 0 rimaniamo in Q0.
Se leggiamo 1 rimaniamo in Q0.
Se leggo 0 vado in Q1, leggo un altro 0
vado in Q2, leggo un altro 0 vado in Q3.
È intuitiva questa macchina, no? Cioè
l'intuizione di questa macchina è in Q0
salto una sequenza di zeri e uni bla bla
bla bla bla bla bla, poi a un certo
punto leggo gli ultimi tre zeri.
È chiaro il significato? C'è una
semantica di questa cosa?
Cioè, che cosa mi piacerebbe che questa
macchina facesse? Chiaro per tutti?
Che problema ha questa macchina?
Un attimo. Hai seguito linguaggi?
Non ho
no più una domanda. Se io sono in Q2 Q2
con uno io devo tornare indietro? No, se
vecchio rimare bloccato là perché la
funzione di transizione la definita così
come è scritto questo grafo. Ok? Allora,
dove aspetta che chi ha seguito
linguaggi? La risposta la sapete, voglio
sentire gli altri. Che problema c'ha
questa macchina? Guardate che è
intuitiva. A morì sta macchina salta un
po' di zeri e un bla bla bla. A un certo
punto mi leggo gli ultimi tre zeri. Ok.
Lei non ha seguito linguaggi? No. Ok.
Esattamente. Questa macchina ha questo
piccolissimo problema. In Q0
se legge zero non sa che fare, cioè fa
rimango in V0, vado in Q1.
Ok?
Però siccome
siccome queste macchine, no, da un punto
di vista intuitivo sono fantastiche
perché ci permettono di programmare in
maniera molto semplice delle cose, noi
ok, le consideriamo lo stesso. Ok? Una
macchina di questo tipo noi la chiamiamo
non deterministica.
e non deterministica
perché
ci sono delle configurazioni,
cioè quindi delle foto, degli snapshot,
del funzionamento corrente della
macchina,
delle configurazioni,
le cui configurazioni
legali successive
possono essere più di una.
È chiaro? Cioè, questo è il senso di
macchina non deterministica. Questa è
una macchina un pochino strana perché è
una macchina che durante il suo calcolo
ha dei punti di scelta
non determinati. Cioè, non è che noi gli
stiamo dicendo che fare in presenza
nello stato Q0 quando legge zero. Noi
non gli stiamo dicendo niente, gli
stiamo dicendo queste sono le tue
possibilità.
Puoi rimanere il Q0, puoi transire il
Q1. Ok? E questo è
una
è alla base del concetto di non
determinismo.
Definizione formale di macchina non
deterministica.
Allora,
where is it? Questo qua N è automa stati
finito non deterministico.
Si definisce in maniera veramente
similare a quello che abbiamo visto
prima. Quindi rivediamola assieme.
Da che cosa è caratterizzato un automa?
Dagli stati. Dall'alfabeto. Ok. Quindi è
pure una macchina non deterministica, è
caratterizzata da un alfabeto
e
poi è caratterizzato da stati dagli
stati,
poi è caratterizzato da iniziale lo
stato iniziale,
poi è caratterizzato da gli stati
accettanti E fino a qui la definizione è
identica, ok?
Dopodiché dobbiamo definire il suo
programma, che è un pochino strano
rispetto ai programmi della
delle macchine deterministiche. Quindi
avremo delta che è il programma di una
macchina non deterministica. Ok? Poi
faremo un po' di esempi e definiamo
cos'è l'accettazione, trucchi di
programmazione, perché qua si deve un
po' giocare.
Il programma che nelle macchine
deterministiche era
una funzione
macchine deterministiche abbiamo che
delta è una funzione che dato uno stato
è un simbolo corrente andiamo in uno
stato successivo.
Nelle macchine non deterministiche
delta è una la chiamiamo relazione.
Possiamo definirla come funzione, però a
volte la chiamiamo relazione di
transizione
perché
dato lo stato corrente Q, vedete, fin
qui è tutto uguale, è il simbolo che
leggiamo scritto proprio da me
dove sta? Qua è sigma. Ok, vedete? Cioè,
la parte iniziale è uguale. Cambia
l'output. L'output di questa funzione è
invece di dirci qual è lo stato
successivo
ci dà un insieme di stati successivi,
cioè mappiamo verso l'insieme delle
parti, il powers set di Q. Ok? Quindi
la funzione di relazione, quindi una
macchina non deterministica, la sua
definizione è quasi uguale a quella
deterministica. Abbiamo i simboli,
abbiamo gli stati, abbiamo lo stato
iniziale, abbiamo lo stato accettante e
fino a lì è la stessissima cosa. Quello
che cambia è il suo programma. Il
programma di una macchina deterministica
è dato uno stato e un simbolo so che
fare dopo per una macchina non
deterministica e dato uno stato e un
simbolo o una serie di posso avere una
serie di scel. Come vedete non è che è
sempre così. Nella macchina che abbiamo
visto qua,
il neterminismo
avviene qua, ma il resto della macchina
è deterministica, ok? Cioè, non è che
una macchina non deterministica deve
essere non deterministica in tutta la
sua fase di esecuzione, cioè può avere
del non determinismo. Ok? Quindi la
differenza nella definizione di funzione
di transizione che è una relazione
dato lo stato corrente e il singolo
letto correntemente.
Non ho soltanto qual è il prossimo
passo, ma ho un insieme di prossimi
passi.
Ok?
Cos'è a questo punto una
computazione parziale
per una macchina non deterministica?
Allora, se guardate i vostri appunti
intuitivamente, che cos'era una
computazione parziale? una computazione
parziale è
una sequenza di foto in cui la prima
foto ci dice come la macchina svavia. La
macchina si avvia nello stato iniziale
con tutta la stend.
Quindi è una sequenza di foto in cui
avevamo detto che ogni foto deve essere
il legal successor della sua precedente,
cioè ogni foto deve essere la prossima
configurazione legale
secondo la funzione di transizione.
Per le macchine non deterministiche è la
stessima cosa,
cioè una foto può seguire un'altra se lo
stato nella seconda configurazione
appartiene fra quelli disponibili che si
possono raggiungere secondo la funzione,
la relazione di transizione nella
configurazione precedente. Tutto qua.
Allora, nelle macchine deterministiche
noi abbiamo che ogni configurazione
determina qual è la sua successiva,
perché sappiamo questo è lo stato,
questo è il simbolo, la funzione ci dà
un solo next step. Quindi date una
configurazione, date una foto, noi
sappiamo che è quella di do qual è. Lo
stato è quello dato dalla funzione di
transizione.
La striga è che noi gli togliamo un
singolo che è facilissimo. Nelle
macchine non deterministiche una foto
può seguirne un'altra.
Basta che lo stato nella seconda foto è
uno di quelli ammessi dalla dalla
relazione di transizione a partire dallo
stato e simbolo. Ok?
Quindi in realtà adesso
e potete capire che un automa non
deterministico
quando
eh computa su una stringa può avere più
computazioni differenti. Ad esempio,
nell'esempio che abbiamo visto prima,
questo qua, eh voi voi l'avete
l'appunto. Ok? Supponiamo,
ok, che vogliamo riconoscere
questa stringa qua, 0.
Ok?
Allora, una computazione potrebbe essere
Q00
seguito da
Q0
seguito da Q 00
seguito da Q100
seguito da Q20
seguito da E seguito da Q3 vuoto. È
chiaro? Cioè quella macchina quando
legge abbiamo detto 01
che cosa fa?
Legge il primo 0 e rimane qua.
Legge 1 e rimane qua. Poi legge 0 0 e
accetta. Questa cosa è
fotografata da questa sequenza qui.
Però questa macchina potrebbe fare pure
un'altra cosa. Al primo zero, invece di
rimanere qua, se ne va avanti. Quindi
un'altra questa è una computazione
legale su 0100
per la macchina N. Però un'altra è
questa qui.
Partiamo sempre da Q0. Ok? Vedete? La
prima foto è sempre la stessa, Q0.
Poi andiamo avanti e facciamo Q1.
Dopodiché la macchina si blocca perché
in Q1 non abbiamo Ei,
in Q1 non abbiamo la definizione di
lettura del simbolo 1. Ok? E quindi
questa è una computazione
e questa è un'altra computazione. Tutte
e due sono legali, ok? Perché rispettano
il fatto che le foto in sequenza
aderiscono al alle regole dettate dalla
relazione di transizione. Ok?
Però che cosa abbiamo? che questa qui,
la prima, è una computazione
accettante perché andiamo a finire in
una configurazione accettante.
Mentre la seconda, sebbene sia una
computazione legale, è una computazione
rigettante, come si dice in italiano,
rejecting rifiutante. Ok,
è chiaro dov'è qua il bous della
questione? Noi abbiamo questa macchina
che riceve input su, una stringa, ha due
computazioni legali,
ok? In una accetta e in un'altra
rifiuta. Allora, la questione qui è
ma questa macchina la stringa 0100
l'accetta o la rifiuta?
L'accetta.
Come? Perché noi cambiamo la definizione
di accettazione
per una un'automa a stati finiti non
deterministico
N
accetta una stringa
W
se esiste
[Musica]
una computazione
di n
su w
che sia accettabile.
L'intuizione qual è?
Una macchina non deterministica
accetta una stringa se esiste un modo
per accettarlo.
Questo è Ok.
E siccome la esiste un modo per la
stringa 0100
di essere accettata da questa macchina
qua, allora vuol dire che quella
macchina la stringa l'accetta. Ok?
Ok. Questo è il passaggio importante,
eh, una macchina non deterministica
accetta una stringa input
se esiste un modo per accettarla.
Ok,
prego. Scusi, l'automa che ha disegnato
lei è un è un automa D errato e un
mentre un automa N corretto. Sì, è un
automa non deterministico. Sì,
una macchina non deterministico. accetto
una stringa input
se esiste un modo per la macchina
di accettare la stringa.
Quindi proprio quando per capire se
effettivamente una stringa do W è
accettata dovrà provare tutte le
possibili combinazioni. Sì, adesso
adesso vi spiego un po' sta faccendata.
Allora, è interessante questa domanda
qui
che ci ha fatto la nostra collega. Ho
detto "Ma allora una macchina non
deterministica per accettare la propria
stringa prova tutte le strade?" Oppure
la domanda che ci ha fatto il nostro
collega, ma se una una macchina non
deterministica,
mentre nel calcolo a un certo punto si
accorge che ha sbagliato, che fa? Torna
indietro?
Ok?
Oppure altri dicono "No, non fa questa
cosa qua." Una macchina non
deterministica prova tutte le strade
contemporaneamente. Questa è un'altra
metafora. Ok? Adesso, seconda volta, una
macchina non deterministica che fa? Le
prova tutti assieme, le prova una dopo
l'altra, torna indietro, fa backtracking
quando sbaglia, che fa una macchina non
deterministica?
Non è il path problem, cioè non è il
problem, è anche un path problem, però
supponiamo di avere questa macchina, ok?
Ma una bellissima automa stati finiti
non deterministico. Eh, gli infiliamo un
input come quello là, quindi sul quale
la scelta che fa sul primo zero fa la
differenza. È chiaro per tutti?
Quindi se la macchina sul primo zero
rimane in q0
alla fine accetterà. Se la macchina sul
primo 0 si sposta in Q1 rifiuterà. Ok?
Ma allora sta macchina che fa?
li prova tutti contemporaneamente,
li prova uno dopo l'altro, fa
backtracking. Che fa sta macchina?
Essendo un deterministic prova
casualmente la prima strada che Ok,
questa è un'altra metafora. La macchina
tira un bel dado e cerca di stabilire da
che lato andare. E se il dado, se la
Flipcoin non funziona, si impalla e
muore. Si impalla e muore. Questa è una
possibilità. Eh sì. un'altra possibilità
se fisse dal fondo, cioè nel senso parte
da uno stato da uno stato accettante e
poi va e ok, però ci sono quelle che per
esempio avresti
non determinismo a tornare indietro, ok?
Che fa sta macchina? le fai in
parallelo, tira la monetina,
usa la palla di cristallo.
Eh, non abbiamo definito un algoritmo,
quindi, cioè, io immagino prova a fare a
eseguire, cioè a leggere la stringa e se
sarà stata accettata sarà stata
accettata, altrimenti se sarà stata
riata, cioè perché non abbiamo definito
un algoritmo, l'algoritmo è quello, eh
però ed è dato dalla relazione di
transizione. Eh, però siccome non è
deterministico, allora quello che farà
fare una volta e basta. Ma lo fa una
volta e basta e se prende la strada
sbagliata e la B andiamo a sbattere al
muro. Eccolo
e questa è anche una possibilità. Prego.
Può guardare più simboli? Può guardare
più simboli? No, la macchina ne guarda
uno solo,
guys. Oh, prego. Io penso che faccio un
backing. Back tracking. Ok. Allora,
volete una soluzione?
La domanda è mal posta.
Questa macchina non fa niente perché
questa macchina non esiste.
Non esiste un una macchina fisica in
grado di fare una cosa di questo tipo.
Questo è un modello astratto. Punto.
Quindi non va né in parallelo, non falli
tentativi, non usa la palla di
cristallo, non tira la monetina. Questa
macchina non esiste.
Questo è solamente un modello astratto
di calcolo che ci siamo inventati
per semplificarci
lo studio dei linguaggi. Tutto qua. Però
ovviamente quando noi poi dobbiamo
andarle a programmare queste strade non
queste macchine non deterministiche una
metafora in testa la dovremmo avere.
Questa è la metafora che uso io e in
genere mi ci trovo bene.
La macchina quando arriva un punto di
scelta
se c'è un punto corretto, se c'è una
scelta corretta la prende bene come
Eh, certo. Non esiste, me la invento
come voglio.
Devo stare attento però che poi io
verifichi,
poi questo lo vedremo di più sulle sulle
macchine di Touring, faremo degli esempi
più specifici perché là poi dobbiamo
stare attenti, eh, ci inventiamo, cioè
dobbiamo stare attenti, vi faccio vedere
velocemente
questo qua. Voi state
voglio far notare una cosa su questa
macchina qui. La macchina sta facendo il
guess, cioè sta indovinando che fare.
Ok? Però una volta che la macchina ha
risolto la questione su un certo zero,
se andare avanti verso Q1, rimanere in
Q0, come vedete questa macchina fa un
controllo deterministico, cioè io poi
alla fine devo verificare che non ho
preso una cantonata perché perché questa
macchina non esiste, quindi non è che è
una macchina che veramente
ha la palla di cristallo ed è in grado
di fare questa cosa. La condizione di
accettazione di questa macchina è la
macchina accetta se esiste un modo per
accettare. Ma quindi allora dobbiamo
definire la sua relazione di transizione
in maniera tale che se la stringa va
rifiutata non ci siano modi per
accettare. Ecco perché intuitivamente,
poi vedremo più nel dettaglio, io metto
questo controllo finale.
È chiaro? Allora, perché perché ci siamo
quasi, dai. Perché?
Scusi. Sì, ma quindi la definizione la
relazione del dell'emn Sì. Eh,
dobbiamo formalizzare meglio oppure
basta quello che abbiamo già dato? Ah,
basta quello che abbiamo già dato. Ok.
La ripeto, la definizione di macchina di
automa non deterministico a che delta è
una relazione di transizione invece che
di una funzione di transizione. Ok?
Questa è la differenza. Cos'è una
computazione? Va semplicemente cambiata.
Eh, qui,
vedete qua
nella definizione di computazione noi
abbiamo che lo stato al passo i + 1 è
dato dal risultato dell'applicazione
della funzione di transizione sulla
coppia stato al passo i simbolo che mi
devo leggere.
Nel caso di macchina non deterministica,
questo pezzo qua è semplicemente
sostituito che invece dell'uguale
ciò appartiene,
capito? Tutto qua. Quindi questo è il
pezzettino che dobbiamo cambiare. Poi
una computazione accettante si definisce
allo stesso modo, quindi è una
computazione legale la cui ultima foto è
una configurazione accettante. Cambia la
definizione di accettazione. Una
macchina non deterministica accetta una
stringa W se esiste una computazione
accettante della macchina su doppia B.
Questa è l'unica differenza per le
macchine deterministiche dalta W c'è
un'unica computazione, quindi quella o è
accettante o non accettante. Sulle
macchine non deterministiche, siccome
possono esserci più computazioni sulla
stessa W, allora noi diciamo che la
macchina accetta W se fra tutte le
computazioni che può fare sul W almeno
una è accettabile. Questa è la
differenza di
definizione.
Una macchina, un automa non
deterministico decide un certo
linguaggio L se accetta tutte le
stringhe che appartengono a L e rifiuta
tutte le stringhe che non appartengono a
L. Ok? Quindi cambia giusto la
definizione di computazione,
relazione di transizione e la condizione
di accettamento accettazione.
Chiaro? Ok.
Allora, le stiamo facendo perché poi le
rivedremo su tuning machines. Su tuning
machines rivedremo queste definizioni
con dei pezzi in più. Ok? Son voluto
partire da qua perché sono proprio base,
poi ci aggiungiamo dei pezzi e qua
magicamente abbiamo delle definizioni di
teorie di machine. Ok? Perché la gente
si è rotta la testa a
studiare questo tipo di di automi?
Perché, come avete visto, sebbene siano
strani, hanno una certa semplicità di
programmazione perché dici "Oh, cavolo,
la macchina indovina"
è è facile. Ok, esiste un risultato che
chi ha fatto il corso di linguaggi
conosce, però non rivediamo qui, che
dimostra che tutto ciò che è decidibile
da un automa non deterministico
è decidibile anche da un automa
deterministico. Ok? esiste un modo per
convertire uno nell'altro, non lo
vediamo, se ne andrebbero due lezioni, è
una cosa che non abbiamo il tempo di
fare. Ok, quindi perché si fa? Perché
programmare un automa non deterministico
è intuitivamente più semplice e poi lo
do in pasta un traduttore. Il traduttore
prende la macchina non deterministica,
tira fuori la macchina deterministica e
abbiamo quello che ci serve. Perché se
vogliamo eseguirlo
su una macchina fisica ci serve un
programma deterministico. Ok.
Ultimo pezzo.
Eh eh eh eh eh.
Ultimo pezzo, vediamo di fare tutto in
10 minuti.
Do un'intuizione di un risultato che
non dimostreremo
in tutti i dettagli perché non c'è
tempo, però giusto per farvi vedere che
insomma
con queste macchine non è che possiamo
fare quello che vogliamo. sono macchine
semplici che riconoscono
linguaggi semplici sostanzialmente. Ok?
Allora, supponiamo di voler riconoscere
questo linguaggio qui. Abbiamo
l'alfabeto dei simboli AB
e il linguaggio
è questo,
l'insieme delle stringhe ammale
che M è un intero maggiore o uguale di
0. Che cosa significa? Questo è il
linguaggio,
un linguaggio sull'alfabeto dei simboli
A e B che contiene tutte le stringhe
formate da un primo gruppo di ma, quindi
a elevato M per noi significa che ci
sono m simboli a
seguito da un gruppo di Moli B. Devono
essere M. Se ce ne stanno 3A ci devono
essere 3B. Se ci stanno 4 A ci devono
essere 4B. Ok?
È chiaro questo linguaggio? Che cos'è?
Adesso questo linguaggio che è
semplicissimo. In Python sapreste
scrivere un programmino che date in
input una stringa di A e di B è in grado
di dire sì. C'è la stringa ha quella
forma.
Sì, in fondo sì. Ok.
è un linguaggio riconoscibile, cioè un
computer standard per noi è in grado di
farlo. Però un automa stati definiti
deterministico
e non deterministico perché vi ho detto
che hanno lo stesso potere espressivo,
non è in grado di farlo. Ok? E adesso
cerchiamo di dare solamente un
velocissimo perché in 10 minuti non ce
la facciamo, un'intuizione del perché
non può esistere un automa stati
definiti che è in grado di riconoscere
questo linguaggio.
Mi ero preparato pure delle slide,
vediamo un po'.
E mi sono dimenticato di prendere
giustamente. Allora, vediamo un po'.
Alri,
me lo fa scaricare sta Geg?
Eh, poi poi non funziona perché non si
vede bene. Ok, zoomiamo qua. Alrgri.
Ok.
Allora, che problema ha sto cavolo di
linguaggio? Allora, il problema di
questo di questo linguaggio è, come
abbiamo detto amm
in cui m è maggiore o uguale di 0. Il
ciò significa che la stringa vuota
dobbiamo essere in grado di accettarlo.
Quindi un primo automa, un primo pezzo
di questo automa potrebbe essere uno
stato iniziale che è anche accettante
perché se non leggiamo niente dobbiamo
rispondere sì. Ok? Quindi quest'automa
qua è in grado di accettare la stringa
vuota.
è in grado di accettare la stringa AB?
No, ci serve un pezzo aggiuntivo e
andiamo qua. Ok? Questo automa è in
grado di riconoscere EP, è in grado di
conoscere AB perché che legge A e va su,
legge B scende giù e accetta. Ok?
Ma questo automa è in grado di accettare
A BB?
Sì. No, no, no, perché A perché una
volta che è arrivato qua
non c'è la seconda a, no? Ok, ci
aggiungiamo un pezzo.
Ok.
A A B. Ok. Adesso saremmo in grado di
riconoscer
è sufficiente? No, perché non saremmo in
grado di conoscere nemmeno a A a A B b.
Ok? Allora, ci serve un altro pezzo,
ma questo non riconoscerebbe stringhe
più lunghe, ci servirebbe un pezzo
ancora più lungo, ma questo non
riconoscerebbe stringhe ancora più
lunghe, ci servirebbe qualcosa di ancora
più lungo. Allora, l'intuizione
è che un autonoma stati finiti,
come in questo caso, non è in grado di
contare
perché non ha, poiché il suo numero di
stati è finito, non è in grado di tenere
traccia di una storia di computazione di
lunghezza.
Cioè non è in grado di fare 1 2 3 4 e
poi di nuovo 1 2 3 4. Questa cosa un
automa stati finiti non lo sa fare, cioè
non sa contare le cose e ricordarsi il
conteggio. Se deve sapere che se deve,
come abbiamo visto prima, vedere tre
zeri di fila e sa fin da subito che
devono essere tre, allora si fa tre
passaggi di stato. Ma se io devo
contare, ricordarmi sto numero e poi
ricontare di nuovo per vedere che i miei
numeri sono uguali, allora questa cosa
non è in grado di farla. Ok? Questa
ovviamente è un'intuizione,
esiste una dimostrazione formale che mi
sa che il tempo non l'abbiamo, però
cerco di darvi un'intuizione su come si
mostra. Ok?
Supponiamo supponiamo che invece siamo
in grado di costruire un automa a stati
finiti, no? Che in grado di riconoscere
queste stringhe a a b. Ok?
Supponiamo noi lo assumiamo
deterministico perché sappiamo che non è
meno potente di un non deterministico.
Ok? Quindi supponiamo che esista un
automa stati finiti deterministico in
grado di riconoscere questa questo
linguaggio strano. Ok?
E siccome un automa stati finiti
avrà un numero finito di stati.
Diciamo che sono P, sono 5 10 18 32 P
gli diamo un nome, ok? Quindi questa
automa ha un numero P di stati. Ok?
Allora, noi che cosa facciamo?
Se questo automa riconosce questo
linguaggio, deve essere in grado di
decidere tutte le stringhe di questo
linguaggio, non solo quelle piccole,
anche quelle grandi. E allora gliene
diamo in input un enorme. Ok? Che ne so?
L'automa c'ha 18 stati, gli diamo in
input una stringa di 2000 caratteri. Ci
sono 1000 A e 1000 B. Ok, chiaro che
cosa stiamo facendo? Alr, proviamo a
visualizzare un po' nella nostra mente
che cosa fa questa macchina mentre
calcola questa macchina di solo 18 stati
mentre processa questa stringona, ok?
2000 caratteri.
Quindi partiamo e la macchinia sarà in
un primo stato. Poi andrà leggerà una a
una a e andrà
non sia meglio. Yes. Legge una A e andrà
in un secondo stato. Poi legge un'altra
A, andrà in un terzo stato. Legge
un'altra a, andrà in un quarto stato, in
un quinto, in un sesto, bla, bla bla
bla, fino a quando arriva alla lunghezza
2m che per noi è 2000. Ok?
Cosa sta facendo questa macchina? Sta,
come abbiamo visto, transendo
da uno stato all'altro mentre si sta
guardando questi caratteri. Ok?
Allora, noi abbiamo una sequenza di 2000
passi,
ma la macchina ne ha, diciamo, solo 18,
come dicevamo prima. Sto dicendo 18,
potrebbe essere 172. Ok? È un numero
piccolo,
quindi facciamo 2000 passi, ma la
macchina ha un numero di stati molto
piccolo. Che cosa possiamo dire su
questa sequenza di stati?
[Musica]
Sì,
qualcuno di quegli stati si deve
ripetere, no? Per il pigon all
principle, se io vado avanti 2000 stati
e ne devo pescare da un insieme di 18, a
un certo punto sti stati si devono
ripetere, ok? Cioè non è possibile che
siano tutte e 2000 differenti. Vuol dire
che la macchina mentre sta girando a un
certo punto deve per forza rivedere uno
stato da cui c'era stata prima, ok?
perché il suo numero di stati è limitato
e la stringa che sta processando è
catastroficamente enorme. Ok? Quindi la
sequenza di passi che la macchina fa non
è tanto lineare, ma è più qualcosa di
questo tipo. Cioè a un certo punto la
macchina deve tornare su una cosa da cui
è già passata.
Ok?
Adesso
poi se volete vi leggete il commentino,
visto che ho 2 minuti e non posso andare
oltre. L'unica cosa a cui dobbiamo stare
attento è siccome stiamo assumendo
che la macchina è deterministica,
qui in questo stato qua, non posso avere
A qui e A qui, altrimenti sarebbe non
deterministica. Quindi questo anello si
deve appendere alla fine delle A.
per forza. Di conseguenza, questa
macchina che cosa riconosce? Legge A a A
a A, poi legge a A a A a A a A, poi ci
stanno le B. Quindi questo qui potrebbe
essere un giro di MA e poi seguito da
MB.
Però se la macchina ha questa forma, in
realtà accetta anche a a a ah tutte
queste, poi si fanno un altro giro,
un'altra ancora, un altro ancora e poi
si legge le B. Di conseguenza questa
macchina non ha il vincolo di vedere
tante B quante A. Può vedere più A di B
per la sua struttura di com'è fatto,
perché perché questa macchina non sa
contare.
Ok.
Cosa tiriamo fuori da ciò? Che ci sono
linguaggi e problemi, no? Questo qua è
leggere se ci sono tante AT B. È come
avere un problema del tipo conta gli
elementi di questi due insieme e dimmi
che è lo stesso numero, ok? È lo stesso
identico problema. Allora, questo
problema che noi sappiamo essere
risolvibile tramite un semplicissimo
programma Python in realtà non è
risolvibile su un automa stati finiti
e infatti gli automi a Stati Uniti non
sono un formalismo sufficiente
sufficientemente potente da permetterci
di dire cosa è decidibile e cosa non è
decidibile. Questi automi dobbiamo
arricchire in qualcosa di più
sofisticato che siano in grado di
riconoscere i linguaggi più tosti e
otterremo il modello che è il modello
della macchina di touring, che è un
automa più potente di quello che abbiamo
visto e mostreremo che ha la potenza di
tutti i computer. Questa cosa la vedremo
dalla prossima settimana, ok? Chiaro per
tutti?
Ok. Grazie mille. Buona giornata.
[Musica]
Eh