Type Inference. COS 326 David Walker Princeton University

Similar documents
Programming Language Concepts: Lecture 19

Principles of Programming Languages

Lecture #13: Type Inference and Unification. Typing In the Language ML. Type Inference. Doing Type Inference

A Functional Evaluation Model

Lecture #23: Conversion and Type Inference

Conversion vs. Subtyping. Lecture #23: Conversion and Type Inference. Integer Conversions. Conversions: Implicit vs. Explicit. Object x = "Hello";

Thinking Induc,vely. COS 326 David Walker Princeton University

Polymorphic lambda calculus Princ. of Progr. Languages (and Extended ) The University of Birmingham. c Uday Reddy

Introduction to OCaml

COSE212: Programming Languages. Lecture 3 Functional Programming in OCaml

More Untyped Lambda Calculus & Simply Typed Lambda Calculus

CMSC 330: Organization of Programming Languages. OCaml Expressions and Functions

Modules and Representation Invariants

CS-XXX: Graduate Programming Languages. Lecture 9 Simply Typed Lambda Calculus. Dan Grossman 2012

CS153: Compilers Lecture 14: Type Checking

CS Lecture 5: Pattern Matching. Prof. Clarkson Fall Today s music: Puff, the Magic Dragon by Peter, Paul & Mary

Introduction to ML. Mooly Sagiv. Cornell CS 3110 Data Structures and Functional Programming

CSCI-GA Scripting Languages

Once Upon a Polymorphic Type

CSE505, Fall 2012, Midterm Examination October 30, 2012

CS Lecture 6: Map and Fold. Prof. Clarkson Fall Today s music: Selections from the soundtrack to 2001: A Space Odyssey

Programming Languages Fall 2014

The Substitution Model

Types, Type Inference and Unification

Lambda Calculus and Type Inference

CS 11 Haskell track: lecture 1

l e t print_name r = p r i n t _ e n d l i n e ( Name : ^ r. name)

MA/CS 109 Lecture 3. Networks, Euler paths, and speaking carefully!

Two Problems. Programming Languages and Compilers (CS 421) Type Inference - Example. Type Inference - Outline. Type Inference - Example

Type Checking and Type Inference

CMSC330 Fall 2016 Midterm #1 2:00pm/3:30pm

CSE 505: Concepts of Programming Languages

Type Systems. Seman&cs. CMPT 379: Compilers Instructor: Anoop Sarkar. anoopsarkar.github.io/compilers-class

Lambda Calculus and Type Inference

Lambda Calculus. Concepts in Programming Languages Recitation 6:

Introduction to OCaml

02157 Functional Programming. Michael R. Ha. Lecture 2: Functions, Types and Lists. Michael R. Hansen

COSE212: Programming Languages. Lecture 4 Recursive and Higher-Order Programming

CMSC 330: Organization of Programming Languages

Scope and Introduction to Functional Languages. Review and Finish Scoping. Announcements. Assignment 3 due Thu at 11:55pm. Website has SML resources

Turing Machine Languages

CS152: Programming Languages. Lecture 11 STLC Extensions and Related Topics. Dan Grossman Spring 2011

Overview. Elements of Programming Languages. Another example. Consider the humble identity function

Type Inference Systems. Type Judgments. Deriving a Type Judgment. Deriving a Judgment. Hypothetical Type Judgments CS412/CS413

Let Arguments Go First

CMSC 330: Organization of Programming Languages. Functional Programming with Lists

Modules and Representa/on Invariants

Compiler Construction

Programming Languages

Lecture Notes on Induction and Recursion

CMSC330 Fall 2017 Final Exam

OCaml. ML Flow. Complex types: Lists. Complex types: Lists. The PL for the discerning hacker. All elements must have same type.

Dependent types and program equivalence. Stephanie Weirich, University of Pennsylvania with Limin Jia, Jianzhou Zhao, and Vilhelm Sjöberg

Tracing Ambiguity in GADT Type Inference

Arbitrary-rank polymorphism in (GHC) Haskell

CS Lecture 6: Map and Fold. Prof. Clarkson Spring Today s music: Selections from the soundtrack to 2001: A Space Odyssey

Programming Language Features. CMSC 330: Organization of Programming Languages. Turing Completeness. Turing Machine.

CMSC 330: Organization of Programming Languages

h0ps://

Limitations of Algorithmic Solvability In this Chapter we investigate the power of algorithms to solve problems Some can be solved algorithmically and

Type Systems, Type Inference, and Polymorphism

Type Systems COMP 311 Rice University Houston, Texas

According to Larry Wall (designer of PERL): a language by geniuses! for geniuses. Lecture 7: Haskell. Haskell 98. Haskell (cont) - Type-safe!

Chapter 13: Reference. Why reference Typing Evaluation Store Typings Safety Notes

A Functional Space Model. COS 326 David Walker Princeton University

COMPUTABILITY THEORY AND RECURSIVELY ENUMERABLE SETS

CS4215 Programming Language Implementation. Martin Henz

Adding GADTs to OCaml the direct approach

CS 421, Fall Sample Final Questions & Solutions

Dialects of ML. CMSC 330: Organization of Programming Languages. Dialects of ML (cont.) Features of ML. Functional Languages. Features of ML (cont.

Functors signature Order = sig functor name type elem (structname:signature) = structure definition; val le : elem*elem -> bool end; elem

CSE 3302 Programming Languages Lecture 8: Functional Programming

Haskell Types, Classes, and Functions, Currying, and Polymorphism

Writing code that I'm not smart enough to write. A funny thing happened at Lambda Jam

Goal. CS152: Programming Languages. Lecture 15 Parametric Polymorphism. What the Library Likes. What The Client Likes. Start simpler.

The Substitution Model. Nate Foster Spring 2018

MATH 22 MORE ABOUT FUNCTIONS. Lecture M: 10/14/2003. Form follows function. Louis Henri Sullivan

Simply-Typed Lambda Calculus

Programming Languages

Programming Languages

Formal Methods of Software Design, Eric Hehner, segment 24 page 1 out of 5

Haskell Overview III (3A) Young Won Lim 10/4/16

Begin at the beginning

Lecture 2: SML Basics

CIS 500 Software Foundations Midterm I

15 212: Principles of Programming. Some Notes on Continuations

15 212: Principles of Programming. Some Notes on Induction

CS3110 Spring 2016 Lecture 6: Modules

Lecture 3: Recursion; Structural Induction

COS 320. Compiling Techniques

A First Look at ML. Chapter Five Modern Programming Languages, 2nd ed. 1

CS558 Programming Languages

Agenda. CS301 Session 11. Common type constructors. Things we could add to Impcore. Discussion: midterm exam - take-home or inclass?

Fall 2013 Midterm Exam 10/22/13. This is a closed-book, closed-notes exam. Problem Points Score. Various definitions are provided in the exam.

Polymorphic Types in ACL2

CSE 130, Fall 2005: Final Examination

CSE 130, Fall 2006: Final Examination

Introduction to ML. Mooly Sagiv. Cornell CS 3110 Data Structures and Functional Programming

CSE341: Programming Languages Lecture 11 Type Inference. Dan Grossman Spring 2016

Introduction to ML. Mooly Sagiv. Cornell CS 3110 Data Structures and Functional Programming

Transcription:

Type Inference COS 326 David Walker Princeton University slides copyright 2017 David Walker permission granted to reuse these slides for non-commercial educafonal purposes

2 Midterm Exam Wed Oct 25, 2017 In Class (11:00-12:20) Midterm Week Be there or be square!

TYPE INFERENCE 3

Language Design for Type Inference The ML language and type system is designed to support a very strong form of type inference.

Language Design for Type Inference The ML language and type system is designed to support a very strong form of type inference. let rec map f l = match l with [ ] -> [ ] hd::tl -> f hd :: map f tl ML finds this type for map: map : ('a -> 'b) -> 'a list -> 'b list

Language Design for Type Inference The ML language and type system is designed to support a very strong form of type inference. let rec map f l = match l with [ ] -> [ ] hd::tl -> f hd :: map f tl ML finds this type for map: map : ('a -> 'b) -> 'a list -> 'b list which is really an abbreviafon for this type: map : forall 'a,'b.('a -> 'b) -> 'a list -> 'b list

Language Design for Type Inference map : ('a -> 'b) -> 'a list -> 'b list We call this type the principle type (scheme) for map. Any other ML-style type you can give map is an instance of this type, meaning we can obtain the other types via subs3tu3on of types for parameters from the principle type. Eg: (bool -> int) -> bool list -> int list ('a -> int) -> 'a list -> int list ('a -> 'a) -> 'a list -> 'a list

Language Design for Type Inference Principle types are great: the type inference engine can make a best choice for the type to give an expression the engine doesn't have to guess (and won't have to guess wrong) The fact that principle types exist is surprisingly briyle. If you change ML's type system a liyle bit in either direcfon, it can fall apart.

Language Design for Type Inference Suppose we take out polymorphic types and need a type for id: let id x = x Then the compiler might guess that id has one (and only one) of these types: id : bool -> bool id : int -> int

Language Design for Type Inference Suppose we take out polymorphic types and need a type for id: let id x = x Then the compiler might guess that id has one (and only one) of these types: id : bool -> bool id : int -> int But later on, one of the following code snippets won't type check: id true id 3 So whatever choice is made, a different one might have been beyer.

Language Design for Type Inference We showed that removing types from the language causes a failure of principle types. Does adding more types always make type inference easier?

Language Design for Type Inference We showed that removing types from the language causes a failure of principle types. Does adding more types always make type inference easier?

Language Design for Type Inference OCaml only has universal types on the outside: forall 'a,'b. ('a -> 'b) -> 'a list -> 'b list Consider this program: let f g = (g true, g 3) It won't type check in OCaml. We might want to give it this type: f : (forall a.a->a) -> bool * int NoFce that the universal quanffier appears under an ->

Language Design for Type Inference System F is a lot like OCaml, except that it allows universal quanffiers in any posifon. It could type check f. let f g = (g true, g 3) f : (forall a.a->a) -> bool * int Unfortunately, type inference in System F is undecideable..

Language Design for Type Inference System F is a lot like OCaml, except that it allows universal quanffiers in any posifon. It could type check f. let f g = (g true, g 3) f : (forall a.a->a) -> bool * int Unfortunately, type inference in System F is undecideable. Developed in 1972 by logician Jean Yves-Girard who was interested in the consistency of a logic of 2 nd -order arithemefc. Rediscovered as programming language by John Reynolds in 1974.

Language Design for Type Inference Even seemingly small changes can effect type inference. Suppose "+" operated on both floats and ints. What type for this? let f x = x + x

Language Design for Type Inference Even seemingly small changes can effect type inference. Suppose "+" operated on both floats and ints. What type for this? let f x = x + x f : int -> int? f : float -> float?

Language Design for Type Inference Even seemingly small changes can effect type inference. Suppose "+" operated on both floats and ints. What type for this? let f x = x + x f : int -> int? f : float -> float? f : 'a -> 'a?

Language Design for Type Inference Even seemingly small changes can effect type inference. Suppose "+" operated on both floats and ints. What type for this? let f x = x + x f : int -> int? f : float -> float? f : 'a -> 'a? No type in OCaml's type system works. In Haskell: f : Num 'a => 'a -> 'a

INFERRING SIMPLE TYPES 20

Type Schemes A type scheme contains type variables that may be filled in during type inference s ::= a int bool s -> s A term scheme is a term that contains type schemes rather than proper types. eg, for funcfons: fun (x:s) -> e let rec f (x:s) : s = e

The Generic Type Inference Algorithm 1) Add disfnct variables in all places type schemes are needed 22

The Generic Type Inference Algorithm 23 1) Add disfnct variables in all places type schemes are needed 2) Generate constraints (equafons between types) that must be safsfied in order for an expression to type check NoFce the difference between this and the type checking algorithm from last Fme. Last Fme, we tried to: eagerly deduce the concrete type when checking every expression reject programs when types didn't match. eg: f e -- f's argument type must equal e This Fme, we'll collect up equafons like: a -> b = c

The Generic Type Inference Algorithm 24 1) Add disfnct variables in all places type schemes are needed 2) Generate constraints (equafons between types) that must be safsfied in order for an expression to type check NoFce the difference between this and the type checking algorithm from last Fme. Last Fme, we tried to: eagerly deduce the concrete type when checking every expression reject programs when types didn't match. eg: f e -- f's argument type must equal e This Fme, we'll collect up equafons like: a -> b = c 3) Solve the equafons, generafng subsftufons of types for var's

Example: Inferring types for map let rec map f l = match l with [] -> [] hd::tl -> f hd :: map f tl

Step 1: Annotate let rec map (f:a) (l:b) : c = match l with [] -> [] hd::tl -> f hd :: map f tl

Step 2: Generate Constraints let rec map (f:a) (l:b) : c = match l with [] -> [] hd::tl -> f hd :: map f tl b = d list a = d -> f...

Step 2: Generate Constraints let rec map (f:a) (l:b) : c = match l with [] -> [] hd::tl -> f hd :: map f tl 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 let rec map (f:a) (l:b) : c = match l with [] -> [] hd::tl -> f hd :: map f tl 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 final solufon: [b' -> c'/a] [b' list/b] [c' list/c]

Step 3: Solve Constraints final solufon: [b' -> c'/a] [b' list/b] [c' list/c] let rec map (f:a) (l:b) : c = match l with [] -> [] hd::tl -> f hd :: map f tl let rec map (f:b' -> c') (l:b' list) : c' list = match l with [] -> [] hd::tl -> f hd :: map f tl

Step 3: Solve Constraints let rec map (f:a) (l:b) : c = match l with [] -> [] hd::tl -> f hd :: map f tl renaming type variables: let rec map (f:a -> b) (l:a list) : b list = match l with [] -> [] hd::tl -> f hd :: map f tl

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

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

Constraint GeneraFon Syntax-directed constraint generafon 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: G -- u => e : t, q constraints that must be solved context unannotated expression annotated expression type (scheme) in OCaml: gen : ctxt -> exp -> ann_exp * scheme * constraints

Constraint GeneraFon 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, q2 ------------------------------------------------------------------------ G -- u1 + u2 ==> e1 + e2 : int, q1 U q2 U {t1 = int, t2 = int} G -- u1 ==> e1 : t1, q1 G -- u2 ==> e2 : t2, q2 ------------------------------------------------------------------------ G -- u1 < u2 ==> 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, q3 ---------------------------------------------------------------- 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}

FuncFon ApplicaFon G -- u1 ==> e1 : t1, q1 G -- u2 ==> e2 : t2, q2 (for a fresh a) ---------------------------------------------------------------- G -- u1 u2==> e1 e2 : a, q1 U q2 U {t1 = t2 -> a}

FuncFon DeclaraFon G, x : a -- u ==> e : t, q (for fresh a) ---------------------------------------------------------------- G -- fun x -> e ==> fun (x : a) -> e : a -> b, q U {t = b}

FuncFon DeclaraFon G, f : a -> b, x : a -- u ==> e : t, q (for fresh a,b) ----------------------------------------------------------------------- G -- rec f(x) = u ==> rec f (x : a) : b = e : a -> b, q U {t = b}

Solving Constraints A solufon to a system of type constraints is a subs3tu3on S a funcfon from type variables to types assume subsftufons 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

Solving Constraints A solufon to a system of type constraints is a subs3tu3on S a funcfon from type variables to types assume subsftufons 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 We can also apply a subsftufon S to a full type scheme s. apply: [ int/a, int->bool/b ] to: b -> a -> b returns: (int->bool) -> int -> (int->bool)

SubsFtuFons We can apply a subsftufon S to a full type scheme: eg: apply [ int/a, int->bool/b ] to b -> a -> b returns: (int->bool) -> int -> (int->bool)

SubsFtuFons When is a subsftufon S a solufon to a set of constraints? Constraints: { s1 = s2, s3 = s4, s5 = s6,... } When the subsftufon makes both sides of all equafons the same. Eg: constraints: a = b -> c c = int -> bool

SubsFtuFons When is a subsftufon S a solufon to a set of constraints? Constraints: { s1 = s2, s3 = s4, s5 = s6,... } When the subsftufon makes both sides of all equafons the same. Eg: constraints: a = b -> c c = int -> bool solufon: b -> (int -> bool)/a int -> bool/c b/b

SubsFtuFons When is a subsftufon S a solufon to a set of constraints? Constraints: { s1 = s2, s3 = s4, s5 = s6,... } When the subsftufon makes both sides of all equafons the same. Eg: constraints: a = b -> c c = int -> bool solufon: b -> (int -> bool)/a int -> bool/c b/b constraints with solufon applied: b -> (int -> bool) = b -> (int -> bool) int -> bool = int -> bool

SubsFtuFons When is a subsftufon S a solufon to a set of constraints? Constraints: { s1 = s2, s3 = s4, s5 = s6,... } When the subsftufon makes both sides of all equafons the same. A second solufon constraints: a = b -> c c = int -> bool solufon 1: b -> (int -> bool)/a int -> bool/c b/b solufon 2: int -> (int -> bool)/a int -> bool/c int/b

SubsFtuFons When is one solufon beyer than another to a set of constraints? constraints: a = b -> c c = int -> bool solufon 1: b -> (int -> bool)/a int -> bool/c b/b solufon 2: int -> (int -> bool)/a int -> bool/c int/b type b -> c with solufon applied: b -> (int -> bool) type b -> c with solufon applied: int -> (int -> bool)

SubsFtuFons solufon 1: b -> (int -> bool)/a int -> bool/c b/b solufon 2: int -> (int -> bool)/a int -> bool/c int/b type b -> c with solufon applied: b -> (int -> bool) type b -> c with solufon applied: int -> (int -> bool) SoluFon 1 is "more general" there is more flex. SoluFon 2 is "more concrete" We prefer solufon 1.

SubsFtuFons solufon 1: b -> (int -> bool)/a int -> bool/c b/b solufon 2: int -> (int -> bool)/a int -> bool/c int/b type b -> c with solufon applied: b -> (int -> bool) type b -> c with solufon applied: int -> (int -> bool) SoluFon 1 is "more general" there is more flex. SoluFon 2 is "more concrete" We prefer the more general (less concrete) solufon 1. Technically, we prefer T to S if there exists another subsftufon U and for all types t, S (t) = U (T (t))

SubsFtuFons solufon 1: b -> (int -> bool)/a int -> bool/c b/b solufon 2: int -> (int -> bool)/a int -> bool/c int/b type b -> c with solufon applied: b -> (int -> bool) type b -> c with solufon applied: int -> (int -> bool) There is always a best solufon, which we can a principle solu3on. The best solufon is (at least as) preferred as any other solufon.

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

ComposiFon of SubsFtuFons We will need to compare subsftufons: T <= S. eg: T <= S if T is more specific /"less general" than S If there is a Formally: T <= S if and only if T = U o S for some U

ComposiFon of SubsFtuFons ComposiFon (U o S) applies the subsftufon S and then applies the subsftufon U: (U o S)(a) = U(S(a)) We will need to compare subsftufons 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

ComposiFon of SubsFtuFons Examples: example 1: any subsftufon is less general than the idenfty subsftufon I: S <= I because S = S o I example 2: S(a) = int, S(b) = c -> c T(a) = int, T(b) = int -> 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 solufon to the constraints q ---------- S = { } S(s1) = S(s2) S = q ----------------------------------- S = {s1 = s2} U q any subsftufon is a solufon for the empty set of constraints a solufon to an equafon is a subsftufon that makes let and right sides equal

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

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

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

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

UnificaFon UnificaFon: An algorithm that provides the principal solufon to a set of constraints (if one exists) UnificaFon systemafcally simplifies a set of constraints, yielding a subsftufon StarFng state of unificafon process: (I,q) Final state of unificafon process: (S, { })

UnificaFon Machine We can specify unificafon as a transifon system: (S1, q1) -> (S2, q2) Base types & simple variables: (S,{bool=bool} U q) -> (S, q) (S,{int=int} U q) -> (S, q) (S,{a=a} U q) -> (S, q)

FuncFons: UnificaFon Machine (S, {s11 -> s12 = s21 -> s22} U q) -> (S, {s11 = s21, s12 = s22} U q) breaks down into smaller constraints Variable definifons when a is not in FreeVars(s) (S, {a=s} U q) -> ([a=s] o S, [s/a]q) do S and then do [a=b] (S, {s=a} U q) -> ([a=s] o S, [s/a]q)

Occurs Check Recall this program: fun x -> x x It generates the the constraints: a -> a = a What is the solufon to {a = a -> a}?

Occurs Check Recall this program: fun x -> x x It generates the the constraints: a -> a = a What is the solufon to {a = a -> a}? There is none! (S, {s=a} U q) -> ([a=s] o S, [s/a]q) "when a is not in FreeVars(s)" the "occurs check"

Irreducible States When all the constraints have been processed, we win! (S1, q1) -> (S2, q2) -> (S3, q3)... -> (Sn, { }) But somefmes we get stuck, with an equafon like this int = bool s1 -> s2 = int s1 -> s2 = bool a = s (s contains a) or is symmetric to one of the above Stuck states arise when constraints are unsolvable & the program does not type check.

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

TerminaFon 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 we can prove (by contradicfon) that there is no infinite decreasing sequence of constraints

TerminaFon Lemma: Every step reduces the size of q Proof: By cases (ie: inducfon) on the definifon of the reducfon relafon. -------------------------------- (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 SoluFons A complete solufon for (S,q) is a subsftufon T such that T <= S T = q

ProperFes of SoluFons Lemma 1: Every final state (S, { }) has a complete solufon. It is S: S <= S S = { }

ProperFes of SoluFons Lemma 2 No stuck state has a complete solufon (or any solufon at all) it is impossible for a subsftufon to make the necessary equafons equal int bool int t1 -> t2...

Lemma 3 If (S,q) -> (S,q ) then ProperFes of SoluFons T is complete for (S,q) iff T is complete for (S,q ) proof by? in the forward direcfon, this is the preservafon theorem for the unificafon machine!

Summary: UnificaFon By terminafon, (I,q) ->* (S,q ) where (S,q ) is irreducible. Moreover: If q = { } then (S,q ) is final (by definifon) S is a principal solufon for q Consider any T such that T is a solufon to q. Now nofce, S is complete for (S,q ) (by lemma 1) S is complete for (I,q) (by lemma 3) Since S is complete for (I,q), T <= S and therefore S is principal.

Summary: UnificaFon (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 solufon. By lemma 3, even (I,q) has no complete solufon and therefore q has no solufon at all.

MORE TYPE INFERENCE 76

let GeneralizaFon Where do we introduce polymorphic values? let x = v ==> let x : forall a1,..,an.s = v if v : s and a1,...,an are the variables of s And place x : forall a1,...,an.s in the context.

let GeneralizaFon Where do we introduce polymorphic values? let x = v ==> let x : forall a1,..,an.s = v if v : s and a1,...,an are the variables of s And place x : forall a1,...,an.s in the context. Where and how do we use a polymorphic value? G - x ==> x : s[b1/a1,...,bn/an), {} when G(x) = forall a1,...,an.s and b1,...,bn are fresh

What is the cost of type inference? In pracfce? Linear in the size of the program In theory, DEXPTIME-complete. Why? Because we can generate a program that has a type that is exponenfally large: let f1 x = x f1 : a -> a let f2 = f1 f1 f2 : (a -> a) -> (a -> a) let f3 = f2 f2 f3 : ((a -> a) -> (a -> a)) -> ((a -> a) -> (a -> a)) let f4 = f3 f3...

Summary: Type Inference Given a context G, and untyped term u: Find e, t, q such that G - u ==> e : t, q Find principal solufon S of q via unificafon if no solufon exists, there is no reconstrucfon Apply S to e, ie our solufon is S(e) S(e) contains schemafc type variables a,b,c, etc that may be instanfated with any type Since S is principal, S(e) characterizes all reconstrucfons. If desired, use the type checking algorithm to validate