deductive program verification
play

Deductive Program Verification Jean-Christophe Filli atre CNRS - PowerPoint PPT Presentation

Deductive Program Verification Jean-Christophe Filli atre CNRS ITP 2018 Oxford, UK July 12, 2018 1 / 32 joint work with Fran cois Bobot Claude March e Guillaume Melquiond Andrei Paskevich 2 / 32 a question for programmers


  1. Deductive Program Verification Jean-Christophe Filliˆ atre CNRS ITP 2018 Oxford, UK July 12, 2018 1 / 32

  2. joint work with Fran¸ cois Bobot Claude March´ e Guillaume Melquiond Andrei Paskevich 2 / 32

  3. a question for programmers shall I be pure or impure? 3 / 32

  4. a question for program verifiers shall I be pure or impure? 4 / 32

  5. a question for program verifiers shall I be pure or impure? mutability FP feast

  6. a question for program verifiers shall I be pure or impure? the While language mutability FP feast

  7. a question for program verifiers shall I be pure or impure? the While language WhyML mutability FP feast 4 / 32

  8. WhyML goal no model of the heap to get simpler VCs solution records with mutable fields + static control of aliases 5 / 32

  9. mutable variables aka references type ref ’a = { mutable contents: ’a; } 6 / 32

  10. we can model some data structures e.g. arrays type array ’a = private { mutable ghost elts: int -> ’a; length: int; } 7 / 32

  11. we can nest mutable types e.g. a heap in a resizeable array type heap = { mutable data: array elt; mutable size: int; mutable ghost view: bag elt; } the type checker is powerful enough to let you replace the data field while keeping track of aliases [ESOP 2013] 8 / 32

  12. the key is abstraction there are mutable DS you cannot implement (e.g. linked lists, mutable trees) yet you can model them easily then you can verify client code, thanks to proof modularity 9 / 32

  13. example: union-find type elem val make : unit -> elem val union: elem -> elem -> unit val find : elem -> elem val same : elem -> elem -> bool 10 / 32

  14. example: union-find type elem val make : unit -> elem val union: elem -> elem -> unit val find : elem -> elem val same : elem -> elem -> bool x 10 / 32

  15. example: union-find type elem val make : unit -> elem val union: elem -> elem -> unit val find : elem -> elem val same : elem -> elem -> bool x y 10 / 32

  16. example: union-find type elem val make : unit -> elem val union: elem -> elem -> unit val find : elem -> elem val same : elem -> elem -> bool x y z 10 / 32

  17. example: union-find type elem val make : unit -> elem val union: elem -> elem -> unit val find : elem -> elem val same : elem -> elem -> bool z x y 10 / 32

  18. example: union-find type elem val make : unit -> elem val union: elem -> elem -> unit val find : elem -> elem val same : elem -> elem -> bool z u x y 10 / 32

  19. example: union-find type elem val make : unit -> elem val union: elem -> elem -> unit val find : elem -> elem val same : elem -> elem -> bool x y u z 10 / 32

  20. example: union-find type elem val make : unit -> elem val union: elem -> elem -> unit val find : elem -> elem val same : elem -> elem -> bool v x y u z 10 / 32

  21. example: union-find type elem val make : unit -> elem val union: elem -> elem -> unit val find : elem -> elem val same : elem -> elem -> bool x y v u z 10 / 32

  22. example: union-find type elem val make : unit -> elem val union: elem -> elem -> unit val find : elem -> elem val same : elem -> elem -> bool w x y v u z 10 / 32

  23. example: union-find type elem val make : unit -> elem val union: elem -> elem -> unit val find : elem -> elem val same : elem -> elem -> bool x y z w v u 10 / 32

  24. example: union-find type elem type uf = { mutable dom: set elem; mutable rep: elem -> elem; } val ghost create () : uf val make (ghost uf: uf) () : elem val union (ghost uf: uf) (x y: elem) : unit val find (ghost uf: uf) (x : elem) : elem val same (ghost uf: uf) (x y: elem) : bool 11 / 32

  25. what else WhyML features • polymorphism • algebraic data types, pattern matching • exceptions, break , continue , return • ghost code and ghost data [CAV 2014] • contracts, loop and type invariants • VCGen = either traditional or Flanagan/Saxe style WP 12 / 32

  26. a logic for program verification goal rich enough to make your life easier, simple enough to be sent to ATPs 13 / 32

  27. a logic for program verification goal rich enough to make your life easier, simple enough to be sent to ATPs our solution a total, polymorphic first-order logic with • algebraic types & pattern matching • recursive definitions • (co)inductive predicates • mapping type α → β , λ -notation, application [FroCos 2011, CADE 2013, VSTTE 2014] 13 / 32

  28. Why3 WhyML Why3 logic

  29. Why3 WhyML Why3 logic ... ... Alt-Ergo Z3 CVC4

  30. Why3 WhyML OCaml C Why3 logic ... ... Alt-Ergo Z3 CVC4

  31. Why3 Java C Ada WhyML OCaml C Why3 logic ... ... Alt-Ergo Z3 CVC4

  32. Why3 your language Java C Ada WhyML OCaml C Why3 logic ... ... Alt-Ergo Z3 CVC4

  33. Why3 your language Java C Ada WhyML OCaml C your VCs Why3 logic ... ... Alt-Ergo Z3 CVC4 14 / 32

  34. using off-the-shelf provers Why3 currently supports 25+ ITPs and ATPs for each prover, a special “driver” file controls [Boogie 2011] • logical transformations to apply • input/output format • predefined symbols, axioms to be removed 15 / 32

  35. example: Z3 driver printer "smtv2" valid "^unsat" invalid "^sat" transformation "inline trivial" transformation "eliminate builtin" transformation "eliminate definition" transformation "eliminate inductive" transformation "eliminate algebraic" transformation "simplify formula" transformation "discriminate" transformation "encoding smt" prelude "(set-logic AUFNIRA)" theory BuiltIn syntax type int "Int" syntax type real "Real" syntax predicate (=) "(= %1 %2)" end ... 16 / 32

  36. demo union-find joint work with S. Melo de Sousa, M. Pereira, and M. Clochard 17 / 32

  37. API type elem type uf = ... val ghost create () : uf val make (ghost uf: uf) () : elem val union (ghost uf: uf) (x y: elem) : unit val find (ghost uf: uf) (x : elem) : elem val same (ghost uf: uf) (x y: elem) : bool 18 / 32

  38. specification type elem type uf = { mutable dom: set elem; mutable rep: elem -> elem; } invariant { forall x. mem x dom -> mem (rep x) dom && rep (rep x) = rep x } val ghost create () : uf ensures { result.dom = empty } 19 / 32

  39. specification val make (ghost uf: uf) () : elem writes { uf.dom, uf.rep } ensures { not (mem result (old uf.dom)) } ensures { uf.dom = add result (old uf.dom) } ensures { uf.rep = (old uf.rep)[result <- result] } val find (ghost uf: uf) (x: elem) : elem requires { mem x uf.dom } ensures { result = uf.rep x } 20 / 32

  40. specification val union (ghost uf: uf) (x y: elem) : ghost elem requires { mem x uf.dom } requires { mem y uf.dom } writes { uf.rep } ensures { result = old (uf.rep x) || result = old (uf.rep y) } ensures { forall z. mem z uf.dom -> uf.rep z = if old (uf.rep z = uf.rep x || uf.rep z = uf.rep y) then result else old (uf.rep z) } 21 / 32

  41. implementation type elem = content ref and content = | Link of elem | Root of int 22 / 32

  42. implementation type elem = content ref x 0 and content = | Link of elem | Root of int 22 / 32

  43. implementation type elem = content ref y 0 x 0 and content = | Link of elem | Root of int 22 / 32

  44. implementation type elem = content ref y 0 x 0 z 0 and content = | Link of elem | Root of int 22 / 32

  45. implementation type elem = content ref x 1 z 0 and content = y | Link of elem | Root of int 22 / 32

  46. implementation type elem = content ref x 1 z 0 u 0 and content = y | Link of elem | Root of int 22 / 32

  47. implementation type elem = content ref x 1 u 0 and content = y z | Link of elem | Root of int 22 / 32

  48. implementation type elem = content ref x 1 u 0 v 0 and content = y z | Link of elem | Root of int 22 / 32

  49. implementation type elem = content ref x 1 v 1 and content = y z u | Link of elem | Root of int 22 / 32

  50. implementation type elem = content ref x 1 v 1 w 0 and content = y z u | Link of elem | Root of int 22 / 32

  51. implementation type elem = x 2 w 0 content ref y z v and content = | Link of elem u | Root of int 22 / 32

  52. implementation type elem = x 2 w 0 content ref y z v and content = | Link of elem u | Root of int let’s verify this with Why3 22 / 32

  53. Why3 implementation too complex for Why3’s type checker; let’s model the heap type loc type elem = type elem = loc content ref and content = type content = | Link loc | Link of elem | Root of int | Root Peano.t type heap = { ghost mutable refs: loc -> option content; } 23 / 32

  54. termination 24 / 32

Recommend


More recommend