Innanzitutto, per ribadire uno dei punti del codice, il calcolo delle costruzioni induttive (su cui si basa il kernel di Coq) è molto diverso dal calcolo delle costruzioni. È meglio pensare che inizi dalla teoria dei tipi di Martin-Löf con gli universi, e poi aggiunga una specie di Prop in fondo alla gerarchia dei tipi. Questa è una bestia molto diversa dall'originale CoC, che è meglio pensare come una versione dipendente di F-omega. (Ad esempio, CiC ha modelli teorici stabiliti e il CoC no.)
Detto questo, il lambda-cubo (di cui il CoC è membro) viene in genere presentato come un sistema di tipo puro per ragioni di economia nel numero di regole di battitura. Trattando specie, tipi e termini come elementi della stessa categoria sintattica, puoi scrivere molte meno regole e anche le tue prove diventano un po 'meno ridondanti.
Tuttavia, per capire, può essere utile separare esplicitamente le diverse categorie. Possiamo introdurre tre categorie sintattiche, tipi (spaziati dal metavariabile k
), tipi (spaziati dal metavariabile A
) e termini (spaziati dal metavariabile e
). Quindi tutti e otto i sistemi possono essere intesi come variazioni su ciò che è consentito a ciascuno dei tre livelli.
λ → (Calcolo lambda semplicemente digitato)
k ::= ∗
A ::= p | A → B
e ::= x | λx:A.e | e e
Questo è il calcolo lambda tipizzato di base. C'è un solo tipo ∗
, che è il tipo di tipi. I tipi stessi sono tipi atomici p
e tipi di funzione A → B
. I termini sono variabili, astrazioni o applicazioni.
λω_ (STLC + operatori di tipo superiore)
k ::= ∗ | k → k
A ::= a | p | A → B | λa:k.A | A B
e ::= x | λx:A.e | e e
L'STLC consente l'astrazione solo a livello di termini. Se lo aggiungiamo a livello di tipi, aggiungiamo un nuovo tipo k → k
che è il tipo di funzioni a livello di tipo e anche astrazione λa:k.A
e applicazione A B
a livello di tipo. Quindi ora non abbiamo il polimorfismo, ma abbiamo operatori di tipo.
Se la memoria serve, questo sistema non ha più potenza computazionale di STLC; ti dà solo la possibilità di abbreviare i tipi.
λ2 (Sistema F)
k ::= ∗
A ::= a | p | A → B | ∀a:k. A
e ::= x | λx:A.e | e e | Λa:k. e | e [A]
Invece di aggiungere operatori di tipo, avremmo potuto aggiungere polimorfismo. A livello di tipo, aggiungiamo ∀a:k. A
quale è un tipo polimorfico precedente e, a livello di termine, aggiungiamo astrazione sui tipi Λa:k. e
e l'applicazione del tipo e [A]
.
Questo sistema è molto più potente dell'STLC - è potente quanto l'aritmetica del secondo ordine.
λω (Sistema F-omega)
k ::= ∗ | k → k
A ::= a | p | A → B | ∀a:k. A | λa:k.A | A B
e ::= x | λx:A.e | e e | Λa:k. e | e [A]
Se abbiamo sia operatori di tipo che polimorfismo, otteniamo F-omega. Questo sistema è più o meno la teoria del tipo di kernel della maggior parte dei linguaggi funzionali moderni (come ML e Haskell). È anche molto più potente del Sistema F - è equivalente in termini di forza all'aritmetica di ordine superiore.
λP (LF)
k ::= ∗ | Πx:A. k
A ::= a | p | Πx:A. B | Λx:A.B | A [e]
e ::= x | λx:A.e | e e
Invece del polimorfismo, avremmo potuto andare nella direzione della dipendenza da un semplice calcolo lambda. Se hai permesso al tipo di funzione di lasciare che il suo argomento fosse usato nel tipo restituito (cioè scrivi Πx:A. B(x)
invece di A → B
), otterrai λP. Per renderlo davvero utile, dobbiamo estendere l'insieme di tipi con un tipo di operatori di tipo che prendono termini come argomenti Πx:A. k
, e quindi dobbiamo aggiungere anche un'astrazione Λx:A.B
e un'applicazione corrispondenti A [e]
a livello di tipo.
Questo sistema viene talvolta chiamato LF o Edinburgh Logical Framework.
Ha la stessa forza computazionale del calcolo lambda tipizzato in modo semplice.
λP2 (nessun nome speciale)
k ::= ∗ | Πx:A. k
A ::= a | p | Πx:A. B | ∀a:k.A | Λx:A.B | A [e]
e ::= x | λx:A.e | e e | Λa:k. e | e [A]
Possiamo anche aggiungere polimorfismo a λP, per ottenere λP2. Questo sistema non viene spesso utilizzato, quindi non ha un nome particolare. (L'unico documento che ho letto che l'ha usato è l' induzione di Herman Geuvers non derivabile nella teoria del tipo dipendente dal secondo ordine .)
Questo sistema ha la stessa forza del sistema F.
λPω_ (nessun nome speciale)
k ::= ∗ | Πx:A. k | Πa:k. k'
A ::= a | p | Πx:A. B | Λx:A.B | A [e] | λa:k.A | A B
e ::= x | λx:A.e | e e
Potremmo anche aggiungere operatori di tipo a λP, per ottenere λPω_. Ciò comporta l'aggiunta di un tipo Πa:k. k'
per operatori di tipo e la corrispondente astrazione Λx:A.B
e applicazione a livello di tipo A [e]
.
Dal momento che non c'è ancora nessun salto nella forza computazionale rispetto allo STLC, questo sistema dovrebbe anche costituire una base eccellente per un framework logico, ma nessuno lo ha fatto.
λPω (il calcolo delle costruzioni)
k ::= ∗ | Πx:A. k | Πa:k. k'
A ::= a | p | Πx:A. B | ∀a:k.A | Λx:A.B | A [e] | λa:k.A | A B
e ::= x | λx:A.e | e e | Λa:k. e | e [A]
Infine, arriviamo a λPω, il calcolo delle costruzioni, prendendo λPω_ e aggiungendo un tipo polimorfico precedente ∀a:k.A
e astrazione a livello di termine Λa:k. e
e applicazione e [A]
per esso.
I tipi di questo sistema sono molto più espressivi che in F-omega, ma hanno la stessa forza computazionale.
soft-question
. Non vedo una domanda veramente tecnica qui. Forse puoi essere un po 'più specifico su ciò che stai chiedendo?