1 / 43

Cooperative Reasoning for Automatic Software Verification

Cooperative Reasoning for Automatic Software Verification. Andrew Ireland School of Mathematical & Computer Sciences Heriot-Watt University Edinburgh. Outline. Cooperative reasoning: Tight integration of complementary techniques Compensating for each other’s weaknesses

qiana
Download Presentation

Cooperative Reasoning for Automatic Software Verification

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Cooperative Reasoning for Automatic Software Verification Andrew Ireland School of Mathematical & Computer Sciences Heriot-Watt University Edinburgh

  2. Outline • Cooperative reasoning: • Tight integration of complementary techniques • Compensating for each other’s weaknesses • Proof planning & cooperative reasoning: • Decouples proof search & proof checking • Promotes a flexible style of proof discovery • Case studies: • Property based verification • Functional verification

  3. Proof Planning Theory Conjectures Proof planning Methods + Critics Proof checking Tactics Proof plans promote reuse, flexibilityand cooperation

  4. Flexibility? • Conjecture: • ∀l:list(A).rotate(length(l),l)=l • Speculative generalization: • ∀l,a:list(A). • rotate(length(l),F1(l,a))= F2(l,a) • Generalized conjecture: • ∀l,a:list(A). rotate(length(l),app(l,a))=app(a,l) • Proof planning promotes the productive use of failure, • and in particular middle-out reasoning (MOR)

  5. The SPARK Approach • A subset of Ada that eliminates potential ambiguities and insecurities (PRAXIS) • Expressive enough for industrial applications, but restrictive enough to support rigorous analysis • SPARK toolset supports data & information flow analysis and formal verification • Partial correctness & exception freedom proof, e.g. proving code is free from buffer overflows, range violations, division by zero. • Avionics, transportation, air traffic control, security,…

  6. The SPARK Approach SPARK code Proofs SPARK Examiner VCs SPADE Simplifier  UnprovenVCs Cmds SPADE Proof Checker

  7. A Filter Example subtype AR_T is Integer range 0..9; type A_T is array (AR_T) of Integer; ... procedure Filter(A: in A_T; R: out Integer) is begin R:=0; for I in AR_T loop if A(I)>=0 and A(I)<=100 then R:=R+A(I); end if; end loop; end Filter; R:=R+A(I); If R <= Integer’Last then potential overflow exception

  8. Loop Invariant subtype AR_T is Integer range 0..9; type A_T is array (AR_T) of Integer; ... procedure Filter(A: in A_T; R: out Integer) is begin R:=0; for I in AR_T loop --# assert R >= 0 and R <= I*100 if A(I)>=0 and A(I)<=100 then R:=R+A(I); end if; end loop; end Filter;

  9. The SPARK Approach SPARK code Proofs SPARK Examiner VCs SPADE Simplifier  UnprovenVCs Cmds SPADE Proof Checker

  10. NuSPADE Project SPARK code Proofs SPARK Examiner VCs SPADE Simplifier  UnprovenVCs Cmds SPADEase SPADE Proof Checker Refinement • Bill J. Ellis • EPSRC Critical Systems programme (GR/R24081) • EPSRC RAIS Scheme (GR/T11289) • http://www.macs.hw.ac.uk/nuspade

  11. SPADEase Proof Planning Program Analysis • Proof planning: • automates invariant & exception freedom proofs • supports equational reasoning • generates program property schemas (invariants) • Program analysis: • instantiates program property schemas (invariants) • generates equational reasoning goals

  12. Loop Invariant VC H1: r >= 0 . H2: r <= loop__1__i * 100 . ... H6: element(a, [loop__1__i]) >= 0 . H7: element(a, [loop__1__i]) <= 100 . … -> C1: r + element(a,[loop__1__i]) >= 0 . C2: r + element(a,[loop__1__i]) <= (loop__1__i + 1) * 100 . …

  13. Loop Invariant VC H1: r >= 0 . H2: r <= loop__1__i * 100 . ... H6: element(a, [loop__1__i]) >= 0 . H7: element(a, [loop__1__i]) <= 100 . … -> C1: r + element(a,[loop__1__i]) >= 0 . C2: r + element(a,[loop__1__i])<=(loop__1__i+ 1)* 100 . … Rippling 

  14. Rippling Proof Pattern Given: ∀u’. f(g(v), h(u’)) f(g(c1(v)), h(u)) Goal:

  15. Rippling Proof Pattern Given: ∀u’. f(g(v), h(u’)) f(g(c1(v)), h(u)) Goal: c2(f(g(v),h(c3(u)))) Rippling = difference identification + reduction

  16. Separation Logic • John Reynolds (CMU) and Peter O’Hearn (QMU) • Simplifies pointer program proofs by enriching Hoare logic with spatial operators • Builds upon the logic of bunched implications (O’Hearn & Pym), and early work by Burstall • Focuses the reasoning effort on only those parts of the heap that are relevant to a program unit, i.e. local reasoning

  17. Modelling the Heap • Empty heap: the assertion emp holds for a heap that contains no cells • Singleton heap:the assertion X ↦ Eholds for a heap that contains a single cell (maps-to relation), e.g. i 5 (i ↦ 5)

  18. Separating Conjunction P*Q holds for a heap if the heap can be divided into two disjoint heaplets H1 and H2, such that P holds for H1 holds forQ holds for H2, e.g. i 5 i 5 7 7 (i↦5)*(i+1↦7) (i↦5)*(i+1↦7) *true (i↦5,7) (i↪5,7)

  19. Separating Implication * P Q asserts that, if the current heap H1 is extended with a disjoint heaplet H2 in which P holds, then Q will hold in the extended heap, e.g. i 5 i 7 * Q (i↦5,7) Q

  20. Singly-linked Lists list([],Y,Z)↔ emp  Y=Z list([W|X],Y,Z)↔(∃p.(Y ↦W,p)*list(X,p,Z)) i a2 a1 an … j list([a1, a2, …, an],i,j)

  21. Loop Invariant Discovery R:{∃A,B.list(A,i,nil)*list(B,j,nil)∧ A0 = app(rev(B),A)} {∃A. list(A,i,nil)∧ A0 = A} j := nil; {R} while not(i = nil) loop k := [i+1]; [i+1] := j; j := i; i := k end loop {∃B.list(B,j,nil) ∧ A0 = rev(B)}

  22. Loop Invariant Discovery R:{∃A,B.list(A,i,nil)*list(B,j,nil)∧A0 = app(rev(B),A)} {∃A. list(A,i,nil)∧ A0 = A} j := nil; {R} while not(i = nil) loop k := [i+1]; [i+1] := j; j := i; i := k end loop {∃B.list(B,j,nil) ∧ A0 = rev(B)} shape

  23. Loop Invariant Discovery R:{∃A,B.list(A,i,nil)*list(B,j,nil)∧A0 = app(rev(B),A)} {∃A. list(A,i,nil)∧ A0 = A} j := nil; {R} while not(i = nil) loop k := [i+1]; [i+1] := j; j := i; i := k end loop {∃B.list(B,j,nil) ∧ A0 = rev(B)} structural

  24. Loop Invariant Discovery R:{∃A,B.list(A,i,nil)*list(B,j,nil)∧A0 = app(rev(B),A)} {∃A. list(A,i,nil)∧ A0 = A} j := nil; {R} while not(i = nil) loop k := [i+1]; [i+1] := j; j := i; i := k end loop {∃B.list(B,j,nil) ∧ A0 = rev(B)} functional

  25. Verification Condition (∃A’,B’.list(A’,i,nil)*list(B’,j,nil) ∧ A0 = app(rev(B’),A’)) ∧(i≠nil) ├ (∃X2.(∃X,Y.(i ↦ X,Y)*((i ↦ X,j) (∃A,B.list(A,X2,nil)*list(B,i,nil) ∧ A0 = app(rev(B),A)))) ∧(∃X1.(i ↪ X1,X2))) Case-splitting Mutating Rippling  *

  26. Given: Loop Invariant xn+1 xn+2 xw i … nil xn xn-1 x1 j … nil (∃A’,B’.list(A’,i,nil)*list(B’,j,nil) ∧ A0 = app(rev(B’),A’))∧(i≠nil)

  27. Goal: Weakest Precondition x2 xn+1 xn+2 xw i … nil xn xn-1 x1 j … nil (∃X2.(∃X,Y.(i ↦ X,Y)*((i ↦ X,j) (∃A,B.list(A,X2,nil)*list(B,i,nil) ∧ A0 = app(rev(B),A))∧(∃X1.(i ↪ X1,X2))) *

  28. Case-splitting & Mutating xn+1 xn+2 xw i … nil xn xn-1 x1 j … nil (∃A,Btl.list([xn+1|A],i,nil)*list(Btl,j,nil) ∧ A0 = app(rev([xn+1|Btl]),A))

  29. Mutating Proof Pattern Goal: … (U ↦ V,W) (( … ) (U’ ↦ V’,W’) ( … )) * * *

  30. Mutating Proof Pattern Goal: …(U ↦ V,W)(( … )(U’ ↦ V’,W’) ( … )) * * * …(U ↦ V,W)((U’ ↦ V’,W’) (( … ) (…))) * * * X (X Y) Y * * (rewrite rule) ((…) ( …)) * Mutating = reconcile complementary heaplets

  31. Rippling (∃A’,B’.list(A’,i,nil)*list(B’,j,nil) ∧ A0 = app(rev(B’),A’)) ∧(i≠nil) ├ (∃A,Btl.list([xn+1|A],i,nil)*list(Btl,j,nil) ∧ A0 = app(rev([xn+1|Btl]),A))

  32. Rippling (∃A’,B’.list(A’,i,nil)*list(B’,j,nil) ∧ A0 = app(rev(B’),A’)) ∧(i≠nil) ├ (∃A,Btl.list([xn+1|A],i,nil)*list(Btl,j,nil) ∧ A0 = app(rev([xn+1|Btl]),A))

  33. Rippling (∃A’,B’.list(A’,i,nil)*list(B’,j,nil) ∧ A0 = app(rev(B’),A’)) ∧(i≠nil) ├ (∃A,Btl.list([xn+1|A],i,nil)*list(Btl,j,nil) ∧ A0 = app(rev([xn+1|Btl]),A)) (∃A,Btl.list([xn+1|A],i,nil)*list(Btl,j,nil) ∧ A0 = app(app(rev(Btl),[xn+1]),A))

  34. Rippling (∃A’,B’.list(A’,i,nil)*list(B’,j,nil) ∧ A0 = app(rev(B’),A’)) ∧(i≠nil) ├ (∃A,Btl.list([xn+1|A],i,nil)*list(Btl,j,nil) ∧ A0 = app(rev([xn+1|Btl]),A)) (∃A,Btl.list([xn+1|A],i,nil)*list(Btl,j,nil) ∧ A0 = app(app(rev(Btl),[xn+1]),A)) (∃A,Btl.list([xn+1|A],i,nil)*list(Btl,j,nil) ∧ A0 = app(rev(Btl),app([xn+1],A)))

  35. Rippling (∃A’,B’.list(A’,i,nil)*list(B’,j,nil) ∧ A0 = app(rev(B’),A’)) ∧(i≠nil) ├ (∃A,Btl.list([xn+1|A],i,nil)*list(Btl,j,nil) ∧ A0 = app(rev([xn+1|Btl]),A)) (∃A,Btl.list([xn+1|A],i,nil)*list(Btl,j,nil) ∧ A0 = app(app(rev(Btl),[xn+1]),A)) (∃A,Btl.list([xn+1|A],i,nil)*list(Btl,j,nil) ∧ A0 = app(rev(Btl),app([xn+1],A))) (∃A,Btl.list([xn+1|A],i,nil)*list(Btl,j,nil) ∧ A0 = app(rev(Btl),[xn+1|,A]))

  36. CORE Project Spec & code CORE system animation Smallfoot (family) IsaPlanner Proofs  Isabelle • Ewen Maclean, Gudmund Grov, Richard Addison • EPSRC (EP/F037597)http://www.macs.hw.ac.uk/core • Smallfoot (O’Hearn’s Theory Group) • IsaPlanner (Bundy’s Mathematical Reasoning Group)

  37. CORE Project Shape Analysis Proof Planning Term Synthesis • Shape analysis automates: • checking of shape properties • shape invariant generation • Proof planning automates proof search: • structural properties • functional properties • Term synthesis automates invariant discovery – • ongoing work (alternative to MOR)

  38. Invariant Discovery (Ongoing) ∃A,B. list(V1,i,nil)* list(V2,j,nil)∧A0 =F1(rev(B),A,B)

  39. Invariant Discovery (Ongoing) ∃A,B. list(V1,i,nil)*list(V2,j,nil)∧A0 =F1(rev(B),A,B) Shape Shape invariants currently hand-crafted, but aiming for automation via Smallfoot family.

  40. Invariant Discovery (Ongoing) ∃A,B. list(V1,i,nil)*list(V2,j,nil)∧A0 =F1(rev(B),A,B) Structural Structural invariants generated via MOR (proof planning within CORE System)

  41. Invariant Discovery (Ongoing) ∃A,B. list(V1,i,nil)* list(V2,j,nil)∧A0 =F1(rev(B),A,B) Functional Functional invariants generated via term synthesis (CORE System) and proved via proof planning (IsaPlanner)

  42. Conclusion • Successful software verification approaches are typically an integration of techniques • Argued for cooperative reasoning, i.e. a tight integration of complementary techniques • Focused on proof planning as a flexible approach to proof automation that promotes cooperative reasoning

More Related