Struct vstd::multiset::Multiset

source ·
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:

To prove that two multisets are equal, it is usually easiest to use the extensionality operator =~=.

Implementations§

source§

impl<V> Multiset<V>

source

pub spec fn count(self, value: V) -> nat

Returns the count, or multiplicity of a single value within the multiset.

source

pub spec fn len(self) -> nat

The total size of the multiset, i.e., the sum of all multiplicities over all values.

source

pub spec fn empty() -> Self

An empty multiset.

source

pub open spec 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.

source

pub open spec fn new(m: Map<V, nat>) -> Self

👎Deprecated: use from_map instead
{ Self::from_map(m) }
source

pub open spec fn from_set(m: Set<V>) -> Self

{ Self::from_map(Map::new(|k| m.contains(k), |v| 1)) }
source

pub spec fn singleton(v: V) -> Self

A singleton multiset, i.e., a multiset with a single element of multiplicity 1.

source

pub spec 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.

source

pub spec 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.

source

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.

source

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.

source

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.

source

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.

source

pub open spec fn le(self, m2: Self) -> bool

👎Deprecated: use m1.subset_of(m2) or m1 <= m2 instead
{ self.subset_of(m2) }
source

pub open spec fn spec_le(self, m2: Self) -> bool

{ self.subset_of(m2) }
source

pub open spec fn ext_equal(self, m2: Self) -> bool

👎Deprecated: use =~= or =~~= instead
{ self =~= m2 }

DEPRECATED: use =~= or =~~= instead. Returns true if the two multisets are pointwise equal, i.e., for every value v: V, the counts are the same in each multiset. This is equivalent to the multisets actually being equal by axiom_multiset_ext_equal.

To prove that two maps are equal via extensionality, it may be easier to use the general-purpose =~= or =~~= or to use the assert_multisets_equal! macro, rather than using ext_equal directly.

source

pub spec fn filter(self, f: impl Fn(V) -> bool) -> Self

source

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.)

source

pub open spec fn contains(self, v: V) -> bool

{ self.count(v) > 0 }

Predicate indicating if the multiset contains the given value.

source

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.

source

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”.

source

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.

source

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

pub open spec fn dom(self) -> Set<V>

{ Set::new(|v: V| self.count(v) > 0) }

Returns the set of all elements that have a count greater than 0

source§

impl<A> Multiset<A>

source

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

source

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.

source

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),

A singleton multiset that contains an alement is equivalent to the singleton multiset with that element.

source

pub proof fn lemma_singleton_size(self)

requires
self.is_singleton(),
ensures
self.len() == 1,

A singleton multiset has length 1.

source

pub proof fn lemma_is_singleton(s: Multiset<A>)

ensures
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.

Auto Trait Implementations§

§

impl<V> Freeze for Multiset<V>

§

impl<V> RefUnwindSafe for Multiset<V>
where V: RefUnwindSafe,

§

impl<V> Send for Multiset<V>
where V: Send,

§

impl<V> Sync for Multiset<V>
where V: Sync,

§

impl<V> Unpin for Multiset<V>
where V: Unpin,

§

impl<V> UnwindSafe for Multiset<V>
where V: UnwindSafe,

Blanket Implementations§

source§

impl<T> Any for T
where T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

source§

impl<T, U> Into<U> for T
where U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.