Proofs: Bit vector
These are the human proofs of Bit vector, at full length.
Each bit vector operation keeps the invariant and returns the right result full
This proof shows: correctness.
Setting. Fix the word size and the universe size . Let . For write and , so with and . The map is one-to-one. A position with , is a padding position when ; then , because by the choice of , so for every position satisfies . Write for bit of word .
Invariant for an array and a set :
- (I1) for every : ;
- (I2) for every padding position .
Every position of the array is either the position of exactly one or a padding position, because the positions with are exactly the images of . Hence (I1) and (I2) together say: exactly when .
Lemma (one-bit masks). For and a -bit word : for and otherwise; for and otherwise; .
Proof. The word has its only 1-bit at position , and has its only 0-bit there. OR with 0 and AND with 1 leave a bit unchanged; OR with 1 gives 1 and AND with 0 gives 0. The right shift by moves bit to bit 0, and AND with 1 keeps only bit 0.
NEW. Line L1 makes all words 0. For , (I1) says that every bit of a universe element is 0, and (I2) says the same of the padding: both hold.
INSERT with . Assume (I1) and (I2) for . Line L2 replaces by . By the lemma only position changes, and it becomes 1. That position belongs to and is not a padding position, so (I2) still holds. For the bit of is unchanged and , so (I1) holds for ; for the bit is 1 and . So the invariant holds for .
DELETE with . The same argument with line L3 and the second part of the lemma: only the bit of changes, it becomes 0, and the invariant holds for .
CONTAINS with . By the lemma line L4 returns true exactly when , which by (I1) is . Nothing is written.
COUNT. Loop invariant: before the test of line C2 with index , , where is the number of 1-bits. It holds for with by line C1, and line C3 keeps it. At exit and is the number of 1-bits in the array. By (I1) and (I2) the 1-bits are exactly the positions of the members of , one per member, so .
NEXT with . Let be the least member of with , or NIL if there is none. If (line N2), then and no member is , so NIL is right. Otherwise line N3 sets to with the bits at positions cleared, because has 1-bits exactly at those positions. Loop invariant for lines N4 to N7: is the word whose 1-bits are exactly the positions of word with and , and no member of lies in . Initially and this holds by line N3 and by (I1) and (I2), and is empty since . If , word has no member , so no member lies in ; lines N5 to N7 move to and load the whole word, which is right because every position of word is . If , then no member lies in and NIL is right. When the loop ends with , the lowest 1-bit of is at position , and is the least member by the invariant. The loop stops because increases and is bounded by .
COMPLEMENT. After lines K1 and K2, every bit of the array is inverted. So for the bit of is 1 exactly when , which is (I1) for , and every padding bit is 1. If there are no padding positions, because then . Otherwise the padding positions are the bits of , since . Line K3 ANDs with , which clears exactly these bits and keeps the others, so (I2) holds and (I1) is not affected.
UNION. Both arrays satisfy the invariant over the same , for sets and . Lines K4 and K5 set each bit of to the OR of the bits at the same position. For the new bit is 1 exactly when or , which is (I1) for . A padding bit is the OR of two zeros by (I2), so it stays 0. Intersection and difference are the same argument with AND, and with AND of the complement; a padding bit of is 0 and stays 0.
Conclusion. NEW establishes the invariant, each operation that writes keeps it for the new set, and each operation that reads returns the value the abstract type asks for, given the invariant. By induction on the number of operations, every sequence of operations from NEW returns correct answers.