vstd/
state_machine_internal.rs

1//! Helper utilities used by the `state_machine_macros` codegen.
2#![allow(unused_imports)]
3#![doc(hidden)]
4
5use super::map::*;
6use super::pervasive::*;
7use super::prelude::*;
8use super::seq::*;
9
10#[cfg_attr(verus_keep_ghost, verifier::external_body)] /* vattr */
11#[cfg_attr(verus_keep_ghost, verifier::accept_recursive_types(T))]
12pub struct SyncSendIfSyncSend<T> {
13    _sync_send: super::prelude::SyncSendIfSyncSend<T>,
14}
15
16#[cfg_attr(verus_keep_ghost, verifier::verus_macro)]
17impl<T> Clone for SyncSendIfSyncSend<T> {
18    #[cfg_attr(verus_keep_ghost, verifier::external_body)]
19    fn clone(&self) -> Self {
20        SyncSendIfSyncSend { _sync_send: self._sync_send.clone() }
21    }
22}
23
24impl<T> Copy for SyncSendIfSyncSend<T> {}
25
26#[cfg_attr(verus_keep_ghost, verifier::external_body)] /* vattr */
27pub struct NoCopy {
28    _no_copy: super::prelude::NoCopy,
29}
30
31#[cfg(verus_keep_ghost)]
32#[verifier::proof]
33#[verifier::custom_req_err("unable to prove assertion safety condition")] /* vattr */
34pub fn assert_safety(b: bool) {
35    requires(b);
36    ensures(b);
37}
38
39#[cfg(verus_keep_ghost)]
40#[verifier::proof]
41#[verifier::custom_req_err("unable to prove safety condition that the pattern matches")] /* vattr */
42pub fn assert_let_pattern(b: bool) {
43    requires(b);
44    ensures(b);
45}
46
47// SpecialOps
48
49#[cfg(verus_keep_ghost)]
50#[verifier::proof]
51#[verifier::custom_req_err("unable to prove inherent safety condition: to add a value Some(_), field must be None before the update")] /* vattr */
52pub fn assert_add_option(b: bool) {
53    requires(b);
54    ensures(b);
55}
56
57#[cfg(verus_keep_ghost)]
58#[verifier::proof]
59#[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 */
60pub fn assert_add_set(b: bool) {
61    requires(b);
62    ensures(b);
63}
64
65#[cfg(verus_keep_ghost)]
66#[verifier::proof]
67#[verifier::custom_req_err("unable to prove inherent safety condition: to add a value `true`, field must be `false` before the update")] /* vattr */
68pub fn assert_add_bool(b: bool) {
69    requires(b);
70    ensures(b);
71}
72
73#[cfg(verus_keep_ghost)]
74#[verifier::proof]
75#[verifier::custom_req_err("unable to prove inherent safety condition: the given key must be absent from the map before the update")] /* vattr */
76pub fn assert_add_map(b: bool) {
77    requires(b);
78    ensures(b);
79}
80
81#[cfg(verus_keep_ghost)]
82#[verifier::proof]
83#[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 */
84pub fn assert_add_persistent_map(b: bool) {
85    requires(b);
86    ensures(b);
87}
88
89#[cfg(verus_keep_ghost)]
90#[verifier::proof]
91#[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 */
92pub fn assert_add_persistent_option(b: bool) {
93    requires(b);
94    ensures(b);
95}
96
97#[cfg(verus_keep_ghost)]
98#[verifier::proof]
99#[verifier::custom_req_err("unable to prove inherent safety condition: the given value to be withdrawn must be stored before the withdraw")] /* vattr */
100pub fn assert_withdraw_option(b: bool) {
101    requires(b);
102    ensures(b);
103}
104
105#[cfg(verus_keep_ghost)]
106#[verifier::proof]
107#[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 */
108pub fn assert_deposit_option(b: bool) {
109    requires(b);
110    ensures(b);
111}
112
113#[cfg(verus_keep_ghost)]
114#[verifier::proof]
115#[verifier::custom_req_err(
116    "unable to prove inherent safety condition: the value being guarded must be stored"
117)] /* vattr */
118pub fn assert_guard_option(b: bool) {
119    requires(b);
120    ensures(b);
121}
122
123#[cfg(verus_keep_ghost)]
124#[verifier::proof]
125#[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 */
126pub fn assert_withdraw_map(b: bool) {
127    requires(b);
128    ensures(b);
129}
130
131#[cfg(verus_keep_ghost)]
132#[verifier::proof]
133#[verifier::custom_req_err("unable to prove inherent safety condition: the given key must be absent from the map before the deposit")] /* vattr */
134pub fn assert_deposit_map(b: bool) {
135    requires(b);
136    ensures(b);
137}
138
139#[cfg(verus_keep_ghost)]
140#[verifier::proof]
141#[verifier::custom_req_err("unable to prove inherent safety condition: the value being guarded must be stored at the given key")] /* vattr */
142pub fn assert_guard_map(b: bool) {
143    requires(b);
144    ensures(b);
145}
146
147// SpecialOps (with general element)
148
149#[cfg(verus_keep_ghost)]
150#[verifier::proof]
151#[verifier::custom_req_err("unable to prove inherent safety condition: the optional values being composed cannot both be Some(_)")] /* vattr */
152pub fn assert_general_add_option(b: bool) {
153    requires(b);
154    ensures(b);
155}
156
157#[cfg(verus_keep_ghost)]
158#[verifier::proof]
159#[verifier::custom_req_err(
160    "unable to prove inherent safety condition: the sets being composed must be disjoint"
161)] /* vattr */
162pub fn assert_general_add_set(b: bool) {
163    requires(b);
164    ensures(b);
165}
166
167#[cfg(verus_keep_ghost)]
168#[verifier::proof]
169#[verifier::custom_req_err("unable to prove inherent safety condition: the boolean values being composed cannot both be `true`")] /* vattr */
170pub fn assert_general_add_bool(b: bool) {
171    requires(b);
172    ensures(b);
173}
174
175#[cfg(verus_keep_ghost)]
176#[verifier::proof]
177#[verifier::custom_req_err("unable to prove inherent safety condition: the key domains of the maps being composed must be disjoint")] /* vattr */
178pub fn assert_general_add_map(b: bool) {
179    requires(b);
180    ensures(b);
181}
182
183#[cfg(verus_keep_ghost)]
184#[verifier::proof]
185#[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 */
186pub fn assert_general_add_persistent_map(b: bool) {
187    requires(b);
188    ensures(b);
189}
190
191#[cfg(verus_keep_ghost)]
192#[verifier::proof]
193#[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 */
194pub fn assert_general_add_persistent_option(b: bool) {
195    requires(b);
196    ensures(b);
197}
198
199#[cfg(verus_keep_ghost)]
200#[verifier::proof]
201#[verifier::custom_req_err("unable to prove inherent safety condition: the optional value to be withdrawn must be stored before the withdraw")] /* vattr */
202pub fn assert_general_withdraw_option(b: bool) {
203    requires(b);
204    ensures(b);
205}
206
207#[cfg(verus_keep_ghost)]
208#[verifier::proof]
209#[verifier::custom_req_err("unable to prove inherent safety condition: the optional values being composed cannot both be Some(_)")] /* vattr */
210pub fn assert_general_deposit_option(b: bool) {
211    requires(b);
212    ensures(b);
213}
214
215#[cfg(verus_keep_ghost)]
216#[verifier::proof]
217#[verifier::custom_req_err(
218    "unable to prove inherent safety condition: the value being guarded must be stored"
219)] /* vattr */
220pub fn assert_general_guard_option(b: bool) {
221    requires(b);
222    ensures(b);
223}
224
225#[cfg(verus_keep_ghost)]
226#[verifier::proof]
227#[verifier::custom_req_err("unable to prove inherent safety condition: the map being withdrawn must be a submap of the stored map")] /* vattr */
228pub fn assert_general_withdraw_map(b: bool) {
229    requires(b);
230    ensures(b);
231}
232
233#[cfg(verus_keep_ghost)]
234#[verifier::proof]
235#[verifier::custom_req_err("unable to prove inherent safety condition: the key domains of the maps being composed must be disjoint")] /* vattr */
236pub fn assert_general_deposit_map(b: bool) {
237    requires(b);
238    ensures(b);
239}
240
241#[cfg(verus_keep_ghost)]
242#[verifier::proof]
243#[verifier::custom_req_err("unable to prove inherent safety condition: the map being guarded must be a submap of the stored map")] /* vattr */
244pub fn assert_general_guard_map(b: bool) {
245    requires(b);
246    ensures(b);
247}
248
249// used by the `update field[idx] = ...;` syntax
250//
251// note: the built-in rust trait IndexMut doesn't work here
252// (because these functions need to be 'spec' code, and IndexMut uses a &mut to do its job)
253// perhaps we'll make our own trait for this purpose some day, but regardless, this suffices
254// for our purposes
255
256verus! {
257
258#[doc(hidden)]
259pub open spec fn nat_max(a: nat, b: nat) -> nat {
260    if a > b {
261        a
262    } else {
263        b
264    }
265}
266
267#[doc(hidden)]
268impl<A> Seq<A> {
269    #[verifier::inline]
270    pub open spec fn update_at_index(self, i: int, a: A) -> Self
271        recommends
272            0 <= i < self.len(),
273    {
274        self.update(i, a)
275    }
276}
277
278#[doc(hidden)]
279impl<K, V> Map<K, V> {
280    // note that despite the name, this is allowed to insert
281    #[verifier::inline]
282    pub open spec fn update_at_index(self, k: K, v: V) -> Self {
283        self.insert(k, v)
284    }
285}
286
287#[doc(hidden)]
288#[verifier::inline]
289pub open spec fn opt_is_none<V>(a: Option<V>) -> bool {
290    a is None
291}
292
293#[doc(hidden)]
294#[verifier::inline]
295pub open spec fn opt_ge<V>(a: Option<V>, b: Option<V>) -> bool {
296    b is Some ==> a === b
297}
298
299#[doc(hidden)]
300#[verifier::inline]
301pub open spec fn opt_add<V>(a: Option<V>, b: Option<V>) -> Option<V> {
302    if b is Some {
303        b
304    } else {
305        a
306    }
307}
308
309#[doc(hidden)]
310#[verifier::inline]
311pub open spec fn opt_agree<V>(a: Option<V>, b: Option<V>) -> bool {
312    a is Some && b is Some ==> a->0 === b->0
313}
314
315#[doc(hidden)]
316#[verifier::inline]
317pub open spec fn opt_sub<V>(a: Option<V>, b: Option<V>) -> Option<V> {
318    if b is Some {
319        Option::None
320    } else {
321        a
322    }
323}
324
325} // verus!