CS 267: Automated Verification Lectures 14: Predicate Abstraction, Counter- Example Guided Abstraction Refinement, Abstract Interpretation Instructor:

Slides:



Advertisements
Similar presentations
Advanced programming tools at Microsoft
Advertisements

The SLAM Project: Debugging System Software via Static Analysis
Automated Theorem Proving Lecture 1. Program verification is undecidable! Given program P and specification S, does P satisfy S?
Modeling issues Book: chapters 4.12, 5.4, 8.4, 10.1.
Abstraction of Source Code (from Bandera lectures and talks)
CS 267: Automated Verification Lecture 2: Linear vs. Branching time. Temporal Logics: CTL, CTL*. CTL model checking algorithm. Counter-example generation.
CS 267: Automated Verification Lecture 8: Automata Theoretic Model Checking Instructor: Tevfik Bultan.
Partial Order Reduction: Main Idea
Verification of Evolving Software Natasha Sharygina Joint work with Sagar Chaki and Nishant Sinha Carnegie Mellon University.
Automatic Verification Book: Chapter 6. What is verification? Traditionally, verification means proof of correctness automatic: model checking deductive:
Abstraction and Modular Reasoning for the Verification of Software Corina Pasareanu NASA Ames Research Center.
Rigorous Software Development CSCI-GA Instructor: Thomas Wies Spring 2012 Lecture 11.
Rigorous Software Development CSCI-GA Instructor: Thomas Wies Spring 2012 Lecture 13.
CS 267: Automated Verification Lecture 10: Nested Depth First Search, Counter- Example Generation Revisited, Bit-State Hashing, On-The-Fly Model Checking.
1 Temporal Claims A temporal claim is defined in Promela by the syntax: never { … body … } never is a keyword, like proctype. The body is the same as for.
A survey of techniques for precise program slicing Komondoor V. Raghavan Indian Institute of Science, Bangalore.
Chair of Software Engineering Software Verification Stephan van Staden Lecture 10: Model Checking.
Automatic Predicate Abstraction of C-Programs T. Ball, R. Majumdar T. Millstein, S. Rajamani.
Thomas Ball, Rupak Majumdar, Todd Millstein, Sriram K. Rajamani Presented by Yifan Li November 22nd In PLDI 01: Programming Language.
CIS 540 Principles of Embedded Computation Spring Instructor: Rajeev Alur
Verification of parameterised systems
SAT and Model Checking. Bounded Model Checking (BMC) A.I. Planning problems: can we reach a desired state in k steps? Verification of safety properties:
Software Verification via Refinement Checking Sagar Chaki, Edmund Clarke, Alex Groce, CMU Somesh Jha, Wisconsin.
Using Statically Computed Invariants Inside the Predicate Abstraction and Refinement Loop Himanshu Jain Franjo Ivančić Aarti Gupta Ilya Shlyakhter Chao.
1 Basic abstract interpretation theory. 2 The general idea §a semantics l any definition style, from a denotational definition to a detailed interpreter.
1 Model Checking, Abstraction- Refinement, and Their Implementation Based on slides by: Orna Grumberg Presented by: Yael Meller June 2008.
Abstractions. Outline Informal intuition Why do we need abstraction? What is an abstraction and what is not an abstraction A framework for abstractions.
Synergy: A New Algorithm for Property Checking
Automatically Validating Temporal Safety Properties of Interfaces Thomas Ball and Sriram K. Rajamani Software Productivity Tools, Microsoft Research Presented.
Predicate Abstraction for Software and Hardware Verification Himanshu Jain Model checking seminar April 22, 2005.
Finding the Weakest Characterization of Erroneous Inputs Dzintars Avots and Benjamin Livshits.
Review: forward E { P } { P && E } TF { P && ! E } { P 1 } { P 2 } { P 1 || P 2 } x = E { P } { \exists … }
CS 267: Automated Verification Lecture 13: Bounded Model Checking Instructor: Tevfik Bultan.
Automated Tools for Software Reliability Suhabe Bugrara Stanford University.
272: Software Engineering Fall 2012 Instructor: Tevfik Bultan Lecture 4: SMT-based Bounded Model Checking of Concurrent Software.
By: Pashootan Vaezipoor Path Invariant Simon Fraser University – Spring 09.
Program Analysis and Verification Spring 2015 Program Analysis and Verification Lecture 2: Operational Semantics I Roman Manevich Ben-Gurion University.
272: Software Engineering Fall 2012 Instructor: Tevfik Bultan Lecture 3: Modular Verification with Magic, Predicate Abstraction.
Rule Checking SLAM Checking Temporal Properties of Software with Boolean Programs Thomas Ball, Sriram K. Rajamani Microsoft Research Presented by Okan.
Aditya V. Nori, Sriram K. Rajamani Microsoft Research India.
CIS 842: Specification and Verification of Reactive Systems Lecture Specifications: LTL Model Checking Copyright , Matt Dwyer, John Hatcliff,
Newton: A tool for generating abstract explanations of infeasibility1 The Problem P (C Program) BP (Boolean Program of P) CFG(P) CFG(BP)
1 Bisimulations as a Technique for State Space Reductions.
Reasoning about programs March CSE 403, Winter 2011, Brun.
Program Analysis and Verification Spring 2014 Program Analysis and Verification Lecture 4: Axiomatic Semantics I Roman Manevich Ben-Gurion University.
Automatically Validating Temporal Safety Properties of Interfaces Thomas Ball, Sriram K. MSR Presented by Xin Li.
Symbolic Execution with Abstract Subsumption Checking Saswat Anand College of Computing, Georgia Institute of Technology Corina Păsăreanu QSS, NASA Ames.
The Yogi Project Software property checking via static analysis and testing Aditya V. Nori, Sriram K. Rajamani, Sai Deep Tetali, Aditya V. Thakur Microsoft.
This Week Lecture on relational semantics Exercises on logic and relations Labs on using Isabelle to do proofs.
Synergy: A New Algorithm for Property Checking Bhargav S. Gulavani (IIT Bombay)‏ Yamini Kannan (Microsoft Research India)‏ Thomas A. Henzinger (EPFL)‏
1 Automatically Validating Temporal Safety Properties of Interfaces - Overview of SLAM Parts of the slides are from
A Tutorial on Automated Verification Tevfik Bultan.
CS357 Lecture 13: Symbolic model checking without BDDs Alex Aiken David Dill 1.
/ PSWLAB Thread Modular Model Checking by Cormac Flanagan and Shaz Qadeer (published in Spin’03) Hong,Shin Thread Modular Model.
Counter Example Guided Refinement CEGAR Mooly Sagiv.
Boolean Programs: A Model and Process For Software Analysis By Thomas Ball and Sriram K. Rajamani Microsoft technical paper MSR-TR Presented by.
24 September 2002© Willem Visser Program Model Checking Enabling Technology Abstraction void add(Object o) { buffer[head] = o; head = (head+1)%size;
CIS 540 Principles of Embedded Computation Spring Instructor: Rajeev Alur
Abstraction and Abstract Interpretation. Abstraction (a simplified view) Abstraction is an effective tool in verification Given a transition system, we.
Presentation Title 2/4/2018 Software Verification using Predicate Abstraction and Iterative Refinement: Part Bug Catching: Automated Program Verification.
Formal methods: Lecture
Reasoning About Code.
Reasoning about code CSE 331 University of Washington.
Symbolic Implementation of the Best Transformer
CSCI1600: Embedded and Real Time Software
Over-Approximating Boolean Programs with Unbounded Thread Creation
CSCI1600: Embedded and Real Time Software
Predicate Abstraction
Course: CS60030 Formal Systems
Presentation transcript:

CS 267: Automated Verification Lectures 14: Predicate Abstraction, Counter- Example Guided Abstraction Refinement, Abstract Interpretation Instructor: Tevfik Bultan

Model Checking Programs Using Abstraction Program model checking tools generally rely on automated abstraction techniques to reduce the state space of the system such as: –Abstract interpretation –Predicate abstraction If the abstraction is conservative, then, if there is no error in the abstracted program, we can conclude that there is no error in the original program In general the problem is to construct a finite state model from the program such that the errors or absence of errors can be demonstrated on the finite state model –Model extraction problem

Model Checking Programs via Abstraction Bandera –A tool for extracting finite state models from programs –Uses various abstract domains to map the state space of the program to a finite set of states via abstraction SLAM project at Microsoft Research –Symbolic model checking for C programs –Can handle unbounded recursion but does not handle concurrency –Uses predicate abstraction, counter-example guided abstraction refinement and BDDs

Abstraction (A simplified view) Abstraction is an effective tool in verification Given a transition system, we want to generate an abstract transition system which is easier to analyze However, we want to make sure that –If a property holds in the abstract transition system, it also holds in the original (concrete) transition system

Abstraction (A simplified view) How do we generate an abstract transition system? Merge states in the concrete transition system (based on some criteria) –This reduces the number of states, so it should be easier to do verification Do not eliminate transitions –This will make sure that the paths in the abstract transition system subsume the paths in the concrete transition system

Abstraction (A simplified view) For every path in the concrete transition system, there is an equivalent path in the abstract transition system –If no path in the abstract transition system violate a property, then no path in the concrete system can violate the property Using this reasoning we can verify ACTL, LTL and ACTL* properties in the abstract transition system –If the property holds on the abstract transition system, we are sure that the property holds in the concrete transition system –If the property does not hold in the abstract transition system, then we are not sure if the property holds or not in the concrete transition system

Abstraction (A simplified view) If the property does not hold in the abstract transition system, what can we do? We can refine the abstract transition system (split some states that we merged) We have to make sure that the refined transition system is still an abstraction of the concrete transition system Then, we can recheck the property again on the refined transition system –If the property does not hold again, we can refine again

Abstraction and Simulation Given two transition systems T 1 = (S 1, I 1, R 1 ) with labeling function L 1 and atomic proposition set AP 1 T 2 = (S 2, I 2, R 2 ) with labeling function L 2 and atomic proposition set AP 2 We call H  (S 1, S 2 ) a simulation relation if, for any (s 1, s 2 )  H –L(s 1 )  AP 2 = L(s 2 ) –For every state s 1 ’ such that (s 1, s 1 ’)  R 1 there exists a state s 2 ’ such that (s 2, s 2 ’)  R 2 and (s 1 ’, s 2 ’)  H We say that T 2 simulates T 1 if there exists a simulation relation H such that for each s 1  I 1, there exists a s 2  I 2 such that (s 1, s 2 )  H.

Abstraction and Simulation If T 2 simulates T 1 then for every ACTL* formula f, T 2 |= f implies T 1 |= f We can define simulation relations between abstract and concrete transition systems such that –the abstract system simulates the concrete system Hence when we verify a property in the abstract transition system we know that it also holds for the concrete transition system

Predicate Abstraction An automated abstraction technique which can be used to reduce the state space of a program The basic idea in predicate abstraction is to remove some variables from the program by just keeping information about a set of predicates about them For example a predicate such as x = y maybe the only information necessary about variables x and y to determine the behavior of the program –In that case we can just store a boolean variable which corresponds to the predicate x = y and remove variables x and y from the program –Predicate abstraction is a technique for doing such abstractions automatically

Predicate Abstraction Given a program and a set of predicates, predicate abstraction abstracts the program so that only the information about the given predicates are preserved The abstracted program adds nondeterminism since in some cases it may not be possible to figure out what the next value of a predicate will be based on the predicates in the given set One needs an automated theorem prover to compute the abstraction

Predicate Abstraction, A Very Simple Example Assume that we have two integer variables x,y We want to abstract the program using a single predicate “x=y” We will divide the states of the program to two: 1.The states where “x=y” is true 2.The states where “x=y” is false, i.e., “x  y” We will then merge all the states in the same set –This is an abstraction –Basically, we forget everything except the value of the predicate “x=y”

Predicate Abstraction, A Very Simple Example We will represent the predicate “x=y” as the boolean variable B in the abstract program –“B=true” will mean “x=y” and –“B=false” will mean “x  y” Assume that we want to abstract the following program which contains only one statement: y := y+1

Predicate Abstraction, Step 1 Calculate preconditions based on the predicate y := y + 1 {x = y} y := y + 1 {x  y} {x  y + 1} {x = y + 1} precondition for B being false after executing the statement y:=y+1 precondition for B being true after executing the statement y:=y+1 Using our temporal logic notation we can say something like: {x=y+1}  AX{x=y} Again, using our temporal logic notation: {x≠y+1}  AX{x≠y}

Predicate Abstraction, Step 2 Use decision procedures to determine if the predicates used for abstraction imply any of the preconditions x = y  x = y + 1 ? No x  y  x = y + 1 ? No x = y  x  y + 1 ? Yes x  y  x  y + 1 ? No

Predicate Abstraction, Step 3 Generate abstract code IF B THEN B := false ELSE B := true | false y := y + 1 Predicate abstraction wrt the predicate “x=y” y := y + 1 {x = y} y := y + 1 {x  y} {x  y + 1} {x = y + 1} 1) Compute preconditions x = y  x = y + 1 ? No x  y  x = y + 1 ? No x = y  x  y + 1 ? Yes x  y  x  y + 1 ? No 2) Check implications 3) Generate abstract code

Model Checking Push-down Automata A class of infinite state systems for which model checking is decidable Push-down automata: Finite state control + one stack LTL model checking for push-down automata is decidable This may sound like a theoretical result but it is the basis of the approach used in SLAM toolkit for model checking C programs –A program with finite data domains which uses recursion can be modeled as a pushdown automaton –A Boolean program generated by predicate abstraction can be represented as a pushdown automaton

Predicate Abstraction + Model Checking Push Down Automata Predicate abstraction combined with results on model checking pushdown automata led to some promising tools –SLAM project at Microsoft Research for verification of C programs –This tool is being used to verify device drivers at Microsoft The main idea: –Use predicate abstraction to obtain finite state abstractions of a program –A program with finite data domains and recursion can be modeled as a pushdown automaton –Use results on model checking push-down automata to verify the abstracted (recursive) program

SLAM Toolkit SLAM toolkit was developed to find errors in windows device drivers –Examples in my slides are from the following paper: “The SLAM Toolkit”, Thomas Ball and Sriram K. Rajamani, CAV 2001 Windows device drivers are required to interact with the windows kernel according to certain interface rules SLAM toolkit has an interface specification language called SLIC (Specification Language for Interface Checking) which is used for writing these interface rules The SLAM toolkit instruments the driver code with assertions based on these interface rules

A SLIC Specification for a Lock This specification states that KeAcquireSpinLock has to be called before KeReleaseSpinLock is called, and KeAcquireSpinLock cannot be called back to back before a KeReleaseSpinLock is called, and vice versa state { enum { Unlocked=0, Locked=1 } state = Unlocked; } KeAcquireSpinLock.return { if (state == Locked) abort; else state = Locked; } KeReleaseSpinLock.return { if (state == Unlocked) abort; else state = Unlocked; } SLIC specification:

A SLIC Specification for a Lock state { enum { Unlocked=0, Locked=1 } state = Unlocked; } KeAcquireSpinLock.return { if (state == Locked) abort; else state = Locked; } KeReleaseSpinLock.return { if (state == Unlocked) abort; else state = Unlocked; } enum { Unlocked=0, Locked=1 } state = Unlocked; void slic_abort() { SLIC_ERROR: ; } void KeAcquireSpinLock_return() { if (state == Locked) slic_abort(); else state = Locked; } void KeReleaseSpinLock_return { if (state == Unlocked) slic_abort(); else state = Unlocked; } SLIC specification: Generated C Code:

An Example void example() { do { KeAcquireSpinLock(); nPacketsOld = nPackets; req = devExt->WLHV; if(req && req->status){ devExt->WLHV = req->Next; KeReleaseSpinLock(); irp = req->irp; if(req->status > 0){ irp->IoS.Status = SUCCESS; irp->IoS.Info = req->Status; } else { irp->IoS.Status = FAIL; irp->IoS.Info = req->Status; } SmartDevFreeBlock(req); IoCompleteRequest(irp); nPackets++; } } while(nPackets!=nPacketsOld); KeReleaseSpinLock(); } void example() { do { KeAcquireSpinLock(); A: KeAcquireSpinLock_return(); nPacketsOld = nPackets; req = devExt->WLHV; if(req && req->status){ devExt->WLHV = req->Next; KeReleaseSpinLock(); B: KeReleaseSpinLock_return(); irp = req->irp; if(req->status > 0){ irp->IoS.Status = SUCCESS; irp->IoS.Info = req->Status; } else { irp->IoS.Status = FAIL; irp->IoS.Info = req->Status; } SmartDevFreeBlock(req); IoCompleteRequest(irp); nPackets++; } } while(nPackets!=nPacketsOld); KeReleaseSpinLock(); C: KeReleaseSpinLock_return(); } Instrumented code

Boolean Programs After instrumenting the code, the SLAM toolkit converts the instrumented C program to a Boolean program using predicate abstraction The Boolean program consists of only Boolean variables –The Boolean variables in the Boolean program are the predicates that are used during predicate abstraction The Boolean program can have unbounded recursion

Boolean Programs decl {state==Locked}, {state==Unlocked} := F,T; void slic_abort() begin SLIC_ERROR: skip; end void KeAcquireSpinLock_return() begin if ({state==Locked}) slic_abort(); else {state==Locked}, {state==Unlocked} := T,F; end void KeReleaseSpinLock_return() begin if ({state == Unlocked}) slic_abort(); else {state==Locked}, {state==Unlocked} := F,T; end enum { Unlocked=0, Locked=1 } state = Unlocked; void slic_abort() { SLIC_ERROR: ; } void KeAcquireSpinLock_return() { if (state == Locked) slic_abort(); else state = Locked; } void KeReleaseSpinLock_return { if (state == Unlocked) slic_abort(); else state = Unlocked; } C Code: Boolean Program:

void example() { do { KeAcquireSpinLock(); A: KeAcquireSpinLock_return(); nPacketsOld = nPackets; req = devExt->WLHV; if(req && req->status){ devExt->WLHV = req->Next; KeReleaseSpinLock(); B: KeReleaseSpinLock_return(); irp = req->irp; if(req->status > 0){ irp->IoS.Status = SUCCESS; irp->IoS.Info = req->Status; } else { irp->IoS.Status = FAIL; irp->IoS.Info = req->Status; } SmartDevFreeBlock(req); IoCompleteRequest(irp); nPackets++; } } while(nPackets!=nPacketsOld); KeReleaseSpinLock(); C: KeReleaseSpinLock_return(); } void example() begin do skip; A: KeAcquireSpinLock_return(); skip; if (*) then skip; B: KeReleaseSpinLock_return(); skip; if (*) then skip; else skip; fi skip; fi while (*); skip; C: KeReleaseSpinLock_return(); end C Code: Boolean Program:

Abstraction Preserves Correctness The Boolean program that is generated with predicate abstraction is non-deterministic. –Non-determinism is used to handle the cases where the predicates used during predicate abstraction are not sufficient enough to determine which branch will be taken If we find no error in the generated abstract Boolean program then we are sure that there are no errors in the original program –The abstract Boolean program allows more behaviors than the original program due to non-determinism. –Hence, if the abstract Boolean program is correct then the original program is also correct.

Counter-Example Guided Abstraction Refinement However, if we find an error in the abstract Boolean program this does not mean that the original program is incorrect. –The erroneous behavior in the abstract Boolean program could be an infeasible execution path that is caused by the non-determinism introduced during abstraction. Counter-example guided abstraction refinement is a technique used to iteratively refine the abstract program in order to remove the spurious counter-example traces

Counter-Example Guided Abstraction Refinement The basic idea in counter-example guided abstraction refinement is the following: First look for an error in the abstract program (if there are no errors, we can terminate since we know that the original program is correct) If there is an error in the abstract program, generate a counter-example path on the abstract program Check if the generated counter-example path is feasible using a theorem prover. If the generated path is infeasible add the predicate from the branch condition where an infeasible choice is made to the predicate set and generate a new abstract program.

Counter-Example Guided Abstraction Refinement void example() begin do skip; A: KeAcquireSpinLock_return(); skip; if (*) then skip; B: KeReleaseSpinLock_return(); skip; if (*) then skip; else skip; fi skip; fi while (*); skip; C: KeReleaseSpinLock_return(); end Boolean Program: Refined Boolean Program: void example() begin do skip; A: KeAcquireSpinLock_return(); b := T; if (*) then skip; B: KeReleaseSpinLock_return(); skip; if (*) then skip; else skip; fi b := b ? F : *; fi while (!b); skip; C: KeReleaseSpinLock_return(); end (using the predicate (nPackets = npacketsOld)) the boolean variable b represents the predicate (nPackets = npacketsOld)

Counter-Example Guided Abstraction Refinement Using counter-example guided abstraction refinement we are iteratively creating more an more refined abstractions This iterative abstraction refinement loop is not guaranteed to converge for infinite domains –This is not surprising since automated verification for infinite domains is undecidable in general The challenge in this approach is automatically choosing the right set of predicates for abstraction refinement –This is similar to finding a loop invariant that is strong enough to prove the property of interest

Abstract Interpretation Abstract interpretation provides a general framework for defining abstractions Different abstract domains can be combined using abstract interpretation framework Abstract interpretation framework also provides techniques such as widening for computing approximations of fixpoints

Abstract Interpretation Example Assume that we have a program with some integer variables We want to figure out possible values these variables can take at a certain point in the program –The results will be a set of integer values for each variable (i.e., the result for each variable will be a member of 2 Z where Z is the set of integers) An easy answer would be to return Z for all the variables –I.e., say that each variable can possibly take any value –This is not a very precise and helpful answer The smaller the sets in our answer, the more precise our answer is –Of course we are not allowed to give a wrong answer by omitting a value that a variable can take!

Abstract Interpretation Example Assume that we have two integer variables x and y The answer we return should be something like –x  {1, 2, 3, 4} –y  {n | n > 5} the variables x and y should not take any value outside of these sets for any execution of the program Unfortunately if we use 2 Z and develop a static analysis to solve this problem the fixpoint computations will not converge since 2 Z an infinite lattice –Use abstraction!

Abstract Interpretation Example Define an abstract domain for integers –For example: 2 {neg, zero, pos} Define abstraction and concretization functions between the integer domain and this abstract domain Interpret integer expressions in the abstract domain The abstract domain 2 {neg, zero, pos} corresponds to a finite lattice, so the fixpoint computations will converge if (y == 0) { x = 2; y = x; } if (y == {zero}) { x = {pos}; y = x; }

Abstract Interpretation In abstract interpretation framework: We define an abstraction function from the concrete domain to the abstract domain –  : Concrete  Abstract We define a concretization function from the abstract domain to the concrete domain –  : Abstract  Concrete

Abstract Interpretation Example Concrete domain: 2 Z (sets of integers) Abstract domain: 2 {neg, zero, pos} Abstraction function  : 2 Z  2 {neg, zero, pos} –  (c) = a such that (  n  c, n = 0  zero  a)  (  n  c, n > 0  pos  a)  (  n  c, n < 0  neg  a) Concretization function  : 2 {neg, zero, pos}  2 Z –  (a) = c such that (zero  a  0  c)  (pos  a  {n | n>0}  c)  (neg  a  {n | n<0}  c)

Precision Ordering Both for the concrete and abstract domains we can define a partial ordering which denotes their precision For both the concrete domain 2 Z and the abstract domain 2 {neg, zero, pos} the precision ordering is  –a  b means that a is more precise than b ( ,  ) is called a Galois connection if and only if  (a)  b  a   (b)

Abstract Interpretation Abstract DomainConcrete Domain a  (a) b  (b) 

Predicate Abstraction as Abstract Interpretation S: set of states of the transition system Concrete lattice: 2 S p 1, p 2, …, p k set of predicates used for predicate abstraction b 1, b 2, …, b k boolean variables representing the predicates Abstract lattice: BF, Boolean formulas over b 1, b 2, …, b k Concretization function  : BF  2 S –  (F) = F[b 1 /p 1, b 2 /p 2, …, b k /p k ] Abstraction function  : 2 S  BF –  (Q) =  {F | Q   (F)}