Skip to content

Commit 25df797

Browse files
fix: restore mathlib3 definition of Multiset.count (#3088)
Previously discussed in https://leanprover.zulipchat.com/#narrow/stream/287929-mathlib4/topic/count_eq_card_filter_eq
1 parent 86e3d29 commit 25df797

File tree

4 files changed

+40
-24
lines changed

4 files changed

+40
-24
lines changed

Mathlib/Algebra/BigOperators/Associated.lean

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,6 @@ theorem Finset.prod_primes_dvd [CancelCommMonoidWithZero α] [Unique αˣ] {s :
9999
intro a
100100
simp only [Multiset.map_id', associated_eq_eq, Multiset.countp_eq_card_filter]
101101
change Multiset.card (Multiset.filter (fun b => a = b) s.val) ≤ 1
102-
simp_rw [@eq_comm _ a]
103102
apply le_of_eq_of_le (Multiset.count_eq_card_filter_eq _ _).symm
104103
apply Multiset.nodup_iff_count_le_one.mp
105104
exact s.nodup)

Mathlib/Data/Multiset/Basic.lean

Lines changed: 34 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -2360,12 +2360,13 @@ variable [DecidableEq α]
23602360

23612361
/-- `count a s` is the multiplicity of `a` in `s`. -/
23622362
def count (a : α) : Multiset α → ℕ :=
2363-
countp (· = a)
2363+
countp (a = ·)
23642364
#align multiset.count Multiset.count
23652365

23662366
@[simp]
2367-
theorem coe_count (a : α) (l : List α) : count a (ofList l) = l.count a :=
2368-
coe_countp (· = a) l
2367+
theorem coe_count (a : α) (l : List α) : count a (ofList l) = l.count a := by
2368+
simp_rw [count, List.count, coe_countp (a = ·) l, @eq_comm _ a]
2369+
rfl
23692370
#align multiset.coe_count Multiset.coe_count
23702371

23712372
@[simp, nolint simpNF] -- Porting note: simp can prove this at EOF, but not right now
@@ -2380,7 +2381,7 @@ theorem count_cons_self (a : α) (s : Multiset α) : count a (a ::ₘ s) = count
23802381

23812382
@[simp]
23822383
theorem count_cons_of_ne {a b : α} (h : a ≠ b) (s : Multiset α) : count a (b ::ₘ s) = count a s :=
2383-
countp_cons_of_neg _ $ h.symm
2384+
countp_cons_of_neg _ $ h
23842385
#align multiset.count_cons_of_ne Multiset.count_cons_of_ne
23852386

23862387
theorem count_le_card (a : α) (s) : count a s ≤ card s :=
@@ -2396,9 +2397,8 @@ theorem count_le_count_cons (a b : α) (s : Multiset α) : count a s ≤ count a
23962397
#align multiset.count_le_count_cons Multiset.count_le_count_cons
23972398

23982399
theorem count_cons (a b : α) (s : Multiset α) :
2399-
count a (b ::ₘ s) = count a s + if a = b then 1 else 0 := by
2400-
refine' (countp_cons (· = a) _ _).trans _
2401-
simp only [@eq_comm _ a b]; rfl
2400+
count a (b ::ₘ s) = count a s + if a = b then 1 else 0 :=
2401+
countp_cons (a = ·) _ _
24022402
#align multiset.count_cons Multiset.count_cons
24032403

24042404
theorem count_singleton_self (a : α) : count a ({a} : Multiset α) = 1 :=
@@ -2417,7 +2417,7 @@ theorem count_add (a : α) : ∀ s t, count a (s + t) = count a s + count a t :=
24172417

24182418
/-- `count a`, the multiplicity of `a` in a multiset, promoted to an `AddMonoidHom`. -/
24192419
def countAddMonoidHom (a : α) : Multiset α →+ ℕ :=
2420-
countpAddMonoidHom (· = a)
2420+
countpAddMonoidHom (a = ·)
24212421
#align multiset.count_add_monoid_hom Multiset.countAddMonoidHom
24222422

24232423
@[simp]
@@ -2456,23 +2456,27 @@ theorem count_eq_card {a : α} {s} : count a s = card s ↔ ∀ x ∈ s, a = x :
24562456
#align multiset.count_eq_card Multiset.count_eq_card
24572457

24582458
@[simp]
2459-
theorem count_replicate_self (a : α) (n : ℕ) : count a (replicate n a) = n :=
2460-
List.count_replicate_self ..
2459+
theorem count_replicate_self (a : α) (n : ℕ) : count a (replicate n a) = n := by
2460+
convert List.count_replicate_self a n
2461+
rw [←coe_count, coe_replicate]
24612462
#align multiset.count_replicate_self Multiset.count_replicate_self
24622463

2463-
theorem count_replicate (a b : α) (n : ℕ) : count a (replicate n b) = if a = b then n else 0 :=
2464-
List.count_replicate ..
2464+
theorem count_replicate (a b : α) (n : ℕ) : count a (replicate n b) = if a = b then n else 0 := by
2465+
convert List.count_replicate a b n
2466+
rw [←coe_count, coe_replicate]
24652467
#align multiset.count_replicate Multiset.count_replicate
24662468

24672469
@[simp]
24682470
theorem count_erase_self (a : α) (s : Multiset α) : count a (erase s a) = count a s - 1 :=
2469-
Quotient.inductionOn s <| List.count_erase_self a
2471+
Quotient.inductionOn s <| fun l => by
2472+
convert List.count_erase_self a l <;> rw [←coe_count] <;> simp
24702473
#align multiset.count_erase_self Multiset.count_erase_self
24712474

24722475
@[simp]
24732476
theorem count_erase_of_ne {a b : α} (ab : a ≠ b) (s : Multiset α) :
24742477
count a (erase s b) = count a s :=
2475-
Quotient.inductionOn s <| List.count_erase_of_ne ab
2478+
Quotient.inductionOn s <| fun l => by
2479+
convert List.count_erase_of_ne ab l <;> rw [←coe_count] <;> simp
24762480
#align multiset.count_erase_of_ne Multiset.count_erase_of_ne
24772481

24782482
@[simp]
@@ -2499,13 +2503,18 @@ theorem count_inter (a : α) (s t : Multiset α) : count a (s ∩ t) = min (coun
24992503

25002504
theorem le_count_iff_replicate_le {a : α} {s : Multiset α} {n : ℕ} :
25012505
n ≤ count a s ↔ replicate n a ≤ s :=
2502-
Quot.inductionOn s fun _l => le_count_iff_replicate_sublist.trans replicate_le_coe.symm
2506+
Quot.inductionOn s fun _l => by
2507+
simp only [quot_mk_to_coe'', mem_coe, coe_count]
2508+
exact le_count_iff_replicate_sublist.trans replicate_le_coe.symm
25032509
#align multiset.le_count_iff_replicate_le Multiset.le_count_iff_replicate_le
25042510

25052511
@[simp]
25062512
theorem count_filter_of_pos {p} [DecidablePred p] {a} {s : Multiset α} (h : p a) :
25072513
count a (filter p s) = count a s :=
2508-
Quot.inductionOn s fun _l => count_filter $ by simpa using h
2514+
Quot.inductionOn s fun _l => by
2515+
simp only [quot_mk_to_coe'', coe_filter, mem_coe, coe_count, decide_eq_true_eq]
2516+
apply count_filter
2517+
simpa using h
25092518
#align multiset.count_filter_of_pos Multiset.count_filter_of_pos
25102519

25112520
@[simp]
@@ -2523,7 +2532,9 @@ theorem count_filter {p} [DecidablePred p] {a} {s : Multiset α} :
25232532
#align multiset.count_filter Multiset.count_filter
25242533

25252534
theorem ext {s t : Multiset α} : s = t ↔ ∀ a, count a s = count a t :=
2526-
Quotient.inductionOn₂ s t fun _l₁ _l₂ => Quotient.eq.trans perm_iff_count
2535+
Quotient.inductionOn₂ s t fun _l₁ _l₂ => Quotient.eq.trans <| by
2536+
simp only [quot_mk_to_coe, coe_filter, mem_coe, coe_count, decide_eq_true_eq]
2537+
apply perm_iff_count
25272538
#align multiset.ext Multiset.ext
25282539

25292540
@[ext]
@@ -2560,7 +2571,7 @@ the multiset -/
25602571
theorem count_map_eq_count [DecidableEq β] (f : α → β) (s : Multiset α)
25612572
(hf : Set.InjOn f { x : α | x ∈ s }) (x) (H : x ∈ s) : (s.map f).count (f x) = s.count x :=
25622573
by
2563-
suffices (filter (fun a : α => f a = f x) s).count x = card (filter (fun a : α => f a = f x) s)
2574+
suffices (filter (fun a : α => f x = f a) s).count x = card (filter (fun a : α => f x = f a) s)
25642575
by
25652576
rw [count, countp_map, ← this]
25662577
exact count_filter_of_pos $ rfl
@@ -2591,7 +2602,9 @@ theorem attach_count_eq_count_coe (m : Multiset α) (a) : m.attach.count a = m.c
25912602
#align multiset.attach_count_eq_count_coe Multiset.attach_count_eq_count_coe
25922603

25932604
theorem filter_eq' (s : Multiset α) (b : α) : s.filter (· = b) = replicate (count b s) b :=
2594-
Quotient.inductionOn s <| fun l => congr_arg _ <| List.filter_eq' l b
2605+
Quotient.inductionOn s <| fun l => by
2606+
simp only [quot_mk_to_coe, coe_filter, mem_coe, coe_count]
2607+
rw [List.filter_eq' l b, coe_replicate]
25952608
#align multiset.filter_eq' Multiset.filter_eq'
25962609

25972610
theorem filter_eq (s : Multiset α) (b : α) : s.filter (Eq b) = replicate (count b s) b := by
@@ -2646,7 +2659,7 @@ def mapEmbedding (f : α ↪ β) : Multiset α ↪o Multiset β :=
26462659
end Embedding
26472660

26482661
theorem count_eq_card_filter_eq [DecidableEq α] (s : Multiset α) (a : α) :
2649-
s.count a = card (s.filter (· = a)) := by rw [count, countp_eq_card_filter]
2662+
s.count a = card (s.filter (a = ·)) := by rw [count, countp_eq_card_filter]
26502663
#align multiset.count_eq_card_filter_eq Multiset.count_eq_card_filter_eq
26512664

26522665
/--
@@ -2663,7 +2676,7 @@ theorem map_count_True_eq_filter_card (s : Multiset α) (p : α → Prop) [Decid
26632676
simp only [count_eq_card_filter_eq, map_filter, card_map, Function.comp.left_id,
26642677
eq_true_eq_id, Function.comp]
26652678
congr; funext _
2666-
simp only [eq_iff_iff, iff_true]
2679+
simp only [eq_iff_iff, true_iff]
26672680
#align multiset.map_count_true_eq_filter_card Multiset.map_count_True_eq_filter_card
26682681

26692682
/-! ### Lift a relation to `Multiset`s -/

Mathlib/Data/Multiset/Dedup.lean

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,9 @@ alias dedup_eq_self ↔ _ Nodup.dedup
8888
#align multiset.nodup.dedup Multiset.Nodup.dedup
8989

9090
theorem count_dedup (m : Multiset α) (a : α) : m.dedup.count a = if a ∈ m then 1 else 0 :=
91-
Quot.induction_on m fun _ => List.count_dedup _ _
91+
Quot.induction_on m fun _ => by
92+
simp only [quot_mk_to_coe'', coe_dedup, mem_coe, List.mem_dedup, coe_nodup, coe_count]
93+
apply List.count_dedup _ _
9294
#align multiset.count_dedup Multiset.count_dedup
9395

9496
@[simp]

Mathlib/Data/Multiset/Nodup.lean

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,9 @@ theorem nodup_iff_ne_cons_cons {s : Multiset α} : s.Nodup ↔ ∀ a t, s ≠ a
8383
#align multiset.nodup_iff_ne_cons_cons Multiset.nodup_iff_ne_cons_cons
8484

8585
theorem nodup_iff_count_le_one [DecidableEq α] {s : Multiset α} : Nodup s ↔ ∀ a, count a s ≤ 1 :=
86-
Quot.induction_on s fun _l => List.nodup_iff_count_le_one
86+
Quot.induction_on s fun _l => by
87+
simp only [quot_mk_to_coe'', coe_nodup, mem_coe, coe_count]
88+
apply List.nodup_iff_count_le_one
8789
#align multiset.nodup_iff_count_le_one Multiset.nodup_iff_count_le_one
8890

8991
@[simp]

0 commit comments

Comments
 (0)