1//! Helper utilities used by the `state_machine_macros` codegen.
2#![allow(unused_imports)]
3#![doc(hidden)]
45use super::map::*;
6use super::pervasive::*;
7use super::prelude::*;
8use super::seq::*;
910#[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}
1516#[cfg_attr(verus_keep_ghost, verifier::verus_macro)]
17impl<T> Clone for SyncSendIfSyncSend<T> {
18#[cfg_attr(verus_keep_ghost, verifier::external_body)]
19fn clone(&self) -> Self {
20 SyncSendIfSyncSend { _sync_send: self._sync_send.clone() }
21 }
22}
2324impl<T> Copy for SyncSendIfSyncSend<T> {}
2526#[cfg_attr(verus_keep_ghost, verifier::external_body)] /* vattr */
27pub struct NoCopy {
28 _no_copy: super::prelude::NoCopy,
29}
3031#[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}
3839#[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}
4647// SpecialOps
4849#[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}
5657#[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}
6465#[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}
7273#[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}
8081#[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}
8889#[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}
9697#[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}
104105#[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}
112113#[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}
122123#[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}
130131#[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}
138139#[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}
146147// SpecialOps (with general element)
148149#[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}
156157#[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}
166167#[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}
174175#[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}
182183#[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}
190191#[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}
198199#[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}
206207#[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}
214215#[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}
224225#[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}
232233#[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}
240241#[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}
248249// 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
255256verus! {
257258#[doc(hidden)]
259pub open spec fn nat_max(a: nat, b: nat) -> nat {
260if a > b {
261 a
262 } else {
263 b
264 }
265}
266267#[doc(hidden)]
268impl<A> Seq<A> {
269#[verifier::inline]
270pub open spec fn update_at_index(self, i: int, a: A) -> Self
271recommends
2720 <= i < self.len(),
273 {
274self.update(i, a)
275 }
276}
277278#[doc(hidden)]
279impl<K, V> Map<K, V> {
280// note that despite the name, this is allowed to insert
281#[verifier::inline]
282pub open spec fn update_at_index(self, k: K, v: V) -> Self {
283self.insert(k, v)
284 }
285}
286287#[doc(hidden)]
288#[verifier::inline]
289pub open spec fn opt_is_none<V>(a: Option<V>) -> bool {
290 a is None
291}
292293#[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}
298299#[doc(hidden)]
300#[verifier::inline]
301pub open spec fn opt_add<V>(a: Option<V>, b: Option<V>) -> Option<V> {
302if b is Some {
303 b
304 } else {
305 a
306 }
307}
308309#[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}
314315#[doc(hidden)]
316#[verifier::inline]
317pub open spec fn opt_sub<V>(a: Option<V>, b: Option<V>) -> Option<V> {
318if b is Some {
319 Option::None
320 } else {
321 a
322 }
323}
324325} // verus!