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 δ\delta. 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)

▹\triangleright segna l'inizio del nastro e ⊔\sqcup è una cella vuota. La testina parte su ▹\triangleright, nello stato ss.

Come leggere una transizione

La macchina si descrive con M=(K,Σ,δ,s)M=(K,\Sigma,\delta,s): stati, alfabeto, transizioni e stato iniziale.

La regola δ(p,σ)=(q,ρ,D)\delta(p,\sigma)=(q,\rho,D) si legge così: nello stato pp, se leggi σ\sigma, scrivi ρ\rho, sposta la testina in direzione DD e passa nello stato qq. Le direzioni sono ←\leftarrow (sinistra), →\rightarrow (destra) e −- (testina ferma). Su ▹\triangleright riscrivi sempre ▹\triangleright e vai a destra.

Una macchina che calcola una funzione termina in hh 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 bb è un bit qualsiasi, bˉ\bar b il suo opposto e σ\sigma un simbolo qualsiasi. Se a destra riscrivi bb o σ\sigma, la cella resta com'era.

Dall'idea alla tabella in quattro passi

  1. Prima di scegliere gli stati, scrivi in due righe che cosa farà la macchina.
  2. Dai uno stato a ogni informazione da ricordare: un bit, un riporto, la fase del calcolo.
  3. Controlla i casi limite: input vuoto, overflow, testina che torna all'inizio del nastro.
  4. 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.

ppσ\sigmaδ(p,σ)\delta(p, \sigma)
ss▹\triangleright(s,▹,→)(s, \triangleright, \rightarrow)
ssbb(s,b,→)(s, b, \rightarrow)
ss⊔\sqcup(q,⊔,←)(q, \sqcup, \leftarrow): 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, δ(q,1)=(q,0,←)\delta(q, 1) = (q, 0, \leftarrow).

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 111+1=1000111 + 1 = 1000.

ppσ\sigmaδ(p,σ)\delta(p, \sigma)commento
ss⊔\sqcup(q,⊔,←)(q, \sqcup, \leftarrow)fine input, inizia il riporto
qq11(q,0,←)(q, 0, \leftarrow)1+riporto=01 + \text{riporto} = 0, il riporto continua
qq00(h,1,−)(h, 1, -)riporto assorbito, fine
qq▹\triangleright(o,▹,→)(o, \triangleright, \rightarrow)overflow
oo00(o′,1,→)(o', 1, \rightarrow)la prima cifra diventa 1
o′o'00(o′,0,→)(o', 0, \rightarrow)scorre le altre cifre
o′o'⊔\sqcup(h,0,−)(h, 0, -)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 (q,w,u)(q, w, u) descrive un istante: qq è lo stato, ww è ciò che sta a sinistra della testina, compreso il simbolo letto, e uu è ciò che sta a destra. Per esempio (q,▹1,0⊔)(q, \triangleright 1, 0\sqcup) vuol dire che la macchina è nello stato qq, la testina legge l'1 e a destra ci sono 0⊔0\sqcup.

(s,▹,11)→∗(q,▹11,⊔)→(q,▹1,0⊔)→(q,▹,00⊔)→(o,▹0,0⊔)→(o′,▹10,⊔)→(o′,▹10⊔,ε)→(h,▹100,ε) (s, \triangleright, 11) \to^* (q, \triangleright 11, \sqcup) \to (q, \triangleright 1, 0\sqcup) \to (q, \triangleright, 00\sqcup) \to (o, \triangleright 0, 0\sqcup) \to (o', \triangleright 10, \sqcup) \to (o', \triangleright 10\sqcup, \varepsilon) \to (h, \triangleright 100, \varepsilon)

Il simbolo →∗\to^* vuol dire "in zero o più passi" (qui i passi di "vai in fondo") e ε\varepsilon è la stringa vuota. L'output è 100 ✔.

Nella tabella sono sottintese le righe del blocco «vai in fondo»: δ(s,▹)=(s,▹,→)\delta(s, \triangleright) = (s, \triangleright, \rightarrow) e δ(s,b)=(s,b,→)\delta(s, b) = (s, b, \rightarrow). La macchina va in fondo all'input e, sulla prima cella vuota, comincia la parte propria di ogni esercizio.

Prova la soluzione

Nastro
▷1011⊔⊔⊔
Stato sPasso 0

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 hh. Aggiungere uno 0 a destra equivale a moltiplicare per 2: 101→1010101 \to 1010, cioè 5→105 \to 10.

ppσ\sigmaδ(p,σ)\delta(p, \sigma)
ss⊔\sqcup(h,0,−)(h, 0, -)

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»: δ(s,▹)=(s,▹,→)\delta(s, \triangleright) = (s, \triangleright, \rightarrow) e δ(s,b)=(s,b,→)\delta(s, b) = (s, b, \rightarrow). La macchina va in fondo all'input e, sulla prima cella vuota, comincia la parte propria di ogni esercizio.

Prova la soluzione

Nastro
▷101⊔⊔⊔⊔
Stato sPasso 0

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 101→10100101 \to 10100, cioè 5⋅4=205 \cdot 4 = 20.

La testina parte su ▹\triangleright. La macchina termina in hh e lascia il risultato sul nastro. Nella tabella bb indica un bit qualsiasi e ⊔\sqcup una cella vuota.

ppσ\sigmaδ(p,σ)\delta(p, \sigma)commento
ss▹\triangleright(s,▹,→)(s, \triangleright, \rightarrow)supera l'inizio del nastro
ssbb(s,b,→)(s, b, \rightarrow)scorre l'input fino in fondo
ss⊔\sqcup(q,0,→)(q, 0, \rightarrow)fine input: scrive il primo 0
qq⊔\sqcup(h,0,−)(h, 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

Nastro
▷101⊔⊔⊔⊔
Stato sPasso 0

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

Nelle tracce: F05, F07

La macchina deve calcolare la divisione intera per 2, scartando il resto. Per farlo cancella l'ultima cifra: 101→10101 \to 10, cioè 5:2=25 : 2 = 2 con resto 1.

Se l'input ha una sola cifra, scrivi 0, perché il risultato non deve essere un nastro vuoto.

ppσ\sigmaδ(p,σ)\delta(p, \sigma)commento
ss⊔\sqcup(q,⊔,←)(q, \sqcup, \leftarrow)fine input
qqbb(r,⊔,←)(r, \sqcup, \leftarrow)cancella l'ultima cifra
rrbb(h,b,−)(h, b, -)è rimasta almeno una cifra
rr▹\triangleright(z,▹,→)(z, \triangleright, \rightarrow)non è rimasto niente…
zz⊔\sqcup(h,0,−)(h, 0, -)…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»: δ(s,▹)=(s,▹,→)\delta(s, \triangleright) = (s, \triangleright, \rightarrow) e δ(s,b)=(s,b,→)\delta(s, b) = (s, b, \rightarrow). La macchina va in fondo all'input e, sulla prima cella vuota, comincia la parte propria di ogni esercizio.

Prova la soluzione

Nastro
▷101⊔⊔⊔⊔
Stato sPasso 0

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: 10110→10110110 \to 101, cioè 22:4=522 : 4 = 5 con resto 2.

Se l'input ha una o due cifre, scrivi 0 invece di lasciare il nastro vuoto.

La macchina termina in hh. Nella tabella bb indica un bit qualsiasi e ⊔\sqcup una cella vuota.

ppσ\sigmaδ(p,σ)\delta(p, \sigma)commento
ss▹\triangleright(s,▹,→)(s, \triangleright, \rightarrow)supera l'inizio del nastro
ssbb(s,b,→)(s, b, \rightarrow)scorre l'input fino in fondo
ss⊔\sqcup(q,⊔,←)(q, \sqcup, \leftarrow)fine input, torna sull'ultima cifra
qqbb(r,⊔,←)(r, \sqcup, \leftarrow)cancella l'ultima cifra
rrbb(t,⊔,←)(t, \sqcup, \leftarrow)cancella la penultima cifra
rr▹\triangleright(z,▹,→)(z, \triangleright, \rightarrow)l'input aveva una sola cifra
ttbb(h,b,−)(h, b, -)è rimasta almeno una cifra: fine
tt▹\triangleright(z,▹,→)(z, \triangleright, \rightarrow)non è rimasto niente…
zz⊔\sqcup(h,0,−)(h, 0, -)…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 ▹\triangleright già nello stato rr e scrive 0 allo stesso modo. La macchina è stata verificata con un simulatore su tutti gli input fino a 8 bit.

Prova la soluzione

Nastro
▷10110⊔⊔
Stato sPasso 0

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 c0c_0 o c1c_1, cancella il numero tornando a sinistra e poi scrivi la cifra ricordata nella prima cella.

Nella tabella ii vale 0 o 1: le righe con cic_i e wiw_i descrivono entrambi i casi.

ppσ\sigmaδ(p,σ)\delta(p, \sigma)commento
ss⊔\sqcup(q,⊔,←)(q, \sqcup, \leftarrow)fine input
qq00(c0,⊔,←)(c_0, \sqcup, \leftarrow)ricorda 0
qq11(c1,⊔,←)(c_1, \sqcup, \leftarrow)ricorda 1
cic_ibb(ci,⊔,←)(c_i, \sqcup, \leftarrow)cancella le altre cifre
cic_i▹\triangleright(wi,▹,→)(w_i, \triangleright, \rightarrow)inizio del nastro
wiw_i⊔\sqcup(h,i,−)(h, i, -)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 (q,0)→yes(q, 0) \to \text{yes} e (q,1)→no(q, 1) \to \text{no}.

Nella tabella sono sottintese le righe del blocco «vai in fondo»: δ(s,▹)=(s,▹,→)\delta(s, \triangleright) = (s, \triangleright, \rightarrow) e δ(s,b)=(s,b,→)\delta(s, b) = (s, b, \rightarrow). La macchina va in fondo all'input e, sulla prima cella vuota, comincia la parte propria di ogni esercizio.

Prova la soluzione

Nastro
▷101⊔⊔⊔⊔
Stato sPasso 0

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 −x-x 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.

ppσ\sigmaδ(p,σ)\delta(p, \sigma)commento
ss⊔\sqcup(c,⊔,←)(c, \sqcup, \leftarrow)fine input
cc00(c,0,←)(c, 0, \leftarrow)copia gli 0 finali
cc11(i,1,←)(i, 1, \leftarrow)copia il primo 1, poi inverte
cc▹\triangleright(h,▹,→)(h, \triangleright, \rightarrow)x=0x = 0, quindi −x=0-x = 0
ii00(i,1,←)(i, 1, \leftarrow)inverte
ii11(i,0,←)(i, 0, \leftarrow)inverte
ii▹\triangleright(h,▹,→)(h, \triangleright, \rightarrow)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 x=10…0x = 10\dots0, il numero più negativo, la macchina restituisce xx stesso, perché −x-x non si può scrivere con lo stesso numero di bit.

Nella tabella sono sottintese le righe del blocco «vai in fondo»: δ(s,▹)=(s,▹,→)\delta(s, \triangleright) = (s, \triangleright, \rightarrow) e δ(s,b)=(s,b,→)\delta(s, b) = (s, b, \rightarrow). La macchina va in fondo all'input e, sulla prima cella vuota, comincia la parte propria di ogni esercizio.

Prova la soluzione

Nastro
▷0110⊔⊔⊔
Stato sPasso 0

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».

ppσ\sigmaδ(p,σ)\delta(p, \sigma)commento
ss▹\triangleright(s,▹,→)(s, \triangleright, \rightarrow)
ss00(a,0,→)(a, 0, \rightarrow)segno positivo
ss11(no,1,−)(\text{no}, 1, -)negativo
ss⊔\sqcup(no,⊔,−)(\text{no}, \sqcup, -)stringa vuota
aabb(a,b,→)(a, b, \rightarrow)va in fondo
aa⊔\sqcup(t,⊔,←)(t, \sqcup, \leftarrow)torna sull'ultimo bit
tt11(yes,1,−)(\text{yes}, 1, -)dispari
tt00(no,0,−)(\text{no}, 0, -)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

Nastro
▷011⊔⊔⊔⊔
Stato sPasso 0

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è xi≠xn+1−ix_i \neq x_{n+1-i}. Con 2 nastri, scegli in modo nondeterministico una posizione ii dell'input e, per ogni cifra che salti, scrivi una tacca I sul secondo nastro: alla fine hai i−1i-1 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.

Statoletto₁letto₂nuovo statoscritto₁, mossa₁scritto₂, mossa₂note
ss▹\triangleright▹\trianglerightss▹,→\triangleright, \rightarrow▹,→\triangleright, \rightarrow
ssaa⊔\sqcupssa,→a, \rightarrowI,→I, \rightarrowscelta 1: salta la cifra aa
ssaa⊔\sqcupgag_aa,→a, \rightarrow⊔,−\sqcup, -scelta 2: confronta aa (ricordata nello stato)
ss⊔\sqcup⊔\sqcupno\text{no}⊔,−\sqcup, -⊔,−\sqcup, -nessuna cifra scelta
gag_abb⊔\sqcupgag_ab,→b, \rightarrow⊔,−\sqcup, -va in fondo
gag_a⊔\sqcup⊔\sqcupcac_a⊔,←\sqcup, \leftarrow⊔,←\sqcup, \leftarrowtorna indietro su entrambi
cac_abbIIcac_ab,←b, \leftarrowI,←I, \leftarrowconsuma una tacca per passo
cac_ab≠ab \neq a▹\trianglerightyes\text{yes}b,−b, -▹,→\triangleright, \rightarrowcifre simmetriche diverse
cac_ab=ab = a▹\trianglerightno\text{no}b,−b, -▹,→\triangleright, \rightarrowquesto ramo rigetta

Qui a∈{0,1}a \in \{0, 1\}, quindi gag_a e cac_a corrispondono a 2 + 2 stati. La macchina accetta xx se almeno un ramo accetta, cioè se esiste una coppia di cifre simmetriche diverse; se xx è palindroma, tutti i rami rigettano.

Il ramo che sceglie la posizione ii fa n+i+2n + i + 2 passi: ii per arrivare alla cifra scelta, n−in - i per arrivare in fondo, i−1i - 1 per tornare indietro consumando le tacche, più qualche passo di servizio. Ogni ramo si ferma quindi entro 2n+22n + 2 passi, cioè il "tempo 2n2n" 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 i=1i = 1 non scrive tacche: dal fondo torna indietro di una sola cella, si trova su x3=0x_3 = 0, lo confronta con a=x1=1a = x_1 = 1 e accetta anche lui. Il ramo i=2i = 2 confronta la cifra centrale con se stessa e rigetta.

Prova la soluzione

Nastro 1
▷100⊔⊔⊔⊔
Nastro 2
▷⊔⊔⊔⊔⊔⊔⊔
Stato sPasso 0

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 ⊔\sqcup sul primo nastro e ▹\triangleright sul secondo.

Statoletto₁letto₂nuovo statoscritto₁, mossa₁scritto₂, mossa₂note
ss▹\triangleright▹\trianglerightss▹,→\triangleright, \rightarrow▹,→\triangleright, \rightarrow
ssbb⊔\sqcupssb,→b, \rightarrowb,→b, \rightarrowscelta 1: copia bb, la prima metà continua
ssbb⊔\sqcupmmb,→b, \rightarrow⊔,←\sqcup, \leftarrowscelta 2: bb è il centro (lunghezza dispari), lo salta
ssbb⊔\sqcupmmb,−b, -⊔,←\sqcup, \leftarrowscelta 3: la prima metà finisce prima di bb (lunghezza pari)
ss⊔\sqcup⊔\sqcupmm⊔,−\sqcup, -⊔,←\sqcup, \leftarrowfine dell'input senza scelte: accetta solo la stringa vuota
mmbbbbmmb,→b, \rightarrowb,←b, \leftarrowcifre simmetriche uguali
mm⊔\sqcup▹\trianglerightyes\text{yes}⊔,−\sqcup, -▹,→\triangleright, \rightarrowfinite 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à). bb è un bit qualsiasi, riscritto uguale.

La macchina accetta se almeno un ramo accetta. Se xx è 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 n+3n + 3 passi, mentre la macchina deterministica del file (sotto) ne fa 3n+43n + 4. È 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 ⊔\sqcup e trova sul 2° nastro una cifra invece di ▹\triangleright.

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

Nastro 1
▷101⊔⊔⊔⊔
Nastro 2
▷⊔⊔⊔⊔⊔⊔⊔
Stato sPasso 0

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

Nelle tracce: F12, G17

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 ss), poi riporta la prima testina all'inizio e lascia la seconda in fondo alla copia (stato rr). Infine confronta l'originale da sinistra con la copia da destra (stato cc): alla prima differenza rifiuta, mentre se tutti i bit coincidono e le due letture terminano insieme accetta.

Statoletto₁letto₂nuovo statoscritto₁, mossa₁scritto₂, mossa₂note
ss▹\triangleright▹\trianglerightss▹,→\triangleright, \rightarrow▹,→\triangleright, \rightarrow
ssbb⊔\sqcupssb,→b, \rightarrowb,→b, \rightarrowcopia l'input
ss⊔\sqcup⊔\sqcuprr⊔,←\sqcup, \leftarrow⊔,−\sqcup, -fine dell'input: la testina 2 resta dopo la copia
rrbb⊔\sqcuprrb,←b, \leftarrow⊔,−\sqcup, -riavvolge il 1° nastro
rr▹\triangleright⊔\sqcupcc▹,→\triangleright, \rightarrow⊔,←\sqcup, \leftarrowtestina 1 sulla prima cifra, testina 2 sull'ultima
ccbbbbccb,→b, \rightarrowb,←b, \leftarrowcifre simmetriche uguali
ccbbbˉ\bar bno\text{no}b,−b, -bˉ,−\bar b, -cifre simmetriche diverse
cc⊔\sqcup▹\trianglerightyes\text{yes}⊔,−\sqcup, -▹,→\triangleright, \rightarrowfinite insieme: palindroma

In tutti gli altri casi rigetta. bb è un bit qualsiasi, riscritto uguale, e bˉ\bar b è il bit opposto. È la macchina della soluzione del file, ricontrollata: fa 3n+43n + 4 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 n+3n + 3 passi invece di 3n+43n + 4.

Prova la soluzione

Nastro 1
▷010⊔⊔⊔⊔
Nastro 2
▷⊔⊔⊔⊔⊔⊔⊔
Stato sPasso 0

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 x≤yx \le y. Con 2 nastri, copia xx sul secondo nastro, riporta la testina all'inizio e confronta xx e yy da sinistra: la prima coppia di bit diversi decide quale numero è maggiore.

Lo stato ee significa «finora uguali», lo stato ll significa «xx è già minore». Le testine devono arrivare insieme alla fine dei due numeri: se le lunghezze sono diverse, la macchina rifiuta.

Statoletto₁ (yy)letto₂ (xx)nuovo statoscritto₁, mossa₁scritto₂, mossa₂note
ss▹\triangleright▹\trianglerightss▹,→\triangleright, \rightarrow▹,→\triangleright, \rightarrow
ssbb⊔\sqcupssb,→b, \rightarrowb,→b, \rightarrowcopia xx
ss;;⊔\sqcuprr;,→;, \rightarrow⊔,←\sqcup, \leftarrowtestina 1 sulla prima cifra di yy
rrσ\sigmabbrrσ,−\sigma, -b,←b, \leftarrowriavvolge il 2° nastro
rrσ\sigma▹\trianglerighteeσ,−\sigma, -▹,→\triangleright, \rightarrowpronto a confrontare
eebbbbeeb,→b, \rightarrowb,→b, \rightarrowcifre uguali
ee1100ll1,→1, \rightarrow0,→0, \rightarrowxx minore di yy
ee0011no\text{no}0,−0, -1,−1, -xx maggiore di yy
llbbb′b'llb,→b, \rightarrowb′,→b', \rightarrowormai conta solo la lunghezza (b′b' è un altro bit qualsiasi)
ee o ll⊔\sqcup⊔\sqcupyes\text{yes}⊔,−\sqcup, -⊔,−\sqcup, -stessa lunghezza e x≤yx \le y
ee o llbb⊔\sqcupno\text{no}——yy più lungo
ee o ll⊔\sqcupbbno\text{no}——xx 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

Nastro 1
▷01;10⊔⊔
Nastro 2
▷⊔⊔⊔⊔⊔⊔⊔
Stato sPasso 0

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: 01+10=1101+10=11 è valido, mentre 11+01=10011+01=100 causa overflow. Con 2 nastri, copia xx sul secondo nastro e porta entrambe le testine sulle ultime cifre di xx e yy. Poi somma da destra verso sinistra scrivendo il risultato sul secondo nastro, e usa c0c_0 per «nessun riporto» e c1c_1 per «riporto 1».

Le testine devono raggiungere insieme ; sul primo nastro e ▹\triangleright sul secondo. Se le lunghezze sono diverse o resta un riporto, rifiuta; altrimenti termina in hh con la somma sul secondo nastro.

Con cifre a,ba,b e riporto rr, scrivi (a+b+r) mod 2(a+b+r)\bmod2 e porta 1 se a+b+r≥2a+b+r\ge2. Per esempio 1+1+0=101+1+0=10: scrivi 0 e porta 1.

Statoletto₁letto₂nuovo statoscritto₁, mossa₁scritto₂, mossa₂note
ss▹\triangleright▹\trianglerightss▹,→\triangleright, \rightarrow▹,→\triangleright, \rightarrow
ssbb⊔\sqcupssb,→b, \rightarrowb,→b, \rightarrowcopia xx
ss;;⊔\sqcupmm;,→;, \rightarrow⊔,−\sqcup, -xx copiato: la testina 2 aspetta qui
mmbb⊔\sqcupmmb,→b, \rightarrow⊔,−\sqcup, -scorre yy
mm⊔\sqcup⊔\sqcupc0c_0⊔,←\sqcup, \leftarrow⊔,←\sqcup, \leftarrowfine di yy: entrambe sull'ultima cifra
c0c_00000c0c_00,←0, \leftarrow0,←0, \leftarrow0+0=00 + 0 = 0
c0c_00011c0c_00,←0, \leftarrow1,←1, \leftarrow0+1=10 + 1 = 1
c0c_01100c0c_01,←1, \leftarrow1,←1, \leftarrow1+0=11 + 0 = 1
c0c_01111c1c_11,←1, \leftarrow0,←0, \leftarrow1+1=101 + 1 = 10: scrive 0, riporto 1
c1c_10000c0c_00,←0, \leftarrow1,←1, \leftarrow0+0+1=10 + 0 + 1 = 1: il riporto si esaurisce
c1c_10011c1c_10,←0, \leftarrow0,←0, \leftarrow0+1+1=100 + 1 + 1 = 10
c1c_11100c1c_11,←1, \leftarrow0,←0, \leftarrow1+0+1=101 + 0 + 1 = 10
c1c_11111c1c_11,←1, \leftarrow1,←1, \leftarrow1+1+1=111 + 1 + 1 = 11: scrive 1, riporto 1
c0c_0;;▹\trianglerighthh;,−;, -▹,→\triangleright, \rightarrowstessa lunghezza, nessun riporto: x+yx + y è sul 2° nastro
c1c_1;;▹\trianglerightno\text{no}——overflow
c0c_0 o c1c_1;;bbno\text{no}——xx più lungo
c0c_0 o c1c_1bb▹\trianglerightno\text{no}——yy 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 x;yx;y 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, δ(s,▹,▹)\delta(s, \triangleright, \triangleright), porta subito nello stato del riporto invece di restare in ss, quindi la macchina rigetta tutto. Con il riporto, 0+0+10 + 0 + 1 dovrebbe togliere il riporto (tornare allo stato senza riporto) e 1+1+11 + 1 + 1 dovrebbe scrivere 1, non 0. Alla fine la testina 1 legge ";" e non ▹\triangleright, quindi le righe finali con (▹,▹)(\triangleright, \triangleright) non scattano mai. Inoltre una macchina che calcola una funzione termina in hh, non in yes.

Prova la soluzione

Nastro 1
▷01;10⊔⊔
Nastro 2
▷⊔⊔⊔⊔⊔⊔⊔
Stato sPasso 0

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

Nelle tracce: SE23, LU24

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,.

Statoletto₁letto₂nuovo statoscritto₁, mossa₁scritto₂, mossa₂note
ss▹\triangleright▹\trianglerightcc▹,→\triangleright, \rightarrow▹,→\triangleright, \rightarrow
ccbb⊔\sqcupccb,→b, \rightarrowb,→b, \rightarrowcopia key
cc,,⊔\sqcuprr,,→,, \rightarrow⊔,←\sqcup, \leftarrowfine di key
rrσ\sigmabbrrσ,−\sigma, -b,←b, \leftarrowriavvolge il 2° nastro
rrσ\sigma▹\trianglerightmmσ,−\sigma, -▹,→\triangleright, \rightarrowpronto a confrontare
mm⊔\sqcupqualsiasiyes\text{yes}——lista finita (dopo l'ultima virgola)
mmbbbbmmb,→b, \rightarrowb,→b, \rightarrowfinora uguali
mmbbbˉ\bar{b} oppure ⊔\sqcupkkb,→b, \rightarrow(uguale), −-cifre diverse, o elemento più lungo di key
mm,,bbrr,,→,, \rightarrowb,←b, \leftarrowelemento più corto: diverso
mm,,⊔\sqcupno\text{no}——elemento uguale a key
kkbbqualsiasikkb,→b, \rightarrow(uguale), −-salta il resto dell'elemento
kk,,qualsiasirr,,→,, \rightarrow(uguale), ←\leftarrowpassa 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 ⊔\sqcup, quindi accetta.

La variante senza virgola finale

Su input senza la virgola finale, come 0,0, l'ultimo elemento finisce con ⊔\sqcup e la tabella sbaglia: accetta 0,0 e rigetta 0,1. Per quel formato, al posto della riga "lista finita" servono tre righe:

  • (m,⊔,⊔)→no(m, \sqcup, \sqcup) \to \text{no}: l'ultimo elemento è uguale a key;
  • (m,⊔,b)→yes(m, \sqcup, b) \to \text{yes}: l'ultimo elemento è più corto, quindi diverso;
  • (k,⊔,qualsiasi)→yes(k, \sqcup, \text{qualsiasi}) \to \text{yes}: 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 ii, "inizio di un elemento": rr va in ii invece che in mm, il simbolo ⊔\sqcup porta a yes solo da ii, e per il resto ii si comporta come mm. Così mm e kk su ⊔\sqcup rigettano (verificato con il simulatore).

Prova la soluzione

Nastro 1
▷01,00,01,⊔⊔
Nastro 2
▷⊔⊔⊔⊔⊔⊔⊔
Stato sPasso 0

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 xx è soddisfacibile e yy non lo è. Copia xx sul nastro di query e interroga l'oracolo: se risponde no, rifiuta. Se risponde sì, cancella la query, copia yy 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 q?q_?, e la risposta la porta in qYESq_{\text{YES}} o qNOq_{\text{NO}} senza spostare le testine.

Bastano due chiamate, quindi SAT-UNSAT∈PSAT\mathrm{SAT\text{-}UNSAT} \in \mathrm{P}^{\mathrm{SAT}}. Nella tabella σ\sigma indica un simbolo della formula, esclusi ;, ⊔\sqcup e ▹\triangleright.

Statoletto₁letto₂nuovo statoscritto₁, mossa₁scritto₂, mossa₂note
ss▹\triangleright▹\trianglerightss▹,→\triangleright, \rightarrow▹,→\triangleright, \rightarrow
ssσ\sigma⊔\sqcupssσ,→\sigma, \rightarrowσ,→\sigma, \rightarrowcopia xx
ss;;⊔\sqcupq?q_?;,−;, -⊔,−\sqcup, -"x∈SATx \in \mathrm{SAT}?"
qNOq_{\text{NO}};;⊔\sqcupno\text{no};,−;, -⊔,−\sqcup, -xx insoddisfacibile
qYESq_{\text{YES}};;⊔\sqcuprr;,−;, -⊔,←\sqcup, \leftarrowxx soddisfacibile: si passa a yy
rr;;σ\sigmarr;,−;, -⊔,←\sqcup, \leftarrowcancella la query
rr;;▹\trianglerightaa;,→;, \rightarrow▹,→\triangleright, \rightarrowquery cancellata
aaσ\sigma⊔\sqcupaaσ,→\sigma, \rightarrowσ,→\sigma, \rightarrowcopia yy
aa⊔\sqcup⊔\sqcupq?q_?⊔,−\sqcup, -⊔,−\sqcup, -"y∈SATy \in \mathrm{SAT}?"
qYESq_{\text{YES}}⊔\sqcup⊔\sqcupno\text{no}⊔,−\sqcup, -⊔,−\sqcup, -yy soddisfacibile
qNOq_{\text{NO}}⊔\sqcup⊔\sqcupyes\text{yes}⊔,−\sqcup, -⊔,−\sqcup, -xx sì, yy no

In tutti gli altri casi rigetta. La tabella è quella della dispensa, con σ\sigma al posto della sua xx per non confonderla con la formula xx. Le due chiamate si distinguono dal simbolo sul 1° nastro: dopo la prima la testina 1 è su ";", dopo la seconda è su ⊔\sqcup.

Traccia per fasi, con xx soddisfacibile e yy 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 δ\delta: uno stato per ogni cosa da ricordare, le righe per i casi limite (▹\triangleright, 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

Nastro 1
▷(x|y)&!x;x&!x⊔⊔
Nastro 2 (query)
▷⊔⊔⊔⊔⊔⊔⊔
Stato sPasso 0

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 KK nodi senza archi tra loro, usando un oracolo CLIQUE. Copia la matrice sul nastro di query invertendo 0 e 1, poi copia KK senza modificarlo e interroga l'oracolo. Basta una domanda: «il complemento ha una cricca di almeno KK nodi?».

Funziona perché un insieme indipendente in GG è una cricca nel grafo complemento Gˉ\bar G, 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 KK 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 K=2K=2 l'oracolo risponde sì. La diagonale non influenza il test, come spiegato sotto.

Statoletto₁letto₂nuovo statoscritto₁, mossa₁scritto₂, mossa₂note
ss▹\triangleright▹\trianglerightss▹,→\triangleright, \rightarrow▹,→\triangleright, \rightarrow
ss00⊔\sqcupss0,→0, \rightarrow1,→1, \rightarrowinverte il bit: c'è un arco in Gˉ\bar G
ss11⊔\sqcupss1,→1, \rightarrow0,→0, \rightarrowinverte il bit: niente arco in Gˉ\bar G
ss,,⊔\sqcupss,,→,, \rightarrow,,→,, \rightarrowcopia il separatore
ss;;⊔\sqcupss;,→;, \rightarrow;,→;, \rightarrowcopia il separatore
ss::⊔\sqcupkk:,→:, \rightarrow:,→:, \rightarrowfine della matrice
kkbb⊔\sqcupkkb,→b, \rightarrowb,→b, \rightarrowcopia KK senza cambiarlo
kk⊔\sqcup⊔\sqcupq?q_?⊔,−\sqcup, -⊔,−\sqcup, -"Gˉ\bar G ha una cricca di almeno KK nodi?"
qYESq_{\text{YES}}⊔\sqcup⊔\sqcupyes\text{yes}⊔,−\sqcup, -⊔,−\sqcup, -c'è un independent set di almeno KK nodi
qNOq_{\text{NO}}⊔\sqcup⊔\sqcupno\text{no}⊔,−\sqcup, -⊔,−\sqcup, -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 PCLIQUE\mathrm{P}^{\mathrm{CLIQUE}}. 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

Nastro 1
▷0,1,0;1,0,1;0,1,0:10⊔⊔
Nastro 2 (query)
▷⊔⊔⊔⊔⊔⊔⊔
Stato sPasso 0

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'è