Multisets #
Multisets are finite sets with duplicates allowed. They are implemented here as the quotient of lists by permutation. This gives them computational content.
Notation #
0: The empty multiset.{a}: The multiset containing a single occurrence ofa.a ::ₘ s: The multiset containing one more occurrence ofathansdoes.s + t: The multiset for which the number of occurrences of eachais the sum of the occurrences ofainsandt.s - t: The multiset for which the number of occurrences of eachais the difference of the occurrences ofainsandt.s ∪ t: The multiset for which the number of occurrences of eachais the max of the occurrences ofainsandt.s ∩ t: The multiset for which the number of occurrences of eachais the min of the occurrences ofainsandt.
Multiset α is the quotient of List α by list permutation. The result
is a type of finite sets with duplicates allowed.
Equations
- Multiset α = Quotient (List.isSetoid α)
Instances For
- Denumerable.multiset
- Multiset.canLift
- Multiset.canLiftFinset
- Multiset.collection
- Multiset.countable
- Multiset.encodable
- Multiset.inhabitedMultiset
- Multiset.instAdd
- Multiset.instAddCancelCommMonoid
- Multiset.instAddLeftMono
- Multiset.instAddLeftReflectLE
- Multiset.instCanonicallyOrderedAdd
- Multiset.instCoeList
- Multiset.instDistribLattice
- Multiset.instEmptyCollection
- Multiset.instExistsAddOfLE
- Multiset.instHasSSubset
- Multiset.instHasSubset
- Multiset.instInsert
- Multiset.instInter
- Multiset.instIsNonstrictStrictOrder
- Multiset.instLattice
- Multiset.instLawfulSingleton
- Multiset.instMembership
- Multiset.instOrderBot
- Multiset.instOrderedCancelAddCommMonoid
- Multiset.instOrderedSub
- Multiset.instPartialOrder
- Multiset.instRepr
- Multiset.instSProd
- Multiset.instSingleton
- Multiset.instSizeOf
- Multiset.instSub
- Multiset.instUnion
- Multiset.instUniqueOfIsEmpty
- Multiset.instWellFoundedLT
- Multiset.instZero
- Multiset.isWellFounded_ssubset
- Sym.hasCoe
- instConsMultiset
- instInfiniteMultisetOfNonempty
Equations
- Multiset.instCoeList = { coe := Multiset.ofList }
Equations
- Multiset.instDecidableEquivListOfDecidableEq l₁ l₂ = inferInstanceAs (Decidable (l₁.Perm l₂))
Equations
- Multiset.instDecidableRListOfDecidableEq l₁ l₂ = inferInstanceAs (Decidable (l₁.Perm l₂))
Equations
- x✝¹.decidableEq x✝ = Quotient.recOnSubsingleton₂ x✝¹ x✝ fun (x x_1 : List α) => decidable_of_iff' (x ≈ x_1) ⋯
defines a size for a multiset by referring to the size of the underlying list
Equations
- s.sizeOf = Quot.liftOn s sizeOf ⋯
Equations
- Multiset.instSizeOf = { sizeOf := Multiset.sizeOf }
Empty multiset #
0 : Multiset α is the empty set
Equations
- Multiset.zero = ↑[]
Equations
- Multiset.instZero = { zero := Multiset.zero }
Equations
- Multiset.instEmptyCollection = { emptyCollection := 0 }
Equations
- Multiset.inhabitedMultiset = { default := 0 }
Equations
- Multiset.instUniqueOfIsEmpty = { default := 0, uniq := ⋯ }
cons a s is the multiset which contains s plus one more instance of a.
Equations
- Multiset.«term_::ₘ_» = Lean.ParserDescr.trailingNode `Multiset.«term_::ₘ_» 67 68 (Lean.ParserDescr.binary `andthen (Lean.ParserDescr.symbol " ::ₘ ") (Lean.ParserDescr.cat `term 67))
Equations
- Multiset.instInsert = { insert := Multiset.cons }
Dependent recursor on multisets.
TODO: should be @[recursor 6], but then the definition of Multiset.pi fails with a stack
overflow in whnf.
Equations
- Multiset.rec C_0 C_cons C_cons_heq m = Quotient.hrecOn m (List.rec C_0 fun (a : α) (l : List α) (b : C ⟦l⟧) => C_cons a ⟦l⟧ b) ⋯
Companion to Multiset.rec with more convenient argument order.
Equations
- m.recOn C_0 C_cons C_cons_heq = Multiset.rec C_0 C_cons C_cons_heq m
a ∈ s means that a has nonzero multiplicity in s.
Equations
- s.Mem a = Quot.liftOn s (fun (l : List α) => a ∈ l) ⋯
Equations
- Multiset.instMembership = { mem := Multiset.Mem }
Equations
- Multiset.decidableMem a s = Quot.recOnSubsingleton s fun (l : List α) => inferInstanceAs (Decidable (a ∈ l))
Singleton #
Equations
- Multiset.instSingleton = { singleton := fun (a : α) => a ::ₘ 0 }
s ⊆ t is the lift of the list subset relation. It means that any
element with nonzero multiplicity in s has nonzero multiplicity in t,
but it does not imply that the multiplicity of a in s is less or equal than in t;
see s ≤ t for this relation.
Equations
- Multiset.instHasSubset = { Subset := Multiset.Subset }
Produces a list of the elements in the multiset using choice.
Equations
- s.toList = Quotient.out s
s ≤ t means that s is a sublist of t (up to permutation).
Equivalently, s ≤ t means that count a s ≤ count a t for all a.
Equations
- s.Le t = Quotient.liftOn₂ s t (fun (x1 x2 : List α) => x1.Subperm x2) ⋯
Equations
Equations
- s.decidableLE t = Quotient.recOnSubsingleton₂ s t List.decidableSubperm
Alias of Multiset.subset_of_le.
Equations
This is a rfl and simp version of bot_eq_zero.
Additive monoid #
Equations
- Multiset.instAdd = { add := Multiset.add }
Alias of the reverse direction of Multiset.add_le_add_iff_left.
Alias of the forward direction of Multiset.add_le_add_iff_left.
Alias of the forward direction of Multiset.add_le_add_iff_right.
Alias of the reverse direction of Multiset.add_le_add_iff_right.
Cardinality #
The cardinality of a multiset is the sum of the multiplicities of all its elements, or simply the length of the underlying list.
Equations
Induction principles #
Suppose that, given that p t can be defined on all supersets of s of cardinality less than
n, one knows how to define p s. Then one can inductively define p s for all multisets s of
cardinality less than n, starting from multisets of card n and iterating. This
can be used either to define data, or to prove properties.
Equations
- Multiset.strongDownwardInduction H s = H s fun {t : Multiset α} (ht : t.card ≤ n) (_h : s < t) => Multiset.strongDownwardInduction H t ht
Analogue of strongDownwardInduction with order of arguments swapped.
Equations
- s.strongDownwardInductionOn H = Multiset.strongDownwardInduction H s
Another way of expressing strongInductionOn: the (<) relation is well-founded.
replicate n a is the multiset containing only a with multiplicity n.
Equations
- Multiset.replicate n a = ↑(List.replicate n a)
Alias of the reverse direction of Multiset.eq_replicate_card.
Erasing one copy of an element #
erase s a is the multiset that subtracts 1 from the multiplicity of a.
Equations
- s.erase a = Quot.liftOn s (fun (l : List α) => ↑(l.erase a)) ⋯
Instances For
map f s is the lift of the list map operation. The multiplicity
of b in map f s is the number of a ∈ s (counting multiplicity)
such that f a = b.
Equations
- Multiset.map f s = Quot.liftOn s (fun (l : List α) => ↑(List.map f l)) ⋯
Instances For
Multiset.fold #
foldl f H b s is the lift of the list operation foldl f b l,
which folds f over the multiset. It is well defined when f is right-commutative,
that is, f (f b a₁) a₂ = f (f b a₂) a₁.
Equations
- Multiset.foldl f b s = Quot.liftOn s (fun (l : List α) => List.foldl f b l) ⋯
foldr f H b s is the lift of the list operation foldr f b l,
which folds f over the multiset. It is well defined when f is left-commutative,
that is, f a₁ (f a₂ b) = f a₂ (f a₁ b).
Equations
- Multiset.foldr f b s = Quot.liftOn s (fun (l : List α) => List.foldr f b l) ⋯
Map for partial functions #
Lift of the list pmap operation. Map a partial function f over a multiset
s whose elements are all in the domain of f.
Equations
- Multiset.pmap f s = Quot.recOn (motive := fun (x : Multiset α) => (∀ a ∈ x, p a) → Multiset β) s (fun (l : List α) (H : ∀ a ∈ Quot.mk (⇑(List.isSetoid α)) l, p a) => ↑(List.pmap f l H)) ⋯
"Attach" a proof that a ∈ s to each element a in s to produce
a multiset on {x // x ∈ s}.
Equations
- s.attach = Multiset.pmap Subtype.mk s ⋯
If p is a decidable predicate,
so is the predicate that all elements of a multiset satisfy p.
Equations
- Multiset.decidableForallMultiset = Quotient.recOnSubsingleton m fun (l : List α) => decidable_of_iff (∀ a ∈ l, p a) ⋯
Equations
- Multiset.decidableDforallMultiset = decidable_of_iff (∀ a ∈ m.attach, p ↑a ⋯) ⋯
decidable equality for functions whose domain is bounded by multisets
Equations
- Multiset.decidableEqPiMultiset f g = decidable_of_iff (∀ (a : α) (h : a ∈ m), f a h = g a h) ⋯
If p is a decidable predicate,
so is the existence of an element in a multiset satisfying p.
Equations
- Multiset.decidableExistsMultiset = Quotient.recOnSubsingleton m fun (l : List α) => decidable_of_iff (∃ a ∈ l, p a) ⋯
Equations
- Multiset.decidableDexistsMultiset = decidable_of_iff (∃ x ∈ m.attach, p ↑x ⋯) ⋯
Filter p s returns the elements in s (with the same multiplicities)
which satisfy p, and removes the rest.
Equations
- Multiset.filter p s = Quot.liftOn s (fun (l : List α) => ↑(List.filter (fun (b : α) => decide (p b)) l)) ⋯
Alias of Multiset.filter_map.
Simultaneously filter and map elements of a multiset #
filterMap f s is a combination filter/map operation on s.
The function f : α → Option β is applied to each element of s;
if f a is some b then b is added to the result, otherwise
a is removed from the resulting multiset.
Equations
- Multiset.filterMap f s = Quot.liftOn s (fun (l : List α) => ↑(List.filterMap f l)) ⋯
countP #
countP p s counts the number of elements of s (with multiplicity) that
satisfy p.
Equations
- Multiset.countP p s = Quot.liftOn s (List.countP fun (b : α) => decide (p b)) ⋯
Multiplicity of an element #
count a s is the multiplicity of a in s.
Equations
- Multiset.count a = Multiset.countP fun (x : α) => a = x
Multiset.map f preserves count if f is injective on the set of elements contained in
the multiset
Multiset.map f preserves count if f is injective
Subtraction #
Equations
- Multiset.instSub = { sub := Multiset.sub }
This is a special case of tsub_zero, which should be used instead of this.
This is needed to prove OrderedSub (Multiset α).
This is a special case of tsub_le_iff_right, which should be used instead of this.
This is needed to prove OrderedSub (Multiset α).
This is a special case of tsub_le_iff_left, which should be used instead of this.
Union #
s ∪ t is the multiset such that the multiplicity of each a in it is the maximum of the
multiplicity of a in s and t. This is the supremum of multisets.
Equations
- Multiset.instUnion = { union := Multiset.union }
Intersection #
s ∩ t is the multiset such that the multiplicity of each a in it is the minimum of the
multiplicity of a in s and t. This is the infimum of multisets.
Equations
- s.inter t = Quotient.liftOn₂ s t (fun (l₁ l₂ : List α) => ↑(l₁.bagInter l₂)) ⋯
Equations
- Multiset.instInter = { inter := Multiset.inter }
Equations
- Multiset.instLattice = Lattice.mk (fun (x1 x2 : Multiset α) => x1 ∩ x2) ⋯ ⋯ ⋯
Equations
Associate to an embedding f from α to β the order embedding that maps a multiset to its
image under f.
Equations
Mapping a multiset through a predicate and counting the Trues yields the cardinality of the set
filtered by the predicate. Note that this uses the notion of a multiset of Props - due to the
decidability requirements of count, the decidability instance on the LHS is different from the
RHS. In particular, the decidability instance on the left leaks Classical.decEq.
See here
for more discussion.
Rel r s t -- lift the relation r between two elements to a relation between s and t,
s.t. there is a one-to-one mapping between elements in s and t following r.
Disjoint multisets #
Alias of Disjoint.symm.
Alias of disjoint_comm.
Alias of Disjoint.mono_left.
Alias of Disjoint.mono_right.
Pairwise r m states that there exists a list of the elements s.t. r holds pairwise on this
list.
Equations
- Multiset.Pairwise r m = ∃ (l : List α), m = ↑l ∧ List.Pairwise r l
Given a proof hp that there exists a unique a ∈ l such that p a, chooseX p l hp returns
that a together with proofs of a ∈ l and p a.
Equations
- One or more equations did not get rendered due to their size.
Given a proof hp that there exists a unique a ∈ l such that p a, choose p l hp returns
that a.
Equations
- Multiset.choose p l hp = ↑(Multiset.chooseX p l hp)
The equivalence between lists and multisets of a subsingleton type.
Equations
- Multiset.subsingletonEquiv α = { toFun := Multiset.ofList, invFun := Quot.lift id ⋯, left_inv := ⋯, right_inv := ⋯ }