Qual è l'insieme minimo di funzionalità / strutture linguistiche che lo rendono Turing completo?
Qual è l'insieme minimo di funzionalità / strutture linguistiche che lo rendono Turing completo?
Risposte:
Un tarpit di Turing è un tipo di linguaggio di programmazione esoterico che si sforza di essere Turing completo mentre utilizza il minor numero possibile di elementi. Brainfuck è forse il tarpit più noto, ma ce ne sono molti.
Iota e Jot sono linguaggi funzionali con due e tre simboli, rispettivamente, basati sul calcolo del combinatore SK (I) .
OISC ( One Instruction Set Computer ) indica un tipo di calcolo imperativo che richiede solo un'istruzione di uno o più argomenti, in genere "sottrarre e ramificare se inferiore o uguale a zero" o "invertire sottrai e saltare se prendere in prestito". La MMU x86 implementa l'istruzione precedente ed è quindi Turing-complete.
In generale, affinché un linguaggio imperativo sia completo di Turing, è necessario:
Una forma di ripetizione condizionale o salto condizionale (ad es. while
, if
+ goto
)
Un modo per leggere e scrivere una forma di archiviazione (ad es. Variabili, nastro)
Perché un linguaggio funzionale basato su lambda-calcolo sia TC, ha bisogno di:
La capacità di astrarre funzioni su argomenti (ad esempio, lambda astrazione, citazione)
La capacità di applicare funzioni agli argomenti (ad es. Riduzione)
Esistono ovviamente altri modi di considerare il calcolo, ma questi sono modelli comuni per i tarp di Turing. Si noti che i computer reali non sono macchine Turing universali perché non dispongono di memoria illimitata. A rigor di termini, sono "macchine di archiviazione limitate". Se dovessi continuare ad aggiungere memoria a loro, si avvicinerebbero asintoticamente alle macchine di Turing al potere. Tuttavia, anche le macchine di archiviazione limitate e le macchine a stati finiti sono utili per il calcolo; semplicemente non sono universali .
A rigor di termini, l'I / O non è richiesto per la completezza di Turing; TC afferma solo che una lingua può calcolare la funzione desiderata, non che può mostrarti il risultato. In pratica, ogni lingua utile ha in qualche modo un modo di interagire con il mondo.
Da un punto di vista più pratico: se riesci a tradurre tutti i programmi in una lingua completa di Turing nella tua lingua, quindi (per quanto ne so), la tua lingua deve essere completa di Turing. Pertanto, se si desidera verificare se una lingua progettata è Turing-completa, è possibile semplicemente scrivere un Brainf *** nel compilatore YourLanguage e dimostrare / dimostrare che può compilare tutti i programmi BF legali.
Per chiarire, intendo che oltre a un interprete per YourLanguage, scrivi un compilatore (in qualsiasi lingua) in grado di compilare qualsiasi programma BF su YourLanguage (mantenendo la stessa semantica, ovviamente).
</sarcasm>
Un sistema può essere considerato completo di Turing solo se può fare qualsiasi cosa una macchina universale di Turing. Poiché si dice che la macchina universale di Turing sia in grado di risolvere qualsiasi funzione calcolabile in un determinato momento, anche i sistemi completi di Turing possono farlo.
Per verificare se qualcosa è Turing completo, vedere se è possibile implementare una macchina Turing al suo interno. In altre parole, controlla se è in grado di simulare quanto segue:
Questi sono i veri requisiti minimi per un sistema da considerare Turing completo. Niente di più, niente di meno. Se non riesce a simulare nessuno di questi in qualche modo, non è Turing completo. I metodi proposti da altre persone sono solo mezzi per raggiungere il fine in quanto ci sono diversi sistemi completi di Turing che non hanno quelle caratteristiche.
Si noti che non esiste un modo noto per costruire effettivamente un vero sistema completo Turing. Questo perché non esiste un modo noto per simulare sinceramente la sconfinatezza del nastro della macchina Turing nello spazio fisico.
Un linguaggio di programmazione è in fase di completamento se è possibile eseguire qualsiasi calcolo con esso. Non esiste un solo set di funzionalità che completa il turing della lingua, quindi le risposte che dicono che hai bisogno di loop o che hai bisogno di variabili sono sbagliate poiché ci sono lingue che non hanno né il turing completo.
Alan Turing ha creato la macchina turing universale e se puoi tradurre qualsiasi programma progettato per funzionare sulla macchina universale per funzionare nella tua lingua, anche Turing è completo. Questo funziona anche indirettamente, quindi puoi dire che la lingua X è completa se tutti i programmi per la lingua completa Y possono essere tradotti per X poiché tutti i programmi universali della macchina turing possono essere tradotti in un programma Y.
La complessità del tempo, la complessità dello spazio, la facilità del formato di input / output e la facilità di scrittura di qualsiasi programma non sono inclusi nell'equazione, quindi tale macchina può teoricamente fare tutti i calcoli se i calcoli non sono fermati dalla perdita di potenza o se la Terra viene ingoiata dal sole.
Di solito per dimostrare la completezza turing fanno di un interprete qualsiasi linguaggio provato turing completo ma per farlo funzionare sono necessari mezzi di input e output, due cose che in realtà non sono necessarie per un linguaggio turing completo. È sufficiente che il programma possa modificare il suo stato all'avvio e che sia possibile ispezionare la memoria dopo l'interruzione del programma.
Per rendere un linguaggio di successo è necessario ben altro che completezza turing e questo è vero anche per tarpit turing. Non credo che BrainFuck sarebbe stato popolare senza ,
e .
.
Non puoi dire se si ripeterà all'infinito o si fermerà.
Spiegazione: Dato qualche input, è impossibile dire in ogni caso (usando un'altra macchina di Turing) se la cosa sta andando all'infinito o alla fine si fermerà, tranne eseguendola (che ti dà una risposta se si ferma, ma non se scorre!).
Ciò significa che devi essere in grado di memorizzare una quantità potenzialmente illimitata di dati in qualche modo: deve esserci un equivalente del nastro infinito, non importa quanto contorto! (Altrimenti ci sono solo un numero finito di stati e quindi puoi verificare se hai attraversato quello stato in precedenza e alla fine fermarti). In generale, le macchine di Turing possono aumentare o ridurre le dimensioni del loro stato con mezzi controllabili.
Poiché la macchina Turing universale originale di Turing presenta un problema di arresto irrisolvibile, anche la tua macchina completa Turing deve avere un problema di arresto irrisolvibile.
I sistemi completi di Turing possono emulare qualsiasi altro sistema completo di Turing, quindi se puoi creare un emulatore per qualche sistema completo Turing ben noto nel tuo sistema, ciò dimostra che anche il tuo sistema è Turing completo.
Ad esempio, supponiamo che tu voglia dimostrare che Snakes & Ladders è Turing completo, dato un tabellone con uno schema a griglia ripetuto all'infinito (con una versione diversa sul lato superiore e sinistro). Sapendo che la macchina Minsky a 2 contatori è Turing completa (che ha 2 segnalini illimitati e 1 stato fuori da un numero finito), puoi costruire una tavola equivalente dove la posizione X e Y sulla griglia è il valore corrente dei 2 contatori e il percorso corrente è lo stato corrente. Scoppio! Hai appena dimostrato che Snakes & Ladders sono Turing completi.
Una condizione necessaria è un loop con un conteggio di iterazione massimo non determinato prima dell'iterazione o ricorsione in cui la profondità di ricorsione massima non è determinata in anticipo. Ad esempio, per ... in ... i loop come li trovi in molte lingue più recenti non sono sufficienti per completare il turing della lingua (ma avranno altri mezzi). Si noti che ciò non significa un numero limitato di iterazioni o profondità di ricorsione limitata, ma che le iterazioni massime e la profondità di ricorsione devono essere calcolate in anticipo.
Ad esempio, la funzione Ackermann non può essere calcolata in una lingua senza queste funzionalità. D'altra parte, è possibile scrivere molti software estremamente complessi e molto utili senza richiedere queste funzionalità.
D'altra parte, con ogni conteggio delle iterazioni e ogni profondità di ricorsione calcolati in anticipo, non solo si può decidere se un programma si arresterà o meno, ma si fermerà .
so che questa non è la risposta formalmente corretta, ma una volta estratto il "minimo" da "Turing-complete" e riportato "pratico" al suo posto, vedrai le caratteristiche più importanti che distinguono un linguaggio di programmazione da un linguaggio di markup sono
il prossimo arrivato
per testare queste affermazioni, inizia con un linguaggio di markup, ad esempio HTML. potremmo inventare un HTML + solo con variabili o solo condizionali (lo ha fatto MS con commenti condizionali) o un qualche tipo di costrutto loop (che in assenza di condizionali probabilmente finirebbe come qualcosa del genere <repeat n='4'>...</repeat>
). fare uno di questi renderà HTML + significativamente (?) più potente del semplice HTML, ma sarebbe comunque più un markup che un linguaggio di programmazione; con ogni nuova funzionalità, la rendi meno un linguaggio dichiarativo e più un linguaggio imperativo.
la ricerca della minimalità nella logica e nella programmazione è sicuramente importante e interessante, ma se dovessi insegnare a n00bies giovani o vecchi "cosa sta programmando" e "come imparare a programmare", difficilmente inizierei con tutta la larghezza e la larghezza delle basi teoriche della completezza di Turing. tutta l'essenza della cucina e della programmazione sta facendo le cose, nell'ordine giusto, ripetendo fino a quando non è pronto, come ha fatto tua madre. che per riassumere per me.
poi di nuovo, non ho mai finito il mio CS.