1 / 28

Loop variant and invariant Part II

Loop variant and invariant Part II. Recitation on OOSC Ohad Barzilay IDC, June 2004. Merge problem. Proving Loop Correctness. The following routine merges two sorted arrays into a new sorted array that contains all their elements

kenny
Download Presentation

Loop variant and invariant Part II

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Loop variant and invariant Part II Recitation on OOSC Ohad Barzilay IDC, June 2004

  2. Merge problem

  3. Proving Loop Correctness • The following routine merges two sorted arrays into a new sorted array that contains all their elements • Assume that this is part of a class with a generic parameter G constrained to inherit from COMPARABLE.

  4. Multisets • A multiset is like a set, except that it can contain multiple equal elements • Formally, a multiset is an unordered collection of elements, some of which may be equal • For example, {a, a, b} and {a, b, a} are equal multisets, but both are different from {a, b}.

  5. Multisets • In a union, all elements are taken, even if equal. • For example, {a, a, b} {b, c} = {a, a, b, b, c}. • As for sets, this operation is commutative and associative.

  6. merge merge (a: ARRAY[G]; b: ARRAY[G]): ARRAY[G] is require a ≠Void; b ≠Void a.lower = 1; b.lower = 1 -- for all i: 1≤i≤a.upper – 1 implies a @ i ≤ a @ (i + 1) -- for all j: 1≤j≤b.upper – 1 implies b @ j ≤ b @ (j + 1) local i, j, k: INTEGER do …

  7. merge (the loop)invariant and variant are missing) !!Result.make(1, a.upper + b.upper) from i := 1; j := 1; k := 1 until i > a.upper and j > b.upper loop if i > a.upper or else (j ≤b.upper and then b @ j ≤a @ i) then Result.put(b @ j, k) j := j + 1 else Result.put(a @ i, k) i := i + 1 end k := k + 1 end

  8. merge (postcondition) ensure -- mset(Result) = mset(a) mset(b) -- for all l: 1 ≤l ≤a.upper + b.upper – 1 implies Result @ l ≤Result @ (l + 1) end • In the first postcondition, the function mset takes an array and returns a mathematical multiset that contains all the elements of the array. • The meaning of the postcondition is therefore that the elements in the array Result are exactly the elements of a and b.

  9. The mission • You should complete the missing loop invariant and variant. • Then use the assertions you added to prove that: • The routine always terminates, that the postconditions of the routine indeed hold • There is no array-out-of-bounds error during the computation.

  10. The mission • Your proof should follow the following steps: (a) the invariant is true at the beginning of the first loop iteration; (b) the invariant is maintained by one pass through the loop body; (c) the postcondition follows from the invariant and the exit condition; (d) the variant is always non-negative; (e) the variant decreases by at least one in every pass through the loop body; and (f) there are no array-out-of-bounds error during the computation.

  11. Merge solution

  12. invariant • 1 ≤i≤a.upper + 1; 1≤j ≤b.upper + 1 • k = i + j – 1 • -- mset(Result[1 .. k – 1]) = mset(a[1 .. i – 1]) mset(b[1 .. j – 1]) • -- for all l: 1≤l≤k – 2 implies Result @ l ≤Result @ (l + 1) • 2≤k≤a.upper + b.upper and 1≤i ≤a.upper implies Result @ (k – 1) ≤a @ i • 2≤k ≤a.upper + b.upper and 1 ≤j ≤b.upper implies Result @ (k – 1) ≤b @ j

  13. variant a.upper + b.upper + 1 – k

  14. Part (a) • The invariant is true at the beginning of the first loop iteration • Line (1) of the invariant follows from the initialization of the variables, the precondition, and the invariant of ARRAY[G] that states that a.upper ≥ a.lower – 1. • Line (2) follows from the initialization. • In line (3) all multisets are empty. • Lines (4–6) are vacuously true.

  15. Part (b) • The invariant is maintained by one pass through the loop body • This is the hardest step – which we would prove last

  16. Part (c) • The postcondition follows from the invariant and the exit condition • By line (1) of the invariant together with the exit condition we know that on exit from the loop: • i = a.upper + 1 • j = b.upper + 1 • k = a.upper + b.upper + 1 • The first line of the postcondition follows immediately from the initialization of the Result array and line (3) of the invariant, and the second line of the postcondition follows from line (4) of the invariant.

  17. Part (d) • The variant is always non-negative • From lines (1–2) of the invariant it follows that k ≤a.upper + b.upper + 1, and therefore the variant is non-negative.

  18. Part (e) • The variant decreases by at least one in every pass through the loop body • The quantity a.upper + b.upper + 1 is constant, and k increases by exactly one in every pass through the loop body. • The variant therefore decreases by exactly one in each pass.

  19. Part (f) • There are no array-out-of-bounds error during the computation • From the invariant we can conclude that inside the loop (except after the last line): 1≤k ≤ a.upper + b.upper • Therefore the assignment to the element of Result at index k is correct. • The indexes i and j are never too low because of line (1) of the invariant.

  20. Part (f) – cont’ • The comparison b @ j ≤a @ i in the if condition is correct because of the preceding conditions, which ensure that i ≤a.upper and j ≤b.upper. • The reference to b @ j in the then part is correct because if i > a.upper then j ≤b.upper (by the exit condition), and otherwise by the second part of the condition. • Because of the if condition, the reference to a @ i in the else part will never happen when i > a.upper, and is therefore also correct.

  21. Part (b) • Denote the values of the variables at the beginning of the pass using primes (') • First note that by the loop exit condition together with line (1) we know that (*) i' + j' ≤a.upper + b.upper + 1 • From this, together with line (2), we get (**) k' ≤a.upper + b.upper.

  22. Part (b) – line (1) • By the inductive hypothesis, 1≤i' ≤a.upper + 1; • inside the loop, i either remains the same or is incremented by one, but only under the condition that i' ≤a.upper. • In any case, at the end of the pass, 1 ≤i ≤a.upper + 1. • The argument for j is identical.

  23. Part (b) – line (2) • k = k' + 1, and either i = i' and j = j' + 1 or i = i' + 1 and j = j'. • The invariant is maintained in both cases.

  24. Part (b) – line (3) • There are two cases. • Case (a): the condition in the if statement was true. • In this case, the element b @ j' has been added to the multiset on the left-hand side, and also to the second multiset on the right-hand side (because j was incremented). • Therefore the equation still holds. • Case (b): the condition was false. • The argument is similar.

  25. Part (b) – line (4) • If k ≤ 2 the assertion is vacuously true. Assume therefore that k > 2, so that k' ≥ 2. • By the induction assumption, the assertion holds for all l between 1 and k' – 2, so we need only prove that Result @ (k' – 1) ≤Result @ k'. • Again there are two cases. • The first case is when the condition in the if statement was true. • In this case, Result @ k' = b @ j', and by line (6) we know that Result @ (k' – 1) ≤b @ j'. • The second case is similar.

  26. Part (b) – line (5a) • Assume that the antecedents of the implication hold. • Again there are two cases. • Case (a): the condition in the if statement was true. In this case, Result @ k' = b @ j', and by the if condition we know that b @ j' ≤ a @ i' • Therefore: Result @ (k – 1) = Result @ k' = b @ j' ≤ a @ i' = a @ i

  27. Part (b) – line (5b) • Case (b): the condition in the if statement was false. • In this case, Result @ k' = a @ i' and i = i' + 1. • By line (1) and the antecedents of the implication we know that i' is between 1 and a.upper – 1, and from the precondition it now follows that: a @ i' ≤a @ (i' + 1) • Therefore: Result @ (k – 1) = Result @ k' = a @ i' ≤ a @ (i' + 1) = a @ i.

  28. Part (b) – line (6) • Similar to line (5), exchanging i and j and the two cases.

More Related