Simpsons 4-slot algorithm, proved in three slides Richard Bornat - - PowerPoint PPT Presentation

simpson s 4 slot algorithm proved in three slides
SMART_READER_LITE
LIVE PREVIEW

Simpsons 4-slot algorithm, proved in three slides Richard Bornat - - PowerPoint PPT Presentation

Simpsons 4-slot algorithm, proved in three slides Richard Bornat School of Computing, Middlesex University (and Matthew Parkinson, ditto) 20th December 2005 1 Data structures: a bit array and a wide data array slot: 0 1 wide data: 2


slide-1
SLIDE 1

Simpson’s 4-slot algorithm, proved in three slides

Richard Bornat School of Computing, Middlesex University (and Matthew Parkinson, ditto) 20th December 2005

1

slide-2
SLIDE 2

Data structures: a bit array and a wide data array

slot: 1 data: wide

2

slide-3
SLIDE 3

Programming is really hard: only nine lines, no CAS, and you still can’t understand it

3

slide-4
SLIDE 4

Programming is really hard: only nine lines, no CAS, and you still can’t understand it

var reading, latest : bit slot : array bit of bit data : array bit of array bit of datatype procedure write (item : datatype); var pair, index : bit; begin pair := not(reading); index := not(slot[pair]); data[pair, index] := item; slot[pair] := index; latest := pair end; procedure read : datatype; var pair, index : bit; begin pair := latest; reading := pair; index := slot[pair]; read := data[pair, index] end;

3

slide-5
SLIDE 5

Separation logic

4

slide-6
SLIDE 6

Separation logic

◮ E → F is a single-celled heap with address E and content F. 4

slide-7
SLIDE 7

Separation logic

◮ E → F is a single-celled heap with address E and content F. ◮ E → F0, F1 is a two-celled heap; E → F0, F1, F2 is three cells;

and so on for four-, five-, ... celled heaps.

4

slide-8
SLIDE 8

Separation logic

◮ E → F is a single-celled heap with address E and content F. ◮ E → F0, F1 is a two-celled heap; E → F0, F1, F2 is three cells;

and so on for four-, five-, ... celled heaps.

◮ E and F must be ‘pure’ expressions that don’t mention the heap

(don’t use →).

4

slide-9
SLIDE 9

Separation logic

◮ E → F is a single-celled heap with address E and content F. ◮ E → F0, F1 is a two-celled heap; E → F0, F1, F2 is three cells;

and so on for four-, five-, ... celled heaps.

◮ E and F must be ‘pure’ expressions that don’t mention the heap

(don’t use →).

◮ A ⋆ B is separation of heaps; A ∧ B, A ∨ B, ¬A, A → B, ∀x · P(x),

∃x · P(x) are as normal. A ∧ B expresses coincidence of heaps; you don’t need to know about A − ⋆ B.

4

slide-10
SLIDE 10

Separation logic

◮ E → F is a single-celled heap with address E and content F. ◮ E → F0, F1 is a two-celled heap; E → F0, F1, F2 is three cells;

and so on for four-, five-, ... celled heaps.

◮ E and F must be ‘pure’ expressions that don’t mention the heap

(don’t use →).

◮ A ⋆ B is separation of heaps; A ∧ B, A ∨ B, ¬A, A → B, ∀x · P(x),

∃x · P(x) are as normal. A ∧ B expresses coincidence of heaps; you don’t need to know about A − ⋆ B.

◮ E → F0, F1 is just shorthand for E → F0 ⋆ E + 1 → F1. 4

slide-11
SLIDE 11

A modified Hoare logic

5

slide-12
SLIDE 12

A modified Hoare logic

◮ {Q} C {R} is a resourced and partial correctness assertion. C

will not go wrong (exceed its allocated resources) if started with resource Q, and will, if it terminates, deliver resource R.

5

slide-13
SLIDE 13

A modified Hoare logic

◮ {Q} C {R} is a resourced and partial correctness assertion. C

will not go wrong (exceed its allocated resources) if started with resource Q, and will, if it terminates, deliver resource R.

◮ The ‘small axioms’ of assignment are

{emp} x := new() {x → } {E → } dispose E {emp} {R[E/x]} x := E {R} (the Hoare axiom) {E → F} x := [E] {x = F ∧ E → F} (x not free in E, F) {E → } [E] := F {E → F}

5

slide-14
SLIDE 14

Three inference rules

6

slide-15
SLIDE 15

Three inference rules

◮ The frame rule:

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

(modifies C free P = {})

6

slide-16
SLIDE 16

Three inference rules

◮ The frame rule:

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

(modifies C free P = {})

◮ The concurrency rule (has horrid side-condition):

{Q1} C1 {R1} {Q2} C2 {R2} . . . {Qn} Cn {Rn} {Q1 ⋆ Q2 ⋆ · · · ⋆ Qn} C1 || C2 || · · · || Cn {R1 ⋆ R2 ⋆ · · · ⋆ Rn}

6

slide-17
SLIDE 17

Three inference rules

◮ The frame rule:

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

(modifies C free P = {})

◮ The concurrency rule (has horrid side-condition):

{Q1} C1 {R1} {Q2} C2 {R2} . . . {Qn} Cn {Rn} {Q1 ⋆ Q2 ⋆ · · · ⋆ Qn} C1 || C2 || · · · || Cn {R1 ⋆ R2 ⋆ · · · ⋆ Rn}

◮ The CCR rule (has atrocious side condition):

{(Q ⋆ Ib) ∧ G} C {R ⋆ Ib} {Q} with b when G do C od {R}

6

slide-18
SLIDE 18

Recent simplifications (not explained here)

7

slide-19
SLIDE 19

Recent simplifications (not explained here)

◮ Permissions (fractions of →, counts of ֌) to allow sharing of

heap;

7

slide-20
SLIDE 20

Recent simplifications (not explained here)

◮ Permissions (fractions of →, counts of ֌) to allow sharing of

heap;

◮ Variable permissions, to allow variables to be resource; 7

slide-21
SLIDE 21

Recent simplifications (not explained here)

◮ Permissions (fractions of →, counts of ֌) to allow sharing of

heap;

◮ Variable permissions, to allow variables to be resource; ◮ Trivial side conditions; 7

slide-22
SLIDE 22

Recent simplifications (not explained here)

◮ Permissions (fractions of →, counts of ֌) to allow sharing of

heap;

◮ Variable permissions, to allow variables to be resource; ◮ Trivial side conditions; ◮ No side conditions at all (very new, this!). 7

slide-23
SLIDE 23

Nine lines are now ten, with added auxiliary proof-variables

write: with bundle when true do pair := not(reading); wuse := pair od; index := not(slot[pair]); data[pair, index] := item; with bundle when true do slot[pair] := index; wuse := −1 od; with bundle when true do latest := pair od read: with bundle when true do pair := latest od; with bundle when true do reading := pair od; with bundle when true do index := slot[pair]; ruse := index od; read := data[pair, index]; with bundle when true do ruse := −1 od

8

slide-24
SLIDE 24

What the writer owns

(A point of notation: I’ve used a special form of → to describe a heap, just to make the slides easy to read. For example, data[pair, index] → replaces data + 2 ⋆ pair + index → . There is no change in meaning.)

9

slide-25
SLIDE 25

What the writer owns

(A point of notation: I’ve used a special form of → to describe a heap, just to make the slides easy to read. For example, data[pair, index] → replaces data + 2 ⋆ pair + index → . There is no change in meaning.) latest0.5, slot0.5, data0.33, wuse0.5, pair, index

  • slot[0] −

− − →

0.5

⋆ slot[1] − − − →

0.5

⋆ if wuse ≥ 0 then data[pair, index] → else emp fi

  • 9
slide-26
SLIDE 26

What the reader owns

reading0.5, ruse0.5, data0.33, pair, index if ruse ≥ 0 then data[pair, index] → else emp fi

10

slide-27
SLIDE 27

The bundle owns the rest

latest0.5, reading0.5, slot0.5, data0.33, wuse0.5, ruse0.5 ∃s ·                      slot[0] − − − →

0.5 s(0) ⋆ slot[1] −

− − →

0.5 s(1) ⋆

if wuse ≥ 0 ∧ ruse ≥ 0 then data[reading, not(ruse)] → ⋆ data[wuse, s(wuse)] → elsf wuse ≥ 0 then data[wuse, s(wuse)] → ⋆ data[not(wuse), s(not(wuse))] → ⋆ data[not(wuse), not(s(not(wuse)))] → elsf ruse ≥ 0 then data[reading, not(ruse)] → ⋆ data[not(reading), s(not(reading))] → ⋆ data[not(reading), not(s(not(reading))] → ) else data → , , , fi                     

11

slide-28
SLIDE 28

The writer

  • latest0.5, slot0.5, data0.33, wuse0.5, pair, index wuse = −1 ∧ slot[0] −

− − →

0.5

⋆ slot[1] − − − →

0.5

  • with bundle when true do pair := not(reading); wuse := pair od;

index := not(slot[pair]); data[pair, index] := item; with bundle when true do slot[pair] := index; wuse := −1 od; with bundle when true do latest := pair od

  • latest0.5, slot0.5, data0.33, wuse0.5, pair, index wuse = −1 ∧ slot[0] −

− − →

0.5

⋆ slot[1] − − − →

0.5

  • 12
slide-29
SLIDE 29

The writer

  • latest0.5, slot0.5, data0.33, wuse0.5, pair, index wuse = −1 ∧ slot[0] −

− − →

0.5

⋆ slot[1] − − − →

0.5

  • with bundle when true do pair := not(reading); wuse := pair od;

   latest0.5, slot0.5, data0.33, wuse0.5, pair, index wuse = pair ∧ ∃i · slot[pair] − − − →

0.5 i ⋆ slot[not(pair)] −

− − →

0.5

⋆ data[pair, not(i)] →

  index := not(slot[pair]); data[pair, index] := item; with bundle when true do slot[pair] := index; wuse := −1 od; with bundle when true do latest := pair od

  • latest0.5, slot0.5, data0.33, wuse0.5, pair, index wuse = −1 ∧ slot[0] −

− − →

0.5

⋆ slot[1] − − − →

0.5

  • 12
slide-30
SLIDE 30

The writer

  • latest0.5, slot0.5, data0.33, wuse0.5, pair, index wuse = −1 ∧ slot[0] −

− − →

0.5

⋆ slot[1] − − − →

0.5

  • with bundle when true do pair := not(reading); wuse := pair od;

   latest0.5, slot0.5, data0.33, wuse0.5, pair, index wuse = pair ∧ ∃i · slot[pair] − − − →

0.5 i ⋆ slot[not(pair)] −

− − →

0.5

⋆ data[pair, not(i)] →

  index := not(slot[pair]);    latest0.5, slot0.5, data0.33, wuse0.5, pair, index wuse = pair ∧ slot[pair] − − − →

0.5 not(index) ⋆ slot[not(pair)] −

− − →

0.5

⋆ data[pair, index] →

  data[pair, index] := item; with bundle when true do slot[pair] := index; wuse := −1 od; with bundle when true do latest := pair od

  • latest0.5, slot0.5, data0.33, wuse0.5, pair, index wuse = −1 ∧ slot[0] −

− − →

0.5

⋆ slot[1] − − − →

0.5

  • 12
slide-31
SLIDE 31

The writer

  • latest0.5, slot0.5, data0.33, wuse0.5, pair, index wuse = −1 ∧ slot[0] −

− − →

0.5

⋆ slot[1] − − − →

0.5

  • with bundle when true do pair := not(reading); wuse := pair od;

   latest0.5, slot0.5, data0.33, wuse0.5, pair, index wuse = pair ∧ ∃i · slot[pair] − − − →

0.5 i ⋆ slot[not(pair)] −

− − →

0.5

⋆ data[pair, not(i)] →

  index := not(slot[pair]);    latest0.5, slot0.5, data0.33, wuse0.5, pair, index wuse = pair ∧ slot[pair] − − − →

0.5 not(index) ⋆ slot[not(pair)] −

− − →

0.5

⋆ data[pair, index] →

  data[pair, index] := item;    latest0.5, slot0.5, data0.33, wuse0.5, pair, index wuse = pair ∧ slot[pair] − − − →

0.5 not(index) ⋆ slot[not(pair)] −

− − →

0.5

⋆ data[pair, index] → item

  with bundle when true do slot[pair] := index; wuse := −1 od; with bundle when true do latest := pair od

  • latest0.5, slot0.5, data0.33, wuse0.5, pair, index wuse = −1 ∧ slot[0] −

− − →

0.5

⋆ slot[1] − − − →

0.5

  • 12
slide-32
SLIDE 32

The writer

  • latest0.5, slot0.5, data0.33, wuse0.5, pair, index wuse = −1 ∧ slot[0] −

− − →

0.5

⋆ slot[1] − − − →

0.5

  • with bundle when true do pair := not(reading); wuse := pair od;

   latest0.5, slot0.5, data0.33, wuse0.5, pair, index wuse = pair ∧ ∃i · slot[pair] − − − →

0.5 i ⋆ slot[not(pair)] −

− − →

0.5

⋆ data[pair, not(i)] →

  index := not(slot[pair]);    latest0.5, slot0.5, data0.33, wuse0.5, pair, index wuse = pair ∧ slot[pair] − − − →

0.5 not(index) ⋆ slot[not(pair)] −

− − →

0.5

⋆ data[pair, index] →

  data[pair, index] := item;    latest0.5, slot0.5, data0.33, wuse0.5, pair, index wuse = pair ∧ slot[pair] − − − →

0.5 not(index) ⋆ slot[not(pair)] −

− − →

0.5

⋆ data[pair, index] → item

  with bundle when true do slot[pair] := index; wuse := −1 od;

  • latest0.5, slot0.5, data0.33, wuse0.5, pair, index wuse = −1 ∧ slot[0] −

− − →

0.5

⋆ slot[1] − − − →

0.5

  • with bundle when true do latest := pair od
  • latest0.5, slot0.5, data0.33, wuse0.5, pair, index wuse = −1 ∧ slot[0] −

− − →

0.5

⋆ slot[1] − − − →

0.5

  • 12
slide-33
SLIDE 33

Details of the first writer step

  • latest0.5, slot0.5, data0.33, wuse0.5, pair, index wuse = −1 ∧ slot[0] −

− − →

0.5

⋆ slot[1] − − − →

0.5

  • with bundle when true do

pair := not(reading); wuse := pair

  • d;
  • latest0.5, slot0.5, data0.33, wuse0.5, pair, index

wuse = pair ∧ ∃i ·

  • slot[pair] −

− − →

0.5 i ⋆ slot[not(pair)] −

− − →

0.5

⋆ data[pair, not(i)] →

  • 13
slide-34
SLIDE 34

Details of the first writer step

  • latest0.5, slot0.5, data0.33, wuse0.5, pair, index wuse = −1 ∧ slot[0] −

− − →

0.5

⋆ slot[1] − − − →

0.5

  • with bundle when true do

               latest, reading0.5, slot, data0.66, wuse,pair, index ∃s ·       wuse = −1 ∧ slot → s(0), s(1) ⋆ data[not(reading), s(not(reading))] → ⋆ data[not(reading), not(s(not(reading)))] → ⋆ if ruse ≥ 0 then data[reading, not(ruse)] → else data[reading, s(reading)] → ⋆ data[reading, not(s(reading))] → fi                      pair := not(reading); wuse := pair

  • d;
  • latest0.5, slot0.5, data0.33, wuse0.5, pair, index

wuse = pair ∧ ∃i ·

  • slot[pair] −

− − →

0.5 i ⋆ slot[not(pair)] −

− − →

0.5

⋆ data[pair, not(i)] →

  • 13
slide-35
SLIDE 35

Details of the first writer step

  • latest0.5, slot0.5, data0.33, wuse0.5, pair, index wuse = −1 ∧ slot[0] −

− − →

0.5

⋆ slot[1] − − − →

0.5

  • with bundle when true do

               latest, reading0.5, slot, data0.66, wuse,pair, index ∃s ·       wuse = −1 ∧ slot → s(0), s(1) ⋆ data[not(reading), s(not(reading))] → ⋆ data[not(reading), not(s(not(reading)))] → ⋆ if ruse ≥ 0 then data[reading, not(ruse)] → else data[reading, s(reading)] → ⋆ data[reading, not(s(reading))] → fi                      pair := not(reading);                latest, reading0.5, slot, data0.66, wuse,pair, index ∃s ·       wuse = −1 ∧ pair = not(reading) ∧ slot → s(0), s(1) ⋆ data[not(reading), s(not(reading))] → ⋆ data[not(reading), not(s(not(reading)))] → ⋆ if ruse ≥ 0 then data[reading, not(ruse)] → else data[reading, s(reading)] → ⋆ data[reading, not(s(reading))] → fi                      wuse := pair

  • d;
  • latest0.5, slot0.5, data0.33, wuse0.5, pair, index

wuse = pair ∧ ∃i ·

  • slot[pair] −

− − →

0.5 i ⋆ slot[not(pair)] −

− − →

0.5

⋆ data[pair, not(i)] →

  • 13
slide-36
SLIDE 36

Details of the first writer step

  • latest0.5, slot0.5, data0.33, wuse0.5, pair, index wuse = −1 ∧ slot[0] −

− − →

0.5

⋆ slot[1] − − − →

0.5

  • with bundle when true do

               latest, reading0.5, slot, data0.66, wuse,pair, index ∃s ·       wuse = −1 ∧ slot → s(0), s(1) ⋆ data[not(reading), s(not(reading))] → ⋆ data[not(reading), not(s(not(reading)))] → ⋆ if ruse ≥ 0 then data[reading, not(ruse)] → else data[reading, s(reading)] → ⋆ data[reading, not(s(reading))] → fi                      pair := not(reading);                latest, reading0.5, slot, data0.66, wuse,pair, index ∃s ·       wuse = −1 ∧ pair = not(reading) ∧ slot → s(0), s(1) ⋆ data[not(reading), s(not(reading))] → ⋆ data[not(reading), not(s(not(reading)))] → ⋆ if ruse ≥ 0 then data[reading, not(ruse)] → else data[reading, s(reading)] → ⋆ data[reading, not(s(reading))] → fi                      wuse := pair                latest, reading0.5, slot, data0.66, wuse,pair, index ∃s ·       wuse = pair ∧ pair = not(reading) ∧ slot → s(0), s(1) ⋆ data[not(reading), s(not(reading))] → ⋆ data[not(reading), not(s(not(reading)))] → ⋆ if ruse ≥ 0 then data[reading, not(ruse)] → else data[reading, s(reading)] → ⋆ data[reading, not(s(reading))] → fi                     

  • d;
  • latest0.5, slot0.5, data0.33, wuse0.5, pair, index

wuse = pair ∧ ∃i ·

  • slot[pair] −

− − →

0.5 i ⋆ slot[not(pair)] −

− − →

0.5

⋆ data[pair, not(i)] →

  • 13
slide-37
SLIDE 37

The reader is even easier than the writer!

  • reading0.5, ruse0.5, data0.33, pair, index ruse = −1
  • with bundle when true do pair := latest od;

with bundle when true do reading := pair od; with bundle when true do index := slot[pair]; ruse := index od; read := data[pair, index]; with bundle when true do ruse := −1 od

  • reading0.5, ruse0.5, data0.33, pair, index ruse = −1
  • 14
slide-38
SLIDE 38

The reader is even easier than the writer!

  • reading0.5, ruse0.5, data0.33, pair, index ruse = −1
  • with bundle when true do pair := latest od;
  • reading0.5, ruse0.5, data0.33, pair, index ruse = −1
  • with bundle when true do reading := pair od;

with bundle when true do index := slot[pair]; ruse := index od; read := data[pair, index]; with bundle when true do ruse := −1 od

  • reading0.5, ruse0.5, data0.33, pair, index ruse = −1
  • 14
slide-39
SLIDE 39

The reader is even easier than the writer!

  • reading0.5, ruse0.5, data0.33, pair, index ruse = −1
  • with bundle when true do pair := latest od;
  • reading0.5, ruse0.5, data0.33, pair, index ruse = −1
  • with bundle when true do reading := pair od;
  • reading0.5, ruse0.5, data0.33, pair, index ruse = −1 ∧ reading = pair
  • with bundle when true do index := slot[pair]; ruse := index od;

read := data[pair, index]; with bundle when true do ruse := −1 od

  • reading0.5, ruse0.5, data0.33, pair, index ruse = −1
  • 14
slide-40
SLIDE 40

The reader is even easier than the writer!

  • reading0.5, ruse0.5, data0.33, pair, index ruse = −1
  • with bundle when true do pair := latest od;
  • reading0.5, ruse0.5, data0.33, pair, index ruse = −1
  • with bundle when true do reading := pair od;
  • reading0.5, ruse0.5, data0.33, pair, index ruse = −1 ∧ reading = pair
  • with bundle when true do index := slot[pair]; ruse := index od;
  • reading0.5, ruse0.5, data0.33, pair, index ruse ≥ 0 ∧ reading = pair ∧ data[pair, index] →
  • read := data[pair, index];

with bundle when true do ruse := −1 od

  • reading0.5, ruse0.5, data0.33, pair, index ruse = −1
  • 14
slide-41
SLIDE 41

The reader is even easier than the writer!

  • reading0.5, ruse0.5, data0.33, pair, index ruse = −1
  • with bundle when true do pair := latest od;
  • reading0.5, ruse0.5, data0.33, pair, index ruse = −1
  • with bundle when true do reading := pair od;
  • reading0.5, ruse0.5, data0.33, pair, index ruse = −1 ∧ reading = pair
  • with bundle when true do index := slot[pair]; ruse := index od;
  • reading0.5, ruse0.5, data0.33, pair, index ruse ≥ 0 ∧ reading = pair ∧ data[pair, index] →
  • read := data[pair, index];

reading0.5, ruse0.5, data0.33, pair, index ruse ≥ 0 ∧ reading = pair ∧ ∃i · data[pair, index] → i ∧ read = i

  • with bundle when true do ruse := −1 od
  • reading0.5, ruse0.5, data0.33, pair, index ruse = −1
  • 14
slide-42
SLIDE 42

The rest of the reader is too easy to bother with

with bundle when true do index := slot[pair]; ruse := index (in the reader) is very very very similar to with bundle when true do pair := not(reading); wuse := pair od (which I just showed you in detail from the writer), so you don’t need to see it.

15

slide-43
SLIDE 43

The rest of the reader is too easy to bother with

with bundle when true do index := slot[pair]; ruse := index (in the reader) is very very very similar to with bundle when true do pair := not(reading); wuse := pair od (which I just showed you in detail from the writer), so you don’t need to see it. And the rest of the reader is trivial.

15