Download presentation
Presentation is loading. Please wait.
1
Compiling with Dependent Types Hongwei Xi University of Cincinnati
2
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
3
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
4
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; }
5
A Datatype in Xanadu A polymorphic datatype for lists: union list with nat = { Nil (0); Cons (n+1) of ‘a * list(n) }
6
Another Program in Xanadu (‘a){n:nat} int(n) length (xs: list(n)) { var: int x;; invariant: [i:nat,j:nat | i+j=n] (xs: list(i), x:int(j)) while (true) { switch (xs) { case Nil: return x; case Cons (_, xs): x = x+1; } } exit; /* can never be reached */ }
7
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.
8
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
9
Low-Level Types = int | float | | top (s) | … n | d; | i; 1, …, n | … 1 + … + n = a:nat n. a … n where nat n is {a:int | 0<= a < n}
10
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 |)
11
Tuple Type Representation 1, …, n ) is represented flatly as 11 … nn
12
Pointer Type Representation (d; ) is represented as d
13
An Example of Boxing The high-level type Int * float may be translated into the low-level type: , int, float
14
Tag Functions A tag function for ( 1,…, n ) has the following type a:nat n. (a; 1,…, n ) int(a)
15
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; }
16
An Example of Tagging (I) The high-level type int + float may be translated into the low-level type: a:nat 2. (a; 1, 2 ) where int(0), int int(1), float
17
An Example of Tagging (II) int(0) / int(1)Int / float a:nat 2. (a; (1,T(int(0), int)), (1,T(int(1), float)))
18
An Interesting Question Would it be still useful to form i … n even if we could not find a tag function for … n)
19
Another Example of Tagging The high-level type Int + float may also be translated into the low-level type: a:nat 2. int(a) (a; 1, ) where 1 = int and 2 = (0, float)
20
Recursive Sum Types (I) ( )list = unit + ( )list list a:nat 2. a; int int list list may be translated into list
21
Recursive Sum Types (II) ( )list = unit + ( )list null = top /* null pointer */ list a:nat 2. a; null list list may be translated into list
22
Dependent Datatypes (I) union list with nat = { Nil (0); Cons (n+1) of ‘a * list(n) } Nil: list(0) Cons: {n:nat} ‘a * list(n) list(n+1)
23
Dependent Datatypes (II) list = forall n nat. unit list a where is n and is a:nat n a
24
Dependent Datatypes (III) list = forall n nat. int int list a where is n and is a:nat n a
25
A Code Fragment in Xanadu We now explain how the following code fragment is compiled invariant: [i:nat,j:nat | i+j=n] (xs: list(i), x:int(j)) while (true) { switch (xs) { case Nil: return x; case Cons (_, xs): x = x+1; } }
26
A Code Fragment in DTAL loop: (‘a,’r){i:nat,j:nat | i + j = n} [r1: 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
27
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?
28
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
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.