Slide 1

Slide 1 text

Verifying Invariants of Lock-free Data Structures with Rely-Guarantee and Refinement Types Colin S. Gordon, Michael D. Ernst, Dan Grossman, and Matthew J. Parkinson TOPLAS (May 2017) @ PLDI 2017

Slide 2

Slide 2 text

Verification Effort vs. Power Verification Power Effort

Slide 3

Slide 3 text

Verification Effort vs. Power Verification Power Effort

Slide 4

Slide 4 text

Verification Effort vs. Power Verification Power Effort RCC/Java

Slide 5

Slide 5 text

Verification Effort vs. Power Verification Power Effort RCC/Java Ownership Types

Slide 6

Slide 6 text

Verification Effort vs. Power Verification Power Effort RCC/Java Ownership Types

Slide 7

Slide 7 text

Verification Effort vs. Power Verification Power Effort RCC/Java VeriFast Ownership Types

Slide 8

Slide 8 text

Verification Effort vs. Power Verification Power Effort RCC/Java VeriFast iCAP Ownership Types

Slide 9

Slide 9 text

Verification Effort vs. Power Verification Power Effort RCC/Java VeriFast FCSL iCAP Ownership Types

Slide 10

Slide 10 text

Verification Effort vs. Power Verification Power Effort RCC/Java Iris VeriFast FCSL iCAP Ownership Types

Slide 11

Slide 11 text

Verification Effort vs. Power Verification Power Effort RCC/Java Iris VeriFast FCSL iCAP Ownership Types

Slide 12

Slide 12 text

Verification Effort vs. Power Verification Power Effort RCC/Java Iris VeriFast FCSL iCAP Ownership Types External Uniqueness

Slide 13

Slide 13 text

Verification Effort vs. Power Verification Power Effort RCC/Java Iris VeriFast FCSL iCAP Ownership Types External Uniqueness Reference Immutability

Slide 14

Slide 14 text

Verification Effort vs. Power Verification Power Effort RCC/Java Iris VeriFast FCSL iCAP Ownership Types External Uniqueness Reference Immutability Refinement Types

Slide 15

Slide 15 text

Verification Effort vs. Power Verification Power Effort RCC/Java Iris VeriFast FCSL iCAP Ownership Types External Uniqueness Reference Immutability Refinement Types

Slide 16

Slide 16 text

Verification Effort vs. Power Verification Power Effort RCC/Java Iris VeriFast FCSL iCAP Ownership Types External Uniqueness Reference Immutability Refinement Types Describe or Restrict Mutation Using a Type System

Slide 17

Slide 17 text

Verification Effort vs. Power Verification Power Effort RCC/Java Iris VeriFast FCSL iCAP Ownership Types External Uniqueness Reference Immutability Refinement Types Describe or Restrict Mutation Using a Type System Reusable Prohibit problematic changes Don’t ensure good changes happen

Slide 18

Slide 18 text

Verification Effort vs. Power Verification Power Effort Reference Immutability Refinement Types

Slide 19

Slide 19 text

New Approach to Invariants of Lock-Free Data Structures

Slide 20

Slide 20 text

New Approach to Invariants of Lock-Free Data Structures • Goals:

Slide 21

Slide 21 text

New Approach to Invariants of Lock-Free Data Structures • Goals: 1. Verify one- and two-state invariants of lock-free data structures

Slide 22

Slide 22 text

New Approach to Invariants of Lock-Free Data Structures • Goals: 1. Verify one- and two-state invariants of lock-free data structures • Includes encoding (asymmetric) protocols for state change

Slide 23

Slide 23 text

New Approach to Invariants of Lock-Free Data Structures • Goals: 1. Verify one- and two-state invariants of lock-free data structures • Includes encoding (asymmetric) protocols for state change 2. Intermediate verification burden

Slide 24

Slide 24 text

New Approach to Invariants of Lock-Free Data Structures • Goals: 1. Verify one- and two-state invariants of lock-free data structures • Includes encoding (asymmetric) protocols for state change 2. Intermediate verification burden 3. Compatible with unverified code

Slide 25

Slide 25 text

New Approach to Invariants of Lock-Free Data Structures • Goals: 1. Verify one- and two-state invariants of lock-free data structures • Includes encoding (asymmetric) protocols for state change 2. Intermediate verification burden 3. Compatible with unverified code • Approach: Extend RGRefs (PLDI’13) for safe concurrency

Slide 26

Slide 26 text

New Approach to Invariants of Lock-Free Data Structures • Goals: 1. Verify one- and two-state invariants of lock-free data structures • Includes encoding (asymmetric) protocols for state change 2. Intermediate verification burden 3. Compatible with unverified code • Approach: Extend RGRefs (PLDI’13) for safe concurrency • Validation: Axiomatic Coq DSL and Liquid Haskell library

Slide 27

Slide 27 text

Rely-Guarantee References ref{ T | P }[ R, G ]

Slide 28

Slide 28 text

Rely-Guarantee References ref{ T | P }[ R, G ] } Regular ML Reference

Slide 29

Slide 29 text

Rely-Guarantee References ref{ T | P }[ R, G ] } Regular ML Reference Predicate/Refinement

Slide 30

Slide 30 text

Rely-Guarantee References ref{ T | P }[ R, G ] } Regular ML Reference Predicate/Refinement Rely (e.g. ==) Guarantee (e.g., ≤)

Slide 31

Slide 31 text

Rely-Guarantee References ref{ T | P }[ R, G ] } Regular ML Reference Predicate/Refinement Rely (e.g. ==) Guarantee (e.g., ≤) Two extra requirements: 1. P is stable w.r.t. R 2. Aliased references are compatible: x.G ⊆ y.R, y.G ⊆ x.R

Slide 32

Slide 32 text

Rely-Guarantee References ref{ T | P }[ R, G ] } Regular ML Reference Predicate/Refinement Rely (e.g. ==) Guarantee (e.g., ≤) By default, P/R/G range over referent and reachable heap fragment! Two extra requirements: 1. P is stable w.r.t. R 2. Aliased references are compatible: x.G ⊆ y.R, y.G ⊆ x.R

Slide 33

Slide 33 text

RGRef Monotonic Counter 3 x:ref{ N | ≥3 }[ ≤, ≤ ] y:ref{ N | ≥1 }[ ≤, == ]

Slide 34

Slide 34 text

RGRef Monotonic Counter 3 x:ref{ N | ≥3 }[ ≤, ≤ ] y:ref{ N | ≥1 }[ ≤, == ] x := !x + 1;

Slide 35

Slide 35 text

RGRef Monotonic Counter 3 x:ref{ N | ≥3 }[ ≤, ≤ ] y:ref{ N | ≥1 }[ ≤, == ] x := !x + 1; 3 ≤ 4 Proof: (!x) <= !x + 1

Slide 36

Slide 36 text

RGRef Monotonic Counter 3 x:ref{ N | ≥3 }[ ≤, ≤ ] y:ref{ N | ≥1 }[ ≤, == ] x := !x + 1; implies 3 ≤ 4 Proof: (!x) <= !x + 1

Slide 37

Slide 37 text

RGRef Monotonic Counter 3 x:ref{ N | ≥3 }[ ≤, ≤ ] y:ref{ N | ≥1 }[ ≤, == ] x := !x + 1; implies 3 ≤ 4 3 ≤ 4 Proof: (!x) <= !x + 1

Slide 38

Slide 38 text

RGRef Monotonic Counter 3 x:ref{ N | ≥3 }[ ≤, ≤ ] y:ref{ N | ≥1 }[ ≤, == ] x := !x + 1; implies 3 ≤ 4 3 ≤ 4 Proof: (!x) <= !x + 1

Slide 39

Slide 39 text

RGRefs are Well-Suited for Fine-Grained Concurrency

Slide 40

Slide 40 text

RGRefs are Well-Suited for Fine-Grained Concurrency • Rely-Guarantee originated in concurrent program verification

Slide 41

Slide 41 text

RGRefs are Well-Suited for Fine-Grained Concurrency • Rely-Guarantee originated in concurrent program verification • Many structures have natural one- and two-state per-node invariants (e.g., O’Hearn et al.’s Hindsight paper, PODC’10)

Slide 42

Slide 42 text

RGRefs are Well-Suited for Fine-Grained Concurrency • Rely-Guarantee originated in concurrent program verification • Many structures have natural one- and two-state per-node invariants (e.g., O’Hearn et al.’s Hindsight paper, PODC’10) • RGRefs “play nice” with unverified code

Slide 43

Slide 43 text

RGRefs are Well-Suited for Fine-Grained Concurrency • Rely-Guarantee originated in concurrent program verification • Many structures have natural one- and two-state per-node invariants (e.g., O’Hearn et al.’s Hindsight paper, PODC’10) • RGRefs “play nice” with unverified code • Subsume regular ML references: ref{ | True }[ True , True ]

Slide 44

Slide 44 text

RGRefs are Well-Suited for Fine-Grained Concurrency • Rely-Guarantee originated in concurrent program verification • Many structures have natural one- and two-state per-node invariants (e.g., O’Hearn et al.’s Hindsight paper, PODC’10) • RGRefs “play nice” with unverified code • Subsume regular ML references: ref{ | True }[ True , True ] • Often we want to verify “critical” code (e.g., lock-free algorithms) without verifying everything

Slide 45

Slide 45 text

RGRefs are Well-Suited for Fine-Grained Concurrency • Rely-Guarantee originated in concurrent program verification • Many structures have natural one- and two-state per-node invariants (e.g., O’Hearn et al.’s Hindsight paper, PODC’10) • RGRefs “play nice” with unverified code • Subsume regular ML references: ref{ | True }[ True , True ] • Often we want to verify “critical” code (e.g., lock-free algorithms) without verifying everything • Unverified code can treat RGRefs as opaque type

Slide 46

Slide 46 text

Atomic Increment let rec atom_inc (c:monotonic_counter) : IO () = x <- !c; done <- CAS(c, x, x+1); if done then return () else atom_inc c;;

Slide 47

Slide 47 text

Atomic Increment let rec atom_inc (c:monotonic_counter) : IO () = x <- !c; done <- CAS(c, x, x+1); if done then return () else atom_inc c;; h[c]=x ⟹ h[c] ≤ x+1

Slide 48

Slide 48 text

Atomic Increment let rec atom_inc (c:monotonic_counter) : IO () = x <- !c; done <- CAS(c, x, x+1); if done then return () else atom_inc c;; h[c]=x ⟹ h[c] ≤ x+1 Other structures require more extensions

Slide 49

Slide 49 text

Refiners

Slide 50

Slide 50 text

Refiners • Some proofs need to observe a heap cell, and later rely on a fact the observation established

Slide 51

Slide 51 text

Refiners • Some proofs need to observe a heap cell, and later rely on a fact the observation established • Refiners are field access that relate the value read to new stable refinements

Slide 52

Slide 52 text

Refiners • Some proofs need to observe a heap cell, and later rely on a fact the observation established • Refiners are field access that relate the value read to new stable refinements 0 1 2 3 4 5 6 …

Slide 53

Slide 53 text

Refiners • Some proofs need to observe a heap cell, and later rely on a fact the observation established • Refiners are field access that relate the value read to new stable refinements 0 1 2 3 4 5 6 … 0

Slide 54

Slide 54 text

Refiners • Some proofs need to observe a heap cell, and later rely on a fact the observation established • Refiners are field access that relate the value read to new stable refinements 0 1 2 3 4 5 6 … 3

Slide 55

Slide 55 text

Refiners • Some proofs need to observe a heap cell, and later rely on a fact the observation established • Refiners are field access that relate the value read to new stable refinements • x:ref{N|≥0}[≤,≤] ⟹ n:N,x:ref{N|≥n}[≤,≤] 0 1 2 3 4 5 6 … 3

Slide 56

Slide 56 text

Refiners • Some proofs need to observe a heap cell, and later rely on a fact the observation established • Refiners are field access that relate the value read to new stable refinements • x:ref{N|≥0}[≤,≤] ⟹ n:N,x:ref{N|≥n}[≤,≤] • observe x as n in (λv,h. n ≤ v) 0 1 2 3 4 5 6 … 3

Slide 57

Slide 57 text

Refiners • Some proofs need to observe a heap cell, and later rely on a fact the observation established • Refiners are field access that relate the value read to new stable refinements • x:ref{N|≥0}[≤,≤] ⟹ n:N,x:ref{N|≥n}[≤,≤] • observe x as n in (λv,h. n ≤ v) • Supports idiom of accumulating invariants during data structure traversal 0 1 2 3 4 5 6 … 3

Slide 58

Slide 58 text

Example Refiner Usages

Slide 59

Slide 59 text

Example Refiner Usages • Observing new lower bound on counter

Slide 60

Slide 60 text

Example Refiner Usages • Observing new lower bound on counter • Observe the final state of a protocol

Slide 61

Slide 61 text

Example Refiner Usages • Observing new lower bound on counter • Observe the final state of a protocol • Observing fixed field value • Used to prove Treiber stack pops exactly 1 node

Slide 62

Slide 62 text

Example Refiner Usages • Observing new lower bound on counter • Observe the final state of a protocol • Observing fixed field value • Used to prove Treiber stack pops exactly 1 node • Observe predicates on rank, order or set membership for union find

Slide 63

Slide 63 text

Lock-Free Union Find

Slide 64

Slide 64 text

Lock-Free Union Find • Anderson & Woll, STOC’91 • Ranks & path compression

Slide 65

Slide 65 text

Lock-Free Union Find • Anderson & Woll, STOC’91 • Ranks & path compression • We give first mechanized proof of invariants

Slide 66

Slide 66 text

Lock-Free Union Find • Anderson & Woll, STOC’91 • Ranks & path compression • We give first mechanized proof of invariants

Slide 67

Slide 67 text

Lock-Free Union Find • Anderson & Woll, STOC’91 • Ranks & path compression • We give first mechanized proof of invariants • Our proof reveals subtleties: • Path “compression” writes sometimes extend the chains momentarily!

Slide 68

Slide 68 text

Lock-Free Union Find • Anderson & Woll, STOC’91 • Ranks & path compression • We give first mechanized proof of invariants • Our proof reveals subtleties: • Path “compression” writes sometimes extend the chains momentarily!

Slide 69

Slide 69 text

Lock-Free Union Find • Anderson & Woll, STOC’91 • Ranks & path compression • We give first mechanized proof of invariants • Our proof reveals subtleties: • Path “compression” writes sometimes extend the chains momentarily!

Slide 70

Slide 70 text

Lock-Free Union Find • Anderson & Woll, STOC’91 • Ranks & path compression • We give first mechanized proof of invariants • Our proof reveals subtleties: • Path “compression” writes sometimes extend the chains momentarily!

Slide 71

Slide 71 text

Lock-Free Union Find • Anderson & Woll, STOC’91 • Ranks & path compression • We give first mechanized proof of invariants • Our proof reveals subtleties: • Path “compression” writes sometimes extend the chains momentarily! • Good example for your next verification paper…

Slide 72

Slide 72 text

Automating RGRefs

Slide 73

Slide 73 text

Automating RGRefs • Because RGRef P/R/G range over referent and heaps, they lead to complex side-conditions

Slide 74

Slide 74 text

Automating RGRefs • Because RGRef P/R/G range over referent and heaps, they lead to complex side-conditions • Annoying to specify, hard to automate or infer

Slide 75

Slide 75 text

Automating RGRefs • Because RGRef P/R/G range over referent and heaps, they lead to complex side-conditions • Annoying to specify, hard to automate or infer • A slight simplification: Drop heaps from predicates and relations!

Slide 76

Slide 76 text

Automating RGRefs • Because RGRef P/R/G range over referent and heaps, they lead to complex side-conditions • Annoying to specify, hard to automate or infer • A slight simplification: Drop heaps from predicates and relations! • The simplification doesn’t cost much useful expressivity

Slide 77

Slide 77 text

Automating RGRefs • Because RGRef P/R/G range over referent and heaps, they lead to complex side-conditions • Annoying to specify, hard to automate or infer • A slight simplification: Drop heaps from predicates and relations! • The simplification doesn’t cost much useful expressivity • Deep heap access rarely used

Slide 78

Slide 78 text

Automating RGRefs • Because RGRef P/R/G range over referent and heaps, they lead to complex side-conditions • Annoying to specify, hard to automate or infer • A slight simplification: Drop heaps from predicates and relations! • The simplification doesn’t cost much useful expressivity • Deep heap access rarely used • Heapless RGRefs lead to a concise Liquid Haskell Library

Slide 79

Slide 79 text

Automating RGRefs • Because RGRef P/R/G range over referent and heaps, they lead to complex side-conditions • Annoying to specify, hard to automate or infer • A slight simplification: Drop heaps from predicates and relations! • The simplification doesn’t cost much useful expressivity • Deep heap access rarely used • Heapless RGRefs lead to a concise Liquid Haskell Library • Other Liquid Haskell mechanisms recover some heap access

Slide 80

Slide 80 text

Examples Considered • Atomic Counter (Coq DSL + Liquid Haskell) • Treiber Stack (Coq) • Michael-Scott Queue (no tail, Coq) • Lock-free linked list (Liquid Haskell) • Lock-free list-based Set (Liquid Haskell) • Lock-free Union Find (Coq)

Slide 81

Slide 81 text

More in the Paper

Slide 82

Slide 82 text

More in the Paper • Detailed examples

Slide 83

Slide 83 text

More in the Paper • Detailed examples • Very detailed discussion of verifying path compression

Slide 84

Slide 84 text

More in the Paper • Detailed examples • Very detailed discussion of verifying path compression • Discussion of idioms for using concurrent RGRefs

Slide 85

Slide 85 text

More in the Paper • Detailed examples • Very detailed discussion of verifying path compression • Discussion of idioms for using concurrent RGRefs • Formal type system

Slide 86

Slide 86 text

More in the Paper • Detailed examples • Very detailed discussion of verifying path compression • Discussion of idioms for using concurrent RGRefs • Formal type system • Views Framework-based soundness proof 
 (see Dinsdale-Young et al., POPL’13)

Slide 87

Slide 87 text

More in the Paper • Detailed examples • Very detailed discussion of verifying path compression • Discussion of idioms for using concurrent RGRefs • Formal type system • Views Framework-based soundness proof 
 (see Dinsdale-Young et al., POPL’13) • Qualitative comparison of Coq DSL vs. Liquid RGRefs

Slide 88

Slide 88 text

More in the Paper • Detailed examples • Very detailed discussion of verifying path compression • Discussion of idioms for using concurrent RGRefs • Formal type system • Views Framework-based soundness proof 
 (see Dinsdale-Young et al., POPL’13) • Qualitative comparison of Coq DSL vs. Liquid RGRefs • Proof burden comparison to FCSL and VeriFast

Slide 89

Slide 89 text

Thanks! • And thanks to the Liquid Haskell team for lots of bug fixes, clarifications, and general tool support! • VM & Source: http://csgordon.github.io/rgref