Lecture 2: indexed datatypes and dependent pattern matching
Jesper Cockx
1 September 2019
The indices of a datatype capture important invariants of our programs:
Two styles of verification:
Intrinsic verification is a good fit for complex programs with simple invariants
For small programs and/or complex invariants, extrinsic verification may work better
By encoding invariants in the types, they can guide the construction of our programs:
()
)n : ℕ
, then Vec A n
consists of vectors of A
s of length n
:
data Vec (A : Set) : ℕ → Set where [] : Vec A 0 _∷_ : ∀ {n} → A → Vec A n → Vec A (suc n)Compare to lists:
data List (A : Set) : Set where [] : List A _∷_ : A → List A → List A
Question: what should be the type of head
and tail
functions on Vec
?
How about _++_
(append) and map
?
n
is a number between 0
and n-1
:
data Fin : ℕ → Set where zero : ∀ {n} → Fin (suc n) suc : ∀ {n} → Fin n → Fin (suc n) lookup : ∀ {A} {n} → Vec A n → Fin n → A lookup xs i = ⋯
lookup
is a total function!
Our correct-by-construction typechecker produces intrinsically well-typed syntax:
data Type : Set where int bool : Type data Exp : Type → Set -- ...
A term e : Exp Γ t
is a well-typed WHILE expression in context Γ
.
data Op : (dom codom : Type) → Set where plus : Op int int gt : Op int bool and : Op bool bool data Exp where eInt : (i : ℤ) → Exp int eBool : (b : Bool) → Exp bool eOp : ∀{t t'} (op : Op t t') → (e e' : Exp t) → Exp t'
See WellTypedSyntax.agda.
C
types as Agda types:
Val : Type → Set Val int = ℤ Val bool = Bool
We can now define eval
for well-typed expressions:
eval : ∀ {t} → Exp t → Val t eval = ⋯
that always returns a value (bye bye Maybe
!)
See definition of eval
in Interpreter.agda.
data Type : Set where int bool : Type Cxt = List TypeA variable is an index into the context
data Var : (Γ : Cxt) (t : Type) → Set where here : ∀ {Γ t} → Var (t ∷ Γ) t there : ∀ {Γ t t'} → Var Γ t → Var (t' ∷ Γ) t
(compare this to the definition of Fin
)
The type Exp
is now parametrized by a context Γ
:
data Exp (Γ : Cxt) : Type → Set where -- ... eVar : ∀{t} (x : Var Γ t) → Exp Γ t
See WellTypedSyntax.agda.
All
typeAll P xs
contains an element of P x
for each x
in the list xs
:
data All {A : Set} (P : A → Set) : List A → Set where [] : All P [] _∷_ : ∀ {x xs} → P x → All P xs → All P (x ∷ xs)
All
variables
Val : Type → Set Val int = ℤ Val bool = Bool Env : Cxt → Set Env Γ = All Val Γ
We can now extend eval
to expressions with variables:
eval : ∀ {Γ} {t} → Env Γ → Exp Γ t → Val t eval = ⋯
See definition of eval
in Interpreter.agda.
Extend the well-typed syntax and interpreter with the syntactic constructions you added before.