game-based model checking key game model properties: syntax-direct: behaviour of any component...
Post on 19-Dec-2015
219 views
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)