310 likes | 502 Views
Programming Language Semantics Axiomatic Semantics of Parallel Programs. Tentative Schedule. 15/6 Parallel Programs 22/6 Rely/Guarantee Reasoning Assignment 2 29/6 Separation Logic 6, 3/7 Type Inference Assignment 3. Plan. More on Hoare Proof Rules Proof Rules for Concurrent Programs.
E N D
Programming Language SemanticsAxiomatic Semantics of Parallel Programs
Tentative Schedule • 15/6 Parallel Programs • 22/6 Rely/Guarantee Reasoning • Assignment 2 • 29/6 Separation Logic • 6, 3/7 Type Inference • Assignment 3
Plan • More on Hoare Proof Rules • Proof Rules for Concurrent Programs
Hoare Proof Rules for Partial Correctness {A} skip {A} {B[a/X]} X:=a {B} (Assignment Rule) {P} c0 {C} {C} c1 {Q} {P} c0;c1{Q} (Composition Rule) {Pb} c0 {Q} {P b} c1 {Q} {P} if b then c0 else c1{Q} (Conditional Rule) (Loop Rule) {Ib} c {I} {I} while b do c{Ib} P P’ {P’} c {Q’} Q’ Q {P} c {Q} (Consequence Rule)
Potential Language Extensions • Blocks • Procedures • Procedures as parameters • Abstract data types • Non-determinism • Parallelism • Arrays, Pointers, and Dynamic allocations
{P1} c {Q1} {P2} c {Q2} {P1P2} c {Q1Q2} (Conjunction Rule) {P} c {P} where Mod(c)Var(P) = (Invariance Rule) More Rules
Underlying Principles of Hoare Rules • Commands are predicate transformers • Different behaviors for different preconditions • Commands can be partial • Resource restriction • Implementation restriction • In {P} comm {Q} • P and Q are contracts with the clients of comm
An Axiomatic Proof Technique for Parallel Programs Owicky & Gries Verification of Sequential and Concurrent Programs Apt & Oldrog Chapters 4-6
IMP+ Parallel Constructs • Abstract syntaxcom::= X := a | skip | com1 ; com2 |if b then com1else com2 |while b do com| cobegin com1 || com2 … || comk coend • All the interleavings of are executed • Example • cobegin X := 1 || (X :=2 ; X := X+2) coend
A First Attempt {P1} c1 {Q1} {P2} c2 {Q2}.. {Pk} ck {Qk} {P1P2 …Pk} cobegin c1 || c2 || …|| cn coend {Q1Q2… Qk} (Parallel Rule)
Simple Examples {true} X := 1 { X >0 } {true} Y:= 1 {Y>0} {true} cobegin X :=1 || Y := 1 coend{X>0 Y >0} {true} X := 1 { X >0 } {true} X:=2 ; X := X+2 {X>0} {true} cobegin X :=1 || X:=2 ; X := X+2 coend{X>0 }
Unsoundness {Y=1} X := 0 { Y=1 } {true} Y:=0 {true} {Y=1} cobegin X :=0 || Y:=0 coend {Y=1 }
Modified Parallel Rule {P1} c1 {Q1} {P2} c2 {Q2}.. {Pk} ck {Qk} {P1P2 …Pk} cobegin c1 || c2 || …|| ck coend {Q1Q2… Qk} Mod(cj)Var(Pi) = Mod(cj)Var(Qi) = ij
Unsoundness from sharing {true} X := 1 { X >0 } {true} X:=2 ; X := X+2 {X>3} {true} cobegin X :=1 || X:=2 ; X := X+2 coend {X>3 }
Handling Shared Variables • Carefully design the proofs of every thread to make them local • Show that the code of other threads do not interfere with the proofs of other threads
Interference • A command T with a precondition pre(T) does not interfere with the proof of {P} C {Q} if: • {Q pre(T) } T {Q} • For any command C’ inside C with a precondition pre(C’) • {pre(C’) pre(T) } T {pre(C’)} • {P1} c1 {Q1} {P2} c2 {Q2}.. {Pk} ck {Qk} are interference free if for every i j and for every assignment in T in ci does not interfere with {Pj} cj {Qj}
Modified Parallel Rule {P1} c1 {Q1} {P2} c2 {Q2}.. {Pk} ck {Qk} {P1P2 …Pk} cobegin c1 || c2 || …|| ck coend {Q1Q2… Qk} {P1} c1 {Q1} {P2} c2 {Q2}.. {Pk} ck {Qk} are interference free
No unsoundness from sharing {true} X := 1 { X >0 } {true} X:=2 ; X := X+2 {X>3} {true} cobegin X :=1 || X:=2 ; X := X+2 coend {X>3 }
A Realistic Example ES=eventopM+1 even(i) l: (even(l) 0<l<i) x(l)0 eventopM x(eventop)>0 Findpos: begin initialize: i :=2 ; j :=1; eventop = M+1 ; oddtop := M+1; search: cobegin Evensearch: while i < min(oddtop, eventop) do if (x(i) > 0) then eventop := i else i := i + 2; || Oddsearch: while j < min(oddtop, eventop) do if (x(j) > 0) then oddtop := j else j := j + 2; coend k := min(eventop, oddtop) end{k M+1 (l: 1 l <k x(l) 0) (k Mx(k)>0)} OS=oddtopM+1 odd(j) l: (odd(l) 0<l<j) x(l)0 oddtopM x(oddtop)>0
Incompleteness • There exist correct programs which cannot be verified by the parallelization rule • {X = Y} cobegin X := X + 1 || Y := Y+1 coend {X=Y}
An Informal Proof of {X = Y} cobegin X := X + 1 || Y := Y+1 coend {X=Y} {X = Z} X : = X + 1 { X = Z +1} {Y = Z} Y : = Y + 1 { Y = Z +1} {X = Z Y = Z}cobegin X := X + 1 || Y := Y+1 coend {X=Z+1 Y= Z+1} {X = Z Y = Z}cobegin X := X + 1 || Y := Y+1 coend {X=Y} {X = Y} Z : = X { X = Y Y = Z} {X =Y } Z : = X ; cobegin X := X + 1 || Y := Y+1 coend {X=Y} {X =Y }cobegin X := X + 1 || Y := Y+1 coend {X=Y}
Auxiliary Variables • Record history information • A set of variables AV is auxiliary for a command S if each variable from AV only occurs in assignments of the form X := t where X AV • Auxiliary variable elimination rule {P} S {Q} {P} S’ {Q} Where A is auxiliary for SFV(Q) A = FV(P) A = S’ results from S by deleting all assignments in to variables in S
A Formal Proof of {X = Y} cobegin X := X + 1 || Y := Y+1 coend {X=Y} (Assign-Rule) {X = Z} X : = X + 1 { X = Z +1} (Assign-Rule) {Y = Z} Y : = Y + 1 { Y = Z +1} {X = Z Y = Z}cobegin X := X + 1 || Y := Y+1 coend {X=Z+1 Y= Z+1} (Par-Rule) {X = Z Y = Z}cobegin X := X + 1 || Y := Y+1 coend {X=Y} (Cons.-Rule) (Assign-Rule) {X = Y} Z : = X { X = Y Y = Z} {X =Y } Z : = X ; cobegin X := X + 1 || Y := Y+1 coend {X=Y} (Comp.-Rule) {X =Y }cobegin X := X + 1 || Y := Y+1 coend {X=Y} (Aux.-Rule)
Synchronization Primitives • Support for atomic sections and communication • A High Level Constructawait B then S • No parallelization in S • Blocked until B holds • If B is true then S is executed atomically • Examples • await true then S • Await “some condition” then skip • Semaphore • P(sem): await sem >0 then sem := sem – 1 • V(sem): await true then sem := sem + 1
Interference (modified) • A command T with a precondition pre(T) does not interfere with the proof of {P} C {Q} if: • {Q pre(T) } T {Q} • For any command C’ inside C but not within await with a precondition pre(C’) • {pre(C’) pre(T) } T {pre(C’)} • {P1} c1 {Q1} {P2} c2 {Q2}.. {Pk} ck {Qk} are interference free if for every i j and for every assignment not inside await or an await T in ci does not interfere with {Pj} cj {Qj}
An Inference Rule for Await {P b} c {Q} {P } await B then c {Q}
Producer-Consumer • Two processes communicating via a shared bounded buffer • Consumer waits for the buffer to be filled • Producer waits for the buffer to be non-full and fills the buffer • buffer[0..N-1] • in – the number of elements added • out – the number of elements deleted • buffer[out mod N], … buffer[(out + in – out -1) mod N] elements
Producer/Consumer Code in := 0; out := 0 ; cobegin producer: … await in-out < N then skip add: buffer(in mod N) := next value; markin: in := in +1; … || consumer: … await in-out >0 then skip remove: this value := buffer(out mod N); markout: out := out +1; … coend
in := 0; out := 0 ; i := 1; j :=1; {M 0} cobegin producer: while i M do begin x:= A[i]; await in-out <N then skip; add: buffer[in mod N] := x ; markin: in := in + 1; i := i + 1 end || consumer: while j M do begin await in-out >0 then skip; remove: y := buffer[out mod N] ; markout: out := out + 1; B[j] := y; j := j + 1 end coend {k: 1 k M B[k] = A[k]} I= k: out < k M buffer[(k-1} mod N] = A[k] 0 in-out N 0 i M+1 0 j M+1
{I i = in+1=1 j=out+1=1} cobegin {I i = in+1=1} producer: while i M do begin x:= A[i]; await in-out <N then skip; add: buffer[in mod N] := x ; markin: in := in + 1; i := i + 1 end {I i = in+1=M+1} || {I j = out+1=1} consumer: while j M do begin await in-out >0 then skip; remove: y := buffer[out mod N] ; markout: out := out + 1; B[j] := y; j := j + 1 end {I k: 1 k M B[k] = A[k]}} coend {k: 1 k M B[k] = A[k]} I= k: out < k M buffer[(k-1} mod N] = A[k] 0 in-out N 0 i M+1 0 j M+1
Summary • Reasoning about concurrent programs is difficult • Aweeki-Gries suggest to carefully design the sequential proofs to simplify the proof procedure • The use of auxiliary variables can make proofs difficult • Can have difficulties with fine-grained concurrency • Benign dataraces • Rely/Guarantee style can allow more elegant/general reasoning (next lesson)