proving a concurrent program correct by
play

Proving a Concurrent Program Correct by Demonstrating It Does - PowerPoint PPT Presentation

Proving a Concurrent Program Correct by Demonstrating It Does Nothing Bernhard Kragl IST Austria doi: 10.1007/978-3-319-96145-3_5 https://github.com/boogie-org/boogie Shaz Qadeer Microsoft https://www.rise4fun.com/civl Credits Cormac


  1. Proving a Concurrent Program Correct by Demonstrating It Does Nothing Bernhard Kragl IST Austria doi: 10.1007/978-3-319-96145-3_5 https://github.com/boogie-org/boogie Shaz Qadeer Microsoft https://www.rise4fun.com/civl

  2. Credits Cormac Flanagan Stephen N. Freund Serdar Tasiran Tayfun Elmas Chris Hawblitzel

  3. Program verification Program 𝒬 Verifier Is 𝒬 safe? Error report Proof

  4. Program verification Invariants Program Templates 𝒬 Proof structure … Verifier Is 𝒬 safe? Error report Proof

  5. Reasoning about transition systems β€’ Transition system π‘Šπ‘π‘ , π½π‘œπ‘—π‘’, 𝑂𝑓𝑦𝑒, 𝑇𝑏𝑔𝑓 π‘Šπ‘π‘  (Variables) π½π‘œπ‘—π‘’ (Initial state predicate over π‘Šπ‘π‘  ) 𝑂𝑓𝑦𝑒 (Transition predicate over π‘Šπ‘π‘  βˆͺ π‘Šπ‘π‘ β€² ) 𝑇𝑏𝑔𝑓 (Safety predicate over π‘Šπ‘π‘  ) β€’ Inductive invariant π½π‘œπ‘€ π½π‘œπ‘—π‘’ β‡’ π½π‘œπ‘€ (Initialization) π½π‘œπ‘€ ∧ 𝑂𝑓𝑦𝑒 β‡’ π½π‘œπ‘€ β€² (Preservation) π½π‘œπ‘€ β‡’ 𝑇𝑏𝑔𝑓 (Safety)

  6. Structured program vs. Transition relation Init: π‘žπ‘‘ = π‘žπ‘‘ 1 = π‘žπ‘‘ 2 = 𝑏 Next: π‘žπ‘‘ = 𝑏 ∧ π‘žπ‘‘ β€² = π‘žπ‘‘ 1 β€² = π‘žπ‘‘ 2 β€² = 𝑐 ∧ 𝑦 β€² = 0 ∧ π‘“π‘Ÿ π‘š, 𝑒 1 , 𝑒 2 a: x := 0 β€² = 𝑑 ∧ Β¬π‘š ∧ π‘š β€² ∧ π‘“π‘Ÿ π‘žπ‘‘, π‘žπ‘‘ 2 , 𝑦, 𝑒 1 , 𝑒 2 π‘žπ‘‘ 1 = 𝑐 ∧ π‘žπ‘‘ 1 b: acquire(l) acquire(l) β€² = 𝑒 ∧ 𝑒 1 β€² = 𝑦 ∧ π‘“π‘Ÿ π‘žπ‘‘, π‘žπ‘‘ 2 , π‘š, 𝑦, 𝑒 2 π‘žπ‘‘ 1 = 𝑑 ∧ π‘žπ‘‘ 1 c: t1 := x t2 := x β€² = 𝑓 ∧ 𝑒 1 β€² = 𝑒 1 + 1 ∧ π‘“π‘Ÿ π‘žπ‘‘, π‘žπ‘‘ 2 , π‘š, 𝑦, 𝑒 2 π‘žπ‘‘ 1 = 𝑒 ∧ π‘žπ‘‘ 1 d: t1 := t1+1 t2 := t2+1 β€² = 𝑔 ∧ 𝑦 β€² = 𝑒 1 ∧ π‘“π‘Ÿ π‘žπ‘‘, π‘žπ‘‘ 2 , π‘š, 𝑒 1 , 𝑒 2 π‘žπ‘‘ 1 = 𝑓 ∧ π‘žπ‘‘ 1 e: x := t1 x := t2 β€² = 𝑕 ∧ Β¬π‘š β€² ∧ π‘“π‘Ÿ(π‘žπ‘‘, π‘žπ‘‘ 2 , 𝑦, 𝑒 1 , 𝑒 2 ) π‘žπ‘‘ 1 = 𝑔 ∧ π‘žπ‘‘ 1 f: release(l) release(l) β€² = 𝑑 ∧ Β¬π‘š ∧ π‘š β€² ∧ π‘“π‘Ÿ π‘žπ‘‘, π‘žπ‘‘ 1 , 𝑦, 𝑒 1 , 𝑒 2 π‘žπ‘‘ 2 = 𝑐 ∧ π‘žπ‘‘ 2 β€² = 𝑒 ∧ 𝑒 2 β€² = 𝑦 ∧ π‘“π‘Ÿ π‘žπ‘‘, π‘žπ‘‘ 1 , π‘š, 𝑦, 𝑒 1 g: assert x = 2 π‘žπ‘‘ 2 = 𝑑 ∧ π‘žπ‘‘ 2 β€² = 𝑓 ∧ 𝑒 2 β€² = 𝑒 2 + 1 ∧ π‘“π‘Ÿ π‘žπ‘‘, π‘žπ‘‘ 1 , π‘š, 𝑦, 𝑒 1 π‘žπ‘‘ 2 = 𝑒 ∧ π‘žπ‘‘ 2 β€² = 𝑔 ∧ 𝑦 β€² = 𝑒 2 ∧ π‘“π‘Ÿ π‘žπ‘‘, π‘žπ‘‘ 1 , π‘š, 𝑒 1 , 𝑒 2 π‘žπ‘‘ 2 = 𝑓 ∧ π‘žπ‘‘ 2 β€² = 𝑕 ∧ Β¬π‘š β€² ∧ π‘“π‘Ÿ(π‘žπ‘‘, π‘žπ‘‘ 1 , 𝑦, 𝑒 1 , 𝑒 2 ) π‘žπ‘‘ 2 = 𝑔 ∧ π‘žπ‘‘ 2 Procedures and dynamic thread creation π‘žπ‘‘ 1 = π‘žπ‘‘ 2 = 𝑕 ∧ π‘žπ‘‘β€² = 𝑕 ∧ π‘“π‘Ÿ(π‘žπ‘‘ 1 , π‘žπ‘‘ 2 , π‘š, 𝑦, 𝑒 1 , 𝑒 2 ) complicate transition relation further! Safe: π‘žπ‘‘ = 𝑕 β‡’ 𝑦 = 2

  7. Interference freedom and Owicki-Gries Ξ¨ 1 : 𝑄 1 𝐷 1 {𝑅 1 } Ξ¨ 2 : 𝑄 2 𝐷 2 𝑅 2 Ξ¨ 1 , Ξ¨ 2 interference free 𝑄 1 ∧ 𝑄 2 𝐷 1 βˆ₯ 𝐷 2 𝑅 1 ∧ 𝑅 2 β€’ Example: 𝑦 = 0 𝑦 ≔ 𝑦 + 1 βˆ₯ 𝑦 ≔ 𝑦 + 2 𝑦 = 3 𝑦 = 0 𝑦 = 0 𝑦 = 0 Interference freedom: 𝑄 1 : {𝑦 = 0 ∨ 𝑦 = 2} 𝑄 2 : {𝑦 = 0 ∨ 𝑦 = 1} 𝑄 1 ∧ 𝑄 2 𝑦 ≔ 𝑦 + 2 𝑄 𝑄 2 ∧ 𝑄 1 𝑦 ≔ 𝑦 + 1 𝑄 2 1 𝑦 ≔ 𝑦 + 1 𝑦 ≔ 𝑦 + 2 𝑅 1 ∧ 𝑄 2 𝑦 ≔ 𝑦 + 2 𝑅 1 𝑅 2 ∧ 𝑄 1 𝑦 ≔ 𝑦 + 1 𝑅 2 𝑅 1 : 𝑦 = 1 ∨ 𝑦 = 3 𝑅 2 : 𝑦 = 2 ∨ 𝑦 = 3 𝑅 1 ∧ 𝑅 2 𝑦 = 3

  8. Ghost variables Need to refer to other thread’s state β€’ local variables β€’ program counter β€’ Example: 𝑦 = 0 𝑦 ≔ 𝑦 + 1 βˆ₯ 𝑦 ≔ 𝑦 + 1 𝑦 = 2 𝑦 = 0 π‘’π‘π‘œπ‘“ 1 ≔ π‘”π‘π‘šπ‘‘π‘“; π‘’π‘π‘œπ‘“ 2 ≔ π‘”π‘π‘šπ‘‘π‘“ 𝑄 1 : Β¬π‘’π‘π‘œπ‘“ 1 ∧ Β¬π‘’π‘π‘œπ‘“ 2 β‡’ 𝑦 = 0 ∧ π‘’π‘π‘œπ‘“ 2 β‡’ 𝑦 = 1 𝑄 2 : Β¬π‘’π‘π‘œπ‘“ 2 ∧ Β¬π‘’π‘π‘œπ‘“ 1 β‡’ 𝑦 = 0 ∧ π‘’π‘π‘œπ‘“ 1 β‡’ 𝑦 = 1 𝑦 ≔ 𝑦 + 1; π‘’π‘π‘œπ‘“ 1 ≔ 𝑒𝑠𝑣𝑓 𝑦 ≔ 𝑦 + 1; π‘’π‘π‘œπ‘“ 2 ≔ 𝑒𝑠𝑣𝑓 𝑅 1 : π‘’π‘π‘œπ‘“ 1 ∧ Β¬π‘’π‘π‘œπ‘“ 2 β‡’ 𝑦 = 1 ∧ π‘’π‘π‘œπ‘“ 2 β‡’ 𝑦 = 2 𝑅 2 : π‘’π‘π‘œπ‘“ 2 ∧ Β¬π‘’π‘π‘œπ‘“ 1 β‡’ 𝑦 = 1 ∧ π‘’π‘π‘œπ‘“ 1 β‡’ 𝑦 = 2 𝑦 = 2

  9. Rely/Guarantee Rely/Guarantee specifications 𝐷 ⊨ (𝑄, 𝑆, 𝐻, 𝑅) for individual threads and composition rule allow for modular proofs of loosely-coupled systems. 𝑦 β‰₯ 0 𝑆 = 𝐻 = 𝑦 β€² β‰₯ 𝑦 𝑦 ≔ 𝑦 + 1 βˆ₯ 𝑦 ≔ 𝑦 + 1 𝑄 = 𝑅 = 𝑦 β‰₯ 0 𝑦 β‰₯ 0

  10. Multi-layered refinement proofs [skip] || 𝑄 1 β‰Ό 𝑄 2 β‰Ό β‹― β‰Ό 𝑄 π‘œβˆ’1 β‰Ό 𝑄 𝑄 π‘œ is safe π‘œ 𝑄 1 is safe Advantages of structured proofs: Better for humans: easier to construct and maintain Better for computers: localized/small checks οƒ  easier to automate Programs that do nothing cannot go wrong

  11. Refinement is well-studied β€’ Logic β€’ 𝑄 𝑦, 𝑦 β€² β‡’ 𝑅(𝑦, 𝑦 β€² ) β€’ Labeled transition systems β€’ Language containment β€’ Simulation (forward, backward, upward, downward, diagonal, sideways, …) β€’ Bisimulation (vanilla, mint, lavender, barbed, triangulated, complicated, …) β€’ …

  12. Refinement is difficult for programs β€’ Programs are complicated β€’ Complex control and data β€’ Gap between program syntax and abstractions β€’ … especially for concurrent programs β€’ … especially for interactive proof construction

  13. CIVL: Construct correct concurrent programs layer by layer procedure P(…) { S } β€’ Operates on program syntax S1; S2 β€’ Organizes proof as a sequence of program if (e) S1 else S2 layers with increasingly coarse-grained while (e) S atomic actions call P β€’ All layers and supporting invariants async call P expressed together in one textual unit call P1 || P2 β€’ Automatically-generated verification call A conditions

  14. Gated atomic actions [Elmas, Q, Tasiran 2009] (Gate, Transition) single-state predicate two-state predicate Command Gate Transition Lock specification 𝑦 β€² = 𝑦 + 𝑧 ∧ 𝑧 β€² = 𝑧 𝑒𝑠𝑣𝑓 x := x+y var lock : ThreadID βˆͺ {nil} 𝑧 β€² = 𝑧 𝑒𝑠𝑣𝑓 havoc x Acquire(): [assume lock == nil; lock := tid] 𝑦 β€² = 𝑦 ∧ 𝑧 β€² = 𝑧 𝑦 < 𝑧 assert x<y Release(): [assert lock == tid; lock := nil] 𝑦 < 𝑧 ∧ 𝑦 β€² = 𝑦 ∧ 𝑧 β€² = 𝑧 𝑒𝑠𝑣𝑓 assume x<y β€’ Unifies precondition and postcondition β€’ Primitive for modeling a (concrete or abstract) concurrent program

  15. Operational semantics β„“, 𝑑 β‹… β€’ Program configuration 𝑕, 𝑔 ⊎ 𝒰 β€’ Transition relation β‡’ between configurations (and failure configuration βŠ₯ ) β‡’ βˆ— βŠ₯ β€’ Safety: Β¬βˆƒπ‘•β„“: 𝑕, β„“, π‘π‘π‘—π‘œ β‡’ βˆ— βŠ₯ β€’ 𝐻𝑝𝑝𝑒 𝑄 = 𝑕 Β¬βˆƒβ„“: 𝑕, β„“, π‘π‘π‘—π‘œ β‡’ βˆ— 𝑕 β€² , βˆ… 𝑕, 𝑕 β€² β€’ π‘ˆπ‘ π‘π‘œπ‘‘ 𝑄 = βˆƒβ„“: 𝑕, β„“, π‘π‘π‘—π‘œ β€’ 𝑄 1 β‰Ό 𝑄 2 : (1) 𝐻𝑝𝑝𝑒 𝑄 2 βŠ† 𝐻𝑝𝑝𝑒 𝑄 (2) 𝐻𝑝𝑝𝑒(𝑄 2 ) ∘ π‘ˆπ‘ π‘π‘œπ‘‘ 𝑄 1 βŠ† π‘ˆπ‘ π‘π‘œπ‘‘(𝑄 2 ) 1 𝑄 2 preserves failures 𝑄 2 preserves final states

  16. var x; IncrBy2() = call IncrBy2() [ x := x + 2 ] var x; Incr() = Op() { call Op() || Op() [ x := x + 1 ] call Incr() } var lock; Acquire() = Release() = Op() { call Op() || Op() var x; [ assume lock == nil; [ assert lock == tid; var t; lock := tid; ] lock := nil; ] call Acquire(); t := x; x := t + 1; call Release(); } var b; Acquire() { Release() { Op() { call Op() || Op() var x; while (true) b := 0; var t; if (CAS(b, 0, 1)) break; } call Acquire(); } t := x; x := t + 1; call Release(); }

  17. const c >= 0; var x; call Main(); Main() { // Create c threads // each executing Incr  [assert x β‰₯ 0] } Incr() { acquire(); assert x β‰₯ 0; x := x + 1; release(); }

  18. const c >= 0; var x; call Main(); Main() { x := 0; // Create c threads  [ ] // each executing Incr } Incr() { acquire(); assert x β‰₯ 0; x := x + 1; release(); }

  19. Programs constructed with CIVL β€’ Concurrent garbage collector [Hawblitzel, Petrank, Q, Tasiran 2015] β€’ FastTrack2 race-detection algorithm [Flanagan, Freund, Wilcox 2018] β€’ Lock-protected memory atop TSO [Hawblitzel] β€’ Thread-local heap atop shared heap [Hawblitzel, Q] β€’ Two-phase commit [K, Q, Henzinger 2018] β€’ Work-stealing queue, Treiber stack, Ticket, …

  20. Program layers in CIVL β€’ A CIVL program denotes a sequence of concurrent programs (layers) β€’ chained together by a refinement-preserving transformation β€’ Transformation between program layers combines β€’ Atomization: Transform statement S into atomic block [S] β€’ Summarization: Transform atomic block [S] into atomic action A β€’ Abstraction: Replace atomic action A with atomic action B

  21. Right and left movers [Lipton 1975] Integer a β€œSemaphore” β€œwait” β€œsignal” P(a) = [assume a > 0; a := a - 1] V(a) = [a := a + 1] right mover (R) left mover (L) Y V(a) P(a) X S 1 S 2 S 3 S 1 S 2 S 3 V(a) Y X P(a) S 1 T 2 S 3 S 1 T 2 S 3 Sequence R*;(N+ ο₯ ); L* is atomic . . . . R* X N Y L* S 0 S 5 . . . . R* X N L* Y S 0 S 5

Download Presentation
Download Policy: The content available on the website is offered to you 'AS IS' for your personal information and use only. It cannot be commercialized, licensed, or distributed on other websites without prior consent from the author. To download a presentation, simply click this link. If you encounter any difficulties during the download process, it's possible that the publisher has removed the file from their server.

Recommend


More recommend