vstd_extra/external/
bits.rs1use crate::bits::u64_bit_is_set;
3use vstd::prelude::*;
4
5verus! {
6
7spec fn u64_set_bits_rec(w: u64, n: u64) -> int
9 decreases n,
10{
11 if n == 0 {
12 0
13 } else {
14 (if u64_bit_is_set(w, n - 1) {
15 1int
16 } else {
17 0int
18 }) + u64_set_bits_rec(w, (n - 1) as u64)
19 }
20}
21
22pub closed spec fn u64_set_bits(w: u64) -> int {
24 u64_set_bits_rec(w, 64)
25}
26
27pub assume_specification[ u64::count_ones ](v: u64) -> (r: u32)
30 ensures
31 r == u64_set_bits(v),
32;
33
34pub broadcast proof fn lemma_u64_set_bits_nonzero(w: u64)
36 ensures
37 #![trigger u64_set_bits(w)]
38 (w != 0u64) == (1 <= u64_set_bits(w)),
39 0 <= u64_set_bits(w) <= 64,
40{
41 reveal(u64_set_bits);
42 lemma_u64_set_bits_rec_bounds(w, 64);
43 assert(w >> 64u64 == 0) by (bit_vector);
44}
45
46proof fn lemma_u64_set_bits_rec_bounds(w: u64, n: u64)
47 requires
48 n <= 64,
49 ensures
50 0 <= u64_set_bits_rec(w, n) <= n,
51 w >> n == 0 ==> ((w != 0) == (1 <= u64_set_bits_rec(w, n))),
52 decreases n,
53{
54 reveal_with_fuel(u64_set_bits_rec, 1);
55 if n != 0 {
56 let prev = (n - 1) as u64;
57 lemma_u64_set_bits_rec_bounds(w, prev);
58 if w >> n == 0 {
59 if w == 0 {
60 assert(u64_bit_is_set(w, prev as int) == false) by {
61 assert((w & (1u64 << (prev as usize))) == 0u64) by (bit_vector)
62 requires
63 w == 0,
64 ;
65 }
66 assert(w >> prev == 0) by (bit_vector)
67 requires
68 w == 0,
69 ;
70 } else {
71 if u64_bit_is_set(w, prev as int) {
72 assert(1 <= u64_bit_is_set(w, prev as int) as int);
73 } else {
74 assert((w & (1u64 << (prev as usize))) == 0u64);
75 assert(w >> prev == 0) by (bit_vector)
76 requires
77 0 < n <= 64,
78 prev == n - 1,
79 w >> n == 0,
80 (w & (1u64 << (prev as usize))) == 0u64,
81 ;
82 }
83 }
84 }
85 } else {
86 assert(w >> n == w) by (bit_vector)
87 requires
88 n == 0,
89 ;
90 }
91}
92
93}