0
procedure bit count(S: bit string)
count := 0
      while S != 0
          count := count + 1
          S := S ∧ (S − 1)
return count {count is the number of 1s in S}

Here S-1 is the bit string obtained by changing the rightmost 1 bit of S to a 0 and all the 0 bits to right of this to 1s.

So I understand why this is correct, and I have write a rough explanation;

After every iteration, the rightmost 1 bit in S, as well as all the bits to the right of it, is set equal to 0. Thus, after each iteration, the next right-most 1 is accounted for and set to 0, until the entire string is 0's and the loop breaks with the count equal to the number of 1's.

I know this kind of answer won't pass in any mathematics community, so I was hoping to write a formal proof, but I don't know how to go about doing that. My proof skills are particularly shoddy, so an explanation of the techniques involved would be greatly appreciated.

2 Answers2

1

A proof using induction could be something like the follows:

Claim: in the beginning of the nth iteration of the algorithm, you have seen (flipped) n-1 1 (set) bits and count == n-1.

Proof:
Base: Trivial for n==1, in the first iteration - you haven't seen any set bit yet, and count is set to 0..
Hypothesis: The claim is true for each k<n (for some n).
Proof for n: The nth iteration is followed by the n-1 iteration. In the n-1 iteration, from the inductive hypothesis you have seen n-1 bits and count == n-1.
Since you reached the n iteration, the n-1 iteration ended successfully - thus the end condition was not met, so there was a flipped bit. You also increased count by one, thus in the nth step you flipped n bits and count == n.

From the above we can conclude that when the algorithm ends, count == #flipped_bits.

QED


Note that the above is a Partial correctness - it proves that if the algorithm terminates - it yields a correct answer, but it does NOT guarantee termination.
Guaranteeing termination can be done by showing that there are at most |S| steps, since you can flip the rightest bit at most |S| times until you get S = 0. (Termination + Partial correctness is called Complete Correctness)


If you are interested in proving algorithms you might be interested in Hoare Logic, which gives a formal tools how to verify a program is correct. This field of studies is known as Software Verification.

amit
  • 175,853
  • 27
  • 231
  • 333
0

First of all, it's not correct. You want while S != 0, not while S = 0.

As for proof, I'd use an inductive proof: prove that it works correctly if no bit is set, then prove that if there is at least one bit set, that it increments the count, reduces the number of bits that are set by one, and repeats.

In the inductive step, the only difficult part is showing that after S := S ∧ (S − 1), that the number of bits set in S will be reduced by exactly 1. The main part of that is that for any number N of the form 10..0, that N-1 has the form 01..1 -- that's the basic nature of binary counting. I'd probably do it in reverse though -- show that for any number : 01..1, that the next successive number is 10..0, which basically comes down to: "1+1 -> 0 + carry`.

Jerry Coffin
  • 476,176
  • 80
  • 629
  • 1,111