Deductive Program Verification with Why3

Similar documents
Why3 where programs meet provers

An Introduction to Deductive Program Verification

Why3 A Multi-Prover Platform for Program Verification

Deductive Program Verification with Why3, Past and Future

Why. an intermediate language for deductive program verification

Deductive Program Verification with Why3 A Tutorial

Deductive Verification in Frama-C and SPARK2014: Past, Present and Future

Why3 Where Programs Meet Provers

Numerical Computations and Formal Methods

Deductive Program Verification with WHY3

Simple proofs of simple programs in Why3

GNATprove a Spark2014 verifying compiler Florian Schanda, Altran UK

Combining Coq and Gappa for Certifying FP Programs

A Modular Way to Reason About Iteration

The Why/Krakatoa/Caduceus Platform for Deductive Program Verication

Formal Verification of MIX Programs

WP Plug-in (Draft) Manual

Producing All Ideals of a Forest, Formally (Verification Pearl)

Reminder of the last lecture. Aliasing Issues: Call by reference, Pointer programs. Introducing Aliasing Issues. Home Work from previous lecture

How to get an efficient yet verified arbitrary-precision integer library

Lost in translation. Leonardo de Moura Microsoft Research. how easy problems become hard due to bad encodings. Vampire Workshop 2015

Verification Condition Generation

Formal Verification of Floating-Point programs

An Annotated Language

Improving Coq Propositional Reasoning Using a Lazy CNF Conversion

Coq. LASER 2011 Summerschool Elba Island, Italy. Christine Paulin-Mohring

Software Verification of Safety-Critical Aerospace Systems1

Why3: Shepherd Your Herd of Provers

Program Verification (6EC version only)

A Case Study on Model Checking and Deductive Verification Techniques of Safety-Critical Software

Main Goal. Language-independent program verification framework. Derive program properties from operational semantics

Coq, a formal proof development environment combining logic and programming. Hugo Herbelin

Specification, Verification, and Interactive Proof

Lectures 20, 21: Axiomatic Semantics

Formally Certified Satisfiability Solving

BOOGIE. Presentation by Itsik Hefez A MODULAR REUSABLE VERIFIER FOR OBJECT-ORIENTED PROGRAMS MICROSOFT RESEARCH

Satisfiability Modulo Theories. DPLL solves Satisfiability fine on some problems but not others

CSC313 High Integrity Systems/CSCM13 Critical Systems. CSC313/CSCM13 Chapter 2 1/ 221

Let s Verify This with Why3

SMT-LIB for HOL. Daniel Kroening Philipp Rümmer Georg Weissenbacher Oxford University Computing Laboratory. ITP Workshop MSR Cambridge 25 August 2009

Laboratory for Automated Reasoning and Analysis

WP 0.6 (Draft Manual)

WP 0.4 (Draft Manual)

Integration of SMT Solvers with ITPs There and Back Again

A CRASH COURSE IN SEMANTICS

Trends in Automated Verification

Lecture 10 Design by Contract

Chapter 1. Introduction

Built-in Treatment of an Axiomatic Floating-Point Theory for SMT Solvers

WP Plug-in Manual. Version 0.9 for Magnesium Patrick Baudin, François Bobot, Loïc Correnson, Zaynah Dargaye

An Extensible Programming Language for Verified Systems Software. Adam Chlipala MIT CSAIL WG 2.16 meeting, 2012

Generating Small Countermodels. Andrew Reynolds Intel August 30, 2012

A Formally Proved, Complete Algorithm for Path Resolution with Symbolic Links

Semi-Persistent Data Structures

Pointer Programs, Separation Logic

Verifying Two Lines of C with Why3: An Exercise in Program Verification

Jessie Plug-In Tutorial

Isabelle/HOL:Selected Features and Recent Improvements

Deductive Methods, Bounded Model Checking

Practical introduction to Frama-C (without Mathematical notations ;-) )

Programming Languages Third Edition

Automated Theorem Proving and Proof Checking

Strongly Connected Components in graphs, formal proof of Tarjan1972 algorithm

Part II. Hoare Logic and Program Verification. Why specify programs? Specification and Verification. Code Verification. Why verify programs?

6. Hoare Logic and Weakest Preconditions

Hoare Logic. COMP2600 Formal Methods for Software Engineering. Rajeev Goré

Yices 1.0: An Efficient SMT Solver

Combining Coq and Gappa for Certifying Floating-Point Programs

Jessie Plugin Tutorial

The SMT-LIB 2 Standard: Overview and Proposed New Theories

λ calculus is inconsistent

A Decision Procedure for (Co)datatypes in SMT Solvers. Andrew Reynolds Jasmin Christian Blanchette IJCAI sister conference track, July 12, 2016

G Programming Languages Spring 2010 Lecture 4. Robert Grimm, New York University

Abstract Interpretation

Frama-C A Collaborative Framework for C Code Verification

How to Compute the Area of a Triangle: a Formal Revisit

Readable semi-automatic formal proofs of Depth-First Search in graphs using Why3

Combining Coq and Gappa for Certifying Floating-Point Programs

Chapter 13: Reference. Why reference Typing Evaluation Store Typings Safety Notes

From Z3 to Lean, Efficient Verification

G Programming Languages - Fall 2012

Complete Instantiation of Quantified Formulas in Satisfiability Modulo Theories. ACSys Seminar

Adam Chlipala University of California, Berkeley ICFP 2006

VS 3 : SMT Solvers for Program Verification

Type Theory meets Effects. Greg Morrisett

Theorem proving. PVS theorem prover. Hoare style verification PVS. More on embeddings. What if. Abhik Roychoudhury CS 6214

Provably Correct Software

Verification Conditions. Juan Pablo Galeotti, Alessandra Gorla, Andreas Rau Saarland University, Germany

Proving SPARK Verification Conditions with SMT solvers

The Mezzo case. Jonathan Protzenko. François Pottier FSFMA'13. Why design a new programming language?

Compositional Cutpoint Verification

Lecture 4. First order logic is a formal notation for mathematics which involves:

Verification of the Functional Behavior of a Floating-Point Program: an Industrial Case Study

Formal C semantics: CompCert and the C standard

CSCI-GA Scripting Languages

A short manual for the tool Accumulator

The Prototype Verification System PVS

An Industrially Useful Prover

Formal Methods. CITS5501 Software Testing and Quality Assurance

DPLL(Γ+T): a new style of reasoning for program checking

Transcription:

Deductive Program Verification with Why3 Jean-Christophe Filliâtre CNRS Mathematical Structures of Computation Formal Proof, Symbolic Computation and Computer Arithmetic Lyon, February 2014

definition program + specification verification conditions proof

this is not new A. M. Turing. Checking a large routine. 1949. STOP r = 1 u = 1 v = u TEST r n s = 1 u = u + v s = s + 1 r = r + 1 TEST s r

this is not new Tony Hoare. Proof of a program: FIND. Commun. ACM, 1971. k v v v

which programs? which specs? program + specification verification conditions proof programs pseudo code / mainstream languages / DSL small / large specs safety, i.e. the program does not crash absence of arithmetic overflow complex behavioral property, e.g. sorts an array

which logic? program + specification verification conditions proof too rich: we won t be able to automate proofs too poor: we can t model programming languages and we can t specify programs typically, a compromise e.g. first-order logic + equality + arithmetic

what about proofs? program + specification verification conditions proof a gift: theorem provers proof assistants: Coq, PVS, Isabelle, etc. TPTP provers: Vampire, Eprover, SPASS, etc. SMT solvers: CVC3, Z3, Yices, Alt-Ergo, etc. dedicated provers

checking a large routine (Turing, 1949) STOP r = 1 u = 1 v = u TEST r n s = 1 u = u + v s = s + 1 r = r + 1 TEST s r

checking a large routine (Turing, 1949) STOP r = 1 u = 1 v = u TEST r n s = 1 u = u + v s = s + 1 r = r + 1 TEST s r u 1 for r = 0 to n 1 do v u for s = 1 to r do u u + v

checking a large routine (Turing, 1949) STOP r = 1 u = 1 v = u TEST r n s = 1 u = u + v s = s + 1 r = r + 1 TEST s r requires {n 0} u 1 for r = 0 to n 1 do v u for s = 1 to r do u u + v ensures {u = fact(n)}

checking a large routine (Turing, 1949) STOP r = 1 u = 1 v = u TEST r n s = 1 u = u + v s = s + 1 r = r + 1 TEST s r requires {n 0} u 1 for r = 0 to n 1 do v u for s = 1 to r do u u + v ensures {u = fact(n)} invariant {u = fact(r)} invariant {u = s fact(r)}

verification condition function fact(int) : int axiom fact0: fact(0) = 1 axiom factn: n:int. n 1 fact(n) = n * fact(n-1) goal vc: n:int. n 0 (0 > n - 1 1 = fact(n)) (0 n - 1 1 = fact(0) ( u:int. ( r:int. 0 r r n - 1 u = fact(r) (1 > r u = fact(r + 1)) (1 r u = 1 * fact(r) ( u1:int. ( s:int. 1 s s r u1 = s * fact(r) ( u2:int. u2 = u1 + u u2 = (s + 1) * fact(r))) (u1 = (r + 1) * fact(r) u1 = fact(r + 1))))) (u = fact((n - 1) + 1) u = fact(n))))

verification condition function fact(int) : int axiom fact0: fact(0) = 1 goal vc: n:int. n 0 (0 > n - 1 1 = fact(n))

verification condition function fact(int) : int axiom factn: n:int. n 1 fact(n) = n * fact(n-1) goal vc: n:int. n 0 (0 n - 1 ( u:int. ( r:int. 0 r r n - 1 u = fact(r) (1 r ( u1:int. (u1 = (r + 1) * fact(r) u1 = fact(r + 1)))))

the SMT revolution SMT means Satisfiability Modulo Theories an SMT solver combines + SAT + Equality + Arith +... e.g. n 0 0 > n 1 (Arith) n = 0 1 = fact(n) fact(0) = 1 (Ax) (Equality)

extracting verification conditions a well-known technique (weakest preconditions, Dijkstra 1971, Barnett/Leino 2005) yet doing it for a realistic programming language is a lot of work

extracting verification conditions a well-known technique (weakest preconditions, Dijkstra 1971, Barnett/Leino 2005) yet doing it for a realistic programming language is a lot of work as in a compiler, we rather design an intermediate language from which we extract VCs two examples: Boogie (Microsoft Research) Why3 (Univ. Paris Sud / Inria)

Why3 in a nutshell a simple programming language, with polymorphism pattern-matching exceptions mutable data structures, with controlled aliasing a polymorphic first-order logic, with algebraic data types recursive definitions inductive and coinductive predicates file.why file.mlw WhyML VCgen Why transform/translate print/run http://why3.lri.fr/ Coq Alt-Ergo CVC3 Z3 etc.

1. a taste of program verification

election given a multiset of N votes A A A C C B B C C C B C C determine the majority, if any

an elegant solution due to Boyer & Moore (1980) linear time constant extra space

principle A A A C C B B C C C B C C cand = A k = 1

principle A A A C C B B C C C B C C cand = A k = 2

principle A A A C C B B C C C B C C cand = A k = 3

principle A A A C C B B C C C B C C cand = A k = 2

principle A A A C C B B C C C B C C cand = A k = 1

principle A A A C C B B C C C B C C cand = A k = 0

principle A A A C C B B C C C B C C cand = B k = 1

principle A A A C C B B C C C B C C cand = B k = 0

principle A A A C C B B C C C B C C cand = C k = 1

principle A A A C C B B C C C B C C cand = C k = 2

principle A A A C C B B C C C B C C cand = C k = 1

principle A A A C C B B C C C B C C cand = C k = 2

principle A A A C C B B C C C B C C cand = C k = 3

principle A A A C C B B C C C B C C cand = C k = 3 then we check if C indeed has majority, with a second pass (in that case, it has: 7 > 13/2)

Fortran code

let mjrty (a: array candidate) : candidate = let n = length a in let cand = ref a[0] in let k = ref 0 in for i = 0 to n-1 do if!k = 0 then begin cand := a[i]; k := 1 end else if!cand = a[i] then incr k else decr k done; if!k = 0 then raise Not found; try if 2 *!k > n then raise Found; k := 0; for i = 0 to n-1 do if a[i] =!cand then begin incr k; if 2 *!k > n then raise Found end done; raise Not found with Found!cand end Why3 code

demo

specification precondition let mjrty (a: array candidate) requires { 1 length a } postcondition in case of success ensures { 2 * numof a result 0 (length a) > length a } postcondition in case of failure raises { Not found c: candidate. 2 * numof a c 0 (length a) length a }

loop invariants first loop for i = 0 to n-1 do invariant { 0!k numof a!cand 0 i } invariant { 2 * (numof a!cand 0 i -!k) i -!k } invariant { c: candidate. c!cand 2 * numof a c 0 i i -!k }... second loop for i = 0 to n-1 do invariant {!k = numof a!cand 0 i } invariant { 2 *!k n }...

proof the verification condition expresses safety array access within bounds termination validity of annotations invariants are initialized and preserved postconditions are established automatically discharged by SMT solvers

2. one logic to use them all

using theorem provers there are many theorem provers SMT solvers: Alt-Ergo, Z3, CVC3, Yices, etc. TPTP provers: Vampire, Eprover, SPASS, etc. proof assistants: Coq, PVS, Isabelle, etc. dedicated provers, e.g. Gappa (Guillaume s talk on Thursday) we want to use all of them if possible we make a compromise

in a nutshell logic of Why3 = polymorphic first-order logic, with (mutually) recursive algebraic data types (mutually) recursive function/predicate symbols (mutually) inductive predicates let-in, match-with, if-then-else more details: Expressing Polymorphic Types in a Many-Sorted Language (FroCos 2011) One Logic To Use Them All (CADE 2013)

declarations types abstract: type t alias: type t = list int algebraic: type list α = Nil Cons α (list α) function / predicate uninterpreted: function f int : int defined: predicate non empty (l: list α) = l Nil inductive predicate inductive trans t t =... axiom / lemma / goal goal G: x: int. x 0 x*x 0

theories logic declarations organized in theories theory end theories can be reused e.g. the theory of integers theory end generic theories can be instantiated e.g. notion of path theory end

under the hood a technology to talk to provers central concept: task a context (a list of declarations) a goal (a formula) goal

workflow theory end Alt-Ergo theory end Z3 theory Vampire end

workflow theory end Alt-Ergo theory end goal Z3 theory Vampire end

workflow theory end Alt-Ergo theory end goal T 1 goal Z3 theory Vampire end

workflow theory end Alt-Ergo theory end T 1 T 2 goal goal goal Z3 theory Vampire end

workflow theory end Alt-Ergo theory end T 1 T 2 P goal goal goal Z3 theory Vampire end

transformations eliminate algebraic data types and match-with eliminate inductive predicates eliminate if-then-else, let-in encode polymorphism, encode types etc. efficient: results of transformations are memoized

driver a task journey is driven by a file transformations to apply prover s input format syntax predefined symbols / axioms prover s diagnostic messages more details: Why3: Shepherd your herd of provers (Boogie 2011)

example: Z3 driver (excerpt) printer "smtv2" valid "^unsat" invalid "^sat" transformation "inline trivial" transformation "eliminate builtin" transformation "eliminate definition" transformation "eliminate inductive" transformation "eliminate algebraic" transformation "simplify formula" transformation "discriminate" transformation "encoding smt" prelude "(set-logic AUFNIRA)" theory BuiltIn syntax type int "Int" syntax type real "Real" syntax predicate (=) "(= %1 %2)" meta "encoding : kept" type int end

proof sessions proofs are stored into an XML file and read/written/updated by various tools why3ide why3replayer yes/no OCaml API proof session why3session L A TEX HTML... more details: Preserving User Proofs Across Specification Changes (VSTTE 2013)

3. to do what?

option 1 Why3 as a front-end to many theorem provers saves you a lot of work currently supports Coq, PVS, Isabelle Alt-Ergo, CVC3, CVC4, Simplify, Yices, Yices2, Z3 E, iprover, SPASS, Vampire, Zenon Gappa, Mathematica through files or via the OCaml API

example Why3 comes with a Coq tactic to call external ATPs as oracles Coq let why3 p gl =... Why3... generalize (h6 (i+1)%z h). why3 "alt-ergo"....

option 2 Why3 as a programming language to prove algorithms more than 80 examples in our gallery, e.g. Knuth-Morris-Pratt algorithm Bellman-Ford algorithm Red-black trees etc. automatically translated to OCaml code

option 3 Why3 as an intermediate language, to verify programs written in other, more complex programming languages Java programs: Krakatoa (Marché Paulin Urbain) C programs: Frama-C plug-ins Jessie (Marché), WP (Correnson) Ada programs: GNATprove (Adacore) probabilistic programs: EasyCrypt (Barthe et al.)

various ways of using Why3 Ada Java C prob. pgms GNATprove Krakatoa Frama-C Jessie WP Easycrypt Why3 WhyML logic proof assistants SMT solvers ATP systems other provers

how to tackle a realistic programming language you have to model most aspects pointers objects dynamic allocation arithmetic etc.

example 1: modeling the heap to verify programs with arbitrary aliasing, you have to come up with a memory model type loc type value =... type state = map loc value... this is what is done for C, Java, Ada, etc.

example 2: modeling integer arithmetic type int32 function to int (n: int32) : int constant min : int = - 0x8000 0000 constant max : int = 0x7fff ffff predicate in bounds (n: int) = min n max axiom to int in bounds: n: int32. in bounds (to int n) val of int (n: int) : int32 requires { in bounds n } ensures { to int result = n } val (+) (a b: int32) : int32 requires { in bounds (to int a + to int b) } ensures { to int result = to int a + to int b }

example 3: modeling floating-point arithmetic following the IEEE-754 standard type mode = NearestTiesToEven ToZero Up Down NearestTiesToAway function round mode real : real... type single function value single: real... type class = Finite Infinite NaN function class single : class... mode details: Sylvie s talk on Tuesday

conclusion

future work to simultaneously increase proof automation e.g. automatic induction enrich the specification logic e.g. higher-order logic support more programming constructs e.g. higher-order functions e.g. module subtyping

more details at http://why3.lri.fr/ source code under LGPL related publications more than 80 examples documentation, lecture notes