Lecture Notes Chapter 2 Midterm 2011 נתונות הפרוצדורות foo ו goo define foo lambda x display x newline x 2 define goo lambda x display 5 newline x 1 ID: 432408
Download Presentation The PPT/PDF document "PPL Static Verification: Type Inference" is the property of its rightful owner. Permission is granted to download and print the materials on this web site for personal, non-commercial use only, and to display it on your personal computer provided you do not modify the materials and that you retain all copyright notices contained in the materials. By downloading content from our website, you accept the terms of this agreement.
Slide1
PPL
Static Verification: Type Inference
Lecture Notes: Chapter 2Slide2Slide3
Midterm 2011
נתונות הפרוצדורות foo
ו-
goo:
(define
foo
(lambda (x) (display x) (newline) (+ x 2)))
(define goo
(lambda (x) (display 5) (newline) (+ x 1)))
א. בחישוב של הביטוי
> (
foo
(goo 0))
התקבל הפלט הבא על המסך:
5
1
5
3
מהי שיטת החישוב של האינטרפרטר? סמן בעיגול תשובה יחידה.
1.
applicative order 2. normal orderSlide4
Type Correctness
Contracts provide signature, precondition etc.It says nothing about implementation
Program correctness
deal with proving that implementation satisfies contract.Slide5
Program Correctness
Type correctness
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 fashionSlide6
Types
All possible values are split into subsets called types that collect values of similar kind.
In Scheme (seen so far):
Values = {Numbers, Booleans, Symbols, Closures}Slide7
Languages and Types
Fully typed (every value has a type)C, Pascal, Java..
Semi-typed (allow
typeless
structures of values)
Scheme
Untyped
Prolog
Well-typing rules
Define relationships between typesSlide8
Static/Dynamic Type Check
StaticBased on program code – can be applied off-line
Dynamic
Needs concrete data – done at runtimeSlide9
Type Checking and Inference
Type Checking. Given an expression, and a “goal” type T, verify that the expression type is T.
Example: Given the expression
(+ (f 3) 7)
, we need to verify that
(f 3)
is a number.
Type Inference
. Infer the type of an expression Example:
(f 3)Slide10
Type Language
We need a language for writing typesAtomic types
Composite types
User defined types
Language expressions vs. Type expressions
Value constructors vs Type constructors
Type Polymorphism
Type variablesSlide11
Void
What is the type of
(λ (
x)
(display (+ 1 x)))
?
[Number -> Void]Slide12
Void
Singleton set {void}
Cannot be embedded in a composite expressionSlide13
Value and Type Constructors
Value ConstructorCreates values!
Examples:
3
,
lambda
Type Constructor
Creates types!
Example:
*
,
->Slide14
What is Type Checking (Summary)
Programming Languages Properties
Typed, Semi-typed
Well typing rules
Type Language Properties
Atomic/composite types
User defined
Polymorphic
Type Correctness Mechanism
Static/Dynamic
Type Inference
Type safetySlide15
The Scheme Type Language
Scheme is fully typed but no type in syntaxType checking is performed at runtime
Well typing rules:
Hierarchy of number types
In procedure application type of argument is an
instance
of type of parameterSlide16
The Scheme Type Language
(seen so far)
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’
Type-variable -> A symbolSlide17
Tuples
What is the type of:
(λ (
x y)
(+ x y))
?
We know that:
[Number * Number -> Number]
What about
(λ (
)
5)
?
[Empty
-> Number]Slide18
Types in Scheme (
cnt’)Tuple
Type
Procedures with any number of parameters: n-
tuples
.
Empty
for 0-tuples.
T
1
*…*
T
n
for n-
tuples
.
*
is type constructor
Cannot be a returned typeSlide19
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
]Slide20
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
expressionsSlide21
Type Variable & Type Polymorphism
Type of identity function is
[
T
->
T]
What is the type of:
(lambda (f x) (f x))
[[T
1
-> T
2
]*T
1
-> T
2
]
(lambda (f x) ( (f x) x))
[[T
1
-> [T
1
-> T
2
]]*T
1
-> T
2
]Slide22
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 expressionsSlide23
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
RenamingSlide24
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)Slide25
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
]}
illegalSlide26
Application of Type Substitution
Type expression
TE
, type substitution
s.
TE°s
= replacing all occurrences of type variable T in TE by s(T)
[[T
1
-> T
2
] -> T
2
] °
{T
1
=Number,
T
2
=[T
3
-> T
3
]} =
[[Number -> [T
3
-> T
3
]] -> [T
3
-> T
3
]]Slide27
Combination of Type Substitution
Two type-substitution s
1
,
s
2
s
1
°s
2
:
s
2
is applied to the type-expressions of
s
1
A variable T for which s
1
(T) is defined is removed from s
2
Modified s
2
is added to s
1
Identity bindings are removed.
Relax! Examples on next slideSlide28
Examples
{T
1
=Number, T
2
=[[Number -> T
3
] -> T
3
]} °
{T
3
=Boolean, T
1
=[T
2
-> T
2
]}
=
{T1 = Number, T2 = [[Number -> Boolean] -> Boolean]}Slide29
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]Slide30
About Well-
TypenessWell Typed
(+ 5 6)
(+ 5
x)
(lambda (x)
(+ 1 x))
(lambda (x)
(+ x (+ x 5)))
Not Well Typed
(+ 5
#t)
(* (+
5 x
) (x 1))
(
lambda (x)
(+
x
(x
5
)))Slide31
Static Type Inference
Infers the type of an expressionChecks for correctness of types (well-
typeness
)
Example: type inference for
(+ x 5)
states that given x is a Number, the type is Number.
Similar to logic inference:
Definitions
Axioms
Rules
AlgorithmSlide32
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
C
omposite
expressions with quote forms, lambda forms
and application
formsSlide33
Terminology
Type Environment
A substitution mapping type variables to types
Is the set of variable type assumptions
Example
:
T
env
= {x:Number
,
y:[Number
–> T
]}
Notation
:
T
env
(x) = Number
Can be extended:
{x:Number, y:[Number –> T]} ◦ {z:boolean} =
{x:Number, y:[Number –> T], z:boolean}
{} ◦ {x
1
:T
1
,...,
x
n
:T
n
} = {x
1
:T
1
,...,
x
n
:T
n
}Slide34
Terminology
Typing statement
A true/false formula
T
env
|- e:T
Under
T
env
, the expression e has the type T
{x:Number} |- (+ x 5):Number
{x:[T
1
–> T
2
], y:T
1
} |- (x y):T
2Slide35
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]Slide36
Terminology
Unifiable typing statementsTyping
statements
TS
and
TS’
are unifiable if
there exists
a type substitution s such that
TS°s
=
TS’°sSlide37
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 proceduresSlide38
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
. Slide39Slide40
Notes
Meta variablesAxiom and rule independence
Identifying
pattern
The monotonicity rule
We’re almost ready to see the algorithm…Slide41
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 onesSlide42
Expression Tree Example
Tree for
(+ 2 (+ 5 7))
(+ 2 (+ 5 7))
+
(+ 5 7)
2
+
5
7Slide43
Well-typeness
Definition: If Type-derivation(e
) ends with
{
} |- e:t
,
We say
that e is well typed, and its type is t
.Slide44
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 otherwiseSlide45
Example
Derive a typing statement for
(+ 2 ( + 5 7))
(+ 2 (+ 5 7))
+
(+ 5 7)
2
+
5
7Slide46
We start with the leaves: we use
Number and primitives axioms.
1. { } |- 5:Number
2. { } |- 7:Number
3. { } |- 2:Number
4. { } |- +:[Number*Number -> Number]Slide47
Next we deal with (+ 5 7): Application axiom.
For every:
type environment _
Tenv
,
expressions _f, _e
1
, ..., _e
n
, n >= 0 , and
type expressions _S
1
, ..., _
S
n
, _S:
Procedure with parameters (n > 0):
If _
Tenv
|- _f:[_S
1
*...*_S
n
-> _S],
_
Tenv
|- _e1:_S
1
, ..., _
Tenv
|- _
e
n
:_S
n
Then _
Tenv
|- (_f _e
1
... _
e
n
):_S
Application of typing rule Application to typing statements 4,1,2, with type substitution
{_S
1
=Number, _S
2
=Number, _S=Number}:
5. { } |- (+ 5 7):NumberSlide48
Application of typing rule Application to typing statements 4,3,5, with type substitution
{_S
1
=Number, _S
2
=Number, _S=Number}:
6. { } |- (+ 2 (+ 5 7)):Number
DoneSlide49
Type-Derivation AlgorithmSlide50
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 variablesSlide51
Example
((
λ
(x) (+ x 3)) 5)
5
(
λ
(x) (+ x 3))
(+ x 3)
3
x
+Slide52
{
} |-
5:Number
{
} |-
3:Number
{ } |- +:[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)Slide53
Another Example: FailSlide54
{x1:T1} |- x1:T1
{
} |- +:[Number*Number -> Number]
{
x:T2} |- x:T2
{
} |- (lambda (x1) x1):[T1 -> T1
]
FailSlide55
Definitions
> (define x 1)
> (define y (+ x 1))
> (+ x y)
3
What is the type of
x
,
y
,
(+ x y)
?Slide56
Typing Rule Define
For every definition expression (define _x _e) and type expression _S:
If
{
} |- _
e:_S
,
Then { } |- (define _x _e):Void, and
{
} |- _
x:_SSlide57
Example
Given
> (define x 1)
> (define y (+ x 1))
Derive a type for
(+ x
y)Slide58
{ } |- 1 : Number
{ } |- (define x 1) : Void
{ } |- x : Number
{ } |- + : [Number * Number] -> Number
{ } |- (+ x 1) : Number
{ } |- (define y (+ x 1)):
Void
{
} |-
y:Number
{
} |- (+ x y):NumberSlide59
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) : _S2Slide60Slide61
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]Slide62
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:_SSlide63
Example
(define fact
(λ (n)
(if (= n 0) 1
(* n (fact (- n 1))))))Slide64
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 1):
Bool
if rule on
ts
4,9,10
{_S1=
Bool
, _S2=Num, _S=
Bool
}
11. {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!Slide65
Type constraints approach
3 Stages:
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 equationsSlide66
Demo by Example
(λ (
f g)
(
λ (
x)
(f (+ x (g 3)))))Slide67
Stage I: Assign Type Variables
Variable
Expression
T
0
(lambda (f g) (lambda (x) (f (+ x (g 3)))))
T
1
(lambda (x) (f (+ x (g 3))))
T
2
(f (+ x (g 3)))
T
f
f
T
3
(+ x (g 3))
T
+
+
T
x
x
T
4
(g 3)
T
g
g
T
num3
3Slide68
Stage II: Construct Type Equations
Primitives: use the primitive type
λ
expression
: for
(
λ
(v
1
…
v
n
) e
1
…
e
m
)
contruct
:
T
(
λ
(v1…
vn
) e1…
em
)
=[T
v1
*…*
T
vn
-> T
em
]
Application
: for
(f e1 … en)
construct:
T
f
=[T
e1
*…*T
en
-> T
(f e1 … en)
]
On boardSlide69
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
componentsSlide70Slide71Slide72Slide73Slide74
Done! The inferred type is:
[[Number -> T
2
] * [Number -> Number] -> [Number -> T
2
]]