In breve : un algoritmo è la parte costruttiva di una dimostrazione costruttiva che un determinato problema ha una soluzione. La motivazione di questa definizione è l'isomorfismo di Curry-Howard tra programmi e prove, considerando che un programma ha un interesse solo se risolve un problema, ma in modo evidente. Questa definizione consente una maggiore astrazione e lascia aperte alcune porte per quanto riguarda il tipo di domini che potrebbero essere interessati, ad esempio per quanto riguarda le proprietà di finiteness.
Attenzione . Sto cercando di trovare un approccio formale adeguato per rispondere alla domanda. Penso che sia necessario, ma sembra che nessuno degli utenti che hanno risposto finora (me compreso, e alcuni erano più o meno espliciti al riguardo in altri post) ha le basi giuste per sviluppare correttamente i problemi, che sono correlati a matematica costruttiva, teoria delle prove, teoria dei tipi e risultati come l' isomorfismo di Curry-Howard tra prove e programmi. Sto facendo del mio meglio qui, con qualsiasi frammento di conoscenza che io abbia (credo di) avere, e sono fin troppo consapevole dei limiti di questa risposta. Spero solo di dare alcuni suggerimenti su come penso che dovrebbe apparire la risposta. Se vedi un punto che è chiaramente sbagliato formalmente (dimostrabilmente), per favore fammi ora in un commento - o via e-mail.
Individuare alcuni problemi
Un modo standard di considerare un algoritmo è affermare che un algoritmo è un programma arbitrariamente specificato in modo preciso per alcuni dispositivi di elaborazione , compresi quelli che non hanno limiti in memoria. Il linguaggio può anche essere il linguaggio macchina del computer. In realtà è sufficiente considerare tutti i programmi per un dispositivo di elaborazione completo di Turing (il che implica che non ha limiti di memoria). Potrebbe non darti presentazioni di tutti gli algoritmi, nel senso che gli algoritmi devono essere espressi in una forma che dipende dai suoi dettagli dal contesto di interpretazione, anche teorica, poiché tutto è definito fino a una certa codifica. Ma dal momento che calcolerà tutto ciò che deve essere calcolato, includerà in qualche modo tutti gli algoritmi, fino alla codifica.
π
π, forse nel senso matematico di quasi tutti. Ma ciò richiederebbe maggiore precisione nelle definizioni.
Quindi la vera domanda è sapere quali sono gli algoritmi significativi. La risposta è che gli algoritmi significativi sono quelli che risolvono un problema, calcolando passo dopo passo la "soluzione", la "risposta", a quel problema. Un algoritmo è interessante se è associato a un problema che risolve.
Quindi, dato un problema formale, come possiamo ottenere un algoritmo che risolva il problema. Sia esplicitamente che implicitamente, gli algoritmi sono associati all'idea che esiste una soluzione al problema, che può essere dimostrata corretta. Se le nostre tecniche di prova sono accurate è un'altra questione, ma cerchiamo almeno di convincerci. Se ti limiti alla matematica costruttiva, che in realtà è ciò che dobbiamo fare (ed è un vincolo assiomatico molto accettabile per la maggior parte della matematica), il modo per dimostrare l'esistenza di una soluzione è passare attraverso prove che mostrano effettivamente un costrutto che rappresenta la soluzione, inclusi eventualmente altri passaggi che la stabiliscono in modo corretto.
Tutti i programmatori pensano qualcosa del genere: se giocherò con i dati in tale e in quel modo, allora otterrò questo widget che ha le proprietà giuste a causa del teorema di Sesame e, eseguendo questa trasformazione che preserva i piedi, ottengo la risposta desiderata . Ma la prova è di solito informale e non elaboriamo tutti i dettagli, il che spiega perché un satellite abbia tentato di orbitare sotto terra su Marte (tra le altre cose). Facciamo molto del ragionamento, ma in realtà manteniamo solo la parte costruttiva che costruisce la soluzione e la descriviamo in un linguaggio informatico come l'algoritmo che risolve il problema.
Algoritmi (o programmi) interessanti
Tutto ciò è stato quello di introdurre le seguenti idee, che sono oggetto di molte ricerche attuali (di cui non sono uno specialista). La nozione di " algoritmo interessante " qui usata è la mia, introdotta come segnaposto informale per definizioni più precise.
Un algoritmo interessante è la parte costruttiva di una prova costruttiva che un determinato problema ha una soluzione . Ciò significa che la prova deve effettivamente mostrare la soluzione piuttosto che dimostrarne semplicemente l'esistenza, ad esempio per contraddizione. Per maggiori dettagli vedi Logica intuitiva e costruttivismo in matematica.
Questa è ovviamente una definizione molto restrittiva, che considera solo ciò che ho chiamato algoritmi interessanti. Quindi li ignora quasi tutti. Ma anche tutti i nostri libri di testo sull'algoritmo. Tentano di insegnare solo alcuni di quelli interessanti.
Dati tutti i parametri del problema (dati di input), spiega come ottenere un risultato specificato passo dopo passo. Un esempio tipico è la risoluzione delle equazioni (l' algoritmo del nome è in realtà derivato dal nome di un matematico persiano, Muhammad ibn Mūsā al-Khwārizmī , che ha studiato la risoluzione di alcune equazioni). Parti della dimostrazione vengono utilizzate per stabilire che alcuni valori calcolati nell'algoritmo hanno alcune proprietà, ma queste parti non devono essere mantenute nell'algoritmo stesso.
Naturalmente, ciò deve avvenire all'interno di un quadro logico formalizzato che stabilisce con quali dati vengono calcolati, quali sono i passaggi di calcolo elementari consentiti e quali sono gli assiomi utilizzati.
Tornando al tuo esempio fattoriale, può essere interpretato come un algoritmo, anche se banale. La normale funzione fattoriale corrisponde a una prova che, dato un quadro aritmetico e dato un numero intero n, esiste un numero che è il prodotto dei primi n numeri interi. Questo è piuttosto semplice, così come il calcolo fattoriale. Potrebbe essere più complesso per altre funzioni.
Ora, se decidi di tabellare fattoriale, supponendo che tu possa, il che non è vero per tutti gli interi (ma potrebbe essere vero per qualche dominio finito di valori), tutto ciò che stai facendo è includere nei tuoi assiomi l'esistenza di fattoriale definendo con un nuovo assioma il suo valore per ogni numero intero, in modo che non sia più necessario provare (quindi calcolare) nulla.
Ma un sistema di assiomi dovrebbe essere finito (o almeno definito in modo fine). E c'è un'infinità di valori per fattoriale, uno per intero. Quindi sei nei guai per il tuo sistema finito di assiomi se assiomi una funzione infinita, cioè definita su un dominio infinito. Ciò si traduce computazionalmente nel fatto che la tua possibile ricerca nella tabella non può essere implementata per tutti i numeri interi. Ciò ucciderebbe il solito requisito di finitezza per gli algoritmi (ma deve essere rigoroso come spesso presentato?).
Potresti decidere di avere un generatore di assiomi finemente definito per gestire tutti i casi. Ciò equivarrebbe, più o meno, a includere il programma fattoriale standard nel tuo algoritmo per inizializzare l'array secondo necessità. Questo è chiamato memoization da parte dei programmatori. Questo è in realtà il più vicino che si ottiene all'equivalente di una tabella pre-calcolata. Si può capire che ha una tabella pre-calcolata, tranne per il fatto che la tabella viene effettivamente creata in modalità di valutazione lenta , quando necessario. Questa discussione avrebbe probabilmente bisogno di cure un po 'più formali.
Puoi definire le tue operazioni primitive come desideri (in coerenza con il tuo sistema formale) e assegnare loro il costo che scegli quando usato in un algoritmo, in modo da fare analisi di complessità o prestazioni. Ma se i sistemi concreti che implementano effettivamente il tuo algoritmo (un computer o un cervello, ad esempio) non possono rispettare queste specifiche di costo, la tua analisi può essere intellettualmente interessante, ma non vale per l'uso reale nel mondo reale.
21000
Quali programmi sono interessanti
Questa discussione dovrebbe essere più propriamente collegata a risultati come l'
isomorfismo di Curry-Howard tra programmi e prove. Se qualsiasi programma è in realtà una prova di qualcosa, qualsiasi programma può essere interpretato come un programma interessante nel senso della definizione sopra.
Tuttavia, per la mia (limitata) comprensione, questo isomorfismo è limitato a programmi che possono essere ben digitati in un sistema di tipizzazione appropriato, in cui i tipi corrispondono alle proposizioni della teoria assiomatica. Quindi non tutti i programmi possono qualificarsi come programmi interessanti. La mia ipotesi è che è in quel senso che un algoritmo dovrebbe risolvere un problema.
Ciò probabilmente esclude la maggior parte dei programmi "generati casualmente".
È anche una definizione piuttosto aperta di ciò che è un "algoritmo interessante". Qualsiasi programma che può essere considerato interessante lo è sicuramente, in quanto esiste un sistema di tipi identificato che lo rende interessante. Ma un programma che finora non era tipizzabile, poteva diventare scrivibile con un sistema di tipo più avanzato, e quindi diventare interessante. Più precisamente, è sempre stato interessante, ma per mancanza di conoscenza del sistema di tipi corretto, non abbiamo potuto conoscerlo.
Tuttavia, è noto che non tutti i programmi sono tipizzabili, poiché è noto che alcune espressioni lambda, come l'implementazione del combinatore Y , non possono essere digitate in un sistema di tipi di suono .
Questo punto di vista si applica solo ai formalismi di programmazione che possono essere direttamente associati ad alcuni sistemi di prova assiomatica. Non so come possa essere esteso a formalismi computazionali di basso livello come la Turing Machine. Tuttavia, poiché l'algoritmo e la calcolabilità sono spesso un gioco di codifica di problemi e soluzioni (si pensi all'aritmetica codificata nel calcolo lambda ), si può considerare che qualsiasi calcolo definito formalmente che può essere mostrato come codifica di un algoritmo è anche un algoritmo. Tali codifiche probabilmente usano solo una piccola parte di ciò che può essere espresso in un formalismo di basso livello, come le macchine di Turing.
Un interesse di questo approccio è che fornisce una nozione di algoritmo che è più astratta e indipendente dai problemi di codifica effettiva, di "rappresentabilità fisica" del dominio di calcolo. Quindi, per esempio, si possono considerare domini con oggetti infiniti purché esista un modo computazionale di usarli.