1 / 75

Programming Languages and Compilers (CS 421)

Programming Languages and Compilers (CS 421). Elsa L Gunter 2112 SC, UIUC http://courses.engr.illinois.edu/cs421. Based in part on slides by Mattox Beckman, as updated by Vikram Adve and Gul Agha. Two Problems. Type checking Question: Does exp. e have type  in env  ? Answer: Yes / No

taini
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) Elsa L Gunter 2112 SC, UIUC http://courses.engr.illinois.edu/cs421 Based in part on slides by Mattox Beckman, as updated by Vikram Adve and Gul Agha

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

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

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

  5. 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   ()

  6. 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)) :  •   ();   (  )

  7. 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)) :  •   ();   (  )

  8. 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)) :  •   ();   (  )

  9. 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)) :  •   ();   (  )

  10. Type Inference - Example • Current subst: { } Use App Rule {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)) :  •   ();   (  )

  11. 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)) :  •   ();   (  )

  12. 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)) :  •   ();   (  )

  13. 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)) :  •   ();   (  )

  14. 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)) :  •   ();   (  )

  15. 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)) :  •   ();   (  )

  16. 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)) :  •   ();   (  )

  17. Type Inference - Example • Current subst: {, z, , } • Need to satisfy constraint   (  ), given subst, becomes:   (()  ) … {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 subproof; return one layer … {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:   ((()  )) … {x : } |- (fun f -> f (f x)) :  { } |- (fun x -> fun f -> f (f x)) :  •   ();

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

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

  22. 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() valid

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

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

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

  26. Type Inference Algorithm (cont) • Case expof • 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

  27. 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 s2os1

  28. 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 Unif

  29. 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 • Constructors applied to different number of arguments (arity) considered different • Substitution of terms for variables

  30. 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);;

  31. 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?

  32. Uses for Unification • Type Inference and type checking • Pattern matching as in OCaml • Can use a simplified version of algorithm • Logic Programming - Prolog • Simple parsing

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

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

  35. Unification Algorithm • Eliminate: if s = x is a variable, and x does not occur in t (the occurs check), then • Let  = {x  t} • Let = Unif((S’)) • Unif(S) = {x  (t)} o  • Note: {x  a} o {y  b} = {y  ({x  a}(b))} o {x  a} if y not in a

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

  37. Example • x,y,z variables, f,g constructors • Unify {(f(x) = f(g(f(z),y))), (g(y,y) = x)} = ?

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

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

  40. Example • x,y,zvariables, f,gconstructors • Pick a pair: (g(y,y)) = x) • Orient: (x = g(y,y)) • Unify {(f(x) = f(g(f(z),y))), (g(y,y) = x)} = Unify {(f(x) = f(g(f(z),y))), (x = g(y,y))} by Orient

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

  42. Example • x,y,zvariables,f,gconstructors • {(f(x) = f(g(f(z),y))), (x = g(y,y))} is non-empty • Unify {(f(x) = f(g(f(z),y))), (x = g(y,y))} = ?

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

  44. Example • x,y,z variables, f,g constructors • Pick a pair: (x = g(y,y)) • Eliminate x with substitution {x g(y,y)} • Check: x not in g(y,y) . • Unify {(f(x) = f(g(f(z),y))), (x = g(y,y))} = ?

  45. Example • x,y,zvariables,f,gconstructors • Pick a pair: (x = g(y,y)) • Eliminate x with substitution {x g(y,y)} • Unify {(f(x) = f(g(f(z),y))), (x = g(y,y))} = Unify {(f(g(y,y)) = f(g(f(z),y)))} o {x g(y,y)}

  46. Example • x,y,zvariables,f,gconstructors • Unify {(f(g(y,y)) = f(g(f(z),y)))} o {x g(y,y)} = ?

  47. Example • x,y,zvariables,f,gconstructors • {(f(g(y,y)) = f(g(f(z),y)))} is non-empty • Unify {(f(g(y,y)) = f(g(f(z),y)))} o {x g(y,y)} = ?

  48. Example • x,y,zvariables,f,gconstructors • Pick a pair: (f(g(y,y)) = f(g(f(z),y))) • Unify {(f(g(y,y)) = f(g(f(z),y)))} o {x g(y,y)} = ?

  49. Example • x,y,zvariables,f,gconstructors • Pick a pair: (f(g(y,y)) = f(g(f(z),y))) • Decompose:(f(g(y,y)) = f(g(f(z),y))) becomes {(g(y,y) = g(f(z),y))} • Unify {(f(g(y,y)) = f(g(f(z),y)))} o {x g(y,y)} = Unify {(g(y,y) = g(f(z),y))} o {x g(y,y)}

  50. Example • x,y,zvariables,f,gconstructors • {(g(y,y) = g(f(z),y))} is non-empty • Unify {(g(y,y) = g(f(z),y))} o {x g(y,y)} = ?

More Related