View
217
Download
2
Embed Size (px)
Citation preview
May 1, 2003 2
Talk Overview
Motivation– Detecting program errors (at compile-time)– Generating proof-carrying code
Programming language Xanadu:– Design decisions– Dependent type system– Programming examples
Current Status and Future Work
May 1, 2003 3
A Wish List
We would like to have a programming language that should– be simple and general– support extensive error checking– facilitate proofs of program properties– possess correct and efficient implementation– ... ...
May 1, 2003 4
Reality
Invariably, there are many conflicts among this wish list
These conflicts must be resolved with careful attention to the needs of the user
May 1, 2003 5
Advantages of Types
Capturing errors at compile-time Enabling compiler optimizations Facilitating program verification
– Using types to encode program properties and verifying the encoded properties through type-checking
Serving as program documentation– Unlike informal comments, types can be fully
trusted after type-checking
May 1, 2003 6
Limitations of (Simple) Types
Not general enough– Many correct programs cannot be typed– For instance, type casts are widely used in C
Not specific enough– Many interesting properties cannot be
captured– For instance, types in Java cannot handle safe
array access
May 1, 2003 7
Narrowing the Gap
NuPrl Coq
Program Extraction Proof synthesis
ML withDependent Types
ML
May 1, 2003 8
Informal Program Comments
/* the function should not be applied to a negative integer
*/int factorial (x: int) { if (x < 0) exit(1); /*defensive
programming*/ if (x == 0) return 1;
else return (x * factorial (x-1));}
May 1, 2003 9
Formalizing Program Comments
{n:nat}int factorial (x: int(n)) { if (x == 0) return 1;
else return (x * factorial (x-1));}
Note: factorial (-1) is ill-typed and rejected!
May 1, 2003 10
Informal Program Comments
/* arrays a and b are of equal size */float dotprod (float a[], float b[]) { int i; float sum = 0.0; if (a.size != b.size) exit(1); for (i = 0; i < a.size; i = i + 1) { sum = sum + a[i] * b[i]; } return sum;}
May 1, 2003 11
Formalizing Program Comments
{n:nat}float dotprod (a: <float> array(n),
b: <float> array(n)) { /* dotprod is assigned the following type: {n:nat}. (<float> array(n), <float> array(n)) ->
float */ /* function body */ … … …}
May 1, 2003 12
Dependent Types
Dependent types are types that are– more refined– dependent on the values of expressions
Examples– int(i): singleton type containing only integer i– <int> array(n): type for integer arrays of size
n
May 1, 2003 13
Type System Design
A practically useful type system should be– Scalable– Applicable– Comprehensible– Unobtrusive– Flexible
May 1, 2003 14
Xanadu
Xanadu is a dependently typed imperative programming language with C-like syntax
The type of a variable in Xanadu can change during execution
The programmer may need to provide dependent type annotations for type-checking purpose
May 1, 2003 15
Early Design Decisions
Practical type-checking Realistic programming features Conservative extension Pay-only-if-you-use policy
May 1, 2003 16
Examples of Dependent Types (I)
int(a): singleton types containing the only integer equal to a, where a ranges over all integers
<‘a> array(a): types for arrays of size a in which all elements are of type ‘a, where ‘a ranges over all natural numbers
May 1, 2003 17
Examples of Dependent Types (II)
int(i,j) is defined as [a:int | i < a < j] int(a),that is, the sum of all types int(a) for i < a < j
int[i,j), int(i,j] , int[i,j] are defined similarly nat is defined as
[a:int | a >=0] int(a)
May 1, 2003 18
A Xanadu Program
{n:nat} unit init (int vec[n]) { var: int ind, size;; /* arraysize: {n:nat} <‘a> array(n) -> int(n) */ size = arraysize(vec); invariant: [i:nat] (ind: int(i)) for (ind=0; ind<size; ind=ind+1){ vec[ind] = ind; }}
May 1, 2003 19
A Slight Variation
{n:nat} unit init (int vec[n]) { var: nat ind, size;; /* arraysize: {n:nat} <‘a> array(n)-> int(n)
*/ size = arraysize(vec); for (ind=0; ind<size; ind=ind+1){ vec[ind] = ind; }}
May 1, 2003 20
Dependent Record Types
A polymorphic type for arrays
{n:nat} <‘a> array(n) { size: int(n); data[n]: ‘a}
May 1, 2003 21
Binary Search in Xanadu
{n:nat}int bs(key: int, vec: <int> array(n)) { var: l: int [0, n], h: int [-1, n); int m, x;; l = 0; h = vec.size - 1; while (l <= h) { m = (l + h) / 2; x = vec.data[m]; if (x < key) { l = m - 1; } else if (x > key) { h = m + 1; } else { return m; } } return –1;}
May 1, 2003 22
Dependent Record Types
A polymorphic type for 2-dimensional arrays:
{m:nat,n:nat} <‘a> array2(m,n) { row: int(m); col: int(n); data[m][n]: ‘a}
May 1, 2003 23
Dependent Record Types
A polymorphic type for sparse arrays:
{m:nat,n:nat} <‘a>sparseArray(m,n) { row: int(m); col: int(n); data[m]: <int[0,n) * ‘a> list}
May 1, 2003 24
Dependent Union Types
A polymorphic type for lists:
union <‘a> list with nat = { Nil(0); {n:nat} Cons(n+1) of ‘a * <‘a> list(n) }
Nil: <‘a> list(0) Cons: {n:nat}‘a * <‘a> list(n)-> <‘a> list(n+1)
May 1, 2003 25
Dependent Union Types
A polymorphic type for binary trees:
union <‘a> tree with (nat,nat) = { E(0,0); {sl:nat,sr:nat,hl:nat,hr:nat} B(sl+sr+1,1+max(hl,hr)) of <‘a> tree(sl,hl) * ‘a * <‘a> tree(sr,hr) }
May 1, 2003 26
Typing Judgment in Xanadu
eContext for index variables
Context for variables with mutable types
Context for variables with fixed types
May 1, 2003 29
Reverse Append in Xanadu
(‘a) {m:nat,n:nat}
<‘a> list(m+n) revApp (xs:<‘a> list(m),ys:<‘a> list(n)) {var: ‘a x;;invariant: [m1:nat,n1:nat | m1+n1=m+n] (xs:<‘a> list(m1), ys:<‘a> list(n1))while (true) { switch (xs) { case Nil: return ys; case Cons (x, xs): ys = Cons(x, ys); } } exit; /* can never be reached */
}
May 1, 2003 30
Constraint Generation in Type-checking
The following integer constraint is generated when the revApp example is type-checked:
m:nat,n:nat, m1:nat,n1:nat, m1+n1=m+n, a:nat, m1=a+1
|= a+(n1+1)=m+n
May 1, 2003 31
Current Status of Xanadu
A prototype implementation of Xanadu in Objective Caml that– performs two-phase type-checking, and– generates assembly level code
An interpreter for interpreting assembly level code
A variety of examples athttp://www.cs.bu.edu/~hwxi/Xanadu/Xanadu.html
May 1, 2003 32
Conclusion (I)
It is still largely an elusive goal in practice to verify the correctness of a program
It is therefore important to identify those program properties that can be effectively verified for realistic programs
May 1, 2003 33
Conclusion (II)
We have designed a type-theoretic approach to capturing simple arithmetic reasoning
The preliminary studies indicate that this approach allows the programmer to capture many more properties in realistic programs while retaining practical type-checking
May 1, 2003 34
Future Work
Adding more programming features into Xanadu– in particular, OO features
Type-preserving compilation: constructing a compiler for Xanadu that can translate dependent types from source level into bytecode level
Incorporating dependent types into (a subset of) Java and …