1#[allow(unused_imports)]
15use super::super::prelude::*;
16
17verus! {
18
19#[cfg(verus_keep_ghost)]
20use super::power::{
21 pow,
22 lemma_pow_positive,
23 lemma_pow_adds,
24 lemma_pow_strictly_increases,
25 lemma_pow_subtracts,
26};
27
28#[verifier::opaque]
32pub open spec fn pow2(e: nat) -> nat
33 decreases
34 e ,
38{
39 pow(2, e) as nat
43}
44
45pub broadcast proof fn lemma_pow2_pos(e: nat)
48 ensures
49 #[trigger] pow2(e) > 0,
50{
51 reveal(pow2);
52 lemma_pow_positive(2, e);
53}
54
55pub broadcast proof fn lemma_pow2(e: nat)
57 ensures
58 #[trigger] pow2(e) == pow(2, e) as int,
59 decreases e,
60{
61 reveal(pow);
62 reveal(pow2);
63 if e != 0 {
64 lemma_pow2((e - 1) as nat);
65 }
66}
67
68pub broadcast proof fn lemma_pow2_unfold(e: nat)
70 requires
71 e > 0,
72 ensures
73 #[trigger] pow2(e) == 2 * pow2((e - 1) as nat),
74{
75 reveal(pow);
76 lemma_pow2(e);
77 lemma_pow2((e - 1) as nat);
78}
79
80pub broadcast proof fn lemma_pow2_adds(e1: nat, e2: nat)
82 ensures
83 #[trigger] pow2(e1 + e2) == pow2(e1) * pow2(e2),
84{
85 lemma_pow2(e1);
86 lemma_pow2(e2);
87 lemma_pow2(e1 + e2);
88 lemma_pow_adds(2, e1, e2);
89}
90
91pub broadcast proof fn lemma_pow2_subtracts(e1: nat, e2: nat)
93 requires
94 e1 <= e2,
95 ensures
96 #[trigger] pow2((e2 - e1) as nat) == pow2(e2) / pow2(e1) > 0,
97{
98 lemma_pow2(e1);
99 lemma_pow2(e2);
100 lemma_pow2((e2 - e1) as nat);
101 lemma_pow_subtracts(2, e1, e2);
102}
103
104pub broadcast proof fn lemma_pow2_strictly_increases(e1: nat, e2: nat)
106 requires
107 e1 < e2,
108 ensures
109 #[trigger] pow2(e1) < #[trigger] pow2(e2),
110{
111 lemma_pow2(e1);
112 lemma_pow2(e2);
113 lemma_pow_strictly_increases(2, e1, e2);
114}
115
116pub proof fn lemma2_to64()
118 ensures
119 pow2(0) == 0x1,
120 pow2(1) == 0x2,
121 pow2(2) == 0x4,
122 pow2(3) == 0x8,
123 pow2(4) == 0x10,
124 pow2(5) == 0x20,
125 pow2(6) == 0x40,
126 pow2(7) == 0x80,
127 pow2(8) == 0x100,
128 pow2(9) == 0x200,
129 pow2(10) == 0x400,
130 pow2(11) == 0x800,
131 pow2(12) == 0x1000,
132 pow2(13) == 0x2000,
133 pow2(14) == 0x4000,
134 pow2(15) == 0x8000,
135 pow2(16) == 0x10000,
136 pow2(17) == 0x20000,
137 pow2(18) == 0x40000,
138 pow2(19) == 0x80000,
139 pow2(20) == 0x100000,
140 pow2(21) == 0x200000,
141 pow2(22) == 0x400000,
142 pow2(23) == 0x800000,
143 pow2(24) == 0x1000000,
144 pow2(25) == 0x2000000,
145 pow2(26) == 0x4000000,
146 pow2(27) == 0x8000000,
147 pow2(28) == 0x10000000,
148 pow2(29) == 0x20000000,
149 pow2(30) == 0x40000000,
150 pow2(31) == 0x80000000,
151 pow2(32) == 0x100000000,
152 pow2(64) == 0x10000000000000000,
153{
154 reveal(pow2);
155 reveal(pow);
156 #[verusfmt::skip]
157 assert(
158 pow2(0) == 0x1 &&
159 pow2(1) == 0x2 &&
160 pow2(2) == 0x4 &&
161 pow2(3) == 0x8 &&
162 pow2(4) == 0x10 &&
163 pow2(5) == 0x20 &&
164 pow2(6) == 0x40 &&
165 pow2(7) == 0x80 &&
166 pow2(8) == 0x100 &&
167 pow2(9) == 0x200 &&
168 pow2(10) == 0x400 &&
169 pow2(11) == 0x800 &&
170 pow2(12) == 0x1000 &&
171 pow2(13) == 0x2000 &&
172 pow2(14) == 0x4000 &&
173 pow2(15) == 0x8000 &&
174 pow2(16) == 0x10000 &&
175 pow2(17) == 0x20000 &&
176 pow2(18) == 0x40000 &&
177 pow2(19) == 0x80000 &&
178 pow2(20) == 0x100000 &&
179 pow2(21) == 0x200000 &&
180 pow2(22) == 0x400000 &&
181 pow2(23) == 0x800000 &&
182 pow2(24) == 0x1000000 &&
183 pow2(25) == 0x2000000 &&
184 pow2(26) == 0x4000000 &&
185 pow2(27) == 0x8000000 &&
186 pow2(28) == 0x10000000 &&
187 pow2(29) == 0x20000000 &&
188 pow2(30) == 0x40000000 &&
189 pow2(31) == 0x80000000 &&
190 pow2(32) == 0x100000000 &&
191 pow2(64) == 0x10000000000000000
192 ) by(compute_only);
193}
194
195pub proof fn lemma2_to64_rest()
199 ensures
200 pow2(33) == 0x200000000,
201 pow2(34) == 0x400000000,
202 pow2(35) == 0x800000000,
203 pow2(36) == 0x1000000000,
204 pow2(37) == 0x2000000000,
205 pow2(38) == 0x4000000000,
206 pow2(39) == 0x8000000000,
207 pow2(40) == 0x10000000000,
208 pow2(41) == 0x20000000000,
209 pow2(42) == 0x40000000000,
210 pow2(43) == 0x80000000000,
211 pow2(44) == 0x100000000000,
212 pow2(45) == 0x200000000000,
213 pow2(46) == 0x400000000000,
214 pow2(47) == 0x800000000000,
215 pow2(48) == 0x1000000000000,
216 pow2(49) == 0x2000000000000,
217 pow2(50) == 0x4000000000000,
218 pow2(51) == 0x8000000000000,
219 pow2(52) == 0x10000000000000,
220 pow2(53) == 0x20000000000000,
221 pow2(54) == 0x40000000000000,
222 pow2(55) == 0x80000000000000,
223 pow2(56) == 0x100000000000000,
224 pow2(57) == 0x200000000000000,
225 pow2(58) == 0x400000000000000,
226 pow2(59) == 0x800000000000000,
227 pow2(60) == 0x1000000000000000,
228 pow2(61) == 0x2000000000000000,
229 pow2(62) == 0x4000000000000000,
230 pow2(63) == 0x8000000000000000,
231 pow2(64) == 0x10000000000000000,
232{
233 reveal(pow2);
234 reveal(pow);
235 #[verusfmt::skip]
236 assert(
237 pow2(33) == 0x200000000 &&
238 pow2(34) == 0x400000000 &&
239 pow2(35) == 0x800000000 &&
240 pow2(36) == 0x1000000000 &&
241 pow2(37) == 0x2000000000 &&
242 pow2(38) == 0x4000000000 &&
243 pow2(39) == 0x8000000000 &&
244 pow2(40) == 0x10000000000 &&
245 pow2(41) == 0x20000000000 &&
246 pow2(42) == 0x40000000000 &&
247 pow2(43) == 0x80000000000 &&
248 pow2(44) == 0x100000000000 &&
249 pow2(45) == 0x200000000000 &&
250 pow2(46) == 0x400000000000 &&
251 pow2(47) == 0x800000000000 &&
252 pow2(48) == 0x1000000000000 &&
253 pow2(49) == 0x2000000000000 &&
254 pow2(50) == 0x4000000000000 &&
255 pow2(51) == 0x8000000000000 &&
256 pow2(52) == 0x10000000000000 &&
257 pow2(53) == 0x20000000000000 &&
258 pow2(54) == 0x40000000000000 &&
259 pow2(55) == 0x80000000000000 &&
260 pow2(56) == 0x100000000000000 &&
261 pow2(57) == 0x200000000000000 &&
262 pow2(58) == 0x400000000000000 &&
263 pow2(59) == 0x800000000000000 &&
264 pow2(60) == 0x1000000000000000 &&
265 pow2(61) == 0x2000000000000000 &&
266 pow2(62) == 0x4000000000000000 &&
267 pow2(63) == 0x8000000000000000 &&
268 pow2(64) == 0x10000000000000000
269 ) by(compute_only);
270}
271
272}