Skip to content

Commit e4df236

Browse files
committed
add example
1 parent 92958f3 commit e4df236

File tree

2 files changed

+122
-1
lines changed

2 files changed

+122
-1
lines changed
Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
#![allow(unused_imports)]
2+
3+
use builtin_macros::*;
4+
use builtin::*;
5+
use vstd::*;
6+
use vstd::modes::*;
7+
use vstd::map::*;
8+
use vstd::seq::*;
9+
use vstd::prelude::*;
10+
use vstd::assert_by_contradiction;
11+
use vstd::calc;
12+
use vstd::std_specs::bits::u64_leading_zeros;
13+
14+
verus!{
15+
16+
global size_of usize == 8;
17+
18+
pub open spec fn smallest_bin_fitting_size(size: int) -> int {
19+
let bytes_per_word = (usize::BITS / 8) as int;
20+
let wsize = (size + bytes_per_word - 1) / bytes_per_word;
21+
if wsize <= 1 {
22+
1
23+
} else if wsize <= 8 {
24+
wsize
25+
} else if wsize > 524288 {
26+
BIN_HUGE as int
27+
} else {
28+
let w = (wsize - 1) as u64;
29+
//let lz = w.leading_zeros();
30+
let lz = u64_leading_zeros(w);
31+
let b = (usize::BITS - 1 - lz) as u8;
32+
let shifted = (w >> (b - 2) as u64) as u8;
33+
let bin_idx = ((b * 4) + (shifted & 0x03)) - 3;
34+
bin_idx
35+
}
36+
}
37+
38+
pub open spec fn pow2(i: int) -> nat
39+
decreases i
40+
{
41+
if i <= 0 {
42+
1
43+
} else {
44+
pow2(i - 1) * 2
45+
}
46+
}
47+
48+
49+
/*
50+
fn stuff() {
51+
assert(0 == 0) by(compute);
52+
assert(0 == 1) by(compute);
53+
54+
assert(0 + 3 == 4) by(compute);
55+
}
56+
*/
57+
58+
pub const BIN_HUGE: u64 = 73;
59+
60+
pub open spec fn valid_bin_idx(bin_idx: int) -> bool {
61+
1 <= bin_idx <= BIN_HUGE
62+
}
63+
64+
pub open spec fn size_of_bin(bin_idx: int) -> nat
65+
recommends valid_bin_idx(bin_idx)
66+
{
67+
if 1 <= bin_idx <= 8 {
68+
(usize::BITS / 8) as nat * (bin_idx as nat)
69+
} else if bin_idx == BIN_HUGE {
70+
// the "real" upper bound on this bucket is infinite
71+
// the lemmas on bin sizes assume each bin has a lower bound and upper bound
72+
// so we pretend this is the upper bound
73+
74+
8 * (524288 + 1)
75+
//8 * (MEDIUM_OBJ_WSIZE_MAX as nat + 1)
76+
} else {
77+
let group = (bin_idx - 9) / 4;
78+
let inner = (bin_idx - 9) % 4;
79+
80+
((usize::BITS / 8) * (inner + 5) * pow2(group + 1)) as nat
81+
}
82+
}
83+
84+
spec fn property_bin(size:int) -> bool
85+
{
86+
131072 >= size_of_bin(smallest_bin_fitting_size(size)) >= size
87+
}
88+
89+
spec fn check_bin(size_start:int, size_end:int) -> bool
90+
decreases size_end - size_start + 8,
91+
{
92+
if size_start >= size_end {
93+
true
94+
} else {
95+
property_bin(size_start)
96+
&& check_bin(size_start + 1, size_end)
97+
}
98+
}
99+
100+
101+
pub proof fn bin_size_result_mul8(size: usize)
102+
requires
103+
size % 8 == 0,
104+
size <= 131072, // == MEDIUM_OBJ_SIZE_MAX
105+
valid_bin_idx(smallest_bin_fitting_size(size as int)),
106+
//ensures
107+
// 131072 >= size_of_bin(smallest_bin_fitting_size(size as int) as int) >= size,
108+
{
109+
reveal(u64_leading_zeros);
110+
assert(check_bin(0, 131072)) by (compute);
111+
}
112+
113+
114+
115+
116+
117+
118+
119+
fn main() { }
120+
121+
}

source/vir/src/fast_interp.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -911,7 +911,7 @@ fn exec_unary(val: &mut Value, op: &IUnaryOp, ctx: &Ctx, msgs: &mut Vec<Message>
911911
}
912912
IUnaryOp::GetFieldAnyVariant(field_idx) => {
913913
match &*val {
914-
Value::Ctor(variant_idx, fields) => {
914+
Value::Ctor(_variant_idx, fields) => {
915915
fields[*field_idx as usize].clone()
916916
}
917917
_ => no_eval()

0 commit comments

Comments
 (0)