Before: If λx:t.e : t' then t' = t1 -> t2 and x : t1 |- e : t2.
After: If λx:t.e : t' then t' ≡ t1 -> t2 : Type and x : t1 |- e : t2, and t1 : Type.
We prove this by induction on the typing derivation - there are two cases we have to consider.Case t-lam: in this case, t = t1 -> t2
t1 : type
x : t1 |- e : t2
------------------- t-lam
λx:t1.e |- t1 -> t2
We want to show t ≡ t1 -> t2 : Type, but because t = t1 -> t2, it suffices to show t1 -> t2 ≡ t1 -> t2 : Type. If we can show that t1 -> t2 : Type, then this rule:
c : k
----------- te-refl
c ≡ c : k
... will allow us to show t1 -> t2 ≡ t1 -> t2 : Type. How will we prove t1 -> t2 : Type? Well, the rule tf-arrow from the previous lecture says we can do so if we show t1 : type and t2 : type. We know t1 : type becasuse it is the first premise, and we know x : t1 |- t2 : type by regularity, which was mentioned in the previous lecture. A strengthing lemma then allows us to conclude t2 : type, which means we're done.
Case t-equiv: in this case, t = t1 -> t2
λx:t1.e2 : c'
c' ≡ t : Type
-------------- t-equiv
λx:t1.e2 : t
By induction, c' ≡ t1 -> t2 : Type, and x : t1 |- e : t2, and t1 : Type. By rule te-symm, t ≡ c', and by rule te-trans, t ≡ t1 -> t2 : Type, which completes the proof.
Before: If e1 e2 : t then e1 : t' -> t and e2 : t'
After: If e1 e2 : t then e1 : t' -> t and e2 : t'
Proof by induction on the derivation of e1 e2 : t. The base case (t-app) is as it was before, and the other case we need to consider is this one:
e1 e2 : c'
c' ≡ t : Type
-------------- t-equiv
e1 e2 : t
By induction, e1 : t1 -> c' and e2 : t1. We need to show e1 : t1 -> t - if we can show t1 -> t ≡ t1 -> c' : Type we can use rule t-equiv to do so.
By regularity, t1 : Type, so by rule te-equiv t1 ≡ t1 : Type, and furthermore because c' ≡ t : Type, t ≡ c' : Type by rule te-symm and therefore t1 -> t ≡ t1 -> c' : Type by rule te-arrow, and so we're done.
Theorem (Injectivity):
e : t
---------- t-useless
e : t
This doesn't interfere with our ability to induct over typing derivations,
even though it allows us to create arbitrarily large typing
derivations.
Why is this? We are ONLY intrested, whenever we do induction, on
finite derivations. This is why I pushed back so hard, on the
very first homework assignment,
on people who tried to do induction on the size of an
expression e instead of the size of a derivation of e : t.
A derivation tree is always finite by definition,
so when we say "If e:t...," that
always means "If we have a finite derivation of the judgment
e:t..." It doesn't matter that it may be arbitrarily large and
finite - induction means that as long as you call the induction hypotehsis
on the smaller derivation, you're making progress.
hd : ∀α:Type. Πn:nat. list (n+1) α -> α
tl : ∀α:Type. Πn:nat. list (n+1) α -> list n α
append : ∀α:Type. Πn:nat. Πm:nat. list n α -> list m α -> list (n + m) α
map : ∀α:Type. ∀β:Type. Πn:nat. (α -> β) -> list n α -> list n β