Course Webpage for B522 Programming Language Foundations, Spring 2020, Indiana University
module GradualTyping where
import Syntax
open import Data.Bool renaming (Bool to πΉ)
open import Data.List using (List; []; _β·_)
open import Data.Nat using (β; zero; suc)
open import Data.Product using (_Γ_; Ξ£; Ξ£-syntax; β; β-syntax; projβ; projβ)
renaming (_,_ to β¨_,_β©)
open import Relation.Binary.PropositionalEquality
using (_β‘_; _β’_; refl; sym; cong; congβ)
open import Relation.Nullary using (Β¬_)
The idea here is to use Agda values as primitive constants. We include natural numbers, Booleans, and Agda functions over naturals and Booleans.
The Base
and Prim
data types describe the types of constants.
data Base : Set where
B-Nat : Base
B-Bool : Base
data Prim : Set where
base : Base β Prim
_β_ : Base β Prim β Prim
The base-rep
and rep
functions map from the type descriptors to
the Agda types that we will use to represent the constants.
base-rep : Base β Set
base-rep B-Nat = β
base-rep B-Bool = πΉ
rep : Prim β Set
rep (base b) = base-rep b
rep (b β p) = base-rep b β rep p
data BaseTy : Set where
Nat : BaseTy
Bool : BaseTy
data Type : Set where
`_ : BaseTy β Type
β : Type
_β_ : Type β Type β Type
_`Γ_ : Type β Type β Type
_`β_ : Type β Type β Type
infix 5 _~_
data _~_ : Type β Type β Set where
unk~L : β {A} β β ~ A
unk~R : β {A} β A ~ β
base~ : β{ΞΉ} β ` ΞΉ ~ ` ΞΉ
fun~ : β{A B A' B'}
β A' ~ A β B ~ B'
-------------------
β (A β B) ~ (A' β B')
pair~ : β{A B A' B'}
β A ~ A' β B ~ B'
-------------------
β (A `Γ B) ~ (A' `Γ B')
sum~ : β{A B A' B'}
β A ~ A' β B ~ B'
-------------------
β (A `β B) ~ (A' `β B')
β¨ : β{A B : Type} β (c : A ~ B) β Type
β¨ {.β} {B} unk~L = B
β¨ {A} {.β} unk~R = A
β¨ {(` ΞΉ)} {.(` _)} base~ = ` ΞΉ
β¨ {.(_ β _)} {.(_ β _)} (fun~ c d) = (β¨ c) β (β¨ d)
β¨ {.(_ `Γ _)} {.(_ `Γ _)} (pair~ c d) = (β¨ c) `Γ (β¨ d)
β¨ {.(_ `β _)} {.(_ `β _)} (sum~ c d) = (β¨ c) `β (β¨ d)
We use the abstract-binding-trees library to represent terms.
data Op : Set where
op-lam : Type β Op
op-app : Op
op-const : (p : Prim) β rep p β Op
op-pair : Op
op-fst : Op
op-snd : Op
op-inl : Op
op-inr : Op
op-case : Op
sig : Op β List β
sig (op-lam A) = 1 β· []
sig op-app = 0 β· 0 β· []
sig (op-const p k) = []
sig op-pair = 0 β· 0 β· []
sig op-fst = 0 β· []
sig op-snd = 0 β· []
sig op-inl = 0 β· []
sig op-inr = 0 β· []
sig op-case = 0 β· 1 β· 1 β· []
open Syntax using (Rename; _β’_; β; id; ext; β¦_β¦)
open Syntax.OpSig Op sig
using (`_; _β¦
_β¦; cons; nil; bind; ast)
renaming (ABT to Term)
infixl 7 _Β·_
pattern $ p k = (op-const p k) β¦
nil β¦
pattern Ζ_Λ_ A N = op-lam A β¦
cons (bind (ast N)) nil β¦
pattern _Β·_ L M = op-app β¦
cons (ast L) (cons (ast M) nil) β¦
pattern pair L M = op-pair β¦
cons (ast L) (cons (ast M) nil) β¦
pattern fst M = op-fst β¦
cons (ast M) nil β¦
pattern snd M = op-snd β¦
cons (ast M) nil β¦
pattern inl M = op-inl β¦
cons (ast M) nil β¦
pattern inr M = op-inr β¦
cons (ast M) nil β¦
pattern case L M N = op-case β¦
cons (ast L) (cons (bind (ast M))
(cons (bind (ast N)) nil)) β¦
typeof-base : Base β Type
typeof-base B-Nat = ` Nat
typeof-base B-Bool = ` Bool
typeof : Prim β Type
typeof (base b) = typeof-base b
typeof (b β p) = typeof-base b β typeof p
data Context : Set where
β
: Context
_,_ : Context β Type β Context
infix 4 _β_β¦_
data _β_β¦_ : Context β β β Type β Set where
Z : β {Ξ A}
------------------
β Ξ , A β 0 β¦ A
S : β {Ξ x A B}
β Ξ β x β¦ A
------------------
β Ξ , B β (suc x) β¦ A
data _βΉ_β_ : Type β Type β Type β Set where
matchββ : β{A B} β (A β B) βΉ A β B
matchββ : β βΉ β β β
data _βΉ_Γ_ : Type β Type β Type β Set where
matchΓΓ : β{A B} β (A `Γ B) βΉ A Γ B
matchΓβ : β βΉ β Γ β
data _βΉ_β_ : Type β Type β Type β Set where
matchββ : β{A B} β (A `β B) βΉ A β B
matchββ : β βΉ β β β
infix 4 _β’G_β¦_
data _β’G_β¦_ : Context β Term β Type β Set where
-- Axiom
β’` : β {Ξ x A}
β Ξ β x β¦ A
-----------
β Ξ β’G ` x β¦ A
-- β-I
β’Ζ : β {Ξ N A B}
β Ξ , A β’G N β¦ B
-------------------
β Ξ β’G (Ζ A Λ N) β¦ A β B
-- β-E
β’Β· : β {Ξ L M A Aβ Aβ B}
β Ξ β’G L β¦ A
β Ξ β’G M β¦ B
β A βΉ Aβ β Aβ
β Aβ ~ B
--------------
β Ξ β’G L Β· M β¦ Aβ
β’$ : β{Ξ p k A}
β A β‘ typeof p
-------------
β Ξ β’G $ p k β¦ A
β’pair : β {Ξ A B}{M N : Term}
β Ξ β’G M β¦ A β Ξ β’G N β¦ B
-----------------------
β Ξ β’G (pair M N) β¦ A `Γ B
β’fst : β {Ξ A Aβ Aβ}{M : Term}
β Ξ β’G M β¦ A
β A βΉ Aβ Γ Aβ
-------------------------
β Ξ β’G fst M β¦ Aβ
β’snd : β {Ξ A Aβ Aβ}{M : Term}
β Ξ β’G M β¦ A
β A βΉ Aβ Γ Aβ
-------------------------
β Ξ β’G (snd M) β¦ Aβ
β’inl : β {Ξ A}{M : Term}
β (B : Type)
β Ξ β’G M β¦ A
-----------------------
β Ξ β’G (inl M) β¦ A `β B
β’inr : β {Ξ B}{M : Term}
β (A : Type)
β Ξ β’G M β¦ B
-----------------------
β Ξ β’G (inr M) β¦ A `β B
β’case : β{Ξ A Aβ Aβ B Bβ Bβ C Cβ Cβ}{L M N : Term}
β Ξ β’G L β¦ A
β Ξ β’G M β¦ B
β Ξ β’G N β¦ C
β {ma : A βΉ Aβ β Aβ }
β {mb : B βΉ Bβ β Bβ }
β {mc : C βΉ Cβ β Cβ }
β {ab : Aβ ~ Bβ}
β {ac : Aβ ~ Cβ}
β {bc : Bβ ~ Cβ}
----------------------------------
β Ξ β’G (case L M N) β¦ β¨ bc
data cc-Op : Set where
op-cc-lam : cc-Op
op-cc-app : cc-Op
op-cc-const : (p : Prim) β rep p β cc-Op
op-cc-pair : cc-Op
op-cc-fst : cc-Op
op-cc-snd : cc-Op
op-cc-inl : cc-Op
op-cc-inr : cc-Op
op-cc-case : cc-Op
op-cc-cast : Type β Type β cc-Op
op-cc-blame : cc-Op
cc-sig : cc-Op β List β
cc-sig op-cc-lam = 1 β· []
cc-sig op-cc-app = 0 β· 0 β· []
cc-sig (op-cc-const p k) = []
cc-sig op-cc-pair = 0 β· 0 β· []
cc-sig op-cc-fst = 0 β· []
cc-sig op-cc-snd = 0 β· []
cc-sig op-cc-inl = 0 β· []
cc-sig op-cc-inr = 0 β· []
cc-sig op-cc-case = 0 β· 1 β· 1 β· []
cc-sig (op-cc-cast A B) = 0 β· []
cc-sig op-cc-blame = []
open Syntax using (Rename; _β’_; β; id; ext; β¦_β¦)
open Syntax.OpSig cc-Op cc-sig
using (_[_]; Subst; βͺ_β«; β¦_β§; exts; rename)
renaming (`_ to ^_; _β¦
_β¦ to _γ_γ; ABT to cc-Term;
cons to cc-cons; nil to cc-nil; bind to cc-bind; ast to cc-ast)
pattern ! p k = (op-cc-const p k)γ cc-nil γ
pattern Ζ N = op-cc-lam γ cc-cons (cc-bind (cc-ast N)) cc-nil γ
pattern app L M = op-cc-app γ cc-cons (cc-ast L) (cc-cons (cc-ast M) cc-nil) γ
pattern cc-pair L M = op-cc-pair γ cc-cons (cc-ast L) (cc-cons (cc-ast M) cc-nil) γ
pattern cc-fst M = op-cc-fst γ cc-cons (cc-ast M) cc-nil γ
pattern cc-snd M = op-cc-snd γ cc-cons (cc-ast M) cc-nil γ
pattern cc-inl M = op-cc-inl γ cc-cons (cc-ast M) cc-nil γ
pattern cc-inr M = op-cc-inr γ cc-cons (cc-ast M) cc-nil γ
pattern cc-case L M N = op-cc-case γ cc-cons (cc-ast L) (cc-cons (cc-bind (cc-ast M))
(cc-cons (cc-bind (cc-ast N)) cc-nil)) γ
pattern _β¨_β_β© M A B = op-cc-cast A B γ cc-cons (cc-ast M) cc-nil γ
pattern blame = op-cc-blame γ cc-nil γ
infix 4 _β’_β¦_
data _β’_β¦_ : Context β cc-Term β Type β Set where
-- Axiom
β’^ : β {Ξ x A}
β Ξ β x β¦ A
-----------
β Ξ β’ ^ x β¦ A
-- β-I
β’Ζ : β {Ξ A B}{N : cc-Term}
β Ξ , A β’ N β¦ B
-------------------
β Ξ β’ Ζ N β¦ A β B
-- β-E
β’Β· : β {Ξ L M A B}
β Ξ β’ L β¦ A β B
β Ξ β’ M β¦ A
--------------
β Ξ β’ app L M β¦ B
β’! : β{Ξ p k A}
β A β‘ typeof p
-------------
β Ξ β’ ! p k β¦ A
β’pair : β {Ξ A B}{M N : cc-Term}
β Ξ β’ M β¦ A β Ξ β’ N β¦ B
-----------------------
β Ξ β’ (cc-pair M N) β¦ A `Γ B
β’fstΓ : β {Ξ A B}{M : cc-Term}
β Ξ β’ M β¦ A `Γ B
-------------------------
β Ξ β’ cc-fst M β¦ A
β’sndΓ : β {Ξ A B}{M : cc-Term}
β Ξ β’ M β¦ A `Γ B
-------------------------
β Ξ β’ (cc-snd M) β¦ B
β’inl : β {Ξ A}{M : cc-Term}
β (B : Type)
β Ξ β’ M β¦ A
-----------------------
β Ξ β’ (cc-inl M) β¦ A `β B
β’inr : β {Ξ B}{M : cc-Term}
β (A : Type)
β Ξ β’ M β¦ B
-----------------------
β Ξ β’ (cc-inr M) β¦ A `β B
β’case : β{Ξ A B C}{L M N : cc-Term}
β Ξ β’ L β¦ A `β B
β Ξ β’ M β¦ A β C
β Ξ β’ N β¦ B β C
----------------------------------
β Ξ β’ (cc-case L M N) β¦ C
β’cast : β {Ξ A B}{M : cc-Term}
β Ξ β’ M β¦ A
β A ~ B
-----------------------
β Ξ β’ M β¨ A β B β© β¦ B
β’blame : β {Ξ A}
-------------
β Ξ β’ blame β¦ A
compile : β{Ξ A}{M : Term} β Ξ β’G M β¦ A β cc-Term
compile (β’` {x = x} xβ) = ^ x
compile (β’Ζ {N = N} β’N) = Ζ (compile β’N)
compile (β’Β· {L = L}{M}{A}{Aβ}{Aβ}{B} β’L β’M m cn) =
let L' = (compile β’L) β¨ A β (Aβ β Aβ) β© in
let M' = (compile β’M) β¨ B β Aβ β© in
app L' M'
compile (β’$ {p = p}{k} eq) = ! p k
compile (β’pair β’L β’M) =
let L' = compile β’L in
let M' = compile β’M in
cc-pair L' M'
compile (β’fst {A = A}{Aβ}{Aβ} β’M m) =
let M' = (compile β’M) β¨ A β (Aβ `Γ Aβ) β© in
cc-fst M'
compile (β’snd {A = A}{Aβ}{Aβ} β’M m) =
let M' = (compile β’M) β¨ A β (Aβ `Γ Aβ) β© in
cc-snd M'
compile (β’inl B β’M) = cc-inl (compile β’M)
compile (β’inr B β’M) = cc-inr (compile β’M)
compile (β’case {Ξ}{A}{Aβ}{Aβ}{B}{Bβ}{Bβ}{C}{Cβ}{Cβ} β’L β’M β’N
{ma}{mb}{mc}{ab}{ac}{bc}) =
let L' = (compile β’L) β¨ A β (Aβ `β Aβ) β©
β¨ (Aβ `β Aβ) β (Bβ `β Cβ) β© in
let M' = (compile β’M) β¨ B β (Bβ β Bβ) β©
β¨ (Bβ β Bβ) β (Bβ β β¨ bc) β© in
let N' = (compile β’N) β¨ C β (Cβ β Cβ) β©
β¨ (Cβ β Cβ) β (Cβ β β¨ bc) β© in
cc-case L' M' N'
data Value : cc-Term β Set where
V-Ζ : {N : cc-Term}
-----------
β Value (Ζ N)
V-const : β {p k}
-------------
β Value (! p k)
V-pair : β {V W : cc-Term}
β Value V β Value W
-----------------
β Value (cc-pair V W)
V-inl : β {V : cc-Term}
β Value V
--------------------------
β Value (cc-inl V)
V-inr : β {V : cc-Term}
β Value V
--------------------------
β Value (cc-inr V)
V-cast : β {A : Type}{V : cc-Term}
β Value V
---------------
β Value (V β¨ A β β β©)
data Frame : Set where
F-Β·β :
cc-Term
β Frame
F-Β·β :
(M : cc-Term) β Value M
β Frame
F-Γβ :
cc-Term
β Frame
F-Γβ :
cc-Term
β Frame
F-fst : Frame
F-snd : Frame
F-inl : Frame
F-inr : Frame
F-case :
cc-Term
β cc-Term
β Frame
F-cast :
Type β Type
β Frame
plug : cc-Term β Frame β cc-Term
plug L (F-Β·β M) = app L M
plug M (F-Β·β L v) = app L M
plug L (F-Γβ M) = cc-pair M L
plug M (F-Γβ L) = cc-pair M L
plug M (F-fst) = cc-fst M
plug M (F-snd) = cc-snd M
plug M (F-inl) = cc-inl M
plug M (F-inr) = cc-inr M
plug L (F-case M N) = cc-case L M N
plug M (F-cast A B) = M β¨ A β B β©
infix 2 _ββ_
data _ββ_ : cc-Term β cc-Term β Set where
ΞΎ : β {M Mβ² : cc-Term} {F : Frame}
β M ββ Mβ²
---------------------
β plug M F ββ plug Mβ² F
ΞΎ-blame : {F : Frame}
---------------------
β plug blame F ββ blame
Ξ² : β {N W : cc-Term}
β Value W
----------------------
β app (Ζ N) W ββ N [ W ]
Ξ΄ : β {p}{b} {f : base-rep b β rep p} {k : base-rep b}
-------------------------------------------------------
β app (! (b β p) f) (! (base b) k) ββ ! p (f k)
Ξ²-fst : β {V W : cc-Term}
β Value V β Value W
--------------------
β cc-fst (cc-pair V W) ββ V
Ξ²-snd : β {V : cc-Term} {W : cc-Term}
β Value V β Value W
--------------------
β cc-snd (cc-pair V W) ββ W
Ξ²-caseL : β {V L M : cc-Term}
β Value V
---------------------------------
β cc-case (cc-inl V) L M ββ app L V
Ξ²-caseR : β {V L M : cc-Term}
β Value V
---------------------------------
β cc-case (cc-inr V) L M ββ app M V
castβ : β {V : cc-Term} {A B C D : Type}
β (v : Value V)
----------------------------------------------------------------
β V β¨ (A β B) β (C β D) β© ββ Ζ (app V ((^ 0) β¨ C β A β©)) β¨ B β D β©
castβ : β {V : cc-Term} {A B : Type}
β (v : Value V) β A ~ B
------------------------------------
β V β¨ A β β β© β¨ β β B β© ββ V β¨ A β B β©
cast-fail : β {V : cc-Term} {A B : Type}
β (v : Value V) β Β¬ (A ~ B)
------------------------------
β V β¨ A β β β© β¨ β β B β© ββ blame
castΓ : β {V : cc-Term} {A B C D : Type}
β (v : Value V)
-----------------------------------------------------------
β V β¨ (A `Γ B) β (C `Γ D) β© ββ cc-pair ((cc-fst V) β¨ A β C β©)
((cc-snd V) β¨ B β D β©)
cast-inl : β {V : cc-Term} {A B C D : Type}
β (v : Value V)
--------------------------------------------------------
β cc-inl V β¨ (A `β B) β (C `β D) β© ββ cc-inl (V β¨ A β C β©)
cast-inr : β {V : cc-Term} {A B C D : Type}
β (v : Value V)
--------------------------------------------------------
β cc-inr V β¨ (A `β B) β (C `β D) β© ββ cc-inr (V β¨ B β D β©)
infix 2 _ββ _
infixr 2 _βββ¨_β©_
infix 3 _β
data _ββ _ : cc-Term β cc-Term β Set where
_β : β (M : cc-Term)
---------
β M ββ M
_βββ¨_β©_ : β (L : cc-Term) {M N : cc-Term}
β L ββ M
β M ββ N
---------
β L ββ N