Simpson’s 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
Programming is really hard: only nine lines, no CAS, and you still can’t understand it 3
Programming is really hard: only nine lines, no CAS, and you still can’t understand it reading , latest : bit var slot : array bit of bit data : array bit of array bit of datatype procedure write ( item : datatype ); pair , index : bit ; var begin pair := not ( reading ); index := not ( slot [ pair ]); data [ pair , index ] := item ; slot [ pair ] := index ; latest := pair end ; read : datatype ; procedure pair , index : bit ; var begin pair := latest ; reading := pair ; index := slot [ pair ]; read := data [ pair , index ] end ; 3
Separation logic 4
Separation logic ◮ E �→ F is a single-celled heap with address E and content F . 4
Separation logic ◮ E �→ F is a single-celled heap with address E and content F . ◮ E �→ F 0 , F 1 is a two-celled heap; E �→ F 0 , F 1 , F 2 is three cells; and so on for four-, five-, ... celled heaps. 4
Separation logic ◮ E �→ F is a single-celled heap with address E and content F . ◮ E �→ F 0 , F 1 is a two-celled heap; E �→ F 0 , F 1 , F 2 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
Separation logic ◮ E �→ F is a single-celled heap with address E and content F . ◮ E �→ F 0 , F 1 is a two-celled heap; E �→ F 0 , F 1 , F 2 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
Separation logic ◮ E �→ F is a single-celled heap with address E and content F . ◮ E �→ F 0 , F 1 is a two-celled heap; E �→ F 0 , F 1 , F 2 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 �→ F 0 , F 1 is just shorthand for E �→ F 0 ⋆ E + 1 �→ F 1 . 4
A modified Hoare logic 5
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
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
Three inference rules 6
Three inference rules { Q } C { R } (modifies C � free P = {} ) ◮ The frame rule: { P ⋆ Q } C { P ⋆ R } 6
Three inference rules { Q } C { R } (modifies C � free P = {} ) ◮ The frame rule: { P ⋆ Q } C { P ⋆ R } ◮ The concurrency rule (has horrid side-condition): { Q 1 } C 1 { R 1 } { Q 2 } C 2 { R 2 } . . . { Q n } C n { R n } { Q 1 ⋆ Q 2 ⋆ · · · ⋆ Q n } C 1 || C 2 || · · · || C n { R 1 ⋆ R 2 ⋆ · · · ⋆ R n } 6
Three inference rules { Q } C { R } (modifies C � free P = {} ) ◮ The frame rule: { P ⋆ Q } C { P ⋆ R } ◮ The concurrency rule (has horrid side-condition): { Q 1 } C 1 { R 1 } { Q 2 } C 2 { R 2 } . . . { Q n } C n { R n } { Q 1 ⋆ Q 2 ⋆ · · · ⋆ Q n } C 1 || C 2 || · · · || C n { R 1 ⋆ R 2 ⋆ · · · ⋆ R n } ◮ The CCR rule (has atrocious side condition): { ( Q ⋆ I b ) ∧ G } C { R ⋆ I b } { Q } with b when G do C od { R } 6
Recent simplifications (not explained here) 7
Recent simplifications (not explained here) ◮ Permissions (fractions of �→ , counts of ) to allow sharing of heap; 7
Recent simplifications (not explained here) ◮ Permissions (fractions of �→ , counts of ) to allow sharing of heap; ◮ Variable permissions, to allow variables to be resource; 7
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
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
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 with bundle when true do pair := latest od; read: 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
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
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.) latest 0 . 5 , slot 0 . 5 , data 0 . 33 , wuse 0 . 5 , pair , index � slot [ 0 ] �− − − → ⋆ slot [ 1 ] �− − − → ⋆ � 0 . 5 0 . 5 � if wuse ≥ 0 then data [ pair , index ] �→ else emp fi 9
What the reader owns reading 0 . 5 , ruse 0 . 5 , data 0 . 33 , pair , index � if ruse ≥ 0 then data [ pair , index ] �→ else emp fi 10
The bundle owns the rest latest 0 . 5 , reading 0 . 5 , slot 0 . 5 , data 0 . 33 , wuse 0 . 5 , ruse 0 . 5 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 )))] �→ � ∃ s · 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
The writer � � latest 0 . 5 , slot 0 . 5 , data 0 . 33 , wuse 0 . 5 , pair , index � wuse = − 1 ∧ slot [ 0 ] �− − − → ⋆ slot [ 1 ] �− − − → 0 . 5 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 � � latest 0 . 5 , slot 0 . 5 , data 0 . 33 , wuse 0 . 5 , pair , index � wuse = − 1 ∧ slot [ 0 ] �− − − → ⋆ slot [ 1 ] �− − − → 0 . 5 0 . 5 12
The writer � � latest 0 . 5 , slot 0 . 5 , data 0 . 33 , wuse 0 . 5 , pair , index � wuse = − 1 ∧ slot [ 0 ] �− − − → ⋆ slot [ 1 ] �− − − → 0 . 5 0 . 5 with bundle when true do pair := not ( reading ); wuse := pair od; latest 0 . 5 , slot 0 . 5 , data 0 . 33 , wuse 0 . 5 , pair , index � slot [ pair ] �− − 0 . 5 i ⋆ slot [ not ( pair )] �− − → − − → ⋆ � � wuse = pair ∧ ∃ i · 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 � � latest 0 . 5 , slot 0 . 5 , data 0 . 33 , wuse 0 . 5 , pair , index � wuse = − 1 ∧ slot [ 0 ] �− − − → ⋆ slot [ 1 ] �− − − → 0 . 5 0 . 5 12
Recommend
More recommend