certified correctness for higher-order programs

Post on 03-Jan-2016

26 Views

Category:

Documents

0 Downloads

Preview:

Click to see full reader

DESCRIPTION

Certified Correctness for Higher-order Programs. Nikhil Swamy Microsoft Research, Redmond. Many recent successes for semi-automated verifiers. Spec#. Why3. Boogie. VeriFast. V ampire. Simplify. CVC4. But, modern languages are pervasively higher-order!. - PowerPoint PPT Presentation

TRANSCRIPT

Certified Correctness for Higher-order Programs

Nikhil SwamyMicrosoft Research, Redmond

Vampire Simplify CVC4

VeriFastWhy3

Boogie

Spec#

Many recent successes for semi-automated verifiers

JavaScript: Higher-order state everywhere!+ AJAX, Event handlers, jQuery, DOM,… Element.addEventListener(ev, function(node){…}) $('li').each(function(index) { .. })

Delegates, lambdas, LINQ, RX, … delegate B Func<A,B>(A arg) foreach (var i in L) {…}

Lambdas everywhere!

But, modern languages are pervasively higher-order!

Higher-order verifiers ~interactive proof assistants

Agda NuPRL …

Very expressive logics! :-)

Impoverished programming languagesPure total functions only :-(

An ML-like languagewith an SMT-based

dependent type system

Enter F* … http://research.microsoft.com/fstar

Fournet Chen Strub Dagand Schlesinger Weinberger Livshits

Bhargavan Borgstrom Chugh Fredrikson Guha Yang Jeannin Swamy

val f: x:int -> y:int{y = x + 1}let f x = x + 1

val hd: xs:list 'a{xs<>[]} -> 'alet hd = function | x::_ -> x | _ -> raise Not_found

val counter: unit -> Writer x:int{x >= 0}let counter = let c = ref 0 in fun () -> c := !c + 1; !c

val compose: (x:'b -> DST 'c (WP_f x)) -> (y:'a -> DST 'b (WF_g y))

-> z:'a -> DST 'c (WP_f . WP_g z)let compose f g x = f (g x)

Term language is core-ML, in a syntax resembling F#/Caml-light

Type language allows expressing precise, functional properties

7

F* source: core-ML with dependent refinement types uses SMT solvers to discharge proof obligations (ESOP ‘10, ICFP’11)

F* source

Z3Type-checker + Compiler

JavaScript

val f: x:int -> y:int{y=x+1}let f x = x + 1

Z3

rDCIL

rDCIL Type-Checker

.NET Virtual Machine

C#, F#,… rDCIL

Interop with C#, VB.NET, F#,…Run on Azure, Windows Phone 7

Preserve types in .NET (PLDI ’10) class C<‘a::int => *>

Coq

Type-checkeritself in F*

Self-certified core type-checker(POPL ’12)

Fully abstract compiler to JS(POPL ’13)

JS verification by translation to F*(PLDI ’13)

Expressions e

Types t

Kinds

0, 1, 2,… true, false, …fun x -> e

Values v

int, bool, … int -> bool…

list int

sz:int -> init:'a -> array sz 'a

array 17 float

0:intfun x->e : int->bool

int:Sint->bool:S

S list:S => S

array:int=>S=>S

S => S

int => S => S

nat = x:int{x >= 0}

sz:nat -> init:'a -> array sz 'a

int => int => E

nat:S

(>=):int => int => E

E

zero = x:int{x = 0}

0:zerofun x->e : int->bool

(=):'a:S => 'a => 'a => E

let x = e in e' match v with D x -> e ref v | v1 := v2 | !v | …

S universeArbitraryEffectful

computation

P universeConstructive

logic core , total functions

E universeAll terms, including ghost terms

A universeAffine types for

controlling effects

The four base-kinds/universes of F*{S, E, A, P}

P <: E S <: E A <: E

Reasoning about effects in

monadic F*

val swap: r1:ref 'a -> r2:ref 'a -> Writer unit (Requires λh. Perm r1 h /\ Perm r2 h) (Ensures λh () h'. Perm r1 h' /\ Perm r2 h' /\ h'[r1]=h[r2]

/\ h'[r2]=h[r1]) (Modifies {r1,r2})let swap r1 r2 = let tmp = !r1 in r1 := !r2; r2 := tmp

Reads and writes the heapPre-condition is a heap predicate (heap => E)

Permission to read and write r1, r2

Post-condition: Relates pre-heap, result and post-heap

heap => 'a => heap => E

h = h' on all ref cells except {r1, r2}, and any newly allocated ref cells

Closures and local state

let evens () = let i = ref 0 in fun () -> i := !i + 1; 2*!i

let evens' () = let i = ref 0 in let j = ref 0 in fun () -> i := !i + 1;

j := !j + 1; !i + !j

Can we give both the same spec, hiding local state from the client?

Idea: pack the closure with invariant on its local state, hiding the representation from the client

type evens_t = | Pkg: 'Inv:heap =>E -> fp:refset -> (unit

-> Writer int(Requires λh. 'Inv (h|fp))(Ensures λh i h'.i%2=0 /\ 'Inv (h'|

fp))(Modifies fp))

-> evens_t

Pkg (Perm i) {i} (fun () -> i:=!i+1; 2*!i) : evens_t

'Inv is a pre- and post-condition of the closure

(h|fp) is the fragment of the heap h whose domain is the set fp of refs

Closure returns an even number

fp={i} footprint of the local state

'Inv instantiated to Perm i

let evens () = let i = ref 0 in Pkg (Perm i) {i} (fun () -> i := !i + 1; 2*!i)

let evens' () = let i = ref 0 in let j = ref 0 in Pkg (λh. Perm i h /\ Perm j h /\ h[i]=h[j]) {i,j} (fun () -> i := !i + 1; j := !j + 1; !i + !j)

Both return evens_t … almost there

The closure owns permission to {i,j};i and j always hold the same value

val evens, evens’: unit -> Writer evens_t (Requires λh.True) (Ensures λh v h'. Pkg.Inv v (h'| Pkg.fp v) /\ Fresh h (Pkg.fp v)) (Modifies {})

Return evens_t

Pkg.Inv: evens_t => heap => E projects the first component of a Pkg value, i.e., the invariant

Pkg.fp: evens_t -> refset projects the second component of a Pkg value, i.e., the footprint

Ensures that the invariant of evens_t holds on the footprint

And that the footprint is fresh

evens_t is a strong sum Can project the existentially bound variables

PLDI ‘13Solutions to VSTTE ‘11 competition with heavy use of local stateVerified library for JavaScript runtime supportJavaScript source code (browser extensions)

To date: nearly 50,000 lines of verified F* code

But, what does it mean to verify a program in F*, formally?

F* in Coq(simplified)

Inductive Tipe :=| Tarrow : name -> Tipe -> Tipe -> Tipe| …with Expr :=| Elam : name -> Tipe -> Expr -> Expr | … .

Inductive Typing : Env -> Config -> Tipe -> Type := | WFVar: g:Env -> x:name -> t:Tipe -> In g (x,t)

–> Typing g (Eval (Var x)) t…

Inductive Steps : Config -> Config :=| …

Deep embedding of syntax of F* in Coq

F* typing relation as an inductive type in Coq

8 mutually recursive judgments, ~65 rules

F* op. semantics

Theorem Preservation: forall G e e’ t, Typing G e t -> Steps e e’ -> Typing G e’ t.

Theorem Progress: forall G e t,Typing G e t

-> Value e \/ (exists e’. Steps e e’)

Metatheory of F* in Coq(simplified)

Well-typed F* programs do not contain failing assertions

Theorem (Correspondence of the P universe): Terms in F*’s logical core of constructive proofs can be embedded in Coq, and the embedding is a forward simulation

More Metatheory of F*(proved manually)

Corollary: F*’s logical core of constructive proofs is strongly normalizing

P universe S universe

E universe

A universe

But, what about the type checker implementation?

Z3

Src.fst

F* checker programmed

in F# F* checker in F*

Coq

Bootstrap certification

Theorem? If src.fst type checks then it does not go wrong.

Self-Certification

Z3

Src.fst

F* typechecker

Theorem: If src.fst typechecks then it does not go wrong.

Type-checker in F*

Theorem Preservation: …Theorem Progress: …

Metatheory.v (Coq)

CoqF*

Definitions.v (Coq)Inductive Tipe := .. Inductive Typing := … …

Correspondence

theorem

Definitions.fst (F*)type Tipe = .. type Typing = … …

check_expr: G:Env -> e:Expr ->

t:Tipe-> Partial (Typing G e

t)check_expr’s result (if any) is a valid typing derivation

Kernel type checker: 5,200 lines of F* code organized into 11 modules

Correspondence

theorem

Theorem Preservation: …Theorem Progress: …

Metatheory.v (Coq)

CoqF*

Definitions.v (Coq)Inductive Tipe := .. Inductive Typing := … …

Definitions.fst (F*)type Tipe = .. type Typing = … …

check_expr: G:Env -> e:Expr ->

t:Tipe-> Partial (Typing G e

t)check_expr’s result (if any) is a valid typing derivation

Pretty print

as Coq term

Typing derivation for

check_expr

Typing derivation for

check_expr

Theorem: forall G e t v, Steps (check_expr (embed G) (embed e)

(embed t)) (Evalue v) -> Typing G e t

7.3GB Coq termTook 24 machine-days to check

What next?

• More bootstrapping– Always elaborating into core F* is expensive– Certify higher-level checkers once and for al

• Meta F* in F*– Prove syntactic soundness of F* in F*– (See tutorial on STLC for flavor)

What next?

• JavaScript, TypeScript, and friends– Verification of JS/TS source– Fully abstract embedding of Safe TS in JS

• Relational F*– A logic for hyperproperties encoded in F*

• …

http://research.microsoft.com/fstar/

Try it out … happy to help you get started!

CERTIFI

ED

top related