Esistono criteri minimi per un linguaggio di programmazione completo di Turing?


55

Esiste un insieme di costrutti del linguaggio di programmazione in un linguaggio di programmazione per essere considerato Turing completo?

Da quello che posso dire da Wikipedia , la lingua deve supportare la ricorsione o, a quanto pare, deve essere in grado di funzionare senza fermarsi. È tutto quello che c'è da fare?


6
Forse la tua domanda dovrebbe porsi "Esiste un insieme minimo di costrutti di programmazione ...?", Perché come è formulato la risposta è "Tutti quelli calcolabili".
Dave Clarke,


@DaveClarke, grazie, l'ho aggiornato. Trovo che il tuo commento sollevi in ​​qualche modo la domanda, anche se presumo sia perché la mia lingua è scarsa. Intendevo chiedere se ci fossero o meno alcune operazioni che se una lingua potesse essere calcolata, sarebbe diventata equivalente.
Khanzor,

Risposte:


45

Ho sempre pensato che le funzioni ricorsive di fossero inchiodate. Ecco cosa definisce l'intero insieme di funzioni calcolabili; è la più piccola serie di funzioni contenenti resp. chiuso contro:μ

  1. La funzione costante0
  2. La funzione successiva
  3. Selezione dei parametri
  4. Composizione delle funzioni
  5. Ricorsione primitiva
  6. L' operatore (cerca la più piccola tale che ...)xμx

Controlla il link sopra per i dettagli; vedi che rende un linguaggio di programmazione molto compatto. È anche orribile programmare - nessun pranzo gratuito. Se lasci cadere uno di questi, perderai la piena potenza, quindi è un insieme minimo di assiomi.

Puoi tradurli letteralmente in elementi sintattici di base per i programmi WHILE , vale a dire

  1. La costante 0
  2. Incremento _ + 1
  3. Accesso variabile x
  4. Concatenazione di programmi / dichiarazioni _; _
  5. Cicli di conto alla rovescia for ( x to 0 ) do _ end
  6. Mentre loop while ( x != 0 ) do _ end

1
Penso che sia ovvio che non puoi lasciare cadere la quinta regola nella lingua. Poiché il whileciclo in 6 è comparabile allo zero costante, le variabili possono essere incrementate solo dalla regola 2 e non ci sono costanti negative da cui iniziare (regola 1), il whileciclo in 6 non è inserito (x = 0) o è infinito ( x> 0 e il corpo del loop non può diminuirlo).
Saluti

1
@MSalters Penso che tu abbia ragione; per la simulazione mi sembra di aver pensato, abbiamo bisogno _ - 1e non riesco a pensare a un modo per implementarlo senza for. Grazie per averlo colto! (Che cosa è "migliore" - compreso _ - 1o for? Hmm.)
Raffaello

20

Esiste un insieme di calcoli che devono essere eseguibili in un linguaggio di programmazione per essere considerato Turing completo?

Sì, per essere considerato Turing completo, un linguaggio di programmazione deve essere in grado di eseguire qualsiasi calcolo che può essere eseguito da una macchina Turing. Quindi, come requisito minimo che si potrebbe dire, è necessario essere in grado di implementare una macchina Turing universale - o un interprete per qualsiasi altro linguaggio completo di Turing - in essa.

Da quello che posso dire da Wikipedia, la lingua deve supportare la ricorsione o, a quanto pare, deve essere in grado di funzionare senza fermarsi. È tutto quello che c'è da fare?

No. Ad esempio, una lingua in cui l'unica operazione consentita è la ricorsione (ovvero l'unica funzione possibile che è possibile scrivere è f(x) = f(x), non è Turing completa perché tutto ciò che è possibile scrivere sono programmi che non si interrompono mai. Come ho detto prima, una lingua completa di Turing deve essere in grado di implementare qualsiasi calcolo che può essere eseguito da una macchina di Turing. Così chiaramente che non è sufficiente.

Inoltre, una lingua non deve supportare la ricorsione nel modo in cui stai pensando. Solo un modo illimitato di esprimere i loop. Potrebbe essere una ricorsione, ma potrebbe anche essere un ciclo di ciclo o goto. Un linguaggio che non ha affatto funzioni può ancora essere Turing completo. E ancora loop o funzioni ricorsive non sono una condizione sufficiente. Hai ancora bisogno di un modo per eseguire codice diverso a seconda di una condizione e un modo per calcolare nuovi valori da quelli vecchi (altrimenti tutti i cicli / ricorsione sarebbero infiniti o non funzionerebbero affatto).


Quanto alla presenza o meno di un insieme minimo di operazioni necessarie e sufficienti, tale che qualsiasi lingua che supporti queste operazioni sia Turing completa e qualsiasi lingua che non lo sia: No, non esiste (a meno che non si definisca "operazione" così vagamente , che diventa insignificante):

Ad esempio, come ho già detto, ci sono linguaggi completi di Turing che non supportano funzioni ricorsive (o nessuna funzione). Questi possono ancora essere Turing completi se hanno gotoun'istruzione o un whileciclo (e un modo per archiviare quantità arbitrarie di dati). Tuttavia, una lingua con funzioni ricorsive non ha bisogno whilegotodi essere completa di Turing. Quindi gotonon sarebbe nel set di operazioni sufficienti necessarie, ma ci sono lingue che non sono più complete se rimuovi goto. Quindi non esiste un tale set.


L'unica parte di cui non sono certo è la tua risposta all'insieme minimo di operazioni necessarie. Sembri limitare la tua definizione di operazioni a Strutture di controllo che sembrano essere un ambito molto più ristretto di quanto richiesto, e al di là del tuo requisito di non definirle "così vagamente, che [diventano] insignificanti".
Joshua Drake,

@JoshuaDrake Non sono sicuro di cosa intendi. Non sto limitando le operazioni per controllare le strutture. È solo che non parlo di operazioni che non sono strutture di controllo nel mio contro esempio perché non sono rilevanti per l'esempio. In realtà menziono "un modo per archiviare quantità arbitrarie di dati", che non è certo una struttura di controllo.
sepp2k,

Fai notare che alcune lingue supportano la completezza di Turing gotoma che altre no, apparentemente affermando che, poiché alcune lo usano e altre no, gotoallora non possono far parte di una serie di operazioni richieste per la completezza di Turing. Il mio punto è che gotoè semplicemente un modo sintattico per implementare un'operazione più generica, come un salto. Pertanto credo che se ti allontanassi semplicemente da specifiche strutture di controllo ti avvicineresti a una serie di operazioni che indicherebbero almeno verso Turing Completezza.
Joshua Drake,

@JoshuaDrake Non penso che usare "jump" invece di goto ci porti al punto in cui possiamo definire un insieme di operazioni sufficiente e necessario. È probabilmente vero che ogni lingua avrebbe bisogno di una sorta di operazione di salto (e se si tratta solo di chiamate di funzione), ma non credo che sarai in grado di inventare ulteriori operazioni per renderlo sufficiente. Ad esempio il calcolo lambda ha due operazioni: applicazione (cioè la nostra operazione di salto) e astrazione (cioè creazione di funzioni) ...
sepp2k

1
@JoshuaDrake Non credo che l'articolo stia cercando di affermare che qualsiasi linguaggio completo di Turing deve avere tali operazioni. Soprattutto perché limita in modo specifico tale affermazione ai linguaggi procedurali. Ad eccezione di una forma di goto (cioè l'applicazione di funzioni), il Lambda Calculus non ha nessuna di queste cose. Penso che "minimo" qui significhi solo che in una lingua che ha solo quelle caratteristiche, non puoi rimuoverne nessuna senza perdere la completezza di Turing. Non che non vi siano altre serie minime di operazioni sufficienti per la completezza di Turing.
sepp2k,

14

Esistono varie istruzioni singole che portano alle lingue complete di Turing. L'esempio tipico è "sottrai e ramifica se zero". Questi sono ben noti nel contesto della programmazione del linguaggio assembly. Vedi l'articolo di Wikipedia per i dettagli.

Questo porta a una caratterizzazione: un linguaggio è Turing completo se e solo se è in grado di simulare le operazioni di recupero e memorizzazione di numeri interi in memoria ed esecuzione dell'operazione "sottrazione e ramo se zero" su di essi.


13

Questa non è una risposta generale alla tua domanda, ma dal teorema di programmazione strutturato , tutto ciò che serve è la capacità di fare selezione (ad esempio, ifin C / C ++) e ripetizione (ad esempio, whilein C / C ++). Modifica: come sottolineato da Dave Clarke nei commenti, anche il teorema di programmazione strutturato richiede una sequenza. Inizialmente non l'ho elencato da quando ho dato per scontato che il lettore avrebbe capito che erano necessari anche blocchi di base di altre istruzioni, come quelle a cui si fa riferimento in seguito per leggere e scrivere nell'archivio di memoria, ecc.). È ovviamente meglio essere espliciti; devi essere in grado di fare anche queste cose.

Dal momento che entrambi questi possono essere implementati usando un'istruzione di salto condizionale (ad esempio, JNZin x86), questo è anche sufficiente per l'equivalenza di Turing.

Si noti che sono necessarie altre cose, ovvero la possibilità di scrivere un numero illimitato di simboli (ad es. Bit ... 0 o 1) in una sorta di memoria esterna. In tal senso, i computer reali non sono equivalenti a Turing, poiché nessuno di essi ha una quantità infinita di spazio di archiviazione. Il modello di Turing è comunque utile, poiché la quantità di memoria è in genere enorme, e anche se qualsiasi problema che un vero computer può risolvere può essere risolto da un automa deterministico finito, l'utilizzo di quel modello di calcolo non è particolarmente utile (poiché il il numero di stati sarebbe assurdamente enorme).

Nota che questo non è necessariamente in contrasto con la risposta di sepp2k; questo è solo un modo diverso di pensare alla stessa domanda.

MODIFICARE:

Nota anche che non hai davvero bisogno di entrambi ife whilein C / C ++. Puoi simulare ifusando whilecome segue:

bool C;
// some code that sets C
if(C) { /* some other code /* }
// rest of the program

Il seguente codice è sempre equivalente:

bool C;
// some code that sets C
bool C2 = C;
while(C2) { /* some other code /* C2 = false; }
// rest of the program

Bene ... la costruzione dovrebbe funzionare ed essere possibile se stai attento, cioè. Si noti inoltre che se si dispone di funzioni ricorsive, alla fine è necessario anche la selezione; poiché le funzioni ricorsive senza selezione non possono realmente implementare casi base, quindi qualsiasi funzione ricorsiva comporterebbe una ricorsione infinita.

MODIFICARE:

Inoltre, riguardo alla tua domanda se la capacità di scrivere un programma che non si ferma è sufficiente per l'equivalenza di Turing, la risposta è no; è necessario, ma non sufficiente. Possiamo risolvere il problema dell'arresto per i programmi scritti in una lingua che non può esprimere programmi che non riescono ad arrestarsi; la risposta è "il programma si ferma" per tutte le istanze. Tuttavia, possiamo definire una lingua in cui l'unica istruzione fa sì che la macchina entri in un ciclo infinito ... tale lingua non è equivalente a Turing.


13

SK(S x y z)=(x z (y z))(K x y)=x

X=λx.((x S) K)


5

I costrutti del linguaggio sono intercambiabili

Non esistono criteri minimi fissi su quali costrutti debbano essere forniti nativamente da un linguaggio di programmazione. Se fornisce alcuni strani costrutti che possono in qualche modo essere contorti per esprimere un sistema completo di Turing, allora apparentemente quei costrutti sono "altrettanto adatti" come qualsiasi altro.

Per dimostrarlo, un linguaggio che fornisce solo un'operazione di "sottrazione e ramificazione se zero" è Turing completato; esistono linguaggi completi di Turing che non forniscono un costrutto separato "sottrarre e ramificare se zero", ergo non esiste un costrutto o un insieme di costrutti obbligatorio.

Gli effetti di qualsiasi costrutto del linguaggio completo TP possono essere emulati dai costrutti di qualsiasi altro linguaggio completo TP.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.