the marriage of dependent types and effects

52
The Marriage of Dependent Types and Effects Greg Morrisett Joint with A.Nanevski (MSR), L.Birkedal (ITU), R.Peterson (ITU), P.Govereau, R.Wisnesky QuickTime™ and a TIFF (Uncompressed) decompressor are needed to see this picture.

Upload: dooley

Post on 31-Jan-2016

39 views

Category:

Documents


0 download

DESCRIPTION

The Marriage of Dependent Types and Effects. Greg Morrisett Joint with A.Nanevski (MSR), L.Birkedal (ITU), R.Peterson (ITU), P.Govereau, R.Wisnesky. The Marriage of Dependent Types and Effects. Greg Morris s ett e - PowerPoint PPT Presentation

TRANSCRIPT

Page 1: The Marriage of Dependent Types and Effects

The Marriage of Dependent Types and

EffectsGreg Morrisett

Joint with A.Nanevski (MSR), L.Birkedal (ITU), R.Peterson (ITU), P.Govereau, R.Wisnesky

QuickTime™ and aTIFF (Uncompressed) decompressor

are needed to see this picture.

QuickTime™ and aTIFF (Uncompressed) decompressor

are needed to see this picture.

Page 2: The Marriage of Dependent Types and Effects

The Marriage of Dependent Types and

Effects

QuickTime™ and aTIFF (Uncompressed) decompressor

are needed to see this picture.

QuickTime™ and aTIFF (Uncompressed) decompressor

are needed to see this picture.

Greg Morrissette

Joint with A.Nanevski (MSR), L.Birkedal (ITU), R.Peterson (ITU), P.Govereau, R.Wisnesky

Page 3: The Marriage of Dependent Types and Effects

27 June 2007 3

From SML to ZML?A discussion at the last ML workshop:

Things people generally agreed upon:– better support for refinement (and thus dependent) types– better treatment of effects– better support for concurrency

Code name: YMLThis talk : Y0 (a.k.a. Y-naught, Y-not, Y-knot, …)

Next year : Y-succ

Page 4: The Marriage of Dependent Types and Effects

27 June 2007 4

Arrays/Vectors

An embarrassment to ML:

sub : array int

So a buffer can cause your server to crash with an uncaught exception.– either refine domain of sub,– or at least reflect when it throws

Page 5: The Marriage of Dependent Types and Effects

27 June 2007 5

What we desire:sub : x:array , {i:int | 0 <= i < size x}

csub : x:array ,i:int, throws IndexOutOfBounds

when i < 0 or i > size x

But this raises a lot of subtle questions:• how to introduce and eliminate refinements?• what is the language of refinements?• how to rectify effects with dependency?• …

Page 6: The Marriage of Dependent Types and Effects

27 June 2007 6

What does this mean?sub : x:array , {i:int | 0 <= i < size x} ->

let x : array int = #[0,1,2,3 ] i : ref int = ref 3in sub x (i := rand() mod 3; fork g; !i)end

Page 7: The Marriage of Dependent Types and Effects

27 June 2007 7

DML [Xi & Pfenning]• Add modeling types at the kind level:

– ::= * | Nat | Bool – ::= 0 | Succ | NatRec | …

• Connect type and term levels with singletons – 0 : S(0), succ : n:Nat, S(n) S(Succ n)

• Limited predicates on modeling types:– sub : n,m:Nat [nm]array n S(m)

• Many follow-ons – ATS, Omega, Concoqtion, …

Page 8: The Marriage of Dependent Types and Effects

27 June 2007 8

DML-style dependency

Pros:– conservative over ML– avoids issues with effects– strong phase separation

Cons:– in practice, lots of duplication

• not just in meta-theory, but in the code.

– can’t say anything about computations– can’t say much about state, IO, exns, …

Page 9: The Marriage of Dependent Types and Effects

27 June 2007 9

An Alternative: Y0

Started with type theory.– we’re doing a shallow embedding in Coq.– (but other environments might do as well)– keys: support for dependency, refinement, etc.– and extraction to ML or Haskell

Add a distinct type of effectful computations.– monadic types as in Haskell: ◊A– but indexed with predicates: ◊{P}A{Q}.– includes recursion, (h.o.) state, exns, …– lots of attention to frame, modularity conditions.

More or less “pay-as-you-go.”

Page 10: The Marriage of Dependent Types and Effects

27 June 2007 10

A Very Simple Example:Definition postinc x := xv <-- !!x ; x ::= (xv + 1) ;; ret xv.

You can extract the corresponding Haskell:postinc x = do {xv <- read x ; write x (xv + 1) ; return xv }

Page 11: The Marriage of Dependent Types and Effects

27 June 2007 11

Expanding the DefinitionDefinition postinc x := xv <-- !!x ; x ::= (xv + 1) ;; ret xv.

Expands into: Definition postinc x := bind (read x) ( xv => bind (write x (xv + 1)) ( _ => ret xv)).

Page 12: The Marriage of Dependent Types and Effects

27 June 2007 12

The ST Monad in Coq

ST(P:pre)(A:Set)(Q:post A) : Set

Read as Hoare-partial correctness:– a computation which– when run in a heap satisfying P,– diverges or else produces a value of type

A and a heap satisfying Q.

Page 13: The Marriage of Dependent Types and Effects

27 June 2007 13

Roadmap

ST(P:pre)(A:Set)(Q:post A) : Set

• Heaps, pre- & post-conditions• Basic monadic & state constructs• Exceptions, conditionals, arrays• Example: hashtable• Recursion and meta-theoretic issues• Modularity & separation• Current & future work

Page 14: The Marriage of Dependent Types and Effects

27 June 2007 14

Heaps, Pre & Post-Conditions

ST(P:pre)(A:Set)(Q:post A) : Set.

pre := heap->Prop

post(A:Set) := A->heap->heap->Prop.

loc : Set.

heap := loc->option Dynamic.

Dynamic := {A:Set ; v:A }.

Page 15: The Marriage of Dependent Types and Effects

27 June 2007 15

Some Primitives & Types:top := fun (h:heap) => True.

(* lift a pure term x into the computation space *)

ret : (x:A),ST top A ( r i f => r=x f=i).

(* allocate a fresh location *)

new : (v:A),ST top loc ( r i f => i r = None f = update r v i).

Note: leaving off implicit parameters.

Page 16: The Marriage of Dependent Types and Effects

27 June 2007 16

More Primitivesptsto(x:loc)(v:A)(h:heap) := h x = Some{A; v}ref(A:Set)(x:loc)(h:heap):= v:A,ptsto x v h.

read : (A:Set)(x:loc), ST (ref A x) A

( r i f => f = i ptsto x r i)

write : (x:loc)(v:A), ST ( i => B, ref B x i) unit ( r i f => f = update x v i)

Page 17: The Marriage of Dependent Types and Effects

27 June 2007 17

Bind(* sequentially compose computations *)

bind:(C1: ST P1 A1 Q1)

(C2: x:A1, ST (P2 x) A2 (Q2 x)),

ST ( i => P1 i

(r h, Q1 r i h -> P2 r h))

A2

( r i f => x h, Q1 x i h Q2 x r h f)

Page 18: The Marriage of Dependent Types and Effects

27 June 2007 18

Back to our Example:

Definition postinc x := bind (read x) ( xv => bind (write x (xv + 1)) ( _ => ret xv)).

Check postinc.

Page 19: The Marriage of Dependent Types and Effects

27 June 2007 19

A Little Hard to Read…postinc : forall x : loc, ST (fun i : heap => (fun i0 : heap => exists v : nat, ptsto x v i0) i /\ (forall (x0 : nat) (m : heap), (fun (y : nat) (i0 m0 : heap) => m0 = i0 /\ ptsto x y i0) x0 i m -> (fun (xv : nat) (i0 : heap) => (fun i1 : heap => exists B : Type, exists w : B, ptsto x w i1) i0 /\ (forall (x1 : unit) (m0 : heap), (fun (_ : unit) (i1 m1 : heap) => m1 = update x (xv + 1) i1) x1 i0 m0 -> (fun (_ : unit) (_ : heap) => True) x1 m0)) x0 m)) (fun (y : nat) (i m : heap) => exists x0 : nat, exists h : heap, (fun (y0 : nat) (i0 m0 : heap) => m0 = i0 /\ ptsto x y0 i0) x0 i h /\ (fun (xv y0 : nat) (i0 m0 : heap) => exists x1 : unit, exists h0 : heap, (fun (_ : unit) (i1 m1 : heap) => m1 = update x (xv + 1) i1) x1 i0 h0 /\ (fun (_ : unit) (r : nat) (i1 f : heap) => r = xv /\ f = i1) x1 y0 h0 m0) x0 y h m)

Page 20: The Marriage of Dependent Types and Effects

27 June 2007 20

Consequence:

(* strengthen pre- and weaken post-condition *)

do : (C : ST P1 A Q1),

(i, P2 i -> P1 i

x f, Q1 x i f -> Q2 x i f) ->

ST P2 A Q2.

Page 21: The Marriage of Dependent Types and Effects

27 June 2007 21

Re-Typing with Do

Definition postinc x : ST (ref nat x) nat ( r i f => v, ptsto x v i ->

r = v f = update x (v+1) i):= do (xv <-- !!x ; x ::= (xv + 1) ;; ret xv) <proof-term>.

Page 22: The Marriage of Dependent Types and Effects

27 June 2007 22

AlternativelyProgram Definition postinc x : ST (ref nat x) nat ( r i f => v, ptsto x v i ->

r = v f = update x (v+1) i):= do (xv <-- !!x ; x ::= (xv + 1) ;; ret xv) _.

<proof-script>

Page 23: The Marriage of Dependent Types and Effects

27 June 2007 23

Or Even:

Program Definition postinc x : ST (ref nat x) nat ( _ _ => ref nat x):= do (xv <-- !!x ; x ::= (xv + 1) ;; ret xv) _.

Page 24: The Marriage of Dependent Types and Effects

27 June 2007 24

Proof Holes• Program lets us leave holes (“_”) for proofs.• After the definition, we enter the proof script

for each hole.– Can register default tactics which take care of

easy proofs, or simplify goals.– In the previous examples, tactics manage to

construct proofs automatically.– In bigger examples, at least simplify VCs to

something that’s manageable.

• Note, no need to specify pre/post-conditions if you don’t care.

Page 25: The Marriage of Dependent Types and Effects

27 June 2007 25

Exceptions

exn : Set.

Inductive ans(A:Set) := | Val : A -> ans A | Exn : exn -> ans A.

ST(P:pre)(A:Set)(Q:post(ans A)) : Set

Page 26: The Marriage of Dependent Types and Effects

27 June 2007 26

Two Ways to Return:

ret : (x:A), ST top A

( a i f => a=(Val x) f=i).

throw : (A:Set)(e:exn), ST top A

( a i f => a=(Exn e) f=i).

Page 27: The Marriage of Dependent Types and Effects

27 June 2007 27

Rebind:bind:(C1: ST P1 A1 Q1)

(C2: x:A1, ST (P2 x) A2 (Q2 x)),

ST ( i => P1 i

(r m, Q1 (Val r) i m -> P2 r m))

A2

( a i f => (x h, Q1 (Val x) i h Q2 x a h f)

(e, a = (Exn e) Q1 a i f)

Page 28: The Marriage of Dependent Types and Effects

27 June 2007 28

Catch is Similar:catch:(C1: ST P1 A Q1)

(C2: e:exn, ST (P2 e) A (Q2 x)),

ST ( i => P1 i

(e m, Q1 (Exn e) i m -> P2 e m))

A

( a i f => (e h, Q1 (Exn e) i h Q2 e a h f)

(x, a = (Val x) Q1 a i f)

Page 29: The Marriage of Dependent Types and Effects

27 June 2007 29

Can code Conditionals:

Program Definition If(test : {R} + {S})

(C1 : R -> ST P1 A Q1)

(C2 : S -> ST P2 A Q2) :

ST (fun i => (R -> P1 i) (S -> P2 i))

A

(fun r i f => (R Q1 r i f) (S Q2 r i f)) :=

match test with

| left pfR => do (C1 pfR) _

| right pfS => do (C2 pfS) _

end.

Page 30: The Marriage of Dependent Types and Effects

27 June 2007 30

Arrays:Treated as an n-vector of (distinct) locations.

vsub : (a:array n)(j:nat)(pf: j<n), loc.

(* subscript on array a at offset j *)

sub : (A:Set)(a:array n)(j:nat)(pf: j<n), ST (ref A (vsub a j pf)) A ( r i f => f = i

ptsto (vsub a j pf) r i)).

Page 31: The Marriage of Dependent Types and Effects

27 June 2007 31

Checked Subscript:

lessthan : (n m:nat), {n<m}+{n>=m}.

Definition csub(A:Set)(a:array n)(j:nat):= If (lessthan j n)

(fun pfj => sub a j pfj)

(fun _ => throw A IndexOutOfBounds).

Page 32: The Marriage of Dependent Types and Effects

27 June 2007 32

A Bigger Example: Hashtables

• Representation: array of list(key*value).– table := {len:nat ; arr:array len}

• Abstraction: (key*value) sets.– kvset : key -> value -> Prop– reps(S:kvset)(t:table)(h:heap): Prop

• Operations to create, insert, and lookup.

Page 33: The Marriage of Dependent Types and Effects

27 June 2007 33

Type of Create:create(n:nat) : ST top table ( y i f => (* old values in memory are preserved *) r A (v:A),ptsto r v i -> ptsto r v f (* array locations are fresh *) j (p:j<len t), unallocated(vsub (arr t) j pj) i (* returns a table that represents {} *) t:table,y=Val t reps empty_set t f).

Page 34: The Marriage of Dependent Types and Effects

27 June 2007 34

Type of Insert:insert : forall (k:key)(v:value)(t:table)(S:kvset), ST (reps S t) ( y i f => (* returns unit *) y=Val tt (* only changes location at (hash k) mod n *) ( r w,(r <> vsub (arr t)((hash k) mod (len t))) -> ptsto r w i -> ptsto r w f) (* array now represents {(k,v)}+S *)

reps (insert_kvset (k,v) S) t f).

Page 35: The Marriage of Dependent Types and Effects

27 June 2007 35

Type of Lookuplookup : (k:key)(t:table)(S:kvset), ST (reps S t) value (y i f => (* memory is unchanged *)

f=i (* throws Lookup when key isn’t in S *) (v,~(S k v) y=Exn Lookup (* or else returns some v s.t. S k v *) v, y=Val v S k v))

Page 36: The Marriage of Dependent Types and Effects

27 June 2007 36

Roadmap

ST(P:pre)(A:Set)(Q:post A) : SetHeaps, pre- & post-conditionsBasic monadic & state constructsExceptions, conditionals, arraysExample: hashtable• Recursion and meta-theoretic issues• Modularity & separation• Current & future work

Page 37: The Marriage of Dependent Types and Effects

27 June 2007 37

Recursion (CBV):

ffix :

(f : (body:x:A, ST(P x)(B x)(Q x))

(x:A), ST (P x)(B x)(Q x)),

(x:A), ST (P x)(B x)(Q x).

Page 38: The Marriage of Dependent Types and Effects

27 June 2007 38

For Example:Fixpoint fact(n:nat) {struct n} : nat := match n with 0 => ret 1 | S m => n * fact(m) end.

Definition spec := n:nat, ST top nat (fun y i f => f=i y=Val(fact n)).

Program Definition fact_body(fact:spec):spec := fun n => do (If (eqnat n 0) (fun _ => ret 1) (fun _ => p <-- fact (n-1) ; ret (n*p))) _.

Definition fact_rec := ffix fact_body.

Page 39: The Marriage of Dependent Types and Effects

27 June 2007 39

Defining ST in Coq?Can try to define:

ST P A Q := {i:heap|P h} -> {f:heap; x:A |Q x i h}

but then you sacrifice:– recursive (diverging) computations– non-deterministic computations– code that stores computations in the heap

So we will do something different.

Page 40: The Marriage of Dependent Types and Effects

27 June 2007 40

Consistency• No equations on computations!

– (except for monad laws)– no way to run them, even in the logic.

• Trivial model: ST = unit.– silly, but ensures we haven’t broken Coq.

• Intermediate model: – ST = predicate transformers (see Sylvain’s talk)– not big enough -- can’t store ST’s in heap!

• Denotational model: – Lars Birkedal & Rasmus Peterson– (subset of Coq corresponding to HTT)

Page 41: The Marriage of Dependent Types and Effects

27 June 2007 41

Operational Soundness• For HTT subset [ESOP’07]:

– give a fairly standard, small-step operational semantics

– assume “heap-consistency” of logic• we get this with the trivial model

– proved preservation & progress• Not an everyday type-soundness

proof.– fact_rec really computes factorial.– hope: scales to things like concurrency…

Page 42: The Marriage of Dependent Types and Effects

27 June 2007 42

Modularity

Thus far, a “big footprint” approach.– specify changes to entire heap.– not modular. – inconvenient specifications.– real nightmare for concurrency.– but meta-theory much simpler.

So we define a separation-based monad in terms of the big footprint ST.– STsep P A Q.– similar to ST, but “tight” footprint.

Page 43: The Marriage of Dependent Types and Effects

27 June 2007 43

STsepDefinition STsep(P:pre)(A:Set)(Q: post A):Set

:= ST (P * top) A (fun x => P -o Q x).

where:top h := True.

(P1*P2) h := h1 h2, h=h1h2 P1 h1 P2 h2.

(this h1) h2 := h1=h2.

(Q - P) i f := i1 f1 h, i=i1h f=f1h Q i1 f1 P h.(P -o Q) i f := h, (P *(this h)) i -> (Q - (this h)) i f.

Intuitively, when run in a heap P*(this h) for some h, yields a heap satisfying Q*(this h).

Page 44: The Marriage of Dependent Types and Effects

27 June 2007 44

Separating Specsemp h := h = empty.(xv) h := h = update x v empty.

definition snew(A:Set)(v:A): STsep emp A ( a i f => a v) := fun A v => do (new v) _.

definition sread(A:Set)(x:loc): STsep ( i => v:A, (x v) i) A ( a i f => (x a) i f=i) := fun A x => do (read x) _.

Page 45: The Marriage of Dependent Types and Effects

27 June 2007 45

Separating BindProgram Definition

sbind (C1 : STsep P1 A1 Q1)

(C2 : x:A1, STsep (P2 x) A2 (Q2 x)) :

STsep (i => (P1 * top) i

x h, (P1 -o Q1 x) i h -> (P2 x * top) h)

A2

(y i f => x h,(P1 -o Q1 x) i h (P2 x -o Q2 x y) h

f)

:= do (bind C1 C2) _.

Page 46: The Marriage of Dependent Types and Effects

27 June 2007 46

Separating DoProgram Definition sdo

sdo(C : STsep P1 A Q1)

(pf : i, P2 i -> h, (P1 * (this h)) i

(y f, (Q1 y) - (this h)) i m -> Q2 y i f)), STSep P2 A Q2

:= do C _.

Page 47: The Marriage of Dependent Types and Effects

27 June 2007 47

AbstractionRecord FinMap(key value:Set)(hash:key->nat):= { t : Set ; reps : set(key*value)->t->heap->Prop ; create : All n:nat, STsep emp t ( r _ => reps empty_set r) ; insert : All k v t S, STsep (reps S t) unit ( _ _ => reps (ins (k,v) S) t) ; ... }

Can build hash table, association list, splay tree, etc. that meets this interface.

Page 48: The Marriage of Dependent Types and Effects

27 June 2007 48

What’s Next?• Examples:

– have simple data structures (e.g., hash tables.)– can abstract over internal invariants.– need larger libraries & apps to drive

development of abstractions & tactics.

• Extraction:– can extract Haskell code now.– but want to build a good ML extractor

• no need to pay the overhead of laziness• can leverage effects in compiler

Page 49: The Marriage of Dependent Types and Effects

27 June 2007 49

Scaling the Language• I/O and Foreign Functions

– obviously needed for practical programming– perhaps a simple treatment of “worlds”– right sort of monad transformers?

• Concurrency– looking at transactions (a la STM) as basis– continue to use STsep for sequential code– simplifies O’Hearn-style separation treatment of

concurrency– but of course, models & soundness tricky

Page 50: The Marriage of Dependent Types and Effects

27 June 2007 50

Concurrency:STsep P A Q -- sequential, undoableCmd I P A Q -- parallel, not undoable

par : Cmd I P1 A1 Q1 ->

Cmd I P2 A2 Q2 ->

Cmd I (P1*P2) (A1*A2) (Q1*Q2)

atomic : STsep (I*P) A (I*Q) -> Cmd I P A Q

Page 51: The Marriage of Dependent Types and Effects

27 June 2007 51

Summary• ST monad in Coq

– state, [de]allocation, strong updates, exceptions, recursion (i.e., core ML++)

– specifications “inferred” for straightline code– various models– operational semantics & soundness argument

• STsep monad:– small footprint treatment of state layered on ST– gives us framing and abstraction

• Working on IO & Concurrency

Page 52: The Marriage of Dependent Types and Effects

27 June 2007 52

Thanks!

• Simona Ronchi Della Rocca• The TLCA PC• Ralf Treinen• Co-authors• and you.