VIEWS: 4 PAGES: 27 POSTED ON: 10/26/2009
game-based model checking key game model properties: syntax-direct: behaviour of any component specified in isolation truly 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 structure if | ; | break | continue | goto | assert block structure state {nat x := M; N} | x := M expressions x | 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 numbers bool 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 v distinguish ab/normally terminating traces trace: start state, moves, end state state: map ids in environment to vals move: val position (in typing) stateful game models (| you()|)m = qyou,myou qyou,myou qyou,myou nd (for all m) (|you()%9|)d = Sm%9=d (| n := you()%9|) () = SdSm%9=d p.a. game model model: {|M|} e = set of traces returning expr e distinguish ab/normally terminating traces trace: start P-state, moves, end P-state P-state: set of (negated) P members move: expr position (in typing) p.a. game models {| you()|}y = {|you()%9|}y%9 = {| n := you()%9|} () = if sat qyou,yyou qyou,yyou qyou,yyou ( y%9/n & ) wrestle game model goer=1 qf1,qyou,nyou ()f1 ()f1 qyou,0you,qf goer=0 goer=0 ()f qf1,()f1 qyou,1you,qf ()f goer=0 wrestle p.a. model pile%9!=0 pile>0 pile%9=9-n goer=1 qf1,qyou,nyou ()f1 pile%9=0 pile>0 pile%9!=9-n goer=0 ()f1 pile%9=0 pile=0 qyou,yyou,qf pile%9!=9-n goer=0 ()f ()f pile%9=0 pile=0 pile%9!=9-n goer=0 qf1,()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 wrestle letp 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 pile%9=9-n goer=1 qf1,qyou,nyou ()f1 pile%9=0 goer=0 qyou,yyou,qf qf1,()f1 ()f 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. wrestle bool 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. wrestle 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}}); letp goer = 0 in assert(goer = 0) c.e.g.a.r. wrestle bool 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. wrestle bool 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. wrestle letp 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. wrestle letp 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. wrestle letp 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. wrestle letp 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)