1 / 28

Compiling with Dependent Types

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

Download Presentation

Compiling with Dependent Types

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  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 <‘a> list with nat = { Nil (0); Cons (n+1) of ‘a * <‘a> list(n)}

  6. 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 */}

  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 • t = int | float | a | top (s)|T (t1, …, tn) | & (d; t)| d (i; t1, …, tn)| … • t1 + … + tn = Sa:natn. d (a; t1, …, tn)where natn is {a:int | 0<= a < n}

  10. Sizes of Types • |int| = 1, |float| = 2 • |top (s)| = s, |a| = 1 • |& (d; t)| = 1 • |T (t1,…, tn) | = |t1| + … + |tn| • |d (i; t1,…, tn) | = max (|t1|, …, |tn|)(currently, we require |t1| = … = |tn|)

  11. Tuple Type Representation • T(t1, …, tn) is represented flatly as t1 … tn

  12. Pointer Type Representation • &(d; t) is represented as t d

  13. An Example of Boxing • The high-level type Int * float may be translated into the low-level type: &(0,T(int, & (0, float)))

  14. Tag Functions • A tag function for (t1,…, tn) has the following typePa:natn. d (a; t1,…, tn) -> int(a)

  15. An Example of Tag Function • Let t1 = & (1, T (int(0), int))t2 = & (1, T (int(1), float)) • Then the following is a tag function for (t1, t2): 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:Sa:nat2. d(a; t1, t2)wheret1 = & (1, T (int(0), int))t2 = & (1, T (int(1), float))

  17. An Example of Tagging (II) Sa:nat2. d(a; &(1,T(int(0), int)),&(1,T(int(1), float))) int(0) / int(1) Int / float

  18. An Interesting Question • Would it be still useful to formd(i; t1, …,tn)even if we could not find a tag function for (t1,…,tn) ?

  19. Another Example of Tagging • The high-level type Int + float may also be translated into the low-level type:Sa:nat2. int(a) *d(a; t1, t2)where t1= int and t2 = & (0, float)

  20. Recursive Sum Types (I) • (a)list = unit + a * (a)list • (a)list = Sa:nat2. d (a; &(1; int(0)), &(1; T(int(1), a, (a)list))) • (a)list may be translated into (a)list

  21. Recursive Sum Types (II) • (a)list = unit + a * (a)list • null = &(0; top(0)) /* null pointer */ • (a)list = Sa:nat2.d (a; null, &(0; T(a, (a)list ))) • (a)list may be translated into (a)list

  22. 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)

  23. Dependent Datatypes (II) • list =foralla.P n:nat.Sf1. unit + Sf2. a * (a)list(a)wheref1 isn = 0 and f2is a:nat, n = a+1

  24. Dependent Datatypes (III) • list=foralla.P n:nat.Sf1. & (1, int(0)) + Sf2. & (1, T(int(1), a, (a)list(a))) wheref1 isn = 0 and f2is a:nat, n = a+1

  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:<‘a> 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:<’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

  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

More Related