1 cps transform for dependent ml hongwei xi university of cincinnati and carsten schürmann yale...

30
1 CPS Transform for Dependent ML Hongwei Xi University of Cincinnati and Carsten Schürmann Yale University

Post on 19-Dec-2015

216 views

Category:

Documents


0 download

TRANSCRIPT

1

CPS Transform forDependent ML

Hongwei XiUniversity of Cincinnati

and

Carsten SchürmannYale University

2

Overview

Motivation Program error detection at compile-time Compilation certification

Dependent ML (DML) Programming Examples Theoretical Foundation

CPS Transform for DMLConclusion

3

Program Error Detection

Unfortunately one often pays a price for [languages which impose no disciplines of types] in the time taken to find rather inscrutable bugs — anyone who mistakenly applies CDR to an atom in LISP and finds himself absurdly adding a property list to an integer, will know the symptoms. -- Robin Milner A Theory of Type Polymorphism in Programming

Therefore, a stronger type discipline allows for capturing more program errors at compile-time.

4

Some Advantages of Types

Detecting program errors at compile-timeEnabling compiler optimizationsFacilitating 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 fully trusted

5

Compiler Correctness

How can we prove the correctness of a (realistic) compiler?

Verifying that the semantics of e is the same as the semantics of |e| for every program e

But this simply seems too challenging (and is unlikely to be feasible)

Source program

e

Target code

|e|

compilation

| . |

6

Compilation Certification

Assume that eholds, i.e., e has the property e.g., memory safety, termination, etc.Then eshould hold, tooA compiler can be designed to produce a certificate to assert that edoes have the property

Target code

e: e holds

Source program

e: e holds

compilation

| . |

7

Semantics-preserving Compilation

e -------------> |e| D of ev --> |D| of |e||v|

This seems unlikely to be feasible in practice

8

Type-preserving Compilation

e --------------> |e| e: -----------> |e|:||

D of e: ----> |D| of |e|:||

D and |D| are both represented in LF The LF type-checker does all type-checking!

9

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

guarantee safe array access

10

Narrowing the Gap

NuPrl Coq

Program Extraction Proof Synthesis

ML

Dependent ML

11

Some Design Decisions

Practical type-checkingRealistic programming featuresConservative extensionPay-only-if-you-use policy

12

Ackermann Function in DML

fun ack (m, n) =if m = 0 then n+1else if n = 0 then ack (m-1, 1) else ack (m-1, ack (m, n-1))

withtype{a:nat,b:nat} int(a) * int(b) -> nat

(* Note: nat = [a:int | a >=0] int(a) *)

13

Binary Search in DML

fun bs (vec, key) =let fun loop (l, u) = if l > u then –1 else let val m = (l + u) / 2 val x = sub (vec, m) (* m needs to be within bounds *) in if x = key then m else if x < key then loop (m+1, u) else loop (l, m-1) end in loop (0, length (vec) – 1) end

(* length: {n:nat} ‘a array(n) -> int(n) *)(* sub: {n:nat,i:nat | i < n} ‘a array(n) * int(i) -> ‘a *)

withtype {i:int,j:int | 0 <= i <= j+1 <= n} int(i) * int(j) -> int

withtype {n:nat} ‘a array(n) * ‘a -> int

14

ML0: start point

base types ::= int | bool | (user defined datatypes)

types ::= | |

patterns p ::= x | c(p) | <> | <p1, p2>match clauses ms ::= (p e) | (p e | ms)expressions

e ::= x | f | c | if (e, e1, e2) | <> | <e1, e2> | lam x:. e | fix f:. e | e1(e2) | let x=e1 in e2 end | case e of ms

values v ::= x | c | <v1, v2> | lam x:. econtext ::= . | , x: | , f:

15

Integer Constraint Domain

We use a for index variablesindex expressions

i, j ::= a | c | i + j | i – j | i * j | i / j | …index propositions

P, Q ::= i < j | i <= j | i > j | i >= j | i = j | i <> j | P Q | P Q

index sorts ::= int | {a : | P }index variable contexts ::= . | , a: | , Pindex constraints ::= P | P | a:

16

Dependent Types

dependent types ::= ... | (i) | a: . | a: .

For instance,int(0), bool array(16);

nat = [a:int | a >= 0] int(a); {a:int | a >= 0} int list(a) -> int

list(a)

17

DML0ML0 + dependent types

expressionse ::= ... | a: .v | e[i] | <i e> | open e1 as <a x> in e2 end

values v ::= ... | a: .v | <i v>typing judgment e

18

Some Typing Rules

aetype-ilamaea

aeaitype-iappeiai

19

Some Typing Rules (cont’d)

eaiitype-pack<i e>a

e1aaxe2

type-openopen e1 as <a x> in e2 end:

20

Some Typing Rules (cont’d)

ebool(i)ie1: ie2: type-ifif (e, e1, e2):

21

Erasure: from DML0 to ML0

The erasure function erases all syntax related to type index

| bool(1) | = |bool(0)| = bool | [a:int | a >= 0] int(a) | = int | {n:nat} ‘a list(n) -> ‘a list(n) | =

‘a list -> ‘a list | open e1 as <a x> in e2 end | =

let x = |e1| in |e2| end

22

Relating DML0 to ML0

answer:type in DML0

program:type in DML0

|program|:|type| in ML0 |answer|:|type| in ML0

evaluation

evaluation

erasure erasure

Type preservation holds in DML0

A program is already typable in ML0 if it is typable in DML0

23

Polymorphism

Polymorphism is largely orthogonal to dependent typesWe have adopted a two phase type-checking algorithm

24

References and Exceptions

A straightforward combination of effects with dependent types leads to unsoundnessWe have adopted a form of value restriction to restore the soundness

25

Quicksort in DML

fun qs [] = []| qs (x :: xs) = par (x, xs, [], [])

withtype {n:nat} int list(n) -> int list(n)and par (x, [], l, g) = qs (l) @ (x :: qs (g))

| par (x, y :: ys, l, g) = if y <= x then par (x, ys, y :: l, g) else par (x, ys, l, y :: g)

withtype{p:nat,q:nat,r:nat}int * int list(p) * int list(q) * int list(r) ->int list(p+q+r+1)

26

CPS transformation for DML (I)

Transformation on types:

|| (i) ||* = (i)

|| 1 -> 2 || = || 1||* -> || 2 ||

|| a:. ||* = a:. ||||*

|| a:. ||* = a:. ||||*

|||| = ||||* -> ans -> ans

(* ans is some newly introduced type *)

27

CPS Transformation for DML (II)

Transformation on expressions:

||c||* = c ||x||* = x

||e x.e||* = e x. ||e||

||v|| = e k. k(||v||*)

||e1(e2)|| = e k.||e1||(e x1.||e2||(e x2 . x1 (x2)(k))

||e[i]|| = e k.||e||(e x . x[i](k))

||fix f.v|| = e k.(fix f. ||v||)(k)... ...

28

CPS Transformation for DML

Theorem Assume D :: |- e : Then D can be transformed to ||D|| such that ||D|| :: |||| |- ||e|| : ||||where||||(x) = ||(x)||* and ||||(f) = ||(f)|| for all x,f in the domain of

This theorem can be readily encoded into LF

We have done this in Twelf.

29

Contributions

A CPS transform for DML The transform can be lifted to the

level of typing derivation

The notion of typing derivation compilation A novel approach to compilation

certification in the presence of dependent types

30

End of the Talk

Thank You! Questions?