Permissions and concurrency: a breakthrough and a Grand Challenge - - PowerPoint PPT Presentation

permissions and concurrency a breakthrough and a grand
SMART_READER_LITE
LIVE PREVIEW

Permissions and concurrency: a breakthrough and a Grand Challenge - - PowerPoint PPT Presentation

Permissions and concurrency: a breakthrough and a Grand Challenge Richard Bornat (Middlesex, UK) 22nd Oct 2004 1 Typing one of the things that formalism has given us; 2 Typing one of the things that formalism has given us; a


slide-1
SLIDE 1

Permissions and concurrency: a breakthrough and a Grand Challenge

Richard Bornat (Middlesex, UK) 22nd Oct 2004

1

slide-2
SLIDE 2

Typing

◮ one of the things that formalism has given us; 2

slide-3
SLIDE 3

Typing

◮ one of the things that formalism has given us; ◮ a relatively recent success (only took C in the early 90s); 2

slide-4
SLIDE 4

Typing

◮ one of the things that formalism has given us; ◮ a relatively recent success (only took C in the early 90s); ◮ never a Grand Challenge; 2

slide-5
SLIDE 5

Typing

◮ one of the things that formalism has given us; ◮ a relatively recent success (only took C in the early 90s); ◮ never a Grand Challenge; ◮ who could live without it? (well ok, low life). 2

slide-6
SLIDE 6

Typing

◮ one of the things that formalism has given us; ◮ a relatively recent success (only took C in the early 90s); ◮ never a Grand Challenge; ◮ who could live without it? (well ok, low life). ◮ (why do the low life do without types? what can we do for

them?)

2

slide-7
SLIDE 7

A Rough History

Types began with Russell, but we got them from FORTRAN, as hints to a compiler.

3

slide-8
SLIDE 8

A Rough History

Types began with Russell, but we got them from FORTRAN, as hints to a compiler. COBOL had structural descriptions, not seen as types.

3

slide-9
SLIDE 9

A Rough History

Types began with Russell, but we got them from FORTRAN, as hints to a compiler. COBOL had structural descriptions, not seen as types. We’ve tried typeless languages – e.g. BCPL – and run-time typed languages – e.g. Lisp.

3

slide-10
SLIDE 10

A Rough History

Types began with Russell, but we got them from FORTRAN, as hints to a compiler. COBOL had structural descriptions, not seen as types. We’ve tried typeless languages – e.g. BCPL – and run-time typed languages – e.g. Lisp. Types became popular as protection against wild use of pointers (instead of just a pointer, a pointer to an X structure) and procedure addresses (argument and result types).

3

slide-11
SLIDE 11

A Rough History

Types began with Russell, but we got them from FORTRAN, as hints to a compiler. COBOL had structural descriptions, not seen as types. We’ve tried typeless languages – e.g. BCPL – and run-time typed languages – e.g. Lisp. Types became popular as protection against wild use of pointers (instead of just a pointer, a pointer to an X structure) and procedure addresses (argument and result types). Typing is about static, value/state independent properties of names.

3

slide-12
SLIDE 12

A Rough History

Types began with Russell, but we got them from FORTRAN, as hints to a compiler. COBOL had structural descriptions, not seen as types. We’ve tried typeless languages – e.g. BCPL – and run-time typed languages – e.g. Lisp. Types became popular as protection against wild use of pointers (instead of just a pointer, a pointer to an X structure) and procedure addresses (argument and result types). Typing is about static, value/state independent properties of names. The world doesn’t yet believe in type inference, and the inventor of C++ has never been put on trial.

3

slide-13
SLIDE 13

Types are not enough

4

slide-14
SLIDE 14

Types are not enough

Types do not protect us from:

◮ dereferencing null pointers; 4

slide-15
SLIDE 15

Types are not enough

Types do not protect us from:

◮ dereferencing null pointers; ◮ double free; 4

slide-16
SLIDE 16

Types are not enough

Types do not protect us from:

◮ dereferencing null pointers; ◮ double free; ◮ rogue librarians (what does System.out.print(s) do?); 4

slide-17
SLIDE 17

Types are not enough

Types do not protect us from:

◮ dereferencing null pointers; ◮ double free; ◮ rogue librarians (what does System.out.print(s) do?); ◮ the ‘variant record error’; 4

slide-18
SLIDE 18

Types are not enough

Types do not protect us from:

◮ dereferencing null pointers; ◮ double free; ◮ rogue librarians (what does System.out.print(s) do?); ◮ the ‘variant record error’; ◮ ... 4

slide-19
SLIDE 19

Types are not enough

Types do not protect us from:

◮ dereferencing null pointers; ◮ double free; ◮ rogue librarians (what does System.out.print(s) do?); ◮ the ‘variant record error’; ◮ ...

“Well-typed programs do not go wrong”: we don’t apply a function to the wrong type of value. But the wrong value of the type ...

4

slide-20
SLIDE 20

Types are not enough

Types do not protect us from:

◮ dereferencing null pointers; ◮ double free; ◮ rogue librarians (what does System.out.print(s) do?); ◮ the ‘variant record error’; ◮ ...

“Well-typed programs do not go wrong”: we don’t apply a function to the wrong type of value. But the wrong value of the type ... hd([ ]), anybody?

4

slide-21
SLIDE 21

A classic resource problem

malloc/new gives you a pointer to a new-ish buffer (one you don’t

  • wn at the time of asking). You can do what you like with the pointer.

5

slide-22
SLIDE 22

A classic resource problem

malloc/new gives you a pointer to a new-ish buffer (one you don’t

  • wn at the time of asking). You can do what you like with the pointer.

(ISO C says you mustn’t do anything naughty, but nobody can tell if you do.)

5

slide-23
SLIDE 23

A classic resource problem

malloc/new gives you a pointer to a new-ish buffer (one you don’t

  • wn at the time of asking). You can do what you like with the pointer.

(ISO C says you mustn’t do anything naughty, but nobody can tell if you do.) free/dispose, given a pointer to a buffer you do own, takes the buffer away.

5

slide-24
SLIDE 24

A classic resource problem

malloc/new gives you a pointer to a new-ish buffer (one you don’t

  • wn at the time of asking). You can do what you like with the pointer.

(ISO C says you mustn’t do anything naughty, but nobody can tell if you do.) free/dispose, given a pointer to a buffer you do own, takes the buffer away. You are left with a pointer (maybe several copies of a pointer) which you are not allowed to use.

5

slide-25
SLIDE 25

A classic resource problem

malloc/new gives you a pointer to a new-ish buffer (one you don’t

  • wn at the time of asking). You can do what you like with the pointer.

(ISO C says you mustn’t do anything naughty, but nobody can tell if you do.) free/dispose, given a pointer to a buffer you do own, takes the buffer away. You are left with a pointer (maybe several copies of a pointer) which you are not allowed to use. Vivid analogy:“An unfrocked priest is capable of celebrating marriage but forbidden to do so” (Marek Sergot, talk on logic of permission and belief; see also Daily Telegraph, 21/vi/93).

5

slide-26
SLIDE 26

A classic resource problem

malloc/new gives you a pointer to a new-ish buffer (one you don’t

  • wn at the time of asking). You can do what you like with the pointer.

(ISO C says you mustn’t do anything naughty, but nobody can tell if you do.) free/dispose, given a pointer to a buffer you do own, takes the buffer away. You are left with a pointer (maybe several copies of a pointer) which you are not allowed to use. Vivid analogy:“An unfrocked priest is capable of celebrating marriage but forbidden to do so” (Marek Sergot, talk on logic of permission and belief; see also Daily Telegraph, 21/vi/93). (BTW, “Ownership types” and/or nulling disposed pointers don’t touch this problem.)

5

slide-27
SLIDE 27

The hardest kind of programming?

Concurrency – multi-threading, multi-processing – is notoriously difficult.

6

slide-28
SLIDE 28

The hardest kind of programming?

Concurrency – multi-threading, multi-processing – is notoriously difficult. 40 years ago, Dijkstra invented semaphores, mutual exclusion, critical sections (Cooperating Sequential Processes, 1965).

6

slide-29
SLIDE 29

The hardest kind of programming?

Concurrency – multi-threading, multi-processing – is notoriously difficult. 40 years ago, Dijkstra invented semaphores, mutual exclusion, critical sections (Cooperating Sequential Processes, 1965). – also fairness, deadlock, starvation, the Banker’s algorithm, bounded and unbounded buffer, ...

6

slide-30
SLIDE 30

The hardest kind of programming?

Concurrency – multi-threading, multi-processing – is notoriously difficult. 40 years ago, Dijkstra invented semaphores, mutual exclusion, critical sections (Cooperating Sequential Processes, 1965). – also fairness, deadlock, starvation, the Banker’s algorithm, bounded and unbounded buffer, ... “We have stipulated that processes should be connected loosely; by this we mean that apart from the (rare) moments of explicit intercommunication, the individual processes themselves are to be regarded as completely independent of each other.”

6

slide-31
SLIDE 31

Separation logic

7

slide-32
SLIDE 32

Separation logic

◮ Just a bastard child of BI (Pym, O’Hearn). 7

slide-33
SLIDE 33

Separation logic

◮ Just a bastard child of BI (Pym, O’Hearn). ◮ E → E′ (points to) is permission to read/write/dispose cell at

heap address E with contents E′.

7

slide-34
SLIDE 34

Separation logic

◮ Just a bastard child of BI (Pym, O’Hearn). ◮ E → E′ (points to) is permission to read/write/dispose cell at

heap address E with contents E′.

◮ → can also be read as ownership and/or a heap predicate. 7

slide-35
SLIDE 35

Separation logic

◮ Just a bastard child of BI (Pym, O’Hearn). ◮ E → E′ (points to) is permission to read/write/dispose cell at

heap address E with contents E′.

◮ → can also be read as ownership and/or a heap predicate. ◮ emp is no permission. 7

slide-36
SLIDE 36

Separation logic

◮ Just a bastard child of BI (Pym, O’Hearn). ◮ E → E′ (points to) is permission to read/write/dispose cell at

heap address E with contents E′.

◮ → can also be read as ownership and/or a heap predicate. ◮ emp is no permission. ◮ A ⋆ B (star) is separation of resource. 7

slide-37
SLIDE 37

Separation logic

◮ Just a bastard child of BI (Pym, O’Hearn). ◮ E → E′ (points to) is permission to read/write/dispose cell at

heap address E with contents E′.

◮ → can also be read as ownership and/or a heap predicate. ◮ emp is no permission. ◮ A ⋆ B (star) is separation of resource. ◮ A ∧ B (and) is identity of resource. 7

slide-38
SLIDE 38

Separation logic

◮ Just a bastard child of BI (Pym, O’Hearn). ◮ E → E′ (points to) is permission to read/write/dispose cell at

heap address E with contents E′.

◮ → can also be read as ownership and/or a heap predicate. ◮ emp is no permission. ◮ A ⋆ B (star) is separation of resource. ◮ A ∧ B (and) is identity of resource. ◮ A ∧ (B ⋆ true) is all A, partly B. 7

slide-39
SLIDE 39

Framing, hence small axioms

blank

8

slide-40
SLIDE 40

Framing, hence small axioms

{Q}C{R} {P ⋆ Q}C{P ⋆ R}

(modifies C ∩ vars P = ∅)

blank

8

slide-41
SLIDE 41

Framing, hence small axioms

{Q}C{R} {P ⋆ Q}C{P ⋆ R}

(modifies C ∩ vars P = ∅)

blank {Rx

E}

x:=E {R} {x → } [x]:=E {x → E} {E′ → E} x:=[E′] {E′ → E ∧ x = E} (x not free in E, E′) {emp} x:=new(E) {x → E} {E → } dispose E {emp}

8

slide-42
SLIDE 42

Concurrency rules

blank blank

9

slide-43
SLIDE 43

Concurrency rules

{Q1} C1 {R1} · · · {Qn} Cn {Rn} {Q1 ⋆ · · · ⋆ Qn} (C1 · · · Cn){R1 ⋆ · · · ⋆ Rn}

(non-interference-of-variables)

blank blank

9

slide-44
SLIDE 44

Concurrency rules

{Q1} C1 {R1} · · · {Qn} Cn {Rn} {Q1 ⋆ · · · ⋆ Qn} (C1 · · · Cn){R1 ⋆ · · · ⋆ Rn}

(non-interference-of-variables)

blank {(Q ⋆ Ir) ∧ B}C{R ⋆ Ir} {Q}with r when B do C od{R} blank

9

slide-45
SLIDE 45

Concurrency rules

{Q1} C1 {R1} · · · {Qn} Cn {Rn} {Q1 ⋆ · · · ⋆ Qn} (C1 · · · Cn){R1 ⋆ · · · ⋆ Rn}

(non-interference-of-variables)

blank {(Q ⋆ Ir) ∧ B}C{R ⋆ Ir} {Q}with r when B do C od{R} blank

◮ Both proved sound by Brookes. 9

slide-46
SLIDE 46

Concurrency rules

{Q1} C1 {R1} · · · {Qn} Cn {Rn} {Q1 ⋆ · · · ⋆ Qn} (C1 · · · Cn){R1 ⋆ · · · ⋆ Rn}

(non-interference-of-variables)

blank {(Q ⋆ Ir) ∧ B}C{R ⋆ Ir} {Q}with r when B do C od{R} blank

◮ Both proved sound by Brookes. ◮ A version of the CCR rule covers semaphores, in which C is

either m := m + 1 or m := m − 1.

9

slide-47
SLIDE 47

The ownership trick (O’Hearn 2002)

resource-bundle r : Vars full, b; full := false; Invariant (full ∧ b → ) ∨ (¬full ∧ emp) blank                    {emp} x := new(); {x → } with r when ¬full do {¬full ∧ emp ⋆ x → } b := x; {¬full ∧ emp ⋆ x → ∧ b = x} full := true {full ∧ b → ⋆ emp}

  • d

{emp} {emp} with r when full do {full ∧ b → ⋆ emp} y := b; {full ∧ b → ⋆ emp ∧ y = b} full := false {¬full ∧ emp ⋆ y → }

  • d;

{y → } dispose y {emp}                   

10

slide-48
SLIDE 48

The ownership trick (O’Hearn 2002)

resource-bundle r : Vars full, b; full := false; Invariant (full ∧ b → ) ∨ (¬full ∧ emp) blank                    {emp} x := new(); {x → } with r when ¬full do {¬full ∧ emp ⋆ x → } b := x; {¬full ∧ emp ⋆ x → ∧ b = x} full := true {full ∧ b → ⋆ emp}

  • d

{emp} {emp} with r when full do {full ∧ b → ⋆ emp} y := b; {full ∧ b → ⋆ emp ∧ y = b} full := false {¬full ∧ emp ⋆ y → }

  • d;

{y → } dispose y {emp}                   

10

slide-49
SLIDE 49

The ownership trick (O’Hearn 2002)

resource-bundle r : Vars full, b; full := false; Invariant (full ∧ b → ) ∨ (¬full ∧ emp) blank                    {emp} x := new(); {x → } with r when ¬full do {¬full ∧ emp ⋆ x → } b := x; {¬full ∧ emp ⋆ x → ∧ b = x} full := true {full ∧ b → ⋆ emp}

  • d

{emp} {emp} with r when full do {full ∧ b → ⋆ emp} y := b; {full ∧ b → ⋆ emp ∧ y = b} full := false {¬full ∧ emp ⋆ y → }

  • d;

{y → } dispose y {emp}                   

10

slide-50
SLIDE 50

The ownership trick (O’Hearn 2002)

resource-bundle r : Vars full, b; full := false; Invariant (full ∧ b → ) ∨ (¬full ∧ emp) blank                    {emp} x := new(); {x → } with r when ¬full do {¬full ∧ emp ⋆ x → } b := x; {¬full ∧ emp ⋆ x → ∧ b = x} full := true {full ∧ b → ⋆ emp}

  • d

{emp} {emp} with r when full do {full ∧ b → ⋆ emp} y := b; {full ∧ b → ⋆ emp ∧ y = b} full := false {¬full ∧ emp ⋆ y → }

  • d;

{y → } dispose y {emp}                   

10

slide-51
SLIDE 51

The ownership trick (O’Hearn 2002)

resource-bundle r : Vars full, b; full := false; Invariant (full ∧ b → ) ∨ (¬full ∧ emp) blank                    {emp} x := new(); {x → } with r when ¬full do {¬full ∧ emp ⋆ x → } b := x; {¬full ∧ emp ⋆ x → ∧ b = x} full := true {full ∧ b → ⋆ emp}

  • d

{emp} {emp} with r when full do {full ∧ b → ⋆ emp} y := b; {full ∧ b → ⋆ emp ∧ y = b} full := false {¬full ∧ emp ⋆ y → }

  • d;

{y → } dispose y {emp}                   

10

slide-52
SLIDE 52

The ownership trick (O’Hearn 2002)

resource-bundle r : Vars full, b; full := false; Invariant (full ∧ b → ) ∨ (¬full ∧ emp) blank                    {emp} x := new(); {x → } with r when ¬full do {¬full ∧ emp ⋆ x → } b := x; {¬full ∧ emp ⋆ x → ∧ b = x} full := true {full ∧ b → ⋆ emp}

  • d

{emp} {emp} with r when full do {full ∧ b → ⋆ emp} y := b; {full ∧ b → ⋆ emp ∧ y = b} full := false {¬full ∧ emp ⋆ y → }

  • d;

{y → } dispose y {emp}                   

10

slide-53
SLIDE 53

The ownership trick (O’Hearn 2002)

resource-bundle r : Vars full, b; full := false; Invariant (full ∧ b → ) ∨ (¬full ∧ emp) blank                    {emp} x := new(); {x → } with r when ¬full do {¬full ∧ emp ⋆ x → } b := x; {¬full ∧ emp ⋆ x → ∧ b = x} full := true {full ∧ b → ⋆ emp}

  • d

{emp} {emp} with r when full do {full ∧ b → ⋆ emp} y := b; {full ∧ b → ⋆ emp ∧ y = b} full := false {¬full ∧ emp ⋆ y → }

  • d;

{y → } dispose y {emp}                   

10

slide-54
SLIDE 54

The ownership trick (O’Hearn 2002)

resource-bundle r : Vars full, b; full := false; Invariant (full ∧ b → ) ∨ (¬full ∧ emp) blank                    {emp} x := new(); {x → } with r when ¬full do {¬full ∧ emp ⋆ x → } b := x; {¬full ∧ emp ⋆ x → ∧ b = x} full := true {full ∧ b → ⋆ emp}

  • d

{emp} {emp} with r when full do {full ∧ b → ⋆ emp} y := b; {full ∧ b → ⋆ emp ∧ y = b} full := false {¬full ∧ emp ⋆ y → }

  • d;

{y → } dispose y {emp}                   

10

slide-55
SLIDE 55

The ownership trick (O’Hearn 2002)

resource-bundle r : Vars full, b; full := false; Invariant (full ∧ b → ) ∨ (¬full ∧ emp) blank                    {emp} x := new(); {x → } with r when ¬full do {¬full ∧ emp ⋆ x → } b := x; {¬full ∧ emp ⋆ x → ∧ b = x} full := true {full ∧ b → ⋆ emp}

  • d

{emp} {emp} with r when full do {full ∧ b → ⋆ emp} y := b; {full ∧ b → ⋆ emp ∧ y = b} full := false {¬full ∧ emp ⋆ y → }

  • d;

{y → } dispose y {emp}                   

10

slide-56
SLIDE 56

The ownership trick (O’Hearn 2002)

resource-bundle r : Vars full, b; full := false; Invariant (full ∧ b → ) ∨ (¬full ∧ emp) blank                    {emp} x := new(); {x → } with r when ¬full do {¬full ∧ emp ⋆ x → } b := x; {¬full ∧ emp ⋆ x → ∧ b = x} full := true {full ∧ b → ⋆ emp}

  • d

{emp} {emp} with r when full do {full ∧ b → ⋆ emp} y := b; {full ∧ b → ⋆ emp ∧ y = b} full := false {¬full ∧ emp ⋆ y → }

  • d;

{y → } dispose y {emp}                   

10

slide-57
SLIDE 57

The ownership trick (O’Hearn 2002)

resource-bundle r : Vars full, b; full := false; Invariant (full ∧ b → ) ∨ (¬full ∧ emp) blank                    {emp} x := new(); {x → } with r when ¬full do {¬full ∧ emp ⋆ x → } b := x; {¬full ∧ emp ⋆ x → ∧ b = x} full := true {full ∧ b → ⋆ emp}

  • d

{emp} {emp} with r when full do {full ∧ b → ⋆ emp} y := b; {full ∧ b → ⋆ emp ∧ y = b} full := false {¬full ∧ emp ⋆ y → }

  • d;

{y → } dispose y {emp}                   

10

slide-58
SLIDE 58

Passivity

11

slide-59
SLIDE 59

Passivity

◮ Passivity is a property of a program and a resource: the program

doesn’t change the contents of the resource.

11

slide-60
SLIDE 60

Passivity

◮ Passivity is a property of a program and a resource: the program

doesn’t change the contents of the resource.

◮ We want to specify passivity by specifying a read-only resource. 11

slide-61
SLIDE 61

Passivity

◮ Passivity is a property of a program and a resource: the program

doesn’t change the contents of the resource.

◮ We want to specify passivity by specifying a read-only resource. ◮ We require that a program, given a read-only resource, cannot

change its contents.

11

slide-62
SLIDE 62

Splitting and sharing

12

slide-63
SLIDE 63

Splitting and sharing

◮ Since Dijkstra, we have known that we can safely share

read-only resources.

12

slide-64
SLIDE 64

Splitting and sharing

◮ Since Dijkstra, we have known that we can safely share

read-only resources.

◮ Total permission E → E′, given by new, allows

read/write/dispose.

12

slide-65
SLIDE 65

Splitting and sharing

◮ Since Dijkstra, we have known that we can safely share

read-only resources.

◮ Total permission E → E′, given by new, allows

read/write/dispose.

◮ Concurrent read permissions must be (⋆) separable, because of

the concurrency rule.

12

slide-66
SLIDE 66

Accounting

13

slide-67
SLIDE 67

Accounting

◮ Splitting into multiple read permissions is easy. 13

slide-68
SLIDE 68

Accounting

◮ Splitting into multiple read permissions is easy. ◮ To write or dispose we have to know when we have all the read

permissions back.

13

slide-69
SLIDE 69

Accounting

◮ Splitting into multiple read permissions is easy. ◮ To write or dispose we have to know when we have all the read

permissions back.

◮ A program which doesn’t keep account leaks resource. 13

slide-70
SLIDE 70

Boyland’s suggestion: 1

2 + 1 2 = 1

14

slide-71
SLIDE 71

Boyland’s suggestion: 1

2 + 1 2 = 1

◮ Boyland (Wisconsin) developed a means of permission

accounting in disjoint concurrency, dealing with variables and heap locations.

14

slide-72
SLIDE 72

Boyland’s suggestion: 1

2 + 1 2 = 1

◮ Boyland (Wisconsin) developed a means of permission

accounting in disjoint concurrency, dealing with variables and heap locations.

◮ He associates a number z with each permission: z = 1 total;

0 < z < 1 read-only.

14

slide-73
SLIDE 73

Boyland’s suggestion: 1

2 + 1 2 = 1

◮ Boyland (Wisconsin) developed a means of permission

accounting in disjoint concurrency, dealing with variables and heap locations.

◮ He associates a number z with each permission: z = 1 total;

0 < z < 1 read-only.

◮ Fractional permissions are specification-only (cf. types). 14

slide-74
SLIDE 74

Boyland’s suggestion: 1

2 + 1 2 = 1

◮ Boyland (Wisconsin) developed a means of permission

accounting in disjoint concurrency, dealing with variables and heap locations.

◮ He associates a number z with each permission: z = 1 total;

0 < z < 1 read-only.

◮ Fractional permissions are specification-only (cf. types). ◮ In practice the arithmetic is very easy: fractions are simpler to

use than (e.g.) sets of binary trees.

14

slide-75
SLIDE 75

Boyland’s suggestion: 1

2 + 1 2 = 1

◮ Boyland (Wisconsin) developed a means of permission

accounting in disjoint concurrency, dealing with variables and heap locations.

◮ He associates a number z with each permission: z = 1 total;

0 < z < 1 read-only.

◮ Fractional permissions are specification-only (cf. types). ◮ In practice the arithmetic is very easy: fractions are simpler to

use than (e.g.) sets of binary trees.

◮ The magnitude of non-integral fractions doesn’t matter, except as

a matter of accounting.

14

slide-76
SLIDE 76

A fractional model (Calcagno, O’Hearn)

15

slide-77
SLIDE 77

A fractional model (Calcagno, O’Hearn)

◮ Heaps are partial maps from Nat to (int, fraction). (Previously

Nat to int.)

15

slide-78
SLIDE 78

A fractional model (Calcagno, O’Hearn)

◮ Heaps are partial maps from Nat to (int, fraction). (Previously

Nat to int.)

◮ A simpler model – just read / total permissions – fails to account

and doesn’t have the frame property.

15

slide-79
SLIDE 79

Proof theory

blank

16

slide-80
SLIDE 80

Proof theory

E − →

z E′

⇒ 0 < z ≤ 1 E − − − − →

z+z′ E′ ∧ z > 0 ∧ z′ > 0 ⇐

⇒ E − →

z E′ ⋆ E −

− →

z′ E′

blank

16

slide-81
SLIDE 81

Proof theory

E − →

z E′

⇒ 0 < z ≤ 1 E − − − − →

z+z′ E′ ∧ z > 0 ∧ z′ > 0 ⇐

⇒ E − →

z E′ ⋆ E −

− →

z′ E′

blank {Rx

E}

x:=E {R} {E′ − →

1

} [E′]:=E {E′ − →

1 E}

{E′ − →

z E}

x:=[E′] {E′ − →

z E ∧ x = E} (x not free in E, E′)

{emp} x:=new(E) {x − →

1 E}

{E − →

1

} dispose E {emp}

16

slide-82
SLIDE 82

Proof theory

E − →

z E′

⇒ 0 < z ≤ 1 E − − − − →

z+z′ E′ ∧ z > 0 ∧ z′ > 0 ⇐

⇒ E − →

z E′ ⋆ E −

− →

z′ E′

blank {Rx

E}

x:=E {R} {E′ − →

1

} [E′]:=E {E′ − →

1 E}

{E′ − →

z E}

x:=[E′] {E′ − →

z E ∧ x = E} (x not free in E, E′)

{emp} x:=new(E) {x − →

1 E}

{E − →

1

} dispose E {emp}

◮ Not (yet) proved sound by Brookes. (But surely ...) 16

slide-83
SLIDE 83

Proof

{emp} x := new(); {x − →

1

} [x] := 1; {x − →

1 1}∴{x −

− − →

0.5 1 ⋆ x −

− − →

0.5 1}

   {x − − − →

0.5 1}

y := [x] {x − − − →

0.5 1 ∧ y = 1}

{x − − − →

0.5 1}

z := [x] + 1 {x − − − →

0.5 1 ∧ z = 2}

   ; {(x − − − →

0.5 1 ∧ y = 1) ⋆ (x −

− − →

0.5 1 ∧ z = 2)}∴{x −

1 1 ∧ y = 1 ∧ z = 2}

dispose x {emp ∧ y = 1 ∧ z = 2}

17

slide-84
SLIDE 84

Proof

{emp} x := new(); {x − →

1

} [x] := 1; {x − →

1 1}∴{x −

− − →

0.5 1 ⋆ x −

− − →

0.5 1}

   {x − − − →

0.5 1}

y := [x] {x − − − →

0.5 1 ∧ y = 1}

{x − − − →

0.5 1}

z := [x] + 1 {x − − − →

0.5 1 ∧ z = 2}

   ; {(x − − − →

0.5 1 ∧ y = 1) ⋆ (x −

− − →

0.5 1 ∧ z = 2)}∴{x −

1 1 ∧ y = 1 ∧ z = 2}

dispose x {emp ∧ y = 1 ∧ z = 2}

17

slide-85
SLIDE 85

Proof

{emp} x := new(); {x − →

1

} [x] := 1; {x − →

1 1}∴{x −

− − →

0.5 1 ⋆ x −

− − →

0.5 1}

   {x − − − →

0.5 1}

y := [x] {x − − − →

0.5 1 ∧ y = 1}

{x − − − →

0.5 1}

z := [x] + 1 {x − − − →

0.5 1 ∧ z = 2}

   ; {(x − − − →

0.5 1 ∧ y = 1) ⋆ (x −

− − →

0.5 1 ∧ z = 2)}∴{x −

1 1 ∧ y = 1 ∧ z = 2}

dispose x {emp ∧ y = 1 ∧ z = 2}

17

slide-86
SLIDE 86

Proof

{emp} x := new(); {x − →

1

} [x] := 1; {x − →

1 1}∴{x −

− − →

0.5 1 ⋆ x −

− − →

0.5 1}

   {x − − − →

0.5 1}

y := [x] {x − − − →

0.5 1 ∧ y = 1}

{x − − − →

0.5 1}

z := [x] + 1 {x − − − →

0.5 1 ∧ z = 2}

   ; {(x − − − →

0.5 1 ∧ y = 1) ⋆ (x −

− − →

0.5 1 ∧ z = 2)}∴{x −

1 1 ∧ y = 1 ∧ z = 2}

dispose x {emp ∧ y = 1 ∧ z = 2}

17

slide-87
SLIDE 87

Proof

{emp} x := new(); {x − →

1

} [x] := 1; {x − →

1 1}∴{x −

− − →

0.5 1 ⋆ x −

− − →

0.5 1}

   {x − − − →

0.5 1}

y := [x] {x − − − →

0.5 1 ∧ y = 1}

{x − − − →

0.5 1}

z := [x] + 1 {x − − − →

0.5 1 ∧ z = 2}

   ; {(x − − − →

0.5 1 ∧ y = 1) ⋆ (x −

− − →

0.5 1 ∧ z = 2)}∴{x −

1 1 ∧ y = 1 ∧ z = 2}

dispose x {emp ∧ y = 1 ∧ z = 2}

17

slide-88
SLIDE 88

Proof

{emp} x := new(); {x − →

1

} [x] := 1; {x − →

1 1}∴{x −

− − →

0.5 1 ⋆ x −

− − →

0.5 1}

   {x − − − →

0.5 1}

y := [x] {x − − − →

0.5 1 ∧ y = 1}

{x − − − →

0.5 1}

z := [x] + 1 {x − − − →

0.5 1 ∧ z = 2}

   ; {(x − − − →

0.5 1 ∧ y = 1) ⋆ (x −

− − →

0.5 1 ∧ z = 2)}∴{x −

1 1 ∧ y = 1 ∧ z = 2}

dispose x {emp ∧ y = 1 ∧ z = 2}

17

slide-89
SLIDE 89

Proof

{emp} x := new(); {x − →

1

} [x] := 1; {x − →

1 1}∴{x −

− − →

0.5 1 ⋆ x −

− − →

0.5 1}

   {x − − − →

0.5 1}

y := [x] {x − − − →

0.5 1 ∧ y = 1}

{x − − − →

0.5 1}

z := [x] + 1 {x − − − →

0.5 1 ∧ z = 2}

   ; {(x − − − →

0.5 1 ∧ y = 1) ⋆ (x −

− − →

0.5 1 ∧ z = 2)}∴{x −

1 1 ∧ y = 1 ∧ z = 2}

dispose x {emp ∧ y = 1 ∧ z = 2}

17

slide-90
SLIDE 90

Proof

{emp} x := new(); {x − →

1

} [x] := 1; {x − →

1 1}∴{x −

− − →

0.5 1 ⋆ x −

− − →

0.5 1}

   {x − − − →

0.5 1}

y := [x] {x − − − →

0.5 1 ∧ y = 1}

{x − − − →

0.5 1}

z := [x] + 1 {x − − − →

0.5 1 ∧ z = 2}

   ; {(x − − − →

0.5 1 ∧ y = 1) ⋆ (x −

− − →

0.5 1 ∧ z = 2)}∴{x −

1 1 ∧ y = 1 ∧ z = 2}

dispose x {emp ∧ y = 1 ∧ z = 2}

17

slide-91
SLIDE 91

Proof

{emp} x := new(); {x − →

1

} [x] := 1; {x − →

1 1}∴{x −

− − →

0.5 1 ⋆ x −

− − →

0.5 1}

   {x − − − →

0.5 1}

y := [x] {x − − − →

0.5 1 ∧ y = 1}

{x − − − →

0.5 1}

z := [x] + 1 {x − − − →

0.5 1 ∧ z = 2}

   ; {(x − − − →

0.5 1 ∧ y = 1) ⋆ (x −

− − →

0.5 1 ∧ z = 2)}∴{x −

1 1 ∧ y = 1 ∧ z = 2}

dispose x {emp ∧ y = 1 ∧ z = 2}

17

slide-92
SLIDE 92

Proof

{emp} x := new(); {x − →

1

} [x] := 1; {x − →

1 1}∴{x −

− − →

0.5 1 ⋆ x −

− − →

0.5 1}

   {x − − − →

0.5 1}

y := [x] {x − − − →

0.5 1 ∧ y = 1}

{x − − − →

0.5 1}

z := [x] + 1 {x − − − →

0.5 1 ∧ z = 2}

   ; {(x − − − →

0.5 1 ∧ y = 1) ⋆ (x −

− − →

0.5 1 ∧ z = 2)}∴{x −

1 1 ∧ y = 1 ∧ z = 2}

dispose x {emp ∧ y = 1 ∧ z = 2}

◮ That is exactly how hard it is to use fractional permissions. 17

slide-93
SLIDE 93

UnProof

{emp} x := new(); {x − →

1

} [x] := 1; {x − →

1 1}∴{x −

− − →

0.5 1 ⋆ x −

− − →

0.5 1}

       {x − − − →

0.5 1}

y := [x]; {x − − − →

0.5 1 ∧ y = 1}

dispose x {??} {x − − − →

0.5 1}

[x] := 2; {??} z := [x] + 1 {??}        {??} [x] := y + z

18

slide-94
SLIDE 94

UnProof

{emp} x := new(); {x − →

1

} [x] := 1; {x − →

1 1}∴{x −

− − →

0.5 1 ⋆ x −

− − →

0.5 1}

       {x − − − →

0.5 1}

y := [x]; {x − − − →

0.5 1 ∧ y = 1}

dispose x {??} {x − − − →

0.5 1}

[x] := 2; {??} z := [x] + 1 {??}        {??} [x] := y + z

18

slide-95
SLIDE 95

UnProof

{emp} x := new(); {x − →

1

} [x] := 1; {x − →

1 1}∴{x −

− − →

0.5 1 ⋆ x −

− − →

0.5 1}

       {x − − − →

0.5 1}

y := [x]; {x − − − →

0.5 1 ∧ y = 1}

dispose x {??} {x − − − →

0.5 1}

[x] := 2; {??} z := [x] + 1 {??}        {??} [x] := y + z

18

slide-96
SLIDE 96

UnProof

{emp} x := new(); {x − →

1

} [x] := 1; {x − →

1 1}∴{x −

− − →

0.5 1 ⋆ x −

− − →

0.5 1}

       {x − − − →

0.5 1}

y := [x]; {x − − − →

0.5 1 ∧ y = 1}

dispose x {??} {x − − − →

0.5 1}

[x] := 2; {??} z := [x] + 1 {??}        {??} [x] := y + z

18

slide-97
SLIDE 97

UnProof

{emp} x := new(); {x − →

1

} [x] := 1; {x − →

1 1}∴{x −

− − →

0.5 1 ⋆ x −

− − →

0.5 1}

       {x − − − →

0.5 1}

y := [x]; {x − − − →

0.5 1 ∧ y = 1}

dispose x {??} {x − − − →

0.5 1}

[x] := 2; {??} z := [x] + 1 {??}        {??} [x] := y + z

18

slide-98
SLIDE 98

Passivity and fractions

Termination Monotonicity: if C must terminate normally in h and h ⋆ h′ is defined, then C must terminate normally in h ⋆ h′.

19

slide-99
SLIDE 99

Passivity and fractions

Termination Monotonicity: if C must terminate normally in h and h ⋆ h′ is defined, then C must terminate normally in h ⋆ h′.

◮ We can prove termination monotonicity for all commands in our

language.

19

slide-100
SLIDE 100

Passivity and fractions

Termination Monotonicity: if C must terminate normally in h and h ⋆ h′ is defined, then C must terminate normally in h ⋆ h′.

◮ We can prove termination monotonicity for all commands in our

language.

◮ Suppose {10 −

− − →

0.5 N}C{10 −

− − →

0.5 N + 1}, and it terminates.

19

slide-101
SLIDE 101

Passivity and fractions

Termination Monotonicity: if C must terminate normally in h and h ⋆ h′ is defined, then C must terminate normally in h ⋆ h′.

◮ We can prove termination monotonicity for all commands in our

language.

◮ Suppose {10 −

− − →

0.5 N}C{10 −

− − →

0.5 N + 1}, and it terminates.

◮ Then (frame rule)

. . . {10 − − − →

0.5 N}C{10 −

− − →

0.5 N + 1}

{10 − − − →

0.5 N ⋆ 10 −

− − →

0.5 N}C{10 −

− − →

0.5 N ⋆ 10 −

− − →

0.5 N + 1}

19

slide-102
SLIDE 102

Passivity and fractions

Termination Monotonicity: if C must terminate normally in h and h ⋆ h′ is defined, then C must terminate normally in h ⋆ h′.

◮ We can prove termination monotonicity for all commands in our

language.

◮ Suppose {10 −

− − →

0.5 N}C{10 −

− − →

0.5 N + 1}, and it terminates.

◮ Then (frame rule)

. . . {10 − − − →

0.5 N}C{10 −

− − →

0.5 N + 1}

{10 − − − →

0.5 N ⋆ 10 −

− − →

0.5 N}C{10 −

− − →

0.5 N ⋆ 10 −

− − →

0.5 N + 1}

◮ – i.e. it won’t terminate in 10 −

− − →

1.0 N.

19

slide-103
SLIDE 103

Passivity and fractions

Termination Monotonicity: if C must terminate normally in h and h ⋆ h′ is defined, then C must terminate normally in h ⋆ h′.

◮ We can prove termination monotonicity for all commands in our

language.

◮ Suppose {10 −

− − →

0.5 N}C{10 −

− − →

0.5 N + 1}, and it terminates.

◮ Then (frame rule)

. . . {10 − − − →

0.5 N}C{10 −

− − →

0.5 N + 1}

{10 − − − →

0.5 N ⋆ 10 −

− − →

0.5 N}C{10 −

− − →

0.5 N ⋆ 10 −

− − →

0.5 N + 1}

◮ – i.e. it won’t terminate in 10 −

− − →

1.0 N.

◮ Therefore C isn’t in our language. 19

slide-104
SLIDE 104

Passivity and fractions

Termination Monotonicity: if C must terminate normally in h and h ⋆ h′ is defined, then C must terminate normally in h ⋆ h′.

◮ We can prove termination monotonicity for all commands in our

language.

◮ Suppose {10 −

− − →

0.5 N}C{10 −

− − →

0.5 N + 1}, and it terminates.

◮ Then (frame rule)

. . . {10 − − − →

0.5 N}C{10 −

− − →

0.5 N + 1}

{10 − − − →

0.5 N ⋆ 10 −

− − →

0.5 N}C{10 −

− − →

0.5 N ⋆ 10 −

− − →

0.5 N + 1}

◮ – i.e. it won’t terminate in 10 −

− − →

1.0 N.

◮ Therefore C isn’t in our language. ◮ Thus we have passivity! 19

slide-105
SLIDE 105

Permission counting

20

slide-106
SLIDE 106

Permission counting

◮ Some programs naturally weigh out permissions to their child

threads: e.g. parallel tree-copy, parallel tree-rewriting (see proceedings).

20

slide-107
SLIDE 107

Permission counting

◮ Some programs naturally weigh out permissions to their child

threads: e.g. parallel tree-copy, parallel tree-rewriting (see proceedings).

◮ Some programs count permissions: e.g. pipeline multicasting,

readers-and-writers.

20

slide-108
SLIDE 108

Permission counting

◮ Some programs naturally weigh out permissions to their child

threads: e.g. parallel tree-copy, parallel tree-rewriting (see proceedings).

◮ Some programs count permissions: e.g. pipeline multicasting,

readers-and-writers.

◮ Permission counting is not specification-only. 20

slide-109
SLIDE 109

Readers and Writers (Courtois et.al. 1972)

P(read); if count = 0 then P(write) else skip fi; count+ := 1; V(read); {z ֌ N} ... reading happens here ... {z ֌ N} P(read); count− := 1; if count = 0 then V(write) else skip fi; V(read) {emp} P(write); {z − → M} ... writing happens here ... {z − → M′} V(write) {emp}

21

slide-110
SLIDE 110

Readers and writers (CCR version)

22

slide-111
SLIDE 111

Readers and writers (CCR version)

{emp} with read when true do if count = 0 then P(write) else skip fi; count+:= 1

  • d;

{z ֌ N} ... reading happens here ... {z ֌ N} with read when count > 0 do count−:= 1; if count = 0 then V(write) else skip fi

  • d

{emp} {emp} P(write); {z − → M} ... writing happens here ... {z − → M′} V(write) {emp}

22

slide-112
SLIDE 112

Readers and writers (CCR version)

{emp} with read when true do if count = 0 then P(write) else skip fi; count+:= 1

  • d;

{z ֌ N} ... reading happens here ... {z ֌ N} with read when count > 0 do count−:= 1; if count = 0 then V(write) else skip fi

  • d

{emp} {emp} P(write); {z − → M} ... writing happens here ... {z − → M′} V(write) {emp}

22

slide-113
SLIDE 113

Readers and writers (CCR version)

{emp} with read when true do if count = 0 then P(write) else skip fi; count+:= 1

  • d;

{z ֌ N} ... reading happens here ... {z ֌ N} with read when count > 0 do count−:= 1; if count = 0 then V(write) else skip fi

  • d

{emp} {emp} P(write); {z − → M} ... writing happens here ... {z − → M′} V(write) {emp}

22

slide-114
SLIDE 114

Readers and writers (CCR version)

{emp} with read when true do if count = 0 then P(write) else skip fi; count+:= 1

  • d;

{z ֌ N} ... reading happens here ... {z ֌ N} with read when count > 0 do count−:= 1; if count = 0 then V(write) else skip fi

  • d

{emp} {emp} P(write); {z − → M} ... writing happens here ... {z − → M′} V(write) {emp}

22

slide-115
SLIDE 115

Readers and writers (CCR version)

{emp} with read when true do if count = 0 then P(write) else skip fi; count+:= 1

  • d;

{z ֌ N} ... reading happens here ... {z ֌ N} with read when count > 0 do count−:= 1; if count = 0 then V(write) else skip fi

  • d

{emp} {emp} P(write); {z − → M} ... writing happens here ... {z − → M′} V(write) {emp}

22

slide-116
SLIDE 116

A counting model (Calcagno, Parkinson)

23

slide-117
SLIDE 117

A counting model (Calcagno, Parkinson)

◮ Heaps are partial maps from Nat to (int, permission). 23

slide-118
SLIDE 118

A counting model (Calcagno, Parkinson)

◮ Heaps are partial maps from Nat to (int, permission). ◮ Permissions are −n (n read permissions), or +n (a “block” from

which n read permissions have been “flaked”).

23

slide-119
SLIDE 119

A counting model (Calcagno, Parkinson)

◮ Heaps are partial maps from Nat to (int, permission). ◮ Permissions are −n (n read permissions), or +n (a “block” from

which n read permissions have been “flaked”).

◮ 0 is total permission. 23

slide-120
SLIDE 120

A counting model (Calcagno, Parkinson)

◮ Heaps are partial maps from Nat to (int, permission). ◮ Permissions are −n (n read permissions), or +n (a “block” from

which n read permissions have been “flaked”).

◮ 0 is total permission. ◮ E

i

− → E′ ⋆ E

j

− → E′ =    undefined i ≥ 0 ∧ j ≥ 0 undefined (i ≥ 0 ∨ j ≥ 0) ∧ i + j < 0 E

i+j

− − − → E′

  • therwise

23

slide-121
SLIDE 121

A counting model (Calcagno, Parkinson)

◮ Heaps are partial maps from Nat to (int, permission). ◮ Permissions are −n (n read permissions), or +n (a “block” from

which n read permissions have been “flaked”).

◮ 0 is total permission. ◮ E

i

− → E′ ⋆ E

j

− → E′ =    undefined i ≥ 0 ∧ j ≥ 0 undefined (i ≥ 0 ∨ j ≥ 0) ∧ i + j < 0 E

i+j

− − − → E′

  • therwise

◮ E ֌ E′ is a notational convenience for E

−1

− − − → E′.

23

slide-122
SLIDE 122

A counting model (Calcagno, Parkinson)

◮ Heaps are partial maps from Nat to (int, permission). ◮ Permissions are −n (n read permissions), or +n (a “block” from

which n read permissions have been “flaked”).

◮ 0 is total permission. ◮ E

i

− → E′ ⋆ E

j

− → E′ =    undefined i ≥ 0 ∧ j ≥ 0 undefined (i ≥ 0 ∨ j ≥ 0) ∧ i + j < 0 E

i+j

− − − → E′

  • therwise

◮ E ֌ E′ is a notational convenience for E

−1

− − − → E′.

◮ We have passivity (same proof as before). 23

slide-123
SLIDE 123

Proof theory

24

slide-124
SLIDE 124

Proof theory

E

n

− → E′ ⇒ n ≥ 0 E

n

− → E′ ⇐ ⇒ E

n+1

− − − − → E′ ⋆ E ֌ E′ blank

24

slide-125
SLIDE 125

Proof theory

E

n

− → E′ ⇒ n ≥ 0 E

n

− → E′ ⇐ ⇒ E

n+1

− − − − → E′ ⋆ E ֌ E′ blank {Rx

E}

x:=E {R} {E′ − → } [x]:=E {E′ − → E} {E′ ֌ E} x:=[E′] {E′ ֌ E ∧ x = E} (x not free in E, E′) {emp} x:=new(E) {x − → E} {E − → } dispose E {emp}

24

slide-126
SLIDE 126

Resource safety proof

write : if write = 0 then emp else z − → N fi read : if count = 0 then emp else z

count

− − − − − → N fi {emp} with read when true do {if count = 0 then emp else z

count

− − − − − → N fi ⋆ emp} if count = 0 then {emp} P(write) {z − → N} else {z

count

− − − − − → N} skip {z

count

− − − − − → N} fi; {z

count

− − − − − → N} count+:= 1 {z

count−1

− − − − − − − → N}∴{z

count

− − − − − → N ⋆ z ֌ N}

  • d

{z ֌ N}

25

slide-127
SLIDE 127

Resource safety proof

write : if write = 0 then emp else z − → N fi read : if count = 0 then emp else z

count

− − − − − → N fi {emp} with read when true do {if count = 0 then emp else z

count

− − − − − → N fi ⋆ emp} if count = 0 then {emp} P(write) {z − → N} else {z

count

− − − − − → N} skip {z

count

− − − − − → N} fi; {z

count

− − − − − → N} count+:= 1 {z

count−1

− − − − − − − → N}∴{z

count

− − − − − → N ⋆ z ֌ N}

  • d

{z ֌ N}

25

slide-128
SLIDE 128

Resource safety proof

write : if write = 0 then emp else z − → N fi read : if count = 0 then emp else z

count

− − − − − → N fi {emp} with read when true do {if count = 0 then emp else z

count

− − − − − → N fi ⋆ emp} if count = 0 then {emp} P(write) {z − → N} else {z

count

− − − − − → N} skip {z

count

− − − − − → N} fi; {z

count

− − − − − → N} count+:= 1 {z

count−1

− − − − − − − → N}∴{z

count

− − − − − → N ⋆ z ֌ N}

  • d

{z ֌ N}

25

slide-129
SLIDE 129

Resource safety proof

write : if write = 0 then emp else z − → N fi read : if count = 0 then emp else z

count

− − − − − → N fi {emp} with read when true do {if count = 0 then emp else z

count

− − − − − → N fi ⋆ emp} if count = 0 then {emp} P(write) {z − → N} else {z

count

− − − − − → N} skip {z

count

− − − − − → N} fi; {z

count

− − − − − → N} count+:= 1 {z

count−1

− − − − − − − → N}∴{z

count

− − − − − → N ⋆ z ֌ N}

  • d

{z ֌ N}

25

slide-130
SLIDE 130

Resource safety proof

write : if write = 0 then emp else z − → N fi read : if count = 0 then emp else z

count

− − − − − → N fi {emp} with read when true do {if count = 0 then emp else z

count

− − − − − → N fi ⋆ emp} if count = 0 then {emp} P(write) {z − → N} else {z

count

− − − − − → N} skip {z

count

− − − − − → N} fi; {z

count

− − − − − → N} count+:= 1 {z

count−1

− − − − − − − → N}∴{z

count

− − − − − → N ⋆ z ֌ N}

  • d

{z ֌ N}

25

slide-131
SLIDE 131

Resource safety proof

write : if write = 0 then emp else z − → N fi read : if count = 0 then emp else z

count

− − − − − → N fi {emp} with read when true do {if count = 0 then emp else z

count

− − − − − → N fi ⋆ emp} if count = 0 then {emp} P(write) {z − → N} else {z

count

− − − − − → N} skip {z

count

− − − − − → N} fi; {z

count

− − − − − → N} count+:= 1 {z

count−1

− − − − − − − → N}∴{z

count

− − − − − → N ⋆ z ֌ N}

  • d

{z ֌ N}

25

slide-132
SLIDE 132

Resource safety proof

write : if write = 0 then emp else z − → N fi read : if count = 0 then emp else z

count

− − − − − → N fi {emp} with read when true do {if count = 0 then emp else z

count

− − − − − → N fi ⋆ emp} if count = 0 then {emp} P(write) {z − → N} else {z

count

− − − − − → N} skip {z

count

− − − − − → N} fi; {z

count

− − − − − → N} count+:= 1 {z

count−1

− − − − − − − → N}∴{z

count

− − − − − → N ⋆ z ֌ N}

  • d

{z ֌ N}

25

slide-133
SLIDE 133

Resource safety proof

write : if write = 0 then emp else z − → N fi read : if count = 0 then emp else z

count

− − − − − → N fi {emp} with read when true do {if count = 0 then emp else z

count

− − − − − → N fi ⋆ emp} if count = 0 then {emp} P(write) {z − → N} else {z

count

− − − − − → N} skip {z

count

− − − − − → N} fi; {z

count

− − − − − → N} count+:= 1 {z

count−1

− − − − − − − → N} ∴ {z

count

− − − − − → N ⋆ z ֌ N}

  • d

{z ֌ N}

25

slide-134
SLIDE 134

Do we need two models?

26

slide-135
SLIDE 135

Do we need two models?

T ::= Lam v T | App T T | Var v

26

slide-136
SLIDE 136

Do we need two models?

T ::= Lam v T | App T T | Var v AST x (Lam v β) z ˆ = ∃b.(x

z

− → 0, v, b ⋆ AST b β z AST x (App φ α) z ˆ = ∃f, a. x

z

− → 1, f, a ⋆ AST f φ z ⋆ AST a α z

  • AST x (Var v) z ˆ

= x

z

− → 2, v

26

slide-137
SLIDE 137

Do we need two models?

T ::= Lam v T | App T T | Var v AST x (Lam v β) z ˆ = ∃b.(x

z

− → 0, v, b ⋆ AST b β z AST x (App φ α) z ˆ = ∃f, a. x

z

− → 1, f, a ⋆ AST f φ z ⋆ AST a α z

  • AST x (Var v) z ˆ

= x

z

− → 2, v (Lam v′ β)[τ/v] =

  • Lam v′ (β[τ/v])

v = v′ Lam v′ β v′ = v (App φ α)[τ/v] = App (φ[τ/v]) (α[τ/v]) (Var v′)[τ/v] =

  • Var v′

v = v′ τ v = v′

26

slide-138
SLIDE 138

Parallel tree rewriting

subst x y v = if [x] = 0 then // Lam if [x + 1] = v then [x + 2] := subst [x + 2] y v else skip fi; x elsf [x] = 1 then // App – do it in parallel

  • [x + 1] := subst [x + 1] y v [x + 2] := subst [x + 2] y v)
  • ;

x elsf [x + 1] = v then // Var, same v dispose x; dispose(x + 1); new(2, copy y) else // Var, different v x fi

27

slide-139
SLIDE 139

Parallel tree rewriting

subst x y v = if [x] = 0 then // Lam if [x + 1] = v then [x + 2] := subst [x + 2] y v else skip fi; x elsf [x] = 1 then // App – do it in parallel

  • [x + 1] := subst [x + 1] y v [x + 2] := subst [x + 2] y v)
  • ;

x elsf [x + 1] = v then // Var, same v dispose x; dispose(x + 1); new(2, copy y) else // Var, different v x fi – proof easy with fractions, ridiculous with counting permissions; readers and writers swings the other way.

27

slide-140
SLIDE 140

Parallel tree rewriting

subst x y v = if [x] = 0 then // Lam if [x + 1] = v then [x + 2] := subst [x + 2] y v else skip fi; x elsf [x] = 1 then // App – do it in parallel

  • [x + 1] := subst [x + 1] y v [x + 2] := subst [x + 2] y v)
  • ;

x elsf [x + 1] = v then // Var, same v dispose x; dispose(x + 1); new(2, copy y) else // Var, different v x fi – proof easy with fractions, ridiculous with counting permissions; readers and writers swings the other way. We need more than one model!

27

slide-141
SLIDE 141

Passivity and concurrency

◮ If I have x −

− − →

0.5

, I can be sure that you can’t write to it.

28

slide-142
SLIDE 142

Passivity and concurrency

◮ If I have x −

− − →

0.5

, I can be sure that you can’t write to it.

◮ If I give you x −

− − →

0.5

in the static case, I can be sure you can’t write to it.

28

slide-143
SLIDE 143

Passivity and concurrency

◮ If I have x −

− − →

0.5

, I can be sure that you can’t write to it.

◮ If I give you x −

− − →

0.5

in the static case, I can be sure you can’t write to it.

◮ In the concurrent/modular case, you might have the other half, or

get it temporarily from elsewhere.

28

slide-144
SLIDE 144

Passivity and concurrency

◮ If I have x −

− − →

0.5

, I can be sure that you can’t write to it.

◮ If I give you x −

− − →

0.5

in the static case, I can be sure you can’t write to it.

◮ In the concurrent/modular case, you might have the other half, or

get it temporarily from elsewhere.

◮ Moral: keep your hand on your ha’penny; don’t give them

everything you’ve got.

28

slide-145
SLIDE 145

Passivity and concurrency

◮ If I have x −

− − →

0.5

, I can be sure that you can’t write to it.

◮ If I give you x −

− − →

0.5

in the static case, I can be sure you can’t write to it.

◮ In the concurrent/modular case, you might have the other half, or

get it temporarily from elsewhere.

◮ Moral: keep your hand on your ha’penny; don’t give them

everything you’ve got.

◮ (Same applies to counting permissions.) 28

slide-146
SLIDE 146

We don’t understand recursive definitions any more

29

slide-147
SLIDE 147

We don’t understand recursive definitions any more

tree nil Empty ˆ = emp tree t (Tip α) ˆ = t → 0, α tree t (Node λ ρ) ˆ = ∃l, r ·

  • t → 1, l, r ⋆ tree l λ ⋆ tree r ρ
  • 29
slide-148
SLIDE 148

We don’t understand recursive definitions any more

tree nil Empty ˆ = emp tree t (Tip α) ˆ = t → 0, α tree t (Node λ ρ) ˆ = ∃l, r ·

  • t → 1, l, r ⋆ tree l λ ⋆ tree r ρ
  • ztree z nil Empty ˆ

= emp ztree z t (Tip α) ˆ = t − →

z 0, α

ztree z t (Node λ ρ) ˆ = ∃l, r ·

  • t −

z 1, l, r ⋆ ztree z l λ ⋆ ztree z r ρ

  • 29
slide-149
SLIDE 149

We don’t understand recursive definitions any more

tree nil Empty ˆ = emp tree t (Tip α) ˆ = t → 0, α tree t (Node λ ρ) ˆ = ∃l, r ·

  • t → 1, l, r ⋆ tree l λ ⋆ tree r ρ
  • ztree z nil Empty ˆ

= emp ztree z t (Tip α) ˆ = t − →

z 0, α

ztree z t (Node λ ρ) ˆ = ∃l, r ·

  • t −

z 1, l, r ⋆ ztree z l λ ⋆ ztree z r ρ

  • x −

− − →

0.5 1, l, l ⋆ l −

− − →

1.0 0, 3 satisfies ztree 0.5 x (Node (Tip 3) (Tip 3))

(and we can write to it)!!

29

slide-150
SLIDE 150

We don’t understand recursive definitions any more

tree nil Empty ˆ = emp tree t (Tip α) ˆ = t → 0, α tree t (Node λ ρ) ˆ = ∃l, r ·

  • t → 1, l, r ⋆ tree l λ ⋆ tree r ρ
  • ztree z nil Empty ˆ

= emp ztree z t (Tip α) ˆ = t − →

z 0, α

ztree z t (Node λ ρ) ˆ = ∃l, r ·

  • t −

z 1, l, r ⋆ ztree z l λ ⋆ ztree z r ρ

  • x −

− − →

0.5 1, l, l ⋆ l −

− − →

1.0 0, 3 satisfies ztree 0.5 x (Node (Tip 3) (Tip 3))

(and we can write to it)!! We have ztree (z + z′) t τ ⇐ ⇒ ztree z t τ ⋆ ztree z′ t τ, but sometimes only vacuously.

29

slide-151
SLIDE 151

We don’t understand recursive definitions any more

tree nil Empty ˆ = emp tree t (Tip α) ˆ = t → 0, α tree t (Node λ ρ) ˆ = ∃l, r ·

  • t → 1, l, r ⋆ tree l λ ⋆ tree r ρ
  • ztree z nil Empty ˆ

= emp ztree z t (Tip α) ˆ = t − →

z 0, α

ztree z t (Node λ ρ) ˆ = ∃l, r ·

  • t −

z 1, l, r ⋆ ztree z l λ ⋆ ztree z r ρ

  • x −

− − →

0.5 1, l, l ⋆ l −

− − →

1.0 0, 3 satisfies ztree 0.5 x (Node (Tip 3) (Tip 3))

(and we can write to it)!! We have ztree (z + z′) t τ ⇐ ⇒ ztree z t τ ⋆ ztree z′ t τ, but sometimes only vacuously. We can write programs which work with ztree 0.5, but crash with ztree 0.499.

29

slide-152
SLIDE 152

The unbounded buffer

begin integer numberOfQueuingPortions, bufferManipulation; numberOfQueuingPortions := 0; bufferManipulation := 1; parbegin producer: begin again1: produce next portion; add portion to buffer; V(numberOfQueuingPortions); goto again1 end; consumer: begin again2: P(numberOfQueuingPortions); take portion from buffer; process portion taken; goto again2 end parend end

Proposed and withdrawn in 1965; proved safe, Habermann 1972.

30

slide-153
SLIDE 153

A proof with variables-as-resource

back b f front n=3 tc tp J K L

31

slide-154
SLIDE 154

A proof with variables-as-resource

                  // Producer. // Semaphore n // Consumer.

  • back, tp, b 1

2 ⊢

back → , ∧ back = b

  • {n, f 1

2 , b 1 2 ⊢ listseg n f b} {front, tc, f 1 2 ⊢ front = f}

back.0 := produce(); tc := front; tp := new(); P : dec n; f := f.2 P(n); back.1 := tp; front := front.2; V(n); V : inc n; b := b.2 consume tc.0; back := tp dispose tc

  • back, tp, b 1

2 ⊢

back → , ∧ back = b

  • {front, tc, f 1

2 ⊢ front = f}

                 

back b f front n=3 tc tp J K L

31

slide-155
SLIDE 155

A proof with variables-as-resource

                  // Producer. // Semaphore n // Consumer.

  • back, tp, b 1

2 ⊢

back → , ∧ back = b

  • {n, f 1

2 , b 1 2 ⊢ listseg n f b} {front, tc, f 1 2 ⊢ front = f}

back.0 := produce(); tc := front; tp := new(); P : dec n; f := f.2 P(n); back.1 := tp; front := front.2; V(n); V : inc n; b := b.2 consume tc.0; back := tp dispose tc

  • back, tp, b 1

2 ⊢

back → , ∧ back = b

  • {front, tc, f 1

2 ⊢ front = f}

                 

back b f front, tc n=3 tp J K L

31

slide-156
SLIDE 156

A proof with variables-as-resource

                  // Producer. // Semaphore n // Consumer.

  • back, tp, b 1

2 ⊢

back → , ∧ back = b

  • {n, f 1

2 , b 1 2 ⊢ listseg n f b} {front, tc, f 1 2 ⊢ front = f}

back.0 := produce(); tc := front; tp := new(); P : dec n; f := f.2 P(n); back.1 := tp; front := front.2; V(n); V : inc n; b := b.2 consume tc.0; back := tp dispose tc

  • back, tp, b 1

2 ⊢

back → , ∧ back = b

  • {front, tc, f 1

2 ⊢ front = f}

                 

back b front, tc n=2 f tp J K L

31

slide-157
SLIDE 157

A proof with variables-as-resource

                  // Producer. // Semaphore n // Consumer.

  • back, tp, b 1

2 ⊢

back → , ∧ back = b

  • {n, f 1

2 , b 1 2 ⊢ listseg n f b} {front, tc, f 1 2 ⊢ front = f}

back.0 := produce(); tc := front; tp := new(); P : dec n; f := f.2 P(n); back.1 := tp; front := front.2; V(n); V : inc n; b := b.2 consume tc.0; back := tp dispose tc

  • back, tp, b 1

2 ⊢

back → , ∧ back = b

  • {front, tc, f 1

2 ⊢ front = f}

                 

back b tc n=2 f front tp J K L

31

slide-158
SLIDE 158

A proof with variables-as-resource

                  // Producer. // Semaphore n // Consumer.

  • back, tp, b 1

2 ⊢

back → , ∧ back = b

  • {n, f 1

2 , b 1 2 ⊢ listseg n f b} {front, tc, f 1 2 ⊢ front = f}

back.0 := produce(); tc := front; tp := new(); P : dec n; f := f.2 P(n); back.1 := tp; front := front.2; V(n); V : inc n; b := b.2 consume tc.0; back := tp dispose tc

  • back, tp, b 1

2 ⊢

back → , ∧ back = b

  • {front, tc, f 1

2 ⊢ front = f}

                 

back b n=2 f front tc tp K L

31

slide-159
SLIDE 159

A proof with variables-as-resource

                  // Producer. // Semaphore n // Consumer.

  • back, tp, b 1

2 ⊢

back → , ∧ back = b

  • {n, f 1

2 , b 1 2 ⊢ listseg n f b} {front, tc, f 1 2 ⊢ front = f}

back.0 := produce(); tc := front; tp := new(); P : dec n; f := f.2 P(n); back.1 := tp; front := front.2; V(n); V : inc n; b := b.2 consume tc.0; back := tp dispose tc

  • back, tp, b 1

2 ⊢

back → , ∧ back = b

  • {front, tc, f 1

2 ⊢ front = f}

                 

back b n=2 f front tp tc K L M

31

slide-160
SLIDE 160

A proof with variables-as-resource

                  // Producer. // Semaphore n // Consumer.

  • back, tp, b 1

2 ⊢

back → , ∧ back = b

  • {n, f 1

2 , b 1 2 ⊢ listseg n f b} {front, tc, f 1 2 ⊢ front = f}

back.0 := produce(); tc := front; tp := new(); P : dec n; f := f.2 P(n); back.1 := tp; front := front.2; V(n); V : inc n; b := b.2 consume tc.0; back := tp dispose tc

  • back, tp, b 1

2 ⊢

back → , ∧ back = b

  • {front, tc, f 1

2 ⊢ front = f}

                 

back b n=3 f front tp tc K L M

31

slide-161
SLIDE 161

A proof with variables-as-resource

                  // Producer. // Semaphore n // Consumer.

  • back, tp, b 1

2 ⊢

back → , ∧ back = b

  • {n, f 1

2 , b 1 2 ⊢ listseg n f b} {front, tc, f 1 2 ⊢ front = f}

back.0 := produce(); tc := front; tp := new(); P : dec n; f := f.2 P(n); back.1 := tp; front := front.2; V(n); V : inc n; b := b.2 consume tc.0; back := tp dispose tc

  • back, tp, b 1

2 ⊢

back → , ∧ back = b

  • {front, tc, f 1

2 ⊢ front = f}

                 

tp, back b n=3 f front tc K L M

31

slide-162
SLIDE 162

We can prove it!

                  // Producer. // Semaphore n // Consumer.

  • back, tp, b 1

2 ⊢

back → , ∧ back = b

  • {n, f 1

2 , b 1 2 ⊢ listseg n f b} {front, tc, f 1 2 ⊢ front = f}

back.0 := produce(); tc := front; tp := new(); P : dec n; f := f.2 P(n); back.1 := tp; front := front.2; V(n); V : inc n; b := b.2 consume tc.0; back := tp dispose tc

  • back, tp, b 1

2 ⊢

back → , ∧ back = b

  • {front, tc, f 1

2 ⊢ front = f}

                 

32

slide-163
SLIDE 163

We can prove it!

                  // Producer. // Semaphore n // Consumer.

  • back, tp, b 1

2 ⊢

back → , ∧ back = b

  • {n, f 1

2 , b 1 2 ⊢ listseg n f b} {front, tc, f 1 2 ⊢ front = f}

back.0 := produce(); tc := front; tp := new(); P : dec n; f := f.2 P(n); back.1 := tp; front := front.2; V(n); V : inc n; b := b.2 consume tc.0; back := tp dispose tc

  • back, tp, b 1

2 ⊢

back → , ∧ back = b

  • {front, tc, f 1

2 ⊢ front = f}

                 

Assertion vs ⊢ P says “owning variables vs, P holds”. P can only mention variables in vs. You can’t write to fractionally-owned variables.

32

slide-164
SLIDE 164

We can prove it!

                  // Producer. // Semaphore n // Consumer.

  • back, tp, b 1

2 ⊢

back → , ∧ back = b

  • {n, f 1

2 , b 1 2 ⊢ listseg n f b} {front, tc, f 1 2 ⊢ front = f}

back.0 := produce(); tc := front; tp := new(); P : dec n; f := f.2 P(n); back.1 := tp; front := front.2; V(n); V : inc n; b := b.2 consume tc.0; back := tp dispose tc

  • back, tp, b 1

2 ⊢

back → , ∧ back = b

  • {front, tc, f 1

2 ⊢ front = f}

                 

Assertion vs ⊢ P says “owning variables vs, P holds”. P can only mention variables in vs. You can’t write to fractionally-owned variables. P can describe separation of the heap: back → , describes

  • wnership of a two-word record; back → , ⋆ front → , describes
  • wnership of two cons-cells separately.

32

slide-165
SLIDE 165

We have more ideas than we can deal with

33

slide-166
SLIDE 166

We have more ideas than we can deal with

◮ existence (no read, no write) permissions: e.g. P+V+read/write

for semaphores;

33

slide-167
SLIDE 167

We have more ideas than we can deal with

◮ existence (no read, no write) permissions: e.g. P+V+read/write

for semaphores;

◮ mobile channels: e.g. read one end, write the other in occam; 33

slide-168
SLIDE 168

We have more ideas than we can deal with

◮ existence (no read, no write) permissions: e.g. P+V+read/write

for semaphores;

◮ mobile channels: e.g. read one end, write the other in occam; ◮ semaphores in the heap (for shared buffers which reclaim

themselves);

33

slide-169
SLIDE 169

We have more ideas than we can deal with

◮ existence (no read, no write) permissions: e.g. P+V+read/write

for semaphores;

◮ mobile channels: e.g. read one end, write the other in occam; ◮ semaphores in the heap (for shared buffers which reclaim

themselves);

◮ mobile code, maybe (if David May will tell us how it works); 33

slide-170
SLIDE 170

We have more ideas than we can deal with

◮ existence (no read, no write) permissions: e.g. P+V+read/write

for semaphores;

◮ mobile channels: e.g. read one end, write the other in occam; ◮ semaphores in the heap (for shared buffers which reclaim

themselves);

◮ mobile code, maybe (if David May will tell us how it works); ◮ ... 33

slide-171
SLIDE 171

The Grand Challenge

34

slide-172
SLIDE 172

The Grand Challenge

Resourcing problems are everywhere. The problem is to make a resourcing solution:

34

slide-173
SLIDE 173

The Grand Challenge

Resourcing problems are everywhere. The problem is to make a resourcing solution:

◮ as lightweight as typing; 34

slide-174
SLIDE 174

The Grand Challenge

Resourcing problems are everywhere. The problem is to make a resourcing solution:

◮ as lightweight as typing; ◮ built into language designs; 34

slide-175
SLIDE 175

The Grand Challenge

Resourcing problems are everywhere. The problem is to make a resourcing solution:

◮ as lightweight as typing; ◮ built into language designs; ◮ built into compilers. 34

slide-176
SLIDE 176

The Grand Challenge

Resourcing problems are everywhere. The problem is to make a resourcing solution:

◮ as lightweight as typing; ◮ built into language designs; ◮ built into compilers.

If we build it, they will come (as they came for types).

34