Deductive Program Verication with Why3 A Tutorial

Size: px
Start display at page:

Download "Deductive Program Verication with Why3 A Tutorial"

Transcription

1 Lecture in the Logic and Semantics group at the Institute of Cybernetics (IoC), Tallinn, Estonia Deductive Program Verication with Why3 A Tutorial Jean-Christophe Filliâtre January 2013

2 Information This lecture has been prepared using Why3 version 0.80 (October 2012). The material related to the lecture (slides, exercises, source code from this document, etc.) is available at In addition, one may consult Why3's documentation and examples from Why3's web site Author: Jean-Christophe Filliâtre LRI - bâtiment 650 Université Paris-Sud Orsay Cedex France [email protected] Web : 2

3 Contents 1 Introduction 5 2 Logic First Contact with Why Talking to Theorem Provers Program Verication First Examples Turing's Proof of a Program McCarthy's 91 Function Arrays Algebraic Data Types Other Data Structures Using Why3 as an Intermediate Language Machine Arithmetic Memory Models

4 4

5 Chapter 1 Introduction Any computer scientist knows John McCarthy's 91 function [15]. function dened as follows: It is the recursive { n 10 if n > 100, f(n) = f(f(n + 11)) otherwise. One may wonder whether this function always return 91, as suggested by its name, or, otherwise, under which condition it does. One may also want to prove its termination, which is not obvious, or to prove that it is equivalent to the following iterative code: e 1 while e > 0 do if n > 100 then n n 10 e e 1 else n n + 11 e e + 1 return n These are questions related to program verication. The programs above are given in pseudo-code, but we can pose similar questions for programs written in mainstream programming languages. For instance, one may wish to prove that the following Java code indeed sorts an array of Boolean values int i = 0, j = a.length - 1; while (i < j) if (!a[i]) i++; else if (a[j]) j; else swap(a, i++, j); or that the following C program, although purposely obfuscated, indeed computes the number of solutions to the N-queens problem: t(a,b,c){int d=0,e=a&~b&~c,f=1;if(a)for(f=0;d=(e-=d)&-e;f+=t(a-d,(b+d)*2,( c+d)/2));return f;}main(q){scanf("%d",&q);printf("%d\n",t(~(~0q),0,0));} 5

6 This lecture is an introduction to Why3 [4], a set of tools to perform deductive program verication [10]. Deductive verication means that we express the correctness of a program as a mathematical statement and then we prove it, which can be summarized as follows: program + specification verification conditions proof This idea is as old as computer science [18, 13], but it is making a giant leap today thanks to recent progress in automated theorem provers, especially those of the SMT family 1. SMT solvers are able to discharge a huge amount of the verication tasks, if not all. The Why3 platform provides a logic language (called Why) and a programming language (called WhyML). The logic is an extension of rst-order logic with polymorphism, algebraic data types, and inductive predicates. The programming language is a rst-order ML-like language with imperative features, pattern matching, and exceptions. The two languages are intimately tied: any logic symbol can be used in programs, and the logic is used to specify programs (via traditional pre- and postconditions, loop invariants, etc.). A standard weakest precondition calculus [8] is used to extract verication conditions from programs. The resulting formulas are then going through several transformations to be sent to a wide set of external theorem provers. The data ow may be depicted as follows: file.mlw file.why VCgen WhyML Why transform/translate print/run Coq Alt-Ergo CVC3 Z3 etc. There are basically three ways of using Why3. for its logic only It is perfectly ne using Why3 without writing a single program. It means you use the logic only (declaring, dening, axiomatizing, stating goals) and you see Why3 as a mere front- for dozens of theorem provers. Yet you save the burden of learning the input languages of all these tools, and the various ways of calling them. You can also use Why3 to manipulate formulas by implementing your own transformations (there is an OCaml API). 1 A computer scientist recently coined the concept of SMT revolution. 6

7 to verify algorithms and data structures Though WhyML has limited imperative features (aliasing is not allowed), a lot of programs and data structures can be implemented in WhyML. Even when some data structure cannot be implemented, it is usually easy to model it and the remaining of the verication can be carried out. WhyML programs can be translated to executable OCaml code. as an intermediate language To verify programs written in a mainstream programming language, it is convenient to use Why3 as an intermediate language. A suitable memory model is designed in Why3 logic and then program constructs are compiled into WhyML constructs. The task of extracting verication conditions (and to pass them to theorem provers) is left to Why3. So far, Why3 has been successfully used that way to verify Java programs [16], C programs [11, 17], Ada programs [12], probabilistic programs [2], and cryptographic programs [1]. The following three chapters describe these three ways of using Why3. Many technical aspects are not covered in this tutorial, such as the transformation process to encode Why3's logic into SMT logic, the type checking rules to exclude aliasing, or the weakest precondition calculus used to extract verication conditions. We invite to reader to get more information from Why3's web site ( and from the author's habilitation thesis [9]. 7

8 8

9 Chapter 2 Logic In this chapter, we introduce Why3 logic. Program verication will be covered in the next two chapters. 2.1 First Contact with Why3 In a le demo_logic.why, let us dene the algebraic data type of polymorphic lists. To do so, we introduce a theory List containing the denition of type list α 1. theory List type list α = Nil Cons α (list α) This le can be processed in a batch way using the following command: why3 demo_logic.why The contents of le demo_logic.why is checked, then printed on standard output. Let us add the denition of a recursive predicate mem checking for the presence of an element x in a list l. predicate mem (x: α) (l: list α) = match l with Nil false Cons y r x = y mem x r The system automatically checks for the terminations of mem, looking for a subset of its arguments that ensures a lexicographic structural decreasing. In this case, it is limited to argument l. If we had written mem x l instead of mem x r, then the denition of mem would have been rejected: why3 demo_logic.why File "demo_logic.why", line 10, characters 2-6: Cannot prove the termination of mem Let us add a third declarations to theory List, namely a goal to show that 2 belongs to the list [1;2;3]. We state it as follows: 1 The type variable α is written 'a in the concrete syntax, as in OCaml. 9

10 goal G1: mem 2 (Cons 1 (Cons 2 (Cons 3 Nil))) It is then possible to attempt discharging this goal using one of the theorem provers supported by Why3. Let us assume that the SMT solver Alt-Ergo is installed and recognized by Why3 (this can be checked with why3 list-provers). Then we pass goal G1 to Alt-Ergo using option -P. why3 -P alt-ergo demo_logic.why demo_logic.why List G1 : Valid (0.03s) As we see, the goal is declared valid, without surprise. We can use the graphical user interface why3ide instead. why3ide demo_logic.why Then we can launch theorem provers interactively, including proof assistants such as Coq. Let us dene now the length of a list. We do that in a second theory Length, whose rst two declarations import the previous theory List, as well as the theory of integer arithmetic from Why3 standard library, namely int.int. theory Length use import List use import int.int In theory List, we did not have to import arithmetic, since only integer literals were used; but here we need addition and order relation as well. We dene a recursive function length over lists, similarly to what we did for predicate mem. function length (l: list α) : int = match l with Nil 0 Cons _ r length r + 1 Once again, the system automatically checks for termination. Then we state a lemma saying that a list length is always nonnegative. lemma length_nonnegative: l:list α. length(l) 0 The automated theorem prover Alt-Ergo is not able to discharge it. More specically, it quickly aborts with message Unknown, which means it could not check the validity of the goal. why3 -P alt-ergo demo_logic.why demo_logic.why List G1 : Valid (0.01s) demo_logic.why Length length_nonnegative : Unknown: Unknown (0.01s) Indeed, proving lemma length_nonnegative requires induction, which is out of reach of SMT solvers. One may use the Coq proof assistant instead to do that proof, by calling it from why3ide for instance. However, Alt-Ergo is able to discharge the following goal, using lemma length_nonnegative as an hypothesis: goal G3: x: int, l: list int. length (Cons x l) > 0 10

11 This is the distinction between declarations goal and lemma: the latter introduces a goal that may be used in the following. It is easy to check that lemma length_nonnegative is indeed an hypothesis of goal G3 from the graphical user interface (in the top-right window). Let us now dene the notion of sorted list. We start with lists of integers. We introduce a new theory SortedList for that purpose, containing the declarations of an inductive predicate sorted 2. theory SortedList use import List use import int.int inductive sorted (list int) = sorted_nil: sorted Nil sorted_one: x: int. sorted (Cons x Nil) sorted_two: x y: int, l: list int. x y sorted (Cons y l) sorted (Cons x (Cons y l)) Such a declaration denes sorted as the smallest predicate satisfying the three axioms sorted_nil, sorted_one, and sorted_two. We can state a goal saying that the list [1;2;3] is sorted: goal sorted123: sorted (Cons 1 (Cons 2 (Cons 3 Nil))) and it is easily discharged by automated theorem provers. However, dening sorted over lists of integers only, and using the order relation only, is not satisfactory. As much as possible, we could prefer dening sorted in a generic way, once and for all. The logic of Why3 being a rst-order logic, it is not possible to pass the order relation as an argument to predicate sorted. Though, there is an alternative. We modify theory SortedList to use an abstract data type t instead of integers and an uninterpreted binary predicate over t. theory SortedList use import List type t predicate ( ) t t To make it right, we add three axioms to express that is an order relation. 2 We could have dened predicate sorted recursively, as follows: predicate sorted (l: list int) = match l with Nil Cons _ Nil true Cons x (Cons y _ as r) x y sorted r But the purpose here is to introduce inductive predicates. 11

12 axiom le_refl: x: t. x x axiom le_asym: x y: t. x y y x x = y axiom le_trans: x y z: t. x y y z x z The denition of sorted is mostly unchanged: we simply substitute t for int and relation over type t for relation over type int. inductive sorted (list t) = sorted_nil: sorted Nil sorted_one: x: t. sorted (Cons x Nil) sorted_two: x y: t, l: list t. x y sorted (Cons y l) sorted (Cons x (Cons y l)) To handle the particular case of lists of integers, we rst set up a new theory in which we import lists and integers: theory SortedIntList use import int.int use import List Then we instantiate the generic theory SortedList with type int and with order relation over integers. To do so, we use the clone command, rather than use, as follows: clone import SortedList with type t = int, predicate ( ) = ( ), lemma le_refl, lemma le_asym, lemma le_trans This command makes a copy of theory SortedList, while substituting type int to type t and the order relation over integers to the uninterpreted predicate (in this case, the two predicates have the same name but this is not a requirement). This command introduces the declaration of a new inductive predicate sorted, with an argument of type list int. We can use it to state the following goal: goal sorted123: sorted (Cons 1 (Cons 2 (Cons 3 Nil))) Additionally, we notice that the clone command above also included lemma le_refl, lemma le_asym, and lemma le_trans. It means that these three axioms must be proved 3. They are turned into lemmas. We can easily check this out by looking at the set of goals contained in le demo_logic.why: why3 -P alt-ergo demo_logic.why... demo_logic.why SortedIntList le_refl : Valid (0.00s) demo_logic.why SortedIntList le_asym : Valid (0.00s) demo_logic.why SortedIntList le_trans : Valid (0.00s) demo_logic.why SortedIntList sorted123 : Valid (0.00s) 3 The system cannot automatically infer axioms that could become lemmas; this is not decidable. Thus it is up to the user to indicate the axioms to be turned into lemmas. 12

13 As illustrated by this example, the concept of cloning allows the design of generic theories to be instantiated later in various ways. This is analogous to generic classes in Java or functors in ML. But this is also slightly more exible, as parameters do not have to be set once and for all. A theory is thus parameterized in various ways simultaneously. In the example above, we can introduce another generic theory, namely that of order relation. It contains type t, order relation, and the three axioms. theory Order type t predicate ( ) t t axiom le_refl: x: t. x x axiom le_asym: x y: t. x y y x x = y axiom le_trans: x y z: t. x y y z x z Then we simply clone it inside theory SortedList, to get the exact same theory as before: theory SortedList use import List clone export Order... The benet here is the ability to reuse theory Order in other contexts. Figure 2.1 summarizes this new version of theory SortedList and its use on lists of integers. The Why3 standard library is built this way. Beside the obvious benet of factorization, splitting the declarations into small theories also allows a ne grain control of the context of each goal. With SMT solvers, in particular, limiting the size of the logical context may improve performances signicantly. Summary. The logic of Why3 is an extension of rst-order logic with polymorphism, mutually recursive algebraic data types, mutually recursive function/predicate symbols, mutually inductive predicates, and constructs let-in, match-with, and if-then-else. Logical declarations are of four dierent kinds: type declaration; function or predicate declaration; inductive predicate declaration; axiom, lemma, or goal declaration. Logical declarations are organized into theories. A theory T 1 may be used (use) in another theory T 2. In that case, symbols from T 1 are shared, axioms from T 1 remain axioms, lemmas from T 1 become axioms, and goals from T 1 are discarded. or cloned (clone) in another theory T 2. In that case, declarations from T 1 are copied or substituted, axioms from T 1 remain axioms or become lemmas/goals, lemmas from T 1 become axioms, and goals from T 1 are discarded. 13

14 theory List type list α = Nil Cons α (list α) theory Order type t predicate ( ) t t axiom le_refl: x: t. x x axiom le_asym: x y: t. x y y x x = y axiom le_trans: x y z: t. x y y z x z theory SortedList use import List clone export Order inductive sorted (list t) = sorted_nil: sorted Nil sorted_one: x: t. sorted (Cons x Nil) sorted_two: x y: t, l: list t. x y sorted (Cons y l) sorted (Cons x (Cons y l)) theory SortedIntList use import int.int use import List clone import SortedList with type t = int, predicate ( ) = ( ), lemma le_refl, lemma le_asym, lemma le_trans goal sorted123: sorted (Cons 1 (Cons 2 (Cons 3 Nil))) Figure 2.1: A generic theory of sorted lists. 14

15 2.2 Talking to Theorem Provers One of the rst benets of Why3 is to provide a technology to talk to provers. There are various theorem provers available and they have distinct logical languages, predened theories, or type systems. Why3 provides a common language and a common tool to use them. This technology is organized around the notion of task. A task is a logical context, that is a list of declarations, followed but exactly one goal, that is a formula. Tasks are extracted from the various theories. Given a task and a target theorem prover, Why3 performs a series of transformations on the task, so that it ts in the logic of the prover. For example, if the target prover is Z3, Why3 will apply, among other things, a transformation to get rid of inductive predicates, since Z3 knows nothing about it. Once all transformations are applied, Why3 simply prints the resulting task into the native syntax of the prover, using a pretty-printer. We can display the task ow as follows: theory Alt-Ergo theory T 1 T 2 P goal goal goal Z3 theory Vampire This journey is driven by a le (called a driver in Why3's terminology). This le lists the transformations to apply, the output format (that is the input syntax of the prover as well as predened symbols and axioms), and regular expressions to diagnose messages from the prover. Such a le can be set up by the user, for instance to add support for a new prover or to conduct experiments with a prover. Drivers are provided with Why3 for the following proves: Alt-Ergo, CVC3, Yices, E-prover, Gappa, MathSAT, Simplify, Spass, Vampire, VeriT, Z3, Zenon, iprover, Mathematica, Coq, PVS. Additionally, Why3 provides an OCaml API. One can build terms, formulas, declarations, tasks, theories (that are all guaranteed to be well-formed), and call provers. Using plug-ins, the system can be exted with new input languages, new transformations, and new pretty-printers. In particular, everything needed to add support for a new prover can be added to the system. More details can be found in the paper Why3: Shepherd your herd of provers [5] as well as Why3's manual [4]. 15

16 16

17 Chapter 3 Program Verication We now turn to program verication using Why First Examples Turing's Proof of a Program As a rst example, let us consider what is most likely the very rst proof of a program. It is a 1949 paper by Alan Turing called Checking a Large Routine [18]. The program computes n! using only additions. It is given as a control ow graph: STOP r = 1 u = 1 v = u TEST r n s = 1 u = u + v s = s + 1 r = r + 1 TEST s r The notation u = u+v stands for the assignment of u+v to variable u, that is u u+v using a modern notation. Variable n contains the input parameter and is not modied. When the program exits, variable u contains n!, the factorial of n. There are two nested loops. In the outer loop, variable u contains r! and its contents is copied into variable v. The inner loop computes (r + 1)! in u, using repetitive additions of v. Variables r and s are loop counters, so we can easily rewrite the program using two for loops. With a slight modication of the control ow 1, the program above is thus equivalent to: u 1 for r = 0 to n 1 do v u for s = 1 to r do u u + v Let us prove the correctness of this program using Why3. In a le demo_turing.mlw we write the program above in the syntax of WhyML, the programming language of Why3. 1 Finding which is left to the reader as an exercise. 17

18 Program declarations are grouped in modules (the programming equivalent to logical theories). module CheckingALargeRoutine use import int.fact use import ref.ref The rst command imports the logical theory int.fact, that is theory Fact from Why3 standard library. This theory provides a function symbol fact denoting the factorial. The second command imports a module from the standard library of WhyML, namely the module Ref providing references. As in ML, references are mutable variables: a reference is created with function ref, we access the contents of reference x with!x, and we assign it with x := e. We can now write a function routine taking an integer argument n as argument and computing its factorial using the algorithm above: let routine (n: int) : int requires { n 0 } ensures { result = fact n } = let u = ref 1 in for r = 0 to n-1 do let v =!u in for s = 1 to r do u :=!u + v done done;!u The code itself is similar to OCaml code. The specication is introduced with keywords requires and ensures. requires introduces the precondition n 0 and ensures the postcondition result = fact n. Within the postcondition, variable result stands for the value returned by the function. As we did in the previous chapter with a le containing logical declarations, we can pass this le to Why3 for type checking and proof processing. why3 -P alt-ergo demo_turing.mlw WP CheckingALargeRoutine WP_parameter routine : Unknown: Unknown (0.08s) We see that Alt-Ergo was not able to discharge the verication condition. If we switch to the graphical user interface (why3ide) which is quickly mandatory when performing program verication we can have a look at the goal expressing the correctness of function routine. Omitting the context, it reduces to the following formula: n, n 0 (0 > n 1 1 = fact n) (0 n 1 u, u = fact n) The rst part of the formula corresponds to the case where we do not even enter the outer for loop, since n = 0. Then we have to show 1 = fact n, that is provable. The other part of the formula corresponds to the case where we enter the for loop. Then we have to prove that the nal value of variable u, here written u, is equal to the factorial of n. But we do not have any information over u, which makes the formula unprovable. 18

19 module CheckingALargeRoutine use import int.fact use import ref.ref let routine (n: int) : int requires { n 0 } ensures { result = fact n } = let u = ref 1 in for r = 0 to n-1 do invariant {!u = fact r } let v =!u in for s = 1 to r do invariant {!u = s * fact r } u :=!u + v done done;!u Figure 3.1: Computing the factorial using additions (Turing, 1949). Indeed, we have to rst set a loop invariant to get information regarding the nal value of u. In our case, this invariant states that u contains the factorial of r. We write it as follows: for r = 0 to n-1 do invariant {!u = fact r } Using this invariant, it is now possible to establish the postcondition when exiting function routine. To see it, we can use the Split command in the graphical user interface, which results in four sub-goals. The validity of the postcondition is the fourth one and is easily discharged by a solver. On the contrary, we cannot discharge the third goal, which states the preservation of the loop invariant we just added. Without any surprise, we have to equip the inner loop with an invariant as well, namely the following: for s = 1 to r do invariant {!u = s * fact r } It is now easy for a solver to show the correctness of the program. There is no termination to prove here, as it is automatically guaranteed in the case of for loops. The whole le is given gure McCarthy's 91 Function Let us consider now another example, namely the aforementioned McCarthy's 91 function [15]. It is the following recursive function: { n 10 if n > 100, f(n) = f(f(n + 11)) otherwise. 19

20 In WhyML syntax, we dene such a function using the let rec construct. let rec f (n:int) : int = if n 100 then f (f (n + 11)) else n - 10 We int to prove the termination of this function. To do so, we must equip it with a variant, that is a term that decreases at each recursive call for a well-founded order relation. The simplest solution is to use an integer term and the following relation: x y def = x < y 0 y. In the case of function 91, the variant is quite easy to gure out. It is n. In WhyML syntax, we give it as follows: let rec f (n:int) : int variant { n } = if n 100 then f (f (n + 11)) else n - 10 As a result, we get a verication condition to show that the variant indeed decreases in each of the two recursive calls. In the rst case, the sub-goal is easily discharged. Indeed we have 100 (n + 11) 100 n when n 100. On the contrary, the second sub-goal cannot be discharged, for we don't have enough information regarding the value returned by the rst recursive call. Thus we have to give function f a specication, namely a postcondition: let rec f (n: int) : int variant { 100-n } ensures { result = if n 100 then 91 else n-10 } = if n 100 then f (f (n + 11)) else n - 10 Then we get a verication condition that is easily discharged by automated provers. It expresses both termination and correctness. This is an example where proving termination requires proving a behavioral property as well. (Another example is Floyd's algorithm for cycle detection, also know as tortoise and hare algorithm; see [9].) Let us consider now a non-recursive version of function 91, namely the following iterative program: let iter (n0: int) = let n = ref n0 in let e = ref 1 in while!e > 0 do if!n > 100 then begin n :=!n - 10; e :=!e - 1 else begin n :=!n + 11; e :=!e

21 done;!n The idea behind this program is the following. It is not necessary to maintain a stack of all recursive calls to f. The total number of such calls is enough. It is maintained in variable e, and initialized to 1. If n > 100 we subtract 10 from n and we decrement e, to account for one completed call to f. Otherwise, we add 11 to argument n and we increment e to account for a completed call to f and to two new calls to be performed. Proving termination of this program is both simpler and more complex than proving the termination of the recursive function. It is simpler as we do not have to prove anything regarding the values computed by the program. But it is also more complex, as the variant is now a pair, namely (101 n + 10e, e), that decreases for the lexicographic order, each component being ordered by relation above. Such a lexicographic order relation is dened in Why3 standard library and we simply need to import it: use import int.lex2 We can now set this variant to the while loop, using the following syntax: while!e > 0 do variant { (100 -!n + 10 *!e,!e) with lex }... where keyword with is used to specify the order relation. The verication condition is discharged automatically, without any other annotation in the program. We could stop here. But proving the behavioral correctness of this iterative code appears to be interesting as well. Indeed, this is not obvious that this new code computes f(n). The loop invariant is f e (n) = f(n 0 ) where n 0 stands for the initial value of n. Therefore, when we exit the loop, with e = 0, we get n = f(n 0 ) and we return this value. To write down such an invariant, we rst introduce the logical function f. function f (x: int) : int = if x 101 then x-10 else 91 This is not the recursive function we proved above, but rather the specication of function 91. Then we dene f k (x). A logical function cannot be dened recursively over integers (only structural recursion is allowed) thus we cannot dene f k (x) recursion over k. As a consequence, we turn to an axiomatization: function iter int int : int axiom iter_0: x: int. iter 0 x = x axiom iter_s: k x: int. 0 < k iter k x = iter (k-1) (f x) More generally, Why3 standard library contains a theory int.iter that axiomatizes the iteration of a given function. Thus we can conveniently replace the three declarations above with the appropriate cloning of that theory: 21

22 use import int.int use import int.lex2 use import ref.ref function f (n: int) : int = if n 100 then 91 else n-10 clone import int.iter with type t = int, function f = f let iter (n0: int) : int ensures { result = f n0 } = let n = ref n0 in let e = ref 1 in while!e > 0 do invariant {!e 0 iter!e!n = f n0 } variant { (100 -!n + 10 *!e,!e) with lex } if!n > 100 then begin n :=!n - 10; e :=!e - 1 else begin n :=!n + 11; e :=!e + 1 done;!n Figure 3.2: Non-recursive version of McCarthy's 91 function. clone import int.iter with type t = int, function f = f The annotated code is given gure 3.2. condition is automatically discharged. 3.2 Arrays As for the recursive version, the verication Up to now, we had programs using only integers. Let us consider now programs using arrays. Why3 standard library provides arrays in module array.array. use import array.array This module declares a polymorphic type array α, an access operation written a[e], an assignment operation written a[e1] e2, and various operations such as create, length, app, sub, or copy. As an example, let us consider proving the correctness of the following algorithm that sorts an array a of n Boolean values according to False < True. 22

23 i, j 0, n 1 while i < j if a[i] then i i + 1 else if a[j] then j j 1 else swap a[i] and a[j]; i i + 1; j j 1 False?...? True i j We rst set up the program specication. We have to state that array a is sorted when the program exits. We dene a predicate sorted to do so: predicate () (x y: bool) = x = False y = True predicate sorted (a: array bool) = i1 i2: int. 0 i1 i2 < a.length a[i1] a[i2] We also have to specify that the nal contents of array a is ane permutation of its initial contents (otherwise, a program setting all elements to False would be accepted as a valid sort). There are multiple ways to dene the permutation property. We could count the number of False (or True) values and assert that it is unchanged, or, equivalently, assert that the two multi-sets of elements are the same. Another solution, well-suited for the program above, consists in dening the permutation property as the smallest equivalence relation containing transpositions (swaps to two elements). Thus we dene permut as an inductive predicate inductive permut (a1 a2: array bool) = with two clauses for reexive and transitive properties permut_refl: a: array bool. permut a a permut_trans: a1 a2 a3: array bool. permut a1 a2 permut a2 a3 permut a1 a3 and a third clause to indicate that permut contains transpositions: permut_swap: a1 a2: array bool. i j : int. length a1 = length a2 0 i < length a1 0 j < length a2 a1[i] = a2[j] a1[j] = a2[i] ( k: int. 0 k < length a1 k i k j a1[k]=a1[k]) permut a1 a2 Note that we have no clause to say that permut is symmetric (which is, in a general case, required to dene an equivalence relation). There are several reasons: rst, we can prove that relation permut is symmetric; second, this extra property is not needed for our proof. The generic denition of permut for arrays with elements of any type is provided by Why3 standard library, in module array.arraypermut. We can now write the specication. It is as follows: let two_way_sort (a: array bool) : unit ensures { sorted a } ensures { permut (old a) a } 23

24 =... Notation old a in the postcondition stands for the initial value of a, that is its values at the function entry. We still need a loop invariant. It decomposes into four parts. First, we have two arithmetic relations over i and j. invariant { 0!i!j < length a } Then we state that all values left to i are all False. invariant { k: int. 0 k <!i a[k] = False } Similarly, we state that all values right to j are all True. invariant { k: int.!j < k < length a a[k] = True } Finally, we have to state the permutation property, that is that array a is always a permutation of its initial contents. To do so, we introduce a label Init at the of the function body, with construct 'Init:, then we use that label in the loop invariant to refer to the value of a at this program point, with notation at a 'Init. invariant { permut (at a 'Init) a } This completes the loop invariant. Besides, we prove termination in a trivial way, using j i as variant. The code is summarized in gure 3.3. Exercise: Dijkstra's Dutch national ag problem. Prove the correctness of a program sorting an array with three dierent values, standing for the three colors of the Dutch national ag (type color = Blue White Red). The code is given on the lecture web site. 3.3 Algebraic Data Types A key idea of Hoare logic [13] is that all symbols from the logic can be used in programs. In particular, we already used type int from the logic in many programs. Similarly, we can use algebraic data types in programs. In Why3 standard library, we nd the following algebraic data types: type bool = True False type option α = None Some α type list α = Nil Cons α (list α) (in bool.bool) (in option.option) (in list.list) The user is free to dene other algebraic data types and to use them in programs. Let us illustrate this on an example. This is the famous same fringe problem: given two binary trees holding values at nodes, we want to check whether they have the same elements when traversed in inorder. The problem is subtle, as the two trees may have dierent shapes. For instance, the two trees 24

25 use import int.int use import bool.bool use import ref.refint use import array.array use import array.arraypermut predicate () (x y: bool) = x = False y = True predicate sorted (a: array bool) = i1 i2: int. 0 i1 i2 < a.length a[i1] a[i2] let two_way_sort (a: array bool) : unit ensures { sorted a } ensures { permut (old a) a } = 'Init: let i = ref 0 in let j = ref (length a - 1) in while!i <!j do invariant { 0!i!j < length a } invariant { k: int. 0 k <!i a[k] = False } invariant { k: int.!j < k < length a a[k] = True } invariant { permut (at a 'Init) a } variant {!j -!i } if not a[!i] then incr i else if a[!j] then decr j else begin let tmp = a[!i] in a[!i] a[!j]; a[!j] tmp; incr i; decr j done Figure 3.3: Sorting an array of Boolean values. 25

26 both have elements 1, 3, 4, 5, 8 when traversed in inorder. This problem has practical application: it provides an order relation over binary search trees (BST) that is shapeinsensitive. This is useful to build other BSTs whose elements are BSTs (to implement sets of sets). Let us write a WhyML program to solve the same fringe problem and let us prove its correctness. We introduce some uninterpreted type elt for the elements (the nature of the elements is irrelevant here) and a type tree for binary search trees. type elt type tree = Empty Node tree elt tree For the purpose of the specication, we introduce a function elements returning the result of an inorder traversal of a tree. function elements (t: tree) : list elt = match t with Empty Nil Node l x r elements l ++ Cons x (elements r) The function we seek to dene and prove is thus as follows: let same_fringe (t1 t2: tree) : bool ensures { result=true elements t1 = elements t2 } =... Of course, we could simply use function elements to solve the problem. However, this would be a quite bad solution: rst, list concatenations are costly (they could reach a quadratic total cost) second, it is unnecessary to build the two lists if they quickly dier (at least in the context of a strict language as WhyML). Thus we consider a better solution, consisting in considering the leftmost branch of each tree as a list, from bottom up. Each element on this list is paired with its right sub-tree. It is thus a list of pairs (x i, t i ), as follows:... x n x 2 t n x 1 t 2 t 1 26

27 On the example above, the two lists are the following: The comparison then proceeds as follows. We rst compare the rst element of each list. If they dier, we are done. Otherwise, we replace the rst element in each list by the leftmost branch of its right sub-tree, and then we recursively perform the comparison. If at some point a list is exhausted while the other is not, we answer negatively. Finally, we successfully terminate if both lists exhaust at the same time. To write this algorithm in WhyML, we rst introduce a data type enum for the lists of pairs (in the following, we call such a list an enumerator). type enum = Done Next elt tree enum Then we dene a recursive function enum_elements to get the inorder traversal of an enumerator, analogous to function elements, for specication purposes only. function enum_elements (e: enum) : list elt = match e with Done Nil Next x r e Cons x (elements r ++ enum_elements e) Now we proceed to the code itself. We start with a function enum that builds an enumerator of type enum from a tree t of type tree. We proceed recursively along the leftmost branch of t. To do so, we pass a second argument e of type enum to accumulate. let rec enum (t: tree) (e: enum) : enum ensures { enum_elements result = elements t ++ enum_elements e } = match t with Empty e Node l x r enum l (Next x r e) The specication states that the traversal of the result is the concatenation of the traversal of t and that of e. Then we write the core of the algorithm as a function eq_enum comparing two enumerators e1 and e2. We proceed recursively, until we exhaust at least one list. let rec eq_enum (e1 e2: enum) : bool ensures { result=true enum_elements e1 = enum_elements e2 } = match e1, e2 with Done, Done True 27

28 Next x1 r1 e1, Next x2 r2 e2 x1 = x2 && eq_enum (enum r1 e1) (enum r2 e2) _ False The specication states that we decide equality of the traversals of e1 and e2. Finally, the solution to the same fringe problem is a mere call to eq_enum on the enumerators for the two trees. let same_fringe (t1 t2: tree) : bool ensures { result=true elements t1 = elements t2 } = eq_enum (enum t1 Done) (enum t2 Done) The solution is summarized in gure 3.4. Exercise: inorder traversal. Using the same type for binary trees, we consider the following recursive function that lls an array a with the elements of a tree t, following an inorder traversal. fill t start def = if t = Empty then return start if t = Node l x r then res fill l start if res = length a then return res a[res] x fill r (res + 1) The WhyML code for this program, as well as the properties to prove, are available from the lecture web site. 3.4 Other Data Structures If we look into Why3 standard library module array.array we nd the following declarations for the type of arrays: type array α model { length: int; mutable elts: map int α } Such a declaration has two meanings. In programs, it is analogous to the declaration of an abstract type, that would be type array α In the logic, however, it is equivalent to the declaration of an immutable record type, that would be type array α = { length: int; elts: map int α } Said otherwise, an array is modeled in the logic as a record with two elds, the length of type int, and the contents of type map int α (a purely applicative map). 28

29 use import int.int use import list.list use import list.app type elt type tree = Empty Node tree elt tree function elements (t: tree) : list elt = match t with Empty Nil Node l x r elements l ++ Cons x (elements r) type enum = Done Next elt tree enum function enum_elements (e: enum) : list elt = match e with Done Nil Next x r e Cons x (elements r ++ enum_elements e) let rec enum (t: tree) (e: enum) : enum ensures { enum_elements result = elements t ++ enum_elements e } = match t with Empty e Node l x r enum l (Next x r e) let rec eq_enum (e1 e2: enum) : bool ensures { result=true enum_elements e1 = enum_elements e2 } = match e1, e2 with Done, Done True Next x1 r1 e1, Next x2 r2 e2 x1 = x2 && eq_enum (enum r1 e1) (enum r2 e2) _ False let same_fringe (t1 t2: tree) : bool ensures { result=true elements t1 = elements t2 } = eq_enum (enum t1 Done) (enum t2 Done) Figure 3.4: Solving the same fringe problem. 29

30 The type being abstract in programs, we cannot implement operations over type array α. But we can declare them. For instance, the access operation is declared as follows: val ([]) (a: array α) (i: int) : α reads {a} requires { 0 i < length a } ensures { result = a[i] } This function takes a and i as arguments, together with a precondition to ensure an array access within bounds. It returns a value of type α, and the postcondition states that the returned value is the value contained in the purely applicative map, that is a.elts. As we see, logical annotations, such as the pre- and postcondition here, have access to the record elds length and elts. It is the purpose of a model type to be available in the logic (and only in the logic). The annotation reads {a} indicates that the function accesses the contents of array a (but does not modify it). The assignment operation is declared in a similar way: val ([] ) (a: array α) (i: int) (v: α) : unit writes {a} requires { 0 i < length a } ensures { a.elts = M.set (old a.elts) i v } The main dierence is the annotation writes {a}, which indicates that the contents of a is modied by a call to this function. This is allowed since the eld elts was declared to be mutable. Modeling Hash Tables. As an example, let us do a similar model of hash tables 2 More precisely, let us consider polymorphic hash tables with the following interface (in OCaml syntax): type t 'a 'b val create: int -> t 'a 'b val clear: t 'a 'b -> unit val add: t 'a 'b -> 'a -> 'b -> unit exception Not_found val find: t 'a 'b -> 'a -> 'b Function create returns a fresh, empty table. Function clear empties a given table. Function add inserts a new entry. Finally, function find returns the value mapped to a key, if any, and raises exception Not_found otherwise. As for arrays above, we rst declare a type t α β for the hash tables, modeling the contents using a purely applicative map. type t α β model { mutable contents: map α (option β) } We choose to map at most one value for each key. Thus the elds contents maps each key k of type α to a value of type option β: None stands for the absence of value for key k, and Some v stands for an entry k v in the table. To ease forthcoming specications, we set up notation h[k] for the entry for key k in table h. function ([]) (h: t α β) (k: α) : option β = get h.contents k 2 Hash tables are provided in Why3 standard library since version

31 Function create takes an integer n as argument (the initial size of the bucket array) and returns a fresh, empty table. val create (n:int) : t α β requires { 0 < n } ensures { k: α. result[k] = None } Function clear empties a given table. Thus it has the same postcondition as function create. But it also has species that table h is modied (writes {h}). val clear (h: t α β) : unit writes { h } ensures { k: α. h[k] = None } Function add also has a writes {h} annotation: val add (h: t α β) (k: α) (v: β) : unit writes { h } ensures { h[k] = Some v k': α. k' k h[k'] = (old h)[k'] } Its postcondition states that key k is now mapped to value v in the new contents of h and that any other key k' is still mapped to the same value as before, that is (old h)[k']. Indeed, annotation writes h denotes a possible modication of all the contents of table h and thus it is here the role of the postcondition to state what is modied and what is not. Finally, we declare function find. exception Not_found val find (h: t α β) (k: α) : β reads { h } ensures { h[k] = Some result } raises { Not_found h[k] = None } The keyword raises introduces a postcondition corresponding to the case where an exception is raised (Not_found in that case), while ensures declares a postcondition corresponding to the case where a value is returned. Figure 3.5 summarizes our model of hash tables. It is worth mentioning that there is currently no possibility to ensure that a given WhyML implementation of hash tables conforms to this model. 31

32 use import option.option use import int.int use import map.map type t α β model { mutable contents: map α (option β) } function ([]) (h: t α β) (k: α) : option β = get h.contents k val create (n:int) : t α β requires { 0 < n } ensures { k: α. result[k] = None } val clear (h: t α β) : unit writes { h } ensures { k: α. h[k] = None } val add (h: t α β) (k: α) (v: β) : unit writes { h } ensures { h[k] = Some v k': α. k' k h[k'] = (old h)[k'] } exception Not_found val find (h: t α β) (k: α) : β reads { h } ensures { h[k] = Some result } raises { Not_found h[k] = None } Figure 3.5: Modeling hash tables. 32

33 Chapter 4 Using Why3 as an Intermediate Language Using Why3 to verify programs written in a mainstream programming language (such as C or Java) requires an adequate modeling of its semantics in the logic of Why3. In this chapter, we briey explain how to do so on two examples. 4.1 Machine Arithmetic So far we have use arithmetic from Why3 standard library, that is mathematical integers of unbounded precision. Let us assume we need to model machine arithmetic instead (say, signed 32-bit integers), either to show the absence of arithmetic overow in a program, or to reason about possible overows. The main diculty is that we do not want to loose the arithmetic capabilities of SMT solvers (which only know about mathematical arithmetic). One way to do is to introduce a new, uninterpreted type int32 for machine integers type int32 together with a function giving the corresponding value of type int: function toint int32 : int The idea is then to use only type int in program annotations, that is to apply function toint in a systematic way around sub-expressions of type int32. The range of 32-bit integers is dened with two constants constant min_int: int = constant max_int: int = and an axiom states that any value of type int32 is bounded by these constants: axiom int32_domain: x: int32. min_int toint x max_int If our purpose is to build a model to prove the absence of arithmetic overow, we simply need to function to build a value of type int32 from a value of type int with a suitable precondition: 33

34 val ofint (x:int) : int32 requires { min_int x max_int } ensures { toint result = x } Then we can translate any program manipulating machine integers into a WhyML program where each arithmetic operation uses function ofint. For instance, an expression such as x + y is translated into ofint (toint x) (toint y). Equivalently, we can also declare (or dene) a function performing this computation, that is val (+) (x: int32) (y: int32) : int32 requires { min_int toint x + toint y max_int } ensures { toint result = toint x + toint y } The lecture web site contains an application of this model to the verication of a program searching for a value in a sorted array using binary search. This way we nd the famous bug related to the computation of the mean value of l and u using (l+u)/2 [3]. Then we can x the bug, for instance using l+(u-l)/2 instead, and we can show that this new program is safe from any arithmetic overow. 4.2 Memory Models A key idea of Hoare Logic, implemented in Why3, is that the system can statically identify the various memory locations. This is absence of aliasing. In particular, memory locations are not rst-class values. Thus to handle programs with mutable data structures such as linked lists or mutable trees, or programs with explicit pointers, one has to model the memory heap. A trivial example would be that of C programs with explicit pointers of type int*. A simple way to model such programs would be to introduce a type for pointers and a global reference holding the contents of the memory: type pointer val memory: ref (map pointer int) Then a C expression such as *p is translated into!memory[p]. If pointer arithmetic is allowed, then either the type pointer is dened as an alias for type int, or operations over type pointer (such as shifting, comparisons, etc.) are introduced. This is somehow a rather crude model, where the user quickly get stuck into a specication nightmare. There are more subtle models, such as the component-as-array model [7, 6]. Say we want to model the following C type for simply linked lists: struct List { int head; struct List *next; }; The idea behind the component-as-array model is to have several maps to model the various structure elds. In this case, we have (at least) two global maps for elds head and next: 34

35 type pointer val head: ref (map pointer int) val next: ref (map pointer pointer) An obvious benet is that any modication to reference head does not have any impact on the contents of reference next. The benet is even greater when there are many C elds (being they of the same type or not, of from the same structure or not). The componentas-array model may be even further rened using a region-analysis of pointers [14]. On the contrary, a drawback is that low-level tricks such as pointer casts or pointer arithmetic are not easily allowed anymore. 35

36 36

37 Bibliography [1] M. Barbosa, Jean-Christophe Filliâtre, J. Sousa Pinto, and B. Vieira. A Deductive Verication Platform for Cryptographic Software. In 4th International Workshop on Foundations and Techniques for Open Source Software Certication (OpenCert 2010), volume 33, Pisa, Italy, September Electronic Communications of the EASST. [2] Gilles Barthe, Benjamin Grégoire, and Santiago Zanella Béguelin. Formal certication of code-based cryptographic proofs. In Zhong Shao and Benjamin C. Pierce, editors, POPL, pages 90101, Savannah, GA, USA, January ACM Press. [3] Joshua Bloch. Nearly all binary searches and mergesorts are broken, extra-extra-read-all-about-it-nearly.html. [4] François Bobot, Jean-Christophe Filliâtre, Claude Marché, Guillaume Melquiond, and Andrei Paskevich. The Why3 platform. LRI, CNRS & Univ. Paris-Sud & INRIA Saclay, version 0.64 edition, February [5] François Bobot, Jean-Christophe Filliâtre, Claude Marché, and Andrei Paskevich. Why3: Shepherd your herd of provers. In Boogie 2011: First International Workshop on Intermediate Verication Languages, pages 5364, Wrocªaw, Poland, August [6] Richard Bornat. Proving pointer programs in Hoare logic. In Mathematics of Program Construction, pages , [7] Rod Burstall. Some techniques for proving correctness of programs which alter data structures. Machine Intelligence, 7:2350, [8] Edsger W. Dijkstra. A discipline of programming. Series in Automatic Computation. Prentice Hall Int., [9] Jean-Christophe Filliâtre. Deductive Program Verication. Thèse d'habilitation, Université Paris-Sud, December In English, hdr/memoire.pdf. [10] Jean-Christophe Filliâtre. Deductive software verication. International Journal on Software Tools for Technology Transfer (STTT), 13(5):397403, August

38 [11] Jean-Christophe Filliâtre and Claude Marché. Multi-Prover Verication of C Programs. In Sixth International Conference on Formal Engineering Methods, pages Springer, [12] Jérôme Guitton, Johannes Kanig, and Yannick Moy. Why Hi-Lite Ada? In Boogie 2011: First International Workshop on Intermediate Verication Languages, pages 2739, Wrocªaw, Poland, August [13] C. A. R. Hoare. An axiomatic basis for computer programming. Communications of the ACM, 12(10): and 583, October [14] Thierry Hubert and Claude Marché. Separation analysis for deductive verication. Technical report, Université Paris XI, separation.pdf. [15] Z. Manna and J. Mccarthy. Properties of programs and partial function logic. In Machine Intelligence, volume 5, [16] Claude Marché, Christine Paulin, and Xavier Urbain. The Krakatoa proof tool, [17] Yannick Moy. Automatic Modular Static Safety Checking for C Programs. PhD thesis, Université Paris-Sud, January [18] Alan Mathison Turing. Checking a large routine. In Report of a Conference on High Speed Automatic Calculing Machines, pages 6769, Cambridge, Mathematical Laboratory. 38

The Why3 platform. François Bobot 1,2 Jean-Christophe Filliâtre 1,2 Claude Marché 2,1 Andrei Paskevich 1,2. LRI, CNRS, Univ Paris-Sud, Orsay, F-91405

The Why3 platform. François Bobot 1,2 Jean-Christophe Filliâtre 1,2 Claude Marché 2,1 Andrei Paskevich 1,2. LRI, CNRS, Univ Paris-Sud, Orsay, F-91405 The Why3 platform Version 0.71, October 2011 François Bobot 1,2 Jean-Christophe Filliâtre 1,2 Claude Marché 2,1 Andrei Paskevich 1,2 1 LRI, CNRS, Univ Paris-Sud, Orsay, F-91405 2 INRIA Saclay - Île-de-France,

More information

Rigorous Software Engineering Hoare Logic and Design by Contracts

Rigorous Software Engineering Hoare Logic and Design by Contracts Rigorous Software Engineering Hoare Logic and Design by Contracts Simão Melo de Sousa RELEASE (UBI), LIACC (Porto) Computer Science Department University of Beira Interior, Portugal 2010-2011 S. Melo de

More information

Why? A central concept in Computer Science. Algorithms are ubiquitous.

Why? A central concept in Computer Science. Algorithms are ubiquitous. Analysis of Algorithms: A Brief Introduction Why? A central concept in Computer Science. Algorithms are ubiquitous. Using the Internet (sending email, transferring files, use of search engines, online

More information

How To Write A Program Verification And Programming Book

How To Write A Program Verification And Programming Book Jose Bacelar Almeida Maria Joao Frade Jorge Sousa Pinto Simao Melo de Sousa Rigorous Software Development An Introduction to Program Verification & Springer Contents 1 Introduction 1 1.1 A Formal Approach

More information

A simple algorithm with no simple verication

A simple algorithm with no simple verication A simple algorithm with no simple verication Laszlo Csirmaz Central European University Abstract The correctness of a simple sorting algorithm is resented, which algorithm is \evidently wrong" at the rst

More information

ML for the Working Programmer

ML for the Working Programmer ML for the Working Programmer 2nd edition Lawrence C. Paulson University of Cambridge CAMBRIDGE UNIVERSITY PRESS CONTENTS Preface to the Second Edition Preface xiii xv 1 Standard ML 1 Functional Programming

More information

Automated Theorem Proving - summary of lecture 1

Automated Theorem Proving - summary of lecture 1 Automated Theorem Proving - summary of lecture 1 1 Introduction Automated Theorem Proving (ATP) deals with the development of computer programs that show that some statement is a logical consequence of

More information

Rigorous Software Development CSCI-GA 3033-009

Rigorous Software Development CSCI-GA 3033-009 Rigorous Software Development CSCI-GA 3033-009 Instructor: Thomas Wies Spring 2013 Lecture 11 Semantics of Programming Languages Denotational Semantics Meaning of a program is defined as the mathematical

More information

Java 6 'th. Concepts INTERNATIONAL STUDENT VERSION. edition

Java 6 'th. Concepts INTERNATIONAL STUDENT VERSION. edition Java 6 'th edition Concepts INTERNATIONAL STUDENT VERSION CONTENTS PREFACE vii SPECIAL FEATURES xxviii chapter i INTRODUCTION 1 1.1 What Is Programming? 2 J.2 The Anatomy of a Computer 3 1.3 Translating

More information

[Refer Slide Time: 05:10]

[Refer Slide Time: 05:10] Principles of Programming Languages Prof: S. Arun Kumar Department of Computer Science and Engineering Indian Institute of Technology Delhi Lecture no 7 Lecture Title: Syntactic Classes Welcome to lecture

More information

Verification of Imperative Programs in Theorema

Verification of Imperative Programs in Theorema Verification of Imperative Programs in Theorema Laura Ildikó Kovács, Nikolaj Popov, Tudor Jebelean 1 Research Institute for Symbolic Computation, Johannes Kepler University, A-4040 Linz, Austria Institute

More information

Applications of formal verification for secure Cloud environments at CEA LIST

Applications of formal verification for secure Cloud environments at CEA LIST Applications of formal verification for secure Cloud environments at CEA LIST Nikolai Kosmatov joint work with A.Blanchard, F.Bobot, M.Lemerre,... SEC2, Lille, June 30 th, 2015 N. Kosmatov (CEA LIST) Formal

More information

Computing Concepts with Java Essentials

Computing Concepts with Java Essentials 2008 AGI-Information Management Consultants May be used for personal purporses only or by libraries associated to dandelon.com network. Computing Concepts with Java Essentials 3rd Edition Cay Horstmann

More information

Constructing Contracts: Making Discrete Mathematics Relevant to Beginning Programmers

Constructing Contracts: Making Discrete Mathematics Relevant to Beginning Programmers Constructing Contracts: Making Discrete Mathematics Relevant to Beginning Programmers TIMOTHY S. GEGG-HARRISON Winona State University Although computer scientists understand the importance of discrete

More information

Thomas Jefferson High School for Science and Technology Program of Studies Foundations of Computer Science. Unit of Study / Textbook Correlation

Thomas Jefferson High School for Science and Technology Program of Studies Foundations of Computer Science. Unit of Study / Textbook Correlation Thomas Jefferson High School for Science and Technology Program of Studies Foundations of Computer Science updated 03/08/2012 Unit 1: JKarel 8 weeks http://www.fcps.edu/is/pos/documents/hs/compsci.htm

More information

WESTMORELAND COUNTY PUBLIC SCHOOLS 2011 2012 Integrated Instructional Pacing Guide and Checklist Computer Math

WESTMORELAND COUNTY PUBLIC SCHOOLS 2011 2012 Integrated Instructional Pacing Guide and Checklist Computer Math Textbook Correlation WESTMORELAND COUNTY PUBLIC SCHOOLS 2011 2012 Integrated Instructional Pacing Guide and Checklist Computer Math Following Directions Unit FIRST QUARTER AND SECOND QUARTER Logic Unit

More information

Deductive Program Verification

Deductive Program Verification ORSAY N o d ordre : 1448 UNIVERSITÉ DE PARIS-SUD 11 CENTRE D ORSAY THÈSE présentée pour obtenir L HABILITATION À DIRIGER DES RECHERCHES DE L UNIVERSITÉ PARIS-SUD 11 PAR Jean-Christophe Filliâtre SUJET

More information

PROPERTECHNIQUEOFSOFTWARE INSPECTIONUSING GUARDED COMMANDLANGUAGE

PROPERTECHNIQUEOFSOFTWARE INSPECTIONUSING GUARDED COMMANDLANGUAGE International Journal of Computer ScienceandCommunication Vol. 2, No. 1, January-June2011, pp. 153-157 PROPERTECHNIQUEOFSOFTWARE INSPECTIONUSING GUARDED COMMANDLANGUAGE Neeraj Kumar Singhania University,

More information

Pretty-big-step semantics

Pretty-big-step semantics Pretty-big-step semantics Arthur Charguéraud INRIA October 2012 1 / 34 Motivation Formalization of JavaScript with Sergio Maeis, Daniele Filaretti, Alan Schmitt, Martin Bodin. Previous work: Semi-formal

More information

Regression Verification: Status Report

Regression Verification: Status Report Regression Verification: Status Report Presentation by Dennis Felsing within the Projektgruppe Formale Methoden der Softwareentwicklung 2013-12-11 1/22 Introduction How to prevent regressions in software

More information

Chapter 1: Key Concepts of Programming and Software Engineering

Chapter 1: Key Concepts of Programming and Software Engineering Chapter 1: Key Concepts of Programming and Software Engineering Software Engineering Coding without a solution design increases debugging time - known fact! A team of programmers for a large software development

More information

Chair of Software Engineering. Software Verification. Assertion Inference. Carlo A. Furia

Chair of Software Engineering. Software Verification. Assertion Inference. Carlo A. Furia Chair of Software Engineering Software Verification Assertion Inference Carlo A. Furia Proving Programs Automatically The Program Verification problem: Given: a program P and a specification S = [Pre,

More information

Managing large sound databases using Mpeg7

Managing large sound databases using Mpeg7 Max Jacob 1 1 Institut de Recherche et Coordination Acoustique/Musique (IRCAM), place Igor Stravinsky 1, 75003, Paris, France Correspondence should be addressed to Max Jacob ([email protected]) ABSTRACT

More information

CHAPTER 7 GENERAL PROOF SYSTEMS

CHAPTER 7 GENERAL PROOF SYSTEMS CHAPTER 7 GENERAL PROOF SYSTEMS 1 Introduction Proof systems are built to prove statements. They can be thought as an inference machine with special statements, called provable statements, or sometimes

More information

The countdown problem

The countdown problem JFP 12 (6): 609 616, November 2002. c 2002 Cambridge University Press DOI: 10.1017/S0956796801004300 Printed in the United Kingdom 609 F U N C T I O N A L P E A R L The countdown problem GRAHAM HUTTON

More information

Sources: On the Web: Slides will be available on:

Sources: On the Web: Slides will be available on: C programming Introduction The basics of algorithms Structure of a C code, compilation step Constant, variable type, variable scope Expression and operators: assignment, arithmetic operators, comparison,

More information

Regular Languages and Finite Automata

Regular Languages and Finite Automata Regular Languages and Finite Automata 1 Introduction Hing Leung Department of Computer Science New Mexico State University Sep 16, 2010 In 1943, McCulloch and Pitts [4] published a pioneering work on a

More information

Software Engineering

Software Engineering Software Engineering Lecture 04: The B Specification Method Peter Thiemann University of Freiburg, Germany SS 2013 Peter Thiemann (Univ. Freiburg) Software Engineering SWT 1 / 50 The B specification method

More information

Boogie: A Modular Reusable Verifier for Object-Oriented Programs

Boogie: A Modular Reusable Verifier for Object-Oriented Programs Boogie: A Modular Reusable Verifier for Object-Oriented Programs M. Barnett, B.E. Chang, R. DeLine, B. Jacobs, K.R.M. Leino Lorenzo Baesso ETH Zurich Motivation Abstract Domains Modular Architecture Automatic

More information

Functional Programming. Functional Programming Languages. Chapter 14. Introduction

Functional Programming. Functional Programming Languages. Chapter 14. Introduction Functional Programming Languages Chapter 14 Introduction Functional programming paradigm History Features and concepts Examples: Lisp ML 1 2 Functional Programming Functional Programming Languages The

More information

Language. Johann Eder. Universitat Klagenfurt. Institut fur Informatik. Universiatsstr. 65. A-9020 Klagenfurt / AUSTRIA

Language. Johann Eder. Universitat Klagenfurt. Institut fur Informatik. Universiatsstr. 65. A-9020 Klagenfurt / AUSTRIA PLOP: A Polymorphic Logic Database Programming Language Johann Eder Universitat Klagenfurt Institut fur Informatik Universiatsstr. 65 A-9020 Klagenfurt / AUSTRIA February 12, 1993 Extended Abstract The

More information

COMPUTER SCIENCE TRIPOS

COMPUTER SCIENCE TRIPOS CST.98.5.1 COMPUTER SCIENCE TRIPOS Part IB Wednesday 3 June 1998 1.30 to 4.30 Paper 5 Answer five questions. No more than two questions from any one section are to be answered. Submit the answers in five

More information

Introducing Formal Methods. Software Engineering and Formal Methods

Introducing Formal Methods. Software Engineering and Formal Methods Introducing Formal Methods Formal Methods for Software Specification and Analysis: An Overview 1 Software Engineering and Formal Methods Every Software engineering methodology is based on a recommended

More information

A Framework for the Semantics of Behavioral Contracts

A Framework for the Semantics of Behavioral Contracts A Framework for the Semantics of Behavioral Contracts Ashley McNeile Metamaxim Ltd, 48 Brunswick Gardens, London W8 4AN, UK [email protected] Abstract. Contracts have proved a powerful concept

More information

A Propositional Dynamic Logic for CCS Programs

A Propositional Dynamic Logic for CCS Programs A Propositional Dynamic Logic for CCS Programs Mario R. F. Benevides and L. Menasché Schechter {mario,luis}@cos.ufrj.br Abstract This work presents a Propositional Dynamic Logic in which the programs are

More information

Moving from CS 61A Scheme to CS 61B Java

Moving from CS 61A Scheme to CS 61B Java Moving from CS 61A Scheme to CS 61B Java Introduction Java is an object-oriented language. This document describes some of the differences between object-oriented programming in Scheme (which we hope you

More information

Cedalion A Language Oriented Programming Language (Extended Abstract)

Cedalion A Language Oriented Programming Language (Extended Abstract) Cedalion A Language Oriented Programming Language (Extended Abstract) David H. Lorenz Boaz Rosenan The Open University of Israel Abstract Implementations of language oriented programming (LOP) are typically

More information

Analysis of Algorithms I: Binary Search Trees

Analysis of Algorithms I: Binary Search Trees Analysis of Algorithms I: Binary Search Trees Xi Chen Columbia University Hash table: A data structure that maintains a subset of keys from a universe set U = {0, 1,..., p 1} and supports all three dictionary

More information

Glossary of Object Oriented Terms

Glossary of Object Oriented Terms Appendix E Glossary of Object Oriented Terms abstract class: A class primarily intended to define an instance, but can not be instantiated without additional methods. abstract data type: An abstraction

More information

programming languages, programming language standards and compiler validation

programming languages, programming language standards and compiler validation Software Quality Issues when choosing a Programming Language C.J.Burgess Department of Computer Science, University of Bristol, Bristol, BS8 1TR, England Abstract For high quality software, an important

More information

The following themes form the major topics of this chapter: The terms and concepts related to trees (Section 5.2).

The following themes form the major topics of this chapter: The terms and concepts related to trees (Section 5.2). CHAPTER 5 The Tree Data Model There are many situations in which information has a hierarchical or nested structure like that found in family trees or organization charts. The abstraction that models hierarchical

More information

Specification and Analysis of Contracts Lecture 1 Introduction

Specification and Analysis of Contracts Lecture 1 Introduction Specification and Analysis of Contracts Lecture 1 Introduction Gerardo Schneider [email protected] http://folk.uio.no/gerardo/ Department of Informatics, University of Oslo SEFM School, Oct. 27 - Nov.

More information

Lecture 18-19 Data Types and Types of a Language

Lecture 18-19 Data Types and Types of a Language Lecture 18-19 Data Types and Types of a Language April 29, 2014 Data Types and Types of a Language Data, Data Types and Types Type: Generalities Type Systems and Type Safety Type Equivalence, Coercion

More information

Lecture Notes on Linear Search

Lecture Notes on Linear Search Lecture Notes on Linear Search 15-122: Principles of Imperative Computation Frank Pfenning Lecture 5 January 29, 2013 1 Introduction One of the fundamental and recurring problems in computer science is

More information

Name: Class: Date: 9. The compiler ignores all comments they are there strictly for the convenience of anyone reading the program.

Name: Class: Date: 9. The compiler ignores all comments they are there strictly for the convenience of anyone reading the program. Name: Class: Date: Exam #1 - Prep True/False Indicate whether the statement is true or false. 1. Programming is the process of writing a computer program in a language that the computer can respond to

More information

LEVERAGING DEDUCTIVE VERIFICATION IN INDUSTRIAL CONTEXTS

LEVERAGING DEDUCTIVE VERIFICATION IN INDUSTRIAL CONTEXTS LEVERAGING DEDUCTIVE VERIFICATION IN INDUSTRIAL CONTEXTS CEA S SOFTWARE SAFETY LABORATORY 1995: LEAP FROM DYNAMIC TO STATIC CODE ANALYSIS! CAVEAT: ARCHITECTURE C source code VC Generator Formal specifications

More information

Outline. 1 Denitions. 2 Principles. 4 Implementation and Evaluation. 5 Debugging. 6 References

Outline. 1 Denitions. 2 Principles. 4 Implementation and Evaluation. 5 Debugging. 6 References Outline Computer Science 331 Introduction to Testing of Programs Mike Jacobson Department of Computer Science University of Calgary Lecture #3-4 1 Denitions 2 3 4 Implementation and Evaluation 5 Debugging

More information

Termination Checking: Comparing Structural Recursion and Sized Types by Examples

Termination Checking: Comparing Structural Recursion and Sized Types by Examples Termination Checking: Comparing Structural Recursion and Sized Types by Examples David Thibodeau Decemer 3, 2011 Abstract Termination is an important property for programs and is necessary for formal proofs

More information

PROBLEM SOLVING SEVENTH EDITION WALTER SAVITCH UNIVERSITY OF CALIFORNIA, SAN DIEGO CONTRIBUTOR KENRICK MOCK UNIVERSITY OF ALASKA, ANCHORAGE PEARSON

PROBLEM SOLVING SEVENTH EDITION WALTER SAVITCH UNIVERSITY OF CALIFORNIA, SAN DIEGO CONTRIBUTOR KENRICK MOCK UNIVERSITY OF ALASKA, ANCHORAGE PEARSON PROBLEM SOLVING WITH SEVENTH EDITION WALTER SAVITCH UNIVERSITY OF CALIFORNIA, SAN DIEGO CONTRIBUTOR KENRICK MOCK UNIVERSITY OF ALASKA, ANCHORAGE PEARSON Addison Wesley Boston San Francisco New York London

More information

09336863931 : provid.ir

09336863931 : provid.ir provid.ir 09336863931 : NET Architecture Core CSharp o Variable o Variable Scope o Type Inference o Namespaces o Preprocessor Directives Statements and Flow of Execution o If Statement o Switch Statement

More information

InvGen: An Efficient Invariant Generator

InvGen: An Efficient Invariant Generator InvGen: An Efficient Invariant Generator Ashutosh Gupta and Andrey Rybalchenko Max Planck Institute for Software Systems (MPI-SWS) Abstract. In this paper we present InvGen, an automatic linear arithmetic

More information

Software Verification: Infinite-State Model Checking and Static Program

Software Verification: Infinite-State Model Checking and Static Program Software Verification: Infinite-State Model Checking and Static Program Analysis Dagstuhl Seminar 06081 February 19 24, 2006 Parosh Abdulla 1, Ahmed Bouajjani 2, and Markus Müller-Olm 3 1 Uppsala Universitet,

More information

Automated Program Behavior Analysis

Automated Program Behavior Analysis Automated Program Behavior Analysis Stacy Prowell [email protected] March 2005 SQRL / SEI Motivation: Semantics Development: Most engineering designs are subjected to extensive analysis; software is

More information

Chapter 4 Multi-Stage Interconnection Networks The general concept of the multi-stage interconnection network, together with its routing properties, have been used in the preceding chapter to describe

More information

Types, Polymorphism, and Type Reconstruction

Types, Polymorphism, and Type Reconstruction Types, Polymorphism, and Type Reconstruction Sources This material is based on the following sources: Pierce, B.C., Types and Programming Languages. MIT Press, 2002. Kanellakis, P.C., Mairson, H.G. and

More information

Combinatorial PCPs with ecient veriers

Combinatorial PCPs with ecient veriers Combinatorial PCPs with ecient veriers Or Meir Abstract The PCP theorem asserts the existence of proofs that can be veried by a verier that reads only a very small part of the proof. The theorem was originally

More information

The Classes P and NP

The Classes P and NP The Classes P and NP We now shift gears slightly and restrict our attention to the examination of two families of problems which are very important to computer scientists. These families constitute the

More information

Peter V. Homeier and David F. Martin. [email protected] and [email protected]

Peter V. Homeier and David F. Martin. homeier@cs.ucla.edu and dmartin@cs.ucla.edu A Mechanically Veried Verication Condition Generator Peter V. Homeier and David F. Martin Computer Science Department, University of California, Los Angeles 90024 USA [email protected] and [email protected]

More information

Symbol Tables. Introduction

Symbol Tables. Introduction Symbol Tables Introduction A compiler needs to collect and use information about the names appearing in the source program. This information is entered into a data structure called a symbol table. The

More information

Embedded Systems. Review of ANSI C Topics. A Review of ANSI C and Considerations for Embedded C Programming. Basic features of C

Embedded Systems. Review of ANSI C Topics. A Review of ANSI C and Considerations for Embedded C Programming. Basic features of C Embedded Systems A Review of ANSI C and Considerations for Embedded C Programming Dr. Jeff Jackson Lecture 2-1 Review of ANSI C Topics Basic features of C C fundamentals Basic data types Expressions Selection

More information

Chapter II. Controlling Cars on a Bridge

Chapter II. Controlling Cars on a Bridge Chapter II. Controlling Cars on a Bridge 1 Introduction The intent of this chapter is to introduce a complete example of a small system development. During this development, you will be made aware of the

More information

Verifying security protocols using theorem provers

Verifying security protocols using theorem provers 1562 2007 79-86 79 Verifying security protocols using theorem provers Miki Tanaka National Institute of Information and Communications Technology Koganei, Tokyo 184-8795, Japan Email: [email protected]

More information

Chapter 7: Functional Programming Languages

Chapter 7: Functional Programming Languages Chapter 7: Functional Programming Languages Aarne Ranta Slides for the book Implementing Programming Languages. An Introduction to Compilers and Interpreters, College Publications, 2012. Fun: a language

More information

AP Computer Science AB Syllabus 1

AP Computer Science AB Syllabus 1 AP Computer Science AB Syllabus 1 Course Resources Java Software Solutions for AP Computer Science, J. Lewis, W. Loftus, and C. Cocking, First Edition, 2004, Prentice Hall. Video: Sorting Out Sorting,

More information

Analyse et Conception Formelle. Lesson 5. Crash Course on Scala

Analyse et Conception Formelle. Lesson 5. Crash Course on Scala Analyse et Conception Formelle Lesson 5 Crash Course on Scala T. Genet (ISTIC/IRISA) ACF-5 1 / 36 Bibliography Simply Scala. Online tutorial: http://www.simply.com/fr http://www.simply.com/ Programming

More information

Programming Languages

Programming Languages Programming Languages Qing Yi Course web site: www.cs.utsa.edu/~qingyi/cs3723 cs3723 1 A little about myself Qing Yi Ph.D. Rice University, USA. Assistant Professor, Department of Computer Science Office:

More information

Binary Search Trees CMPSC 122

Binary Search Trees CMPSC 122 Binary Search Trees CMPSC 122 Note: This notes packet has significant overlap with the first set of trees notes I do in CMPSC 360, but goes into much greater depth on turning BSTs into pseudocode than

More information

Boolean Expressions, Conditions, Loops, and Enumerations. Precedence Rules (from highest to lowest priority)

Boolean Expressions, Conditions, Loops, and Enumerations. Precedence Rules (from highest to lowest priority) Boolean Expressions, Conditions, Loops, and Enumerations Relational Operators == // true if two values are equivalent!= // true if two values are not equivalent < // true if left value is less than the

More information

Verication by Finitary Abstraction Weizmann Institute of Sciences and Universite Joseph Fourier, Grenoble Fourth International Spin Workshop (SPIN'98) Paris 2.11.98 Joint work with: Y. Kesten Ben Gurion

More information

KITES TECHNOLOGY COURSE MODULE (C, C++, DS)

KITES TECHNOLOGY COURSE MODULE (C, C++, DS) KITES TECHNOLOGY 360 Degree Solution www.kitestechnology.com/academy.php [email protected] [email protected] Contact: - 8961334776 9433759247 9830639522.NET JAVA WEB DESIGN PHP SQL, PL/SQL

More information

1/1 7/4 2/2 12/7 10/30 12/25

1/1 7/4 2/2 12/7 10/30 12/25 Binary Heaps A binary heap is dened to be a binary tree with a key in each node such that: 1. All leaves are on, at most, two adjacent levels. 2. All leaves on the lowest level occur to the left, and all

More information

CS 2112 Spring 2014. 0 Instructions. Assignment 3 Data Structures and Web Filtering. 0.1 Grading. 0.2 Partners. 0.3 Restrictions

CS 2112 Spring 2014. 0 Instructions. Assignment 3 Data Structures and Web Filtering. 0.1 Grading. 0.2 Partners. 0.3 Restrictions CS 2112 Spring 2014 Assignment 3 Data Structures and Web Filtering Due: March 4, 2014 11:59 PM Implementing spam blacklists and web filters requires matching candidate domain names and URLs very rapidly

More information

Is Sometime Ever Better Than Alway?

Is Sometime Ever Better Than Alway? Is Sometime Ever Better Than Alway? DAVID GRIES Cornell University The "intermittent assertion" method for proving programs correct is explained and compared with the conventional method. Simple conventional

More information

Theory of Automated Reasoning An Introduction. Antti-Juhani Kaijanaho

Theory of Automated Reasoning An Introduction. Antti-Juhani Kaijanaho Theory of Automated Reasoning An Introduction Antti-Juhani Kaijanaho Intended as compulsory reading for the Spring 2004 course on Automated Reasononing at Department of Mathematical Information Technology,

More information

Portable Bushy Processing Trees for Join Queries

Portable Bushy Processing Trees for Join Queries Reihe Informatik 11 / 1996 Constructing Optimal Bushy Processing Trees for Join Queries is NP-hard Wolfgang Scheufele Guido Moerkotte 1 Constructing Optimal Bushy Processing Trees for Join Queries is NP-hard

More information

Semester Review. CSC 301, Fall 2015

Semester Review. CSC 301, Fall 2015 Semester Review CSC 301, Fall 2015 Programming Language Classes There are many different programming language classes, but four classes or paradigms stand out:! Imperative Languages! assignment and iteration!

More information

The Clean programming language. Group 25, Jingui Li, Daren Tuzi

The Clean programming language. Group 25, Jingui Li, Daren Tuzi The Clean programming language Group 25, Jingui Li, Daren Tuzi The Clean programming language Overview The Clean programming language first appeared in 1987 and is still being further developed. It was

More information

Introduction to Programming System Design. CSCI 455x (4 Units)

Introduction to Programming System Design. CSCI 455x (4 Units) Introduction to Programming System Design CSCI 455x (4 Units) Description This course covers programming in Java and C++. Topics include review of basic programming concepts such as control structures,

More information

Topology-based network security

Topology-based network security Topology-based network security Tiit Pikma Supervised by Vitaly Skachek Research Seminar in Cryptography University of Tartu, Spring 2013 1 Introduction In both wired and wireless networks, there is the

More information

MAT-71506 Program Verication: Exercises

MAT-71506 Program Verication: Exercises MAT-71506 Program Verication: Exercises Antero Kangas Tampere University of Technology Department of Mathematics September 11, 2014 Accomplishment Exercises are obligatory and probably the grades will

More information

Analysis of Algorithms I: Optimal Binary Search Trees

Analysis of Algorithms I: Optimal Binary Search Trees Analysis of Algorithms I: Optimal Binary Search Trees Xi Chen Columbia University Given a set of n keys K = {k 1,..., k n } in sorted order: k 1 < k 2 < < k n we wish to build an optimal binary search

More information

Formal Methods for Software Engineering

Formal Methods for Software Engineering Formal Methods for Software Engineering Virendra Singh Computer Design and Test Lab Indian Institute of Science Bangalore Email: [email protected] Introduction Problems in software development Formal

More information

A binary search tree or BST is a binary tree that is either empty or in which the data element of each node has a key, and:

A binary search tree or BST is a binary tree that is either empty or in which the data element of each node has a key, and: Binary Search Trees 1 The general binary tree shown in the previous chapter is not terribly useful in practice. The chief use of binary trees is for providing rapid access to data (indexing, if you will)

More information

Obfuscation: know your enemy

Obfuscation: know your enemy Obfuscation: know your enemy Ninon EYROLLES [email protected] Serge GUELTON [email protected] Prelude Prelude Plan 1 Introduction What is obfuscation? 2 Control flow obfuscation 3 Data flow

More information

Verifying Specifications with Proof Scores in CafeOBJ

Verifying Specifications with Proof Scores in CafeOBJ Verifying Specifications with Proof Scores in CafeOBJ FUTATSUGI, Kokichi 二 木 厚 吉 Chair of Language Design Graduate School of Information Science Japan Advanced Institute of Science and Technology (JAIST)

More information

Lecture 4 Online and streaming algorithms for clustering

Lecture 4 Online and streaming algorithms for clustering CSE 291: Geometric algorithms Spring 2013 Lecture 4 Online and streaming algorithms for clustering 4.1 On-line k-clustering To the extent that clustering takes place in the brain, it happens in an on-line

More information

StaRVOOrS: A Tool for Combined Static and Runtime Verification of Java

StaRVOOrS: A Tool for Combined Static and Runtime Verification of Java StaRVOOrS: A Tool for Combined Static and Runtime Verification of Java Jesús Mauricio Chimento 1, Wolfgang Ahrendt 1, Gordon J. Pace 2, and Gerardo Schneider 3 1 Chalmers University of Technology, Sweden.

More information

Relations: their uses in programming and computational specifications

Relations: their uses in programming and computational specifications PEPS Relations, 15 December 2008 1/27 Relations: their uses in programming and computational specifications Dale Miller INRIA - Saclay & LIX, Ecole Polytechnique 1. Logic and computation Outline 2. Comparing

More information

TECHNOLOGY Computer Programming II Grade: 9-12 Standard 2: Technology and Society Interaction

TECHNOLOGY Computer Programming II Grade: 9-12 Standard 2: Technology and Society Interaction Standard 2: Technology and Society Interaction Technology and Ethics Analyze legal technology issues and formulate solutions and strategies that foster responsible technology usage. 1. Practice responsible

More information

each college c i C has a capacity q i - the maximum number of students it will admit

each college c i C has a capacity q i - the maximum number of students it will admit n colleges in a set C, m applicants in a set A, where m is much larger than n. each college c i C has a capacity q i - the maximum number of students it will admit each college c i has a strict order i

More information

Concepts and terminology in the Simula Programming Language

Concepts and terminology in the Simula Programming Language Concepts and terminology in the Simula Programming Language An introduction for new readers of Simula literature Stein Krogdahl Department of Informatics University of Oslo, Norway April 2010 Introduction

More information

Formal Engineering for Industrial Software Development

Formal Engineering for Industrial Software Development Shaoying Liu Formal Engineering for Industrial Software Development Using the SOFL Method With 90 Figures and 30 Tables Springer Contents Introduction 1 1.1 Software Life Cycle... 2 1.2 The Problem 4 1.3

More information

WHAT ARE MATHEMATICAL PROOFS AND WHY THEY ARE IMPORTANT?

WHAT ARE MATHEMATICAL PROOFS AND WHY THEY ARE IMPORTANT? WHAT ARE MATHEMATICAL PROOFS AND WHY THEY ARE IMPORTANT? introduction Many students seem to have trouble with the notion of a mathematical proof. People that come to a course like Math 216, who certainly

More information