pub struct Multiset<V> { /* private fields */ }Expand description
Multiset<V> is an abstract multiset type for specifications.
Multiset<V> can be encoded as a (total) map from elements to natural numbers,
where the number of nonzero entries is finite.
Multisets can be constructed in a few different ways:
Multiset::empty()constructs an empty multiset.Multiset::singletonconstructs a multiset that contains a single element with multiplicity 1.- [
Multiset::new] constructs a multiset from a map of elements to multiplicities. - By manipulating existings multisets with
Multiset::add,Multiset::insert,Multiset::sub,Multiset::remove,Multiset::update, orMultiset::filter. - TODO:
multiset!constructor macro, multiset from set, from map, etc.
To prove that two multisets are equal, it is usually easiest to use the
extensionality operator =~=.
Implementations§
Source§impl<V> Multiset<V>
impl<V> Multiset<V>
Sourcepub uninterp fn count(self, value: V) -> nat
pub uninterp fn count(self, value: V) -> nat
Returns the count, or multiplicity of a single value within the multiset.
Sourcepub uninterp fn len(self) -> nat
pub uninterp fn len(self) -> nat
The total size of the multiset, i.e., the sum of all multiplicities over all values.
Sourcepub uninterp fn from_map(m: Map<V, nat>) -> Self
pub uninterp fn from_map(m: Map<V, nat>) -> Self
Creates a multiset whose elements are given by the domain of the map m and whose
multiplicities are given by the corresponding values of m[element]. The map m
must be finite, or else this multiset is arbitrary.
Sourcepub open spec fn from_set(m: Set<V>) -> Self
pub open spec fn from_set(m: Set<V>) -> Self
{ Self::from_map(Map::new(|k| m.contains(k), |v| 1)) }Sourcepub uninterp fn singleton(v: V) -> Self
pub uninterp fn singleton(v: V) -> Self
A singleton multiset, i.e., a multiset with a single element of multiplicity 1.
Sourcepub uninterp fn add(self, m2: Self) -> Self
pub uninterp fn add(self, m2: Self) -> Self
Takes the union of two multisets. For a given element, its multiplicity in the resulting multiset is the sum of its multiplicities in the operands.
Sourcepub uninterp fn sub(self, m2: Self) -> Self
pub uninterp fn sub(self, m2: Self) -> Self
Takes the difference of two multisets.
The multiplicities of m2 are subtracted from those of self; if any element
occurs more in m2 then the resulting multiplicity bottoms out at 0.
(See axiom_multiset_sub for the precise definition.)
Note in particular that self == self.sub(m).add(m) only holds if
m is included in self.
Sourcepub open spec fn insert(self, v: V) -> Self
pub open spec fn insert(self, v: V) -> Self
{ self.add(Self::singleton(v)) }Inserts one instance the value v into the multiset.
This always increases the total size of the multiset by 1.
Sourcepub open spec fn remove(self, v: V) -> Self
pub open spec fn remove(self, v: V) -> Self
{ self.sub(Self::singleton(v)) }Removes one instance of the value v from the multiset.
If v was absent from the multiset, then the multiset is unchanged.
Sourcepub open spec fn update(self, v: V, mult: nat) -> Self
pub open spec fn update(self, v: V, mult: nat) -> Self
{
let map = Map::new(
|key: V| (self.contains(key) || key == v),
|key: V| if key == v { mult } else { self.count(key) },
);
Self::from_map(map)
}Updates the multiplicity of the value v in the multiset to mult.
Sourcepub open spec fn subset_of(self, m2: Self) -> bool
pub open spec fn subset_of(self, m2: Self) -> bool
{ forall |v: V| self.count(v) <= m2.count(v) }Returns true is the left argument is contained in the right argument,
that is, if for each value v, the number of occurences in the left
is at most the number of occurences in the right.
Sourcepub open spec fn choose(self) -> V
pub open spec fn choose(self) -> V
{ choose |v: V| self.count(v) > 0 }Chooses an arbitrary value of the multiset.
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.)
Sourcepub open spec fn contains(self, v: V) -> bool
pub open spec fn contains(self, v: V) -> bool
{ self.count(v) > 0 }Predicate indicating if the multiset contains the given value.
Sourcepub open spec fn spec_has(self, v: V) -> bool
pub open spec fn spec_has(self, v: V) -> bool
{ self.contains(v) }Predicate indicating if the set contains the given element: supports self has a syntax.
Sourcepub open spec fn intersection_with(self, other: Self) -> Self
pub open spec fn intersection_with(self, other: Self) -> Self
{
let m = Map::<
V,
nat,
>::new(
|v: V| self.contains(v),
|v: V| min(self.count(v) as int, other.count(v) as int) as nat,
);
Self::from_map(m)
}Returns a multiset containing the lower count of a given element between the two sets. In other words, returns a multiset with only the elements that “overlap”.
Sourcepub open spec fn difference_with(self, other: Self) -> Self
pub open spec fn difference_with(self, other: Self) -> Self
{
let m = Map::<
V,
nat,
>::new(|v: V| self.contains(v), |v: V| clip(self.count(v) - other.count(v)));
Self::from_map(m)
}Returns a multiset containing the difference between the count of a given element of the two sets.
Sourcepub open spec fn is_disjoint_from(self, other: Self) -> bool
pub open spec fn is_disjoint_from(self, other: Self) -> bool
{ forall |x: V| self.count(x) == 0 || other.count(x) == 0 }Returns true if there exist no elements that have a count greater than 0 in both multisets. In other words, returns true if the two multisets have no elements in common.
Source§impl<A> Multiset<A>
impl<A> Multiset<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” multiset, i.e., a set containing no elements and has length 0
Sourcepub open spec fn is_singleton(self) -> bool
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 has at least one element with multiplicity 1 and any two elements are equal.
Sourcepub proof fn lemma_is_singleton_contains_elem_equal_singleton(self, x: A)
pub proof fn lemma_is_singleton_contains_elem_equal_singleton(self, x: A)
self.is_singleton(),self.contains(x),ensuresself =~= Multiset::singleton(x),A singleton multiset that contains an alement is equivalent to the singleton multiset with that element.
Sourcepub proof fn lemma_singleton_size(self)
pub proof fn lemma_singleton_size(self)
self.is_singleton(),ensuresself.len() == 1,A singleton multiset has length 1.
Sourcepub proof fn lemma_is_singleton(s: Multiset<A>)
pub proof fn lemma_is_singleton(s: Multiset<A>)
s.is_singleton() <==> (s.len() == 1),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.