Dato che la corrispondenza Curry-Howard è così diffusa / estesa, c'è qualche differenza tra prove e programmi (o tra proposizioni e tipi)? Possiamo davvero identificarli?
Dato che la corrispondenza Curry-Howard è così diffusa / estesa, c'è qualche differenza tra prove e programmi (o tra proposizioni e tipi)? Possiamo davvero identificarli?
Risposte:
I linguaggi di programmazione che le persone usano quotidianamente non si adattano molto bene alla corrispondenza Curry-Howard, perché i loro sistemi di tipi sono troppo deboli. Per dire qualcosa di interessante usando Curry-Howard per i programmi imperativi, è necessario disporre di un sistema di tipi più sofisticato. Il libro Adattare le prove come programmi spinge questo angolo con l'obiettivo di sintetizzare i programmi imperativi. Con i tipi dipendenti che stanno diventando sempre più popolari, certamente nei linguaggi funzionali di ricerca ( Agda , Epigram ), la distinzione sta diventando più sfocata. Ovviamente puoi fare la sintesi / estrazione del programma all'interno del prover del teorema di Coq (e presumibilmente altri), che ovviamente si basa su Curry-Howard.
La corrispondenza Curry-Howard può essere utilizzata anche in situazioni in cui le prove non corrispondono in modo così chiaro ai programmi (o non sono programmi che nessuno potrà mai eseguire). Un esempio di ciò è rappresentato dall'autorizzazione di prova . Le proposizioni corrispondono a dichiarazioni su chi è autorizzato a fare cosa. Le prove forniscono le prove richieste che una proposta è valida, pertanto è consentita una richiesta di autorizzazione. Per codificare le prove, vengono introdotti termini di prova (tramite Curry-Howard). I termini di prova vengono inviati tra le parti come rappresentazioni di prove della validità delle richieste di autorizzazione, ma non sono considerati programmi.
In Coq, ci sono 2 tipi (Prop e Set), che vengono utilizzati dal programmatore per separare quali sono le prove che non producono codice effettivo e la parte della prova che verrà utilizzata per estrarre il codice in esecuzione (il tuo programma).
Questa è una buona soluzione per il problema che ci si chiede, come identificare cosa si intende generare codice macchina (programma) e cosa è presente per completare la prova della proposizione (o tipo).
AFAIK non esiste un modo automatico per distinguere entrambi. Questo potrebbe essere qualcosa di interessante per la ricerca? O forse qualcuno è in grado di sottolineare che è chiaramente impossibile?
Con i tipi dipendenti non solo non c'è una chiara distinzione tra prove e programmi, ma non c'è nemmeno una distinzione tra programmi e tipi! L'unica distinzione sarà dove appare il tipo (o programma), rendendolo parte del luogo "programma" o del luogo "tipo" di un dato termine.
Un esempio lo chiarirà, spero:
Quando usi la funzione Identity con tipi dipendenti devi passare il tipo con cui userai la funzione! Il tipo viene utilizzato come valore nel tuo "programma"!
Calcolo lambda non tipizzato:
Con tipi dipendenti:
id: (A: Imposta) -> A -> A
Se stai usando questa funzione, lo faresti come in questo esempio:
id Naturals 1
Si noti che il "tipo" (in questo caso il Set di Naturali) che viene passato come valore viene gettato via in modo che non venga mai calcolato, ma è ancora nella parte "programma" del termine. Questo è ciò che accadrà anche con le parti "di prova", devono essere lì per il controllo del tipo, ma durante il calcolo verranno gettate via.
Esco di qui e dico che, se sei disposto a strizzare gli occhi, è possibile identificare prove e programmi di chiusura .
Qualsiasi programma di chiusura è una prova che puoi prendere il suo input e produrre il suo output. Questo è un tipo molto semplice di prova dell'implicazione.
Naturalmente, per far sì che questa implicazione porti informazioni più significative che affermare l'ovvio, devi essere in grado di mostrare che il programma funziona per qualsiasi istanza di input disegnata da una classe con significato logico. (E così anche per l'output.)
Dall'altra direzione, qualsiasi prova con passaggi di inferenza finiti è un programma simbolico che manipola oggetti in un sistema logico. (Se non ci preoccupiamo troppo di ciò che i simboli e le regole logici significano computazionalmente.)
Questo è piuttosto semplicistico, ma penso che suggerisca la solidità dell'idea. (Anche se alcune persone sono destinate a non apprezzarlo. ;-))
Prova irrilevanza?
Quando scrivi un programma, sei interessato alle sue prestazioni, al consumo di memoria, ecc.
Ad esempio, è meglio usare un algoritmo di ordinamento intelligente invece di un ordinamento a bolle, anche se le loro implementazioni hanno gli stessi tipi (anche nelle impostazioni di tipo dipendente).
Ma quando provi un teorema è solo l'esistenza di una prova che ti interessa.
Naturalmente, dal punto di vista estetico, alcune prove sono più semplici / belle / stimolanti / ecc. (Ad esempio prove dal libro).
Se accetti la corrispondenza Curry-Howard, allora la domanda è principalmente filosofica. "Le prove e i programmi sono diversi? Certo. Come? Bene, chiamiamo prove" prove "e chiamiamo programmi" programmi "."
O per dirla in modo meno esagerato, se c'è un isomorfismo tra prove e programmi - che sembra chiaramente che ci sia - allora la tua domanda è chiederti se esiste un oracolo in grado di distinguere i due. Gli umani li classificano come diversi (per la maggior parte), quindi è certamente discutibile che esista un simile oracolo. La domanda importante diventa quindi se c'è una differenza significativa tra loro, che è in discussione filosofica. Che cos'è una "prova"? Non esiste una definizione formale di ciò che costituisce una prova; è un termine artistico, molto simile alla nozione di "effettivamente calcolabile" nella tesi Church-Turing. Del resto, "programma" non ha neppure una definizione formale.
Queste sono parole del linguaggio naturale usate per classificare i diversi campi dell'indagine matematica. Ciò che Curry e Howard hanno osservato è che questi due campi diversi dovevano effettivamente studiare la stessa cosa. Notare questa connessione è importante perché dice che questi diversi ricercatori dovrebbero parlare tra loro. Ma ad un altro livello, notare la connessione è credere alla differenza tra loro. Quando si affronta un problema, a volte è più utile pensarlo come un problema di programmazione, mentre altre volte è più vantaggioso considerarlo come un problema logico. Questa differenza di prospettiva è, penso, la differenza importante tra loro. Ma se una differenza di prospettiva costituisce una differenza di identità è una profonda questione filosofica che è stata esplorata almeno fino a quella di FregeUeber Sinn und Bedeutung .