Ok, iniziamo. Iniziamo. Ah, dopo questa pausa forzata di una settimana che immagino avrete sfruttato sicuramente per ripetervi le cose che ne sono certo. Vi ricordate una cipa, eh? Ok. E come facciamo oggi? È un po' un problema. Ok. Perché oggi facciamo riduzioni. Quindi, che cos'è una riduzione? Ve la ricordate? Eh sì. Fatemi vedere un po' le facce. Siete spersi. Niente, che ha mai sentito sta cosa? Chi è che si ricorda cos'è una ridezione? Ok, prego. Sì, trasformando esattamente. Esattamente. Esattamente. È una definizione formale di cos'è per noi una riduzione. Rintuizione c'è, è corretta. Prendiamo istanze di un problema, le trasformiamo in istanze di un altro problema, riutilizziamo le soluzioni per il problema di partenza, ok? E quando invece parliamo di problemi indecisione, che cos'è per noi una reduzione? Formalmente ve lo ricordate? Prego. Primo, stesso al secondo. Esattamente. Quindi, formalmente, per noi una riduzione è una funzione fita fra due problemi, cioè quindi è una funzione che è tailored, dato un problema di partenza e un problema di arrivo, però non è che trasforma problemi, trasforma cose? Trasforma istanze di problemi, ok? Quindi è una funzione che viene pensata fra problemi, però è una funzione che trasforma stringhe su stringhe. Ok? Fuzione da un problema A un problema B. Se uno F è calcolabile. Ok? Quindi se F non è calcolabile non è una riduzione e secondariamente F deve essere tale per cui per ogni stringa w che appartiene all'insieme delle stringhe W appartiene al linguaggio A se è solo se il trasformato di W tramite F appartiene a B. Ok? È chiaro per voi cosa significa se è solo se? Cioè che quando diciamo qua se è solo sé, che cosa intendiamo? Sì. Che significa se solo? C'è quando quando ha un significato formale specifico, eh perché poi lo riutilizziamo nelle dimostrazioni. Se X appartiene a allora anche f(x) appartiene B. Se X non appartiene ad A, allora anche f(x) non non appartiene a B. Ok? Questo è il significato. Se è solo 6 significa che se W appartiene ad A, allora il trasformato di W rispetto a F appartiene a B. Se W non appartiene ad A, allora il trasformato di W rispetto a F non appartiene a B. Ok? E se il trasformato di W appartiene a B, che B che possiamo dire del B? Ripeto, abbiamo f appartiene a B. E allora W appartiene ad A. Ok? In genere questi saranno i modi in cui sfruttiamo le cose, eh, cioè che se W appartiene ad A, dimostriamo che il trasformato di W appartiene a B. Se il trasformato di W appartiene a B, era perché partivamo da una W che apparteneva ad A, ok? e cioè le stringhe che noi otteniamo per testarle se appartengono a B o meno. Non è che sono stringhe a caso, sono stringhe ottenute tramite la trasformazione di F. Questo è importante, eh, oggi lo vedremo per vari esempi, però questa è la cosa specifica. Nel momento in cui trasformiamo stringhe su stringhe, le stringhe in arrivo hanno forma specifica. Le stringhe in arrivo sono stringhe ottenute tramite la trasformazione F. Ok? Questo è importante, senò le dimostrazioni non ci funzionano. Ok? Alr e vi ricordate per cosa le abbiamo usate le riduzioni? Un attimo, eh, vediamo un po'. Dimostrare un problema è Ok, le abbiamo usate per mostrare la difficoltà reciproca di alcuni problemi. Ok? Cioè, quindi se riduciamo un problema indecidibile A a un problema B, allora possiamo dire che anche B è indecidibile. Ok? Ci siamo lasciati con un esempino sul linguaggio vuoto e via. Quello che faremo oggi è noi ci chiediamo, ma questi problemi che sono indecidibili sono tutti un po' problemi del piffero, cioè sono tutti problemi che riguardano macchine di touring eccetera, ma è possibile che non ci siano problemi più naturali che siano indecidibili. Oggi vedremo un paio di problemi naturali che sono indecidibili, cioè problemi più standard che fanno parte della nostra, a parte il problema dell'arresto che più o meno riusciamo, no? è qualcosa che fa parte del del dominio delle cose che pensiamo, no? Dice magari un compilatore, se me lo dicesse, sarebbe utile, però per il resto quella comunque è un problema su macchine, altri problemi che abbiamo visto, quella roba stranissima del linguaggio diagonale eccetera, ma è possibile che sti problemi indecidibili hanno tutte forme strane? Quello che vedremo oggi è che ci sono problemi abbastanza naturali per i quali non esistono algoritmi che li risolvono, ok? E ovviamente no, non è così ovvio, però per dimostrare la loro indicibilità quello che faremo faremo delle riduzioni perché tramite riduzioni noi saremo più facilmente in grado di dire "Ok, questo problema è indecidibile perché è in grado di codificare, che ne so, il problema dell'arresto o il problema del linguaggio universale, no? Quindi avremo problemi altri, diciamo, che saranno indicibili mostrati tramite delle riduzioni." Ok? Quindi questo è quello che faremo oggi. Vediamo un problema prima della pausa e un problema dopo la pausa. Ok. Altro altro? No. Alri. Il primo problema che consideriamo è questo qua, il problema di corrispondenza di post, chiamiamo PCP. PCP. Ok. Post. Post. Post. Sì. nome di un matematico. Allora, questo problema è un problema su stringhe che si configura così. Abbiamo due liste di stringhe definite sullo stesso alfabeto, ad esempio questa e questa qua, questa qui e questa qui, questa qui e questa qua. Ok? Quindi abbiamo due liste che chiamiamo A e B di stringhe definite sullo stesso alfabeto. Abbiamo tante stringhe in A quante sono in B, quindi potremmo vederle pure come in coppie, ok? Coppie corrispondenti da quel nome che possono essere qualsiasi, ok? Cioè l'unico vincolo è che siano definite sullo stesso alfabeto. Allora, quello che noi ci chiediamo è se esista o meno una sequenza al solo, dico parole, poi lo scriviamo. Ok? Noi abbiamo che un'istanza è fatta in questo modo, no? un'istanza sì di questo problema è un'istanza tale per cui esiste una sequenza di indici tale per cui se prendiamo le stringhe dalla lista A secondo l'ordine di quei di quegli indici e le stringhe dalla lista B secondo l'ordine di quegli indici, arriviamo a costruire la stessa cosa. Ok? Cioè, quindi quello che noi ci chiediamo è data queste due liste di stringhe A e B, dove magari queste le chiamiamo R1, R2, R3 e così via. E queste sono S1, S2, S3 e così via. Quello che ci chiediamo è vero, no, che esiste una sequenza di indici I1, I2, I con n strettamente maggiore di 0 tale per cui R1 concatenato, R2 concatenato, bla bla bla bla concatenato. Sorry, this is wrong. R1 concatenato R2 concatenato bla bla bla R è uguale a che cosa? A S1 concatenato S2 concatenato bla bla bla bla concatenato SIN. Ok? Contate che non è che questi devono essere uguali a coppie, eh? Cioè è la somma totale che deve essere la stessa sem devono essere ordinate le microstringere. In che senso? Cioè da essere per forza S1 S2 oppure S1 S4. No, no, I1, I2, I3, I4. Ad esempio, una soluzione per questa qua è questa. La sequenza 2 1 1 3 è una soluzione per quell'istanza specifica perché partiamo dalla lista, per esempio, quelle costruite da R e quelle costruite da S. Ok? Prendiamo la stringa con indice 2 che è 10 1 1 mentre su S la stringa di indice 2 è 10. Poi prendiamo 1 su R e prendiamo 1 sulle stringhe S, poi un altro uno sulla stringhe R, un altro 1 sulle stringhe S e poi abbiamo l'indice 3 che è 1 0 e 1. Chiaro? Cioè, quindi noi abbiamo una sequenza di indici tale per cui se concateniamo le stringhe che provengono da A secondo quegli indici otteniamo una stringa. Concateniamo le stringhe che provengono da B secondo quella sequenza di indici e otteniamo la stessa stringa. È chiaro il problema? Scusate, ma questo com'è? Scusa, s non è la concazione della s eh non c'è. Ah yeah ah thank you. Ok queste due stringhe sono uguali. Ok istanze per cui una tale soluzione non esiste perché iniziamo a a concatenarle come vogliamo, ma non arriveremo mai a ottenere due stringhe uguali. Ok? Quindi questo è un problema di decisione. Date queste due liste A e B, noi ci chiediamo è vero o no che esiste una sequenza di indici I1, I2, bla bla in N, tale per cui se concateniamo le liste provenienti da A, le stringhe proveniente da A, in quell'ordine otteniamo la stessa stringa che otterremmo se concatenassimo le stringhe provenienti da B in quell'ordine. Quindi la nostra risposta è solamente sì, no, non siamo interessati a sapere chi è. Sappiamo siamo solo interessati a sapere se c'è o meno. Ok. La lista è finita. La liste sono finite. Le liste sono finite e gli indici, la sequenza di indici deve contenere almeno un indice perché ovviamente se non avessimo la concatenazione di nulla avremo stringa vuota uguale a stringa vuota. La risposta sarebbe banale, ok? Quindi dobbiamo avere almeno un indice. Ok? Adesso secondo voi questo problema sta in R o no? Sì, ho sentito un Sì, sì. Se stai nel re ci deve essere una macchina di Turing che è in grado di risolverlo, anche non deterministica, eh, che lo accetti, che lo accetti, ok? Che sia in grado di dire sì in tempo finito. Come possiamo fare? Allora, se deterministica indovina qual è che è la sequenza. Indoviniamo una sequenza finita di indici. Concateniamo le stringhe provenienti da A, concateniamo le stringhe provenienti da B. Poiché la la sequenza di indici che è stata è finita, tutte ste operazioni si possono fare in tempo finito. Si confrontano le stringhe. Se è la stessa cosa, diciamo di sì. Ok? Questo algoritmo dà garanzia di risposta no. No, no. Quindi questo algoritmo ci dice solamente che il problema sta in R. Ok? La questione è se questo problema sia in R o meno. Dimostreremo che questo problema non sta in R, ok? Quindi potete sbattere la testa quanto volete. Un algoritmo che lo risolve non lo troverete mai. Ok? E come si fa? ci serve una riduzione. Ecco perché, insomma, ci serve un po' il concetto di riduzione. Dimostreremo che questo problema è indecidibile tramite una riduzione da Lu, quindi ci inventeremo un modo per trasformare il problema LU nel problema di stabilire se due liste di stringhe possono essere concatenate e ottenere lo stesso risultato. Ok? In particolare faremo la cosa in più passaggi, ok? Per semplificarci il compito. Come primo passaggio ridurremo il linguaggio universale a una variante del problema PCP che chiamiamo modified PCP. Poi vi spiego qual è la differenza. Dopodiché ridurremo quello a PCP. Ok? Adesso domanda per voi. Se il linguaggio universale si traduce al modified PCP e il modified PCP si riduce a PCP, è vero o no che le usi riduce a PCP? Sì, perché per la proprietà che avevamo detto su Attenzione, non l'ho menzionata esplicitamente, però Sì, è vero. Ma perché? transitività mh transitività per la transitività delle riduzioni. Ok, però anche sì quella che diceva lei, nel senso io ottengo la indecidibilità di quello intermedio e poi riapplico il teorema e ce l'ho quello. Però, sostanzialmente, se io riesco a ridurre lu a Mpcp tramite una funzione f ed Mpcp lo riduco a PCP tramite una funzione G che devono essere entrambi calcolabili, allora la composizione di G con F è una funzione che trasforma le istanze da LU verso F verso PCP. Ok? Quindi avremmo G di F. Questo è quello che otterremo. Ok. Ma ridurre LU direttamente a PCP non lo facciamo perché è troppo complicato, perché è più tricky. Sì, ci conviene avere un problema intermedio che poi trasformiamo la PCP. Lo vedremo anche in altre lezioni che per riuscire a ridurre un problema o un altro ci serve un problema intermedio, non perché non sia possibile, ma perché è difficile, cioè dovremmo stare attenti a troppe cose. Quindi prendiamo prima un problema in mezzo che è un po' più simile, un po' più simile, eh ci lo possiamo gestire un po' meglio. Quindi riduciamo L a MPCP e poi MPCP lo riduciamo a PCP. Vorrebbe un'altra domanda. Ma la riduzione tra MPCP a PCP sì eh noi la svolgiamo effettivamente come dimostrazione oppure enunciamo soltanto che poiché MPCP ha delle condizioni particolari di PCP noi presupponiamo della tesi che è comunque riducibile, no? Adesso vi enuncio MPCP e le spiego perché non possiamo fare questo tipo di discorso. Ok? Allora, MPCP è una variante di PCP in cui abbiamo la stessima cosa, le due liste, le stringhe, eccetera, bla bla. Vogliamo calcolare una sequenza di indici. Come al solito, è proprio uguale. L'unica differenza è che su MPCP questo indice qua, il primo, deve essere uno per forza. Tutto qua. Ok? Cioè la differenza fra MPCP e PCP è che le soluzioni corrette per MPCP devono avere come sequenza soluzione una sequenza che parte da uno. Tutto qua. Cioè noi siamo vogliamo che sia questa la coppia d'inizio. Possiamo quindi dire che siccome MPCP è un caso particolare di PCP otteniamo la riduzione, no? Perché potrebbe essere che MPCP, essendo un caso particolare, se è più facile. Quindi ci serve una dimostrazione formale, ok? Che alla fine non sarà molto difficile portare l'uno all'altro, dobbiamo crearci delle cose in maniera tale da forzare la soluzione. Tutto qua. Però nel momento in cui riduciamo da un problema all'altro, noi dobbiamo mostrare per ognuno dei passaggi la trasformazione. Ok? Avrei una curiosità, ma è possibile costruire eh un problema intermediario che risulta più difficile effettivamente da quello in cui vogliamo ridurci? Cioè, per esempio, avere un MPCP in realtà diventa più complicato a risolvere rispetto che PCB stesso. Sì. Il problema qual è? Il problema è che io posso sempre ridurre un problema facile o un problema difficile. La questione è che non si può ridurre un problema difficile o un problema facile. Quindi se io voglio voglio partire da L per arrivare a PCP e io passo di mezzo da un problema che è estremamente complicato, io magari riesco a ridurre LO a quello intermedio, ma poi non riesco a ridurre quell'intermedio a PCP perché quello intermedio è troppo difficile per essere ridotto lì. Lo vedremo alla prossima lezione perché al momento stiamo vedendo tutti i problemi re fuori re, forse non ve ne siete accorti ancora, hanno tutti più o meno la stessa forma. La prossima lezione ci accorgeremo che ci sono problemi sostanzialmente più sofisticati, più problematici di quelli che abbiamo visto finora. Ecco, se noi riduccessimo a questo problema molto più difficile, la riduzione verso PCP non riusciremmo a ottenerla. Ok? E quindi, cioè, è ovvio, io un problema lo posso posso complicarmelo come voglio. Ad esempio, quando vi ho fatto l'esempio della eh trasformazione del problema del campionato nel problema della colorabilità, no? Il problema della colorabilità è un problema sostanzialmente più complicato del problema del generare un campionato, perché con un algoritmo opportuno generare un campionato si fa in tempo polinomiale. Ok? Noi a quel tempo semplicemente non ce n'eravamo non c'eravamo resi conto di come si potesse fare. Tutti i nostri tentativi polinomiali fallivano. A quel punto ho detto vabboh, abbiamo un algoritmo per la colorabilità, sfruttiamo quello. Ok? Però il problema della colorabilità è un problema più arduo, cioè un problema per quale non non siamo a conoscenza di algoritmi polinomiali. Quindi io st cosa stavamo facendo? Stavo trasformando un problema che ammette soluzione polinomiale in un problema che non lo ammette. Cioè, quindi io posso sempre trasformare un problema difficile in un problema facile in uno difficile. Il problema è che se poi sto coso intermedio lo devo riportare su un problema facile, quella cosa non si fa. Quindi e dobbiamo essere noi furbi, sen noi ci perdiamo per strada. Ok, grazie. Niente. Ah, ok. Partiamo. Quindi la prima cosa che facciamo è ridurre lu a mpcpina nuova, abbiamo lu e mcp. Ok, dobbiamo fare questa riduzione. Il problema di partenza è Lu, il problema di arrivo è MCP. Queste sono sempre le domande che vi dovete porre. Qual è il problema di partenza? Qual è il problema di arrivo? Qual è un istanza del problema di partenza? Quali sono le stanze di Lu? Ve lo ricordate il linguaggio universale? No. Una coppia macchina stringa. Una coppia macchina stringa. Ok. Che sono le istanze di MPCP? L'abbiamo detto prima questo, eh, sono due liste di stringhe, ok? Quindi abbiamo A e B, ok? Quindi noi ci dobbiamo inventare come trasformare una coppia macchina stringa in due liste di stringhe. E questa trasformazione non è che deve essere a buffo, deve essere una cosa che trasforma in stanze. Sì. di LU inanze sì di MPCP e istanze no di in istanze no di MPCP. Ok? Quali sono le istanze sì di LU? Tutte quelle macchine che accettano la stringa quelle coppie macchina stringa tale per cui se la macchina processa l'oper di sì. Ok? Quali sono le stringhe s di MPCP? Le istanze Sì di MPCP. La corrispondenza. Attenzione, attenzione, sono le coppie di liste di stringhe A e B, tale per cui esiste una sequenza di indici che se prendiamo le stringhe proveniente da A e proveniente da B, costruiamo la stessa cosa. Ok? Quali sono le stanze no di LU? Quali sono le stanze noi lu? Sì, anche in cui non accetta. Non accetta W. Ma non accetta W significa che si ferma e dice di no o significa qualcosa di particolare? Risponde di no oppure non esattamente. Ok. E le stanze no sono quelle coppie MW per le quali M processando W M non dice di sì, cioè quindi o si ferma e dice di no o non si ferma mai. Ok? Le stanze no di MPCP sono le coppie di liste di stringhe tale per cui non esiste la sequenza. Ok? Allora, la questione adesso è inventarsi un modo per trasformare le istanze di MW in due liste di string. Ok? È una riduzione un po' tosta e quindi ve la dico. Cioè non è non è difficile, cioè non è non è intricata una volta che ci viene spiegata, eh, però venir fuori con l'idea non è la cosa più semplice di questo mondo. Ok? Allora, quello che noi dobbiamo ottenere è praticamente noi vogliamo far sì che tramite le stringhe delle liste A e B vogliamo simulare il comportamento della macchina M su W. Cioè questa è l'idea. Ci dobbiamo inventare quindi un modo per infilare stringhe in A e B tali per cui se la macchina M accetta W noi riusciamo a ad avere le corrispondenze, ok? A costruire una soluzione di MCP. Se la macchina non accetta W, allora noi questa ricostruzione non sappiamo essere in grado di farla. Ok? Allora, l'idea alla base della riduzione è la seguente. Vi ricordo che ogni, cioè la computazione di ogni macchina di Touring su una certa stringa, ok? Può essere può essere codificata tramite la sequenza dell instantaneous descriptions che la macchina attraversa. Ok? Cioè la sequenza delle configurazioni che la macchina attraversa sono sostanzialmente la storia del calcolo della macchina su W. Ok? E che sono queste configurazioni? Le possiamo rappresentare come stringhe. Adesso, se pezzi di configurazioni le andiamo a infilare dentro A e dentro B, siamo più o meno in grado di ricostruire la faccenda. Ok? Questa è l'idea. Allora, sostanzialmente noi avremo che una computazione di m su w sarà una stringa in cui c'è un cancelletto, la prima configurazione alfa 1, un cancelletto, poi la seconda configurazione, un cancelletto, la terza configurazione e così via, dove tra alfa 1 e alfa 2 c'è la relazione di next step della macchina. Ok, però quello che noi andremo a guardare è solamente una stringa, quindi noi andremo a infilare pezzi di questa stringa lunghissima che codifica i passi della macchina M che processa W. L' andiamo a mettere qua dentro. Ok, tutto tutto qui. Questo è il trucco. Ok, adesso però ci dobbiamo inventare delle coppie di stringhe R con I, s con i in maniera tale che il tutto torni. Ok? Quello è la parte trucchettosa della riduzione. E facciamo così. Ci sono cinque classi di coppie di stringhe R e S con I, no? che servono a permetterci di ricostruire ci permettono di ricostruire il funzionamento di m su w. Allora, l'idea sarebbe sarebbe questa che le stringhe che provengono da R e le stringhe che provengono dagli Saranno fatte tale per cui questa stringa qui, che è la stringa codificante, la sequenza di configurations che la macchina attraverse, sarà possibile ottenerla sia tramite la concatenazione degli R con I, sia tramite la concatenazione degli s con i, però la stringa proveniente da s dagli s con i sarà, tra virgolette un passo avanti rispetto alla stringa proveniente dagli arregoni. Ok? Quindi avremo una cosa di questo tipo, cioè no, alfa 1, alfa 2, alfa 3. Cioè noi ci andremo a collocare intuitivamente in un contesto nel quale agganciando le stringhe che provengono da dalla lista A e agganciando le liste che provengono dalla dalla le stringhe che provengono dalla lista B, la loro concatenazione sarà per le stringhe che provengono da B una configurazione avanti rispetto a quello che otteniamo concatenando le stringhe che ok? Quindi noi manterremo questa cosa che le stringhe che provengono da A è come se inseguissero le stringhe che provengono da B, ok? Perché saranno sempre un passo dietro, quindi questo sarà avanti, questo sarà indietro e si inseguiranno, andranno sempre avanti assieme e le stringhe proveniendo da A, provenienti da A, potranno raggiungere quelle proveniente da B solamente se la macchina entra in uno stato accettato. Ok? Chiara l'intuizione? Questo è quello che vogliamo ottenere, però ora dobbiamo vedere il dettaglio. Ok? Allora, op. Prima classe di stringhe. Abbiamo detto che noi vogliamo ottenere che le stringhe che provengono da B siano un passo avanti rispetto alle stringhe che provengono da A. Ok? Allora, la stringa R1 e la stringa S1. Allora, qui metterò sempre ciò che mi proviene da A e qui quello che proviene da B. Ok? Allora, R1 sarà fatta così. Cancelletto. Mentre S1 sarà fatta così. Cancelletto Q0, dove Q0 è lo stato iniziale della macchina M. e poi la stringa W con tutti i suoi simboli. Ok? Chiaro che facciamo? Quindi la prima coppia delle liste EB c'ha sta forma particolare R1 c'è il cancelletto. RS1 ha cancelletto0 alla configurazione iniziale di M. Praticamente cancelletto configurazione iniziale cancelletto. Ok? E siccome un'istanza di MPCP e ogni soluzione candidata dovrà partire da questa coppia di di stringhe, nel momento in cui iniziamo ad agganciare noi avremo già che la stringa proveniente dalla lista A è un passo dietro alla stringa proveniente dalla lista B. Ok? Ok. Quindi questa è la prima classe. Poi vi faccio vedere un esempio specifico. La prima classe di stringhe, seconda classe di stringhe, abbiamo la stringa X, la stringa X e la stringa X, dove X è un qualsiasi simbolo per ogni x appartenente a gamma. Quindi X è un qualsiasi simbolo di nastro. Quindi avremo che la seconda classe di string che ne so R2 S2 R3 S3 ne avremo una per ogni possibile simbolo che può apparire sul nastro e poi c'abbiamo un'altra che è cancelletto. Cancelletto. Ok? A che ci serve questa roba? Ve lo vedremo nell'esempio che poi vi faccio vedere. ci serve a poter estendere, quindi stiamo partendo con A che c'ha solo cancelletto. Le stringhe provenenti da B c'hanno cancelletto, stato, simboli, cancelletto. Per estendere A ed inseguire B, noi avremo che in A possiamo inserire simboli per ricopiare le cose. Ok? Questo è il senso. E questa è la seconda classe di simboli di di stringa. Ok? Terza classeamo. Ma non è che stai facendo in questo momento? Sto trasformando, sto costruendo un'istanza di MPCP partendo da un'istanza di M da partendo da Mw da un'istanza di Lu. Quindi io sto partendo da MU, sto definendo la funzione f sostanzialmente, quindi input fent m w. Ok. F inizia a girare. Tratatan tratatan, tratatan. Allora, che fa? Inizia a tirare fuori ste coppie. La prima coppia che tira fuori è cancelletto. Cancelletto Q0 W cancelletto. Cioè da dove la prende w? Dall'input ha ricevuto input, M è W. Quindi la prima cosa che sputa fuori è sta coppia cancelletto cancelletto Q0 W cancelletto. Ok, può farlo? Così sta solo sputando fuori singoli. Poi che cos'altro ci appiccica ad A e B la funzione F? Quello coppie 00 1 1. Cancelletto cancelletto. Può farlo sì. Sta generando quindi le liste A e B per il trasformato di F. Non mi è chiaro a cosa serve il passaggio? Cioè perché devono essere di pari lunghezza? Le le sarà più chiaro quando faccio un esempio. Ok. Perché capisco che è un po' complicato da togliere. Poi lo vediamo e cerchiamo di capire. Ok, la pausa sarà cortissima oggi questo orario. Ok, terza classe di di coppie. Dobbiamo codificare sostanzialmente nelle stringhe proven a e b la funzione di transizione di della macchina M. Ok? Allora, facciamo così. Su A mettiamo la stringa QX dove X è un simbolo proveniente da gamma e su B abbiamo la stringa YP. Per ogni regola del tipo che sono nello stato Q, leggo X, transisco in P, scrivo Y e vado a destra. Ok? Quindi, se nella macchina M, che è la funzione f prende in input, ok? Vede una cosa del genere nella funzione di transizione, la funzione f sputa questa coppia di string. Ok? Questo ci serve che cosa? A simulare che se sono nello stato Q e sto leggendo X, al passo successivo, al posto di X ci sarà Y sarà avanzato e diventato P. Ok, then altro ZQX + ZY, dove z X y sono di nuovo simboli che appartengono a gamma, ok? e li infiliamo là. Se esiste una regola del tipo sono in Q, leggo X, transisco in P, scrivo Y e vado dietro. Ok? Perché? Perché se questo è un pezzo delligurazione che significa? sono in Q e sto leggendo X perché X appare alla sua destra. Nella configurazione successiva al posto di X noi avremo Yato Q che è indietreggia di un posto si troverà alla destra di Z perché Z stava alla sinistra della testina. Ok? avanti. Poi dobbiamo gestirci il caso nel caso in cui ovviamente Ah, ok, c'è un'assunzione che va fatta in unetto. Noi stiamo assumendo che m è una macchina particolare, è una macchina che non scrive mai il bianco e questo è un'assunzione, ok? perché possiamo sostituire il bianco con un altro simbolo. Una peculiarità di M è che M ha un nastro semiinfinito, cioè non sposta mai la sua testina alla sinistra della posizione iniziale. Questo si può assumere senza perdita di generalità. C'è un teorema sul vostro libro che mostra che qualsiasi macchina di Touring può essere trasformata in questa variante. Ok? Perché usiamo questo constraint sulle macchine? Perché fare la riduzione così ci viene più semplice? Ok. Alright. Quindi abbiamo dobbiamo gestirci un caso in cui lo stato Q sia leggendo l'ultimo blank. Quindi abbiamo Q SAR e poi abbiamo YP SAR. Nel momento in cui c'è una transizione in cui sono in Q, leggo blank, vado in P, scrivo Y e mi muovo avanti. E l'altra è ZQ che diventa pzy sharp. Se sono in Q leggo blank, transisco in in P, scrivo Y e vado dietro. Ok, queste ovviamente vanno tutte generate, adesso lo vediamo un esempio specifico, vanno tutte generate per tutti i possibili le possibili triple di simboli zx y che appartengono al gamma che rispettino quelle condizioni. Ok, questa era la terza classe di coppie di stringhe. Avanti, quarta, quarta classe. La terza coppia di string, cioè la terza classe di stringhe, viene definita per una Q che è uno stato non terminale. Ok? Q non è uno stato qualsiasi, è solo uno stato non terminale. Lo scriviamo qua. Q appartiene a Q - F. Ok, quarta coppia, quarta categoria di coppie di stringhe. Allora, tutte queste cose che abbiamo visto finora permetteranno di estendere la stringhe proveniente da A e le stringhe provenienti da B con la computazione di M. Poi facciamo un esempio, vi faccio vedere come cosa succede. Però tutto ciò farà sì che le stringhe che provengono da B saranno sempre un passo avanti rispetto alle stringhe che provengono da A. Noi gli dobbiamo dare la possibilità alle stringhe che provengono da A di raggiungere le stringhe provenienti da B nel momento in cui la macchina transisce in uno stato accettante. Quindi la quarta classe di coppie di stringhe faranno sì che le stringhe provenenti da A possono accelerare un po'. Ok? E allora per gli stati Q appartenenti agli stati finali definiamo XQY QY Q. Ok? dove Q è un qualsiasi stato finale, X e Y sono simboli provenienti da sono simboli provenienti da gamma. Ok? Quinta e ultima classe di regole. Capisco che è intricato, le riduzioni sono così alle volte. Adesso vediamo un esempio per renderci conto di come funziona sta cosa. Ok? Quinta classe di string abbiamo Q sharp sharp su B dove Q appartiene agli stati finali. Ok? Chiaro? Cioè che cosa cosa fa sta funzione di trasformazione f? Prende input la coppia MW e inizia a sputare fuori in output liste A e B. dove ci stanno coppie di stringhe che seguono queste regole. Ok? Adesso possono sembrare completamente senza senso, ma quello che vedremo ora è che una trasformazione si fatta permette di ottenere appunto la riduzione, cioè noi saremo in grado di generare un'istanza di MPCP che è un'istanza soscina M accetta W. Ok? Alri, supponiamo Q2, Q3. Ok? Supponiamo quindi di avere una coppia MW da dare input alla funzione f. Adesso disegniamo cos'è questa M, diciamo cos'è w e vediamo che cosa esce fuori per su dal termine della trasformazione. Ok? La macchina M è fatta di una cosa di questo tipo. Vediamo un po'. Ok, Q1 è lo stato iniziale. Sono in Q1, se leggo 1 scrivo 0 torno indietro. Se leggo zero, scrivo 1, vado avanti. Poi sono in Q2, leggo 1, scrivo 0 e vado avanti. Sono in Q1, leggo blank, scrivo 1 e torno dietro. in Q2 scrivo leggo blank, scrivo 0 e vado avanti e poi c'è questa transizione 00 0 e torno dietro. Ok? Supponiamo che quindi m sia questa cosa qua. Questo è m, ok? E w è 01. Ok? Quindi abbiamo questa coppia MW che viene data impasto alla funzione F di riduzione. La funzione f riduzione legge la funzione di transizione di M che gli viene data input come con la codifica delle macchine che abbiamo visto quella volta. Ok? Riceve quindi la codifica di M, riceve w input e deve sputare fuori in output questa cosa qua. Ok? Deve sputare in output le liste A e B. Allora, la computazione, vediamo prima assieme la computazione di questa macchina sulla stringa 01, ok? Q101. Come funzionerebbe? Allora, siamo in Q1, leggiamo 0, ok? Quindi si attiva questa questo branch qua, ok? Siamo in Q1, leggiamo 0, che facciamo? Scriviamo 1 sullo 0, da Q1 transiamo in Q2 e ci spostiamo a destra. Quindi da questa configurazione otteniamo quest'altra configurazione. È chiaro? Questa è tutta roba vecchia. Ok. Poi siamo in Q2, leggiamo 1. Quindi siamo qui su questo ramo qua, siamo in Q2, leggiamo 1, scriviamo 0 e andiamo ancora a destra. Quindi ci sposteremo in ci spostiamo a destra, quindi Q2 avanza verso destra e transiamo verso Q1. Quindi questo sarebbe la il resto della configurazione. Ok? Quindi adesso siamo in Q1 e leggiamo blank. Siamo in Qo. Leggiamo blank. Scriviamo 1, torniamo indietro e transiamo verso Q2. Di conseguenza abbiamo 1 Q2 Ok? Sto solo simulando il funzionamento di questa macchina di Touring su questa stringa. Ok. Ultimo passaggio, siamo in Q2, leggiamo scriviamo 0 e ci spostiamo verso destra e andiamo verso Q3. E allora che cosa avviene? Q3 10 1. Chiaro? Questo è il funzionamento di questa macchina su W. Adesso quello che noi vogliamo vedere è che la simulazione che otteniamo che otteniamo tramite la riduzione che abbiamo proposto prima va a replicare esattamente il funzionamento di questa macchina. Ok? Quindi noi partiamo da quella macchina, dobbiamo produrre le liste A e B. Ok? Allora, che abbiamo? Mettiamo B. Qua abbiamo che la prima coppia cos'è? È cancelletto su A, cancelletto Q101 cancelletto. Ok? Questa è la è la prima classe di coppie, ok? Poi la seconda classe di coppie era sui simboli. Supponiamo che l'alfabeto di nastro sia 01. Quindi abbiamo 0 0 1 bianco bianco. Ok, cancelletto cancelletto e chiudiamo. Questa è la seconda classe di stringhe. La terza classe di stringhe è noi dobbiamo andare a codificare eh allora che abbiamo usato questa qua. Ok, codifichiamo quelle che ci serve. Se andiamo a guardare le appunti che avevamo preso, quindi abbiamo che per ogni stato non terminale, quindi Q1 Q2, dobbiamo fare questa cosa qui. Q1, il possibile simbolo che leggiamo è 0, quindi è q 0. Questa cosa che cosa diventa? Scriviamo 1 e transiamo in Q2. Quindi l'altra stinga è 1 Q2. Poi quello da dove viene? Sì, siamo in Q1, leggiamo 1, scriviamo 0, sì. E andiamo a sinistra. Quindi adesso traduco questa qua. Sono 0, quindi 0 q1. Questo di Q2 oppure Q1 Q1 1. Questo di Q2. Sto semplicemente applicando quelle regole lì, eh, perché abbiamo Q1 Q1 legge Q1, ok? Che sarebbe questo Q1 legge 1, sul quale ci scrive 0 e qui abbiamo che questi uni qua diventano 0 qua. Dopodiché noi prima di Q1 potremmo avere o 0 o 1 e lo dobbiamo replicare. Quindi sarebbe questo e quest'altro. Ok, eccetera eccetera eccetera. Qual è l'altro prezzo? Ok, poi ce ne saranno altri, non ve le faccio vedere tutte, però vediamo un po'. Abbiamo codificato quello che ci serve. Sì, eccola qua. Allora, supponiamo quindi che vogliamo costruire da A e B la stringa ottenuta dalle concatenazioni. Abbiamo detto che noi partiamo sempre dalla prima coppia, questa qui. E quindi che cosa abbiamo? Diamo cancelletto qua e cancelletto Q1 cancelletto. Ok? Adesso notate questa cosa qua. Le stringhe. Vi do l'intuizione perché poi farla tutta poca, eh, e visto che si è fatto abbastanza tardi, le stringhe che provengono da B, come vedete qui, sono un passo avanti rispetto alla stringa proveniente da A, cioè qui c'è la prima configurazione, mentre qua non ci sta niente. Ok? Concentriamoci su questo pezzo qua in cui ci dice che noi siamo nello stato Q1, stiamo leggendo zero. Ok? Guardate qua, c'è questa coppia Q10, scrivo 1, vado in Q2 che è la codifica coppie di cosa? di questo ramo qua. Di conseguenza questa stringa qui e questa stringa qui la posso estendere con questa coppia qua. Ok? Quindi io prendo questa coppia qui, Q10, lo infilo qua, quindi avrò Q10. E guardate che qui stiamo avendo un matching dei simboli, mentre sulla stringa che proviene da B devoirci questa. Quindi su B si inizierà a costruire che cosa? l'inizio della seconda configurazione. Quindi guardate qua, avevamo che all'inizio questo pezzo che era un passo avanti rispetto a questo qua. Nel momento in cui tento di matcare questi simboli con questi qua, sono costretto a prendere una coppia di stringhe proveniente da A e proveniente da B, tale per cui la stringa proveniente da A mi questo pezzo qui, però sono costretto a prendere da B delle stringhe che stanno simulando quale sarà la prossima configurazione. Di conseguenza, qui sto, iniz, mentre qui sto scrivendo a poco a poco alfa 1, qua sto già iniziando a scrivere alfa 2. Secondo cosa? secondo la funzione di transizione della macchina, perché queste coppie qua sono scritte secondo le possibili transizioni che la macchina può effettuare. Di conseguenza, a B, cioè la stringa provenente da B, ci appiccicherò pezzi che stanno simulando il next step della macchina. Ad esempio, una volta che c'ho questo, posso prendere queste coppie qua, tipo questa qui e avrò 1 1. Poi posso prendere questa, avrò cancelletto. Cancelletto. E come potete vedere avremo che dopo aver agganciato questi pezzi di stringhe, la stringa proveniente da A ha ha la prima configurazione, mentre la stringa proveniente da B c'ha già due configurazioni. Andiamo a prendere quest'altro. Eh no, quella è su Q1, mi serve quella su Q2. Vediamo dov'è. Ok, scrive zero e va avanti. Questo qua. Questa qui, ad esempio, dov'è? Dov'è? Dov'è? legge 1, scrive zero e va avanti. Questo qua. Codifichiamo questo pezzo qua. Avremo qui una cosa di questo tipo. Tra le altre eh avremo Q2 1 e qua avremo 0 Q1. Ok? Fra ce ne sono varie qui, eh, ce ne sono tante, non è solo questo. Quindi questo pezzo qua Q2 1 e 0 Q1 proviene dalla trasformazione di questa pezzo di funzione di transizione. Quindi, che cosa avrò qua? Qui inizia con uno. Allora, per estendere A con lo stesso simbolo che sta da quelli di B, devo usare questa qui, ad esempio, 1 e quindi c'avrò uno qua e uno qua. Da dove mi proviene? Mi proviene dalla scelta di questa coppia. Poi devo estendere qui con dei simboli che sono uguali a questi. Vado a pescarmeli. Chi sono? Questi qua? E se io mi prendo loro, io mi devo anche prendere questo pezzo qui. Quindi avrò Q2 qui, ma 0 Q1 qua, perché proviene da questo pezzo di B, no? Poi prendo un cancelletto e un altro cancelletto e di nuovo avrò che la lista, cioè la stringa provenente dalla lista A, mi avrà codificato alfa 1 e alfa 2, mentre su B avrò alfa 1, alfa 2 e alfa La questione è che l'organizzazione delle stringhe su A e B è fatta ad arte in maniera tale da procur da codificare i passi che la che la macchina di Touring fa da una configurazione all'altra. Ok? Non è che nella riduzione costruiamo pezzi di coppie, no, così a caso, no? mettiamo le coppie di stringhe che permettono nella ricostruzione delle stringhe provenienti da A e B, permettono di simulare il funzionamento di questa macchina, ok? Cioè i pezzi delle coppie di stringhe che stanno in A e che stanno in B stanno descrivendo cosa c'è nella configurazione alfa con i e che cosa deve avvenire nella configurazione alfa i + 1. Questa cosa va avanti avanti fino a quando raggiungeremo poi la una configurazione finale tale per cui possiamo utilizzare queste regole che, come vedete, sono più lunghe le stringhe provenenti da A che le lunghe che le stringhe provenenti da B, tale per cui a quel punto la stringa proveniente dalla lista A potrà raggiungere la stringa proveniente dalla lista B. Chiara l'intuizione? più o meno. Ok? L'intuizione è nelle stringhe delle liste A e B noi dobbiamo andare a mettere tutte le ipotetiche computazioni che la macchina M potrebbe fare sul W. Guardate che noi nelle nelle stringhe della lista A e della lista B non stiamo codificando la computazione di M su w perché altrimenti dovremmo simularla e se simulassimo m su w questa simulazione potrebbe non terminare mai. Nelle stringhe della lista A e della lista B stiamo mettendo pezzi di possibili computazioni prese da dove? dalla funzione di transizione. Diceva nel caso in cui, per esempio, questo qua che dice? Nel caso in cui Q fossimo in Q2 e leggessimo 1, allora dovremmo scrivere 0 transiring 1 e andare avanti. Cioè queste coppie di stringhe codificano la funzione di transizione, non la computazione in sé. Cioè, non è che simuliamo M su W e poi costruiamo, no? Dentro A e B mettiamo tutti i casi che potrebbero accadere, però casi sensati, cioè cose che devono rispecchiare il funzionamento della macchina. Sì. Quindi, allora, nella prima classe, diciamo, è la forma di come avviene questa transizione. Sì. La seconda classe sono i simboli che si possono incontrare da una parte all'altra. La terza e la quarta sono eh La terza è la funzione di transizione e la quarta E la quarta è se entro in uno stato finale devo dare la possibilità alle stringhe di A di essere più lunghe delle stringhe di B in maniera tale da allungare la stringa proveniente da A di più di quanto si allunga la stringa proveniente da B e possono cacciare se la può raggiungere. Ma sia terza e quarta sono tutte le possibili mosse che possono essere svolte mediante la macchina. La terza sono tutte le possibili mosse che possono essere svolte dalla macchina. La quarta è sono regole inventate apposta. È come se la macchina cancellasse pezzi di input. In realtà non fa quello. Sono regole inventate apposta per permettere alle stringhe provenienti dalla lista A di raggiungere le stringhe provenenti dalla lista B perché so più lunghe, sono sempre state avanti. E la quinta invece? La quinta è la cosa di chiusura, perché praticamente che cosa succede? Se noi continuassimo a simulare qui, noi avremmo altri pezzi di stringhe qua e qua, fino a quando arriveremo a un punto in cui avremmo cancelletto Q3, cancelletto cancelletto e qui cancelletto Q3, cancelletto cancelletto. La quinta serve a chiudere il pattern. Tutto qua. Nulla. Allora, la cosa che è importante sottolineare è questa. La funzione f è una funzione che deve essere calcolabile, cioè è una funzione che ricevuto il suo input sputa l'output in tempo finito e lo sputa sempre, non è che si incastra da qualche parte e non ci dice no. Quindi la funzione fasforma la coppia Mw in due liste di stringhe A e B non è che può simulare M su w perché se inizia a simulare m su w e M non si arresta mai, la trasformazione non finirebbe mai. Quello che fa la funzione di riduzione è che prende la funzione di di transizione di f e la codifica in queste coppie di possibili computazioni che sono il numero finito. Sono i possibili passi che la macchina potrebbe mai fare. È quello il senso. Ok? E questo si può fare in tempo finito. È chiara l'intuizione? Poi se leggete sul vostro libro ci stanno tutti i dettagli, ve lo spiega anche un altro modo. Ok? Alrght ora dimostrare che questa è una riduzione da L a MPCP. Ok? Dobbiamo adesso dimostrare questa cosa qua. Ok. Perché fino a mo abbiamo dato una sola trasformazione. Quello che ora dobbiamo dimostrare è che questa trasformazione in effetti trasforma istanze sì di LU in istanze sì di MPCP e istanze no di LU in istanze no di MPCP. Primo pezzo della dimostrazione, dobbiamo dimostrare che se partiamo da un'istanza s di Lu, allora il trasformato della coppia MW è una coppia di liste di stringhe AB tale per cui ammetto una soluzione secondo MPCP. Ok? La dimostrazione sta sostanzialmente nella costruzione. La costruzione che abbiamo mostrato è una costruzione che permette di simulare il funzionamento della macchina M su W tramite la concatenazione di stringhe che descrivono le configurazioni che la macchina attraversa di passo in passo. Ok? Se la macchina M accetta W, ok? La la stringa, la sequenza di indici che possiamo costruire per la soluzione di MPCP ovviamente parte della prima coppia in cui abbiamo h * A e poi HQ0 WH e quindi partiamo da quella. Dopodiché abbiamo regole di questa classe qua che ci permettono di ricopiare i pezzi della configurazione distanti dalla testina. Mentre queste regole qua, queste coppie qui ci permettono di allungare le stringhe per le porzioni di configurazioni che stanno nell'intorno della testina e quindi di simulare il comportamento della macchina. Quindi, se m accetta w noi saremo in grado di concatenare pezzi di stringhe fino ad arrivare al momento in cui in queste configurazioni apparirà lo stato finale. Se appare lo stato finale, noi potremo poi andare a usare coppie di questo tipo, nel quale le coppie di A sono più lunghe, cioè la stringa della lista A è più lunga delle stringhe proveniente dalla lista B e permettiamo alla stringa proveniente da A di raggiungere la stringa proveniente dalla lista B, fino a quando, come ultima coppia, possiamo usare questa qui che ci permette di matchare le due stringhe, ok? Perché? Perché la la macchina M m mentre processo la W arriverà a un certo momento in uno stato accettabile. È chiaro? Quindi M processa W. Noi possiamo appiccicare, impivare le stringhe provenienti da A e proveniente da B secondo la computazione di MV fino a quando M arrivi a uno stato accettante. Dopodiché le classi di coppie 4 e 5 ci permetteranno di avere le stringhe che provengono da A, di raggiungere le stringhe che provengono da B. Tutto qua. Ok? Quindi con questo dimostriamo che se partiamo da un'istanza C di LU stiamo costruendo il trasformato della coppia MW e un'istanza s del problema MPCP. Ok? Altro verso della riduzione della della prova. Ok? Supponiamo che la riduzione ci abbia costruito un'istanza sì di MPCP. Dobbiamo adesso dimostrare che stavamo partendo da un'istanza Sì di Lu. Allora, se siamo arrivati a un'istanza sì di MPCP, l'istanza sì che abbiamo costruito non è che è un'istanza a caso, è un'istanza che ha questa forma. Ok? Quindi una possibile soluzione dovrà partire per forza con questa coppia di stringhe che inizierà a far partire la simulazione della macchina sulla stringa input. Adesso, poiché le coppie di stringhe ce le siamo inventate apposta per simulare il funzionamento della macchina, se riusciamo a costruire delle stringhe che quando si estendono arrivano a costruire la stessa cosa è perché a un certo punto avremmo utilizzato coppie della classe 4 e 5. Di conseguenza, nella simulazione della macchina, sta macchina deve arrivare a un certo punto ad accettare nello stato accettante da cui l'istanza di partenza di LU da cui partivamo era un'istanza semplice. È chiaro? Questo dimostra, capisco che è tosta, eh? Questo serve un po' di tempo, poi dovete riguardarvela, soprattutto sul libro perché vi dà ulteriori dettagli e serve tempo per capire. Ok? Questa cosa cosa dimostra? Dimostra che dimostra che ci ho messo molto più tempo del del previsto e quindi il secondo problema non so come lo facendere. Ok? In caso spostiamo la prossima lezione. Allora, che cosa dimostra? dimostra che nu si riduce a MPCP da cui MPCP non è un problema ricorsivo, non è un problema di R. Sì, prego. Scusi, quindi la dimostrazione noi la facciamo solo per, diciamo, i casi positivi, no? Per i casi positivi. Ok. Perché, cioè da da un lato e dall'altro con i positivi, sì, i negativi ancora non abbiamo fatto. Eh, attenzione, nel momento in cui nel momento in cui abbiamo dimostrato, è una questione di equivalenza logica, no? Se abbiamo dimostrato che la funzione ha generato un'istanza sì perché stava partendo da unistanza sì, questo è logicamente equivalente a dimostrare che se partiamo da no produciamo no. Ok? È una questione di riscrittura dell'implicazione logica. Se lei prende a eh no, x implica y che è uguale al not y, questa cosa la può riscrivere come not y implica not, cioè lei prende il converso, ci mette il not davanti è la stessa cosa. Ok? L'importante è che venga fatta in tutti e due i versi. Ok? Adesso la cosa interessante da notare qual è? è che noi abbiamo dimostrato l'indecedibilità di MPCP senza fare dimostrazioni strane dell'inesistenza di macchine eccetera. Abbiamo preso un problema indecidibile che è nuato che le sue istanze sì possono essere mappate su istanze sì del problema PCP e che le istanze no del problema L possono essere mappate su istanze no di L di di MPCP. Da per questa ragione siccome MPCP mostra una struttura simile a LU deve essere per forza indecidibile, altrimenti potremmo risolvere LU tramite un risolutore di MPCP. Ok? Quindi cosa ci dice questo? Che MPCP è in R, perché l'abbiamo visto prima, basta cheare una soluzione, però non sta in R, cioè non avremo mai un algoritmo che in tempo finito è in grado di dirci no, questa istanza non ha una soluzione. Chiaro? M ok, ci manca un pezzo. No, è inutile farlo di corsa. Facciamo un po' di pausa e il secondo problema lo vediamo la prossima volta. Allora, facciamo un dai 5 minuti di pausa e cecchiamo. Ok. Allora, cosa abbiamo visto nella prima metà della lezione? Un po' più di metà, diciamo, abbiamo visto che il problema LU si riduce a MPCP. Ok, la riduzione intricata, lo so benissimo questa altre saranno intricate. Il teorema di Cook sarà una cosa impossibile che è veramente enorme. Cioè, ci sono alcune dimostrazioni che sono veramente toste. Questa è una di quelle, ok? Ma non perché una volta che capite il principio che ci sta dietro, non è che è intrigata, è lunga. Questa è la cosa. Si deve capire che dietro ci sta il principio che io estendo, cioè mi costruisco le coppie di stringhe sulla lista A e sulla lista B, in maniera tale da far sì che quando vado ad appiccicare pezzi di stringhe sono costretto a simulare il funzionamento di m su w. Quella è la è la ragione che ci sta dietro. Tutto qua. Ok? Poi è lunga perché è fatta di tanti pezzi. Questa è la cosa, cioè non è difficile di per sé. Ok? Quindi prima cosa abbiamo visto? Abbiamo visto che LU si riduce a MPCP, però MPCP non è il problema iniziale, ok? Perché MPCP? A che ci serviva la riduzione da LU a MPCP? Perché MPCP imponendo che la soluzione deve partire dalla coppia di indice 1 impone che dobbiamo costruire quando iniziamo a costruire le stringhe siamo ci viene imposto che iniziamo a simulare m su w. Quello è sostanzialmente il trucco, ok? Però la riduzione ci dimostra quindi che MPCP è indecidibile. Come facciamo a dimostrare che PCP è indecidibile? Lo facciamo facendo un'altra riduzione da MPCP a PCP. Ok? Dobbiamo fare questa seconda riduzione e siccome MPCP l'abbiamo appena dimostrato indecidibile, anche PCP sarà indecidibile. Ok? Che cos'è un'istanza per MPCP? una coppia. Una coppia di cos'è unistanza per PCP? Un'altra coppia di list. Ok? Quindi dobbiamo inventarci una trasformazione fra le coppie di liste A e B in coppie di liste C e D tale per cui A e B è un'istanza s di MPCP. Se è solo se CD è un'istanza sì di PCP. Ok? Vi ricordo che l'unica differenza è che le soluzioni per MPCP richiedono che la soluzione parta dalla coppia all'indice 1, mentre per PCP questo vincolo non è richiesto. Qualsiasi sequenza di indici va benissimo. Ok? Allora, la riduzione è questa. Ve lo faccio su un esempio specifico e così ve la faccio capire. Ok? Supponiamo di avere la stessa lista che abbiamo visto all'inizio, ok? Come esempio 1 1 1 poi abbiamo 1 e qui c'era uno 0 e poi ci sta 1 0 e 0. Ok? Da questa dobbiamo ottenere CD. Ok? Quindi che fa questa coppia? Questa funzione di transizione? Prende la coppia di liste A e B con le sue stringhe al suo interno. Ok? Sputa fuori due liste di stringhe che chiamiamo C e D solamente per distinguerla in cui le coppie di stringhe che fanno parte di C e D provengono dalle coppie di stringhe che che stavano in A e B. Quindi prendiamo quelle, le modifichiamo un pochettino in maniera tale da ottenere la riduzione e funziona così. Per ognuna delle stringhe provenienti da A, mettiamo una stringa in C in cui ogni simbolo della stringa di partenza viene seguito da un asterisco. Che significa, per esempio, supponiamo di star trasformando questa, quindi qui avremo asterisco. Supponiamo di trasformare la seconda, quindi avremo 1 asterisco, 0 asterisco, 1 asterisco, 1 asterisco, 1 asterisco. Ok? Cioè l'asterisco è un nuovo simbolo che aggiungiamo. Quando prendiamo le stringhe proveniente da A, le prendiamo e le ricopiamo in questo modo. Prendiamo il un simbolo e ci appiccichiamo asterisco, un altro simbolo, ci mettiamo un asterisco. Ok? Facciamo sempre così. Questa qua diventa 1 asterisco 0 asterisco. Ok? Chiaro? Molto semplice. Le le stringhe proveniente da B vengono trasformate in stringhe di D in un modo simile nel quale l'asterisco, invece di seguire il simbolo lo precede. Quindi avremo asterisco 1, asterisco 1, asterisco 1, poi qui avremo asterisco 1, asterisco 0 e poi avremo asterisco 0. Ok? Cioè, facciamo sto trucchetto. Prendiamo le stringhe da A e mettiamo dopo i simboli un asterisco. Prendiamo le stringhe da B e mettiamo prima dei simboli un asterisco. Ok? Come potete vedere al allo stato attuale della trasformazione la l'istanza CD non ammetterà mai una soluzione perché tutte le stringhe della lista C partono con un simbolo diverso dalle stringhe della lista D. Ok? Quindi la riduzione non è ancora finita, dobbiamo aggiungerci dei pezzi. Allora, il pezzo aggiuntivo è che in C prendiamo questa stringa qui che era quella proveniente dalla prima coppia e ne facciamo un'altra copia fatta così. Mettiamo un asterisco all'inizio e poi la ricopriamo. Uno asterisco. Ok? per D. Invece questa qua è semplicemente questa ricopiata, quindi avremo asterisco 1, asterisco 1, asterisco 1. Ok? Vi faccio notare ancora che così come è fatta l'istanza CD ancora non ammette soluzione perché la stringa che noi siamo in grado di costruire partendo dalla lista C termina con un asterisco, mentre le stringhe che la stringa proveniente dalla concatenazione di stringhe della lista D termina con un simbolo diverso dall'asterisco. Ok? Quindi questa ancora è un'istanza no. Ci dobbiamo aggiungere un pezzello. Mettiamo il simbolo dollaro come ultima stringa e il simbolo asterisco dollaro a come ultima stringa. Ok? Chiaro? Quindi la trasformazione che fa? Questo deve essere chiaro, eh? La trasformazione non è che si occupa di stabilire se l'istanza AB è un'istanza sì. Perché non possiamo farlo? Perché il problema MPCP è un problema indecidibile. Quindi se noi volessimo mai, fin da principio stabilire se l'istanza che abbiamo che stiamo trasformando è un'istanza sì per poter sputare in output un'istanza sì, questa cosa non la si può fare in tempo garantito essere finito perché il problema MPCP sappiamo non essere ricorsivo. Quindi la funzione che trasforma le liste A e B in liste C e D non si dovrà mai chiedere se la liste A B ammettono una soluzione. Deve prenderle e trasformarle senza porsi la questione. Ok? Deve però ovviamente fare una trasformazione che mantenga la risposta, cioè deve fare una trasformazione che per sua struttura, senza sapere se stiamo partendo da un istanza, sì. istanza, no. Le stanze sì le trasforma in istanze sì di PCP e le stanze no di MPCP le trasforma in istanze no di PCP. È chiaro? Quindi questa è la parte fondamentale. La parte fondamentale è che la funzione che fa la riduzione non può sapere se l'istanza di partenza è sì o no, perché per saperlo dovrebbe tentare di risolvere un problema indecidibile, ma la funzione di trasformazione deve essere una funzione calcolabile, ok? cioè che la sua risposta la deve dare in tempo finito. Quindi f non potrà mai tentare di risolvere l'istanza di partenza, ok? Deve fare una trasformazione di struttura. E per questo insieme specifico, per questo problema specifico lo fa in questo modo. Prende le stringhe di A per produrre le stringhe di C. Come fa? le prendi a uno a uno e ci metti un asterisco dopo ogni simbolo. Dopodiché aggiunge una stringa all'inizio, quella di indice zero, per esempio. Supponiamo che questo è indice 0 1 2 3 4 Ok? Aggiunge una stringa di indice 0 che è uguale alla stringa di indice 1 più un asterisco all'inizio. Ok? Dopodiché, come ultima stringa, mette dollaro, che è un altro simbolo che non faceva parte dell'alfabeto. Come ottiene le stringhe di D? Va a guardare le stringhe di B e che fa? Le ricopia mettendo un asterisco di fronte prima di ogni singolo. Ok? Poi la stringa di indice 0 è uguale alla stringa di indice 1 e poi l'ultima stringa di D è asterisco dollaro. Ok? Tutto qua. Sì. Quello che abbiamo fatto per la stringa 1 possiamo farlo per qualsiasi, cioè per la coppia di stringa 1 possiamo farlo per qualsiasi. Lo potremmo fare in linea di principio per quello che vogliamo. Lo facciamo per la prima stringa perché ci serve, ora lo vedremo. Ci serve perché noi dobbiamo imporre che le soluzioni che il solver di PCP propone parta sempre dalla prima coppia perché MPCP vuole una soluzione che parta dalla prima coppia. Ecco perché la facciamo su quella e non sull'altra. Chiaro? Perché il principio che ci sta dietro è sempre io trasformo le istanze di una di un problema in istanze di un altro problema per usare il solver dell'altro problema. Ok? Siccome il solver di PCP quando gli diamo l'istanza a lui di partire dalla prima coppia non gliene importa niente per forzarlo a darci una soluzione che parta dalla prima coppia io me le costruisco ad arte. Questo è è il senso. Ok. Sì, però se M PCP, cioè l'unica differenza che deve partire dalla prima coppia e noi forziamo TCP a partire dalla nostra non il suo senso. M no, la questione è che quando noi domanda molto interessante, cioè quando noi prendiamo le istanze di un problema e le trasformiamo in istanze di un altro problema, ok? Non è che noi stiamo coprendo. E faccio un esempio. C'abbiamo tempo più o meno. Allora, sì, no. Sì, no. Allora, queste sono è il dominio delle istanze del problema di partenza e questo è il dominio delle stanze del problema di arrivo, ok? Che sono divise in s e. Ok? Vi ricordo che c'è un'istanza è di per sé sì, no? Non è che un'istanza è indeterminata. La questione è una macchina è in grado di stabilire si no. Ok? Quindi noi possiamo prendere l'insieme delle stringhe e lo partizioniamo in due. Da un lato ci stanno le s, dall'altro ci stanno le no. Ok? Allora, cosa fa la funzione di trasformazione? La funzione di riduzione La funzione di riduzione praticamente prende una qualsiasi stringa da qui e la trasforma in un set non necessariamente esaustivo di istanze sie del problema di arrivo. Poi prende le istanze, una qualsiasi stanza, no, e la trasforma in un set non necessariamente esaustivo di istanze, no, dell'altro problema perché F non è che sputa fuori una qualsiasi stanza no, o una qualsiasi stanza sì del problema di arrivo, no, le fa secondo una certa logica. per esempio in PCP che abbiamo visto prima, cioè prende la macchina la l'insieme di stringhe che produce la trasformazione dell'EPCP produce un'istanza di MPCP che è molto specifica a quella forma. Poi ce ne stanno una marea di altre stanze di MPCP. Ok? Quindi quello che noi facciamo prendere tutte le stanze del problema di partenza e in linea di principio trasformarle in una sottoclasse, un sottoinsieme di stanze sì e no. Ok? Allora, lei diceva giustamente, "Ma se facciamo questa cosa qui non ci stiamo andando a ridurre, a rendere più piccolo il problema di arrivo?" Allora, la questione è che è questa. Praticamente se noi riusciamo a fare un mapping di questo tipo verso un sottoinsieme delle istanze e noi sappiamo che questo problema qui è indecidibile, allora avremo che questa porzione piccolina è già indecidibile. Di conseguenza, siccome loro fanno parte delle possibili istanze del problema di arrivo, il problema di arrivo sarà indecidibile anche solo se consideriamo quelle stanze là. Ok? Quindi in realtà sì, sembra una cosa dire, ma è un po' strano perché gli stiamo dando una forma particolare. In realtà stiamo selezionando del sul dominio delle istanze del problema di arrivo un sottodominio che di per sé è indecidibile. Quindi in generale il problema, siccome gli possono arrivare, se è disgraziato e gli arrivano un po' di istanze strambe, gli arrivano queste e queste, su quello non sa rispondere. Ok? Quindi quello è sufficienza a dire che il problema di arrivo è indecidibile. Ok? Grazie per la domanda. Alright. In questi 7 minuti dobbiamo dimostrare che MPCP si riduce a PCP. Ok? dimostrazione. Supponiamo che partiamo da una coppia di liste AB che sia un'istanza Sì di MPCP. Ok? Se è un'istanza Sì di MPCP, ci siamo? Cosa stiamo dimostrando? Stiamo dimostrando che se partiamo da un'istanza S di MPCP, allora la nostra funzione di trasformazione ha sputato fuori un'istanza Sì di PCP. Supponiamo di star partendo da un'istanza Sì di MPCP. Che vuol dire? Vuol dire che esiste una sequenza di indici tale per cui costruiamo le stesse stringhe. Adesso queste per convenienza le chiamiamo R con I questa qua, S con I questa qua, X con I sono queste di C e Y con i sono quelle di D. Ok? Vi diamo giusto dei nomi per orientarci. Allora, se A e B è un'istanza s di MPCP, abbiamo una sequenza di indici particolari, è una sequenza di indici che parte con uno, quindi abbiamo 1, I2, I3, bla bla bla I M. Ok? Tale per cui avremo che cosa? che R1 concatenato a R2 concatenato a R3 bla bla bla concatenato a Rim è uguale a S1 concateno, SI2 concatenata si bla bla bla concatenato Sim. Il proprio primo un R. Come il primo è un R I R R1 R1 secondo R I2 R I3 bla bla questo lo abbiamo perché stiamo partendo da un istanza sì. Ok? Allora, noi potremmo fare questa cosa qua partendo da questa che è una soluzione per l'istanza di MPCP mostriamo che esiste una soluzione anche per l'istanza di PCP, no? E facciamo così. Invece di R1 consideriamo X1, invece di R2 consideriamo Xi2, XI3 bla bla bla X. Dall'altro lato avremo Y1, Y2, Y3, YM. Adesso questa sequenza di stringhe costruite con questi pezzi è quasi uguale perché le stringhe x1 x2 bla bla hanno gli asterischi dopo. Invece quella y1 y i2 bla bla hanno gli asterischi dopo. Di conseguenza, se io ci piazzo un asterisco qua, mi risolvo un pezzo del problema. L'unica questione è che questa stringa X finisce con un asterisco, mentre la stringa Yim finisce con un singolo standard. Allora, che cosa posso fare? Posso lì metterci la coppia, asterisco dollaro e qui dollaro. Queste due stringhe sono uguali, ok? Cioè la soluzione sarebbe questo qui è x0 e questa qui è è l'ultima, come lo chiamiamo? X k + 1. X + 1. Ok? E questo qua, questo qui è Y per definizione, questo è Y k +. Ok? Semplicemente è questo qua. È chiaro? Una cosa molto semplice. Sì. Ma quindi le liste in TCP sono finite per definizione? Sì, sì, sì, sì, sì, sì, sì, sì, sì. Sia la lunghezza di ogni singola stringa che la lunghezza della lista è finita. Ok. Le stringhe possono essere buone? No, no, cioè no, in linea di principio sì, puoi avere una stringa vuota. Sì, sì, sì, sì. Ma se poteva una stringa vuota, allora non bastava mettere come primo e prima coppia C asterisco blank. Ah, il mio principio sì. Ok, allora in realtà non lo so se può essere vuoto. Secondo me potrebbe essere vuoto, non cambia il problema, però mi sa che la definizione del libro dice che debba esserci qualcosa per forza. Allora, questo dimostra che quindi se partiamo da un'istanza Sì MPCP, siamo arrivati a un'istanza sì di eh PCP. Dobbiamo ora dimostrare che se siamo arrivati a un'istanza SìP, il secondo pezzo della dimostrazione era perché partivamo da un'istanza sì di PCP. Ok? Supponiamo di NPCP, supponiamo di essere arrivati a un'istanza sì di PCP, ok? Quindi avremo una sequenza di indici tale per cui se concateniamo le stringhe costruiamo la stessa cosa. Adesso, per come è stata costruita nello specifico l'istanza di PCP, la soluzione deve per forza partire da indice zero e finire sull'ultima coppia perché perché così abbiamo costruito l'istanza. Ok? Perché la questione è supponiamo di essere, sentite la parola, supponiamo di essere arrivati a un'istanza C di MPCP. Siamo arrivati a un'istanza di PCP, il che significa che questa istanza che stiamo analizzando è il frutto della funzione di riduzione, non è unistanza a caso. Quindi supponiamo di essere arrivati a un'istanza sì di PCP. La sua soluzione deve per forza partire dalla coppia di indice zero perché è l'unica coppia che ha lo stesso simbolo all'inizio. Quindi noi potremmo trasformare una soluzione dell'istanza di arrivo di PCP in una soluzione per l'istanza di partenza di MPCP. Perché? Perché abbiamo forzato tramite una costruzione opportuna che tutte le possibili soluzioni sull'istanza di arrivo contemplino solamente come partenza la primissima coppia. Ok? Quindi, se siamo arrivati a un'istanza sì di M di PCP era perché stavamo partendo da un'istanza Sì di PCP da cui MPCP si riduce a PCP e quindi PCP è indecidibile. Ok, ci abbiamo messo 2 ore, pensavo sarebbe stata più corta. Ok, è chiaro? Non ho capito l'ultimissima parte. Eh, allora noi ci siamo giunti a unistanza sì, quindi vuol dire che possiamo costruire istanze sì di partenza e dare in qua. Attenzione, se siamo arrivati o se ho capito bene il il punto, se siamo arrivati a un'istanza di MCP e ci siamo arrivati tramite quella costruzione che ci siamo inventati, allora le la soluzione per questa istanza che abbiamo prodotto contempla per forza il partire con la coppia di indice zero. Quindi quella soluzione io la posso usare per costruire una soluzione sull'istanza di partenza, quindi anche l'istanza di partenza era un'istanza simile, quindi M PCP si riduce a PCP che risulta indecidibile. Il concetto di riduzione è una cosa importantissima perché cioè da adesso in poi lo useremo quasi in ogni lezione, eh, quindi è una cosa che dovete proprio cogliere, senò vi perdete pezzi pezzi importanti perché da adesso in poi è quasi tutto riduzioni. Ok? E vabbò. Buona serata. Grazie per essere venuti