User:Rsimmons/Lecture 23: Typed Lambda Calculus in Twelf

From The Twelf Project
Jump to: navigation, search
This is Literate Twelf
Code: here
Status: %% OK %%
Output: here.

Syntax

We have a programming language that we started last time that we want to represent in Twelf. First the types "on paper:"

τ ::= unit | τ → τ

... and then, we can see those types in Twelf:

tp : type.

unit : tp.
arrow : tp -> tp -> tp.

Next, the terms "on paper:"

e ::= x | * | λx:τ.e | e e

... and in Twelf:

exp : type.

* : exp.
lam : tp -> (exp -> exp) -> exp.
app : exp -> exp -> exp.

Note that there is no case for "variables" x.

Static semantics (typing rules)

The old judgment for typing was e : τ - in other words, it was a two-place relation that took an expression and a type. We will describe this in Twelf as of.

of : exp -> tp -> type.

Okay - now we need to describe this rule:

-------- of/star
* : unit
of/star : of * unit.

Next we describe the more interesting rule for application:

e1 : τ → τ'
e2 : τ
------------ of/app
e1 e2 : τ'
of/app : of (app E1 E2) T
  <- of E1 (arrow T T')
  <- of E2 T.

The rule for abstractions uses a hypothetical! We're going to pull this off by using a Pi-binding (represented in Twelf as {x: exp} to create a fresh variable, and then using an LF arrow -> to say that you are proving of (E x) T' under the hypothetical assumption that of x T, which matches exactly with how we've been using assumptions all semester.

x : τ |- e : τ'
--------------- of/lam
λx:τ.e : τ → τ'
of/lam : of (lam T ([x] E x)) (arrow T T')
  <- ({x: exp} of x T -> of (E x) T').

Example derivation

On paper:

-------------------- hyp
x : unit |- e : unit
----------------------- of/lam
λx:unit.e : unit → unit

In Twelf:

_ = of/lam (_) : of (lam unit ([x] x)) (arrow unit unit).
Twelf 1.7.1+ (r1896, built 05/05/15 at 12:56:43 on yazoo.plparty.org)

_ : {X1:{x:exp} of x unit -> of x unit} of (lam unit ([x:exp] x)) (arrow unit unit) = [X1:{x:exp} of x unit -> of x unit] of/lam ([x:exp] [x1:of x unit] X1 x x1).

%% OK %%

Okay, it looks like we need something (X1) of type {x:exp} of x unit -> of x unit, in other words, something of type Πx:exp. of x unit -> of x unit - this is the type of a (dependent) function that takes a term with type exp (call it x), and returns a (not dependent) function that takes a term with type of x unit and then returns a term with type of x unit. In other words, take an expression and then give me the identity function!

You guys should know what to do from here (it's just like what you were doing in Homework 5, but for LF instead of System F!). We want λx:exp. λd:of x unit. d.

_ = of/lam ([x: exp] [d: of x unit] d) : of (lam unit ([x] x)) (arrow unit unit).
Twelf 1.7.1+ (r1896, built 05/05/15 at 12:56:43 on yazoo.plparty.org)

_ : of (lam unit ([x:exp] x)) (arrow unit unit) = of/lam ([x:exp] [d:of x unit] d).

%% OK %%

The absolutely correct observation made about this in class was that Hypotheticals in the object language are represented as functions in the metalanguage.

Dynamic semantics (evaluation rules)

First, values e value:

------------ value/star
* value
------------ value/lam
λx:τ.e value
value : exp -> type.

value/star : value *.

value/lam : value (lam T ([x] E x)).

Next, evaluation rules e -> e

e1 -> e'1
--------------------- step/app1
e1 e2 -> e'1 e2
e1 value
e2 -> e'2
--------------------- step/app2
e1 e2 -> e1 e'2
e2 value
--------------------- step/applam
(λx:τ.e) e2 -> e1 e'2
step : exp -> exp -> type.

step/app1 : step (app E1 E2) (app E1' E2)
  <- step E1 E1'.

step/app2 : step (app E1 E2) (app E1 E2')
  <- value E1
  <- step E2 E2'.

step/applam : step (app (lam T ([x] E x)) E2) (E E2)
  <- value E2.

Coda: Type Safety

Last time, we used the commutativity of addition to write a logic program that took in a term of type sum N1 N2 N3 and produced a term of type sum N2 N1 N3. In other words, we proved this theorem:

Sum commutes: if sum(n1, n2, n3) then sum(n1, n1, n1)

...by writing this in Twelf and proving it to be a total relation:

sum-commutes : sum N1 N2 N3 -> sum N2 N1 N3 -> type.
%mode sum-commutes +D1 -D2.

So we an prove this theorem:

Preservation: if e : τ and e -> e', then e' : τ

...by writing this in Twelf and proving it to be a total relation:

preservation : of E T -> step E E' -> of E' T -> type.
%mode preservation +D1 +D2 -D2.

Thus ends today's lesson.