Presentation is loading. Please wait.

Presentation is loading. Please wait.

Type Correctness.

Similar presentations


Presentation on theme: "Type Correctness."— Presentation transcript:

1 Type Correctness

2 Type Correctness Contracts provide signature, precondition etc.
It says nothing about implementation Program correctness deal with proving that implementation satisfies contract.

3 Program Correctness Type correctness Program Verification
Verify that the types of expressions in the program are “correct” – well-typing E.g. + is applied to numbers In other languages: we should also check that the type of value stored in a variable correspond to the variable declared type Program Verification Verify that the program halts and produces the “correct” output Somewhat easier with design-by-contract, where it can be done in a modular fashion

4 Static/Dynamic Type Check
Based on program code – can be applied off-line Dynamic Needs concrete data – done at runtime

5 Static Type Inference We will see 2 algorithms: Type inference rules
Type equations

6 Type Checking / Inference
Infer the type of an expression. In other words, we associate an expression e with a type t such that the evaluation of e yields a value in t. The purpose is to guarantee type safety.

7 Languages and Types How to include type information ?
Fully typed (every value has a type) C, Pascal, Java.. Semi-typed (allow typeless structures of values) Scheme Untyped Prolog

8 How Types are Specified? – the Type Language
We need a language for writing types Atomic types Composite types User defined types Language expressions vs. Type expressions Value constructors vs Type constructors Type Polymorphism Type variables

9 The Type Language Our restricted type language:
Atomic types: Number, Boolean, Symbol, Void, Empty and Procedure. No union types. No user-defined types. נדבר על instance מאוחר יותר.

10 Type Variable & Type Polymorphism
What is the type of: (lambda (x) x) ? It can applied to values of any type! ( (lambda (x) x) 3) => 3 ( (lambda (x) x) #t) => #t ( (lambda (x) x) +) => <primitive:+> [Number -> Number] [Boolean -> Boolean] [[Number * Number] -> Number] -> [[Number * Number] -> Number]

11 Type Variable & Type Polymorphism
We know variables that hold values. Now we have variables that holds types! Type variables provide the necessary abstraction: we can substitute (replace) type variables by other type expressions

12 Type Variable & Type Polymorphism
Type of identity function is [T -> T] What is the type of: (lambda (f x) (f x)) [[T1 -> T2]*T1 -> T2] (lambda (f x) ( (f x) x)) [[T1 -> [T1 -> T2]]*T1 -> T2]

13 Type Variable & Type Polymorphism
Type expressions that include type variables are called polymorphic type expressions Language expressions whose type is polymorphic are called polymorphic language expressions

14 Type Variable & Type Polymorphism
Unfortunately for you, checking well-typing with polymorphic types requires the concepts of: Substitution Composition of substitutions Application of a substitution Renaming

15 Type Variable & Type Polymorphism
Fortunately for you, you have already met those concepts More fortunately for you, we will again go over the definitions! (with type flavor)

16 BNF of the Type Language
Type -> ’Void’ | Non-void Non-Void -> Atomic | Composite | Type-variable Atomic -> ’Number’ | ’Boolean’ | ’Symbol’ Composite -> Procedure | Tuple Procedure -> ’[’ Tuple ’->’ Type ’]’ Tuple -> (Non-void ’*’ )* Non-void | ’Empty’ Pair -> ’Pair’ ’(’ Non-void ’,’ Non-void ’)’ List -> ’List’ ’(’ Non-void ’)’ | ’List’ Type-variable -> A symbol Note: Parameter for procedure cannot be Void. Procedure cannot return Empty.

17 Value and Type Constructors
Value Constructor Creates values! Examples: 3, lambda Type Constructor Creates types! Example: *, ->

18 Type Substitution Mapping s from a finite set of type variables to a finite set to type expressions, such that s(T) does not include T. {T1=Number, T2=[[Number -> T3] -> T3]} {T1=Number, T2=[[Number -> T3] -> T2]} illegal

19 Application of Type Substitution
Type expression τ, type substitution s. τ °s = replacing all occurrences of type variable T in τ by s(T) [[T1 -> T2] -> T2] ° {T1=Number, T2=[T3 -> T3]} = [[Number -> [T3 -> T3]] -> [T3 -> T3]]

20 Application of Type Substitution
A type expression τ’ is an instance of type-expression τ if there is a type-substitution s such that τ◦s= τ’. τ is more general than τ’ if τ’ is an instance of τ. e.g. all following are instances of [T -> T]: [Num -> Num] = [T->T]◦{T = Num} [Sym -> Sym] = [T->T]◦{T = Sym} [[Num -> Num] -> [Num -> Num]] = [T->T]◦{T = [Num->Num]} [[Num -> T1] -> [Num -> T1]] = [T->T]◦{T = [Num->T1]}

21 Combination of Type Substitution
Two type-substitution s1, s2 , s1°s2 is defined: s2 is applied to the type-expressions of s1 A variable T for which s1(T) is defined is removed from s2 Modified s2 is added to s1 Identity bindings are removed. Relax! Examples on next slide

22 Examples {T1=Number, T2=[[Number -> T3] -> T3]} ° {T3=Boolean, T1=[T2 -> T2]} = {T1 = Number, T2 = [[Number -> Boolean] -> Boolean]}

23 Renaming Type variables can be consistently renamed, but the new variables name should be new. [[T1 -> T2]*T1 -> T2] [[S1 -> T2]*S1 -> T2] [[S1 -> S2]*S1 -> S2] [[T1 -> T2]*S2 -> T2] [[T2 -> T2]*T2 -> T2] [[[T1 -> T2] -> T2]*[T1 -> T2] -> T2]

24 Unifier of Type Expressions
A type-substitution s, s.t. for two type expressions τ1, τ2 : τ1◦ s = τ2 ◦ s (no common type variables) Example: τ1 = [S*[Number->S1]->S] τ2 = [Pair(T1)*[T1->T1]->T2] s = {S=Pair(Number), T1=Number, S1=Number, T2=Pair(Number)}

25 Unifier of Type Expressions
Another Example: τ1 = [S*[Number->S]->S] τ2 = [Pair(T1)*[T1->T1]->T2] s = ?

26 Most General Unifier There can be infinite number of unifiers. For example: τ1 = [S*S->S] τ2 = [Pair(T1)*T2->T2] s = {S=Pair(T1), T2=Pair(T1)} {S=Pair(Number), T2=Pair(Number)} {S=Pair(Boolean), T2=Pair(Boolean)} Only the first one is the most general unifier (mgu)

27 Static Type Inference for Scheme
We start with a typing system for a restricted language that includes only: Atomic expressions with numbers, Booleans, primitive procedures, and variables Composite expressions with quote forms, lambda forms and application forms

28 Terminology Type Environment
A substitution mapping language variables to type expressions. Is the set of variable type assumptions Example: Tenv = {x:Number, y:[Number –> T]} Notation: Tenv(x) = Number Can be extended: {x:Number, y:[Number –> T]} ◦ {z:boolean} = {x:Number, y:[Number –> T], z:boolean} {} ◦ {x1:T1,...,xn:Tn} = {x1:T1,...,xn:Tn} Write on board

29 Terminology Typing statement A true/false formula Tenv |- e:T
Under Tenv, the expression e has the type T {x:Number} |- (+ x 5):Number {x:[T1 –> T2], y:T1} |- (x y):T2

30 Terminology Instantiation of Type statement
Applying substitution s to type statement TS {x:[T1 –> T2]} |- (x e):T2 {x:[T1 –> Boolean]} |- (x e):Boolean {x:[Number –> [Number –> Boolean]]} |- (x e):[Number –> Boolean]

31 Terminology Unifiable typing statements
Typing statements TS and TS’ are unifiable if there exists a type substitution s such that TS°s = TS’°s

32 Restricted Scheme (syntax)
<scheme-exp> -> <exp> <exp> -> <atomic> | <composite> <atomic> -> <number> | <boolean> | <variable> <composite> -> <special> | <form> <number> -> Numbers <boolean> -> ’#t’ | ’#f’ <variable> -> sequences of letters <special> -> <lambda> | <quote> <form> -> ’(’ <exp>+ ’)’ <lambda> -> ’(’ ’lambda’ ’(’ <variable>* ’)’ <exp>+ ’)’ <quote> -> ’(’ ’quote’ <variable> ’)’ For now: no ‘if’s, no ‘define’s and no recursive procedures

33 Well-Typing Rules To infer the type of an expression (as well as whether or not it is well-typed), we need to define axioms and rules To be used on sub-expressions, to derive types of the more complex expression Only abbreviated forms are given here, see lecture notes for full description of rules.

34 ע"מ 215

35 Notes We’re almost ready to see the algorithm… Meta variables
Axiom and rule independence Identifying pattern The monotonicity rule Exhaustive sub-expression typing We’re almost ready to see the algorithm…

36 Expression Trees The nesting of expressions can be viewed as a tree Sub-trees correspond to composite expressions For lambda expressions, their body expressions reside in their children Leaves correspond to atomic ones

37 Expression Tree Example
Tree for (+ 2 (+ 5 7)) (+ 2 (+ 5 7)) + 2 (+ 5 7) + 5 7

38 Type Derivation (inference) Algorithm
Main idea: go bottom-up on the expression tree, deriving new type statements by using the “type-statements-pool”, rules and substitution Add the result to the type-statements-pool Declare T if you get {} |-e:T FAIL otherwise

39 Example Derive a typing statement for (+ 2 ( + 5 7)) (+ 2 (+ 5 7)) + 2

40 We start with the leaves: we use Number and primitives axioms.
4. { } |- +:[Number*Number -> Number]

41 Next we deal with (+ 5 7): Application axiom.
For every: type environment _Tenv, expressions _f, _e1, ..., _en, n >= 0 , and type expressions _S1, ..., _Sn, _S: Procedure with parameters (n > 0): If _Tenv |- _f:[_S1*...*_Sn -> _S], _Tenv |- _e1:_S1, ..., _Tenv |- _en:_Sn Then _Tenv |- (_f _e1 ... _en):_S Application of typing rule Application to typing statements 4,1,2, with type substitution {_S1=Number, _S2=Number, _S=Number}: 5. { } |- (+ 5 7):Number

42 Application of typing rule Application to typing statements 4,3,5, with type substitution
{_S1=Number, _S2=Number, _S=Number}: 6. { } |- (+ 2 (+ 5 7)):Number Done

43 Type-Derivation Algorithm
ע"מ 213

44 For Every Type Environment…
Non determinism  So: always pick a minimal type environment: Axioms user empty TE, except Variable axiom. Procedure rule TE only with free variables Application rule TE of existing TS

45 Well-typeness e is well-typed if Type-derivation(e) does not fail.
e has a type if it is well typed and Type-derivation(e) ends with { } |- e:t

46 Example ((λ (x) (+ x 3)) 5) (λ (x) (+ x 3)) 5 (+ x 3) + x 3

47 { } |- +:[Number*Number -> Number] {x:T} |- x:T (variable axiom)
{x:T1} |- 3:Number (monoticity) {x:T2} |- +:[Number*Number -> Number] (monoticity) {x:Number} |- (+ x 3):Number (application, unification) { } |- (lambda (x) (+ x 3)):[Number -> Number] (procedure) { } |- ((lambda (x) (+ x 3)) 5):Number (application) דוגמה מפורטת בספר בע"מ 121

48 Another Example: Fail

49 {x1:T1} |- x1:T1 { } |- +:[Number*Number -> Number] {x:T2} |- x:T2 { } |- (lambda (x1) x1):[T1 -> T1] Fail

50 Definitions > (define x 1) > (define y (+ x 1)) > (+ x y) 3 What is the type of x, y, (+ x y) ?

51 Typing Rule Define For every definition expression (define _x _e) and type expression _S: If { } |- _e:_S, Then { } |- _x:_S

52 Example Given > (define x 1) > (define y (+ x 1)) Derive a type for (+ x y)

53 { } |- 1 : Number { } |- x : Number { } |- + : [Number * Number] -> Number { } |- (+ x 1) : Number { } |- y:Number { } |- (+ x y):Number

54 Throwing in control flow (if)
For every type environment _Tenv, expressions _e1, _e2, _e3, and type expressions _S1, _S2: If _Tenv |- _e1:S1 and _Tenv |- _e2:_S2 and _Tenv |- _e3:_S2 Then _Tenv |- (if _e1 _e2 _e3) : _S2

55

56 Recursions (define f e), but e contains a free variable
We modify the notion of well-typeness: (define f e) is ok if: {f:[S1*...Sn –> S]} |- e:[S1*...Sn –> S]

57 Recursions For every: recursive-definition expression (define _f _e) and type expression _S: If {_f:_S } |- _e:_S, Then { } |- (define _f _e):Void, and { } |- _f:_S

58 Example (define fact (λ (n) (if (= n 0) 1 (* n (fact (- n 1))))))
לצייר על הלוח את העץ ואת חוק application.

59 Well typed! Application rule on ts 2,4,5 {_S1=T1=Num, _S2=Num, _S=num}
1. {} |- =:[Num*Num -> Bool] 2. {} |- -:[Num*Num -> Num] 3. {} |- *:[Num*Num -> Num] 4. {} |- 1:Num 5. {n:T1} |- n:T1 6. {fact:T2} |- fact:T2 Application rule on ts 2,4,5 {_S1=T1=Num, _S2=Num, _S=num} 7. {n:Num} |- (- n 1): num Application rule on ts 6,7 {_S1=Num, _S=T3, T2=[Num->T3]} 8. {fact:[Num->T3], n:Num} |- (fact (- n 1)):T3 Application rule on ts 5,6,8 {_S1=Num, _S2=Num, _S=Num, T1=Num, T3=Num} 9. {fact:[Num->Num], n:Num} |- (* n (fact (- n 1))):Num Application rule on ts 1,5,4 {_S1=Bool, _S2=Num, _S=Bool} 10. {n:Num} |- (= n 0):Bool if rule on ts 4,9, {fact:[Num->Num], n:Num} |- (if …):Num Procedure rule on ts 11 {_S1=Num, _U1=Num} 12. {fact:[Num->Num]} |- (λ (n) (if …)):[Num -> Num] Recursive-definition to statement no. 12, with type-substitution {_S=[Number -> Number]}: 13. { } |- (define fact (λ (n) (if …))):Void 14. { } |- fact:[Num -> Num] Well typed!

60 Pair & List Types Operations are primitives, so all have axioms.
ע"מ 238

61 Type Constraints Approach
4 Stages: Rename bound variables Assign type variable for all sub-expression Construct type equations over these variables Numbers, booleans, quoted symbols, primitive procedures: Construct equations using their types. Intuitive rules for lambda and applications Solve the equations

62 Demo by Example (λ (f g) (λ (x) (f (+ x (g 3)))))

63 Stage II: Assign Type Variables
Expression T0 (lambda (f g) (lambda (x) (f (+ x (g 3))))) T1 (lambda (x) (f (+ x (g 3)))) T2 (f (+ x (g 3))) Tf f T3 (+ x (g 3)) T+ + Tx x T4 (g 3) Tg g Tnum3 3

64 Stage III: Construct Type Equations
Primitives: use the primitive type λ expression: for (λ (v1…vn) e1…em) contruct: T(λ (v1…vn) e1…em)=[Tv1*…*Tvn -> Tem] Application: for (f e1 … en) construct: Tf=[Te1*…*Ten -> T(f e1 … en)] On board

65 Solving the equations Apply current substitution on equation
Check atomic types If a circular substitution is created output FAIL. If both sides of equation are composite and have same type constructor, split the equation into equations between corresponding components

66

67

68

69

70 Done! The inferred type is:
[[Number -> T2] * [Number -> Number] -> [Number -> T2]]


Download ppt "Type Correctness."

Similar presentations


Ads by Google