1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
//! Helper utilities used by the `state_machine_macros` codegen.
#![allow(unused_imports)]
#![doc(hidden)]

use super::map::*;
use super::pervasive::*;
use super::prelude::*;
use super::seq::*;

#[cfg_attr(verus_keep_ghost, verifier::external_body)] /* vattr */
#[cfg_attr(verus_keep_ghost, verifier::accept_recursive_types(T))]
pub struct SyncSendIfSyncSend<T> {
    _sync_send: super::prelude::SyncSendIfSyncSend<T>,
}

#[cfg_attr(verus_keep_ghost, verifier::verus_macro)]
impl<T> Clone for SyncSendIfSyncSend<T> {
    #[cfg_attr(verus_keep_ghost, verifier::external_body)]
    fn clone(&self) -> Self {
        SyncSendIfSyncSend { _sync_send: self._sync_send.clone() }
    }
}

impl<T> Copy for SyncSendIfSyncSend<T> {}

#[cfg_attr(verus_keep_ghost, verifier::external_body)] /* vattr */
pub struct NoCopy {
    _no_copy: super::prelude::NoCopy,
}

#[cfg(verus_keep_ghost)]
#[verifier::proof]
#[verifier::custom_req_err("unable to prove assertion safety condition")] /* vattr */
pub fn assert_safety(b: bool) {
    requires(b);
    ensures(b);
}

#[cfg(verus_keep_ghost)]
#[verifier::proof]
#[verifier::custom_req_err("unable to prove safety condition that the pattern matches")] /* vattr */
pub fn assert_let_pattern(b: bool) {
    requires(b);
    ensures(b);
}

// SpecialOps

#[cfg(verus_keep_ghost)]
#[verifier::proof]
#[verifier::custom_req_err("unable to prove inherent safety condition: to add a value Some(_), field must be None before the update")] /* vattr */
pub fn assert_add_option(b: bool) {
    requires(b);
    ensures(b);
}

#[cfg(verus_keep_ghost)]
#[verifier::proof]
#[verifier::custom_req_err("unable to prove inherent safety condition: to add a singleton set, the value must not be in the set before the update")] /* vattr */
pub fn assert_add_set(b: bool) {
    requires(b);
    ensures(b);
}

#[cfg(verus_keep_ghost)]
#[verifier::proof]
#[verifier::custom_req_err("unable to prove inherent safety condition: to add a value `true`, field must be `false` before the update")] /* vattr */
pub fn assert_add_bool(b: bool) {
    requires(b);
    ensures(b);
}

#[cfg(verus_keep_ghost)]
#[verifier::proof]
#[verifier::custom_req_err("unable to prove inherent safety condition: the given key must be absent from the map before the update")] /* vattr */
pub fn assert_add_map(b: bool) {
    requires(b);
    ensures(b);
}

#[cfg(verus_keep_ghost)]
#[verifier::proof]
#[verifier::custom_req_err("unable to prove inherent safety condition: if the key is already in the map, its existing value must agree with the provided value")] /* vattr */
pub fn assert_add_persistent_map(b: bool) {
    requires(b);
    ensures(b);
}

#[cfg(verus_keep_ghost)]
#[verifier::proof]
#[verifier::custom_req_err("unable to prove inherent safety condition: if the previous value is Some(_), then this existing value must agree with the newly provided value")] /* vattr */
pub fn assert_add_persistent_option(b: bool) {
    requires(b);
    ensures(b);
}

#[cfg(verus_keep_ghost)]
#[verifier::proof]
#[verifier::custom_req_err("unable to prove inherent safety condition: the given value to be withdrawn must be stored before the withdraw")] /* vattr */
pub fn assert_withdraw_option(b: bool) {
    requires(b);
    ensures(b);
}

#[cfg(verus_keep_ghost)]
#[verifier::proof]
#[verifier::custom_req_err("unable to prove inherent safety condition: to deposit a value into Some(_), the field must be None before the deposit")] /* vattr */
pub fn assert_deposit_option(b: bool) {
    requires(b);
    ensures(b);
}

#[cfg(verus_keep_ghost)]
#[verifier::proof]
#[verifier::custom_req_err(
    "unable to prove inherent safety condition: the value being guarded must be stored"
)] /* vattr */
pub fn assert_guard_option(b: bool) {
    requires(b);
    ensures(b);
}

#[cfg(verus_keep_ghost)]
#[verifier::proof]
#[verifier::custom_req_err("unable to prove inherent safety condition: the value to be withdrawn must be stored at the given key before the withdraw")] /* vattr */
pub fn assert_withdraw_map(b: bool) {
    requires(b);
    ensures(b);
}

#[cfg(verus_keep_ghost)]
#[verifier::proof]
#[verifier::custom_req_err("unable to prove inherent safety condition: the given key must be absent from the map before the deposit")] /* vattr */
pub fn assert_deposit_map(b: bool) {
    requires(b);
    ensures(b);
}

#[cfg(verus_keep_ghost)]
#[verifier::proof]
#[verifier::custom_req_err("unable to prove inherent safety condition: the value being guarded must be stored at the given key")] /* vattr */
pub fn assert_guard_map(b: bool) {
    requires(b);
    ensures(b);
}

// SpecialOps (with general element)

#[cfg(verus_keep_ghost)]
#[verifier::proof]
#[verifier::custom_req_err("unable to prove inherent safety condition: the optional values being composed cannot both be Some(_)")] /* vattr */
pub fn assert_general_add_option(b: bool) {
    requires(b);
    ensures(b);
}

#[cfg(verus_keep_ghost)]
#[verifier::proof]
#[verifier::custom_req_err(
    "unable to prove inherent safety condition: the sets being composed must be disjoint"
)] /* vattr */
pub fn assert_general_add_set(b: bool) {
    requires(b);
    ensures(b);
}

#[cfg(verus_keep_ghost)]
#[verifier::proof]
#[verifier::custom_req_err("unable to prove inherent safety condition: the boolean values being composed cannot both be `true`")] /* vattr */
pub fn assert_general_add_bool(b: bool) {
    requires(b);
    ensures(b);
}

#[cfg(verus_keep_ghost)]
#[verifier::proof]
#[verifier::custom_req_err("unable to prove inherent safety condition: the key domains of the maps being composed must be disjoint")] /* vattr */
pub fn assert_general_add_map(b: bool) {
    requires(b);
    ensures(b);
}

#[cfg(verus_keep_ghost)]
#[verifier::proof]
#[verifier::custom_req_err("unable to prove inherent safety condition: the maps being composed must agree on their values for any key in both domains")] /* vattr */
pub fn assert_general_add_persistent_map(b: bool) {
    requires(b);
    ensures(b);
}

#[cfg(verus_keep_ghost)]
#[verifier::proof]
#[verifier::custom_req_err("unable to prove inherent safety condition: if the previous value and the newly added values are both Some(_), then their values must agree")] /* vattr */
pub fn assert_general_add_persistent_option(b: bool) {
    requires(b);
    ensures(b);
}

#[cfg(verus_keep_ghost)]
#[verifier::proof]
#[verifier::custom_req_err("unable to prove inherent safety condition: the optional value to be withdrawn must be stored before the withdraw")] /* vattr */
pub fn assert_general_withdraw_option(b: bool) {
    requires(b);
    ensures(b);
}

#[cfg(verus_keep_ghost)]
#[verifier::proof]
#[verifier::custom_req_err("unable to prove inherent safety condition: the optional values being composed cannot both be Some(_)")] /* vattr */
pub fn assert_general_deposit_option(b: bool) {
    requires(b);
    ensures(b);
}

#[cfg(verus_keep_ghost)]
#[verifier::proof]
#[verifier::custom_req_err(
    "unable to prove inherent safety condition: the value being guarded must be stored"
)] /* vattr */
pub fn assert_general_guard_option(b: bool) {
    requires(b);
    ensures(b);
}

#[cfg(verus_keep_ghost)]
#[verifier::proof]
#[verifier::custom_req_err("unable to prove inherent safety condition: the map being withdrawn must be a submap of the stored map")] /* vattr */
pub fn assert_general_withdraw_map(b: bool) {
    requires(b);
    ensures(b);
}

#[cfg(verus_keep_ghost)]
#[verifier::proof]
#[verifier::custom_req_err("unable to prove inherent safety condition: the key domains of the maps being composed must be disjoint")] /* vattr */
pub fn assert_general_deposit_map(b: bool) {
    requires(b);
    ensures(b);
}

#[cfg(verus_keep_ghost)]
#[verifier::proof]
#[verifier::custom_req_err("unable to prove inherent safety condition: the map being guarded must be a submap of the stored map")] /* vattr */
pub fn assert_general_guard_map(b: bool) {
    requires(b);
    ensures(b);
}

// used by the `update field[idx] = ...;` syntax
//
// note: the built-in rust trait IndexMut doesn't work here
// (because these functions need to be 'spec' code, and IndexMut uses a &mut to do its job)
// perhaps we'll make our own trait for this purpose some day, but regardless, this suffices
// for our purposes

verus! {

#[doc(hidden)]
pub open spec fn nat_max(a: nat, b: nat) -> nat {
    if a > b {
        a
    } else {
        b
    }
}

#[doc(hidden)]
impl<A> Seq<A> {
    #[verifier::inline]
    pub open spec fn update_at_index(self, i: int, a: A) -> Self
        recommends
            0 <= i < self.len(),
    {
        self.update(i, a)
    }
}

#[doc(hidden)]
impl<K, V> Map<K, V> {
    // note that despite the name, this is allowed to insert
    #[verifier::inline]
    pub open spec fn update_at_index(self, k: K, v: V) -> Self {
        self.insert(k, v)
    }
}

#[doc(hidden)]
#[verifier::inline]
pub open spec fn opt_is_none<V>(a: Option<V>) -> bool {
    a.is_None()
}

#[doc(hidden)]
#[verifier::inline]
pub open spec fn opt_ge<V>(a: Option<V>, b: Option<V>) -> bool {
    b.is_Some() ==> a === b
}

#[doc(hidden)]
#[verifier::inline]
pub open spec fn opt_add<V>(a: Option<V>, b: Option<V>) -> Option<V> {
    if b.is_Some() {
        b
    } else {
        a
    }
}

#[doc(hidden)]
#[verifier::inline]
pub open spec fn opt_agree<V>(a: Option<V>, b: Option<V>) -> bool {
    a.is_Some() && b.is_Some() ==> a.get_Some_0() === b.get_Some_0()
}

#[doc(hidden)]
#[verifier::inline]
pub open spec fn opt_sub<V>(a: Option<V>, b: Option<V>) -> Option<V> {
    if b.is_Some() {
        Option::None
    } else {
        a
    }
}

} // verus!