//! Helper utilities used by the `verus_state_machines_macros` codegen. #![allow(unused_imports)] #![doc(hidden)] use super::imap::*; use super::iset::*; use super::map::*; use super::pervasive::*; use super::prelude::*; use super::seq::*; use super::set::*; #[cfg_attr(verus_keep_ghost, verifier::external_body)] /* vattr */ #[cfg_attr(verus_keep_ghost, verifier::accept_recursive_types(T))] pub struct SyncSendIfSyncSend { _sync_send: super::prelude::SyncSendIfSyncSend, } #[cfg_attr(verus_keep_ghost, verifier::verus_macro)] impl Clone for SyncSendIfSyncSend { #[cfg_attr(verus_keep_ghost, verifier::external_body)] fn clone(&self) -> Self { SyncSendIfSyncSend { _sync_send: self._sync_send.clone() } } } impl Copy for SyncSendIfSyncSend {} #[cfg_attr(verus_keep_ghost, verifier::external_body)] /* vattr */ pub struct NoCopy { _no_copy: super::prelude::NoCopy, } #[cfg(verus_keep_ghost)] #[verifier::proof] pub fn assert_safety(b: bool) { requires( #[verifier::custom_err("unable to prove assertion safety condition")] /* vattr */ b, ); ensures(b); } #[cfg(verus_keep_ghost)] #[verifier::proof] pub fn assert_let_pattern(b: bool) { requires( #[verifier::custom_err("unable to prove safety condition that the pattern matches")] /* vattr */ b, ); ensures(b); } // SpecialOps #[cfg(verus_keep_ghost)] #[verifier::proof] pub fn assert_add_option(b: bool) { requires( #[verifier::custom_err( "unable to prove inherent safety condition: to add a value Some(_), field must be None before the update" )] /* vattr */ b, ); ensures(b); } #[cfg(verus_keep_ghost)] #[verifier::proof] pub fn assert_add_set(b: bool) { requires( #[verifier::custom_err( "unable to prove inherent safety condition: to add a singleton set, the value must not be in the set before the update" )] /* vattr */ b, ); ensures(b); } #[cfg(verus_keep_ghost)] #[verifier::proof] pub fn assert_add_iset(b: bool) { requires( #[verifier::custom_err( "unable to prove inherent safety condition: to add a singleton iset, the value must not be in the iset before the update" )] /* vattr */ b, ); ensures(b); } #[cfg(verus_keep_ghost)] #[verifier::proof] pub fn assert_add_bool(b: bool) { requires( #[verifier::custom_err( "unable to prove inherent safety condition: to add a value `true`, field must be `false` before the update" )] /* vattr */ b, ); ensures(b); } #[cfg(verus_keep_ghost)] #[verifier::proof] pub fn assert_add_map(b: bool) { requires( #[verifier::custom_err( "unable to prove inherent safety condition: the given key must be absent from the map before the update" )] /* vattr */ b, ); ensures(b); } #[cfg(verus_keep_ghost)] #[verifier::proof] pub fn assert_add_imap(b: bool) { requires( #[verifier::custom_err( "unable to prove inherent safety condition: the given key must be absent from the imap before the update" )] /* vattr */ b, ); ensures(b); } #[cfg(verus_keep_ghost)] #[verifier::proof] pub fn assert_add_persistent_map(b: bool) { requires( #[verifier::custom_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 */ b, ); ensures(b); } #[cfg(verus_keep_ghost)] #[verifier::proof] pub fn assert_add_persistent_imap(b: bool) { requires( #[verifier::custom_err( "unable to prove inherent safety condition: if the key is already in the imap, its existing value must agree with the provided value" )] /* vattr */ b, ); ensures(b); } #[cfg(verus_keep_ghost)] #[verifier::proof] pub fn assert_add_persistent_option(b: bool) { requires( #[verifier::custom_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 */ b, ); ensures(b); } #[cfg(verus_keep_ghost)] #[verifier::proof] pub fn assert_withdraw_option(b: bool) { requires(b); ensures(b); } #[cfg(verus_keep_ghost)] #[verifier::proof] pub fn assert_deposit_option(b: bool) { requires( #[verifier::custom_err( "unable to prove inherent safety condition: to deposit a value into Some(_), the field must be None before the deposit" )] /* vattr */ b, ); ensures(b); } #[cfg(verus_keep_ghost)] #[verifier::proof] pub fn assert_guard_option(b: bool) { requires( #[verifier::custom_err( "unable to prove inherent safety condition: the value being guarded must be stored" )] /* vattr */ b, ); ensures(b); } #[cfg(verus_keep_ghost)] #[verifier::proof] pub fn assert_withdraw_map(b: bool) { requires( #[verifier::custom_err( "unable to prove inherent safety condition: the value to be withdrawn must be stored at the given key before the withdraw" )] /* vattr */ b, ); ensures(b); } #[cfg(verus_keep_ghost)] #[verifier::proof] pub fn assert_withdraw_imap(b: bool) { requires( #[verifier::custom_err( "unable to prove inherent safety condition: the value to be withdrawn must be stored at the given key before the withdraw" )] /* vattr */ b, ); ensures(b); } #[cfg(verus_keep_ghost)] #[verifier::proof] pub fn assert_deposit_map(b: bool) { requires( #[verifier::custom_err( "unable to prove inherent safety condition: the given key must be absent from the map before the deposit" )] /* vattr */ b, ); ensures(b); } #[cfg(verus_keep_ghost)] #[verifier::proof] pub fn assert_deposit_imap(b: bool) { requires( #[verifier::custom_err( "unable to prove inherent safety condition: the given key must be absent from the imap before the deposit" )] /* vattr */ b, ); ensures(b); } #[cfg(verus_keep_ghost)] #[verifier::proof] pub fn assert_guard_map(b: bool) { requires( #[verifier::custom_err( "unable to prove inherent safety condition: the value being guarded must be stored at the given key" )] /* vattr */ b, ); ensures(b); } #[cfg(verus_keep_ghost)] #[verifier::proof] pub fn assert_guard_imap(b: bool) { requires( #[verifier::custom_err( "unable to prove inherent safety condition: the value being guarded must be stored at the given key" )] /* vattr */ b, ); ensures(b); } // SpecialOps (with general element) #[cfg(verus_keep_ghost)] #[verifier::proof] pub fn assert_general_add_option(b: bool) { requires( #[verifier::custom_err( "unable to prove inherent safety condition: the optional values being composed cannot both be Some(_)" )] /* vattr */ b, ); ensures(b); } #[cfg(verus_keep_ghost)] #[verifier::proof] pub fn assert_general_add_set(b: bool) { requires( #[verifier::custom_err( "unable to prove inherent safety condition: the sets being composed must be disjoint" )] /* vattr */ b, ); ensures(b); } #[cfg(verus_keep_ghost)] #[verifier::proof] pub fn assert_general_add_iset(b: bool) { requires( #[verifier::custom_err( "unable to prove inherent safety condition: the isets being composed must be disjoint" )] /* vattr */ b, ); ensures(b); } #[cfg(verus_keep_ghost)] #[verifier::proof] pub fn assert_general_add_bool(b: bool) { requires( #[verifier::custom_err( "unable to prove inherent safety condition: the boolean values being composed cannot both be `true`" )] /* vattr */ b, ); ensures(b); } #[cfg(verus_keep_ghost)] #[verifier::proof] pub fn assert_general_add_map(b: bool) { requires( #[verifier::custom_err( "unable to prove inherent safety condition: the key domains of the maps being composed must be disjoint" )] /* vattr */ b, ); ensures(b); } #[cfg(verus_keep_ghost)] #[verifier::proof] pub fn assert_general_add_imap(b: bool) { requires( #[verifier::custom_err( "unable to prove inherent safety condition: the key domains of the imaps being composed must be disjoint" )] /* vattr */ b, ); ensures(b); } #[cfg(verus_keep_ghost)] #[verifier::proof] pub fn assert_general_add_persistent_map(b: bool) { requires( #[verifier::custom_err( "unable to prove inherent safety condition: the maps being composed must agree on their values for any key in both domains" )] /* vattr */ b, ); ensures(b); } #[cfg(verus_keep_ghost)] #[verifier::proof] pub fn assert_general_add_persistent_imap(b: bool) { requires( #[verifier::custom_err( "unable to prove inherent safety condition: the imaps being composed must agree on their values for any key in both domains" )] /* vattr */ b, ); ensures(b); } #[cfg(verus_keep_ghost)] #[verifier::proof] pub fn assert_general_add_persistent_option(b: bool) { requires( #[verifier::custom_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 */ b, ); ensures(b); } #[cfg(verus_keep_ghost)] #[verifier::proof] pub fn assert_general_withdraw_option(b: bool) { requires( #[verifier::custom_err( "unable to prove inherent safety condition: the optional value to be withdrawn must be stored before the withdraw" )] /* vattr */ b, ); ensures(b); } #[cfg(verus_keep_ghost)] #[verifier::proof] pub fn assert_general_deposit_option(b: bool) { requires( #[verifier::custom_err( "unable to prove inherent safety condition: the optional values being composed cannot both be Some(_)" )] /* vattr */ b, ); ensures(b); } #[cfg(verus_keep_ghost)] #[verifier::proof] pub fn assert_general_guard_option(b: bool) { requires( #[verifier::custom_err( "unable to prove inherent safety condition: the value being guarded must be stored" )] /* vattr */ b, ); ensures(b); } #[cfg(verus_keep_ghost)] #[verifier::proof] pub fn assert_general_withdraw_map(b: bool) { requires( #[verifier::custom_err( "unable to prove inherent safety condition: the map being withdrawn must be a submap of the stored map" )] /* vattr */ b, ); ensures(b); } #[cfg(verus_keep_ghost)] #[verifier::proof] pub fn assert_general_withdraw_imap(b: bool) { requires( #[verifier::custom_err( "unable to prove inherent safety condition: the imap being withdrawn must be a submap of the stored imap" )] /* vattr */ b, ); ensures(b); } #[cfg(verus_keep_ghost)] #[verifier::proof] pub fn assert_general_deposit_map(b: bool) { requires( #[verifier::custom_err( "unable to prove inherent safety condition: the key domains of the maps being composed must be disjoint" )] /* vattr */ b, ); ensures(b); } #[cfg(verus_keep_ghost)] #[verifier::proof] pub fn assert_general_deposit_imap(b: bool) { requires( #[verifier::custom_err( "unable to prove inherent safety condition: the key domains of the imaps being composed must be disjoint" )] /* vattr */ b, ); ensures(b); } #[cfg(verus_keep_ghost)] #[verifier::proof] pub fn assert_general_guard_map(b: bool) { requires( #[verifier::custom_err( "unable to prove inherent safety condition: the map being guarded must be a submap of the stored map" )] /* vattr */ b, ); ensures(b); } #[cfg(verus_keep_ghost)] #[verifier::proof] pub fn assert_general_guard_imap(b: bool) { requires( #[verifier::custom_err( "unable to prove inherent safety condition: the imap being guarded must be a submap of the stored imap" )] /* vattr */ 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 Seq { #[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 Map { // 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)] impl IMap { // 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(a: Option) -> bool { a is None } #[doc(hidden)] #[verifier::inline] pub open spec fn opt_ge(a: Option, b: Option) -> bool { b is Some ==> a == b } #[doc(hidden)] #[verifier::inline] pub open spec fn opt_add(a: Option, b: Option) -> Option { if b is Some { b } else { a } } #[doc(hidden)] #[verifier::inline] pub open spec fn opt_agree(a: Option, b: Option) -> bool { a is Some && b is Some ==> a->0 == b->0 } #[doc(hidden)] #[verifier::inline] pub open spec fn opt_sub(a: Option, b: Option) -> Option { if b is Some { Option::None } else { a } } } // verus!