Type Inference David Walker COS 441. Criticisms of Typed Languages Types overly constrain functions & data polymorphism makes typed constructs useful.

Slides:



Advertisements
Similar presentations
Types and Programming Languages Lecture 4 Simon Gay Department of Computing Science University of Glasgow 2006/07.
Advertisements

Types and Programming Languages Lecture 13 Simon Gay Department of Computing Science University of Glasgow 2006/07.
Functional Programming Lecture 10 - type checking.
Type Inference David Walker COS 320. Criticisms of Typed Languages Types overly constrain functions & data polymorphism makes typed constructs useful.
Type Checking, Inference, & Elaboration CS153: Compilers Greg Morrisett.
1 Turing Machines and Equivalent Models Section 13.2 The Church-Turing Thesis.
10 October 2006 Foundations of Logic and Constraint Programming 1 Unification ­An overview Need for Unification Ranked alfabeths and terms. Substitutions.
CSE341: Programming Languages Lecture 2 Functions, Pairs, Lists Dan Grossman Winter 2013.
Cs776 (Prasad)L4Poly1 Polymorphic Type System. cs776 (Prasad)L4Poly2 Goals Allow expression of “for all types T” fun I x = x I : ’a -> ’a Allow expression.
The lambda calculus David Walker CS 441. the lambda calculus Originally, the lambda calculus was developed as a logic by Alonzo Church in 1932 –Church.
Getting started with ML ML is a functional programming language. ML is statically typed: The types of literals, values, expressions and functions in a.
Composition CMSC 202. Code Reuse Effective software development relies on reusing existing code. Code reuse must be more than just copying code and changing.
ML: a quasi-functional language with strong typing Conventional syntax: - val x = 5; (*user input *) val x = 5: int (*system response*) - fun len lis =
1 Introduction to Computability Theory Lecture12: Reductions Prof. Amos Israeli.
Introduction to Computability Theory
1 Introduction to Computability Theory Lecture7: PushDown Automata (Part 1) Prof. Amos Israeli.
Constraint Logic Programming Ryan Kinworthy. Overview Introduction Logic Programming LP as a constraint programming language Constraint Logic Programming.
ML: a quasi-functional language with strong typing Conventional syntax: - val x = 5; (*user input *) val x = 5: int (*system response*) - fun len lis =
Catriel Beeri Pls/Winter 2004/5 type reconstruction 1 Type Reconstruction & Parametric Polymorphism  Introduction  Unification and type reconstruction.
Catriel Beeri Pls/Winter 2004/05 types 65  A type-checking algorithm The task: (since we start with empty H, why is the goal not just E?) The rule set.
Type Inference David Walker CS 510, Fall Criticisms of Typed Languages Types overly constrain functions & data polymorphism makes typed constructs.
Type Inference II David Walker COS 441. Type Inference Goal: Given unannotated program, find its type or report it does not type check Overview: generate.
Semantics for MinML COS 441 Princeton University Fall 2004.
Describing Syntax and Semantics
Proof by Deduction. Deductions and Formal Proofs A deduction is a sequence of logic statements, each of which is known or assumed to be true A formal.
Programming Language Semantics Denotational Semantics Chapter 5 Part III Based on a lecture by Martin Abadi.
Introduction Even though the syntax of Scheme is simple, it can be very difficult to determine the semantics of an expression. Hacker’s approach: Run it.
Type Inference II David Walker CS 510. ML-style Polymorphism 2 characteristics: prenex (let) polymorphism let f : all [a,b,c].t =... in e polymorphic.
CSE341: Programming Languages Lecture 11 Type Inference Dan Grossman Winter 2013.
Chapter 4: A Universal Program 1. Coding programs Example : For our programs P we have variables that are arranged in a certain order: Y 1 X 1 Z 1 X 2.
Boolean Algebra – the ‘Lingua Franca’ of the Digital World The goal of developing an automata is based on the following (loosely described) ‘ideal’: if.
Solve Equations with Variables on Both Sides
Chapter 4.1 Solving Systems of Linear Equations in two variables.
Lesson 4 Typed Arithmetic Typed Lambda Calculus 1/21/02 Chapters 8, 9, 10.
Type Safety Kangwon National University 임현승 Programming Languages.
Type Inference II David Walker COS 441. Type Inference Goal: Given unannotated program, find its type or report it does not type check Overview: generate.
Systems of Equations 7-4 Learn to solve systems of equations.
Arvind Computer Science and Artificial Intelligence Laboratory M.I.T. L06-1 September 26, 2006http:// Type Inference September.
Advanced Formal Methods Lecture 3: Simply Typed Lambda calculus Mads Dam KTH/CSC Course 2D1453, Some material from B. Pierce: TAPL + some from.
Foundations of (Theoretical) Computer Science Chapter 2 Lecture Notes (Section 2.2: Pushdown Automata) Prof. Karen Daniels, Fall 2010 with acknowledgement.
Static Techniques for V&V. Hierarchy of V&V techniques Static Analysis V&V Dynamic Techniques Model Checking Simulation Symbolic Execution Testing Informal.
CS104:Discrete Structures Chapter 2: Proof Techniques.
COMP 412, FALL Type Systems II C OMP 412 Rice University Houston, Texas Fall 2000 Copyright 2000, Robert Cartwright, all rights reserved. Students.
Types and Programming Languages Lecture 14 Simon Gay Department of Computing Science University of Glasgow 2006/07.
CS383 Programming Languages Quiz Which one is a term schema? a.‘a b.s :: = ‘a| int | bool c.fun f (x: int) : bool = e d.fun f (x: s1) : s2 = e.
Process Algebra (2IF45) Basic Process Algebra Dr. Suzana Andova.
COMP 412, FALL Type Systems C OMP 412 Rice University Houston, Texas Fall 2000 Copyright 2000, Robert Cartwright, all rights reserved. Students.
Lesson 10 Type Reconstruction
CS5205: Foundation in Programming Languages Type Reconstruction
Manuel Fahndrich Jakob Rehof Manuvir Das
CSE341: Programming Languages Lecture 11 Type Inference
ML: a quasi-functional language with strong typing
Example: Solve the equation. Multiply both sides by 5. Simplify both sides. Add –3y to both sides. Simplify both sides. Add –30 to both sides. Simplify.
Solving Equations with the Variable on Each Side
CSE341: Programming Languages Lecture 2 Functions, Pairs, Lists
Lesson 4 Typed Arithmetic Typed Lambda Calculus
6-2 Solving Systems using Substitution
Typed Arithmetic Expressions
CSE341: Programming Languages Lecture 11 Type Inference
CSE341: Programming Languages Lecture 2 Functions, Pairs, Lists
CSE341: Programming Languages Lecture 2 Functions, Pairs, Lists
CSE341: Programming Languages Lecture 2 Functions, Pairs, Lists
CSE341: Programming Languages Lecture 11 Type Inference
CSE341: Programming Languages Lecture 2 Functions, Pairs, Lists
CSE341: Programming Languages Lecture 11 Type Inference
CSE341: Programming Languages Lecture 2 Functions, Pairs, Lists
6.3 Using Elimination to Solve Systems
CSE341: Programming Languages Lecture 11 Type Inference
CSE341: Programming Languages Lecture 11 Type Inference
Presentation transcript:

Type Inference David Walker COS 441

Criticisms of Typed Languages Types overly constrain functions & data polymorphism makes typed constructs useful in more contexts universal polymorphism => code reuse existential polymorphism => rep. independence subtyping => coming soon Types clutter programs and slow down programmer productivity type inference uninformative annotations may be omitted

Type Inference Today overview generation of type constraints from unannotated simply-typed programs not ML yet solving type constraints Textbook Pierce 22: “Type Reconstruction”

Type Schemes A type scheme contains type variables that may be filled in during type inference s ::= a | int | bool | s1 -> s2 A term scheme is a term that contains type schemes rather than proper types e ::=... | fun f (x:s1) : s2 is e end

Example fun map (f, l) = if null (l) then nil else cons (f (hd l), map (f, tl l)))

Example fun map (f, l) = if null (l) then nil else cons (f (hd l), map (f, tl l))) library functions argument type is ‘a list library function argument type is (‘a * ‘a list) result type is ‘a list result type is ‘a

Step 1: Add Type Schemes fun map (f : a, l : b) : c = if null (l) then nil else cons (f (hd l), map (f, tl l))) type schemes on functions

Step 2: Generate Constraints fun map (f : a, l : b) : c = if null (l) then nil else cons (f (hd l), map (f, tl l))) b = b’ list

Step 2: Generate Constraints fun map (f : a, l : b) : c = if null (l) then nil else cons (f (hd l), map (f, tl l))) : d list constraints b = b’ list

Step 2: Generate Constraints fun map (f : a, l : b) : c = if null (l) then nil else cons (f (hd l), map (f, tl l))) : d list constraints b = b’ list b = b’’ list b = b’’’ list

Step 2: Generate Constraints fun map (f : a, l : b) : c = if null (l) then nil else cons (f (hd l : b’’ ), map (f, tl l : b’’’ list ))) : d list constraints b = b’ list b = b’’ list b = b’’’ list a = a

Step 2: Generate Constraints fun map (f : a, l : b) : c = if null (l) then nil else cons (f (hd l : b’’ ) : a’, map (f, tl l) : c )) : d list constraints b = b’ list b = b’’ list b = b’’’ list a = a b = b’’’ list a = b’’ -> a’

Step 2: Generate Constraints fun map (f : a, l : b) : c = if null (l) then nil else cons (f (hd l : b’’ ) : a’, map (f, tl l) : c )) : c’ list : d list constraints b = b’ list b = b’’ list b = b’’’ list a = a b = b’’’ list a = b’’ -> a’ c = c’ list a’ = c’

Step 2: Generate Constraints fun map (f : a, l : b) : c = if null (l) then nil else cons (f (hd l : b’’ ) : a’, map (f, tl l) : c )) : c’ list : d list constraints b = b’ list b = b’’ list b = b’’’ list a = a b = b’’’ list a = b’’ -> a’ c = c’ list a’ = c’ d list = c’ list

Step 2: Generate Constraints fun map (f : a, l : b) : c = if null (l) then nil else cons (f (hd l : b’’ ) : a’, map (f, tl l) : c )) : c’ list : d list constraints b = b’ list b = b’’ list b = b’’’ list a = a b = b’’’ list a = b’’ -> a’ c = c’ list a’ = c’ d list = c’ list d list = c

Step 2: Generate Constraints fun map (f : a, l : b) : c = if null (l) then nil else cons (f (hd l), map (f, tl l))) final constraints b = b’ list b = b’’ list b = b’’’ list a = a b = b’’’ list a = b’’ -> a’ c = c’ list a’ = c’ d list = c’ list d list = c

Step 3: Solve Constraints final constraints b = b’ list b = b’’ list b = b’’’ list a = a... Constraint solution provides all possible solutions to type scheme annotations on terms solution a = b’ -> c’ b = b’ list c = c’ list map (f : b’ -> c’ x : b’ list) : c’ list is... end

Step 4: Generate types Generate types from type schemes Option 1: pick an instance of the most general type when we have completed type inference on the entire program map : (int -> int) -> int list -> int list Option 2: generate polymorphic types for program parts and continue (polymorphic) type inference map : All (a,b,c) (a -> b) -> a list -> b list

Type Inference Details Type constraints are sets of equations between type schemes q ::= {s11 = s12,..., sn1 = sn2} eg: {b = b’ list, a = b -> c}

Constraint Generation Syntax-directed constraint generation our algorithm crawls over abstract syntax of untyped expressions and generates a term scheme a set of constraints Algorithm defined as set of inference rules (as always) G |-- u => e : t, q

Constraint Generation Simple rules: G |-- x ==> x : s, { } (if G(x) = s) G |-- 3 ==> 3 : int, { } (same for other ints) G |-- true ==> true : bool, { } G |-- false ==> false : bool, { }

Operators G |-- u1 ==> e1 : t1, q1 G |-- u2 ==> e2 : t2, q G |-- u1 + u2 ==> e1 + e2 : int, q1 U q2 U {t1 = int, t2 = int} G |-- u1 ==> e1 : t1, q1 G |-- u2 ==> e2 : t2, q G |-- u1 e1 < e2 : bool, q1 U q2 U {t1 = int, t2 = int}

If statements G |-- u1 ==> e1 : t1, q1 G |-- u2 ==> e2 : t2, q2 G |-- u3 ==> e3 : t3, q G |-- if u1 then u2 else u3 ==> if e1 then e2 else e3 : a, q1 U q2 U q3 U {t1 = bool, a = t2, a = t3}

Function Application G |-- u1 ==> e1 : t1, q1 G |-- u2 ==> e2 : t2, q G |-- u1 u2==> e1 e2 : a, q1 U q2 U {t1 = t2 -> a}

Function Declaration G, f : a -> b, x : a |-- u ==> e : t, q G |-- fun f(x) = u ==> fun f (x : a) : b = e : a -> b, q U {t = b} (a,b are fresh type variables; not in G, t, q)

Solving Constraints A solution to a system of type constraints is a substitution S a function from type variables to types because some things get simpler, we assume substitutions are defined on all type variables: S(a) = a (for almost all variables a) S(a) = s (for some type scheme s) dom(S) = set of variables s.t. S(a)  a

Substitutions Given a substitution S, we can define a function S* from type schemes (as opposed to type variables) to type schemes: S*(int) = int S*(s1 -> s2) = S*(s1) -> S*(s2) S*(a) = S(a) Due to laziness, I will write S(s) instead of S*(s)

Composition of Substitutions Composition (U o S) applies the substitution S and then applies the substitution U: (U o S)(a) = U(S(a)) We will need to compare substitutions T <= S if T is “more specific” than S T <= S if T is “less general” than S Formally: T <= S if and only if T = U o S for some U

Composition of Substitutions Examples: example 1: any substitution is less general than the identity substitution I: S <= I because S = S o I example 2: S(a) = int, S(b) = c -> c T(a) = int, T(b) = int -> int, T(c) = int we conclude: T <= S if T(a) = int, T(b) = int -> bool then T is unrelated to S (neither more nor less general)

Solving a Constraint S |= q if S is a solution to the constraints q S(s1) = S(s2) S |= q S |= {s1 = s2} U q S |= { } any substitution is a solution for the empty set of constraints a solution to an equation is a substitution that makes left and right sides equal

Most General Solutions S is the principal (most general) solution of a constraint q if S |= q (it is a solution) if T |= q then T <= S (it is the most general one) Lemma: If q has a solution, then it has a most general one We care about principal solutions since they will give us the most general types for terms

Examples Example 1 q = {a=int, b=a} principal solution S:

Examples Example 1 q = {a=int, b=a} principal solution S: S(a) = S(b) = int S(c) = c (for all c other than a,b)

Examples Example 2 q = {a=int, b=a, b=bool} principal solution S:

Examples Example 2 q = {a=int, b=a, b=bool} principal solution S: does not exist (there is no solution to q)

principal solutions principal solutions give rise to most general reconstruction of typing information for a term: fun f(x:a):a = x is a most general reconstruction fun f(x:int):int = x is not

Unification Unification: An algorithm that provides the principal solution to a set of constraints (if one exists) If one exists, it will be principal

Unification Unification: Unification systematically simplifies a set of constraints, yielding a substitution during simplification, we maintain (S,q) S is the solution so far q are the constraints left to simplify Starting state of unification process: (I,q) Final state of unification process: (S, { })

Unification Machine We can specify unification as a transition system: (S,q) -> (S’,q’) Base types & simple variables: (S,{int=int} U q) -> (S, q) (S,{bool=bool} U q) -> (S, q) (S,{a=a} U q) -> (S, q)

Unification Machine Functions: Variable definitions (S,{s11 -> s12= s21 -> s22} U q) -> (S, {s11 = s21, s12 = s22} U q) (a not in FV(s)) (S,{a=s} U q) -> ([a=s] o S, [s/a]q) (a not in FV(s)) (S,{s=a} U q) -> ([a=s] o S, [s/a]q)

Occurs Check What is the solution to {a = a -> a}?

Occurs Check What is the solution to {a = a -> a}? There is none! (Remember your homework) The occurs check detects this situation (a not in FV(s)) (S,{s=a} U q) -> ([a=s] o S, [s/a]q) occurs check

Irreducible States Recall: final states have the form (S, { }) Stuck states (S,q) are such that every equation in q has the form: int = bool s1 -> s2 = s (s not function type) a = s (s contains a) or is symmetric to one of the above Stuck states arise when constraints are unsolvable

Termination We want unification to terminate (to give us a type reconstruction algorithm) In other words, we want to show that there is no infinite sequence of states (S1,q1) -> (S2,q2) ->...

Termination We associate an ordering with constraints q < q’ if and only if q contains fewer variables than q’ q contains the same number of variables as q’ but fewer type constructors (ie: fewer occurrences of int, bool, or “->”) This is a lexacographic ordering There is no infinite decreasing sequence of constraints To prove termination, we must demonstrate that every step of the algorithm reduces the size of q according to this ordering

Termination Lemma: Every step reduces the size of q Proof: By cases (ie: induction) on the definition of the reduction relation (S,{int=int} U q) -> (S, q) (S,{bool=bool} U q) -> (S, q) (S,{a=a} U q) -> (S, q) (S,{s11 -> s12= s21 -> s22} U q) -> (S, {s11 = s21, s12 = s22} U q) (a not in FV(s)) (S,{a=s} U q) -> ([a=s] o S, [s/a]q)

Complete Solutions A complete solution for (S,q) is a substitution T such that 1. T <= S 2. T |= q intuition: T extends S and solves q A principal solution T for (S,q) is complete for (S,q) and 3. for all T’ such that 1. and 2. hold, T’ <= T

Properties of Solutions Lemma 1: Every final state (S, { }) has a complete solution. It is S: S <= S S |= { }

Properties of Solutions Lemma 2 No stuck state has a complete solution (or any solution at all) it is impossible for a substitution to make the necessary equations equal int  bool int  t1 -> t2...

Properties of Solutions Lemma 3 If (S,q) -> (S’,q’) then T is complete for (S,q) iff T is complete for (S’,q’) T is principal for (S,q) iff T is principal for (S’,q’) in the forward direction, this is the preservation theorem for the unification machine!

Summary: Unification By termination, (I,q) ->* (S,q’) where (S,q’) is irreducible. Moreover: If q’ = { } then (S,q’) is final (by definition) S is a principal solution for q Consider any T such that T is a solution to q. Now notice, S is principal for (S,q’) (by lemma 1) S is principal for (I,q) (by lemma 3) Since S is principal for (I,q), we know T <= S and therefore S is a principal solution for q.

Summary: Unification (cont.)... Moreover: If q’ is not { } (and (I,q) ->* (S,q’) where (S,q’) is irreducible) then (S,q) is stuck. Consequently, (S,q) has no complete solution. By lemma 3, even (I,q) has no complete solution and therefore q has no solution at all.

Summary: Type Inference Type inference algorithm. Given a context G, and untyped term u: Find e, t, q such that G |- u ==> e : t, q Find principal solution S of q via unification if no solution exists, there is no reconstruction Apply S to e, ie our solution is S(e) S(e) contains schematic type variables a,b,c, etc that may be instantiated with any type Since S is principal, S(e) characterizes all reconstructions.

End