pub struct Set<A> { /* private fields */ }Expand description
Set<A> is a set type for specifications.
An object set: Set<A> is a subset of the set of all values a: A.
Equivalently, it can be thought of as a boolean predicate on A.
In general, a set might be infinite.
To work specifically with finite sets, see the self.finite() predicate.
Sets can be constructed in a few different ways:
Set::emptygives an empty setSet::fullgives the set of all elements inASet::newconstructs a set from a boolean predicate- The
set!macro, to construct small sets of a fixed size - By manipulating an existing sequence with
Set::union,Set::intersect,Set::difference,Set::complement,Set::filter,Set::insert, orSet::remove.
To prove that two sequences are equal, it is usually easiest to use the extensionality
operator =~=.
Implementations§
source§impl<A> Set<A>
impl<A> Set<A>
sourcepub spec fn new<F: Fn(A) -> bool>(f: F) -> Set<A>
pub spec fn new<F: Fn(A) -> bool>(f: F) -> Set<A>
Set whose membership is determined by the given boolean predicate.
sourcepub open spec fn full() -> Set<A>
pub open spec fn full() -> Set<A>
{ Set::empty().complement() }The “full” set, i.e., set containing every element of type A.
sourcepub spec fn contains(self, a: A) -> bool
pub spec fn contains(self, a: A) -> bool
Predicate indicating if the set contains the given element.
sourcepub open spec fn spec_has(self, a: A) -> bool
pub open spec fn spec_has(self, a: A) -> bool
{ self.contains(a) }Predicate indicating if the set contains the given element: supports self has a syntax.
sourcepub open spec fn ext_equal(self, s2: Set<A>) -> bool
👎Deprecated: use =~= or =~~= instead
pub open spec fn ext_equal(self, s2: Set<A>) -> bool
{ self =~= s2 }DEPRECATED: use =~= or =~~= instead.
Returns true if for every value a: A, it is either in both input sets or neither.
This is equivalent to the sets being actually equal
by axiom_set_ext_equal.
To prove that two sets are equal via extensionality, it may be easier
to use the general-purpose =~= or =~~= or
to use the assert_sets_equal! macro,
rather than using .ext_equal directly.
sourcepub open spec fn subset_of(self, s2: Set<A>) -> bool
pub open spec fn subset_of(self, s2: Set<A>) -> bool
{ forall |a: A| self.contains(a) ==> s2.contains(a) }Returns true if the first argument is a subset of the second.
sourcepub spec fn insert(self, a: A) -> Set<A>
pub spec fn insert(self, a: A) -> Set<A>
Returns a new set with the given element inserted. If that element is already in the set, then an identical set is returned.
sourcepub spec fn remove(self, a: A) -> Set<A>
pub spec fn remove(self, a: A) -> Set<A>
Returns a new set with the given element removed. If that element is already absent from the set, then an identical set is returned.
sourcepub open spec fn spec_add(self, s2: Set<A>) -> Set<A>
pub open spec fn spec_add(self, s2: Set<A>) -> Set<A>
{ self.union(s2) }+ operator, synonymous with union
sourcepub open spec fn spec_mul(self, s2: Set<A>) -> Set<A>
pub open spec fn spec_mul(self, s2: Set<A>) -> Set<A>
{ self.intersect(s2) }* operator, synonymous with intersect
sourcepub spec fn difference(self, s2: Set<A>) -> Set<A>
pub spec fn difference(self, s2: Set<A>) -> Set<A>
Set difference, i.e., the set of all elements in the first one but not in the second.
sourcepub open spec fn spec_sub(self, s2: Set<A>) -> Set<A>
pub open spec fn spec_sub(self, s2: Set<A>) -> Set<A>
{ self.difference(s2) }Set complement (within the space of all possible elements in A).
- operator, synonymous with difference
sourcepub spec fn complement(self) -> Set<A>
pub spec fn complement(self) -> Set<A>
sourcepub open spec fn filter<F: Fn(A) -> bool>(self, f: F) -> Set<A>
pub open spec fn filter<F: Fn(A) -> bool>(self, f: F) -> Set<A>
{ self.intersect(Self::new(f)) }Set of all elements in the given set which satisfy the predicate f.
sourcepub open spec fn choose(self) -> A
pub open spec fn choose(self) -> A
{ choose |a: A| self.contains(a) }Chooses an arbitrary element of the set.
This is often useful for proofs by induction.
(Note that, although the result is arbitrary, it is still a deterministic function
like any other spec function.)
source§impl<A> Set<A>
impl<A> Set<A>
sourcepub open spec fn is_full(self) -> bool
pub open spec fn is_full(self) -> bool
{ self == Set::<A>::full() }Is true if called by a “full” set, i.e., a set containing every element of type A.
sourcepub open spec fn is_empty(self) -> b : bool
pub open spec fn is_empty(self) -> b : bool
{ self.len() == 0 }Is true if called by an “empty” set, i.e., a set containing no elements and has length 0
sourcepub open spec fn map<B>(self, f: FnSpec<(A,), B>) -> Set<B>
pub open spec fn map<B>(self, f: FnSpec<(A,), B>) -> Set<B>
{ Set::new(|a: B| exists |x: A| self.contains(x) && a == f(x)) }Returns the set contains an element f(x) for every element x in self.
sourcepub open spec fn fold<E>(self, init: E, f: FnSpec<(E, A), E>) -> E
pub open spec fn fold<E>(self, init: E, f: FnSpec<(E, A), E>) -> E
{
if self.finite() {
if self.len() == 0 {
init
} else {
let a = self.choose();
self.remove(a).fold(f(init, a), f)
}
} else {
arbitrary()
}
}Folds the set, applying f to perform the fold. The next element for the fold is chosen by
the choose operator.
Given a set s = {x0, x1, x2, ..., xn}, applying this function s.fold(init, f)
returns f(...f(f(init, x0), x1), ..., xn).
sourcepub open spec fn to_seq(self) -> Seq<A>
pub open spec fn to_seq(self) -> Seq<A>
self.finite(),{
if self.len() == 0 {
Seq::<A>::empty()
} else {
let x = self.choose();
Seq::<A>::empty().push(x) + self.remove(x).to_seq()
}
}Converts a set into a sequence with an arbitrary ordering.
sourcepub open spec fn to_sorted_seq(self, leq: FnSpec<(A, A), bool>) -> Seq<A>
pub open spec fn to_sorted_seq(self, leq: FnSpec<(A, A), bool>) -> Seq<A>
{ self.to_seq().sort_by(leq) }Converts a set into a sequence sorted by the given ordering function leq
sourcepub open spec fn is_singleton(self) -> bool
pub open spec fn is_singleton(self) -> bool
{
&&& self.len() > 0
&&& (forall |x: A, y: A| self.contains(x) && self.contains(y) ==> x == y)
}A singleton set has at least one element and any two elements are equal.
sourcepub closed spec fn find_unique_minimal(self, r: FnSpec<(A, A), bool>) -> A
pub closed spec fn find_unique_minimal(self, r: FnSpec<(A, A), bool>) -> A
total_ordering(r),self.len() > 0,self.finite(),Any totally-ordered set contains a unique minimal (equivalently, least) element. Returns an arbitrary value if r is not a total ordering
sourcepub proof fn find_unique_minimal_ensures(self, r: FnSpec<(A, A), bool>)
pub proof fn find_unique_minimal_ensures(self, r: FnSpec<(A, A), bool>)
self.finite(),self.len() > 0,total_ordering(r),ensuresis_minimal(r, self.find_unique_minimal(r), self)
&& (forall |min: A| is_minimal(r, min, self) ==> self.find_unique_minimal(r) == min),Proof of correctness and expected behavior for Set::find_unique_minimal.
sourcepub closed spec fn find_unique_maximal(self, r: FnSpec<(A, A), bool>) -> A
pub closed spec fn find_unique_maximal(self, r: FnSpec<(A, A), bool>) -> A
total_ordering(r),self.len() > 0,Any totally-ordered set contains a unique maximal (equivalently, greatest) element. Returns an arbitrary value if r is not a total ordering
sourcepub proof fn find_unique_maximal_ensures(self, r: FnSpec<(A, A), bool>)
pub proof fn find_unique_maximal_ensures(self, r: FnSpec<(A, A), bool>)
self.finite(),self.len() > 0,total_ordering(r),ensuresis_maximal(r, self.find_unique_maximal(r), self)
&& (forall |max: A| is_maximal(r, max, self) ==> self.find_unique_maximal(r) == max),Proof of correctness and expected behavior for Set::find_unique_maximal.
sourcepub open spec fn to_multiset(self) -> Multiset<A>
pub open spec fn to_multiset(self) -> Multiset<A>
{
if self.len() == 0 {
Multiset::<A>::empty()
} else {
Multiset::<A>::empty()
.insert(self.choose())
.add(self.remove(self.choose()).to_multiset())
}
}Converts a set into a multiset where each element from the set has multiplicity 1 and any other element has multiplicity 0.
sourcepub proof fn lemma_len0_is_empty(self)
pub proof fn lemma_len0_is_empty(self)
self.finite(),self.len() == 0,ensuresself == Set::<A>::empty(),A finite set with length 0 is equivalent to the empty set.
sourcepub proof fn lemma_singleton_size(self)
pub proof fn lemma_singleton_size(self)
self.is_singleton(),ensuresself.len() == 1,A singleton set has length 1.
sourcepub proof fn lemma_is_singleton(s: Set<A>)
pub proof fn lemma_is_singleton(s: Set<A>)
s.finite(),ensuress.is_singleton() == (s.len() == 1),A set has exactly one element, if and only if, it has at least one element and any two elements are equal.
sourcepub proof fn lemma_len_filter(self, f: FnSpec<(A,), bool>)
pub proof fn lemma_len_filter(self, f: FnSpec<(A,), bool>)
self.finite(),ensuresself.filter(f).finite(),self.filter(f).len() <= self.len(),The result of filtering a finite set is finite and has size less than or equal to the original set.
sourcepub proof fn lemma_greatest_implies_maximal(self, r: FnSpec<(A, A), bool>, max: A)
pub proof fn lemma_greatest_implies_maximal(self, r: FnSpec<(A, A), bool>, max: A)
pre_ordering(r),ensuresis_greatest(r, max, self) ==> is_maximal(r, max, self),In a pre-ordered set, a greatest element is necessarily maximal.
sourcepub proof fn lemma_least_implies_minimal(self, r: FnSpec<(A, A), bool>, min: A)
pub proof fn lemma_least_implies_minimal(self, r: FnSpec<(A, A), bool>, min: A)
pre_ordering(r),ensuresis_least(r, min, self) ==> is_minimal(r, min, self),In a pre-ordered set, a least element is necessarily minimal.
sourcepub proof fn lemma_maximal_equivalent_greatest(self, r: FnSpec<(A, A), bool>, max: A)
pub proof fn lemma_maximal_equivalent_greatest(self, r: FnSpec<(A, A), bool>, max: A)
total_ordering(r),ensuresis_greatest(r, max, self) <==> is_maximal(r, max, self),In a totally-ordered set, an element is maximal if and only if it is a greatest element.
sourcepub proof fn lemma_minimal_equivalent_least(self, r: FnSpec<(A, A), bool>, min: A)
pub proof fn lemma_minimal_equivalent_least(self, r: FnSpec<(A, A), bool>, min: A)
total_ordering(r),ensuresis_least(r, min, self) <==> is_minimal(r, min, self),In a totally-ordered set, an element is maximal if and only if it is a greatest element.
sourcepub proof fn lemma_least_is_unique(self, r: FnSpec<(A, A), bool>)
pub proof fn lemma_least_is_unique(self, r: FnSpec<(A, A), bool>)
partial_ordering(r),ensuresforall |min: A, min_prime: A| {
is_least(r, min, self) && is_least(r, min_prime, self) ==> min == min_prime
},In a partially-ordered set, there exists at most one least element.
sourcepub proof fn lemma_greatest_is_unique(self, r: FnSpec<(A, A), bool>)
pub proof fn lemma_greatest_is_unique(self, r: FnSpec<(A, A), bool>)
partial_ordering(r),ensuresforall |max: A, max_prime: A| {
is_greatest(r, max, self) && is_greatest(r, max_prime, self) ==> max == max_prime
},In a partially-ordered set, there exists at most one greatest element.
sourcepub proof fn lemma_minimal_is_unique(self, r: FnSpec<(A, A), bool>)
pub proof fn lemma_minimal_is_unique(self, r: FnSpec<(A, A), bool>)
total_ordering(r),ensuresforall |min: A, min_prime: A| {
is_minimal(r, min, self) && is_minimal(r, min_prime, self) ==> min == min_prime
},In a totally-ordered set, there exists at most one minimal element.
sourcepub proof fn lemma_maximal_is_unique(self, r: FnSpec<(A, A), bool>)
pub proof fn lemma_maximal_is_unique(self, r: FnSpec<(A, A), bool>)
self.finite(),total_ordering(r),ensuresforall |max: A, max_prime: A| {
is_maximal(r, max, self) && is_maximal(r, max_prime, self) ==> max == max_prime
},In a totally-ordered set, there exists at most one maximal element.