-
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
1 parent
36170d3
commit 223a22a
Showing
20 changed files
with
964 additions
and
42 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
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
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
#[allow(unused_imports)] | ||
use super::multiset::Multiset; | ||
#[allow(unused_imports)] | ||
use super::prelude::*; | ||
|
||
verus! { | ||
|
||
broadcast use super::multiset::group_multiset_axioms; | ||
|
||
impl<A> Multiset<A> { | ||
/// Is `true` if called by an "empty" multiset, i.e., a set containing no elements and has length 0 | ||
pub open spec fn is_empty(self) -> (b: bool) { | ||
self.len() == 0 | ||
} | ||
|
||
/// A singleton multiset has at least one element with multiplicity 1 and any two elements are equal. | ||
pub open spec fn is_singleton(self) -> bool { | ||
&&& self.len() > 0 | ||
&&& (forall|x: A| self.contains(x) ==> self.count(x) == 1) | ||
&&& (forall|x: A, y: A| self.contains(x) && self.contains(y) ==> x == y) | ||
} | ||
|
||
/// A singleton multiset that contains an alement is equivalent to the singleton multiset with that element. | ||
pub proof fn lemma_is_singleton_contains_elem_equal_singleton(self, x: A) | ||
requires | ||
self.is_singleton(), | ||
self.contains(x), | ||
ensures | ||
self =~= Multiset::singleton(x), | ||
{ | ||
assert forall|y: A| #[trigger] Multiset::singleton(x).count(y) == self.count(y) by { | ||
if self.contains(y) { | ||
} else { | ||
} | ||
}; | ||
} | ||
|
||
/// A singleton multiset has length 1. | ||
pub proof fn lemma_singleton_size(self) | ||
requires | ||
self.is_singleton(), | ||
ensures | ||
self.len() == 1, | ||
{ | ||
self.lemma_is_singleton_contains_elem_equal_singleton(self.choose()); | ||
} | ||
|
||
/// A multiset has exactly one element, if and only if, it has at least one element with multiplicity 1 and any two elements are equal. | ||
pub proof fn lemma_is_singleton(s: Multiset<A>) | ||
ensures | ||
s.is_singleton() <==> (s.len() == 1), | ||
{ | ||
if s.is_singleton() { | ||
s.lemma_singleton_size(); | ||
} | ||
if s.len() == 1 { | ||
assert forall|x: A, y: A| s.contains(x) && s.contains(y) implies x == y by { | ||
assert(s.remove(x).len() == 0); | ||
if x != y { | ||
assert(s.remove(x).count(y) == 0); | ||
assert(s.remove(x).insert(x) =~= s); | ||
} | ||
} | ||
} | ||
} | ||
} | ||
|
||
} // 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
#![allow(unused_variables)] | ||
|
||
use super::prelude::*; | ||
|
||
// This file implements prophecy variables. | ||
// | ||
// A prophecy variable is represented by a Prophecy<T>, and predicts some value | ||
// of type T. | ||
// | ||
// A prophecy can be allocated by calling Prophecy::<T>::alloc() in exec mode. | ||
// The result is a prophecy variable whose view is an arbitrary value of type T. | ||
// | ||
// A prophecy can be resolved by calling Prophecy::<T>::resolve() in exec mode. | ||
// This call ensures that the view of the prophecy variable is equal to the value | ||
// passed to resolve(). This call (and in particular, its argument v) must be | ||
// exec-mode to avoid circular dependency on the value of the prophecy variable. | ||
// | ||
// An informal soundness argument (following the Future-is-ours paper) is that, | ||
// for any execution of the program, there is some sequence of calls to resolve(), | ||
// whose values do not depend on spec- or proof-mode values. Those values can be | ||
// plugged into the arbitrary ghost values chosen by alloc(), for the corresponding | ||
// prophecy variables, to justify the proof accompanying the program. Since both | ||
// alloc() and resolve() are exec-mode, there is no ambiguity about which alloc() | ||
// call corresponds to a particular resolve() value. | ||
|
||
verus! { | ||
|
||
pub struct Prophecy<T> { | ||
v: Ghost<T>, | ||
} | ||
|
||
impl<T> Prophecy<T> where T: Structural { | ||
pub closed spec fn view(self) -> T { | ||
self.v@ | ||
} | ||
|
||
#[inline(always)] | ||
pub exec fn new() -> (result: Self) { | ||
Prophecy::<T> { v: Ghost(arbitrary()) } | ||
} | ||
|
||
#[inline(always)] | ||
#[verifier::external_body] | ||
pub exec fn resolve(self, v: &T) | ||
ensures | ||
self@ == v, | ||
{ | ||
} | ||
} | ||
|
||
} // 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
Oops, something went wrong.