Lectures on Model Checking Stolen from lectures of Tom Henzinger - EE219C (CS294)

Post on 05-Jan-2016

213 views 0 download

Transcript of Lectures on Model Checking Stolen from lectures of Tom Henzinger - EE219C (CS294)

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)