You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
__CPROVER_assert(__CPROVER_forall { size_t j; (0 <= j && j < len) ==> array[j] == 0 }, "array is set to 0"); // post-condition
168
+
}
169
+
```
170
+
171
+
### Caution With Nested Loop
172
+
Due to the nature of @ref contracts-assigns, we need to be aware of the non-deterministic value of the assigned target.
173
+
In the example below,
174
+
```c
175
+
const unsigned table[256] = {1, 2, 3, ..., 256};
176
+
177
+
void nested_loop_example() {
178
+
unsigned t = 0;
179
+
for( j=0; j<18; j++ )
180
+
__CPROVER_assigns(t, j, k) // t and k are also assigns targets of the outer loop as they are assigned in the inner loop
181
+
__CPROVER_loop_invariant(0 <= j && j <= 18 && t < 256) // without t < 256, the program state for the inductive step allows t to have arbitrary value
182
+
__CPROVER_decreases(18 - j)
183
+
{
184
+
for( k=0; k<48; k++ )
185
+
__CPROVER_assigns(t, k)
186
+
__CPROVER_loop_invariant(0 <= k && k <= 48 && t < 256)
187
+
__CPROVER_decreases(48 - k)
188
+
{
189
+
t = table[t];
190
+
}
191
+
}
192
+
}
193
+
```
194
+
If `t < 256` is not included in the outer loop invariant, the inner loop invariant `t < 256` will immediately fail at loop entry because, in the inductive step of the outer loop, the assigns target `t` of the outer loop will be a non-deterministic value which can be greater than 256. With the predicate `t<256` in the outer loop's invariants will restrict `t` to be less than `256` in the proof of the inductive step of the outer loop.
0 commit comments