Domanda 8 delle tracce
Impara a programmare una macchina di Turing
Qui trovi il metodo per scrivere la tabella delle transizioni, un esempio costruito un passo alla volta e le soluzioni di tutte le macchine uscite nelle tracce. La tua macchina la scrivi e la consegni nella domanda 8 di ogni traccia.
Nastro, testina e stati
Una macchina di Turing legge e scrive su un nastro diviso in celle. La testina indica la cella su cui sta lavorando, e lo stato ricorda a che punto del calcolo è arrivata.
Il programma è la tabella . Ogni riga dice che cosa leggere, che cosa scrivere al suo posto, dove spostare la testina e in quale stato passare.
Con input 1011 la macchina parte così:
▷ 1 0 1 1 ⊔ ⊔ …
↑
testina (stato iniziale s)
segna l'inizio del nastro e è una cella vuota. La testina parte su , nello stato .
Come leggere una transizione
La macchina si descrive con : stati, alfabeto, transizioni e stato iniziale.
La regola si legge così: nello stato , se leggi , scrivi , sposta la testina in direzione e passa nello stato . Le direzioni sono (sinistra), (destra) e (testina ferma). Su riscrivi sempre e vai a destra.
Una macchina che calcola una funzione termina in e lascia il risultato sul nastro; se i nastri sono più di uno, il simulatore legge il risultato sull'ultimo. Una macchina di decisione termina in yes per accettare e in no per rifiutare. Per le combinazioni che non hanno una regola scrivi «in tutti gli altri casi rigetta». Con più nastri, ogni regola indica per ciascun nastro il simbolo letto, quello scritto e il movimento.
Nelle tabelle è un bit qualsiasi, il suo opposto e un simbolo qualsiasi. Se a destra riscrivi o , la cella resta com'era.
Dall'idea alla tabella in quattro passi
- Prima di scegliere gli stati, scrivi in due righe che cosa farà la macchina.
- Dai uno stato a ogni informazione da ricordare: un bit, un riporto, la fase del calcolo.
- Controlla i casi limite: input vuoto, overflow, testina che torna all'inizio del nastro.
- Simula a mano un input piccolo, una transizione alla volta.
Nelle simulazioni scritte di questa pagina, la cella tra parentesi quadre è quella sotto la testina e ogni riga è un passo. Quando la tua tabella è pronta, la verifichi sui casi di prova con «Consegna», nella domanda 8 di ogni traccia.
Un blocco che torna spesso: arrivare all'ultima cifra
Molte operazioni sui numeri binari cominciano dall'ultima cifra. Per arrivarci, scorri tutti i bit verso destra e, sulla prima cella vuota, torna indietro di una posizione.
| : da qui cambia da macchina a macchina |
Nelle tabelle delle operazioni che usano questo blocco le prime due righe sono sottintese.
Esempio guidato: l'incremento di 1
La tabella si costruisce in quattro passi, e a ogni passo le righe nuove sono evidenziate. All'ultimo passo puoi eseguire la macchina.
Per aggiungere 1 a un numero binario si parte da destra: ogni 1 finale diventa 0 e il primo 0 diventa 1. Prima, però, la macchina deve arrivare all'ultima cifra, quindi scorre l'input fino alla prima cella vuota e torna indietro di una posizione. È quello che fanno le prime tre righe.
Transizioni scritte finora
- δ(s, ▷) = (s, ▷, →)supera l'inizio del nastro
- δ(s, b) = (s, b, →)vai in fondo
- δ(s, ⊔) = (q, ⊔, ←)fine input, inizia il riporto
Come scrivere le transizioni
Nella domanda 8 di ogni traccia la macchina si scrive in una tabella, con una riga per ogni transizione. La riga con stato q, legge 1, nuovo stato q, scrive 0 e mossa ← vuol dire: se sei in q e leggi 1, scrivi 0, spostati a sinistra e resta in q. In formule, .
Le mosse sono → (destra), ← (sinistra) e − (testina ferma). ▷ segna l'inizio del nastro e ⊔ una cella vuota: puoi scriverli come > e _, oppure inserirli nella cella selezionata con la barra «Inserisci» sotto la tabella.
Nelle celle puoi usare dei jolly. b è un bit qualsiasi e b' un secondo bit, indipendente dal primo; b̄ (oppure !b) è il bit opposto a b; σ (oppure *) è un simbolo qualsiasi tranne ▷. Scritti a destra della freccia, b, b' e σ valgono il simbolo letto con quel nome, quindi su un altro nastro lo copiano; b̄ scrive il bit opposto a b.
La macchina parte da s. Termina in h quando restituisce un risultato, in yes per accettare e in no per rifiutare. La colonna del commento è facoltativa e non viene eseguita.
Con più nastri ogni riga ha, per ciascun nastro, un simbolo letto, un simbolo scritto e una mossa. Con un oracolo scrivi la domanda sull'ultimo nastro ed entra in q?: la risposta porta la macchina in qYES oppure in qNO. Per questi stati, e per yes e no, maiuscole e minuscole sono indifferenti.
Se per lo stato e i simboli letti non c'è nessuna riga, la macchina rifiuta. Se le righe applicabili sono più di una, vincono quelle con più simboli esatti; a parità, ogni riga è un ramo nondeterministico.
Soluzioni delle tracce
Apri un esercizio per leggere come si risolve e per eseguire la soluzione nel simulatore.
Incremento di 11 tracciafunzione · 1 nastro
Nelle tracce: F14
La macchina deve aggiungere 1 al numero binario sul nastro. Parti dall'ultima cifra e vai a sinistra: ogni 1 diventa 0, il primo 0 diventa 1 e il calcolo termina.
Se trovi solo 1, serve una cifra in più: scrivi 1 all'inizio e aggiungi uno 0 in coda, come in .
| commento | |||
|---|---|---|---|
| fine input, inizia il riporto | |||
| , il riporto continua | |||
| riporto assorbito, fine | |||
| overflow | |||
| la prima cifra diventa 1 | |||
| scorre le altre cifre | |||
| aggiunge lo 0 in coda |
Traccia su input 11 (= 3):
▷ 1 1 [⊔] s : fine input, torno indietro
▷ 1 [1] ⊔ q : 1 + riporto = 0, il riporto continua
▷ [1] 0 ⊔ q : di nuovo 1 → 0
[▷] 0 0 ⊔ q : sono all'inizio: overflow
▷ [0] 0 ⊔ o : la prima cifra diventa 1
▷ 1 [0] ⊔ o' : scorro a destra
▷ 1 0 [⊔] o' : scrivo lo 0 finale e mi fermo
▷ 1 0 0 risultato 100 = 4 ✔
La stessa traccia con le configurazioni
Una configurazione descrive un istante: è lo stato, è ciò che sta a sinistra della testina, compreso il simbolo letto, e è ciò che sta a destra. Per esempio vuol dire che la macchina è nello stato , la testina legge l'1 e a destra ci sono .
Il simbolo vuol dire "in zero o più passi" (qui i passi di "vai in fondo") e è la stringa vuota. L'output è 100 ✔.
Nella tabella sono sottintese le righe del blocco «vai in fondo»: e . La macchina va in fondo all'input e, sulla prima cella vuota, comincia la parte propria di ogni esercizio.
Prova la soluzione
Prossima transizione: δ(s, ▷) = (s, ▷, →) · supera l'inizio del nastro
Mostra il codice della soluzione
s ▷ -> s ▷ R # supera l'inizio del nastro s b -> s b R # vai in fondo s ⊔ -> q ⊔ L # fine input, inizia il riporto q 1 -> q 0 L # 1 + riporto = 0, il riporto continua q 0 -> h 1 S # riporto assorbito, fine q ▷ -> o ▷ R # overflow o 0 -> o' 1 R # la prima cifra diventa 1 o' 0 -> o' 0 R # scorre le altre cifre o' ⊔ -> h 0 S # aggiunge lo 0 in coda
Moltiplicazione per 21 tracciafunzione · 1 nastro
Nelle tracce: F13
La macchina deve moltiplicare per 2 il numero binario sul nastro. Raggiungi la prima cella vuota, scrivi 0 e termina in . Aggiungere uno 0 a destra equivale a moltiplicare per 2: , cioè .
Traccia su input 101 (= 5):
▷ 1 0 1 [⊔] s : fine input (dopo "vai in fondo"): scrivo 0 e mi fermo
▷ 1 0 1 [0] h : risultato 1010 = 10 = 2 · 5 ✔
Nella tabella sono sottintese le righe del blocco «vai in fondo»: e . La macchina va in fondo all'input e, sulla prima cella vuota, comincia la parte propria di ogni esercizio.
Prova la soluzione
Prossima transizione: δ(s, ▷) = (s, ▷, →) · supera l'inizio del nastro
Mostra il codice della soluzione
s ▷ -> s ▷ R # supera l'inizio del nastro s b -> s b R # vai in fondo s ⊔ -> h 0 S # fine input: scrive 0 e si ferma
Moltiplicazione per 41 tracciafunzione · 1 nastro
Nelle tracce: G20v2
La macchina deve moltiplicare per 4 il numero binario sul nastro. Raggiungi la fine dell'input e aggiungi due 0: ogni 0 raddoppia il valore, quindi , cioè .
La testina parte su . La macchina termina in e lascia il risultato sul nastro. Nella tabella indica un bit qualsiasi e una cella vuota.
| commento | |||
|---|---|---|---|
| supera l'inizio del nastro | |||
| scorre l'input fino in fondo | |||
| fine input: scrive il primo 0 | |||
| scrive il secondo 0 e si ferma |
Nella traccia ogni riga è un istante: tra parentesi quadre c'è la cella sotto la testina, a destra lo stato e cosa fa la macchina. Traccia su input 101 (= 5):
▷ 1 0 1 [⊔] ⊔ s : fine input (dopo "vai in fondo"): scrivo 0 e vado a destra
▷ 1 0 1 0 [⊔] q : scrivo il secondo 0 e mi fermo
▷ 1 0 1 0 0 h : risultato 10100 = 20 = 4 · 5 ✔
Con input 0 l'output è 000, che vale ancora 0 ✔, perché gli zeri a sinistra non cambiano il valore. La macchina è stata verificata con un simulatore su tutti gli input fino a 8 bit.
Prova la soluzione
Prossima transizione: δ(s, ▷) = (s, ▷, →) · supera l'inizio del nastro
Mostra il codice della soluzione
s ▷ -> s ▷ R # supera l'inizio del nastro s b -> s b R # vai in fondo s ⊔ -> q 0 R # fine input: scrive il primo 0 q ⊔ -> h 0 S # scrive il secondo 0 e si ferma
Divisione intera per 22 traccefunzione · 1 nastro
La macchina deve calcolare la divisione intera per 2, scartando il resto. Per farlo cancella l'ultima cifra: , cioè con resto 1.
Se l'input ha una sola cifra, scrivi 0, perché il risultato non deve essere un nastro vuoto.
| commento | |||
|---|---|---|---|
| fine input | |||
| cancella l'ultima cifra | |||
| è rimasta almeno una cifra | |||
| non è rimasto niente… | |||
| …quindi scrive 0 |
Traccia su input 101 (= 5) e sul caso limite 1:
▷ 1 0 1 [⊔] s : fine input, torno indietro
▷ 1 0 [1] ⊔ q : cancello l'ultima cifra
▷ 1 [0] ⊔ ⊔ r : è rimasta almeno una cifra: mi fermo (h)
risultato 10 = 2 ✔
▷ 1 [⊔] s : fine input, torno indietro
▷ [1] ⊔ q : cancello l'unica cifra
[▷] ⊔ ⊔ r : non è rimasto niente
▷ [⊔] ⊔ z : scrivo 0 e mi fermo (h)
risultato 0 ✔
Nella tabella sono sottintese le righe del blocco «vai in fondo»: e . La macchina va in fondo all'input e, sulla prima cella vuota, comincia la parte propria di ogni esercizio.
Prova la soluzione
Prossima transizione: δ(s, ▷) = (s, ▷, →) · supera l'inizio del nastro
Mostra il codice della soluzione
s ▷ -> s ▷ R # supera l'inizio del nastro s b -> s b R # vai in fondo s ⊔ -> q ⊔ L # fine input q b -> r ⊔ L # cancella l'ultima cifra r b -> h b S # è rimasta almeno una cifra r ▷ -> z ▷ R # non è rimasto niente… z ⊔ -> h 0 S # …quindi scrive 0
Divisione intera per 41 tracciafunzione · 1 nastro
Nelle tracce: G20v5
La macchina deve calcolare la divisione intera per 4, scartando il resto. Per farlo cancella le ultime due cifre: , cioè con resto 2.
Se l'input ha una o due cifre, scrivi 0 invece di lasciare il nastro vuoto.
La macchina termina in . Nella tabella indica un bit qualsiasi e una cella vuota.
| commento | |||
|---|---|---|---|
| supera l'inizio del nastro | |||
| scorre l'input fino in fondo | |||
| fine input, torna sull'ultima cifra | |||
| cancella l'ultima cifra | |||
| cancella la penultima cifra | |||
| l'input aveva una sola cifra | |||
| è rimasta almeno una cifra: fine | |||
| non è rimasto niente… | |||
| …quindi scrive 0 |
Nella traccia ogni riga è un istante: tra parentesi quadre c'è la cella sotto la testina, a destra lo stato e cosa fa la macchina. Traccia su input 10110 (= 22) e sul caso limite 11 (= 3):
▷ 1 0 1 1 0 [⊔] s : fine input (dopo "vai in fondo"), torno indietro
▷ 1 0 1 1 [0] ⊔ q : cancello l'ultima cifra
▷ 1 0 1 [1] ⊔ ⊔ r : cancello la penultima cifra
▷ 1 0 [1] ⊔ ⊔ ⊔ t : è rimasta almeno una cifra: mi fermo (h)
risultato 101 = 5 = 22 : 4 (resto scartato) ✔
▷ 1 1 [⊔] s : fine input, torno indietro
▷ 1 [1] ⊔ q : cancello l'ultima cifra
▷ [1] ⊔ ⊔ r : cancello la penultima cifra
[▷] ⊔ ⊔ ⊔ t : non è rimasto niente
▷ [⊔] ⊔ ⊔ z : scrivo 0 e mi fermo (h)
risultato 0 = 3 : 4 ✔
Con input di una sola cifra (0 oppure 1) la macchina arriva su già nello stato e scrive 0 allo stesso modo. La macchina è stata verificata con un simulatore su tutti gli input fino a 8 bit.
Prova la soluzione
Prossima transizione: δ(s, ▷) = (s, ▷, →) · supera l'inizio del nastro
Mostra il codice della soluzione
s ▷ -> s ▷ R # supera l'inizio del nastro s b -> s b R # vai in fondo s ⊔ -> q ⊔ L # fine input, torna sull'ultima cifra q b -> r ⊔ L # cancella l'ultima cifra r b -> t ⊔ L # cancella la penultima cifra r ▷ -> z ▷ R # l'input aveva una sola cifra t b -> h b S # è rimasta almeno una cifra: fine t ▷ -> z ▷ R # non è rimasto niente… z ⊔ -> h 0 S # …quindi scrive 0
Resto della divisione per 24 traccefunzione · 1 nastro
Nelle tracce: F02, F04, F06, G20v1
La macchina deve lasciare sul nastro solo il resto della divisione per 2, cioè 0 oppure 1. Leggi l'ultima cifra e ricordala nello stato o , cancella il numero tornando a sinistra e poi scrivi la cifra ricordata nella prima cella.
Nella tabella vale 0 o 1: le righe con e descrivono entrambi i casi.
| commento | |||
|---|---|---|---|
| fine input | |||
| ricorda 0 | |||
| ricorda 1 | |||
| cancella le altre cifre | |||
| inizio del nastro | |||
| scrive il resto |
Traccia su input 101 (= 5):
▷ 1 0 1 [⊔] s : fine input, torno indietro
▷ 1 0 [1] ⊔ q : l'ultima cifra è 1: la ricordo (c1) e la cancello
▷ 1 [0] ⊔ ⊔ c1 : cancello
▷ [1] ⊔ ⊔ ⊔ c1 : cancello
[▷] ⊔ ⊔ ⊔ ⊔ c1 : sono all'inizio
▷ [⊔] ⊔ ⊔ ⊔ w1 : scrivo la cifra ricordata e mi fermo (h)
risultato 1 = resto di 5 diviso 2 ✔
Se il testo chiedesse invece una macchina di decisione ("accetta i numeri pari"), basterebbero le righe e .
Nella tabella sono sottintese le righe del blocco «vai in fondo»: e . La macchina va in fondo all'input e, sulla prima cella vuota, comincia la parte propria di ogni esercizio.
Prova la soluzione
Prossima transizione: δ(s, ▷) = (s, ▷, →) · supera l'inizio del nastro
Mostra il codice della soluzione
s ▷ -> s ▷ R # supera l'inizio del nastro s b -> s b R # vai in fondo s ⊔ -> q ⊔ L # fine input q 0 -> c0 ⊔ L # ricorda 0 q 1 -> c1 ⊔ L # ricorda 1 c0 b -> c0 ⊔ L # cancella le altre cifre c1 b -> c1 ⊔ L c0 ▷ -> w0 ▷ R # inizio del nastro c1 ▷ -> w1 ▷ R w0 ⊔ -> h 0 S # scrive il resto w1 ⊔ -> h 1 S
Calcolare −x in complemento a due1 tracciafunzione · 1 nastro
Nelle tracce: L18
La macchina deve calcolare in complemento a due, mantenendo lo stesso numero di bit. Da destra, lascia invariati gli 0 finali e il primo 1, poi inverti tutti i bit che restano a sinistra.
Questo equivale a invertire tutti i bit e sommare 1: il riporto ripristina gli 0 finali e il primo 1, mentre i bit a sinistra restano invertiti.
| commento | |||
|---|---|---|---|
| fine input | |||
| copia gli 0 finali | |||
| copia il primo 1, poi inverte | |||
| , quindi | |||
| inverte | |||
| inverte | |||
| fine |
Traccia su input 0110 (= 6):
▷ 0 1 1 0 [⊔] s : fine input, torno indietro
▷ 0 1 1 [0] ⊔ c : 0 finale: lo copio
▷ 0 1 [1] 0 ⊔ c : primo 1: lo copio, da qui inverto
▷ 0 [1] 1 0 ⊔ i : 1 → 0
▷ [0] 0 1 0 ⊔ i : 0 → 1
[▷] 1 0 1 0 ⊔ i : sono all'inizio: mi fermo (h)
risultato 1010 = −6 ✔
Per , il numero più negativo, la macchina restituisce stesso, perché non si può scrivere con lo stesso numero di bit.
Nella tabella sono sottintese le righe del blocco «vai in fondo»: e . La macchina va in fondo all'input e, sulla prima cella vuota, comincia la parte propria di ogni esercizio.
Prova la soluzione
Prossima transizione: δ(s, ▷) = (s, ▷, →) · supera l'inizio del nastro
Mostra il codice della soluzione
s ▷ -> s ▷ R # supera l'inizio del nastro s b -> s b R # vai in fondo s ⊔ -> c ⊔ L # fine input c 0 -> c 0 L # copia gli 0 finali c 1 -> i 1 L # copia il primo 1, poi inverte c ▷ -> h ▷ R # x = 0, quindi −x = 0 i 0 -> i 1 L # inverte i 1 -> i 0 L i ▷ -> h ▷ R # fine
Interi positivi dispari in complemento a due1 tracciadecisione · 1 nastro
Nelle tracce: F01
La macchina deve accettare solo gli interi positivi dispari scritti in complemento a due. Controlla due condizioni: primo bit 0 (segno non negativo) e ultimo bit 1 (numero dispari, quindi diverso da zero). Per esempio, 011 è accettato, mentre 111 è rifiutato perché negativo.
Qui devi leggere anche la prima cifra, quindi non partire direttamente dal blocco «vai in fondo».
| commento | |||
|---|---|---|---|
| segno positivo | |||
| negativo | |||
| stringa vuota | |||
| va in fondo | |||
| torna sull'ultimo bit | |||
| dispari | |||
| pari (o zero) |
Traccia su input 011 (= 3):
▷ [0] 1 1 s : primo bit 0, positivo
▷ 0 [1] 1 a : vado in fondo
▷ 0 1 [1] a
▷ 0 1 1 [⊔] a : fine, torno sull'ultimo bit
▷ 0 1 [1] ⊔ t : ultimo bit 1, dispari: yes ✔
Con 110, che è negativo, la macchina rigetta al primo bit; con 010, che è pari, rigetta sull'ultimo.
Prova la soluzione
Prossima transizione: δ(s, ▷) = (s, ▷, →)
Mostra il codice della soluzione
s ▷ -> s ▷ R s 0 -> a 0 R # segno positivo s 1 -> no 1 S # negativo s ⊔ -> no ⊔ S # stringa vuota a b -> a b R # va in fondo a ⊔ -> t ⊔ L # torna sull'ultimo bit t 1 -> yes 1 S # dispari t 0 -> no 0 S # pari (o zero)
Stringhe non palindrome: macchina nondeterministica3 traccedecisione · 2 nastri · nondeterministica
Nelle tracce: G20v4, FE23, MA23
La macchina deve accettare se esistono due cifre simmetriche diverse, cioè . Con 2 nastri, scegli in modo nondeterministico una posizione dell'input e, per ogni cifra che salti, scrivi una tacca I sul secondo nastro: alla fine hai tacche. Ricorda nello stato la cifra scelta e raggiungi la fine dell'input, poi torna indietro di una cella per ogni tacca e confronta la cifra raggiunta con quella ricordata.
Un ramo accetta quando trova una differenza, e basta un ramo accettante per riconoscere una stringa non palindroma.
| Stato | letto₁ | letto₂ | nuovo stato | scritto₁, mossa₁ | scritto₂, mossa₂ | note |
|---|---|---|---|---|---|---|
| scelta 1: salta la cifra | ||||||
| scelta 2: confronta (ricordata nello stato) | ||||||
| nessuna cifra scelta | ||||||
| va in fondo | ||||||
| torna indietro su entrambi | ||||||
| consuma una tacca per passo | ||||||
| cifre simmetriche diverse | ||||||
| questo ramo rigetta |
Qui , quindi e corrispondono a 2 + 2 stati. La macchina accetta se almeno un ramo accetta, cioè se esiste una coppia di cifre simmetriche diverse; se è palindroma, tutti i rami rigettano.
Il ramo che sceglie la posizione fa passi: per arrivare alla cifra scelta, per arrivare in fondo, per tornare indietro consumando le tacche, più qualche passo di servizio. Ogni ramo si ferma quindi entro passi, cioè il "tempo " della traccia a meno di costanti, che per lo speedup lineare non contano.
Traccia passo passo del ramo che sceglie i = 3 su x = 100
stato nastro 1 nastro 2
s [▷] 1 0 0 [▷] parto
s ▷ [1] 0 0 ▷ [⊔] scelta 1: salto la cifra, scrivo una tacca
s ▷ 1 [0] 0 ▷ I [⊔] scelta 1: salto, seconda tacca
s ▷ 1 0 [0] ▷ I I [⊔] scelta 2: confronto questa (a = 0)
g0 ▷ 1 0 0 [⊔] ▷ I I [⊔] in fondo: torno indietro su entrambi
c0 ▷ 1 0 [0] ⊔ ▷ I [I] ⊔ consumo una tacca
c0 ▷ 1 [0] 0 ⊔ ▷ [I] I ⊔ consumo una tacca
c0 ▷ [1] 0 0 ⊔ [▷] I I ⊔ tacche finite: sono su x1 = 1, diverso da a = 0
yes
Il ramo che sceglie non scrive tacche: dal fondo torna indietro di una sola cella, si trova su , lo confronta con e accetta anche lui. Il ramo confronta la cifra centrale con se stessa e rigetta.
Prova la soluzione
Prossima transizione: δ(s, ▷, ▷) = (s, ▷, →, ▷, →)
Mostra il codice della soluzione
s ▷ ▷ -> s ▷ R ▷ R s 0 ⊔ -> s 0 R I R # scelta 1: salta la cifra 0 s 0 ⊔ -> g0 0 R ⊔ S # scelta 2: confronta la cifra 0 s 1 ⊔ -> s 1 R I R # scelta 1: salta la cifra 1 s 1 ⊔ -> g1 1 R ⊔ S # scelta 2: confronta la cifra 1 s ⊔ ⊔ -> no ⊔ S ⊔ S # nessuna cifra scelta g0 b ⊔ -> g0 b R ⊔ S # va in fondo g1 b ⊔ -> g1 b R ⊔ S g0 ⊔ ⊔ -> c0 ⊔ L ⊔ L # torna indietro su entrambi g1 ⊔ ⊔ -> c1 ⊔ L ⊔ L c0 b I -> c0 b L I L # consuma una tacca per passo c1 b I -> c1 b L I L c0 1 ▷ -> yes 1 S ▷ R # cifre simmetriche diverse c1 0 ▷ -> yes 0 S ▷ R c0 0 ▷ -> no 0 S ▷ R # questo ramo rigetta c1 1 ▷ -> no 1 S ▷ R
Palindrome: macchina nondeterministica a 2 nastri1 tracciadecisione · 2 nastri · nondeterministica
Nelle tracce: F03
La macchina, nondeterministica e a 2 nastri, deve riconoscere una stringa palindroma. Copia l'inizio dell'input sul secondo nastro e indovina dove termina la prima metà; se la lunghezza è dispari salta il bit centrale, se è pari non saltare nulla. Poi confronta il resto dell'input con la copia letta all'indietro. Un ramo accetta se tutti i confronti coincidono e le due metà finiscono insieme, cioè con sul primo nastro e sul secondo.
| Stato | letto₁ | letto₂ | nuovo stato | scritto₁, mossa₁ | scritto₂, mossa₂ | note |
|---|---|---|---|---|---|---|
| scelta 1: copia , la prima metà continua | ||||||
| scelta 2: è il centro (lunghezza dispari), lo salta | ||||||
| scelta 3: la prima metà finisce prima di (lunghezza pari) | ||||||
| fine dell'input senza scelte: accetta solo la stringa vuota | ||||||
| cifre simmetriche uguali | ||||||
| finite insieme: palindroma |
In tutti gli altri casi rigetta, cioè quando trova due cifre diverse oppure quando un nastro finisce prima dell'altro (il punto scelto non era la metà). è un bit qualsiasi, riscritto uguale.
La macchina accetta se almeno un ramo accetta. Se è palindroma accetta il ramo che sceglie la metà giusta; se non lo è, ogni ramo trova due cifre diverse o finisce i nastri in momenti diversi, e rigetta. Ogni ramo si ferma entro passi, mentre la macchina deterministica del file (sotto) ne fa . È stata verificata con un simulatore su tutte le stringhe fino a 10 bit.
Traccia passo passo: il ramo che accetta su x = 101 e su x = 0110
stato nastro 1 nastro 2
s [▷] 1 0 1 ⊔ [▷] ⊔ ⊔
s ▷ [1] 0 1 ⊔ ▷ [⊔] ⊔ scelta 1: copio 1
s ▷ 1 [0] 1 ⊔ ▷ 1 [⊔] scelta 2: 0 è il centro, lo salto
m ▷ 1 0 [1] ⊔ ▷ [1] ⊔ 1 = 1
m ▷ 1 0 1 [⊔] [▷] 1 ⊔ finiti insieme
yes
s [▷] 0 1 1 0 ⊔ [▷] ⊔ ⊔
s ▷ [0] 1 1 0 ⊔ ▷ [⊔] ⊔ scelta 1: copio 0
s ▷ 0 [1] 1 0 ⊔ ▷ 0 [⊔] scelta 1: copio 1
s ▷ 0 1 [1] 0 ⊔ ▷ 0 1 [⊔] scelta 3: la metà finisce qui
m ▷ 0 1 [1] 0 ⊔ ▷ 0 [1] ⊔ 1 = 1
m ▷ 0 1 1 [0] ⊔ ▷ [0] 1 ⊔ 0 = 0
m ▷ 0 1 1 0 [⊔] [▷] 0 1 ⊔ finiti insieme
yes
Gli altri rami rigettano. Su 101, per esempio, il ramo che fa la scelta 3 davanti allo 0 confronta 0 con 1, mentre quello che copia tutte e tre le cifre arriva a e trova sul 2° nastro una cifra invece di .
La soluzione del file è una MdT deterministica a 2 nastri che copia l'input, riavvolge il 1° nastro e confronta: è la palindrome deterministica. Va bene anche quella, perché una MdT deterministica è un caso particolare di nondeterministica in cui ogni configurazione ha una sola mossa.
Prova la soluzione
Prossima transizione: δ(s, ▷, ▷) = (s, ▷, →, ▷, →)
Mostra il codice della soluzione
s ▷ ▷ -> s ▷ R ▷ R s b ⊔ -> s b R b R # scelta 1: copia b, la prima metà continua s b ⊔ -> m b R ⊔ L # scelta 2: b è il centro (lunghezza dispari), lo salta s b ⊔ -> m b S ⊔ L # scelta 3: la prima metà finisce prima di b (lunghezza pari) s ⊔ ⊔ -> m ⊔ S ⊔ L # fine dell'input senza scelte m b b -> m b R b L # cifre simmetriche uguali m ⊔ ▷ -> yes ⊔ S ▷ R # finite insieme: palindroma
Palindrome: macchina deterministica a 2 nastri2 traccedecisione · 2 nastri
La macchina deve riconoscere una stringa che si legge nello stesso modo da sinistra e da destra. Con 2 nastri, copia l'intero input sul secondo nastro (stato ), poi riporta la prima testina all'inizio e lascia la seconda in fondo alla copia (stato ). Infine confronta l'originale da sinistra con la copia da destra (stato ): alla prima differenza rifiuta, mentre se tutti i bit coincidono e le due letture terminano insieme accetta.
| Stato | letto₁ | letto₂ | nuovo stato | scritto₁, mossa₁ | scritto₂, mossa₂ | note |
|---|---|---|---|---|---|---|
| copia l'input | ||||||
| fine dell'input: la testina 2 resta dopo la copia | ||||||
| riavvolge il 1° nastro | ||||||
| testina 1 sulla prima cifra, testina 2 sull'ultima | ||||||
| cifre simmetriche uguali | ||||||
| cifre simmetriche diverse | ||||||
| finite insieme: palindroma |
In tutti gli altri casi rigetta. è un bit qualsiasi, riscritto uguale, e è il bit opposto. È la macchina della soluzione del file, ricontrollata: fa passi tra copia, riavvolgimento e confronto, e accetta anche la stringa vuota. La verifica con un simulatore copre tutte le stringhe fino a 10 bit.
Traccia passo passo su x = 010 (accetta) e su x = 011 (rigetta)
stato nastro 1 nastro 2
s [▷] 0 1 0 ⊔ [▷] ⊔ ⊔ ⊔ ⊔
s ▷ [0] 1 0 ⊔ ▷ [⊔] ⊔ ⊔ ⊔ copio 0
s ▷ 0 [1] 0 ⊔ ▷ 0 [⊔] ⊔ ⊔ copio 1
s ▷ 0 1 [0] ⊔ ▷ 0 1 [⊔] ⊔ copio 0
s ▷ 0 1 0 [⊔] ▷ 0 1 0 [⊔] fine dell'input
r ▷ 0 1 [0] ⊔ ▷ 0 1 0 [⊔] riavvolgo il nastro 1
r ▷ 0 [1] 0 ⊔ ▷ 0 1 0 [⊔]
r ▷ [0] 1 0 ⊔ ▷ 0 1 0 [⊔]
r [▷] 0 1 0 ⊔ ▷ 0 1 0 [⊔] inizio del nastro 1
c ▷ [0] 1 0 ⊔ ▷ 0 1 [0] ⊔ 0 = 0
c ▷ 0 [1] 0 ⊔ ▷ 0 [1] 0 ⊔ 1 = 1
c ▷ 0 1 [0] ⊔ ▷ [0] 1 0 ⊔ 0 = 0
c ▷ 0 1 0 [⊔] [▷] 0 1 0 ⊔ finiti insieme
yes
Su 011 i primi nove passi sono uguali. Al primo confronto la testina 1 legge 0 e la testina 2 legge l'ultima cifra, 1: le cifre sono diverse, quindi la macchina va in no.
Con il nondeterminismo si fa in tempo n
La macchina nondeterministica indovina dove finisce la prima metà e non deve riavvolgere: ogni ramo si ferma entro passi invece di .
Prova la soluzione
Prossima transizione: δ(s, ▷, ▷) = (s, ▷, →, ▷, →)
Mostra il codice della soluzione
s ▷ ▷ -> s ▷ R ▷ R s b ⊔ -> s b R b R # copia l'input s ⊔ ⊔ -> r ⊔ L ⊔ S # fine dell'input: la testina 2 resta dopo la copia r b ⊔ -> r b L ⊔ S # riavvolge il 1° nastro r ▷ ⊔ -> c ▷ R ⊔ L # testina 1 sulla prima cifra, testina 2 sull'ultima c b b -> c b R b L # cifre simmetriche uguali c b b̄ -> no b S b̄ S # cifre simmetriche diverse c ⊔ ▷ -> yes ⊔ S ▷ R # finite insieme: palindroma
Confronto tra numeri binari: x ≤ y3 traccedecisione · 2 nastri
Nelle tracce: G20v3, MZ22, GE23
La macchina deve accettare l'input x;y se i due numeri binari hanno la stessa lunghezza e . Con 2 nastri, copia sul secondo nastro, riporta la testina all'inizio e confronta e da sinistra: la prima coppia di bit diversi decide quale numero è maggiore.
Lo stato significa «finora uguali», lo stato significa « è già minore». Le testine devono arrivare insieme alla fine dei due numeri: se le lunghezze sono diverse, la macchina rifiuta.
| Stato | letto₁ () | letto₂ () | nuovo stato | scritto₁, mossa₁ | scritto₂, mossa₂ | note |
|---|---|---|---|---|---|---|
| copia | ||||||
| testina 1 sulla prima cifra di | ||||||
| riavvolge il 2° nastro | ||||||
| pronto a confrontare | ||||||
| cifre uguali | ||||||
| minore di | ||||||
| maggiore di | ||||||
| ormai conta solo la lunghezza ( è un altro bit qualsiasi) | ||||||
| o | stessa lunghezza e | |||||
| o | — | — | più lungo | |||
| o | — | — | più lungo |
In tutti gli altri casi (per esempio se manca il ";") rigetta.
Traccia passo passo su 01;10
stato nastro 1 (x;y) nastro 2
s [▷] 0 1 ; 1 0 [▷]
s ▷ [0] 1 ; 1 0 ▷ [⊔] copio x
s ▷ 0 [1] ; 1 0 ▷ 0 [⊔] copio x
s ▷ 0 1 [;] 1 0 ▷ 0 1 [⊔] fine di x
r ▷ 0 1 ; [1] 0 ▷ 0 [1] ⊔ riavvolgo il nastro 2
r ▷ 0 1 ; [1] 0 ▷ [0] 1 ⊔
r ▷ 0 1 ; [1] 0 [▷] 0 1 ⊔ inizio del nastro 2
e ▷ 0 1 ; [1] 0 ▷ [0] 1 ⊔ y ha 1, x ha 0: x < y
l ▷ 0 1 ; 1 [0] ▷ 0 [1] ⊔ ormai conta solo la lunghezza
l ▷ 0 1 ; 1 0 [⊔] ▷ 0 1 [⊔] finiscono insieme
yes
Prova la soluzione
Prossima transizione: δ(s, ▷, ▷) = (s, ▷, →, ▷, →)
Mostra il codice della soluzione
s ▷ ▷ -> s ▷ R ▷ R s b ⊔ -> s b R b R # copia x s ; ⊔ -> r ; R ⊔ L # testina 1 sulla prima cifra di y r σ b -> r σ S b L # riavvolge il 2° nastro r σ ▷ -> e σ S ▷ R # pronto a confrontare e b b -> e b R b R # cifre uguali e 1 0 -> l 1 R 0 R # x minore di y e 0 1 -> no 0 S 1 S # x maggiore di y l b b' -> l b R b' R # ormai conta solo la lunghezza e ⊔ ⊔ -> yes ⊔ S ⊔ S # stessa lunghezza e x ≤ y l ⊔ ⊔ -> yes ⊔ S ⊔ S e b ⊔ -> no b S ⊔ S # y più lungo l b ⊔ -> no b S ⊔ S e ⊔ b -> no ⊔ S b S # x più lungo l ⊔ b -> no ⊔ S b S
Somma binaria senza overflow1 tracciafunzione · 2 nastri
Nelle tracce: LU22
La macchina deve sommare i numeri binari dell'input x;y, che devono avere la stessa lunghezza, e il risultato deve stare nello stesso numero di bit: è valido, mentre causa overflow. Con 2 nastri, copia sul secondo nastro e porta entrambe le testine sulle ultime cifre di e . Poi somma da destra verso sinistra scrivendo il risultato sul secondo nastro, e usa per «nessun riporto» e per «riporto 1».
Le testine devono raggiungere insieme ; sul primo nastro e sul secondo. Se le lunghezze sono diverse o resta un riporto, rifiuta; altrimenti termina in con la somma sul secondo nastro.
Con cifre e riporto , scrivi e porta 1 se . Per esempio : scrivi 0 e porta 1.
| Stato | letto₁ | letto₂ | nuovo stato | scritto₁, mossa₁ | scritto₂, mossa₂ | note |
|---|---|---|---|---|---|---|
| copia | ||||||
| copiato: la testina 2 aspetta qui | ||||||
| scorre | ||||||
| fine di : entrambe sull'ultima cifra | ||||||
| : scrive 0, riporto 1 | ||||||
| : il riporto si esaurisce | ||||||
| : scrive 1, riporto 1 | ||||||
| stessa lunghezza, nessun riporto: è sul 2° nastro | ||||||
| — | — | overflow | ||||
| o | — | — | più lungo | |||
| o | — | — | più lungo |
In tutti gli altri casi (per esempio se manca ";" o compare un simbolo diverso da 0 e 1) rigetta. La macchina è verificata con un simulatore su tutte le coppie fino a 5 bit ciascuno.
Traccia passo passo su 01;10 (1 + 2 = 3)
stato nastro 1 (x;y) nastro 2
s [▷] 0 1 ; 1 0 [▷]
s ▷ [0] 1 ; 1 0 ▷ [⊔] copio x
s ▷ 0 [1] ; 1 0 ▷ 0 [⊔] copio x
s ▷ 0 1 [;] 1 0 ▷ 0 1 [⊔] fine di x
m ▷ 0 1 ; [1] 0 ▷ 0 1 [⊔] scorro y, la testina 2 aspetta
m ▷ 0 1 ; 1 [0] ▷ 0 1 [⊔]
m ▷ 0 1 ; 1 0 [⊔] ▷ 0 1 [⊔] fine di y
c0 ▷ 0 1 ; 1 [0] ▷ 0 [1] ⊔ 0 + 1 = 1: scrivo 1
c0 ▷ 0 1 ; [1] 0 ▷ [0] 1 ⊔ 1 + 0 = 1: scrivo 1
c0 ▷ 0 1 [;] 1 0 [▷] 1 1 ⊔ arrivano insieme, nessun riporto
h sul nastro 2 resta 11
Traccia con overflow su 11;01 (3 + 1 = 4, che non sta in 2 cifre)
stato nastro 1 (x;y) nastro 2
... (copia di x e scorrimento di y come sopra)
c0 ▷ 1 1 ; 0 [1] ▷ 1 [1] ⊔ 1 + 1 = 10: scrivo 0, riporto 1
c1 ▷ 1 1 ; [0] 1 ▷ [1] 0 ⊔ 0 + 1 + 1 = 10: scrivo 0, riporto 1
c1 ▷ 1 1 [;] 0 1 [▷] 0 0 ⊔ arrivano insieme, ma con riporto
no overflow
La tabella nel file della soluzione non funziona
Ha tre errori. La prima riga, , porta subito nello stato del riporto invece di restare in , quindi la macchina rigetta tutto. Con il riporto, dovrebbe togliere il riporto (tornare allo stato senza riporto) e dovrebbe scrivere 1, non 0. Alla fine la testina 1 legge ";" e non , quindi le righe finali con non scattano mai. Inoltre una macchina che calcola una funzione termina in , non in yes.
Prova la soluzione
Prossima transizione: δ(s, ▷, ▷) = (s, ▷, →, ▷, →)
Mostra il codice della soluzione
s ▷ ▷ -> s ▷ R ▷ R s b ⊔ -> s b R b R # copia x s ; ⊔ -> m ; R ⊔ S # x copiato: la testina 2 aspetta qui m b ⊔ -> m b R ⊔ S # scorre y m ⊔ ⊔ -> c0 ⊔ L ⊔ L # fine di y: entrambe sull'ultima cifra c0 0 0 -> c0 0 L 0 L # 0 + 0 = 0 c0 0 1 -> c0 0 L 1 L # 0 + 1 = 1 c0 1 0 -> c0 1 L 1 L # 1 + 0 = 1 c0 1 1 -> c1 1 L 0 L # 1 + 1 = 10: scrive 0, riporto 1 c1 0 0 -> c0 0 L 1 L # 0 + 0 + 1 = 1: il riporto si esaurisce c1 0 1 -> c1 0 L 0 L # 0 + 1 + 1 = 10 c1 1 0 -> c1 1 L 0 L # 1 + 0 + 1 = 10 c1 1 1 -> c1 1 L 1 L # 1 + 1 + 1 = 11: scrive 1, riporto 1 c0 ; ▷ -> h ; S ▷ R # stessa lunghezza, nessun riporto: x + y è sul 2° nastro c1 ; ▷ -> no ; S ▷ S # overflow c0 ; b -> no ; S b S # x più lungo c1 ; b -> no ; S b S c0 b ▷ -> no b S ▷ S # y più lungo c1 b ▷ -> no b S ▷ S
Chiave assente dalla lista2 traccedecisione · 2 nastri
La macchina deve accettare se la chiave è diversa da tutti gli elementi della lista. Usa 2 nastri: copia la chiave sul secondo e, prima di ogni confronto, riporta la testina all'inizio della copia. Se chiave ed elemento hanno gli stessi bit e finiscono insieme, rifiuta. Se trovi bit diversi o lunghezze diverse, passa all'elemento successivo; se la lista finisce senza corrispondenze, accetta.
L'input ha il formato key,el1,el2,…,eln,, con la virgola obbligatoria anche dopo l'ultimo elemento, come in 01,1,011,.
| Stato | letto₁ | letto₂ | nuovo stato | scritto₁, mossa₁ | scritto₂, mossa₂ | note |
|---|---|---|---|---|---|---|
| copia key | ||||||
| fine di key | ||||||
| riavvolge il 2° nastro | ||||||
| pronto a confrontare | ||||||
| qualsiasi | — | — | lista finita (dopo l'ultima virgola) | |||
| finora uguali | ||||||
| oppure | (uguale), | cifre diverse, o elemento più lungo di key | ||||
| elemento più corto: diverso | ||||||
| — | — | elemento uguale a key | ||||
| qualsiasi | (uguale), | salta il resto dell'elemento | ||||
| qualsiasi | (uguale), | passa al prossimo elemento |
Nel formato della traccia la tabella è corretta (verificata con il simulatore).
Traccia passo passo su 01,00,01,
stato nastro 1 nastro 2
s [▷] 0 1 , 0 0 , 0 1 , [▷]
c ▷ [0] 1 , 0 0 , 0 1 , ▷ [⊔] copio key
c ▷ 0 [1] , 0 0 , 0 1 , ▷ 0 [⊔]
c ▷ 0 1 [,] 0 0 , 0 1 , ▷ 0 1 [⊔] fine di key
r ▷ 0 1 , [0] 0 , 0 1 , ▷ 0 [1] ⊔ riavvolgo il nastro 2
r ▷ 0 1 , [0] 0 , 0 1 , ▷ [0] 1 ⊔
r ▷ 0 1 , [0] 0 , 0 1 , [▷] 0 1 ⊔
m ▷ 0 1 , [0] 0 , 0 1 , ▷ [0] 1 ⊔ 0 = 0
m ▷ 0 1 , 0 [0] , 0 1 , ▷ 0 [1] ⊔ 0 ≠ 1: elemento diverso
k ▷ 0 1 , 0 0 [,] 0 1 , ▷ 0 [1] ⊔ virgola: prossimo elemento
r ▷ 0 1 , 0 0 , [0] 1 , ▷ [0] 1 ⊔ riavvolgo
r ▷ 0 1 , 0 0 , [0] 1 , [▷] 0 1 ⊔
m ▷ 0 1 , 0 0 , [0] 1 , ▷ [0] 1 ⊔ 0 = 0
m ▷ 0 1 , 0 0 , 0 [1] , ▷ 0 [1] ⊔ 1 = 1
m ▷ 0 1 , 0 0 , 0 1 [,] ▷ 0 1 [⊔] finiscono insieme: uguale a key
no
Con 01,1,, invece, l'elemento 1 differisce da 01 già alla prima cifra: la macchina salta alla virgola, riavvolge e all'inizio del nuovo elemento trova , quindi accetta.
La variante senza virgola finale
Su input senza la virgola finale, come 0,0, l'ultimo elemento finisce con e la tabella sbaglia: accetta 0,0 e rigetta 0,1. Per quel formato, al posto della riga "lista finita" servono tre righe:
- : l'ultimo elemento è uguale a key;
- : l'ultimo elemento è più corto, quindi diverso;
- : l'ultimo elemento era diverso.
All'esame vale la tabella principale, perché la traccia dice che la virgola finale fa parte dell'input. In quel formato la variante sbaglia con key vuota: rigetta ,0,.
Come nelle soluzioni della dispensa, l'input si assume ben formato. Per controllare anche il formato, aggiungi uno stato , "inizio di un elemento": va in invece che in , il simbolo porta a yes solo da , e per il resto si comporta come . Così e su rigettano (verificato con il simulatore).
Prova la soluzione
Prossima transizione: δ(s, ▷, ▷) = (c, ▷, →, ▷, →)
Mostra il codice della soluzione
s ▷ ▷ -> c ▷ R ▷ R c b ⊔ -> c b R b R # copia key c , ⊔ -> r , R ⊔ L # fine di key r σ b -> r σ S b L # riavvolge il 2° nastro r σ ▷ -> m σ S ▷ R # pronto a confrontare m ⊔ σ -> yes ⊔ S σ S # lista finita (dopo l'ultima virgola) m b b -> m b R b R # finora uguali m b b̄ -> k b R b̄ S # cifre diverse m b ⊔ -> k b R ⊔ S # elemento più lungo di key m , b -> r , R b L # elemento più corto: diverso m , ⊔ -> no , S ⊔ S # elemento uguale a key k b σ -> k b R σ S # salta il resto dell'elemento k , σ -> r , R σ L # passa al prossimo elemento
SAT-UNSAT con un oracolo SAT4 traccedecisione · 2 nastri · oracolo SAT
Nelle tracce: F08, G16, E26, ND
La macchina deve accettare x;y se è soddisfacibile e non lo è. Copia sul nastro di query e interroga l'oracolo: se risponde no, rifiuta. Se risponde sì, cancella la query, copia e interroga di nuovo l'oracolo; accetta solo se questa volta risponde no.
L'oracolo SAT risponde in un passo alla domanda «questa formula è soddisfacibile?». La macchina scrive la formula sul secondo nastro ed entra in , e la risposta la porta in o senza spostare le testine.
Bastano due chiamate, quindi . Nella tabella indica un simbolo della formula, esclusi ;, e .
| Stato | letto₁ | letto₂ | nuovo stato | scritto₁, mossa₁ | scritto₂, mossa₂ | note |
|---|---|---|---|---|---|---|
| copia | ||||||
| "?" | ||||||
| insoddisfacibile | ||||||
| soddisfacibile: si passa a | ||||||
| cancella la query | ||||||
| query cancellata | ||||||
| copia | ||||||
| "?" | ||||||
| soddisfacibile | ||||||
| sì, no |
In tutti gli altri casi rigetta. La tabella è quella della dispensa, con al posto della sua per non confonderla con la formula . Le due chiamate si distinguono dal simbolo sul 1° nastro: dopo la prima la testina 1 è su ";", dopo la seconda è su .
Traccia per fasi, con soddisfacibile e no:
fase nastro 1 (input) nastro 2 (query) stato
copia x ▷ x [;] y ▷ x [⊔] s → q?
1ª domanda ▷ x [;] y ▷ x [⊔] q? → qYES (x è soddisfacibile)
cancella la query ▷ x [;] y [▷] ⊔ ⊔ r → a
copia y ▷ x ; y [⊔] ▷ y [⊔] a → q?
2ª domanda ▷ x ; y [⊔] ▷ y [⊔] q? → qNO (y non lo è)
fine yes
In generale, per la domanda 8 scrivi l'idea in due righe, poi la tabella : uno stato per ogni cosa da ricordare, le righe per i casi limite (, stringa vuota, overflow) e "in tutti gli altri casi rigetta". Sui numeri binari si lavora da destra, dopo il blocco "vai in fondo"; con più nastri si copia una parte dell'input sul 2° nastro e la si confronta. Prima di consegnare, simula la macchina riga per riga su un input piccolo.
Prova la soluzione
Prossima transizione: δ(s, ▷, ▷) = (s, ▷, →, ▷, →)
Mostra il codice della soluzione
s ▷ ▷ -> s ▷ R ▷ R s σ ⊔ -> s σ R σ R # copia x s ; ⊔ -> q? ; S ⊔ S # "x ∈ SAT?" s ⊔ ⊔ -> no ⊔ S ⊔ S # manca ";" (qui σ non comprende ⊔) qNO ; ⊔ -> no ; S ⊔ S # x insoddisfacibile qYES ; ⊔ -> r ; S ⊔ L # x soddisfacibile: si passa a y r ; σ -> r ; S ⊔ L # cancella la query r ; ▷ -> a ; R ▷ R # query cancellata a σ ⊔ -> a σ R σ R # copia y a ⊔ ⊔ -> q? ⊔ S ⊔ S # "y ∈ SAT?" qYES ⊔ ⊔ -> no ⊔ S ⊔ S # y soddisfacibile qNO ⊔ ⊔ -> yes ⊔ S ⊔ S # x sì, y no
INDEPENDENT SET con un oracolo CLIQUE1 tracciadecisione · 2 nastri · oracolo CLIQUE
Nelle tracce: SP
La macchina deve decidere se un grafo ha un insieme di almeno nodi senza archi tra loro, usando un oracolo CLIQUE. Copia la matrice sul nastro di query invertendo 0 e 1, poi copia senza modificarlo e interroga l'oracolo. Basta una domanda: «il complemento ha una cricca di almeno nodi?».
Funziona perché un insieme indipendente in è una cricca nel grafo complemento , che tra nodi distinti ha un arco dove prima non c'era.
Nell'input scrivi la matrice di adiacenza con , tra gli elementi e ; tra le righe, poi : e in binario.
Per esempio, nel cammino in cui 2 è collegato sia a 1 sia a 3, i nodi 1 e 3 non sono collegati. Nel complemento formano una cricca, quindi con l'oracolo risponde sì. La diagonale non influenza il test, come spiegato sotto.
| Stato | letto₁ | letto₂ | nuovo stato | scritto₁, mossa₁ | scritto₂, mossa₂ | note |
|---|---|---|---|---|---|---|
| inverte il bit: c'è un arco in | ||||||
| inverte il bit: niente arco in | ||||||
| copia il separatore | ||||||
| copia il separatore | ||||||
| fine della matrice | ||||||
| copia senza cambiarlo | ||||||
| " ha una cricca di almeno nodi?" | ||||||
| c'è un independent set di almeno nodi | ||||||
| non c'è |
In tutti gli altri casi (per esempio se manca ":") rigetta. La macchina è verificata con un simulatore, usando un oracolo simulato, su tutti i grafi fino a 4 nodi e su tutte le soglie da 0 a 5.
Traccia per fasi sull'esempio:
fase nastro 1 (input) nastro 2 (query) stato
inverte la matrice ▷ 0,1,0;1,0,1;0,1,0 [:] 10 ▷ 1,0,1;0,1,0;1,0,1 [⊔] s → k
copia K ▷ 0,1,0;1,0,1;0,1,0:10 [⊔] ▷ 1,0,1;0,1,0;1,0,1:10 [⊔] k → q?
domanda "il complemento ha una cricca di 2 nodi?" sì, {1, 3} q? → qYES
fine yes
E la diagonale della matrice?
Invertendo tutte le celle, anche la diagonale passa da 0 a 1, come se ogni nodo fosse collegato a sé stesso. La risposta non cambia: una cricca chiede archi tra nodi distinti, quindi l'oracolo non guarda la diagonale (lo assumiamo, come è naturale). Per lasciarla a 0 bisognerebbe contare riga e colonna con due contatori in binario, cioè aggiungere stati senza nessuna idea nuova.
La macchina fa una passata sull'input e una sola domanda all'oracolo, quindi lavora in tempo polinomiale e INDEPENDENT SET sta in . Non sorprende, perché la traduzione "prendi il complemento del grafo" è la riduzione da INDEPENDENT SET a CLIQUE: qui la macchina la calcola e passa il risultato all'oracolo.
Prova la soluzione
Prossima transizione: δ(s, ▷, ▷) = (s, ▷, →, ▷, →)
Mostra il codice della soluzione
s ▷ ▷ -> s ▷ R ▷ R s 0 ⊔ -> s 0 R 1 R # inverte il bit: c'è un arco nel complemento s 1 ⊔ -> s 1 R 0 R # inverte il bit: niente arco nel complemento s , ⊔ -> s , R , R # copia il separatore s ; ⊔ -> s ; R ; R s : ⊔ -> k : R : R # fine della matrice k b ⊔ -> k b R b R # copia K senza cambiarlo k ⊔ ⊔ -> q? ⊔ S ⊔ S # "il complemento ha una cricca di almeno K nodi?" qYES ⊔ ⊔ -> yes ⊔ S ⊔ S # c'è un independent set di almeno K nodi qNO ⊔ ⊔ -> no ⊔ S ⊔ S # non c'è