Specifying and Verifying Concurrent Algorithms with Histories - - PowerPoint PPT Presentation

specifying and verifying concurrent algorithms with
SMART_READER_LITE
LIVE PREVIEW

Specifying and Verifying Concurrent Algorithms with Histories - - PowerPoint PPT Presentation

Specifying and Verifying Concurrent Algorithms with Histories and Subjectivity Ilya Sergey Aleks Nanevski Anindya Banerjee ESOP 2015 A logic-based approach for Specifying and Verifying Concurrent Algorithms An


slide-1
SLIDE 1


 with 
 Histories and Subjectivity

ESOP 2015

Ilya Sergey Aleks Nanevski Anindya Banerjee

Specifying and Verifying 
 Concurrent Algorithms

slide-2
SLIDE 2

A logic-based approach 
 for

Specifying and Verifying 
 Concurrent Algorithms

slide-3
SLIDE 3

An approach, which is

slide-4
SLIDE 4

An approach, which is

  • Natural
  • captures intuition behind realistic algorithms
slide-5
SLIDE 5

An approach, which is

  • Natural
  • captures intuition behind realistic algorithms
  • Powerful
  • enables compositional verification of concurrency
slide-6
SLIDE 6

An approach, which is

  • Natural
  • captures intuition behind realistic algorithms
  • Powerful
  • enables compositional verification of concurrency
  • Lightweight
  • does not require to engineer a new logical framework
slide-7
SLIDE 7

Key ideas

  • Subjectivity
  • Partial Commutative Monoids (PCMs)
  • Histories
slide-8
SLIDE 8

Key ideas

  • Subjectivity
  • Partial Commutative Monoids (PCMs)
  • Histories

Nanevski et al. [ESOP’14]

slide-9
SLIDE 9

Key ideas

  • Subjectivity
  • Partial Commutative Monoids (PCMs)
  • Histories
slide-10
SLIDE 10

Hoare-style program specifications

slide-11
SLIDE 11

Hoare-style program specifications

{ P } { Q }

c

slide-12
SLIDE 12

Hoare-style program specifications

{ P } { Q }

precondition

c

slide-13
SLIDE 13

Hoare-style program specifications

{ P } { Q }

precondition postcondition

c

slide-14
SLIDE 14

Hoare-style program specifications

If the initial state satisfies P , 
 then, after c terminates, 
 the final state satisfies Q.

{ P } { Q }

precondition postcondition

c

slide-15
SLIDE 15

push(x) pop()

Abstract specifications for a stack

slide-16
SLIDE 16

push(x) pop()

Abstract specifications for a stack

slide-17
SLIDE 17

push(x)

{ S = xs } { S′= x :: xs }

pop()

Abstract specifications for a stack

slide-18
SLIDE 18

push(x)

{ S = xs } { S′= x :: xs }

pop()

{ S = xs } { res = None ⋀ S = Nil ⋁ ∃x, xs′. res = Some x ⋀ 
 xs = x :: xs′ ⋀ S′ = xs′ }

Abstract specifications for a stack

slide-19
SLIDE 19

push(x)

{ S = xs } { S′= x :: xs }

pop()

{ S = xs }

Suitable for sequential case

{ res = None ⋀ S = Nil ⋁ ∃x, xs′. res = Some x ⋀ 
 xs = x :: xs′ ⋀ S′ = xs′ }

Abstract specifications for a stack

slide-20
SLIDE 20

push(x)

{ S = xs } { S′= x :: xs }

pop()

{ S = xs }

Not so good for concurrent use: useless in the presence of interference

Abstract specifications for a stack

{ res = None ⋀ S = Nil ⋁ ∃x, xs′. res = Some x ⋀ 
 xs = x :: xs′ ⋀ S′ = xs′ }

slide-21
SLIDE 21

y := pop();

slide-22
SLIDE 22

y := pop();

{ S = Nil }

slide-23
SLIDE 23

y := pop();

{ y = ??? } { S = Nil }

slide-24
SLIDE 24

y := pop();

  • push(1);

push(2);

{ S = Nil }

slide-25
SLIDE 25

y := pop();

{ y = 1 ⋁ y = 2 ⋁ y = None }

  • push(1);

push(2);

{ S = Nil }

slide-26
SLIDE 26

y := pop();

{ S = Nil }

  • push(1);

push(2);

  • push(3);
slide-27
SLIDE 27

y := pop();

{ S = Nil }

{ y = 1 ⋁ y = 2 ⋁ y = 3 ⋁ y = None }

  • push(1);

push(2);

  • push(3);
slide-28
SLIDE 28

y := pop();

{ y = ??? } { S = Nil }

Thread-modular spec for pop?

slide-29
SLIDE 29

Idea

slide-30
SLIDE 30

Capture the effect of self, 
 abstract over the others. Idea

slide-31
SLIDE 31

Capture the effect of self, 
 abstract over the others. Idea

(subjective specification)

slide-32
SLIDE 32

y := pop();

Subjective stack specifications

slide-33
SLIDE 33

y := pop();

  • Hs — pushes/pops to the stack by this thread

Subjective stack specifications

slide-34
SLIDE 34

y := pop();

  • Hs — pushes/pops to the stack by this thread
  • Ho — pushes/pops by all other threads

Subjective stack specifications

slide-35
SLIDE 35

y := pop();

{ Hs = ∅ }

  • Hs — pushes/pops to the stack by this thread
  • Ho — pushes/pops by all other threads

Subjective stack specifications

slide-36
SLIDE 36

y := pop();

{ y = None ⋁ y = Some(v), where v ∈ Ho } { Hs = ∅ }

  • Hs — pushes/pops to the stack by this thread
  • Ho — pushes/pops by all other threads

Subjective stack specifications

slide-37
SLIDE 37

y := pop();

{ y = None ⋁ y = Some(v), where v ∈ Ho } { Hs = ∅ }

Subjective stack specifications

| {z }

what I popped depends


  • n what the others have pushed
  • Hs — pushes/pops to the stack by this thread
  • Ho — pushes/pops by all other threads
slide-38
SLIDE 38

{ y = None ⋁ y = Some(v), where v ∈ Ho }

Valid only if the stack is changed

  • nly by push/pops.

| {z }

what I popped depends


  • n what the others have pushed

y := pop();

{ Hs = ∅ }

Subjective stack specifications

slide-39
SLIDE 39

{ P } { Q }

y := pop();

slide-40
SLIDE 40

{ P } { Q } C ⊢

y := pop();

slide-41
SLIDE 41

{ P } { Q } C ⊢

Specifies expected
 thread interference y := pop();

slide-42
SLIDE 42

Concurrent Resources

slide-43
SLIDE 43

Shared state

Concurrent Resources

slide-44
SLIDE 44

Concurrent Resources

Auxiliary state Shared state

Owicki, Gries [CACM’77]

slide-45
SLIDE 45

Subjective Concurrent Resources

Shared state

Ley-Wild, Nanevski [POPL’13]

slide-46
SLIDE 46

Auxiliary state, 
 controlled by this thread

Subjective Concurrent Resources

Shared state

Ley-Wild, Nanevski [POPL’13]

slide-47
SLIDE 47

Auxiliary state, 
 controlled by this thread

Auxiliary state, 
 controlled by others

Subjective Concurrent Resources

Shared state

Ley-Wild, Nanevski [POPL’13]

slide-48
SLIDE 48

Subjective Concurrent Resources

Jones [TOPLAS’83]

slide-49
SLIDE 49

Changes (transitions) 
 allowed to myself
 (Guarantee)

Subjective Concurrent Resources

Jones [TOPLAS’83]

slide-50
SLIDE 50

Transitions, allowed 
 to the others
 (Rely) Changes (transitions) 
 allowed to myself
 (Guarantee)

Subjective Concurrent Resources

Jones [TOPLAS’83]

slide-51
SLIDE 51

Transitions, allowed 
 to the others
 (Rely) Changes (transitions) 
 allowed to myself
 (Guarantee)

What I have = what I can do and what I have done.

Subjective Concurrent Resources

Jones [TOPLAS’83]

slide-52
SLIDE 52

State Transition Systems
 with 
 Subjective Auxiliary State

Concurrent Resources =

Nanevski, Ley-Wild, Sergey, Delbianco [ESOP’14]

slide-53
SLIDE 53

State Transition Systems
 with 
 Subjective Auxiliary State

Concurrent Resources =

Nanevski, Ley-Wild, Sergey, Delbianco [ESOP’14]

(Concurroids)

slide-54
SLIDE 54

Specifications with concurroids

slide-55
SLIDE 55

Self

  • Self — state controlled by me

Specifications with concurroids

slide-56
SLIDE 56

Self

Other

  • Self — state controlled by me
  • Other — state controlled by all other threads

Specifications with concurroids

slide-57
SLIDE 57

Self

Other Joint

  • Self — state controlled by me
  • Other — state controlled by all other threads
  • Joint — modified by everyone, as allowed by transitions

Specifications with concurroids

slide-58
SLIDE 58

C =

Specifications with concurroids

Self

Other Joint

slide-59
SLIDE 59

C =

{ P } c { Q } C ⊢

Specifications with concurroids

Self

Other Joint

slide-60
SLIDE 60

C =

{ P } c { Q }@ C

Specifications with concurroids

Self

Other Joint

slide-61
SLIDE 61

C =

{ P } c { Q }

| {z }

defines resources, touched by c, their transitions and invariants

@ C

Specifications with concurroids

Self

Other Joint

slide-62
SLIDE 62

C =

{ P } c { Q }@ C

Specifications with concurroids

Self

Other Joint

specify self/other/joint parts

slide-63
SLIDE 63

FCSL: Fine-grained Concurrent Separation Logic

Nanevski, Ley-Wild, Sergey, Delbianco [ESOP’14]

slide-64
SLIDE 64

FCSL: Fine-grained Concurrent Separation Logic

Nanevski, Ley-Wild, Sergey, Delbianco [ESOP’14]

  • Logic for reasoning with concurroids
slide-65
SLIDE 65

FCSL: Fine-grained Concurrent Separation Logic

Nanevski, Ley-Wild, Sergey, Delbianco [ESOP’14]

  • Logic for reasoning with concurroids
  • Emphasis on subjective specifications
slide-66
SLIDE 66

Key ideas

  • Subjectivity
  • PCMs
  • Histories
slide-67
SLIDE 67

Key ideas

  • Subjectivity — reasoning with self and other
  • PCMs
  • Histories
slide-68
SLIDE 68
  • Subjectivity — reasoning with self and other
  • PCMs
  • Histories

Key ideas

slide-69
SLIDE 69

Partial Commutative Monoids

  • A set S of elements
  • Join (⊕): commutative, associative, partial
  • Unit element 0: ∀e ∈ S, e⊕0 = 0⊕e = e

(S, ⊕, 0)

slide-70
SLIDE 70

Parallel composition

slide-71
SLIDE 71

child1 child2

||

parent

Parallel composition

slide-72
SLIDE 72

child1 child2

||

parent

  • commutative
  • associative
  • unit — idle thread
  • partial

Parallel composition

slide-73
SLIDE 73

child1 child2

||

parent

{ s1 ⊕ s2 }

Logical state split

slide-74
SLIDE 74

child1 child2

||

s1 ⊕ s2

parent

{ s1 ⊕ s2 }

s3

Logical state split

slide-75
SLIDE 75

parent child1 || State that belongs to child1 child2

||

s1

{ s1 } { s1 ⊕ s2 }

Logical state split

s2 ⊕ s3

slide-76
SLIDE 76

child1 || State that belongs to child2 child2

||

s2

{ s1 } { s2 }

parent

{ s1 ⊕ s2 }

Logical state split

s1 ⊕ s3

slide-77
SLIDE 77

|| ||

z2

{ s2 } { s1 } { z1 } { z2 } { s1 ⊕ s2 }

Logical state split

child1 child2 parent

z1 ⊕ z3

slide-78
SLIDE 78

z1 ⊕ z2

||

New state that belongs to parent′

||

parent′

{ s2 } { s1 } { z1 } { z2 } { s1 ⊕ s2 } { z1 ⊕ z2 }

Logical state split

child1 child2 parent

z3

slide-79
SLIDE 79
  • Subjectivity — reasoning with self and other
  • PCMs
  • Histories

Key ideas

slide-80
SLIDE 80
  • Subjectivity — reasoning with self and other
  • PCMs — uniform way to logically split state
  • Histories

Key ideas

slide-81
SLIDE 81

Familiar PCM: finite heaps

slide-82
SLIDE 82

Familiar PCM: finite heaps

  • Heaps are partial finite maps nat →

Val

slide-83
SLIDE 83

Familiar PCM: finite heaps

  • Heaps are partial finite maps nat →

Val

  • Join operation ⊕ is disjoint union
slide-84
SLIDE 84

Familiar PCM: finite heaps

  • Heaps are partial finite maps nat →

Val

  • Join operation ⊕ is disjoint union
  • Unit element 0 is the empty heap ∅
slide-85
SLIDE 85

Concurroid for thread-local state

slide-86
SLIDE 86

hs

  • hs — heap, logically owned by this thread

Concurroid for thread-local state

slide-87
SLIDE 87

hs

  • hs — heap, logically owned by this thread
  • ho — heap, owned by others

ho ∅

Concurroid for thread-local state

slide-88
SLIDE 88

hs

  • hs — heap, logically owned by this thread
  • ho — heap, owned by others

ho ∅

Concurroid for thread-local state

Concurrent Separation Logic
 O’Hearn [CONCUR’04]

slide-89
SLIDE 89

*x := 5; *y := 7;

slide-90
SLIDE 90

*x := 5; *y := 7;

{ hs = x ↦ - ⊕ y ↦ - ⋀ ho = h }

slide-91
SLIDE 91

*x := 5; *y := 7;

{ hs = x ↦ - ⊕ y ↦ - ⋀ ho = h }

  • disjoint by resource definition
slide-92
SLIDE 92

*x := 5; *y := 7;

{ hs = x ↦ - ⊕ y ↦ - ⋀ ho = h }

{ hs = x ↦ - ⋀ ho = y ↦ ? ⊕ h }

  • disjoint by resource definition
slide-93
SLIDE 93

*x := 5; *y := 7;

{ hs = x ↦ - ⊕ y ↦ - ⋀ ho = h }

{ hs = x ↦ - ⋀ ho = y ↦ ? ⊕ h } { hs = y ↦ - ⋀ ho = x ↦ ? ⊕ h }

  • disjoint by resource definition
slide-94
SLIDE 94

*x := 5; *y := 7;

{ hs = x ↦ - ⊕ y ↦ - ⋀ ho = h }

{ hs = x ↦ - ⋀ ho = y ↦ ? ⊕ h } { hs = y ↦ - ⋀ ho = x ↦ ? ⊕ h } { hs = x ↦ 5 ⋀ ho = y ↦ ? ⊕ h } { hs = y ↦ 7 ⋀ ho = x ↦ ? ⊕ h }

  • disjoint by resource definition
slide-95
SLIDE 95

*x := 5; *y := 7;

{ hs = x ↦ - ⊕ y ↦ - ⋀ ho = h }

{ hs = x ↦ - ⋀ ho = y ↦ ? ⊕ h } { hs = y ↦ - ⋀ ho = x ↦ ? ⊕ h } { hs = x ↦ 5 ⋀ ho = y ↦ ? ⊕ h } { hs = y ↦ 7 ⋀ ho = x ↦ ? ⊕ h }

{ hs = x ↦ 5 ⊕ y ↦ 7 ⋀ ho = h }

  • disjoint by resource definition
slide-96
SLIDE 96
  • Subjectivity — reasoning with self and other
  • PCMs — uniform way to logically split state
  • Histories

Key ideas

slide-97
SLIDE 97
  • Subjectivity — reasoning with self and other
  • PCMs — uniform way to logically split state
  • Histories

Key ideas

slide-98
SLIDE 98
  • Subjectivity — reasoning with self and other
  • PCMs — uniform way to logically split state
  • Histories

Key ideas

Sergey et al. [ESOP’15]

slide-99
SLIDE 99

push(x)

Atomic stack specifications

slide-100
SLIDE 100

push(x)

{ S = xs } { S′ = x :: xs }

Atomic stack specifications

slide-101
SLIDE 101

x :: xs xs

tk →

Atomic stack specifications

slide-102
SLIDE 102

x :: xs xs

“timestamp”

tk →

Atomic stack specifications

slide-103
SLIDE 103

tk →

slide-104
SLIDE 104

tk → tk+1 →

tk+2 → tk+3 →

……

tk+n → tk+4 →

slide-105
SLIDE 105

Changes by this thread Changes by other threads

tk+4 →

tk+1 →

tk+3 → tk+n →

tk →

tk+2 →

……

slide-106
SLIDE 106

tk+4 →

tk+1 →

tk+3 → tk+n →

tk →

tk+2 →

……

slide-107
SLIDE 107 t k+4 → t k+1 → t k+3 → t k+n → t k → t k+2 → ……

Hs Ho

Hs, Ho — self/other contributions to the resource history

slide-108
SLIDE 108

Histories are like heaps!

slide-109
SLIDE 109

Histories are like heaps!

  • Histories are partial finite maps nat → AbsOp
slide-110
SLIDE 110

Histories are like heaps!

  • Histories are partial finite maps nat → AbsOp
  • Join operation ⊕ is disjoint union
slide-111
SLIDE 111

Histories are like heaps!

  • Histories are partial finite maps nat → AbsOp
  • Join operation ⊕ is disjoint union
  • Unit element 0 is the empty history ∅
slide-112
SLIDE 112

Specifying stacks with histories

Cstack =

Hs Ho

slide-113
SLIDE 113

Specifying stacks with histories

Cstack =

  • Hs, Ho = { tk ↦ (xs, x::xs), tn ↦ (x::xs, xs), … }

Hs Ho

slide-114
SLIDE 114

Specifying stacks with histories

Cstack =

  • Hs, Ho = { tk ↦ (xs, x::xs), tn ↦ (x::xs, xs), … }
  • Joint part is specific for each implementation

Hs Ho

slide-115
SLIDE 115

Specifying stacks with histories

Cstack =

  • Hs, Ho = { tk ↦ (xs, x::xs), tn ↦ (x::xs, xs), … }
  • Joint part is specific for each implementation
  • Adjacent history entries agree on overlapping abstract states

Hs Ho

slide-116
SLIDE 116

push(x)

{ ∃t, xs. Hs = t ↦ (xs, x::xs) ⋀ H ⊆ Ho ⋀ H < t }@Cstack

Stack specification

{ Hs = ∅ ⋀ H ⊆ Ho }

slide-117
SLIDE 117

push(x)

{ ∃t, xs. Hs = t ↦ (xs, x::xs) ⋀ H ⊆ Ho ⋀ H < t }@Cstack

Stack specification

{ Hs = ∅ ⋀ H ⊆ Ho }

self-contribution is a single entry

slide-118
SLIDE 118

push(x)

{ ∃t, xs. Hs = t ↦ (xs, x::xs) ⋀ H ⊆ Ho ⋀ H < t }@Cstack

Stack specification

{ Hs = ∅ ⋀ H ⊆ Ho }

t allocated during the call

slide-119
SLIDE 119

{ res. if (res = Some x) then ∃t, xs. H ⊆ Ho ⋀ H < t ⋀ Hs = t ↦ (x::xs, xs)) else ∃t. H ⊆ Ho ⋀ H ≤ t ⋀ Hs = ∅ ⋀ t ↦ (_, Nil) ⊆ Ho }@Cstack

Stack specification

pop()

{ Hs = ∅ ⋀ H ⊆ Ho }

slide-120
SLIDE 120

{ res. if (res = Some x) then ∃t, xs. H ⊆ Ho ⋀ H < t ⋀ Hs = t ↦ (x::xs, xs)) else ∃t. H ⊆ Ho ⋀ H ≤ t ⋀ Hs = ∅ ⋀ t ↦ (_, Nil) ⊆ Ho }@Cstack

Stack specification

pop()

{ Hs = ∅ ⋀ H ⊆ Ho }

  • pop has hit Nil during its execution at the moment t
slide-121
SLIDE 121

{ res. if (res = Some x) then ∃t, xs. H ⊆ Ho ⋀ H < t ⋀ Hs = t ↦ (x::xs, xs)) else ∃t. H ⊆ Ho ⋀ H ≤ t ⋀ Hs = ∅ ⋀ t ↦ (_, Nil) ⊆ Ho }@Cstack

Stack specification

pop()

{ Hs = ∅ ⋀ H ⊆ Ho }

no self-contributions initially?

slide-122
SLIDE 122

Framing in FCSL

slide-123
SLIDE 123

Framing in FCSL

my_program

slide-124
SLIDE 124

Framing in FCSL

{ }

my_program

slide-125
SLIDE 125

Framing in FCSL

{ }

my_program

{ }

slide-126
SLIDE 126

Framing in FCSL

{ }

my_program

{ }

slide-127
SLIDE 127

Framing in FCSL

{ }

my_program

{ }

Works for any PCM, not just heaps!

slide-128
SLIDE 128

push(x)

{ ∃t, xs. H ⊆ Ho ⋀ H < t ⋀ Hs = t ↦ (xs, x::xs) }@Cstack { Hs = ∅ ⋀ H ⊆ Ho }

Framing histories

slide-129
SLIDE 129

push(x)

{ ∃t, xs. H2 ⊆ Ho ⋀ H1 ⊕ H2 < t ⋀ Hs = H1 ⊕ t ↦ (xs, x::xs) }@Cstack

{ Hs = H1 ⋀ H2 ⊆ Ho }

Framing histories

slide-130
SLIDE 130

push(x)

{ ∃t, xs. H2 ⊆ Ho ⋀ H1 ⊕ H2 < t ⋀ Hs = H1 ⊕ t ↦ (xs, x::xs) }@Cstack

{ Hs = H1 ⋀ H2 ⊆ Ho }

Framing histories

initial self-contribution

slide-131
SLIDE 131

push(x)

{ ∃t, xs. H2 ⊆ Ho ⋀ H1 ⊕ H2 < t ⋀ Hs = H1 ⊕ t ↦ (xs, x::xs) }@Cstack

{ Hs = H1 ⋀ H2 ⊆ Ho }

Framing histories

final self-contribution

slide-132
SLIDE 132
  • Subjectivity — reasoning with self and other
  • PCMs — uniform way to logically split state
  • Histories

Key ideas

slide-133
SLIDE 133
  • Subjectivity — reasoning with self and other
  • PCMs — uniform way to logically split state
  • Histories — logical updates via auxiliary state

Key ideas

slide-134
SLIDE 134

How useful are
 histories for clients?

slide-135
SLIDE 135

A stack client program

  • Two threads: producer and consumer
  • Ap — an n-element producer array
  • Ac — an n-element consumer array
  • A shared concurrent stack S is used as a buffer
  • The goal: prove the exchange correct
slide-136
SLIDE 136
  • Pushed H E iff 


E is a multiset of elements, pushed in H

  • Popped H E iff 


E is a multiset of elements, popped in H

Auxiliary Predicates

slide-137
SLIDE 137

letrec produce(i : nat) = { if (i == n) then return; else { S.push(Ap[i]); produce(i+1); } }

slide-138
SLIDE 138

letrec produce(i : nat) = { if (i == n) then return; else { S.push(Ap[i]); produce(i+1); } }

{ Ap ↦ L ⋀ Pushed Hs L[< i] ⋀ Popped Hs ∅ } { Ap ↦ L ⋀ Pushed Hs L[< n] ⋀ Popped Hs ∅ }

slide-139
SLIDE 139

letrec produce(i : nat) = { if (i == n) then return; else { S.push(Ap[i]); produce(i+1); } }

{ Ap ↦ L ⋀ Pushed Hs L[< i] ⋀ Popped Hs ∅ } { Ap ↦ L ⋀ Pushed Hs L[< n] ⋀ Popped Hs ∅ }

slide-140
SLIDE 140

letrec consume(i : nat) = { if (i == n) then return; else { t ← S.pop(); if t == Some v 
 then { Ac[i] := v; consume(i+1); } else consume(i); } }

slide-141
SLIDE 141

letrec consume(i : nat) = { if (i == n) then return; else { t ← S.pop(); if t == Some v 
 then { Ac[i] := v; consume(i+1); } else consume(i); } }

{∃L, Ac ↦ L ⋀ Pushed Hs ∅ ⋀ Popped Hs L[< i] } {∃L, Ac ↦ L ⋀ Pushed Hs ∅ ⋀ Popped Hs L[< n] }

slide-142
SLIDE 142

letrec consume(i : nat) = { if (i == n) then return; else { t ← S.pop(); if t == Some v 
 then { Ac[i] := v; consume(i+1); } else consume(i); } }

{∃L, Ac ↦ L ⋀ Pushed Hs ∅ ⋀ Popped Hs L[< i] } {∃L, Ac ↦ L ⋀ Pushed Hs ∅ ⋀ Popped Hs L[< n] }

slide-143
SLIDE 143

consume(0) produce(0)

slide-144
SLIDE 144

consume(0) produce(0)

     

      

hide Cstack(hS) in

slide-145
SLIDE 145

consume(0) produce(0)

     

      

No other threads
 can interfere on S

hide Cstack(hS) in

slide-146
SLIDE 146

consume(0) produce(0)

     

      

{ Ap ↦ L ⊕ Ac ↦ L′ ⊕ hS }

hide Cstack(hS) in

slide-147
SLIDE 147

consume(0) produce(0)

     

      

{ Ap ↦ L ⊕ Ac ↦ L′ ⊕ hS }

{ Ap ↦ L { Ac ↦ L′

hide Cstack(hS) in

slide-148
SLIDE 148

consume(0) produce(0)

     

      

{ Ap ↦ L ⊕ Ac ↦ L′ ⊕ hS }

{ Ap ↦ L { Ac ↦ L′ ⋀ Pushed Hs ∅ ⋀ Popped Hs ∅ } ⋀ Pushed Hs ∅ ⋀ Popped Hs ∅ }

hide Cstack(hS) in

slide-149
SLIDE 149

consume(0) produce(0)

     

      

{ Ap ↦ L ⊕ Ac ↦ L′ ⊕ hS }

{ Ap ↦ L { Ac ↦ L′ ⋀ Pushed Hs ∅ ⋀ Popped Hs ∅ } ⋀ Pushed Hs ∅ ⋀ Popped Hs ∅ } { Ap ↦ L ⋀ 
 Pushed Hs L[< n] ⋀ 
 Popped Hs ∅ } { Ac ↦ L′′ ⋀ 
 Pushed Hs ∅ ⋀ 
 Popped Hs L′′[<n] }

hide Cstack(hS) in

slide-150
SLIDE 150

consume(0) produce(0)

     

      

{ Ap ↦ L ⊕ Ac ↦ L′ ⊕ hS }

{ Ap ↦ L { Ac ↦ L′ ⋀ Pushed Hs ∅ ⋀ Popped Hs ∅ } ⋀ Pushed Hs ∅ ⋀ Popped Hs ∅ } { Ap ↦ L ⋀ 
 Pushed Hs L[< n] ⋀ 
 Popped Hs ∅ } { Ac ↦ L′′ ⋀ 
 Pushed Hs ∅ ⋀ 
 Popped Hs L′′[<n] }

These are the only changes 
 in the stack’s history

hide Cstack(hS) in

slide-151
SLIDE 151

consume(0) produce(0)

     

      

{ Ap ↦ L ⊕ Ac ↦ L′ ⊕ hS }

{ Ap ↦ L { Ac ↦ L′ ⋀ Pushed Hs ∅ ⋀ Popped Hs ∅ } ⋀ Pushed Hs ∅ ⋀ Popped Hs ∅ } { Ap ↦ L ⋀ 
 Pushed Hs L[< n] ⋀ 
 Popped Hs ∅ } { Ac ↦ L′′ ⋀ 
 Pushed Hs ∅ ⋀ 
 Popped Hs L′′[<n] }

{ Ap ↦ L ⊕ Ac ↦ L′′ ⊕ hS′ ⋀ L =set L′′}

hide Cstack(hS) in

slide-152
SLIDE 152

consume(0) produce(0)

     

      

{ Ap ↦ L ⊕ Ac ↦ L′ ⊕ hS }

{ Ap ↦ L { Ac ↦ L′ ⋀ Pushed Hs ∅ ⋀ Popped Hs ∅ } ⋀ Pushed Hs ∅ ⋀ Popped Hs ∅ } { Ap ↦ L ⋀ 
 Pushed Hs L[< n] ⋀ 
 Popped Hs ∅ } { Ac ↦ L′′ ⋀ 
 Pushed Hs ∅ ⋀ 
 Popped Hs L′′[<n] }

{ Ap ↦ L ⊕ Ac ↦ L′′ ⊕ hS′ ⋀ L =set L′′}

hide Cstack(hS) in

slide-153
SLIDE 153

More use for histories

(see the paper)

slide-154
SLIDE 154

More use for histories

  • Verifying atomic snapshots

(see the paper)

slide-155
SLIDE 155

More use for histories

  • Verifying atomic snapshots
  • Instantiating higher-order concurrent structures

(see the paper)

slide-156
SLIDE 156

More use for histories

  • Verifying atomic snapshots
  • Instantiating higher-order concurrent structures
  • Deriving sequential specifications via hiding

(see the paper)

slide-157
SLIDE 157

More use for histories

  • Verifying atomic snapshots
  • Instantiating higher-order concurrent structures
  • Deriving sequential specifications via hiding

(see the paper)

slide-158
SLIDE 158

To take away

slide-159
SLIDE 159

To take away

  • Histories as auxiliary state
  • Expressive abstraction for concurrent specs
slide-160
SLIDE 160

To take away

  • Histories as auxiliary state
  • Expressive abstraction for concurrent specs
  • Histories are a PCM
  • They are subject of the same rules as heaps
slide-161
SLIDE 161

To take away

  • Histories as auxiliary state
  • Expressive abstraction for concurrent specs
  • Histories are a PCM
  • They are subject of the same rules as heaps
  • Historical reasoning requires subjectivity
  • History-based specs often talk about the effect of other threads
slide-162
SLIDE 162

To take away

  • Histories as auxiliary state
  • Expressive abstraction for concurrent specs
  • Histories are a PCM
  • They are subject of the same rules as heaps
  • Historical reasoning requires subjectivity
  • History-based specs often talk about the effect of other threads

software.imdea.org/fcsl

slide-163
SLIDE 163

To take away

  • Histories as auxiliary state
  • Expressive abstraction for concurrent specs
  • Histories are a PCM
  • They are subject of the same rules as heaps
  • Historical reasoning requires subjectivity
  • History-based specs often talk about the effect of other threads

Thanks!

software.imdea.org/fcsl

slide-164
SLIDE 164
slide-165
SLIDE 165

Q&A slides

slide-166
SLIDE 166

Owicki-Gries (1976) CSL (2004) Rely-Guarantee (1983) SAGL (2007) RGSep (2007) Deny-Guarantee (2009) CAP (2010) Jacobs-Piessens (2011) Liang-Feng (2013) LRG (2009) SCSL (2013) HOCAP (2013) iCAP (2014) Iris (2015) CaReSL (2013) FCSL (2014) TaDA (2014) CoLoSL (2015) Gotsman-al (2007) HLRG (2010) Bornat-al (2005) RGSim (2012)

slide-167
SLIDE 167

How is your stuff different from 


  • ther existing concurrent logics?
  • [Owicki-Gries:CACM76] - reasoning about parallel composition is not compositional; subjectivity fixes that;
  • [OHearn:CONCUR04] - only one type of resources — critical sections; 


FCSL allows one to define arbitrary resources;

  • [Feng-al:ESOP07,Vafeiadis-Parkinson:CONCUR07] - framing over Rely/Guarantee, but only one shared

resource: FCSL allows multiple ones;

  • [Feng:POPL09] - introduced local Rely/Guarantee; FCSL improves on it by introducing 


a subjective state and explicitly identifying resources as STS;

  • [DinsdaleYoung-al:ECOOP10] - first introduced concurred protocols;


FCSL generalises permissions - self-state defines what a thread is allowed to do with a resource;

  • [DinsdaleYoung-al:POPL13] - general framework for concurrency logic;


FCSL is a particular logic, not clear whether it is an instance of Views;

  • [Turon-al:ICFP13] - CaReSL and reasoning about contextual refinement;


FCSL doesn’t address CR, in our experience it’s never required for Hoare-style reasoning;

  • [Svendsen-al:ESOP13,ESOP14] - use much richer semantic domain, 


FCSL uses transitions and communication instead of view-shifts for changes in state and composition of resources;

  • [Raad-al:ESOP15] - different notion of subjectivity, no self/other dichotomy, no observation made about PCMs.

FCSL’s assertions work explicitly with state variables.

slide-168
SLIDE 168

How is your stuff different from Iris?

  • Iris makes the same observations as FCSL did in 2014 (PCMs, Invariants);
  • Iris doesn’t have hiding and self/other dichotomy;
  • It considers more primitive “building blocks” and encodes protocols 


as STSs + interpretation;

  • This encoding is made default in FCSL, and so far it suffices;
  • Currently, FCSL doesn’t support abstract atomicity in Iris/iCAP sense


(however, it can recover most of it through the choice of PCMs). Jung-al [POPL’15]

slide-169
SLIDE 169

Encoding verification in FCSL

slide-170
SLIDE 170

Encoding verification in FCSL

Program Definition my_prog: STSep (p, q) := Do c.

slide-171
SLIDE 171

Encoding verification in FCSL

Program Definition my_prog: STSep (p, q) := Do c.

  • Program c’s weakest pre- and strongest postconditions (p*, q*) wrt. safety, 


inferred from the types of basic commands (ret, par, bind);

has type STSep (p*, q*)

slide-172
SLIDE 172

Encoding verification in FCSL

Program Definition my_prog: STSep (p, q) := Do c.

  • Program c’s weakest pre- and strongest postconditions (p*, q*) wrt. safety, 


inferred from the types of basic commands (ret, par, bind);

  • Do encodes the application of the rule of consequence (p*, q*) ⊑ (p, q);

Notation for do (_ : (p*, q*) ⊑ (p, q)) c

slide-173
SLIDE 173

Encoding verification in FCSL

Program Definition my_prog: STSep (p, q) := Do c.

  • Program c’s weakest pre- and strongest postconditions (p*, q*) wrt. safety, 


inferred from the types of basic commands (ret, par, bind);

  • Do encodes the application of the rule of consequence (p*, q*) ⊑ (p, q);
  • The client constructs the proof of (p*, q*) ⊑ (p, q) interactively;

Notation for do (_ : (p*, q*) ⊑ (p, q)) c

slide-174
SLIDE 174

Encoding verification in FCSL

Program Definition my_prog: STSep (p, q) := Do c.

  • Program c’s weakest pre- and strongest postconditions (p*, q*) wrt. safety, 


inferred from the types of basic commands (ret, par, bind);

  • Do encodes the application of the rule of consequence (p*, q*) ⊑ (p, q);
  • The client constructs the proof of (p*, q*) ⊑ (p, q) interactively;
  • The obligations are reduced via structural lemmas (inference rules).

Notation for do (_ : (p*, q*) ⊑ (p, q)) c

slide-175
SLIDE 175

Program Libs Conc Acts Stab Main Total Build CAS-lock 63 291 509 358 27 1248 1m 1s Ticketed lock 58 310 706 457 116 1647 2m 46s Increment 26

  • 44

70 8s Allocator 82

  • 192

274 14s Pair snapshot 167 233 107 80 51 638 4m 7s Treiber stack 56 323 313 133 155 980 2m 41s Spanning tree 348 215 162 217 305 1247 1m 11s Flat combiner 92 442 672 538 281 2025 10m 55s

  • Seq. stack

65

  • 125

190 1m 21s FC-stack 50

  • 114

164 44s Prod/Cons 365

  • 243

608 2m 43s

Implementation and evaluation

slide-176
SLIDE 176

Proof of push specification

slide-177
SLIDE 177

Proof of push specification

Next Obligation. apply: gh=>i [h hS][B][v] X C. case: C (C) X=>_ [_][xa][->{i}][_][xp][xt][->] Cp Ct Ca C [P S H]. rewrite (getC Cp C) !(getC Ct C) /= in P S H. rewrite -!joinA joinCA in C *. apply: step; apply: val_extend=>//;apply: (gh_ex h); apply: val_do=>//. move=>p' {xt S H C Ct Ca} xt [t][K] S H _ Ct s C M. case: {M} (menvs_coh M) (M) C=>_ [_][xp1][xa1][->{s}] Cp1 Ca M C. case/(menvs_split (injLE _ (erefl _)) Cp Cp1): M=>/= M _. have {M P} P : pv_self xp1 = p :-> v \+ hS by rewrite -(menvs_loc M). rewrite -joinCA in C *. apply: step; apply: val_extend=>//. apply: (gh_ex hS); apply: val_do; first by exists B, v. case=>{xp xp1 xa C Cp Cp1 Ca P} xp P Cp s /= C M. case: {M} (menvs_coh M) (M) C=>_ [_][xt1][xa][->{s}] Ct1 Ca M C. case/(menvs_split (injLA _ (erefl _)) Ct Ct1): M=>/= {xa1} M _. have {S} S : tb_self xt1 = Unit by rewrite -(menvs_loc M). have {xt Ct M H} H : [h <<= tb_other xt1] by apply: hist_trans H (hist_other M). rewrite joinA in C *. apply: step; apply: val_extend; first by apply/(star_coh_prec C). apply: (gh_ex h); apply: (gh_ex hS); apply: val_do.

  • by move=>C'; rewrite (getC Cp C') !(getC Ct1 C').

move=>b s X Y; case: Y (Y) X=>_ [xp1][xt][->{s}] {Cp} Cp1 Ct Y X. move=>xa1 /= {C} C M; case: (menvs_coh M)=>_ {M xa Ca} Ca1. rewrite (getC Cp1 Y) !(getC Ct Y) in X. case: b X; last first.

  • case=>{P S H} P S H.

apply: (gh_ex h); apply: (gh_ex hS); apply: val_do=>//. move=>{C} C; exists (prod A ptr), (e, p'). by rewrite (getC Cp1 C) !(getC Ct C). case=>{xp xt1 Ct1 P K S H} t' [ls][P K S H]. apply: val_ret=>//= m M; rewrite -(menvs_loc M). rewrite (getC Cp1 C) (getC Ct C). exists t', ls; split=>//. case: {M} (menvs_coh M) (M)=>_ /= X'. case: X' (X')=>_ [s][xa][->{m}] Y'; case: Y' (Y')=>_ [xp][xt1][->]. move=>Cp Ct1 Y' {Ca1} Ca {C} C. case/(menvs_split (injLE _ (erefl _)) Y Y'). case/(menvs_split (injLE _ (erefl _)) Cp1 Cp)=> _ M _. by rewrite (getC Ct1 C); apply: hist_trans H (hist_other M). apply: gh=>i [h hS] X C. case: C (C) X =>_ [_][xa][->][_][xp][xt][->] Cp Ct Ca C /= [P Ps H]. rewrite !(getC Ct C) !(getC Cp C) /= in P Ps H. rewrite joinAC /V /= starAC in C *. apply: step; apply: val_extend; first by apply/(star_coh_prec C). apply: (gh_ex (pv_self xp)); apply: val_do.

  • by move=>Cpa; rewrite (getC Cp Cpa).

move=>x m [B][v] Y X {Cp Ca C}. case: X (X) Y=>_ [xp1][xa1][->{m}] /= Cp Ca X S xt1 C M. rewrite {X} (getC Cp X) in S. case: (menvs_coh M)=>_ /= {Ct} Ct. have {P} P : tb_self xt1 = Unit by rewrite -(menvs_loc M). have {H M} H : [h <<= tb_other xt1] by apply: hist_trans H (hist_o M). apply: (gh_ex h); apply: (gh_ex (pv_self xp)). apply: val_do=>[_|]; first by exists B, v; rewrite!(getC Ct C). case=>m [t][ls][P2 S2 H2 K2]; exists t, ls; rewrite P2; split=>//. Qed.

slide-178
SLIDE 178

Next Obligation. apply: gh=>i [h hS][B][v] X C. case: C (C) X=>_ [_][xa][->{i}][_][xp][xt][->] Cp Ct Ca C [P S H]. rewrite (getC Cp C) !(getC Ct C) /= in P S H. rewrite -!joinA joinCA in C *. apply: step; apply: val_extend=>//;apply: (gh_ex h); apply: val_do=>//. move=>p' {xt S H C Ct Ca} xt [t][K] S H _ Ct s C M. case: {M} (menvs_coh M) (M) C=>_ [_][xp1][xa1][->{s}] Cp1 Ca M C. case/(menvs_split (injLE _ (erefl _)) Cp Cp1): M=>/= M _. have {M P} P : pv_self xp1 = p :-> v \+ hS by rewrite -(menvs_loc M). rewrite -joinCA in C *. apply: step; apply: val_extend=>//. apply: (gh_ex hS); apply: val_do; first by exists B, v. case=>{xp xp1 xa C Cp Cp1 Ca P} xp P Cp s /= C M. case: {M} (menvs_coh M) (M) C=>_ [_][xt1][xa][->{s}] Ct1 Ca M C. case/(menvs_split (injLA _ (erefl _)) Ct Ct1): M=>/= {xa1} M _. have {S} S : tb_self xt1 = Unit by rewrite -(menvs_loc M). have {xt Ct M H} H : [h <<= tb_other xt1] by apply: hist_trans H (hist_other M). rewrite joinA in C *. apply: step; apply: val_extend; first by apply/(star_coh_prec C). apply: (gh_ex h); apply: (gh_ex hS); apply: val_do.

  • by move=>C'; rewrite (getC Cp C') !(getC Ct1 C').

move=>b s X Y; case: Y (Y) X=>_ [xp1][xt][->{s}] {Cp} Cp1 Ct Y X. move=>xa1 /= {C} C M; case: (menvs_coh M)=>_ {M xa Ca} Ca1. rewrite (getC Cp1 Y) !(getC Ct Y) in X. case: b X; last first.

  • case=>{P S H} P S H.

apply: (gh_ex h); apply: (gh_ex hS); apply: val_do=>//. move=>{C} C; exists (prod A ptr), (e, p'). by rewrite (getC Cp1 C) !(getC Ct C). case=>{xp xt1 Ct1 P K S H} t' [ls][P K S H]. apply: val_ret=>//= m M; rewrite -(menvs_loc M). rewrite (getC Cp1 C) (getC Ct C). exists t', ls; split=>//. case: {M} (menvs_coh M) (M)=>_ /= X'. case: X' (X')=>_ [s][xa][->{m}] Y'; case: Y' (Y')=>_ [xp][xt1][->]. move=>Cp Ct1 Y' {Ca1} Ca {C} C. case/(menvs_split (injLE _ (erefl _)) Y Y'). case/(menvs_split (injLE _ (erefl _)) Cp1 Cp)=> _ M _. by rewrite (getC Ct1 C); apply: hist_trans H (hist_other M). apply: gh=>i [h hS] X C. case: C (C) X =>_ [_][xa][->][_][xp][xt][->] Cp Ct Ca C /= [P Ps H]. rewrite !(getC Ct C) !(getC Cp C) /= in P Ps H. rewrite joinAC /V /= starAC in C *. apply: step; apply: val_extend; first by apply/(star_coh_prec C). apply: (gh_ex (pv_self xp)); apply: val_do.

  • by move=>Cpa; rewrite (getC Cp Cpa).

move=>x m [B][v] Y X {Cp Ca C}. case: X (X) Y=>_ [xp1][xa1][->{m}] /= Cp Ca X S xt1 C M. rewrite {X} (getC Cp X) in S. case: (menvs_coh M)=>_ /= {Ct} Ct. have {P} P : tb_self xt1 = Unit by rewrite -(menvs_loc M). have {H M} H : [h <<= tb_other xt1] by apply: hist_trans H (hist_o M). apply: (gh_ex h); apply: (gh_ex (pv_self xp)). apply: val_do=>[_|]; first by exists B, v; rewrite!(getC Ct C). case=>m [t][ls][P2 S2 H2 K2]; exists t, ls; rewrite P2; split=>//. Qed.

seq seq seq seq fun_call fun_call fun_call fun_call fun_call fun_call return

Proof of push specification

slide-179
SLIDE 179

Next Obligation. apply: gh=>i [h hS][B][v] X C. case: C (C) X=>_ [_][xa][->{i}][_][xp][xt][->] Cp Ct Ca C [P S H]. rewrite (getC Cp C) !(getC Ct C) /= in P S H. rewrite -!joinA joinCA in C *. apply: step; apply: val_extend=>//;apply: (gh_ex h); apply: val_do=>//. move=>p' {xt S H C Ct Ca} xt [t][K] S H _ Ct s C M. case: {M} (menvs_coh M) (M) C=>_ [_][xp1][xa1][->{s}] Cp1 Ca M C. case/(menvs_split (injLE _ (erefl _)) Cp Cp1): M=>/= M _. have {M P} P : pv_self xp1 = p :-> v \+ hS by rewrite -(menvs_loc M). rewrite -joinCA in C *. apply: step; apply: val_extend=>//. apply: (gh_ex hS); apply: val_do; first by exists B, v. case=>{xp xp1 xa C Cp Cp1 Ca P} xp P Cp s /= C M. case: {M} (menvs_coh M) (M) C=>_ [_][xt1][xa][->{s}] Ct1 Ca M C. case/(menvs_split (injLA _ (erefl _)) Ct Ct1): M=>/= {xa1} M _. have {S} S : tb_self xt1 = Unit by rewrite -(menvs_loc M). have {xt Ct M H} H : [h <<= tb_other xt1] by apply: hist_trans H (hist_other M). rewrite joinA in C *. apply: step; apply: val_extend; first by apply/(star_coh_prec C). apply: (gh_ex h); apply: (gh_ex hS); apply: val_do.

  • by move=>C'; rewrite (getC Cp C') !(getC Ct1 C').

move=>b s X Y; case: Y (Y) X=>_ [xp1][xt][->{s}] {Cp} Cp1 Ct Y X. move=>xa1 /= {C} C M; case: (menvs_coh M)=>_ {M xa Ca} Ca1. rewrite (getC Cp1 Y) !(getC Ct Y) in X. case: b X; last first.

  • case=>{P S H} P S H.

apply: (gh_ex h); apply: (gh_ex hS); apply: val_do=>//. move=>{C} C; exists (prod A ptr), (e, p'). by rewrite (getC Cp1 C) !(getC Ct C). case=>{xp xt1 Ct1 P K S H} t' [ls][P K S H]. apply: val_ret=>//= m M; rewrite -(menvs_loc M). rewrite (getC Cp1 C) (getC Ct C). exists t', ls; split=>//. case: {M} (menvs_coh M) (M)=>_ /= X'. case: X' (X')=>_ [s][xa][->{m}] Y'; case: Y' (Y')=>_ [xp][xt1][->]. move=>Cp Ct1 Y' {Ca1} Ca {C} C. case/(menvs_split (injLE _ (erefl _)) Y Y'). case/(menvs_split (injLE _ (erefl _)) Cp1 Cp)=> _ M _. by rewrite (getC Ct1 C); apply: hist_trans H (hist_other M). apply: gh=>i [h hS] X C. case: C (C) X =>_ [_][xa][->][_][xp][xt][->] Cp Ct Ca C /= [P Ps H]. rewrite !(getC Ct C) !(getC Cp C) /= in P Ps H. rewrite joinAC /V /= starAC in C *. apply: step; apply: val_extend; first by apply/(star_coh_prec C). apply: (gh_ex (pv_self xp)); apply: val_do.

  • by move=>Cpa; rewrite (getC Cp Cpa).

move=>x m [B][v] Y X {Cp Ca C}. case: X (X) Y=>_ [xp1][xa1][->{m}] /= Cp Ca X S xt1 C M. rewrite {X} (getC Cp X) in S. case: (menvs_coh M)=>_ /= {Ct} Ct. have {P} P : tb_self xt1 = Unit by rewrite -(menvs_loc M). have {H M} H : [h <<= tb_other xt1] by apply: hist_trans H (hist_o M). apply: (gh_ex h); apply: (gh_ex (pv_self xp)). apply: val_do=>[_|]; first by exists B, v; rewrite!(getC Ct C). case=>m [t][ls][P2 S2 H2 K2]; exists t, ls; rewrite P2; split=>//. Qed.

seq seq seq seq fun_call fun_call fun_call fun_call fun_call fun_call return

Proof of push specification

proving stability proving stability proving stability proving stability proving stability

slide-180
SLIDE 180

Why do you need the explicit other? Other logics don’t have it!

  • Other makes it possible to state open-world assumptions 


in a straightforward way (e.g., in push);

  • It allows us to use hiding for uniformly cancelling the interference;
  • Some algorithms are given more natural specs via other-contributions

(e.g., stack’s pop and atomic snapshots).

slide-181
SLIDE 181

Composing concurrent resources

slide-182
SLIDE 182

Connect ownership-transferring transitions with right polarity

Composing concurrent resources

slide-183
SLIDE 183

Connect ownership-transferring transitions with right polarity

acq acq acq acq rel rel rel rel

  • Some channels might be left loose
  • Some channels might be shut down
  • Same channels might be connected several times

Composing concurrent resources

slide-184
SLIDE 184

Can you extract the verified program
 from your Coq implementation and run it?

slide-185
SLIDE 185

Can you extract the verified program
 from your Coq implementation and run it?

Not yet.

slide-186
SLIDE 186

Can you extract the verified program
 from your Coq implementation and run it?

Not yet.

  • Imperative programs are composed and verified 


(i.e., type-checked) by means of Coq;

  • They cannot be run by means of Gallina’s operational semantics;
  • The reason for that is the necessity to reason about 


concurrent computations and potentially diverging programs;

  • Extraction will require proving operationally of arbitrary 


atomic actions.