So che, nei linguaggi di programmazione imperativa, un ciclo while-do è sufficiente come costrutto del flusso di controllo per rendere completo il linguaggio Turing (per quanto riguarda il flusso di controllo - ovviamente abbiamo anche bisogno di memoria illimitata e alcuni operatori ...) . L'essenza della mia domanda è: un ciclo do-while ha la stessa potenza computazionale di un ciclo while-do? In altre parole, una lingua può essere Turing completa se è impossibile saltare del tutto le istruzioni.
Mi rendo conto che alcune delle semantiche qui potrebbero essere un po 'ambigue, quindi lasciatemi esprimere la domanda effettiva con un esempio specifico:
Brainfuck (BF) è un tarpit di Turing in cui l'unico flusso di controllo è un loop while-do, indicato come [...]
(c'è una specifica di linguaggio completa nella parte inferiore della domanda, nel caso in cui non si abbia familiarità con Brainfuck). Definiamo un nuovo linguaggio BF *, dove ,.+-<>
ha la stessa semantica di BF, ma invece di []
quello {}
che denota un ciclo do-while. Cioè, l'unica differenza rispetto a BF è che ogni ciclo viene eseguito almeno una volta prima di poter saltare ulteriori iterazioni.
BF * Turing è completo? In tal caso, sarei interessato a come avrei potuto tradurre da BF a BF *. In caso contrario, come posso dimostrarlo?
Alcune mie osservazioni:
- Non tutti i programmi BF possono essere tradotti in BF *. Ad esempio, è impossibile scrivere un programma in BF * che potrebbe o meno leggere o stampare un valore - se il programma potenzialmente stampa uno o più valori, ne stamperà sempre almeno uno. Tuttavia, potrebbe esserci un sottoinsieme completo di Turing di BF che può essere tradotto in BF *.
- Non possiamo semplicemente tradurre
[f]
(dove sif
trova un programma Brainfuck arbitrario costituito solo da+-[]<>
) in (nel tentativo di annullare l'effetto della prima iterazione), perché a) non tutte le funzioni calcolabili hanno un inverso calcolabile eb) anche se lo facesse, non avrebbe necessariamente un numero inferiore di loop rispetto all'applicazione, quindi applicare questo passaggio in modo ricorsivo non è garantito per terminare in primo luogo.f-1{f}
f-1
f
Ecco una rapida panoramica del linguaggio Brainfuck. Brainfuck opera su un nastro infinito in cui ogni cella contiene un valore di byte, inizialmente zero. Gli overflow si avvolgono, quindi l'incremento di 255 dà 0 e viceversa. La lingua è composta da 8 istruzioni:
+ Increment the current cell.
- Decrement the current cell.
> Move tape head to the right.
< Move tape head to the left.
, Input a character from STDIN into the current cell.
. Output the current cell as a character to STDOUT.
[ If the current cell is zero, jump past the matching ].
] If the current cell is non-zero, jump back to just behind the matching [.
[]
non sta esattamente definendo un ciclo "while do" in BF. come nella tabella le parentesi sinistra e destra valutano la cella zero / diversa da zero. quindi qual è la descrizione esatta della corrispondente {}
logica di valutazione delle parentesi graffe? suggerire ulteriori dialoghi / discussioni in Computer Science Chat . anche le tue "osservazioni" sono più simili a "postulati" o "proposizioni" senza prove.
{}
sarebbe stata quella di {
non fare assolutamente nulla e }
lo stesso di ]
. Non avrò molto tempo nei prossimi giorni, ma mi unirò a te in chat quando troverò del tempo.
{}
e rimozione []
, BF * Turing è completo. con la consapevolezza che BF []
è un costrutto solo qualcosa di simile / analogo a un ciclo while-do nei linguaggi completi di Turing.