Module docstring
{"# Basic results on multisets
","### Multiset.toList ","### Induction principles "}
{"# Basic results on multisets
","### Multiset.toList ","### Induction principles "}
Multiset.toList
definition
(s : Multiset α)
Multiset.coe_toList
theorem
(s : Multiset α) : (s.toList : Multiset α) = s
@[simp, norm_cast]
theorem coe_toList (s : Multiset α) : (s.toList : Multiset α) = s :=
s.out_eq'
Multiset.toList_eq_nil
theorem
{s : Multiset α} : s.toList = [] ↔ s = 0
@[simp]
theorem toList_eq_nil {s : Multiset α} : s.toList = [] ↔ s = 0 := by
rw [← coe_eq_zero, coe_toList]
Multiset.empty_toList
theorem
{s : Multiset α} : s.toList.isEmpty ↔ s = 0
theorem empty_toList {s : Multiset α} : s.toList.isEmpty ↔ s = 0 := by simp
Multiset.toList_zero
theorem
: (Multiset.toList 0 : List α) = []
@[simp]
theorem toList_zero : (Multiset.toList 0 : List α) = [] :=
toList_eq_nil.mpr rfl
Multiset.mem_toList
theorem
{a : α} {s : Multiset α} : a ∈ s.toList ↔ a ∈ s
@[simp]
theorem mem_toList {a : α} {s : Multiset α} : a ∈ s.toLista ∈ s.toList ↔ a ∈ s := by
rw [← mem_coe, coe_toList]
Multiset.toList_eq_singleton_iff
theorem
{a : α} {m : Multiset α} : m.toList = [a] ↔ m = { a }
@[simp]
theorem toList_eq_singleton_iff {a : α} {m : Multiset α} : m.toList = [a] ↔ m = {a} := by
rw [← perm_singleton, ← coe_eq_coe, coe_toList, coe_singleton]
Multiset.toList_singleton
theorem
(a : α) : ({ a } : Multiset α).toList = [a]
@[simp]
theorem toList_singleton (a : α) : ({a} : Multiset α).toList = [a] :=
Multiset.toList_eq_singleton_iff.2 rfl
Multiset.length_toList
theorem
(s : Multiset α) : s.toList.length = card s
@[simp]
theorem length_toList (s : Multiset α) : s.toList.length = card s := by
rw [← coe_card, coe_toList]
Multiset.strongInductionOn
definition
{p : Multiset α → Sort*} (s : Multiset α) (ih : ∀ s, (∀ t < s, p t) → p s) : p s
/-- The strong induction principle for multisets. -/
@[elab_as_elim]
def strongInductionOn {p : Multiset α → Sort*} (s : Multiset α) (ih : ∀ s, (∀ t < s, p t) → p s) :
p s :=
(ih s) fun t _h =>
strongInductionOn t ih
termination_by card s
decreasing_by exact card_lt_card _h
Multiset.strongInductionOn_eq
theorem
{p : Multiset α → Sort*} (s : Multiset α) (H) : @strongInductionOn _ p s H = H s fun t _h => @strongInductionOn _ p t H
theorem strongInductionOn_eq {p : Multiset α → Sort*} (s : Multiset α) (H) :
@strongInductionOn _ p s H = H s fun t _h => @strongInductionOn _ p t H := by
rw [strongInductionOn]
Multiset.case_strongInductionOn
theorem
{p : Multiset α → Prop} (s : Multiset α) (h₀ : p 0) (h₁ : ∀ a s, (∀ t ≤ s, p t) → p (a ::ₘ s)) : p s
@[elab_as_elim]
theorem case_strongInductionOn {p : Multiset α → Prop} (s : Multiset α) (h₀ : p 0)
(h₁ : ∀ a s, (∀ t ≤ s, p t) → p (a ::ₘ s)) : p s :=
Multiset.strongInductionOn s fun s =>
Multiset.induction_on s (fun _ => h₀) fun _a _s _ ih =>
(h₁ _ _) fun _t h => ih _ <| lt_of_le_of_lt h <| lt_cons_self _ _
Multiset.strongDownwardInduction
definition
{p : Multiset α → Sort*} {n : ℕ} (H : ∀ t₁, (∀ {t₂ : Multiset α}, card t₂ ≤ n → t₁ < t₂ → p t₂) → card t₁ ≤ n → p t₁)
(s : Multiset α) : card s ≤ n → p s
/-- 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. -/
def strongDownwardInduction {p : Multiset α → Sort*} {n : ℕ}
(H : ∀ t₁, (∀ {t₂ : Multiset α}, card t₂ ≤ n → t₁ < t₂ → p t₂) → card t₁ ≤ n → p t₁)
(s : Multiset α) :
card s ≤ n → p s :=
H s fun {t} ht _h =>
strongDownwardInduction H t ht
termination_by n - card s
decreasing_by simp_wf; have := (card_lt_card _h); omega
Multiset.strongDownwardInduction_eq
theorem
{p : Multiset α → Sort*} {n : ℕ} (H : ∀ t₁, (∀ {t₂ : Multiset α}, card t₂ ≤ n → t₁ < t₂ → p t₂) → card t₁ ≤ n → p t₁)
(s : Multiset α) : strongDownwardInduction H s = H s fun ht _hst => strongDownwardInduction H _ ht
theorem strongDownwardInduction_eq {p : Multiset α → Sort*} {n : ℕ}
(H : ∀ t₁, (∀ {t₂ : Multiset α}, card t₂ ≤ n → t₁ < t₂ → p t₂) → card t₁ ≤ n → p t₁)
(s : Multiset α) :
strongDownwardInduction H s = H s fun ht _hst => strongDownwardInduction H _ ht := by
rw [strongDownwardInduction]
Multiset.strongDownwardInductionOn
definition
{p : Multiset α → Sort*} {n : ℕ} :
∀ s : Multiset α, (∀ t₁, (∀ {t₂ : Multiset α}, card t₂ ≤ n → t₁ < t₂ → p t₂) → card t₁ ≤ n → p t₁) → card s ≤ n → p s
/-- Analogue of `strongDownwardInduction` with order of arguments swapped. -/
@[elab_as_elim]
def strongDownwardInductionOn {p : Multiset α → Sort*} {n : ℕ} :
∀ s : Multiset α,
(∀ t₁, (∀ {t₂ : Multiset α}, card t₂ ≤ n → t₁ < t₂ → p t₂) → card t₁ ≤ n → p t₁) →
card s ≤ n → p s :=
fun s H => strongDownwardInduction H s
Multiset.strongDownwardInductionOn_eq
theorem
{p : Multiset α → Sort*} (s : Multiset α) {n : ℕ}
(H : ∀ t₁, (∀ {t₂ : Multiset α}, card t₂ ≤ n → t₁ < t₂ → p t₂) → card t₁ ≤ n → p t₁) :
s.strongDownwardInductionOn H = H s fun {t} ht _h => t.strongDownwardInductionOn H ht
theorem strongDownwardInductionOn_eq {p : Multiset α → Sort*} (s : Multiset α) {n : ℕ}
(H : ∀ t₁, (∀ {t₂ : Multiset α}, card t₂ ≤ n → t₁ < t₂ → p t₂) → card t₁ ≤ n → p t₁) :
s.strongDownwardInductionOn H = H s fun {t} ht _h => t.strongDownwardInductionOn H ht := by
dsimp only [strongDownwardInductionOn]
rw [strongDownwardInduction]
Multiset.chooseX
definition
: ∀ _hp : ∃! a, a ∈ l ∧ p a, { a // a ∈ l ∧ p a }
/-- 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`. -/
def chooseX : ∀ _hp : ∃! a, a ∈ l ∧ p a, { a // a ∈ l ∧ p a } :=
Quotient.recOn l (fun l' ex_unique => List.chooseX p l' (ExistsUnique.exists ex_unique))
(by
intros a b _
funext hp
suffices all_equal : ∀ x y : { t // t ∈ b ∧ p t }, x = y by
apply all_equal
rintro ⟨x, px⟩ ⟨y, py⟩
rcases hp with ⟨z, ⟨_z_mem_l, _pz⟩, z_unique⟩
congr
calc
x = z := z_unique x px
_ = y := (z_unique y py).symm
)
Multiset.choose
definition
(hp : ∃! a, a ∈ l ∧ p a) : α
/-- Given a proof `hp` that there exists a unique `a ∈ l` such that `p a`, `choose p l hp` returns
that `a`. -/
def choose (hp : ∃! a, a ∈ l ∧ p a) : α :=
chooseX p l hp
Multiset.choose_spec
theorem
(hp : ∃! a, a ∈ l ∧ p a) : choose p l hp ∈ l ∧ p (choose p l hp)
theorem choose_spec (hp : ∃! a, a ∈ l ∧ p a) : choosechoose p l hp ∈ lchoose p l hp ∈ l ∧ p (choose p l hp) :=
(chooseX p l hp).property
Multiset.choose_mem
theorem
(hp : ∃! a, a ∈ l ∧ p a) : choose p l hp ∈ l
theorem choose_mem (hp : ∃! a, a ∈ l ∧ p a) : choosechoose p l hp ∈ l :=
(choose_spec _ _ _).1
Multiset.choose_property
theorem
(hp : ∃! a, a ∈ l ∧ p a) : p (choose p l hp)
theorem choose_property (hp : ∃! a, a ∈ l ∧ p a) : p (choose p l hp) :=
(choose_spec _ _ _).2
Multiset.subsingletonEquiv
definition
[Subsingleton α] : List α ≃ Multiset α
/-- The equivalence between lists and multisets of a subsingleton type. -/
def subsingletonEquiv [Subsingleton α] : ListList α ≃ Multiset α where
toFun := ofList
invFun :=
(Quot.lift id) fun (a b : List α) (h : a ~ b) =>
(List.ext_get h.length_eq) fun _ _ _ => Subsingleton.elim _ _
left_inv _ := rfl
right_inv m := Quot.inductionOn m fun _ => rfl
Multiset.coe_subsingletonEquiv
theorem
[Subsingleton α] : (subsingletonEquiv α : List α → Multiset α) = ofList
@[simp]
theorem coe_subsingletonEquiv [Subsingleton α] :
(subsingletonEquiv α : List α → Multiset α) = ofList :=
rfl
Multiset.sizeOf_lt_sizeOf_of_mem
theorem
[SizeOf α] {x : α} {s : Multiset α} (hx : x ∈ s) : SizeOf.sizeOf x < SizeOf.sizeOf s
@[deprecated "Deprecated without replacement." (since := "2025-02-07")]
theorem sizeOf_lt_sizeOf_of_mem [SizeOf α] {x : α} {s : Multiset α} (hx : x ∈ s) :
SizeOf.sizeOf x < SizeOf.sizeOf s := by
induction s using Quot.inductionOn
exact List.sizeOf_lt_sizeOf_of_mem hx