-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Automated verus snapshot update by GitHub Actions.
- Loading branch information
Showing
12 changed files
with
715 additions
and
50 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -309,7 +309,8 @@ pub struct InvCell<T> { | |
} | ||
|
||
impl<T> InvCell<T> { | ||
pub closed spec fn wf(&self) -> bool { | ||
#[verifier::type_invariant] | ||
closed spec fn wf(&self) -> bool { | ||
&&& self[email protected]() === (self.possible_values@, self.pcell) | ||
} | ||
|
||
|
@@ -321,7 +322,7 @@ impl<T> InvCell<T> { | |
requires | ||
f(val), | ||
ensures | ||
cell.wf() && forall|v| f(v) <==> cell.inv(v), | ||
forall|v| f(v) <==> cell.inv(v), | ||
{ | ||
let (pcell, Tracked(perm)) = PCell::new(val); | ||
let ghost possible_values = Set::new(f); | ||
|
@@ -333,10 +334,13 @@ impl<T> InvCell<T> { | |
impl<T> InvCell<T> { | ||
pub fn replace(&self, val: T) -> (old_val: T) | ||
requires | ||
self.wf() && self.inv(val), | ||
self.inv(val), | ||
ensures | ||
self.inv(old_val), | ||
{ | ||
proof { | ||
use_type_invariant(self); | ||
} | ||
let r; | ||
open_local_invariant!(self.perm_inv.borrow() => perm => { | ||
r = self.pcell.replace(Tracked(&mut perm), val); | ||
|
@@ -347,11 +351,12 @@ impl<T> InvCell<T> { | |
|
||
impl<T: Copy> InvCell<T> { | ||
pub fn get(&self) -> (val: T) | ||
requires | ||
self.wf(), | ||
ensures | ||
self.inv(val), | ||
{ | ||
proof { | ||
use_type_invariant(self); | ||
} | ||
let r; | ||
open_local_invariant!(self.perm_inv.borrow() => perm => { | ||
r = *self.pcell.borrow(Tracked(&perm)); | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,228 @@ | ||
// altered from HashMap | ||
use core::marker; | ||
use std::borrow::Borrow; | ||
|
||
#[allow(unused_imports)] | ||
use super::pervasive::*; | ||
use super::prelude::*; | ||
#[allow(unused_imports)] | ||
use super::set::*; | ||
#[cfg(verus_keep_ghost)] | ||
use super::std_specs::hash::obeys_key_model; | ||
#[allow(unused_imports)] | ||
use core::hash::Hash; | ||
use std::collections::HashSet; | ||
|
||
verus! { | ||
|
||
#[verifier::ext_equal] | ||
#[verifier::reject_recursive_types(Key)] | ||
pub struct HashSetWithView<Key> where Key: View + Eq + Hash { | ||
m: HashSet<Key>, | ||
} | ||
|
||
impl<Key> View for HashSetWithView<Key> where Key: View + Eq + Hash { | ||
type V = Set<<Key as View>::V>; | ||
|
||
closed spec fn view(&self) -> Self::V; | ||
} | ||
|
||
impl<Key> HashSetWithView<Key> where Key: View + Eq + Hash { | ||
#[verifier::external_body] | ||
pub fn new() -> (result: Self) | ||
requires | ||
obeys_key_model::<Key>(), | ||
forall|k1: Key, k2: Key| k1@ == k2@ ==> k1 == k2, | ||
ensures | ||
result@ == Set::<<Key as View>::V>::empty(), | ||
{ | ||
Self { m: HashSet::new() } | ||
} | ||
|
||
#[verifier::external_body] | ||
pub fn with_capacity(capacity: usize) -> (result: Self) | ||
requires | ||
obeys_key_model::<Key>(), | ||
forall|k1: Key, k2: Key| k1@ == k2@ ==> k1 == k2, | ||
ensures | ||
result@ == Set::<<Key as View>::V>::empty(), | ||
{ | ||
Self { m: HashSet::with_capacity(capacity) } | ||
} | ||
|
||
#[verifier::external_body] | ||
pub fn reserve(&mut self, additional: usize) | ||
ensures | ||
self@ == old(self)@, | ||
{ | ||
self.m.reserve(additional); | ||
} | ||
|
||
pub open spec fn spec_len(&self) -> usize; | ||
|
||
#[verifier::external_body] | ||
#[verifier::when_used_as_spec(spec_len)] | ||
pub fn len(&self) -> (result: usize) | ||
ensures | ||
result == self@.len(), | ||
{ | ||
self.m.len() | ||
} | ||
|
||
#[verifier::external_body] | ||
pub fn insert(&mut self, k: Key) -> (result: bool) | ||
ensures | ||
self@ == old(self)@.insert(k@) && result == !old(self)@.contains(k@), | ||
{ | ||
self.m.insert(k) | ||
} | ||
|
||
#[verifier::external_body] | ||
pub fn remove(&mut self, k: &Key) -> (result: bool) | ||
ensures | ||
self@ == old(self)@.remove(k@) && result == old(self)@.contains(k@), | ||
{ | ||
self.m.remove(k) | ||
} | ||
|
||
#[verifier::external_body] | ||
pub fn contains(&self, k: &Key) -> (result: bool) | ||
ensures | ||
result == self@.contains(k@), | ||
{ | ||
self.m.contains(k) | ||
} | ||
|
||
#[verifier::external_body] | ||
pub fn get<'a>(&'a self, k: &Key) -> (result: Option<&'a Key>) | ||
ensures | ||
match result { | ||
Some(v) => self@.contains(k@) && v == &k, | ||
None => !self@.contains(k@), | ||
}, | ||
{ | ||
self.m.get(k) | ||
} | ||
|
||
#[verifier::external_body] | ||
pub fn clear(&mut self) | ||
ensures | ||
self@ == Set::<<Key as View>::V>::empty(), | ||
{ | ||
self.m.clear() | ||
} | ||
} | ||
|
||
pub broadcast proof fn axiom_hash_set_with_view_spec_len<Key>(m: &HashSetWithView<Key>) where | ||
Key: View + Eq + Hash, | ||
|
||
ensures | ||
#[trigger] m.spec_len() == [email protected](), | ||
{ | ||
admit(); | ||
} | ||
|
||
#[verifier::ext_equal] | ||
pub struct StringHashSet { | ||
m: HashSet<String>, | ||
} | ||
|
||
impl View for StringHashSet { | ||
type V = Set<Seq<char>>; | ||
|
||
closed spec fn view(&self) -> Self::V; | ||
} | ||
|
||
impl StringHashSet { | ||
#[verifier::external_body] | ||
pub fn new() -> (result: Self) | ||
ensures | ||
result@ == Set::<Seq<char>>::empty(), | ||
{ | ||
Self { m: HashSet::new() } | ||
} | ||
|
||
#[verifier::external_body] | ||
pub fn with_capacity(capacity: usize) -> (result: Self) | ||
ensures | ||
result@ == Set::<Seq<char>>::empty(), | ||
{ | ||
Self { m: HashSet::with_capacity(capacity) } | ||
} | ||
|
||
#[verifier::external_body] | ||
pub fn reserve(&mut self, additional: usize) | ||
ensures | ||
self@ == old(self)@, | ||
{ | ||
self.m.reserve(additional); | ||
} | ||
|
||
pub open spec fn spec_len(&self) -> usize; | ||
|
||
#[verifier::external_body] | ||
#[verifier::when_used_as_spec(spec_len)] | ||
pub fn len(&self) -> (result: usize) | ||
ensures | ||
result == self@.len(), | ||
{ | ||
self.m.len() | ||
} | ||
|
||
#[verifier::external_body] | ||
pub fn insert(&mut self, k: String) -> (result: bool) | ||
ensures | ||
self@ == old(self)@.insert(k@) && result == !old(self)@.contains(k@), | ||
{ | ||
self.m.insert(k) | ||
} | ||
|
||
#[verifier::external_body] | ||
pub fn remove(&mut self, k: &str) -> (result: bool) | ||
ensures | ||
self@ == old(self)@.remove(k@) && result == old(self)@.contains(k@), | ||
{ | ||
self.m.remove(k) | ||
} | ||
|
||
#[verifier::external_body] | ||
pub fn contains(&self, k: &str) -> (result: bool) | ||
ensures | ||
result == self@.contains(k@), | ||
{ | ||
self.m.contains(k) | ||
} | ||
|
||
#[verifier::external_body] | ||
pub fn get<'a>(&'a self, k: &str) -> (result: Option<&'a String>) | ||
ensures | ||
match result { | ||
Some(v) => self@.contains(k@) && v@ == k@, | ||
None => !self@.contains(k@), | ||
}, | ||
{ | ||
self.m.get(k) | ||
} | ||
|
||
#[verifier::external_body] | ||
pub fn clear(&mut self) | ||
ensures | ||
self@ == Set::<Seq<char>>::empty(), | ||
{ | ||
self.m.clear() | ||
} | ||
} | ||
|
||
pub broadcast proof fn axiom_string_hash_set_spec_len(m: &StringHashSet) | ||
ensures | ||
#[trigger] m.spec_len() == [email protected](), | ||
{ | ||
admit(); | ||
} | ||
|
||
pub broadcast group group_hash_set_axioms { | ||
axiom_hash_set_with_view_spec_len, | ||
axiom_string_hash_set_spec_len, | ||
} | ||
|
||
} // verus! |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.