Presentation is loading. Please wait.

Presentation is loading. Please wait.

Imperative Programming with Dependent Types

Similar presentations


Presentation on theme: "Imperative Programming with Dependent Types"— Presentation transcript:

1 Imperative Programming with Dependent Types
Hongwei Xi University of Cincinnati 20 September 2018

2 Talk Overview Motivation Programming language Xanadu Conclusion
Program error detection Compilation certification Proof-carrying code Programming language Xanadu Design decisions Dependent type system Programming examples Conclusion 20 September 2018

3 Some Advantages of Types
Detecting program errors at compile-time Enabling compiler optimizations Facilitating program verification Using types to encode program properties Verifying the encoded properties through type-checking Serving as program documentation Unlike informal comments, types are formally verified and can thus be trusted 20 September 2018

4 Limitations of (Simple) Types
Not general enough Many correct programs cannot be typed For instance, downcasts are widely used in Java Not specific enough Many interesting program properties cannot be captured For instance, types in Java cannot handle safe array access 20 September 2018

5 Narrowing the Gap NuPrl Coq Program Extraction Proof synthesis
Dependent ML ML 20 September 2018

6 A Challenging Problem How can we prove the correctness of a (realistic) compiler? Verifying that the semantics of P is the same as the semantics of |P| for every program P But this simply seems too challenging (and is unlikely to be feasible) compilation | . | Source program P Target code |P| 20 September 2018

7 Compilation Certification
Assume that P(P) holds, i.e., P has the property P Then there is likely some property |P| related to P such that |P|(|P|) holds A compiler can be designed to produce a certificate that asserts |P| does have the property |P| compilation | . | Source program P: P(P) holds Target code |P|: |P|(|P|) holds 20 September 2018

8 Proof-Carrying Code Unpacking Code Poof-Carrying Code Verifying Proof
Executing Memory Safety Termination 20 September 2018

9 Proof Construction Building type derivations at source level with a practical type inference algorithm Translating such type derivations into proofs at target level compilation | . | Source program P Target code |P| Proof of P(P) Proof of |P|(|P|) proof translation 20 September 2018

10 Talk Overview Motivation Programming language Xanadu Conclusion
Program error detection Compilation certification Proof-carrying code Programming language Xanadu Design decisions Dependent type system Programming examples Conclusion 20 September 2018

11 Xanadu: an Exotic Place
In Xanadu did Kubla Khan A stately pleasure-dome decree … … -- Samuel Taylor Coleridge 20 September 2018

12 Xanadu: an “Exotic” Language
Xanadu is an imperative programming language with C/Java-like syntax that supports a restricted form of dependent types The type of a variable in Xanadu may change during execution The programmer may need to provide dependent type annotations for type-checking purpose 20 September 2018

13 A Type for Arrays A polymorphic type for arrays record <‘a> array { size: int; data[]: ‘a } But this does not enforce that the integer stored in size is the size of the array to which data points size data 20 September 2018

14 A Dependent Type for Arrays
A polymorphic type for arrays {n:nat} record <‘a> array(n) { size: int(n); data[n]: ‘a } 20 September 2018

15 Informal Comments /* the function should not be applied to a negative integer */ int factorial (x: int) { /* defensive programming */ if (x < 0) exit(1); if (x == 0) return 1; else return (x * factorial (x-1)); } Note: factorial(-1) is well-typed! 20 September 2018

16 Formalizing Comments {n:nat} int factorial (x: int(n)) {
if (x == 0) return 1; else return (x * factorial (x-1)); } Note: factorial (-1) is now ill-typed and rejected! 20 September 2018

17 Informal 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; 20 September 2018

18 Formalizing 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 */ … … … } 20 September 2018

19 Some Design Decisions Practical type-checking
Realistic programming features Conservative extension Pay-only-if-you-use policy 20 September 2018

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

21 Examples of Dependent Types
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) 20 September 2018

22 Array Initialization in Xanadu
{n:nat} unit init (vec: <int> array(n)) { var: int ind;; invariant: [i:int | i>=0] (ind: int(i)) for (ind=0; ind<vec.size; ind=ind+1){ vec.data[ind] = 0; } 20 September 2018

23 A Slight Variation {n:nat} unit init (vec: <int> array(n)) {
var: int ind;; invariant: [i:int | i<=n] (ind: int(i)) for (ind=vec.size; ind>=0; ind=ind-1){ vec.data[ind] = 0; } 20 September 2018

24 Another Slight Variation
{n:nat} unit init (vec: <int> array(n)) { var: nat ind;; for (ind=0; ind<vec.size; ind=ind+1){ vec.data[ind] = 0; } 20 September 2018

25 Binary Search in Xanadu
{n:nat} int bsearch (key: int, vec: <int> array(n)) { var: int l, h, m, x;; l = 0; h = vec.size - 1; invariant: [i:int,j:int | 0<=i<=j+1<=n] (l:int(i),h:int(j)) 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; 20 September 2018

26 A Slight Variation {n:nat}
int bsearch (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; 20 September 2018

27 2-dimensional Arrays A polymorphic type for 2-dimensional arrays: {m:nat,n:nat} record <‘a>array2(m,n) { row: int(m); col: int(n); data[m][n]: ‘a } 20 September 2018

28 Sparse Arrays A polymorphic type for sparse arrays:
{m:nat,n:nat} record <‘a> sparseArray(m,n) { row: int(m); col: int(n); data[m]: <int[0,n) * ‘a> list } 20 September 2018

29 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) 20 September 2018

30 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) } The two indices represent size and height, respectively 20 September 2018

31 Type Judgment in Xanadu
f1;D1;G |- e: (f2;D2;t) f: Context for index variables D: Context for variables with mutable types G: Context for variables with fixed types 20 September 2018

32 ---------------------------
Typing an Assignment f1;D1;G |- e: (f2;D2;t) f1;D1;G |- x = e: (f2;D2[x->t];unit) 20 September 2018

33 Typing a Loop f1;D1 |- $f.D f1,f;D;G|- e1:(f2;D2;bool(i)) f2,i=1;D2;G |- e2:(f3;D3;unit) f3;D3 |- $f.D f1;D1;G |-while(e1,e2):(f2,i=0;D2;unit) Note: $f.D is a loop invariant 20 September 2018

34 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 */ } 20 September 2018

35 A Generated Constraint
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 20 September 2018

36 Talk Overview Motivation Programming language Xanadu Conclusion
Program error detection Compilation certification Proof-carrying code Programming language Xanadu Design decisions Dependent type system Programming examples Conclusion 20 September 2018

37 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 (FFT, Heapsort, Quicksort, Gaussian elimination, etc.) at 20 September 2018

38 Conclusion 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 20 September 2018

39 Conclusion We have designed a type-theoretic approach to capturing some simple arithmetic reasoning in programming The preliminary studies indicate that this approach allows the programmer to capture many more properties in realistic programs while retaining practical type-checking 20 September 2018

40 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 … 20 September 2018

41 Related Work Here is some related work
Dependent types in practical programming (Xi & Pfenning) Cayenne (Augustsson) TALC Compiler (Morrisett et al at Cornell) Safe C compiler: Touchstone (Necula & Lee) TIL compiler (the Fox project at CMU) FLINT compiler (Shao et al at Yale) Secure Internet Programming (Appel, Felten et al at Princeton) 20 September 2018

42 End of the Talk Thank You! Questions? 20 September 2018


Download ppt "Imperative Programming with Dependent Types"

Similar presentations


Ads by Google