1 / 60

Programming Languages and Compilers (CS 421)

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. Objective.

bbrenda
Download Presentation

Programming Languages and Compilers (CS 421)

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

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))}

More Related