È possibile sostituire la ricorsione con iterazione più memoria illimitata .
Se hai solo iterazioni (diciamo, mentre loop) e una quantità finita di memoria, allora tutto ciò che hai è un automa finito. Con una quantità finita di memoria, il calcolo ha un numero finito di passaggi possibili, quindi è possibile simularli tutti con un automa finito.
La memoria illimitata modifica l'affare. Questa memoria illimitata può assumere molte forme che risultano avere un potere espressivo equivalente. Ad esempio, una macchina Turing lo rende semplice: c'è un singolo nastro e il computer può solo spostarsi avanti o indietro sul nastro di un passo alla volta, ma è abbastanza per fare tutto ciò che è possibile fare con le funzioni ricorsive.
Una macchina Turing può essere vista come un modello idealizzato di un computer (macchina a stati finiti) con un po 'di spazio in più che cresce su richiesta. Si noti che è fondamentale che non solo non ci sia un limite finito sul nastro, ma anche dato l'input, non è possibile prevedere in modo affidabile la quantità di nastro necessaria. Se potessi prevedere (cioè calcolare) la quantità di nastro necessaria dall'input, potresti decidere se il calcolo si fermerebbe calcolando la dimensione massima del nastro e quindi trattando l'intero sistema, incluso il nastro ormai finito, come una macchina a stati finiti .
Un altro modo per simulare una macchina Turing con i computer è il seguente. Simula la macchina Turing con un programma per computer che memorizza l'inizio del nastro in memoria. Se il calcolo raggiunge la fine della parte del nastro che si adatta alla memoria, sostituire il computer con un computer più grande ed eseguire nuovamente il calcolo.
Supponiamo ora di voler simulare un calcolo ricorsivo con un computer. Le tecniche per eseguire funzioni ricorsive sono ben note: ogni chiamata di funzione ha un pezzo di memoria, chiamato frame di stack . Fondamentalmente, le funzioni ricorsive possono propagare le informazioni attraverso più chiamate passando variabili. In termini di implementazione su un computer, ciò significa che una chiamata di funzione potrebbe accedere al frame dello stack di una chiamata (grand-) * parent.
Un computer è un processore - una macchina a stati finiti (con un numero enorme di stati, ma qui stiamo facendo la teoria dei calcoli, quindi tutto ciò che conta è che è finito) - accoppiato con una memoria finita. Il microprocessore esegue un loop gigante mentre: "mentre l'alimentazione è accesa, leggere un'istruzione dalla memoria ed eseguirla". (I processori reali sono molto più complessi di così, ma non influiscono su ciò che possono calcolare, solo quanto velocemente e comodamente lo fanno.) Un computer può eseguire funzioni ricorsive con questo ciclo while per fornire iterazione, oltre al meccanismo per accedere alla memoria, inclusa la possibilità di aumentare le dimensioni della memoria a piacimento.
Se si limita la ricorsione alla ricorsione primitiva, è possibile limitare l'iterazione all'iterazione limitata . Cioè, invece di utilizzare i cicli while con un tempo di esecuzione imprevedibile, è possibile utilizzare per i cicli in cui il numero di iterazioni è noto all'inizio del ciclo¹. Il numero di iterazioni potrebbe non essere noto all'inizio del programma: può essere stato calcolato da cicli precedenti.
Non ho nemmeno intenzione di delineare una prova qui, ma esiste una relazione intuitiva tra il passaggio dalla ricorsione primitiva alla ricorsione completa e il passaggio da cicli a cicli continui: in entrambi i casi, implica non sapere in anticipo quando Stop. Con la ricorsione completa, questo viene fatto con l'operatore di minimizzazione, dove si continua fino a quando non si trova un parametro che soddisfa la condizione. Con i cicli while, questo viene fatto continuando fino a quando la condizione del loop è soddisfatta.
¹ I loop in linguaggi di tipo C possono eseguire iterazioni illimitate proprio come , è solo una questione di convenzione limitarli a iterazioni limitate. Quando le persone parlano di "per loop" nella teoria del calcolo, ciò significa solo loop che contano da 1 a n (o equivalenti). for
while
n