Post on 05-Jan-2016
Lectures on Model Checking
Stolen from lectures of
Tom Henzinger - EE219C (CS294)
A specific model-checking problem is defined by
I |= S
“implementation” (system model)
“specification” (system property)
“satisfies”, “implements”, “refines” (satisfaction relation)
more detailed
more abstract
Model-checking problem
I |= S
system model system property
satisfaction relation
While the choice of system model is important for ease of modeling in a given situation,
the only thing that is important for model checking is that the system model can be translated into some form of state-transition graph.
State-transition graph
Q set of states {q1,q2,q3}
A set of atomic observations {a,b,c,d}
Q Q transition relation q1 q2
[ ]: Q 2A observation function [q1] = {a, b}
set of observations
a
a,b b
q1
q3q2
State-transition graph
The translation from a system description to a state-transition graph usually involves an exponential blow-up !!!
e.g., n boolean variables 2n states
“state-explosion problem.”
State-transition graphs are not necessarily finite-state, but if not, they are not easy to deal with.
Model-checking problem
I |= S
system model system property
satisfaction relation
Three important decisions when choosing system properties:
1 operational vs. declarative: automata vs. logic
2 may vs. must: branching vs. linear time
3 prohibiting bad vs. desiring good behavior: safety vs. liveness
The three decisions are orthogonal, and they lead to substantially different model-checking problems.
Safety vs. liveness
Safety: something “bad” will never happen
Liveness: something “good” will happen (but we don’t know when)
Safety vs. liveness for state-transition graphs
Safety: those properties whose violation always has a finite witness
(“if something bad happens on an infinite run, then it happens already on some finite prefix”)
Liveness: those properties whose violation never has a finite witness (“no matter what happens along a finite run, something good could still happen later”)
We can have an infinite witness by a trace that has a loop
a
a,b b
q1
q3q2
Run: q1 q3 q1 q3 q1 q2 q2
Trace: a b a b a a,b a,b
Runs and Traces
State-transition graph S = ( Q, A, , [] )
Finite runs: finRuns(S) Q*
Infinite runs: infRuns(S) Q
Finite traces: finTraces(S) (2A)*
Infinite traces: infTraces(S) (2A)
Safety: the properties that can be checked on finRuns
Liveness: the properties that cannot be checked on finRuns
This is much easier.
(they need to be checked on infRuns)
Example: Mutual exclusion
It cannot happen that both processes are in their critical sections simultaneously.
Safety
Example: Bounded overtaking
Whenever process P1 wants to enter the critical section, then process P2 gets to enter at most once before process P1 gets to enter.
Safety
Example: Starvation freedom
Whenever process P1 wants to enter the critical section, provided process P2 never stays in the critical section forever, P1 gets to enter eventually.
Liveness
a
a,b b
q1
q3q2
infRuns finRuns
a
a,b b
q1
q3q2
infRuns finRuns
* closure
*finite branching
For state-transition graphs, all properties are safety properties !
Example: Starvation freedom
Whenever process P1 wants to enter the critical section, provided process P2 never stays in the critical section forever, P1 gets to enter eventually.
Liveness
a
a,b b
q1
q3q2
Fairness constraint:
the green transition cannot be ignored forever
a
a,b b
q1
q3q2
Without fairness: infRuns = q1 (q3 q1)* q2 (q1
q3)
With fairness: infRuns = q1 (q3 q1)* q2
Two important types of fairness
1 Weak (Buchi) fairness: a specified set of transitions cannot be enabled forever without being taken
2 Strong (Streett) fairness:a specified set of transitions cannot be enabled infinitely often without being
taken
a
a,b b
q1
q3q2
Strong fairness
a
a,b
q1
q2
Weak fairness
Fair state-transition graph S = ( Q, A, , [], WF, SF)
WF set of weakly fair actions
SF set of strongly fair actions
where each action is a subset of
Weak fairness comes from modeling concurrency
loop x:=0 end loop.
loop x:=1 end loop.
||
x=0 x=1
Weakly fair action Weakly fair action
Strong fairness comes from modeling choice
Strongly fair action Strongly fair action
loop m: n: x:=0 | x:=1 end loop.
pc=n x=0
pc=n x=1
pc=m x=0
pc=m x=1
Weak fairness is sufficient for asynchronous models (“no process waits forever if it can move”).
Strong fairness is necessary for modeling synchronous interaction (rendezvous).
Strong fairness makes model checking more difficult.
Fairness changes only infRuns, not finRuns.
Fairness can be ignored for checking safety properties.
The vast majority of properties to be verified are safety.
While nobody will ever observe the violation of a true liveness property, fairness is a useful abstraction that turns complicated safety into simple liveness.
Two remarks
Three important decisions when choosing system properties:
1 operational vs. declarative: automata vs. logic
2 may vs. must: branching vs. linear time
3 prohibiting bad vs. desiring good behavior: safety vs. liveness
The three decisions are orthogonal, and they lead to substantially different model-checking problems.
Branching vs. linear time
Branching time: something may (or may not) happen (e.g., every req may
be followed by grant)
Linear time: something must (or must not) happen (e.g., every req must be
followed by grant)
One is rarely interested in may properties,
but certain may properties are easy to model check, and they imply interesting must properties.
(This is because unlike must properties, which refer only to observations, may properties can refer to states.)
Fair state-transition graph S = ( Q, A, , [], WF, SF )
Finite runs: finRuns(S) Q*
Infinite runs: infRuns(S) Q
Finite traces: finTraces(S) (2A)*
Infinite traces: infTraces(S) (2A)
Linear time: the properties that can be checked on infTraces
Branching time: the properties that cannot be checked on infTraces
LinearBranching
Safety finTracesfinRuns
Liveness infTraces infRuns
a
aaa
a
b bc c
Same traces {aab, aac} {aab, aac}
Different runs {q0 q1 q3, q0 q2 q4}, {q0 q1 q3, q0 q1 q4}
q0q0
q2q1 q1
q4 q4q3q3
Observation a may occur.
||
It is not the case that a must not occur.
Linear
We may reach an a from which we must not reach a b .
Branching
a
aaa
a
b bc c
Same traces, different runs
q0q0
q2q1 q1
q4 q4q3q3
Linear time is conceptually simpler than branching time (words vs. trees).
Branching time is often computationally more efficient.
(Because branching-time algorithms can work with given states,
whereas linear-time algorithms often need to “guess” sets of possible states.)
Three important decisions when choosing system properties:
1 operational vs. declarative: automata vs. logic
2 may vs. must: branching vs. linear time
3 prohibiting bad vs. desiring good behavior: safety vs. liveness
The three decisions are orthogonal, and they lead to substantially different model-checking problems.
LinearBranching
Safety STL
Liveness LTL CTL
Logics
LTL linear temporal logicSTL safe temporal logicCTL computational tree logic
must may
finite
infinite
STL (Safe Temporal Logic)
-safety (only finite runs)
-branching (runs, not traces)
Defining a logic
1. Syntax:
What are the formulas?
2. Semantics:
What are the models?
Does model M satisfy formula ?
M |=
Propositional logics (PL):
1. boolean variables (a,b) & boolean operators (,)
2. model = truth-value assignment for variables
Propositional modal (e.g., temporal) logics:
1. PL + modal operators (,)
2. model = set of (e.g., temporally) related prop. models observations
state-transition graph (“Kripke structure”)
atomic observations
STL Syntax
::= a | | | | U
boolean variable (atomic
observation)
boolean operators
modal operators
STL Model
( K, q )
state-transition graph (Kripke
structure)
state of K
STL Semantics
(K,q) |= a iff a [q]
(K,q) |= iff (K,q) |= and (K,q) |=
(K,q) |= iff not (K,q) |=
(K,q) |= iff exists q’ s.t. q q’ and (K,q’) |=
(K,q) |= U iff exist q0, ..., qn s.t. 1. q = q0 q1 ...
qn 2. for all 0 i < n, (K,qi) |= 3. (K,qn) |=
EX exists next
= AX forall next
U EU exists until
= true U EF exists eventually
= AG forall always
W = ( () U ( ))
AW forall waiting-for (forall weak-
until)
Defined modalities
Important safety properties
Invariance a
Sequencing a W b W c W d
= a W (b W (c W d))
Important safety properties: mutex protocol
Invariance (pc1=in pc2=in)
Sequencing ( pc1=req
(pc2in) W (pc2=in) W (pc2in) W (pc1=in))
Branching properties
Deadlock freedom true
Possibility (a b)
(pc1=req (pc1=in))
CTL (Computation Tree Logic)
-safety & liveness
-branching time
[Clarke & Emerson; Queille & Sifakis 1981]
CTL Syntax
::= a | | | | U |
CTL Model
( K, q )
fair state-transition graph state of K
CTL Semantics
(K,q) |= iff exist q0, q1, ... s.t.
1. q = q0 q1 ... is an infinite fair run
2. for all i 0, (K,qi) |=
EG exists always
= AF forall eventually
W = ( U ) ( )
U = ( W ) ()
Defined modalities
Important liveness property
Response (a b)
(pc1=req (pc1=in))
If only universal properties are of interest,
why not omit the path quantifiers?
LTL (Linear Temporal Logic)
-safety & liveness
-linear time
[Pnueli 1977; Lichtenstein & Pnueli 1982]
LTL Syntax
::= a | | | | U
LTL Model
infinite trace t = t0 t1 t2 ... (sequence of observations)
(K,q) |= iff for all t L(K,q), t |=
(K,q) |= iff exists t L(K,q), t |=
Language of deadlock-free state-transition graph K at state q :
L(K,q) ... set of infinite traces of K starting at q
LTL Semantics
t |= a iff a t0
t |= iff t |= and t |=
t |= iff not t |=
t |= iff t1 t2 ... |=
t |= U iff exists n 0 s.t.1. for all 0 i < n, ti ti+1 ... |
= 2. tn tn+1 ... |=
X next
U U until
= true U F eventually
= G always
W = ( U ) W waiting-for (weak-until)
Defined modalities
Summary of modalities
STL U W
CTL all of the above and W U
LTL U W
Important properties
Invariance a safety
(pc1=in pc2=in)
Sequencing a W b W c W dsafety
(pc1=req
(pc2in) W (pc2=in) W (pc2in) W (pc1=in))
Response (a b) liveness
(pc1=req (pc1=in))
Composed modalities
a infinitely often a
a almost always a
Where did fairness go ?
Unlike in CTL, fairness can be expressed in LTL !
So there is no need for fairness in the model.
Weak (Buchi) fairness :
(enabled taken ) =
(enabled taken)
Strong (Streett) fairness :
( enabled ) ( taken )
Starvation freedom, corrected
(pc2=in (pc2=out))
(pc1=req (pc1=in))
CTL cannot express fairness
a a
b b
ba aq0
q1 q2
LTL cannot express branching
Possibility (a b)
So, LTL and CTL are incomparable.
(There are branching logics that can express fairness, e.g., CTL* = CTL + LTL, but they lose the computational attractiveness of CTL.)
-safety (finite runs) vs. liveness (infinite runs)
-linear time (traces) vs. branching time (runs)
-logic (declarative) vs. automata (operational)
System property: 2x2x2 choices
Automata
Safety: finite automata
Liveness: omega automata
Linear: language containment
Branching: simulation relation
Automata
Safety: finite automata
Liveness: omega automata
Linear: language containment for word automata
Branching: language containment for tree automata
Specification Automata
Syntax, given a set A of atomic observations:
S finite set of states
S0 S set of initial states
S S transition relation
: S PL(A) where the formulas of PL are
::= a | |
for a A
Language L(M) of specification automaton
M = (S, S0, , ) :
finite trace t0, ..., tn L(M)
iff
there exists a finite run s0 s1 ... sn of M
such that
for all 0 i n, ti |= (si)
(K,q) |=L M iff L(K,q) L(M)
Linear semantics of specification automata:
language containment
state-transition graph
state of K
specification automaton
finite traces
Invariance specification automaton
pc1 in
pc2 in
One-bounded overtaking specification automaton
pc1=out
pc1=req
pc2inpc1=req
pc2=in
pc1=inpc1=req
pc2in
Automata are more expressive than logic (LTL), because temporal logic
cannot count :
This cannot be expressed in LTL.
a true
(How about a (a a) ?)
Checking language containment between finite automata is PSPACE-complete !
L(K,q) L(M)
iff
L(K,q) complement( L(M) ) =
involves determinization (subset construction)
In practice:
1. require deterministic specification automata
2. use monitor automata
3. use branching semantics
Monitor Automata
Syntax:
same as specification automata, except also set E S of error states
Semantics:
define L(M) s.t. runs must end in error states
(K,q) |=C M iff L(K,q) L(M) =
Invariance monitor automaton
pc1 in
pc2 in
pc1 = in
pc2 = in
ERROR
One-bounded overtaking monitor automaton
pc1=out
pc1=req
pc2inpc1=req
pc2=in
pc1=in pc1=req
pc2in
pc1=req
pc2=in
ERROR
Specification automaton Monitor automaton
M complement(M)
-describe correct traces -describe error traces
-check language containment-check emptiness (linear): (exponential) reachability of error states
“All safety verification is reachability checking.”
In practice:
1. require deterministic specification automata
2. use monitor automata
3. use branching semantics
(K,q) |=B M
iff
there exists a simulation relation R Q S s.t. (q,s) R for some initial state s of M
Branching semantics of specification automata:
simulation
states of K
states of M
ANDAND
R Q S is a simulation relation
iff
(q,s) R implies
1. [q] |= (s)
2. for all q’ s.t. q q’ , exists s’ s.t. s s’
and (q’,s’) R.
[Milner 1974]
a
a
cb c
q|=L
b
true
truetrue
a
a
cb c
q|=B
b
true
truetrue
observations (s)
[q] |= (s) and for all (q,s) R,for all q’ s.t. q q’ , exists s’ s.t. s s’ and (q’,s’)
R.
?
(K,q) |=L M M language contains (K,q) :exponential check
(K,q) |=B M M simulates (K,q) :quadratic check
X
involves only traces (hence linear !)
involves states (hence branching !)
In practice, simulation is usually the “right” notion.
(If there is language containment, but not simulation, this is usually accidental, not by design.)
-safety & liveness (infinite runs !)
-specification vs. monitor automata
-linear (language containment) vs. branching (simulation) semantics
We discuss only the linear specification case.
Omega Automata
Specification Omega Automata
Syntax as for finite automata, in addition one of the following acceptance conditions:
Buchi: BA S
coBuchi: CA S
Streett: SA 2S 2S
Rabin: RA 2S 2S
Language L(M) of specification omega-automaton
M = (S, S0, , , A ) :
infinite trace t0, t1, ... L(M)
iff
there exists an infinite run s0 s1 ... of M
such that
1. s0 s1 ... satisfies A
2. for all i 0, ti |= (si)
Let Inf(s) = { p | p = si for infinitely many i }.
(set of states that occur infinitely often)The infinite run s satisfies the acceptance condition A
iff
Buchi: Inf(s) BA
coBuchi: Inf(s) CA
Streett: for all (l,r) SA, if Inf(s) l then Inf(s) r
Rabin: for some (l,r) RA, Inf(s) l = and Inf(s) r
finite: FA
Buchi: BA
coBuchi: CA
Streett: (l r)
Rabin: (l r)
(K,q) |=L M iff L(K,q) L(M)
Linear semantics of specification omega automata:
omega-language containment
infinite traces
Response specification automaton :
(a b) assuming (a b) = false
a b
ba
s1
s2
s3
s0
Here (s) is (s)= [(a b) = false]
Buchi condition { s0, s3 }
Note: Buchi condition takes of fairness
Response monitor automaton :
(a b) assuming (a b) = false
a b
s1 s2
Buchi condition { s2 }
s0
true
a a
s0s1
Buchi condition { s0 }
No coBuchi condition
a
Streett condition { ({s0,s1}, {s0}) }
Rabin condition { (, {s0}) }
a a
s0s1
No Buchi condition
coBuchi condition { s0 }
a
Streett condition { ({s1}, ) }
Rabin condition { ({s1}, {s0,s1}) }
a a
s0s1
Buchi condition { s2 }
a
a
s2
-Buchi and coBuchi automata cannot be determinized (i.e. exists an ND Buchi with a language not given by any deterministic Buchi)
-Streett and Rabin automata can be determinized (i.e. for every ND Streett, there is a deterministic Streett with the same language.)
nondeterministic Buchi =
deterministic Streett = deterministic Rabin =
nondeterministic Streett = nondeterministic Rabin =
omega-regular [Buchi 1960]
Omega automata are strictly more expressive than LTL.
Omega-automata: omega-regular languages
LTL: counter-free omega-regular languages
Omega automata: omega-regular languages = second-order theory of monadic
predicates & successor = omega-regular expressions
LTL: counter-free omega-regular languages = first-order theory of monadic predicates & successor = star-free omega-regular expressions
Can convert an LTL formula into an omega (ND -Buchi) automaton using the “tableau” construction
Structure of the Omega-Regular Languages
Streett = Rabin
Buchi coBuchi
FinitecoFinite
what is coFinite
Structure of the Omega-Regular Languages
Streett = Rabin
Buchi coBuchi
FinitecoFinite
counter-free
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
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
easiest harder hard
Model-Checking Algorithms = Graph Algorithms
1 Safety:
-solve: STL (U model checking), finite monitors ( emptiness)
-algorithm: reachability (linear)
2 Eventuality under weak fairness:
-solve: weakly fair CTL ( model checking), Buchi monitors ( emptiness)
-algorithm: strongly connected components (linear)
3 Liveness:
-solve: strongly fair CTL, Streett monitors ( ()
emptiness)
-algorithm: recursively nested SCCs (quadratic)
From specification automata to monitor automata:
determinization (exponential) + complementation (easy)
From LTL to monitor automata:
complementation (easy) + tableau construction (exponential)