Type Safety ----------- Simply Typed Lambda Calculus Syntax: (types) t ::= bool | t1 -> t2 (expressions) e ::= x | true | false | if e1 then e2 else e3 | fun f (x:t1):t2 = e | e1 e2 (values) v ::= true | false | fun f (x:t1):t2 = e (contexts) G ::= . | G,x:t Call-by-value Evaluation: e --> e' ------------------------------------------------------- (E-if0) if e then e1 else e2 --> if e' then e1 else e2 ------------------------------------- (E-if1) if true then e1 else e2 --> e1 ------------------------------------- (E-if2) if false then e1 else e2 --> e2 e1 --> e1' -------------------- (E-app1) e1 e2 --> e1' e2 e2 --> e2' -------------------- (E-app2) v e2 --> v e2' ------------------------------------------------------------------- (E-app3) (fun f(x:t1):t2 = e) v --> e[v/x][(fun f(x:t1):t2 = e)/f] Typing: ----------------- (T-var) G |-- x : G(x) --------------------- (T-true) G |-- true : bool ---------------------- (T-false) G |-- false : bool G |-- e : bool G |-- e1 : t G |-- e2 : t ----------------------------------------------------- (T-if) G |-- if e then e1 else e2 : t G, f:t1->t2, x:t1 |-- e : t2 ----------------------------------------- (T-fun) G |-- fun f (x:t1):t2 = e : t1 -> t2 G |-- e1 : t1 -> t2 G |-- e2 : t1 ------------------------------------------ (T-app) G |-- e1 e2 : t2 ============================================= Canonical Forms Lemma Idea: Given a type, want to know something about the shape of the value If . |- v: t then If t = bool then v = true or v = false; If t = t1 -> t2 then v = fun f (x: t1) : t2 = e Proof: By inspection of the typing rules. ============================================= Exchange Lemma If G, x:t1, y:t2, G' |- e:t, then G, y:t2, x:t1, G' |- e:t. Proof by induction on derivation of G, y:t, x:t, G' |- e:t (Practice Exercise!) ============================================= Weakening Lemma If G |- e:t then G, x:t' |- e:t (provided x not in Dom(G)) Proof by induction on derivation of G |- e:t (Practice Exercise!) ============================================= Substitution Preserves Typing If G, x:t |- e:t' and G |- v:t then G |- e[v/x]:t'. Proof: By induction on the derivation of G, x:t |- e:t' A few example cases (one case for each typing rule) below: Case: ------------------------- G, x:t |- y: (G, x:t)(y) Subcase 1: x = y G, x:t |- x:t (note t = t') Must prove G |- x[v/x]:t Same as G |- v:t, which is our assumption Subcase 2: x != y Must prove G | - y[v/x]:t' Same as G |- y:t' which is G |- y: G(y) Case: ------------------- G, x:t |- true:bool Must prove G |- true[v/x]:bool Same as G |- true : bool (which can be proven by typing rule T-true) Case: (1) G, x:t |- e1:t1->t2 (2) G, x:t |- e2:t1 --------------------------------------------- G, x:t |- e1 e2 : t2 (3) G |- e1[v/x]:t1->t2 (1 and IH) (4) G |- e2[v/x]:t1 (2 and IH) Therefore, G |- (e1[v/x]) (e2[v/x]):t2 (3, 4, and typing rule T-app) Same as G |- (e1 e2)[v/x]:t2 (By definition of substitution) Type Preservation of One-step evaluation ---------------------------------------- If . |- e:t and e -> e' then . |- e': t Proof: By induction on the derivation of e -> e' Case: (1) e1 -> e1' ----------------------------------------------- if e1 then e2 else e3 -> if e1' then e2 else e3 (2) . |- if e1 then e2 else e3 : t (by assumption) (3) . |- e1 : bool (by 2 and inversion of T-if typing rule) (4) . |- e2 : t (by 2 and inversion of T-if typing rule) (5) . |- e3 : t (by 2 and inversion of T-if typing rule) (6) . |- e1': bool (by 1, 3, IH) . |- if e1' then e2 else e3 : t (by 6, 4, 5) Case: ----------------------------- if true then e2 else e3 -> e2 (1) . |- if true then e2 else e3 : t (by assumption) (2) . |- e2 : t (by 1 and inversion of T-if typing rule) Case: ----------------------------- if false then e2 else e3 -> e3 (1) . |- if false then e2 else e3 : t (by assumption) (2) . |- e3 : t (by 1 and inversion) Case: ----------------------------------------------------------- (fun f (x:t1) : t2 = e) v -> e[v/x][funf (x:t) : t2 = e /f] (1) |- (fun f (x:t1) : t2 = e) v : t2 (by assumption) (2) |- fun f (x:t1) : t2 = e : t1 -> t2 (by 1 and inversion of T-app) (3) |- v: t1 (by 1 and inversion of T-app) (4) f: t1 -> t2, x:t |- e: t2 (by 2 and inversion of T-fun) (5) f: t1 -> t2 |- e[v/x]:t2 (by 3 and 4 and substitution lemma) (6) |- e[v/x][fun f (x: t1) : t2 = e/f] : t2 (by 2, 5 and substitution lemma) (end of case) (cases for E-app1 and E-app2 similar to the case for E-if0 -- try them for practice) (end proof)