Skip to content

Commit bd3665d

Browse files
committed
Updated recursion example to use u32::MAX.
Also reworded doc text per suggestion from @parno.
1 parent c9db144 commit bd3665d

File tree

2 files changed

+17
-19
lines changed

2 files changed

+17
-19
lines changed

examples/guide/recursion.rs

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ fn rec_triangle(n: u32) -> (sum: u32)
105105
// ANCHOR: rec
106106
fn rec_triangle(n: u32) -> (sum: u32)
107107
requires
108-
triangle(n as nat) < 0x1_0000_0000,
108+
triangle(n as nat) < u32::MAX,
109109
ensures
110110
sum == triangle(n as nat),
111111
decreases n,
@@ -121,7 +121,7 @@ fn rec_triangle(n: u32) -> (sum: u32)
121121
// ANCHOR: mut
122122
fn mut_triangle(n: u32, sum: &mut u32)
123123
requires
124-
triangle(n as nat) < 0x1_0000_0000,
124+
triangle(n as nat) < u32::MAX,
125125
ensures
126126
*sum == triangle(n as nat),
127127
decreases n,
@@ -141,7 +141,7 @@ fn tail_triangle(n: u32, idx: u32, sum: &mut u32)
141141
requires
142142
idx <= n,
143143
*old(sum) == triangle(idx as nat),
144-
triangle(n as nat) < 0x1_0000_0000,
144+
triangle(n as nat) < u32::MAX,
145145
ensures
146146
*sum == triangle(n as nat),
147147
{
@@ -197,14 +197,14 @@ fn tail_triangle(n: u32, idx: u32, sum: &mut u32)
197197
requires
198198
idx <= n,
199199
*old(sum) == triangle(idx as nat),
200-
triangle(n as nat) < 0x1_0000_0000,
200+
triangle(n as nat) < u32::MAX,
201201
ensures
202202
*sum == triangle(n as nat),
203203
decreases n - idx,
204204
{
205205
if idx < n {
206206
let idx = idx + 1;
207-
assert(*sum + idx < 0x1_0000_0000) by {
207+
assert(*sum + idx < u32::MAX) by {
208208
triangle_is_monotonic(idx as nat, n as nat);
209209
}
210210
*sum = *sum + idx;
@@ -216,7 +216,7 @@ fn tail_triangle(n: u32, idx: u32, sum: &mut u32)
216216
// ANCHOR: loop
217217
fn loop_triangle(n: u32) -> (sum: u32)
218218
requires
219-
triangle(n as nat) < 0x1_0000_0000,
219+
triangle(n as nat) < u32::MAX,
220220
ensures
221221
sum == triangle(n as nat),
222222
{
@@ -226,11 +226,11 @@ fn loop_triangle(n: u32) -> (sum: u32)
226226
invariant
227227
idx <= n,
228228
sum == triangle(idx as nat),
229-
triangle(n as nat) < 0x1_0000_0000,
229+
triangle(n as nat) < u32::MAX,
230230
decreases n - idx,
231231
{
232232
idx = idx + 1;
233-
assert(sum + idx < 0x1_0000_0000) by {
233+
assert(sum + idx < u32::MAX) by {
234234
triangle_is_monotonic(idx as nat, n as nat);
235235
}
236236
sum = sum + idx;
@@ -242,7 +242,7 @@ fn loop_triangle(n: u32) -> (sum: u32)
242242
// ANCHOR: loop_return
243243
fn loop_triangle_return(n: u32) -> (sum: u32)
244244
ensures
245-
sum == triangle(n as nat) || (sum == 0xffff_ffff && triangle(n as nat) >= 0x1_0000_0000),
245+
sum == triangle(n as nat) || (sum == 0xffff_ffff && triangle(n as nat) >= u32::MAX),
246246
{
247247
let mut sum: u32 = 0;
248248
let mut idx: u32 = 0;
@@ -253,7 +253,7 @@ fn loop_triangle_return(n: u32) -> (sum: u32)
253253
decreases n - idx,
254254
{
255255
idx = idx + 1;
256-
if sum as u64 + idx as u64 >= 0x1_0000_0000 {
256+
if sum as u64 + idx as u64 >= u32::MAX as u64 {
257257
proof {
258258
triangle_is_monotonic(idx as nat, n as nat);
259259
}
@@ -269,7 +269,7 @@ fn loop_triangle_return(n: u32) -> (sum: u32)
269269
// ANCHOR: loop_break
270270
fn loop_triangle_break(n: u32) -> (sum: u32)
271271
ensures
272-
sum == triangle(n as nat) || (sum == 0xffff_ffff && triangle(n as nat) >= 0x1_0000_0000),
272+
sum == triangle(n as nat) || (sum == 0xffff_ffff && triangle(n as nat) >= u32::MAX),
273273
{
274274
let mut sum: u32 = 0;
275275
let mut idx: u32 = 0;
@@ -278,11 +278,11 @@ fn loop_triangle_break(n: u32) -> (sum: u32)
278278
idx <= n,
279279
sum == triangle(idx as nat),
280280
ensures
281-
sum == triangle(n as nat) || (sum == 0xffff_ffff && triangle(n as nat) >= 0x1_0000_0000),
281+
sum == triangle(n as nat) || (sum == 0xffff_ffff && triangle(n as nat) >= u32::MAX),
282282
decreases n - idx,
283283
{
284284
idx = idx + 1;
285-
if sum as u64 + idx as u64 >= 0x1_0000_0000 {
285+
if sum as u64 + idx as u64 >= u32::MAX as u64 {
286286
proof {
287287
triangle_is_monotonic(idx as nat, n as nat);
288288
}
@@ -298,7 +298,7 @@ fn loop_triangle_break(n: u32) -> (sum: u32)
298298
// ANCHOR: for_loop
299299
fn for_loop_triangle(n: u32) -> (sum: u32)
300300
requires
301-
triangle(n as nat) < 0x1_0000_0000,
301+
triangle(n as nat) < u32::MAX,
302302
ensures
303303
sum == triangle(n as nat),
304304
{
@@ -307,9 +307,9 @@ fn for_loop_triangle(n: u32) -> (sum: u32)
307307
for idx in iter: 0..n
308308
invariant
309309
sum == triangle(idx as nat),
310-
triangle(n as nat) < 0x1_0000_0000,
310+
triangle(n as nat) < u32::MAX,
311311
{
312-
assert(sum + idx + 1 < 0x1_0000_0000) by {
312+
assert(sum + idx + 1 < u32::MAX) by {
313313
triangle_is_monotonic((idx + 1) as nat, n as nat);
314314
}
315315
sum = sum + idx + 1;

source/docs/guide/src/triangle.md

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,7 @@ We connect the correctness of `loop_triangle`'s return value to our mathematical
1212
in `loop_triangle`'s `ensures` clause.
1313

1414
However, to successfully verify `loop_triangle`, we need a few more things. First, in executable
15-
code, we have to worry about the possibility of arithmetic overflow. To that end, the function requires its
16-
output to be less than `0x1_0000_0000`. This is 16^8, or 2^32, which is the limit of the range of values that can fit
17-
in a `u32`.
15+
code, we have to worry about the possibility of arithmetic overflow. To keep the overflow reasoning simple, we add a precondition to loop_triangle saying that the result needs to fit within a `u32`.
1816

1917
We also need to translate the knowledge that the final `triangle` result fits in a `u32`
2018
into the knowledge that each individual step of computing the result won't overflow,

0 commit comments

Comments
 (0)