420 likes | 424 Vues
Model Checking Lecture 4. Outline. 1 Specifications: logic vs. automata, linear vs. branching, safety vs. liveness 2 Graph algorithms for model checking Symbolic algorithms for model checking Pushdown systems. Model-checking problem. I |= S. system model: state-transition graph.
E N D
Model Checking Lecture 4
Outline • 1 Specifications: logic vs. automata, linear vs. branching, safety vs. liveness • 2 Graph algorithms for model checking • Symbolic algorithms for model checking • Pushdown systems
Model-checking problem I|=S system model: state-transition graph system property: -safety v. weak v. strong fairness -logic v. spec v. monitor automata -linear v. branching
Graph Algorithms Given: labeled graph (Q, , A, [ ] ) Cost: each node access and edge access has unit cost Complexity: in terms of |Q| = n ... number of nodes || = m ... number of edges Reachability and s.c.c.s: O(m+n)
The Graph-Algorithmic View is Problematic -The graph is given implicitly (by a program) not explicitly (e.g., by adjacency lists). -Building an explicit graph representation is exponential, but usually unnecessary (“on-the-fly” algorithms). -The explicit graph representation may be so big, that the “unit-cost model” is not realistic. -A class of algorithms, called “symbolic algorithms”, do not operate on nodes and edges at all.
Symbolic Model-Checking Algorithms Given: a “symbolic theory”, that is, an abstract data type called region with the following operations: pre, pre, post, post : region region , , \ : region region region , = : region region bool < >, > < : A region , Q : region
Intended Meaning of Symbolic Theories region ... set of states , , \, , =, ... set operations <a> = { q Q | [q] = a } >a< = { q Q | [q] a } pre (R) = { q Q | ( r R) q r } pre (R) = { q Q | ( r)( q r r R )} post (R) = { q Q | ( r R) r q } post (R) = { q Q | ( r)( r q r R )}
If the state of a system is given by variables of type Vals, and the transitions of the system can be described by operations Ops on Vals, then the first-order theoryFO(Vals, Ops) is an adequate symbolic theory: region ... formula of FO (Vals, Ops) , , \, , =, , Q ... , , , , , f, t pre (R(X)) = ( X’)( Trans(X,X’) R(X’) ) pre (R(X)) = ( X’)( Trans(X,X’) R(X’) ) post (R(X)) = ( X”)( R(X”) Trans(X”,X) ) post (R(X)) = ( X”)( Trans(X”,X) R(X’’) )
If FO (Vals, Ops) admits quantifier elimination, then the propositional theory ZO (Vals, Ops) is an adequate symbolic theory: each pre/post operation is a quantifier elimination
Example: Boolean Systems -all system variables X are boolean -region: quantifier-free boolean formula over X -pre, post: boolean quantifier elimination Complexity: PSPACE
Example: Presburger Systems -all system variables X are integers -the transition relation Trans(X,X’) is defined using only and -region: quantifier-free formula of (Z, , ) -pre, post: quantifier elimination
An iterative language for writing symbolic model-checking algorithms -only data type is region -expressions: pre, post, , , \ , , =, < >, , Q -assignment, sequencing, while-do, if-then-else
Example: Reachability a S := R := <a> while R S do S := S R R := pre(R)
A recursive language for writing symbolic model-checking algorithms: The Mu-Calculus a = ( R) (a pre(R)) a = ( R) (a pre(R))
Syntax of the Mu-Calculus • ::= a | a | | | pre() | pre() | (R) | (R) | R pre = pre = R ... region variable
Semantics of the Mu-Calculus [[ a ]]E := <a> [[ a ]]E := >a< [[ ]]E := [[ ]]E [[ ]]E [[ ]]E := [[ ]]E [[ ]]E [[ pre() ]]E := pre( [[ ]]E ) [[ pre() ]]E:= pre( [[ ]]E ) E maps each region variable to a region.
Operational Semantics of the Mu-Calculus [[ (R) ]]E := S’ := ; repeat S := S’; S’ := [[]]E(RS) until S’=S; return S [[ (R) ]]E := S’ := Q; repeat S := S’; S’ := [[]]E(RS) until S’=S; return S
Denotational Semantics of the Mu-Calculus [[ (R) ]]E := smallest region S such that S = [[]]E(RS) [[ (R) ]]E := largest region S such that S = [[]]E(RS) These regions are unique because all operators on regions (, , pre, pre) are monotonic.
a = ( R) (a pre(R)) a = ( R) (a pre(R)) a = ( R) (a pre(R)) a = ( R) (a pre(R)) b U a = ( R) (a (b pre(R))) a = ( R) (a pre(R)) = ( R) ( S) ((a pre(R)) pre(S))
-every / alternation adds expressiveness -all omega-regular languages in alternation depth 2 -model checking complexity: O( (|| (m+n)) d ) for formulas of alternation depth d -most common implementation (SMV, Mocha): use BDDs to represent boolean regions
Binary Decision Diagrams -canonical data structure for representing quantifier-free boolean formulas -equivalence checking in constant time -in practice, model checkers spend more than 90% of their time in “pre-image” or “post-image” computation -almost synonymous with “symbolic” model checking -SAT solvers superior in bounded model checking, which requires no termination (i.e., equivalence) check
Binary Decision Tree -order k boolean variables x1, ..., xk -binary tree of height k+1, each leaf labeled 0 or 1 -leaf of path “left, right, right, ...” gives value of boolean formula if x1=0, x2=1, x3=1, etc.
Vertex represents decision Follow green (dashed) line for value 0 Follow red (solid) line for value 1 Function value determined by leaf value Along each path, variables occur in the variable order Along each path, a variable occurs exactly once Truth Table Decision Tree
(Reduced Ordered) Binary Decision Diagram • Identify isomorphic subtrees (this gives a dag) • Eliminate nodes with identical left and right successors • Eliminate redundant tests For a given boolean formula and variable order, the result is unique. (The choice of variable order may make an exponential difference!)
a a a Reduction rule #1 Merge equivalent leaves
x x x x x x y z y z y z Reduction rule #2 Merge isomorphic nodes
x y y Reduction rule #3 Eliminate redundant tests
Initial graph Reduced graph (x1 x2) x3 • Canonical representation of Boolean function • For given variable ordering, two functions equivalent if and only if their graphs are isomorphic • Test in linear time
Constants Variable Unique unsatisfiable function Treat variable as function Unique tautology Typical function Odd parity • (x1 x2) x3 • No vertex labeledx3 • independent ofx3 • Many subgraphs shared Linear representation Examples
Linear growth Exponential growth Effect of variable ordering (a1 b1) (a2 b2) (a3 b3) Good ordering Bad ordering
Operation Read inputs in sequence; produce 0 or 1 as function value. Store information about previous inputs to correctly deduce function value from remaining inputs. Relation to BDD Size Processor requires K bits of memory at step i. BDD has ~2K branches crossing level i. Bit-serial computer analogy
K = 2 K = n (a1 b1) (a2 b2) (a3 b3) Good ordering Bad ordering
Dynamic variable reordering • Invented by Richard Rudell, Synopsys • Periodically attempt to improve ordering for all BDDs • Part of garbage collection • Move each variable through ordering to find its best location • Has proved very successful
• • • • • • • • • • • • Lower bound for multiplication (Bryant 1991) • Integer multiplier circuit • n-bit input words A and B • 2n-bit output word P • Boolean function • Middle bit (n-1) of product • Complexity • Exponential BDD for all possible variable orderings bn-1 p2n-1 Multn Intractable Function b0 pn an-1 pn-1 a0 p0 Actual Numbers • 40,563,945 BDD nodes to represent all outputs of 16-bit multiplier • Grows 2.86x per bit of word size
BDD operations , , , , BDD node n.var = x n.false = a n.true = b n x a b - BDD manager maintains a directed acyclic graph of BDD nodes - ite(x,a,b) returns a node with variable x, left child a, and right child b.
and(a,b) if (a = false b = false) return false if (a = true) return b if (b = true) return a if (a = b) return a if (a.var < b.var) return ite(a.var, and(a.false,b), and(a.true,b)) if (b.var < a.var) return ite(b.var, and(a,b.false), and(a,b.true)) // a.var = b.var return ite(a.var, and(a.false,b.false), and(a.true,b.true)) Complexity: O(|a| |b|)
not(a) if (a = true) return false if (a = false) return true return ite(a.var, not(a.false), not(a.true)) Complexity: O(|a|)
cofactor(a,x,b) if (x < a.var) return a if (x > a.var) return ite(a.var, cofactor(a.false,x,b), cofactor(a.true,x,b)) // x = a.var if (b) return a.true else return a.false Complexity: O(|a|)
Derived operations Operations returning BDD: or(a,b) not(and(not(a),not(b))) exists(a,x) or(cofactor(a,x,false), cofactor(a,x,true)) forall(a,x) and(cofactor(a,x,false), cofactor(a,x,true)) Operations returning boolean: implies(a,b) (or(not(a),b) = true) iff(a,b) (a = b)
substitute(a,x,y) Assumptions - a is independent of y - x and y are adjacent in variable order if (a = true a = false) return a if (a.var > x) return a if (a.var < x) return ite(a.var, substitute(a.false,x,y), substitute(a.true,x,y)) if (a.var = x) return ite(y,a.false,a.true)
Symbolic reachability analysis with BDDs Vector of state variables: X = (x1,…,xn) Init predicate: I(X) Transition relation: T(X,X’) Error predicate: E(X) Invariant: For each xi, xi and xi’ are adjacent in variable order R(X) = I(X) do { S(X) = R(X) R(X’) = exists(and(S(X),T(X,X’)), X) R(X) = substitute(R(X’),X’,X) R(X) = or(R(X),S(X)) } while (R S)