Upload
zahir-ellis
View
22
Download
0
Embed Size (px)
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
Citation preview
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
http://rise4fun.com/FStar/tutorial/guide
http://rise4fun.com/FStar/plplY
http://rise4fun.com/FStar/FCE
http://rise4fun.com/FStar/8Ky
http://rise4fun.com/FStar/tutorial/jsStar
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