Facilitating Programming Verification with Dependent Types Hongwei Xi

  • Slides: 24
Download presentation
Facilitating Programming Verification with Dependent Types Hongwei Xi University of Cincinnati

Facilitating Programming Verification with Dependent Types Hongwei Xi University of Cincinnati

A Wish List n We would like to have a programming language that should

A Wish List n We would like to have a programming language that should n be simple and general n support extensive error checking n facilitate proofs of program properties n possess correct and efficient implementation n. . .

Reality n Invariably, there are many conflicts among this wish list n These conflicts

Reality n Invariably, there are many conflicts among this wish list n These conflicts must be resolved with careful attention to the needs of the user

Advantages of Types n Capturing errors at compile-time n Enabling compiler optimizations n Facilitating

Advantages of Types n Capturing errors at compile-time n Enabling compiler optimizations n Facilitating program verification n Serving as program documentation

Limitations of Types n Not general enough n Many correct programs cannot be typed

Limitations of Types n Not general enough n Many correct programs cannot be typed n Not specific enough n Many interesting properties cannot be captured

Dependent Types n Dependent types are types that are n more refined n dependent

Dependent Types n Dependent types are types that are n more refined n dependent on the values of expressions n Examples n int(i): singleton type containing only integer i n <int> array(n): type for integer arrays of size n

Type System Design n A practically useful type system should be n Scalable n

Type System Design n A practically useful type system should be n Scalable n Applicable n Comprehensible n Unobtrusive n Flexible

Xanadu n Xanadu is a dependently typed imperative programming language with C-like syntax n

Xanadu n Xanadu is a dependently typed imperative programming language with C-like syntax n The type of a variable in Xanadu can change during execution n The programmer may need to provide dependent type annotations for typechecking purpose

Early Design Decisions n Practical type-checking n Realistic programming features n Conservative extension n

Early Design Decisions n Practical type-checking n Realistic programming features n Conservative extension n Pay-only-if-you-use policy

Examples of Dependent Types in Xanadu n int(a): singleton types containing the only integer

Examples of Dependent Types in Xanadu n int(a): singleton types containing the only integer equal to a, where a ranges over all integers n <‘a> array(a): types for arrays of size a in which all elements are of type ‘a, where a ranges over all natural numbers

Examples of Dependent Types in Xanadu n int(i, j) is defined as [a: int

Examples of Dependent Types in Xanadu n int(i, j) is defined as [a: int | i < a < j] int(a) n int[i, j) is defined as [a: int | i <= a < j] int(a) n int(i, j] is defined as [a: int | i < a <= j] int(a) n int[i, j] is defined as [a: int | i <= a <= j] int(a)

A Xanadu Program {n: nat} unit init (int vec[n]) { var int ind, size;

A Xanadu Program {n: nat} unit init (int vec[n]) { var int ind, size; ; size = arraysize(vec); invariant: [i: nat] (ind: int(i)) for (ind=0; ind<size; ind=ind+1){ vec[ind] = ind; } }

Binary Search in Xanadu {n: nat} int bs(int key, int vec[n]) { var: int

Binary Search in Xanadu {n: nat} int bs(int key, int vec[n]) { var: int l, m, h; float x; ; l = 0; h = arraysize(vec) - 1; invariant: [i: nat, j: nat | 0 <= i <= n, 0 <= j+1 <= n] (l: int(i), h: int(j)) while (l <= h) { m = (l + h) / 2; x = vec[m]; if (x < key) { l = m - 1; } else if (x > key) { h = m + 1; } else { return m; } } return – 1; }

Dependent Record Types n A polymorphic type for arrays {n: nat} <‘a> array(n) {

Dependent Record Types n A polymorphic type for arrays {n: nat} <‘a> array(n) { size: int(n); data[n]: ‘a }

Dependent Record Types n A polymorphic type for 2 -dimensional arrays: {n: nat} <‘a>

Dependent Record Types n A polymorphic type for 2 -dimensional arrays: {n: nat} <‘a> array 2(m, n) { row: int(m); col: int(n); data[m][n]: ‘a }

Dependent Record Types n A polymorphic type for heaps: {m: nat} <‘a> heap(m) {

Dependent Record Types n A polymorphic type for heaps: {m: nat} <‘a> heap(m) { max: int(m); size: int[0, m]; data[m]: ‘a }

Dependent Record Types n A polymorphic type for sparse arrays: <‘a>sparse. Array(m, n) {

Dependent Record Types n A polymorphic type for sparse arrays: <‘a>sparse. Array(m, n) { row: int(m); col: int(n); data[m]: <int[0, n) * ‘a> list }

Dependent Union Types n A polymorphic type for lists: union <‘a> list with nat

Dependent Union Types n A polymorphic type for lists: union <‘a> list with nat = { Nil(0); {n: nat} Cons(n+1) of ‘a * <‘a> list(n) } n Nil: <‘a> list(0) n Cons: {n: nat} ‘a * <‘a> list(n) -> ‘a list(n+1)

Dependent Union Types n A polymorphic type for binary trees: union <‘a> tree with

Dependent Union Types n A polymorphic type for binary trees: union <‘a> tree with (nat, nat) = { E(0, 0); {n: nat} B(sl+sr+1, 1+max(hl, hr)) of <‘a> tree(sl, hl) * ‘a * <‘a> tree(sr, hr) }

Reverse Append in Xanadu (‘a) {m: nat, n: nat} <‘a> list(m+n) rev. App (xs:

Reverse Append in Xanadu (‘a) {m: nat, n: nat} <‘a> list(m+n) rev. App (xs: <‘a> list(m), ys: <‘a> list(n)) { var: ‘a x; ; invariant: [m 1: nat, n 1: nat | m 1+n 1=m+n] (xs: <‘a> list(m 1), ys: <‘a> list(n 1)) while (true) { switch (xs) { case Nil: return ys; case Cons (x, xs): ys = Cons(x, ys); } } exit; /* can never be reached */ }

Constraint Generation in Type-checking The following integer constraint is generated when the rev. App

Constraint Generation in Type-checking The following integer constraint is generated when the rev. App example is type-checked: m: nat, n: nat, m 1: nat, n 1: nat, m 1+n 1=m+n, a: nat, m 1=a+1 |- a+(n 1+1)=m+n

Conclusion n It is still largely an elusive goal in practice to verify the

Conclusion n It is still largely an elusive goal in practice to verify the correctness of a program n It is therefore important to identify those program properties that can be effectively verified for realistic programs

Conclusion n We have designed a type-theoretic approach to capturing simple arithmetic reasoning n

Conclusion n We have designed a type-theoretic approach to capturing simple arithmetic reasoning n The preliminary studies indicate that this approach allows the programmer to capture many more properties in realistic programs

Future Work n Adding more program features into Xanadu n Constructing a compiler for

Future Work n Adding more program features into Xanadu n Constructing a compiler for Xanadu that can compile dependent types from source level into bytecode level n Incorporating dependent types into Java and …