Lecture 18: Fω

November 5
While we started this in the last lecture, we will present Fω here.

Syntax

      k    ::= type | k -> k
      c, τ ::= α | c -> c | ∀α:k.c | λα:k.c | c c
      e    ::= x | λx:c.e | e e | Λα:k.e | e[c]
    

Type formation

We've got our own little static-semantics-ey thing for type constructors, which are classified by kinds.
      α : k |- c : k' 
      ----------------- tf-lambda
      λα:k.c : k -> k'
    
      c1 : type
      c2 : type
      ----------------- tf-arrow
      c1 -> c2 : type
    
      c1 : k -> k'
      c2 : k
      ----------------- tf-app
      c1 c2 : k'
    
      α : k |- c : type
      ----------------- tf-forall
      ∀α:k.c : type
    

Typing Rules

The true purpose of that new premise to the lambda rule that we threw in for System F is now revealed - since type constructors c can have kinds other than type, we actually do need to check that some constructor is a type.
      c : type
      x : c |- e : c'
      ----------------- t-lam
      λx:c.e : c -> c'
    
      e1 : c -> c'
      e2 : c
      ----------------- t-app
      e1 e2 : c'      
    
      α : k |- e : c
      ----------------- t-poly
      Λα:k.e : ∀α:k.c
    
      e : ∀α.c
      c': type
      ----------------- t-tapp
      e[c'] : [c'/α]c
    

Dynamic Semantics

Same as it ever was, same as it ever was. We have two rules defining e value...
      ----------------- v-lam
      λc:k.e value
    
      ----------------- v-lam
      λc:k.e value
    
And five rules defining e -> e'...
      e1 -> e'1
      ----------------------- e-app1
      e1 e2 -> e'1 e2
    
      e1 value
      e2 -> e'2
      ----------------------- e-app2
      e1 e2 -> e1 e'2
    
      e2 value
      ----------------------- e-applam
      (λx:c.e0) e2 -> [e2/x]e0
    
      e -> e'
      ----------------------- e-tapp
      e[c] -> e[c']
    
      ----------------------- e-tapp-poly
      (Λα:k.e0)[c] -> [c'/α]e0
    

Type Equivalence

This is new! We have a problem, which is that we've got this term: e = Λα : type -> type. λx:α int. 12. There was some difficulty in class ascertaining what the type of this term was, so let's be clear: you should be sure you are able to rapidly figure out the type of examples like this one.. Here is the typing derivation, where Γ = α : type -> type and Γ' = Γ, x : α int.
      --------------------- hyp --------------- tf-int
      Γ |- α : type -> type     Γ |- int : type
      ----------------------------------------- tf-app    ---------------- t-int
      Γ |- α int : type -> type                            Γ' |- 12 : int
      -------------------------------------------------------------------- t-lam
      α : type -> type |- λx:α int.12 : α int -> int
      --------------------------------------------------------------- t-poly
      Λα : type -> type. λx:α int. 12 : ∀α:type->type. α int -> int
    
However, trouble arises if we try to typecheck e[λβ:type.β]5, because we get that e[λβ:type.β]:(λβ:type.β) int -> int, but we WANT this term to have the type int -> int so that we can apply it to 5. Why do we know that (λβ:type.β) int -> int is equivalent to int -> int? We will define a notion of type equivalence c ≡ c : k, and add a typing rule:
      e : c'
      c ≡ c' : type
      -------------- t-equiv
      e : c
    
Here are (some of) the rules for the judgment c ≡ c : k.
      c : k
      ----------------------- te-refl
      c ≡ c : k
    
      c1 ≡ c2 : k
      ----------------------- te-symm
      c1 ≡ c2 : k
    
      c1 ≡ c2 : k
      c2 ≡ c3 : k
      ----------------------- te-trans
      c1 ≡ c3 : k
    
      c1 ≡ c'1 : k -> k'
      c2 ≡ c'2 : k'
      ----------------------- te-app
      c1 c2 ≡ c'1 c'2 : k'
    
      c1 : Type
      c2 : Type
      ----------------------- te-arrow
      c1 -> c2 : Type
    

etc, etc

This is the important rule, it actually talks about computation:
      α : k |- c0 : k'
      c2 : k
      --------------------------- te-trans
      (λα:k.c0) c2 ≡ [c2/α]c0 : k'
    

Regularity

If Γ |- e : c then Γ |- c : type.

If Γ |- c1 ≡ c2 : k, then Γ |- c1 : k and Γ |- c2 : k

You should be able to prove this!

Fixing progress and preservation

Canonical forms is no longer trivial, it is an inductive proof. Furthermore, in order for the induction to go to, we need to know that ∀αk.c ≡ c1 -> c2 can never happen, because those two types have different canonical forms. Quote from Karl: "The heart of canonical forms is consistency."

Lemma (Consistency) It is not the case that c1 -> c2 ≡ ∀α:k.c.
Big idea: you need to make sure you can't go through transitivity to make some big mess. The proof works because of a few ideas that we won't go into in the class: look up confluence, the Church-Rosser Theorem, and term rewriting theory if you are interested in knowing more.

Lemma (Canonical Forms)

To prove this, we have to do induction on the typing rule considering ALL cases, and use either induction or consistency as necessary.


$LastChangedDate: 2008-11-10 13:22:34 -0500 (Mon, 10 Nov 2008) $
$Author: rjsimmon $
$Rev: 1030 $