22
Dependent Types in Practical Programming Hongwei Xi Oregon Graduate Institute

Dependent Types in Practical Programming Hongwei Xi Oregon Graduate Institute

Embed Size (px)

Citation preview

Page 1: Dependent Types in Practical Programming Hongwei Xi Oregon Graduate Institute

Dependent Types in Practical Programming

Hongwei Xi

Oregon Graduate Institute

Page 2: Dependent Types in Practical Programming Hongwei Xi Oregon Graduate Institute

Motivation: Narrowing the Huge Gap

NuPrl Coq

Program Extraction Proof synthesis

ML withDependent Types

ML

Page 3: Dependent Types in Practical Programming Hongwei Xi Oregon Graduate Institute

Some Key Issues in Language Design

• Program error detection• Program verification• Large scale programming• Program documentation• Efficient implementation

Page 4: Dependent Types in Practical Programming Hongwei Xi Oregon Graduate Institute

Some key features in SML

• Rich programming constructs• Imperative features• Advanced type system• Sophisticated module system

Page 5: Dependent Types in Practical Programming Hongwei Xi Oregon Graduate Institute

zip: dynamic safety

datatype ‘a list = nil | :: ‘a * ‘a list

exception UnequalLengths

fun(‘a, ‘b)

zip(nil, nil) = nil

| zip(x :: xs, y :: ys) = (x, y) :: zip(xs, ys)

| zip(x :: xs, nil) = raise UnequalLengths

| zip(nil, y :: ys) = raise UnequalLengths

Page 6: Dependent Types in Practical Programming Hongwei Xi Oregon Graduate Institute

An Example of Dependent Types

• We refine the datatype ‘a list:typeref ‘a list of nat

with nil <| ‘a list(0)

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

• Some explanation– nil is a list of length 0– :: yields a list of length n+1 when given an

element of type ‘a and a list of length n

Page 7: Dependent Types in Practical Programming Hongwei Xi Oregon Graduate Institute

zip: static safety

fun(‘a, ‘b)

zip(nil, nil) = nil

| zip(x :: xs, y :: ys) = (x, y) :: zip(xs,ys)

(*

| zip(x :: xs, nil) = raise UnequalLengths

| zip(nil, y :: ys) = raise UnequalLengths

*)

where zip <| {n:nat} ‘a list(n) * ‘b list(n) ->

‘a * ‘b list(n)

Page 8: Dependent Types in Practical Programming Hongwei Xi Oregon Graduate Institute

zip: An Elaborated Version

fun(‘a, ‘b)

zip[0](nil, nil) = nil

| zip[n+1](x :: xs, y :: ys) =(x, y) :: zip[n](xs,ys)

where zip <| {n:nat} ‘a list(n) * ‘b list(n) ->

‘a * ‘b list(n)

Page 9: Dependent Types in Practical Programming Hongwei Xi Oregon Graduate Institute

Array bounds Checking

Array bounds checking refers to determining whetherthe value of an expression is within the bounds of an array when it is used to index the array.• Pascal, Ada, Modula-3, SML, Java are among the

programming languages which require that all bounds violations be captured.

• C and C++ are not.However, array bounds checking can be expensive.• FoxNet (SML): up to 30% loss of throughput• SPIN kernel (Modula-3): significant performance

loss

Page 10: Dependent Types in Practical Programming Hongwei Xi Oregon Graduate Institute

Array Bounds Check Elimination

• Some previous approaches:– Synthesizing loop invariants (Suzuki & Ishihata):

too expensive in practice to be applicable– Flow analysis (Gupta; Kolte & Wolfe): totally

automatic but sensitive to program structures and not thorough

• A recent approach:– Safe C compiler (Necula and Lee): relatively

simple language constructs

A serious drawback: no or little feedback

Page 11: Dependent Types in Practical Programming Hongwei Xi Oregon Graduate Institute

Some Built-in Dependent Types

• int(i) stands for the singleton type which contains only integer i.

• bool(b)stands for the singleton type which contains only boolean b.

• ‘a array(n) stands for the type of arrays of size n whose elements are of type ‘a.

Page 12: Dependent Types in Practical Programming Hongwei Xi Oregon Graduate Institute

Dependent Types of Some Built-in Functions

assert sub <| {size:nat}{index:nat | index < size}

‘a array(size) * int(index) -> ‘a

• This implies that sub can only be applied to an array of size size and an integer of value index such that 0 <= index < size holds.

• Other array operations such as update can be typed similarly.

Page 13: Dependent Types in Practical Programming Hongwei Xi Oregon Graduate Institute

Dot Product: A version in DML

fun{n:nat}

dotprod v1 v2 =

let

fun loop(i, n, result) =

if i = n then result

else loop(i+1, n, result+sub(v1,i)*sub(v2,i))

where loop <| {i:nat | i<=n} int(i) * int(n) -> int

in loop (0, length v1, 0) end

where dotprod <| int array(n) -> int array(n) -> int

Page 14: Dependent Types in Practical Programming Hongwei Xi Oregon Graduate Institute

Dot Product: A Version in de Caml

let dotprod v1 v2 = begin

let result = ref 0 in

for i = 0 to vect_length v1 - 1 do

result := result + v1..(i) * v2..(i)

done;

!result

end withtype {n:nat} int vect(n) -> int vect(n) -> int

;;

(* for example:

dotprod [|1;2;3|] [|1;2;3|] = 1*1 + 2*2 + 3*3 = 14 *)

Page 15: Dependent Types in Practical Programming Hongwei Xi Oregon Graduate Institute

Dependently Typed Assembly Language

• We aim for passing dependent types from source level to assembly level.

• This is inspired and/or supported by– TIL compiler (Fox project at CMU)– RML compiler (Tolmach and Oliva)– Proof-carrying code (Necula and Lee)– Typed Assembly Language (Morrisett et

al)

Page 16: Dependent Types in Practical Programming Hongwei Xi Oregon Graduate Institute

Some Advantages of DTAL

• Providing invaluable support for compiler writers (Tolmach and Oliva; Morrisett et al)

• Producing memory safety proofs for proof-carrying code

• An alternative to proof-carrying code• Aggressive compiler optimization

Page 17: Dependent Types in Practical Programming Hongwei Xi Oregon Graduate Institute

bcopy: A Version in de Caml

let bcopy (src, dst) =

let length = vect_length src in

for n = 0 to length - 1 do

dst..(n) <- src..(n)

done

withtype {i:nat}{j:nat | i <= j}

‘a vect(i) * ‘a vect(j) -> unit

;;

Page 18: Dependent Types in Practical Programming Hongwei Xi Oregon Graduate Institute

bcopy: A Version in DTALbcopy: {i:nat}{j:nat | i<=j}

[r1: int(i), r2: int array(i), r3: int array(j)]

mov r4, 0 // set the count to be 0

jmp loop // start the loop

loop: {i:nat}{j:nat | i<=j}{k:nat}

[r1: int(i), r2: int array(i),

r3: int array(j), r4: int(k)]

sub r5, r4, r1

beq r5, finish // r4 = r1 and done

load r5, r2(r4) // r5 <- r2(r4)

store r3(r4), r5 // r3(r4) <- r5

add r4, r4, 1 // r4 <- r4 + 1

jmp loop // loop again

finish:[]

halt

Page 19: Dependent Types in Practical Programming Hongwei Xi Oregon Graduate Institute

Proof Generation forProof-Carrying Code

Code

Proof

Poof-CarryingCode

Unpacking

Verifying

Executing

Memory SafetyTermination

Page 20: Dependent Types in Practical Programming Hongwei Xi Oregon Graduate Institute

A Similar Scenario

NuPrl proof Proof verificationProgram extraction

Code-carrying proof?

Page 21: Dependent Types in Practical Programming Hongwei Xi Oregon Graduate Institute

Significant Features of DML

• Exhibiting convincing signs of a practical programming language– Theoretical fundation– Prototype implementation and evaluation

• Enhancing both code safety and code efficiency

• Generating DTAL (ongoing research)

Page 22: Dependent Types in Practical Programming Hongwei Xi Oregon Graduate Institute

Current Status and Future Direction

• We have finished the following.– Theoretical development of DML– A prototype implementation of DML– A prototype implementation of DTAL

• We are working on the following.– Writing a DML front-end for Caml-light (de Caml)– Designing a dependently typed assembly

language

• We intend to do the following.– Dependent types for (a subset of) Java!