1. In a lecture we solved the Find a Majority problem. Recall that the majority of a bag B is defined to be a value whose multiplicity (i.e., # of occurrences) in B is greater than |B|/2, where |B| is the cardinality (i.e., size) of B. Obviously, a bag has at most one majority. For example, the bag U = {| 5, 3, 5, 5, 2, 5, 5 |} has 5 as its majority, whereas the bag V = {| 5, 3, 4, 5, 5, 2, 1 |} has no majority.
The concept of majority is easily generalized to p-majority, for p>1. We define a value x to be a p-majority of a bag B if the number of occurrences of x in B is greater than |B|/p. (Thus, what we called a majority above corresponds to a 2-majority under this generalized definition.)
Clearly, a bag has at most p−1 p-majorities. For example, the bag W = {| 2, 2, 2, 7, 7, 7, 5, 0 |} has both 2 and 7 as 3-majorities. The bags U and V from above have 5 alone as a 3-majority, and the bag X = {| 0, 0, 1, 2, 5, 7 |} has no 3-majority.
For this problem, you are to develop a program that, given as input a bag B represented by the constant array B[], establishes variables r0 and r1 so that, if x is a 3-majority of B, either x = r0 or x = r1. (Hence, if B has two 3-majorities, r0 must be one of them and r1 the other. If, on the other hand, B has only one 3-majority, it must be equal to one among r0 and r1.) Here is the program, partially completed:
|[con N : nat; con B : array[0..N) of T; var r0, r1 : T; var m0, m1 : int; var k : int; r0, m0, r1, m1, k := null, 0, null, 0, 0; { loop invariant I: {(r0,m0), (r1,m1)} ∈ Red3.Bk) ∧ 0≤k≤N } { bound function t: N-k} do k ≠ N → r0, m0, r1, m1 := ?,?,?,? ;k := k+1 od {Q': {(r0,m0),(r1,m1)} ∈ Red3.Bk ∧ k=N} {Q: {(r0,m0),(r1,m1)} ∈ Red3.BN} ]| |
Regarding notation used above:
C := A; do while there exist three disinct values that are members of C remove from C one copy of each of three distinct values; od; { C ∈ Red3.A } |
where s and t are of type T (the type of values in bag B), s ≠ t, and m and n are natural numbers. This expression denotes the bag containing m occurrences of s, n occurrences of t, and no other members. In the case m = 0 (respectively, n = 0), the value of s (respectively, t) is irrelevant.
Although it is not directly relevant to your task, the following theorem (which is a generalization of the one presented in class) assures us that the ending values of program variables r0 and r1 identify the only possible 3-majorities of B.
Theorem: If x is a 3-majority of A and C is a member of Red3.A, then x is also a 3-majority of C.
Similar to what we encountered in the lecture, the key to finishing the program is understanding how to transform a bag that is a member of Red3.Bk (obtained by "reducing" the bag whose elements are those in B[0..k)) to a bag that is a member of Red3.Bk+1 (obtained by "reducing" the bag whose elements are those in B[0..k+1)).
For the sake of convenience, you may assume that the value (non-value?) null (to which r0 and r1 are initialized) does not occur in the array B[]. This relieves you from having to worry about whether or not r0 and r1 have "well-defined" values.
2. Prove the correctness of the following program segment, which swaps two adjacent array elements, if necessary, to ensure that the elements in a particular segment of length three are not in increasing order.
{P ∧ 1≤n<#b-1} if b.(n-1) < b.n ∧ b.n < b.(n+1) ---> swap(b,n,n+1) [] ¬(b.(n-1) < b.n ∧ b.n < b.(n+1)) ---> skip fi ;n := n+1 {P}where P: (∀i | 1≤i<n : b[i-1] ≥ b[i] ∨ (i < #b-1 ⟹ b[i] ≥ b[i+1])) |
The command swap(b,i,j) is, in effect, the assignment b := b(i,j : b.j,b.i) and therefore (in accord with the wp assignment law) has the following semantics:
where (provided that i=j implies E=F)
b(i,j : E,F).k = { | E | if i=k |
F | if j=k | |
b.k | otherwise |
To make your proof more readable, you should introduce the shorthand b' as a name for b(n,n+1 : b.(n+1),b.n).