the calculus of computation decision procedures with 5
play

The Calculus of Computation: Decision Procedures with 5. Program - PowerPoint PPT Presentation

The Calculus of Computation: Decision Procedures with 5. Program Correctness: Mechanics Applications to Verification by Aaron Bradley Zohar Manna Springer 2007 5- 1 5- 2 Program A: LinearSearch with function specification Function


  1. The Calculus of Computation: Decision Procedures with 5. Program Correctness: Mechanics Applications to Verification by Aaron Bradley Zohar Manna Springer 2007 5- 1 5- 2 Program A: LinearSearch with function specification Function LinearSearch searches subarray of array a of integers for specified value e . @pre 0 ≤ ℓ ∧ u < | a | Function specifications @post rv ↔ ∃ i . ℓ ≤ i ≤ u ∧ a [ i ] = e ◮ Function postcondition (@ post ) bool LinearSearch( int [] a , int ℓ, int u , int e ) { It returns true iff a contains the value e in the range [ ℓ, u ] for @ ⊤ ◮ Function precondition (@ pre ) ( int i := ℓ ; i ≤ u ; i := i + 1) { It behaves correctly only if 0 ≤ ℓ and u < | a | if ( a [ i ] = e ) return true ; } for loop: initially set i to be ℓ , return false ; execute the body and increment i by 1 } as long as i ≤ n @ - program annotation 5- 3 5- 4

  2. Program B: BinarySearch with function specification The recursive function BinarySearch searches subarray of sorted array a of integers for specified value e . @pre 0 ≤ ℓ ∧ u < | a | ∧ sorted( a , ℓ, u ) sorted: weakly increasing order, i.e. @post rv ↔ ∃ i . ℓ ≤ i ≤ u ∧ a [ i ] = e sorted( a , ℓ, u ) ⇔ ∀ i , j . ℓ ≤ i ≤ j ≤ u → a [ i ] ≤ a [ j ] bool BinarySearch( int [] a , int ℓ, int u , int e ) { if ( ℓ > u ) return false ; Defined in the combined theory of integers and arrays, T Z ∪ A else { int m := ( ℓ + u ) div 2; Function specifications if ( a [ m ] = e ) return true ; ◮ Function postcondition (@ post ) else if ( a [ m ] < e ) return BinarySearch( a , m + 1 , u , e ); It returns true iff a contains the value e in the range [ ℓ, u ] else return BinarySearch( a , ℓ, m − 1 , e ); } ◮ Function precondition (@ pre ) } It behaves correctly only if 0 ≤ ℓ and u < | a | 5- 5 5- 6 Program C: BubbleSort with function specification Function BubbleSort sorts integer array a a: unsorted sorted @pre ⊤ @post sorted( rv , 0 , | rv | − 1) largest int [] BubbleSort( int [] a 0 ) { int [] a := a 0 ; by “bubbling” the largest element of the left unsorted region of a for @ ⊤ toward the sorted region on the right. ( int i := | a | − 1; i > 0; i := i − 1) { for @ ⊤ Each iteration of the outer loop expands the sorted region by one ( int j := 0; j < i ; j := j + 1) { cell. if ( a [ j ] > a [ j + 1]) { int t := a [ j ]; a [ j ] := a [ j + 1]; a [ j + 1] := t ; } } } return a ; } 5- 7 5- 8

  3. Sample execution of BubbleSort Program Annotation ◮ Function Specifications 2 3 4 1 2 5 6 function postcondition (@ post ) j i function precondition (@ pre ) 2 3 4 1 2 5 6 j i ◮ Runtime Assertions e.g., @ 0 ≤ j < | a | ∧ 0 ≤ j + 1 < | a | 2 3 4 1 2 5 6 a [ j ] := a [ j + 1] j i ◮ Loop Invariants 2 3 1 4 2 5 6 e.g., @ L : ℓ ≤ i ∧ ∀ j . ℓ ≤ j < i → a [ j ] � = e j i 2 3 1 2 4 5 6 j , i 2 3 1 2 4 5 6 j i 5- 9 5- 10 Program A: LinearSearch with runtime assertions Program B: BinarySearch with runtime assertions @pre ⊤ @pre ⊤ @post ⊤ @post ⊤ bool BinarySearch( int [] a , int ℓ, int u , int e ) { bool LinearSearch( int [] a , int ℓ, int u , int e ) { if ( ℓ > u ) return false ; for @ ⊤ else { ( int i := ℓ ; i ≤ u ; i := i + 1) { @ 2 � = 0; @ 0 ≤ i < | a | ; int m := ( ℓ + u ) div 2; if ( a [ i ] = e ) return true ; @ 0 ≤ m < | a | ; } if ( a [ m ] = e ) return true ; return false ; else { } @ 0 ≤ m < | a | ; if ( a [ m ] < e ) return BinarySearch( a , m + 1 , u , e ); else return BinarySearch( a , ℓ, m − 1 , e ); } } } 5- 11 5- 12

  4. Program C: BubbleSort with runtime assertions Loop Invariants while @pre ⊤ @ F @post ⊤ � cond � { � body � } int [] BubbleSort( int [] a 0 ) { int [] a := a 0 ; ◮ apply � body � as long as � cond � holds for @ ⊤ ◮ assertion F holds at the beginning of every iteration ( int i := | a | − 1; i > 0; i := i − 1) { for @ ⊤ evaluated before � cond � is checked ( int j := 0; j < i ; j := j + 1) { @ 0 ≤ j < | a | ∧ 0 ≤ j + 1 < | a | ; for if ( a [ j ] > a [ j + 1]) { @ F int t := a [ j ]; ( � init � ; � cond � ; � incr � ) { � body � } a [ j ] := a [ j + 1]; a [ j + 1] := t ; ⇒ } } � init � ; } while return a ; @ F } � cond � { � body � � incr � } 5- 13 5- 14 Proving Partial Correctness Program A: LinearSearch with loop invariants A function is partially correct if when the function’s precondition is satisfied on entry, @pre 0 ≤ ℓ ∧ u < | a | its postcondition is satisfied when the function halts. @post rv ↔ ∃ i . ℓ ≤ i ≤ u ∧ a [ i ] = e bool LinearSearch( int [] a , int ℓ, int u , int e ) { for ◮ A function + annotation is reduced to finite set of @ L : ℓ ≤ i ∧ ( ∀ j . ℓ ≤ j < i → a [ j ] � = e ) verification conditions (VCs), FOL formulae ( int i := ℓ ; i ≤ u ; i := i + 1) { ◮ If all VCs are valid, then the function obeys its specification if ( a [ i ] = e ) return true ; (partially correct) } return false ; } 5- 15 5- 16

  5. Program A: LinearSearch Basic Paths: Loops To handle loops, we break the function into basic paths Basic Paths of LinearSearch (1) @ ← precondition or loop invariant @pre 0 ≤ ℓ ∧ u < | a | i := ℓ ; sequence of instructions @ L : ℓ ≤ i ∧ ∀ j . ℓ ≤ j < i → a [ j ] � = e (with no loop invariants) (2) @ ← loop invariant, assertion, or postcondition @ L : ℓ ≤ i ∧ ∀ j . ℓ ≤ j < i → a [ j ] � = e assume i ≤ u ; assume a [ i ] = e ; rv := true ; @post rv ↔ ∃ j . ℓ ≤ j ≤ u ∧ a [ j ] = e 5- 17 5- 18 (3) Visualization of basic paths of LinearSearch @ L : ℓ ≤ i ∧ ∀ j . ℓ ≤ j < i → a [ j ] � = e assume i ≤ u ; @pre assume a [ i ] � = e ; (1) i := i + 1; (3) L @ L : ℓ ≤ i ∧ ∀ j . ℓ ≤ j < i → a [ j ] � = e (2) , (4) (4) @post @ L : ℓ ≤ i ∧ ∀ j . ℓ ≤ j < i → a [ j ] � = e assume i > u ; rv := false ; @post rv ↔ ∃ j . ℓ ≤ j ≤ u ∧ a [ j ] = e 5- 19 5- 20

  6. Program C: BubbleSort with loop invariants for   1 ≤ i < | a | ∧ 0 ≤ j ≤ i @pre ⊤ ∧ partitioned( a , 0 , i , i + 1 , | a | − 1) @post sorted( rv , 0 , | rv | − 1)   @ L 2 :   ∧ partitioned( a , 0 , j − 1 , j , j ) int [] BubbleSort( int [] a 0 ) {   ∧ sorted( a , i , | a | − 1) int [] a := a 0 ; ( int j := 0; j < i ; j := j + 1) { for if ( a [ j ] > a [ j + 1]) {   − 1 ≤ i < | a | int t := a [ j ]; @ L 1 : ∧ partitioned( a , 0 , i , i + 1 , | a | − 1)   a [ j ] := a [ j + 1]; ∧ sorted( a , i , | a | − 1) a [ j + 1] := t ; ( int i := | a | − 1; i > 0; i := i − 1) { } } } return a ; } 5- 21 5- 22 Partition (2) @ L 1 : − 1 ≤ i < | a | ∧ partitioned( a , 0 , i , i + 1 , | a | − 1) ∧ sorted( a , i , | a | − 1) partitioned( a , ℓ 1 , u 1 , ℓ 2 , u 2 ) assume i > 0; ⇔ ∀ i , j . ℓ 1 ≤ i ≤ u 1 < ℓ 2 ≤ j ≤ u 2 → a [ i ] ≤ a [ j ] j := 0; in T Z ∪ T A . � 1 ≤ i < | a | ∧ 0 ≤ j ≤ i ∧ partitioned( a , 0 , i , i + 1 , | a | − 1) � @ L 2 : That is, each element of a in the range [ ℓ 1 , u 1 ] is ≤ each element ∧ partitioned( a , 0 , j − 1 , j , j ) ∧ sorted( a , i , | a | − 1) in the range [ ℓ 2 , u 2 ]. (3) Basic Paths of BubbleSort � 1 ≤ i < | a | ∧ 0 ≤ j ≤ i ∧ partitioned( a , 0 , i , i + 1 , | a | − 1) � @ L 2 : (1) ∧ partitioned( a , 0 , j − 1 , j , j ) ∧ sorted( a , i , | a | − 1) @pre ⊤ ; assume j < i ; assume a [ j ] > a [ j + 1]; a := a 0 ; t := a [ j ]; i := | a | − 1; a [ j ] := a [ j + 1]; @ L 1 : − 1 ≤ i < | a | ∧ partitioned( a , 0 , i , i + 1 , | a | − 1) a [ j + 1] := t ; ∧ sorted( a , i , | a | − 1) j := j + 1; � 1 ≤ i < | a | ∧ 0 ≤ j ≤ i ∧ partitioned( a , 0 , i , i + 1 , | a | − 1) � @ L 2 : ∧ partitioned( a , 0 , j − 1 , j , j ) ∧ sorted( a , i , | a | − 1) 5- 23 5- 24

Download Presentation
Download Policy: The content available on the website is offered to you 'AS IS' for your personal information and use only. It cannot be commercialized, licensed, or distributed on other websites without prior consent from the author. To download a presentation, simply click this link. If you encounter any difficulties during the download process, it's possible that the publisher has removed the file from their server.

Recommend


More recommend