"Certificatore di compilazione" di solito significa qualcosa di leggermente diverso: significa che hai un compilatore che può dimostrare che il codice macchina che emette implementa correttamente la semantica di alto livello. Cioè, questa è una prova che non ci sono bug del compilatore. I programmi che le persone danno al compilatore possono ancora essere sbagliati, ma il compilatore genererà una versione corretta del codice macchina del programma sbagliato. La più grande storia di successo in questo senso è il compilatore verificato CompCert , che è un compilatore per un ampio sottoinsieme di C.
Il compilatore Compcert stesso è un programma con una prova di correttezza (eseguita in Coq), che garantisce che se genera codice per un programma, sarà corretto (rispetto alla semantica operativa di assembly & C utilizzata dai progettisti di CompCert). Lo sforzo di controllare automaticamente queste cose è piuttosto grande; in genere la prova di correttezza sarà compresa tra 1 e 100 volte la dimensione del programma che si sta verificando. Scrivere programmi e prove controllati automaticamente è una nuova abilità che devi imparare - non è matematica o programmazione come al solito, anche se dipende dalla capacità di fare entrambe le cose bene. Sembra che tu stia ricominciando da capo, come essere di nuovo un programmatore alle prime armi.
Non ci sono barriere teoriche speciali a questo, però. L'unica cosa su questa linea è il teorema di Blum Size che per qualsiasi lingua in cui tutti i programmi sono totali, puoi trovare un programma in una lingua ricorsiva generale che sarà almeno esponenzialmente più grande quando programmato nella lingua totale. Il modo per comprendere questo risultato è che una lingua totale codifica non solo un programma, ma anche una prova di terminazione. Quindi puoi avere programmi brevi con prove di terminazione lunghe. Tuttavia, questo non ha molta importanza in pratica, dato che scriveremo solo programmi con prove di terminazione gestibili.
EDIT: Dai Le ha chiesto qualche elaborazione dell'ultimo punto.
Questa è principalmente un'affermazione pragmatica, basata sul fatto che se riesci a capire perché un programma funziona, è improbabile che la ragione sia lunga milioni di pagine invarianti. (Gli invarianti più lunghi che ho usato sono lunghi poche pagine, e ragazzi fanno brontolare i recensori! Comprensibilmente, anche perché l'invariante è la ragione per cui il programma funziona spogliato di tutta la narrazione che aiuta le persone a capirlo.)
Ma ci sono anche alcune ragioni teoriche. Fondamentalmente, non conosciamo molti modi per inventare sistematicamente programmi le cui prove di correttezza sono molto lunghe. Il metodo principale è (1) prendere la logica in cui si dimostra la correttezza, (2) trovare una proprietà che non può essere direttamente espressa in quella logica (le prove di coerenza sono la fonte tipica) e (3) trovare un programma il cui la prova di correttezza si basa su una famiglia di conseguenze espressibili della proprietà indicibile. Poiché (2) è inesprimibile, ciò significa che la prova di ogni conseguenza esprimibile deve essere eseguita in modo indipendente, il che consente di far esplodere la dimensione della prova di correttezza. Come semplice esempio, si noti che nella logica del primo ordine con una relazione principale, non è possibile esprimere la relazione antenata.kk) è espressibile, per ogni fisso . Quindi, dando un programma che utilizza alcune proprietà degli antenati fino a una certa profondità (diciamo, 100), puoi forzare una prova di correttezza in FOL per contenere prove di tali proprietà centinaia di volte.k
La sofisticata interpretazione di questa materia si chiama "matematica inversa" ed è lo studio di quali assiomi sono necessari per dimostrare dati teoremi. Non ne so molto, ma se pubblichi una domanda sulla sua applicazione a CS, e sono sicuro che almeno Timothy Chow, e probabilmente molte altre persone, saranno in grado di dirti cose interessanti.