game-based model checking key game model properties: syntax-direct: behaviour of any component...

27

Post on 19-Dec-2015

219 views

Category:

Documents


0 download

TRANSCRIPT

game-based model checking

key game model properties:syntax-direct: behaviour of any

component specified in isolationtruly compositional: behaviour of

component built from sub-models

any component can be verified in isolation huge programs could be verified by isolating difficult parts

game-based p.a.

game models cannot avoid state explosion- would benefit from predicate

abstraction!

predicate abstraction most naturally treated as a model mutation- would benefit from syntax-direct and

compositional explanation

contributions

• a game semantics of p.a.• a verification tool for a large subset of

C• a predicate annotation approach that

exploits the syntax-direct property• a CEGAR verification algorithm that

exploits the syntax-direct property

programming language: IAL

C-like control structureif | ; | break | continue | goto | assert

block structure state{nat x := M; N} | x := M

expressionsx | k | M(N1,..,Nn) | let f(x1,..,xn) = M in N

battle of numbers

bool goer := 0; nat pile := 10 * you()%10 + me()%10;f (if pile > 0 then {goer := 1; pile -= you()%9%pile}; if pile > 0 then {goer := 0; pile -= me()%9%pile});if pile = 0 then winner := goer

wrestle of numbersbool goer := 0; nat pile := {nat n = you()%10; n*10 + 9 – n};assert(pile%9 = 0);f (if pile > 0 then {nat n := you()%9; goer := 1; pile -= n; assert(pile%9 = 9 - n); if pile > 0 then {pile -= 9 – n; goer := 0}});assert(goer = 0)

stateful game model – no p.a.

model: M v = set of traces returning val vdistinguish ab/normally terminating traces

trace: start state, moves, end statestate: map ids in environment to valsmove: val position (in typing)

|)(|

you()%9 d = m%9=d qyou,myou

stateful game models

you() m = qyou,myou (for all m)

(|

(| |)

|)

n := you()%9 () = dm%9=d qyou,myou

(| |) nd

p.a. game modelmodel: M e = set of traces returning

expr edistinguish ab/normally terminating traces

trace: start P-state, moves, end P-stateP-state: set of (negated) P membersmove: expr position (in typing)

{| |}

if sat( & )

p.a. game models

you()%9 y%9 = qyou,yyou

you() y = qyou,yyou

n := you()%9 () = qyou,yyou

y%9/n

{|

{|

{|

|}

|}

|}

wrestle game model

goer=0goer=0

goer=0

goer=1

qyou,0you,qf

qf1,qyou,nyou

()f1

()f

()f

qf1,()f1

qyou,1you,qf…

()f1

wrestle p.a. model

pile%9=0

pile%9!=9-ngoer=0

pile>0

pile%9!=0

pile%9=9-n

pile>0

goer=1

qyou,yyou,qf

qf1,qyou,nyou

pile%9=0

pile%9!=9-n

pile=0

goer=0

()f1

()f

()f

pile%9=0

pile%9!=9-n

pile=0

goer=0

qf1,()f1

()f1

about this formulation

+ simple+ stateful and p.a. variants similar+ control semantics orthogonal to state

semantics (control ignored in this talk!)

– less compositional in spirit than some game semantics

- environments are important- p.a. semantics difficult to handle otherwise

p.a. properties

• the p.a. model is decidable (finite-state)

• if p.a. model of M has no aborting traces then M is safe

syntactic predicate annotation

we can trivially move predicate annotations from the model to the program

this can be used to minimize the predicate state size

annotated wrestleletp goer = 0 in bool goer := 0; letp pile%9 = 0 in nat pile := {nat n = you()%10; n*10 + 9 – n}; assert(pile%9 = 0); f (if pile > 0 then {nat n := you()%9; goer := 1; letp pile%9 = 9 – n in pile -= n; assert(pile%9 = 9 - n); if pile > 0 then {pile -= 9 – n; goer := 0}}); assert(goer = 0)

annotated p.a. model

pile%9=0 goer=0

pile%9!=0

pile%9=9-ngoer=1

qyou,yyou,qf

qf1,qyou,nyou

()f

qf1,()f1

()f1

goer=0

game p.a. c.e.g.a.r.

make each conditional a predicate– as tightly scoped as possible

model check– safe => safe– unsafe =>

• check trace feasibility• widen scope of some letp if infeasible

c.e.g.a.r. wrestlebool goer := 0;nat pile := {nat n = you()%10; n*10 + 9 – n};letp pile%9 = 0 in assert(pile%9 = 0);f (if letp pile > 0 in pile > 0 then {nat n := you()%9; goer := 1; pile -= n; letp pile%9 = 9 – n in assert(pile%9 = 9 - n); if letp pile > 0 in pile > 0 then {pile -= 9 – n; goer := 0}});letp goer = 0 in assert(goer = 0)

c.e.g.a.r. wrestlebool goer := 0;letp pile%9 = 0 in nat pile := {nat n = you()%10; n*10 + 9 – n}; assert(pile%9 = 0);f (if letp pile > 0 in pile > 0 then {nat n := you()%9; goer := 1; pile -= n; letp pile%9 = 9 – n in assert(pile%9 = 9 - n); if letp pile > 0 in pile > 0 then {pile -= 9 – n; goer := 0}});letp goer = 0 in assert(goer = 0)

c.e.g.a.r. wrestlebool goer := 0;letp pile%9 = 0 in nat pile := {nat n = you()%10; n*10 + 9 – n}; assert(pile%9 = 0);letp goer = 0 in f (if letp pile > 0 in pile > 0 then {nat n := you()%9; goer := 1; pile -= n; letp pile%9 = 9 – n in assert(pile%9 = 9 - n); if letp pile > 0 in pile > 0 then {pile -= 9 – n; goer := 0}}); assert(goer = 0)

c.e.g.a.r. wrestlebool goer := 0;letp goer = 0 in letp pile%9 = 0 in nat pile := {nat n = you()%10; n*10 + 9 – n}; assert(pile%9 = 0); f (if letp pile > 0 in pile > 0 then {nat n := you()%9; goer := 1; pile -= n; letp pile%9 = 9 – n in assert(pile%9 = 9 - n); if letp pile > 0 in pile > 0 then {pile -= 9 – n; goer := 0}}); assert(goer = 0)

c.e.g.a.r. wrestleletp goer = 0 in bool goer := 0; letp pile%9 = 0 in nat pile := {nat n = you()%10; n*10 + 9 – n}; assert(pile%9 = 0); f (if letp pile > 0 in pile > 0 then {nat n := you()%9; goer := 1; pile -= n; letp pile%9 = 9 – n in assert(pile%9 = 9 - n); if letp pile > 0 in pile > 0 then {pile -= 9 – n; goer := 0}}); assert(goer = 0)

c.e.g.a.r. wrestleletp goer = 0 in bool goer := 0; letp pile%9 = 0 in nat pile := {nat n = you()%10; n*10 + 9 – n}; assert(pile%9 = 0); f (if letp pile > 0 in pile > 0 then {nat n := you()%9; goer := 1; pile -= n; letp pile%9 = 9 – n in assert(pile%9 = 9 -

n); if letp pile > 0 in pile > 0 then {pile -= 9 – n; goer := 0}}); assert(goer = 0)

c.e.g.a.r. wrestleletp goer = 0 in bool goer := 0; letp pile%9 = 0 in nat pile := {nat n = you()%10; n*10 + 9 – n}; assert(pile%9 = 0); f (if letp pile > 0 in pile > 0 then {nat n := you()%9; goer := 1; letp pile%9 = 9 – n in pile -= n; assert(pile%9 = 9 - n); if letp pile > 0 in pile > 0 then {pile -= 9 – n; goer := 0}}); assert(goer = 0)

c.e.g.a.r. wrestleletp goer = 0 in bool goer := 0; letp pile%9 = 0 in nat pile := {nat n = you()%10; n*10 + 9 – n}; assert(pile%9 = 0); f (if letp pile > 0 in pile > 0 then {nat n := you()%9; goer := 1; letp pile%9 = 9 – n in pile -= n; assert(pile%9 = 9 - n); if letp pile > 0 in pile > 0 then {pile -= 9 – n; goer := 0}}); assert(goer = 0)