compiling with dependent types

28
Compiling with Dependent Types Hongwei Xi University of Cincinnati

Upload: brent-ortega

Post on 04-Jan-2016

63 views

Category:

Documents


3 download

DESCRIPTION

Compiling with Dependent Types. Hongwei Xi University of Cincinnati. What do we want to do?. To produce (optimized) self-certified code that can guarantee both type safety and memory safety Self-certification is done through the use of a form of low-level dependent types - PowerPoint PPT Presentation

TRANSCRIPT

Compiling with Dependent Types

Hongwei XiUniversity of Cincinnati

What do we want to do?

To produce (optimized) self-certified code that can guarantee both type safety and memory safety

Self-certification is done through the use of a form of low-level dependent types

Such low-level dependent types are to be translated from high-level dependent types in source programs

Source Language: Xanadu

Xanadu (Xi, 2000) 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

A Program in Xanadu

{n:nat} float dotprod (len: int(n), a[n]: float, b[n]: float) {

var: nat i; float sum;; /* nat is [a: int | a >= 0] int(a) */

sum = 0.0;

for (i = 0; i < len; i = i + 1) { sum = sum +. a[i] *. b [i];

}

return sum;}

A Datatype in Xanadu

A polymorphic datatype for lists:

union <‘a> list with nat = { Nil (0); Cons (n+1) of ‘a * <‘a> list(n)}

Another Program in Xanadu (‘a){n:nat} int(n) length (xs: <‘a>list(n)) {

var: int x;; invariant: [i:nat,j:nat | i+j=n] (xs:<‘a> list(i), x:int(j)) while (true) { switch (xs) { case Nil: return x; case Cons (_, xs): x = x+1; } } exit; /* can never be reached */}

Target Language: DTAL

DTAL is a dependently typed assembly language (Xi and Harper, 1999)

DTAL was originally designed to extend TAL (Morrisett et al, 1998) with a form of dependent types adopted from DML (Xi and Pfenning, 1999) for certifying memory safety.

What is in this talk?

This talk is focused on low-level data representation

In particular, we show how dependent datatypes are represented

We also briefly explain how a state type annotation in Xanadu is transformed into a state type in DTAL

Low-Level Types

= int | float | | top (s) | …n|d; |i; 1, …, n| …

1 + … + n = a:natn. a…nwhere natn is {a:int | 0<= a < n}

Sizes of Types

|int| = 1, |float| = 2 |top (s)| = s, || = 1 | (d; )| = 1 |1,…, n | = |1| + … + |n| | (i; 1,…, n) | = max (|1|, …, |n|)

(currently, we require || … |n|)

Tuple Type Representation

1, …, n) is represented flatly as

1 … n

Pointer Type Representation

(d; ) is represented as

d

An Example of Boxing

The high-level type Int * float may be translated into the low-level type:

,int, float

Tag Functions

A tag function for (1,…, n) has the following type

a:natn. (a; 1,…, n) int(a)

An Example of Tag Function

Let 1 = (1, (int(0), int)) 2 = (1, (int(1), float))

Then the following is a tag function for (1, 2): tag (x) = { var y; load y, x(-1); ret y; }

An Example of Tagging (I)

The high-level type int + float may be translated into the low-level type:

a:nat2. (a; 1, 2)

where int(0), int int(1), float

An Example of Tagging (II)

int(0) / int(1) Int / float

a:nat2. (a; (1,T(int(0), int)), (1,T(int(1), float)))

An Interesting Question

Would it be still useful to form i… neven if we could not find a tag function for…n)

Another Example of Tagging

The high-level type Int + float may also be translated into the low-level type:

a:nat2. int(a) (a; 1, )

where 1 = int and 2 = (0, float)

Recursive Sum Types (I)

()list = unit + ()list list

a:nat2.a; intintlist

list may be translated intolist

Recursive Sum Types (II)

()list = unit + ()list null = top/* null pointer */ list

a:nat2.a; nulllist

list may be translated intolist

Dependent Datatypes (I)

union <‘a> list with nat = { Nil (0); Cons (n+1) of ‘a * <‘a> list(n)}

Nil: <‘a> list(0) Cons:

{n:nat} ‘a * <‘a> list(n) <‘a> list(n+1)

Dependent Datatypes (II)

list = forall nnat. unit listawhere is n andis a:natn a

Dependent Datatypes (III)

list = forall nnat. intintlistawhere is n andis a:natn a

A Code Fragment in Xanadu

We now explain how the following code fragment is compiled

invariant: [i:nat,j:nat | i+j=n] (xs:<‘a> list(i), x:int(j)) while (true) { switch (xs) { case Nil: return x; case Cons (_, xs): x = x+1; } }

A Code Fragment in DTAL

loop: (‘a,’r){i:nat,j:nat | i + j = n} [r1:<’a>list(i), r2:int(j), sp: [sp: int(n) :: ‘r] :: ‘r]

unfold r1 /* for type-checking purpose */

load r3, r1(-1)

beq r3, finish

load r1, r1(1)

add r2, r2, 1

jmp loop

Some Questions

Would it be beneficial to introduce a low-level language with some structures instead of handling native code directly?

In particular, would it be beneficial to introduce the notion of macros? How?

Conclusion

Translating (dependent) types from source level to target level presents an effective approach to establishing properties on low-level code, which would often be difficult to prove from scratch

This practice can also be of great help for debugging a compiler