è molto utile per l'estrazione del programma perché ci consente di eliminare parti di codice inutili. Ad esempio, per estrarre un algoritmo di ordinamento proveremmo l'affermazione "per ogni elenco ℓ esiste un elenco k tale che k è ordinato e k è un permutatiom di ℓ ". Se lo scriviamo in Coq ed estraiamo senza usarePropℓkkkℓ , otterremo:Prop
- "per tutti c'è k " ci darà una mappa che porta gli elenchi in elenchi,ℓk
sort
- "tale che sia ordinato" fornirà una funzione che attraversa k e verifica che sia ordinato, ek
verify
k
- " è una permutazione di ℓ " darà una permutazione che prende da ℓ a k . Si noti che non è solo una mappatura, ma anche la mappatura inversa insieme ai programmi che verificano che le due mappe siano realmente inverse.kℓ
pi
ℓkpi
Mentre le cose extra non sono del tutto inutili, in molte applicazioni vogliamo liberarcene e mantenerci giuste sort
. Questo può essere realizzato se usiamo per indicare " k è ordinato" e " k è una permutazione di ℓ ", ma non "per tuttiPropkkℓ c'è k ".ℓk
In generale, un modo comune per estrarre il codice è quello di considerare un'istruzione del modulo dove x è input, y è output e ϕ ( x , y ) spiega cosa significa che y è un output corretto. (Nell'esempio precedente A e B sono i tipi di elenchi e ϕ ( ℓ , k ) è " k è ordinato e k è una permutazione di ℓ .") Se ϕ è in P r o p, l' estrazione fornisce una mappa f :∀x:A.∃y:B.ϕ(x,y)xyϕ(x,y)yABϕ(ℓ,k)kkℓϕProp tale chef:A→B vale per ogni x ∈ A . Se ϕ è in S e t, otteniamo anche una funzione g tale che g ( x ) è la prova che ϕ ( x , f ( x ) ) vale, per tuttiϕ(x,f(x))x∈AϕSetgg(x)ϕ(x,f(x))x∈A. Spesso la prova è inutilmente computazionale e preferiamo liberarcene, specialmente quando è annidata profondamente in qualche altra affermazione. ci dà la possibilità di farlo.Prop
Aggiunto 2015/07/29: V'è un problema se potremmo evitare complessivamente ottimizzando automaticamente via "codice estratto inutile". In una certa misura possiamo farlo, ad esempio tutto il codice estratto dal frammento negativo della logica (materiale creato dal tipo vuoto, tipo di unità, prodotti) è inutile in quanto si sposta semplicemente attorno all'unità. Ma ci sono autentiche decisioni di progettazione che bisogna prendere quando si usa P r o p . Ecco un esempio semplice, in cui Σ significa che siamo in T y p e e ∃ significa che siamo in P r o pPropPropΣType∃Prop . Se estraiamo da
otterremo un programma che decompone n nel suo bit più basso b e i rimanenti bit k , ovvero calcola tutto. Se estraiamo da
Π n : N Σ b : { 0 , 1 } ∃ k : N
Πn:NΣb:{0,1}Σk:Nn=2⋅k+b
nbk
il programma calcolerà solo il bit più basso
b . La macchina non può dire quale sia quella corretta, l'utente deve dirgli quello che vuole.
Πn:NΣb:{0,1}∃k:Nn=2⋅k+b
b