Software Correctness Proofs

70
1 Software Correctness Proofs CIS 376 Bruce R. Maxim UM-Dearborn

description

Software Correctness Proofs. CIS 376 Bruce R. Maxim UM-Dearborn. Formal Analysis. Refers to tool-based methods used to explore, debug, and verify formal specifications Methods Theorem proving Proof checking Model checking Animation and simulation. Formal Proof - part 1. - PowerPoint PPT Presentation

Transcript of Software Correctness Proofs

Page 1: Software Correctness Proofs

1

Software Correctness Proofs

CIS 376

Bruce R. Maxim

UM-Dearborn

Page 2: Software Correctness Proofs

2

Formal Analysis

• Refers to tool-based methods used to explore, debug, and verify formal specifications

• Methods– Theorem proving– Proof checking– Model checking– Animation and simulation

Page 3: Software Correctness Proofs

3

Formal Proof - part 1

• Use deductive reasoning• Proofs are based on a formal system that includes

– set of primitives• finite strings from a fixed alphabet

– set of axioms• specifying the rules of behavior for the primitives

– set of inference rules• allow deduction of additional true statements (known a

theorems) within the system

Page 4: Software Correctness Proofs

4

Formal Proof - part 2

• Deductive system– axioms and inference rules for a formal system

• Theory– axioms and derived theorems in a formal system

• Proof of theorem– sequence of statement transformations that adheres to the

system’s inference rules

• s1, s2, s3, … , sn |- T

– theorem T is provable following the sequence si

Page 5: Software Correctness Proofs

5

Formal System Properties• Consistent

– not possible to derive a statement and its contradiction form the same set of initial statements

• Complete– every true statement is provable

• Decidable– there is an algorithm for determining whether any legal

statement is true

• Note: consistency must be present, completeness and decidability would be nice

Page 6: Software Correctness Proofs

6

Proof Construction

• Forward argument (deductive calculus)– starting with axioms and proven results the inference

rules are used to prove the desired consequent

• Backward argument (test calculus)– starting with the desired result and applying the

inference rules to derive a known result, axiom, or theorem

Page 7: Software Correctness Proofs

7

Program Verification

• Similar to writing a mathematical proof

• You must present a valid argument that is believable to the reader

• The argument must demonstrate using evidence that the algorithm is correct

• Algorithm is correct if code correctly transforms initial state to final state

Page 8: Software Correctness Proofs

8

State of Computation

• Most programming algorithms are based on the notion of transforming the inputs to outputs

• The state of computation may be defined by examining the contents of key variables before and after the execution of each statement

Page 9: Software Correctness Proofs

9

Assertions

• Assertions are facts about the state of the program variables

• It is wasteful to spend your time looking at variables that are not effected by a particular statement

• Default assertion– any variable not mentioned in the assertion for a

statement do not affect the state of computation

Page 10: Software Correctness Proofs

10

Use of Assertions

• Pre-condition– assertion describing the state of computation

before statement is executed

• Post condition– assertion describing the state of computation

after a statement is executed

• Careful use of assertions as program comments can help control side effects

Page 11: Software Correctness Proofs

11

Code Verification Example

• Let’s assume we have an array with a search operation that corresponds to the English specifications below– The procedure searches and array A of length N for a

value X

– If X is found than the value of Y is set to the array index where X was found on exit

– If no array element in A matches X then Y will be set to zero on exit

Page 12: Software Correctness Proofs

12

Example - Formal Specifications

• Pre-condition– N > 0

• Post condition– {X = A[Y] and (1 <= Y <= N)} or– {(Y = 0) and (k : (1 <= k <= N) A[k] <> X)}

• Proof would need to show that algorithm transformed state of computation from pre-condition to the post condition

Page 13: Software Correctness Proofs

13

Page 14: Software Correctness Proofs

14

Page 15: Software Correctness Proofs

15

Simple Algorithm

• Model {P} A {Q}– P = pre-condition– A = Algorithm– Q = post condition

• Sum algorithm{pre: x = x0 and y = y0}z = x + y

{post: z = x0 + y0}

Page 16: Software Correctness Proofs

16

Sequence Algorithm

• Model if {P} A1 {Q1} and {Q1} A2 {Q}

then {P} A1 ; A2 {Q} is true

• Swap algorithm{pre: x = x0 and y = y0}

temp = x

x = y

y = temp

{post: temp = x0 and x = y0 and y = x0}

Page 17: Software Correctness Proofs

17

Intermediate Assertions

• Swap algorithm{pre: x = x0 and y = y0}temp = x

{temp = x0 and x = x0 and y = y0}x = y

{temp = x0 and x = y0 and y = y0}y = temp

{post: temp = x0 and x = y0 and y = x0}

Page 18: Software Correctness Proofs

18

Conditional Statements

• Absolute value{pre: x = x0}

if x < 0 then

y = - x

else

y = x

{post: y = | x0 |}

Page 19: Software Correctness Proofs

19

Intermediate Assertions

if x < 0 then

{x = x0 and x0< 0}

y = - x

{y = | x0 |}

else

{x = x0 and x0>= 0}

y = x

{y = | x0 |}

Page 20: Software Correctness Proofs

20

Understanding the While Loop• Every well designed while loop must

– make progress to ensure eventual termination

– must maintain the loop invariant to ensure that it is valid at each loop exit point

//invariant holds here

while (condition) do

//invariant holds here

make_progress

restore_invariant

//invariant and not(condition) hold here

Page 21: Software Correctness Proofs

21

Loop Invariant

• Type of assertion that describes the variables which remain unchanged during the execution of a loop

• In general the stopping condition should remain unchanged during the execution of the loop

• Some people show the loop invariant as a statement which becomes false when loop execution is complete

Page 22: Software Correctness Proofs

22

Loop Invariant Example

k = 0;

//invariant: A[1], … , A[k] equal 0

//assert: N >= 0

while k < N do

k = k +1; //make progress

A[k] = 0; //restore invariant

//assert: A[1], … , A[k] equal 0 and k >= N

Note: say k=N will require an induction argument

Page 23: Software Correctness Proofs

23

While Loop Example

• Algorithmwhile y <> 0 do

z = z + x

y = y – 1

ans = z

• What does it do?

Page 24: Software Correctness Proofs

24

While Loop Assertions

{pre: x = x0 and z = z0 and y = y0 and y0 >= 0}while y <> 0 dobegin

{0 < n <= y0 and z’ = z0 + n * x0} z = z + x y = y – 1end

{y = 0 and z’ = z0 + y0 * x0}ans = z

{post: ans = z0 + y0 * x0}

Page 25: Software Correctness Proofs

25

Proof -1

• If y = 0 loop does not execute and no variables change soz = z + 0 * x = ans

• If we assume that for n = k if program begins loop with y = k it will exit withans = z + k * x

Page 26: Software Correctness Proofs

26

Proof - 2

• We must prove that when program begins loop with y = k + 1 it will exit loop withans = z + (k + 1) * x

• Suppose y = k + 1 at top of loop and the body of the loop executes one timex = x ‘ = xy = y’ = (k + 1) – 1 = kz = z’ = z + x

Page 27: Software Correctness Proofs

27

Proof - 3

• Since we are at the top of the loop with y = k, we can use our induction hypothesis to getans = z’ + k * x’

• Substituting we getans = (z + x) + k * x

= z + (x + k * x)

= z + (1 + k) * x

= z + (k + 1) * x

Page 28: Software Correctness Proofs

28

Second While Loop ExampleProd = 0

I = 0

{X and N are initialized and Prod = I * X and I <= N}

while (I < N) do

begin

{Prod = I * X and I < N}

Prod = Prod + X

{Prod = (I + 1) * X and I < N}

I = I + 1

{Prod = I * X and I <= N}

end

{loop exited with Prod = I * X and I >= N}

{Prod = N * X}

Page 29: Software Correctness Proofs

29

Proof - 1

• Check I = 0Verify that invariant is true

Prod = 0

Prod = 0 * X = 0

If N = 0 condition is false and loop terminates

If N > 0 condition is true and loop execution continues

Page 30: Software Correctness Proofs

30

Proof - 2• Assume correctness of the invariant at the top

of the loop when I = KProd = K * XIf K < N condition is true and the loop execution

continuesIf K = N condition is false and loop terminatesSo post condition is true

• So we are assuming thatX0 + X0 + X0 + … + X0 + X0 = K * X0 = Prod

k times

Page 31: Software Correctness Proofs

31

Proof - 3• If we are at the top of the loop and execution

continues the body adds X0 to both sides

• Using our induction hypothesis we get(X0 + X0 + X0 + … + X0 + X0) + X0 = K * X0 + X0

k times

• Which gives usX0 + X0 + X0 + … + X0 + X0 + X0 = K * X0 + X0

k + 1 times

• Which can be written asX0 + X0 + X0 + … + X0 + X0 + X0 = (K + 1) *X0 = Prod

Page 32: Software Correctness Proofs

32

Proof - 4

• Since assuming the invariant is true for K we showed that it held for K + 1

• If the loop condition is true execution continues

• otherwise is halts withI = N + 1

Prod = X0 * N

Page 33: Software Correctness Proofs

33

Counting Loop Example

• This loop stores the sum of the first I array elements in position C[I]

{pre: max >= M >= 1 and C initialized}

for I = 1 to M

C[I] = C[I] + C[I – 1]

{post: I = M + 1 and

for each J = 1 to I – 1 : C’[J] = C[0] + … + C[J]}

Page 34: Software Correctness Proofs

34

Proof - 1

• Show for the case M = 1 that the program will exit with C[1] = C[1] + C[0] and C’[0] = C[0]

• If M = 1 loop executes with I = 1 and C’[1] = C[0] + C[1]

• Loop is satisfied and result isI = 2 and C[1] = C[1] + C[0] and C[0] = C[0]

• This gives us our intended result

Page 35: Software Correctness Proofs

35

Proof - 2

• For our induction hypothesis we assumeif loop reaches top with M = K the loop exits

C’[K] = C[0] + … + C[K]

C’[1] = C[0] + C[1]

C’[0] = C[0]

Page 36: Software Correctness Proofs

36

Proof - 3

• We need to show that if loop reaches the top with M = K + 1 the loop ends withC’[K + 1] = C[0] + … + C[K + 1]

C’[K] = C[0] + … + C[K]

C’[1] = C[0] + C[1]

C’[0] = C[0]

Page 37: Software Correctness Proofs

37

Proof - 4

• C’[K + 1] = C[K + 1] + C[(K + 1) - 1]

• C’[K + 1] = C[K + 1] + C[K]

• By our induction hypothesis C[K] now contains C’[K] soC’[K + 1] = C[K + 1] + C’[K]

C’[K + 1] = C[K + 1] + C[K] + … + C[0]

Page 38: Software Correctness Proofs

38

Proof - 5

• Loop condition is satisfied andI = (K + 1) + 1 = K + 2

• The array should now containC’[K + 1] = C[0] + … + C[K + 1]C’[K] = C[0] + … + C[K]…C’[1] = C[0] + C[1]C’[0] = C[0]

Page 39: Software Correctness Proofs

39

These proof examples were posted on the World Wide Web by

Ken Abernathy

Furman University

Page 40: Software Correctness Proofs

40

Proof Technique Sequent Calculus

• One type of deductive calculus • A sequent is written |- , which means /\

implies \/ , where is a (possibly empty) list of formulas {A1, …, An} and is a (possibly empty) list of formulas {B1, …, Bn}

– the formulas in are called the antecedents– the formulas in are called the consequents

• To restate, |- meansA1 /\ … /\ An implies B1 \/ … \/ Bn

Page 41: Software Correctness Proofs

41

Sequent Calculus• A sequent calculus proof is a tree of sequents whose root

is a sequent of the form |- T where T is the formula to be proved and the antecedent is empty

• The proof tree is then generated by applying inference rules of the form:

1 |- 1 … n |- n

|- • Intuitively, this rule replaces a leaf node in the proof tree

of form |- with the n new leaves specified in the rule. If n is zero, that branch of the proof tree terminates.

Rule N

Page 42: Software Correctness Proofs

42

Sequent Calculus - Example Rule 1

• The Propositional Axiom (Prop_Axiom) is one of the rules of inference in sequent calculus. It has the following form form:

, A |- (A,

• Intuitively, this rule indicates that a proof branch is complete when the sequent above is derived. Note that the consequent means the following:

/\ A implies A \/ which is obviously true.

Prop_Axiom

Page 43: Software Correctness Proofs

43

Sequent Calculus - Example Rule 2

• The Rule for Conjunction on the Right (And_Right) is another of the rules of inference in the sequent calculus. It has the following form:

|- A, |- B,

|- (A /\ B, • This rule is typical of many sequent calculus inference

rules which divide, but simplify, a branch of the proof tree. Note that the consequent is replaced by two simpler formulas which will be easier for a mechanized theorem prover to deal with.

And_Right

Page 44: Software Correctness Proofs

44

Sequent Calculus - Example Rule 3

• The Rule for Conjunction on the Left (And_Left) is another of the rules of inference in the sequent calculus. It has the following simple (non-branching) form:

A, B, |-

(A /\ B, |-

• This rule is typical of several sequent calculus inference rules which simply restate the “obvious,” thereby providing a form easier for a mechanized theorem prover to deal with.

And_Left

Page 45: Software Correctness Proofs

45

Sequent Calculus - Example Rule 4

• The Rule for Implication on the Left (Implies_Left) is another of the rules of inference in the sequent calculus. It has the following form:

|- A, B, |-

(A => B, |-

• Similar to the And_Right rule, this rule again splits the proof into two cases, each of which will be easier for the mechanical prover to deal with.

Implies_Left

Page 46: Software Correctness Proofs

46

Sequent Calculus - Example Rule 5

• The Rule for Implication on the Right (Implies_Right) is another of the rules of inference in the sequent calculus. It has the following form:

A |- B,

|- (A => B,

• This rule does not branch, but provides a form easier for a mechanized theorem prover to deal with.

Implies_Right

Page 47: Software Correctness Proofs

47

Sequent Calculus Proof Example

Theorem 1: (P => (Q => R)) => ((P /\ Q) => R)

We begin the proof by forming the requisite sequent:

Antecedents: none

Consequents:

Formula 1: (P => (Q => R)) => ((P /\ Q) => R)

Page 48: Software Correctness Proofs

48

Proof Example - Step 1

As our first step we apply the rule Implies_Right. This rule will decompose the entire formula. Remember there is an implied “implies” in the sequent. In other words this sequent could be written

|- (P => (Q => R)) => ((P /\ Q) => R).

Antecedents: Formula 1: P => (Q => R)

Consequents:Formula 1: (P /\ Q) => R

Page 49: Software Correctness Proofs

49

Proof Example Step 2

A second application of the rule Implies_Right will decompose the formula below the line in a similar way. Remember that rules applying to the “left” part of the sequent work on formulas above the bar; rules applying to the “right” part of the sequent work below the bar.

Antecedents: Formula 1: P => (Q => R)Formula 2: P /\ Q

Consequents:Formula 1: R

Page 50: Software Correctness Proofs

50

Proof Example Step 3

We next apply the rule And_Left -- this rule will modify (rewrite) Formula 2 above the line. Remember that all formulas above the line are connected by AND’s; formulas below the line are connected by OR’s.

Antecedents: Formula 1: P => (Q => R)Formula 2: P Formula 3: Q

Consequents:Formula 1: R

Page 51: Software Correctness Proofs

51

Proof Example Step 4

We next apply the rule Implies_Left -- this rule will modify Formula 1 above the line. Remember that Implies_Left splits the proof tree into two branches. We show and deal with Case 1 first, then move to Case 2 later.

Case 1:Antecedents:

Formula 1: Q => RFormula 2: P Formula 3: Q

Consequents:Formula 1: R

Page 52: Software Correctness Proofs

52

Proof Example Step 5

To modify Formula 1 above the line, we next apply the rule Implies_Left again. Again this splits the proof tree into two branches. We show and deal with Case 1.1 first, then move to Case 1.2 later.

Case 1.1:Antecedents:

Formula 1: RFormula 2: P Formula 3: Q

Consequents:Formula 1: R

Case 1.1 will now yield to an application of Prop_Axiom

Page 53: Software Correctness Proofs

53

Proof Example Steps 5 & 6

As noted, an application of Prop_Axiom (Step 5) completes Case 1.1. We now move to Case 1.2. This is the second case resulting from the application of Implies_Left on the Case 1 sequent. Another application of Prop_Axiom (Step 6) completes Case 1.2 (and in turn Case 1 itself).

Case 1.2:Antecedents:

Formula 1: PFormula 2: Q

Consequents:Formula 1: QFormula 2: R

Case 1.2 will also yield to an application of Prop_Axiom

Page 54: Software Correctness Proofs

54

Proof Example Step 7Having completed the proof for Case 1, we now move to Case 2. Recall that this is the second case resulting from our first application of Implies_Left. Another application of Prop_Axiom (Step 7) completes Case 2 (and in turn the entire proof).

Case 2:Antecedents:

Formula 1: PFormula 2: Q

Consequents:Formula 1: PFormula 2: R

Case 2 will also yield to an application of Prop_Axiom

Page 55: Software Correctness Proofs

55

Mechanical Theorem Provers

• Many mechanical theorem provers require human interaction

• Users typically are required to choose the rule of inference to be applied at each step

• The theorem prover may be able to discover (by heuristic search) some rules to apply on its own

• The user needs to translate the statements to some normal form prior to beginning

Page 56: Software Correctness Proofs

56

Proving Algorithm Correctness

• Suppose you have a software component that accepts as input an array T of size N

• As output the component produces an T` which contains the elements of T arranged in ascending order

• How would we convert the code to its logical counterpart and prove its correctness?

Page 57: Software Correctness Proofs

57

Bubble Sort AlgorithmT` = T

more = true

lab1: i = 0

if (more ~= true) then go to end

not(more) = true

//** assertion needed

lab2: i = i + 1

if i >= N then go to lab1

if T`(i) < T`(i+1) then go to lab2

//* assertion needed

exchange T`(i) with T`(i+1) more = true

go to lab2

Page 58: Software Correctness Proofs

58

Step 1• Write assertions to describe the components input

and output conditions• input assertion

A1: (T is an array) & (T is of size N)

• output assertion

Aend: (T` is an array) &

( i if i < N then (T`(i) <= T`(i+1)) &

( i if i < N then j(T`(i) = T(j)) &

(T` is of size N)

Page 59: Software Correctness Proofs

59

Step 2• Draw a flow diagram to represent the logical flow

through the component • Indicate points where data transformations will

occur and write assertions• Ex. Assuming a bubble sort is used two assertions

might be– [(not(more) = true)) & (i < N) & T`(i) > T`(i+1))]

[T`(i) is exchanged with T`(i+1)] //*

– [(not(more) = true)) & (I >= N)] [T`(i) sorted] //**

Page 60: Software Correctness Proofs

60

Step 3

• From the assertions a we generate a series of theorems to be proved

• If your first assertion is A1 and the first transformation point has assertion A2 associated with it the theorem to be proved is

A1 A2

• Once the list of theorems is established each must be proved individually (order does not matter)

Page 61: Software Correctness Proofs

61

Steps 4 and 5

• We need to locate each loop in the flow diagram and write an if-then assertion for each loop condition

• To prove correctness, each logic path beginning with A1 and ending with Aend Following each of these paths allows us to demonstrate that the code shows that the truth of the input condition will lead to the truth of the output condition

Page 62: Software Correctness Proofs

62

Steps 6 & 7

• After identifying each logic paths the truth of each path is proved rigorously (showing the the input assertion implies the output assertion according to the logic transformations found on that path)

• Finally you need to prove the program terminates (which may mean an induction argument if loops are involved)

Page 63: Software Correctness Proofs

63

Cost of Correctness Proofs - part 1

• Advantages– You can discover algorithmic faults in the code

– Gives you a formal understanding of the logical structures of the program

– Regular use of proofs forces you to be more precise in specifying data, data structures and algorithmic rules

• Disadvantages– Code is often smaller size than its proof

– It may take less effort to create code than to prove its correctness

Page 64: Software Correctness Proofs

64

Cost of Correctness Proofs - part 2

• Disadvantages (continued)– Large programs require complex diagrams and contain

many transformations to prove

– Nonnumeric algorithms are hard to represent logically

– Parallel processing is hard to represent

– Complex data structures require complex transformations

– Mathematical proofs have occasionally been found to be incorrect after years of use

Page 65: Software Correctness Proofs

65

Symbolic Execution• Involves simulated execution of the program code using

symbols rather than data variables

• The test program is viewed as having an input state defined by the input data and preconditions

• As each line of code is executed the program statement is checked for state changes

• Each logical path in the program corresponds to an ordered sequence of state changes

• The final state of each path must be a proper output state

• A program is correct if each input state generates the appropriate output state

Page 66: Software Correctness Proofs

66

Symbolic Execution Example

• Consider the following lines of code

a = b + c;

if (a > d)

call_task1( );

else

call_task2( );

Page 67: Software Correctness Proofs

67

Symbolic Execution Steps

• A symbolic execution tool would decide that (a>d) can be true or false, without worrying about the values assigned to a and d

• This gives us two states– (a > d) is false

– (a > d) is true

• All data values are presumed to fall into one of the equivalence classes defined by the two states (so only a small number of test cases need be considered in a proof)

• This technique has many of the same costs and disadvantages of using logical correctness proofs

Page 68: Software Correctness Proofs

68

Structural Induction

• Induction can be used to show loop termination and correctness of list processing algorithms

• To show the f(list) is true for every list you must prove that– f(list) is true for an empty list //the base case

– whenever f(list`) is true, so is f(x :: list) in other words adding an element to the list preserves truth no matter how the list is //induction step

– f([x1, … ,xn]) is true after n steps

Page 69: Software Correctness Proofs

69

Generalizing Induction

• Suppose you want to show that k addlen(k. list) = k + nlength(list)

• Give the following definitionsnlength([ ]) = 0

nlength(x :: xs) = 1 + nlength(xs)

addlen(k, [ ]) = k

addlen(k, x::xs) = addlen(k + 1, xs)

Page 70: Software Correctness Proofs

70

Induction Correctness Proof

k addlen(k. list) = k + nlength(list)• Base case:

addlen(k, [ ]) = k

= k + 0

= k + nlength([ ])

• Induction step - assume that

addlen(k, x::list`) = addlen(k + 1, list`)

= k + 1 + nlength(list`) //IHOP

= k + nlength(x :: list`) // must prove