Download
programming languages and compilers cs 421 n.
Skip this Video
Loading SlideShow in 5 Seconds..
Programming Languages and Compilers (CS 421) PowerPoint Presentation
Download Presentation
Programming Languages and Compilers (CS 421)

Programming Languages and Compilers (CS 421)

1 Vues Download Presentation
Télécharger la présentation

Programming Languages and Compilers (CS 421)

- - - - - - - - - - - - - - - - - - - - - - - - - - - E N D - - - - - - - - - - - - - - - - - - - - - - - - - - -
Presentation Transcript

  1. Programming Languages and Compilers (CS 421) Grigore Rosu 2110 SC, UIUC http://courses.engr.illinois.edu/cs421 Slides by Elsa Gunter, based in part on slides by Mattox Beckman, as updated by Vikram Adve and Gul Agha

  2. Objective • Learn type inference and the distinction between type inference and type checking • Understand how type inference algorithmically reduces to unification • Learn unification and how to implement it

  3. Type Inference

  4. Two Problems • Type checking • Question: Does exp. e have type in env? • Answer: Yes / No • Method: Type derivation • Typability • Question Does exp. e have some type in env. ? If so, what is it? • Answer: Type / error • Method: Type inference

  5. Type Inference - Outline • Begin by assigning a type variable as the type of the whole expression • Decompose the expression into component expressions • Use typing rules to generate constraints on components and whole • Recursively find substitution that solves typing judgment of first subcomponent • Apply substitution to next subcomponent and find substitution solving it; compose with first, etc. • Apply comp of all substitution to orig. type var. to get answer

  6. Type Inference - Example • What type can we give to (fun x -> fun f -> f (f x)) • Start with a type variable and then look at the way the term is constructed

  7. Type Inference - Example • First approximate: [ ] |- (fun x -> fun f -> f (f x)) :  • Second approximate: use fun rule [x : ] |- (fun f -> f (f x)) :  [ ] |- (fun x -> fun f -> f (f x)) :  • Remember constraint   ()

  8. Type Inference - Example • Third approximate: use fun rule [f :  ; x : ] |- f (f x) :  [x : ] |- (fun f -> f (f x)) :  [ ] |- (fun x -> fun f -> f(f x)) :  •   ();   (  )

  9. Type Inference - Example • Fourth approximate: use app rule [f:; x:]|- f :   [f:; x:]|- f x :  [f :  ; x : ] |- (f (f x)) :  [x : ] |- (fun f -> f (f x)) :  [ ] |- (fun x -> fun f -> f (f x)) :  •   ();   (  )

  10. Type Inference - Example • Fifth approximate: use var rule, get constraint  , Solve with same • Apply to next sub-proof [f:; x:]|- f :   [f:; x:]|- f x :  [f :  ; x : ] |- (f (f x)) :  [x : ] |- (fun f -> f (f x)) :  [ ] |- (fun x -> fun f -> f (f x)) :  •   ();   (  )

  11. Type Inference - Example • Current subst: { } … [f: ; x:]|- f x :  [f :  ; x : ] |- (f (f x)) :  [x : ] |- (fun f -> f (f x)) :  [ ] |- (fun x -> fun f -> f (f x)) :  •   ();   (  )

  12. Type Inference - Example • Current subst: { } [f:; x:]|- f:z [f:; x:]|- x:z … [f: ; x:]|- f x :  [f :  ; x : ] |- (f (f x)) :  [x : ] |- (fun f -> f (f x)) :  [ ] |- (fun x -> fun f -> f (f x)) :  •   ();   (  )

  13. Type Inference - Example • Current subst: { } • Var rule: Solve z  Unification [f:; x:]|- f:z [f:; x:]|- x:z … [f: ; x:]|- f x :  [f :  ; x : ] |- (f (f x)) :  [x : ] |- (fun f -> f (f x)) :  [ ] |- (fun x -> fun f -> f (f x)) :  •   ();   (  )

  14. Type Inference - Example • Current subst: {z, } o { } • Var rule: Solve z  Unification [f:; x:]|- f:z [f:; x:]|- x:z … [f: ; x:]|- f x :  [f :  ; x : ] |- (f (f x)) :  [x : ] |- (fun f -> f (f x)) :  [ ] |- (fun x -> fun f -> f (f x)) :  •   ();   (  )

  15. Type Inference - Example • Current subst: {z, , } • Apply to next sub-proof … [f:; x:]|- x: … [f: ; x:]|- f x :  [f :  ; x : ] |- (f (f x)) :  [x : ] |- (fun f -> f (f x)) :  [ ] |- (fun x -> fun f -> f (f x)) :  •   ();   (  )

  16. Type Inference - Example • Current subst: {z, , } • Var rule:  … [f:; x:]|- x: … [f: ; x:]|- f x :  [f :  ; x : ] |- (f (f x)) :  [x : ] |- (fun f -> f (f x)) :  [ ] |- (fun x -> fun f -> f (f x)) :  •   ();   (  )

  17. Type Inference - Example • Current subst: {}o{z, , } • Solves subproof; return one layer … [f:; x:]|- x: … [f: ; x:]|- f x :  [f :  ; x : ] |- (f (f x)) :  [x : ] |- (fun f -> f (f x)) :  [ ] |- (fun x -> fun f -> f (f x)) :  •   ();   (  )

  18. Type Inference - Example • Current subst: {, z, , } • Solves this subproof; return one layer … [f: ; x:]|- f x :  [f :  ; x : ] |- (f (f x)) :  [x : ] |- (fun f -> f (f x)) :  [ ] |- (fun x -> fun f -> f (f x)) :  •   ();   (  )

  19. Type Inference - Example • Current subst: {, z, , } • Need to satisfy constraint   (  ), given subst:   (()  ) [f :  ; x : ] |- (f (f x)) :  [x : ] |- (fun f -> f (f x)) :  [ ] |- (fun x -> fun f -> f (f x)) :  •   ();   (  )

  20. Type Inference - Example • Current subst: {  (()  ),, z, , } • Solves subproof; return one layer [f :  ; x : ] |- (f (f x)) :  [x : ] |- (fun f -> f (f x)) :  [ ] |- (fun x -> fun f -> f (f x)) :  •   ();   (  )

  21. Type Inference - Example • Current subst: {  (()  ),, z, , } • Need to satisfy constraint   () given subst:   ((()  )) [x : ] |- (fun f -> f (f x)) :  [ ] |- (fun x -> fun f -> f (f x)) :  •   ();

  22. Type Inference - Example • Current subst: {  ((()  )),   (()  ),, z, , } • Solves subproof; return on layer [x : ] |- (fun f -> f (f x)) :  [ ] |- (fun x -> fun f -> f (f x)) : 

  23. Type Inference - Example • Current subst: {  ((()  )),   (()  ),, z, , } • Done:   ((()  )) [ ] |- (fun x -> fun f -> f (f x)) : 

  24. Type Inference Algorithm

  25. Type Inference Algorithm Let infer (, e, ) = s •  is a typing environment (giving polymorphic types to expression variables) • e is an expression •  is a type (with type variables), • s is a substitution of types for type variables • Idea: s is the constraints on type variables necessary for  |- e :  • Should have s() |- e : s()

  26. Type Inference Algorithm infer(, exp, ) = • Case exp of • Var v --> return Unify{  freshInstance((v))} • Replace all quantified type vars by fresh ones • Const c --> return Unify{  freshInstance } where  |- c :  by the constant rules • fun x -> e --> • Let ,  be fresh variables • Let s= infer([x : ] + , e, ) • Return Unify{s()  s(  )}os

  27. Type Inference Algorithm (cont) • Case exp of • App (e1e2) --> • Let  be a fresh variable • Let s1 = infer(, e1,   ) • Let s2 = infer(s1(), e2, s1()) • Return s2 os1

  28. Type Inference Algorithm (cont) • Case exp of • If e1 then e2 else e3 --> • Let s1 = infer(, e1, bool) • Let s2 = infer(s1(), e2, s1()) • Let s3 = infer(s2o s1(),e2,s2o s1()) • Return s3 o s2 os1

  29. Type Inference Algorithm (cont) • Case exp of • let x = e1 in e2 --> • Let  be a fresh variable • Let s1 = infer(, e1, ) • Let s2 = infer([x : GEN(s1(), s1())] + s1(), e2,s1()) • Return s2 os1

  30. Type Inference Algorithm (cont) • Case exp of • let rec x = e1 in e2 --> • Let  be a fresh variable • Let s1 = infer([x : ] + , e1, ) • Let s2 = infer([x : GEN(s1(), s1())] + s1(), e2,s1()) • Return s2 os1

  31. Type Inference Algorithm (cont) • To infer a type, introduce type_of • Let  be a fresh variable • type_of(, e) = • Let s = infer(, e, ) • Return s() • Need an algorithm for Unify

  32. Unification

  33. Background for Unification • Terms made from constructors and variables (for the simple first order case) • Constructors may be applied to arguments (other terms) to make new terms • Variables and constructors with no arguments are base cases; the latter are also called constants • Constructors applied to different number of arguments (arity) considered different • Substitution of terms for variables

  34. Simple Implementation Background type term = Variable of string | Const of (string * term list) let rec subst var_name residue term = match term with Variable name -> if var_name = name then residue else term | Const (c, tys) -> Const (c, List.map (subst var_name residue) tys);;

  35. Unification Problem Given a set of pairs of terms (“equations”) {(s1, t1), (s2, t2), …, (sn, tn)} (theunification problem) does there exist a substitution  (the unification solution) of terms for variables such that (si) = (ti), for all i = 1, …, n?

  36. Uses for Unification • Type Inference and type checking • Pattern matching as in OCAML • Can use a simplified version of algorithm • Logic Programming - Prolog • …

  37. Unification Algorithm • Let S = {(s1, t1), (s2, t2), …, (sn, tn)} be a unification problem. • Case S = { }: Unify(S) = Identity function (i.e., no substitution) • Case S = {(s, t)}  S’: Four main steps

  38. Unification Algorithm • Delete: if s = t (they are the same term) then Unify(S) = Unify(S’) • Decompose: if s = f(q1, … , qm) and t = f(r1, … , rm) (same f, same m!), then Unify(S) = Unify({(q1, r1), …, (qm, rm)}  S’) • Orient:if t = x is a variable, and s is not a variable, Unify(S) = Unify({(x,s)}  S’)

  39. Unification Algorithm • Eliminate: if s is var x, and x does not occur in t (occurs check), then • Let  = x | t • Let  = Unify((S’)) • Unify(S) = {x | (t)} o  • Recall how composition of substitutions works. For example (suppose y not in a): {x | a} o {y | b} = {y | ({x | a}(b))} o {x | a}

  40. Tricks for Efficient Unification • Don’t return substitution, rather do it incrementally • Make substitution be constant time • Requires implementation of terms to use mutable structures (or possibly lazy structures) • We won’t discuss these

  41. Example • x,y,z variables, f,g constructors • S = {(f(x), f(g(y,z))), (g(y,f(y)), x)}

  42. Example • x,y,z variables, f,g constructors • S is nonempty • S = {(f(x), f(g(y,z))), (g(y,f(y)), x)}

  43. Example • x,y,z variables, f,g constructors • Pick a pair: (g(y,f(y)), x) • S = {(f(x), f(g(y,z))), (g(y,f(y)), x)}

  44. Example • x,y,z variables, f,g constructors • Pick a pair: (g(y,f(y))), x) • Orient: (x, g(y,f(y))) • S = {(f(x), f(g(y,z))), (g(y,f(y)), x)} • -> {(f(x), f(g(y,z))), (x, g(y,f(y)))}

  45. Example • x,y,z variables, f,g constructors • S -> {(f(x), f(g(y,z))), (x, g(y,f(y)))}

  46. Example • x,y,z variables, f,g constructors • Pick a pair: (f(x), f(g(y,z))) • S -> {(f(x), f(g(y,z))), (x, g(y,f(y)))}

  47. Example • x,y,z variables, f,g constructors • Pick a pair: (f(x), f(g(y,z))) • Decompose: (x, g(y,z)) • S -> {(f(x), f(g(y,z))), (x, g(y,f(y)))} • -> {(x, g(y,z)), (x, g(y,f(y)))}

  48. Example • x,y,z variables, f,g constructors • Pick a pair: (x, g(y,f(y))) • Substitute: {x |-> g(y,f(y))} • S -> {(x, g(y,z)), (x, g(y,f(y)))} • -> {(g(y,f(y)), g(y,z))} • With {x |-> g(y,f(y))}

  49. Example • x,y,z variables, f,g constructors • Pick a pair: (g(y,f(y)), g(y,z)) • S -> {(g(y,f(y)), g(y,z))} With {x | g(y,f(y))}

  50. Example • x,y,z variables, f,g constructors • Pick a pair: (g(y,f(y)), g(y,z)) • Decompose: (y, y) and (f(y), z) • S -> {(g(y,f(y)), g(y,z))} • -> {(y, y), (f(y), z)} With {x | g(y,f(y))}