Theorem: List.sum_map_count_dedup_filter_eq_countP
File: Mathlib/Algebra/BigOperators/Group/List.lean

tactic: induction' l with a as h
state_before: ι : Type u_1
α : Type u_2
β : Type u_3
M : Type u_4
N : Type u_5
P : Type u_6
G : Type u_7
inst✝ : DecidableEq α
p : α → Bool
l : List α
⊢ (map (fun x => count x l) (filter p l.dedup)).sum = countP p l
state_after: case nil
ι : Type u_1
α : Type u_2
β : Type u_3
M : Type u_4
N : Type u_5
P : Type u_6
G : Type u_7
inst✝ : DecidableEq α
p : α → Bool
⊢ (map (fun x => count x []) (filter p [].dedup)).sum = countP p []

case cons
ι : Type u_1
α : Type u_2
β : Type u_3
M : Type u_4
N : Type u_5
P : Type u_6
G : Type u_7
inst✝ : DecidableEq α
p : α → Bool
a : α
as : List α
h : (map (fun x => count x as) (filter p as.dedup)).sum = countP p as
⊢ (map (fun x => count x (a :: as)) (filter p (a :: as).dedup)).sum = countP p (a :: as)

tactic: simp
state_before: case nil
ι : Type u_1
α : Type u_2
β : Type u_3
M : Type u_4
N : Type u_5
P : Type u_6
G : Type u_7
inst✝ : DecidableEq α
p : α → Bool
⊢ (map (fun x => count x []) (filter p [].dedup)).sum = countP p []
state_after: no goals

tactic: simp_rw [List.countP_cons, List.count_cons, List.sum_map_add]
state_before: case cons
ι : Type u_1
α : Type u_2
β : Type u_3
M : Type u_4
N : Type u_5
P : Type u_6
G : Type u_7
inst✝ : DecidableEq α
p : α → Bool
a : α
as : List α
h : (map (fun x => count x as) (filter p as.dedup)).sum = countP p as
⊢ (map (fun x => count x (a :: as)) (filter p (a :: as).dedup)).sum = countP p (a :: as)
state_after: case cons
ι : Type u_1
α : Type u_2
β : Type u_3
M : Type u_4
N : Type u_5
P : Type u_6
G : Type u_7
inst✝ : DecidableEq α
p : α → Bool
a : α
as : List α
h : (map (fun x => count x as) (filter p as.dedup)).sum = countP p as
⊢ (map (fun i => count i as) (filter p (a :: as).dedup)).sum +
      (map (fun i => if i = a then 1 else 0) (filter p (a :: as).dedup)).sum =
    countP p as + if p a = true then 1 else 0

tactic: congr 1
state_before: case cons
ι : Type u_1
α : Type u_2
β : Type u_3
M : Type u_4
N : Type u_5
P : Type u_6
G : Type u_7
inst✝ : DecidableEq α
p : α → Bool
a : α
as : List α
h : (map (fun x => count x as) (filter p as.dedup)).sum = countP p as
⊢ (map (fun i => count i as) (filter p (a :: as).dedup)).sum +
      (map (fun i => if i = a then 1 else 0) (filter p (a :: as).dedup)).sum =
    countP p as + if p a = true then 1 else 0
state_after: case cons.e_a
ι : Type u_1
α : Type u_2
β : Type u_3
M : Type u_4
N : Type u_5
P : Type u_6
G : Type u_7
inst✝ : DecidableEq α
p : α → Bool
a : α
as : List α
h : (map (fun x => count x as) (filter p as.dedup)).sum = countP p as
⊢ (map (fun i => count i as) (filter p (a :: as).dedup)).sum = countP p as

case cons.e_a
ι : Type u_1
α : Type u_2
β : Type u_3
M : Type u_4
N : Type u_5
P : Type u_6
G : Type u_7
inst✝ : DecidableEq α
p : α → Bool
a : α
as : List α
h : (map (fun x => count x as) (filter p as.dedup)).sum = countP p as
⊢ (map (fun i => if i = a then 1 else 0) (filter p (a :: as).dedup)).sum = if p a = true then 1 else 0

tactic: refine _root_.trans ?_ h
state_before: case cons.e_a
ι : Type u_1
α : Type u_2
β : Type u_3
M : Type u_4
N : Type u_5
P : Type u_6
G : Type u_7
inst✝ : DecidableEq α
p : α → Bool
a : α
as : List α
h : (map (fun x => count x as) (filter p as.dedup)).sum = countP p as
⊢ (map (fun i => count i as) (filter p (a :: as).dedup)).sum = countP p as
state_after: case cons.e_a
ι : Type u_1
α : Type u_2
β : Type u_3
M : Type u_4
N : Type u_5
P : Type u_6
G : Type u_7
inst✝ : DecidableEq α
p : α → Bool
a : α
as : List α
h : (map (fun x => count x as) (filter p as.dedup)).sum = countP p as
⊢ (map (fun i => count i as) (filter p (a :: as).dedup)).sum = (map (fun x => count x as) (filter p as.dedup)).sum

tactic: by_cases ha : a ∈ as
state_before: case cons.e_a
ι : Type u_1
α : Type u_2
β : Type u_3
M : Type u_4
N : Type u_5
P : Type u_6
G : Type u_7
inst✝ : DecidableEq α
p : α → Bool
a : α
as : List α
h : (map (fun x => count x as) (filter p as.dedup)).sum = countP p as
⊢ (map (fun i => count i as) (filter p (a :: as).dedup)).sum = (map (fun x => count x as) (filter p as.dedup)).sum
state_after: case pos
ι : Type u_1
α : Type u_2
β : Type u_3
M : Type u_4
N : Type u_5
P : Type u_6
G : Type u_7
inst✝ : DecidableEq α
p : α → Bool
a : α
as : List α
h : (map (fun x => count x as) (filter p as.dedup)).sum = countP p as
ha : a ∈ as
⊢ (map (fun i => count i as) (filter p (a :: as).dedup)).sum = (map (fun x => count x as) (filter p as.dedup)).sum

case neg
ι : Type u_1
α : Type u_2
β : Type u_3
M : Type u_4
N : Type u_5
P : Type u_6
G : Type u_7
inst✝ : DecidableEq α
p : α → Bool
a : α
as : List α
h : (map (fun x => count x as) (filter p as.dedup)).sum = countP p as
ha : a ∉ as
⊢ (map (fun i => count i as) (filter p (a :: as).dedup)).sum = (map (fun x => count x as) (filter p as.dedup)).sum

tactic: simp [dedup_cons_of_mem ha]
state_before: case pos
ι : Type u_1
α : Type u_2
β : Type u_3
M : Type u_4
N : Type u_5
P : Type u_6
G : Type u_7
inst✝ : DecidableEq α
p : α → Bool
a : α
as : List α
h : (map (fun x => count x as) (filter p as.dedup)).sum = countP p as
ha : a ∈ as
⊢ (map (fun i => count i as) (filter p (a :: as).dedup)).sum = (map (fun x => count x as) (filter p as.dedup)).sum
state_after: no goals

tactic: simp only [dedup_cons_of_not_mem ha, List.filter]
state_before: case neg
ι : Type u_1
α : Type u_2
β : Type u_3
M : Type u_4
N : Type u_5
P : Type u_6
G : Type u_7
inst✝ : DecidableEq α
p : α → Bool
a : α
as : List α
h : (map (fun x => count x as) (filter p as.dedup)).sum = countP p as
ha : a ∉ as
⊢ (map (fun i => count i as) (filter p (a :: as).dedup)).sum = (map (fun x => count x as) (filter p as.dedup)).sum
state_after: case neg
ι : Type u_1
α : Type u_2
β : Type u_3
M : Type u_4
N : Type u_5
P : Type u_6
G : Type u_7
inst✝ : DecidableEq α
p : α → Bool
a : α
as : List α
h : (map (fun x => count x as) (filter p as.dedup)).sum = countP p as
ha : a ∉ as
⊢ (map (fun i => count i as)
        (match p a with
        | true => a :: filter p as.dedup
        | false => filter p as.dedup)).sum =
    (map (fun i => count i as) (filter p as.dedup)).sum

tactic: match p a with
| true => simp only [List.map_cons, List.sum_cons, List.count_eq_zero.2 ha, zero_add]
| false => simp only
state_before: case neg
ι : Type u_1
α : Type u_2
β : Type u_3
M : Type u_4
N : Type u_5
P : Type u_6
G : Type u_7
inst✝ : DecidableEq α
p : α → Bool
a : α
as : List α
h : (map (fun x => count x as) (filter p as.dedup)).sum = countP p as
ha : a ∉ as
⊢ (map (fun i => count i as)
        (match p a with
        | true => a :: filter p as.dedup
        | false => filter p as.dedup)).sum =
    (map (fun i => count i as) (filter p as.dedup)).sum
state_after: no goals

tactic: simp only [List.map_cons, List.sum_cons, List.count_eq_zero.2 ha, zero_add]
state_before: ι : Type u_1
α : Type u_2
β : Type u_3
M : Type u_4
N : Type u_5
P : Type u_6
G : Type u_7
inst✝ : DecidableEq α
p : α → Bool
a : α
as : List α
h : (map (fun x => count x as) (filter p as.dedup)).sum = countP p as
ha : a ∉ as
⊢ (map (fun i => count i as)
        (match true with
        | true => a :: filter p as.dedup
        | false => filter p as.dedup)).sum =
    (map (fun i => count i as) (filter p as.dedup)).sum
state_after: no goals

tactic: simp only
state_before: ι : Type u_1
α : Type u_2
β : Type u_3
M : Type u_4
N : Type u_5
P : Type u_6
G : Type u_7
inst✝ : DecidableEq α
p : α → Bool
a : α
as : List α
h : (map (fun x => count x as) (filter p as.dedup)).sum = countP p as
ha : a ∉ as
⊢ (map (fun i => count i as)
        (match false with
        | true => a :: filter p as.dedup
        | false => filter p as.dedup)).sum =
    (map (fun i => count i as) (filter p as.dedup)).sum
state_after: no goals

tactic: by_cases hp : p a
state_before: case cons.e_a
ι : Type u_1
α : Type u_2
β : Type u_3
M : Type u_4
N : Type u_5
P : Type u_6
G : Type u_7
inst✝ : DecidableEq α
p : α → Bool
a : α
as : List α
h : (map (fun x => count x as) (filter p as.dedup)).sum = countP p as
⊢ (map (fun i => if i = a then 1 else 0) (filter p (a :: as).dedup)).sum = if p a = true then 1 else 0
state_after: case pos
ι : Type u_1
α : Type u_2
β : Type u_3
M : Type u_4
N : Type u_5
P : Type u_6
G : Type u_7
inst✝ : DecidableEq α
p : α → Bool
a : α
as : List α
h : (map (fun x => count x as) (filter p as.dedup)).sum = countP p as
hp : p a = true
⊢ (map (fun i => if i = a then 1 else 0) (filter p (a :: as).dedup)).sum = if p a = true then 1 else 0

case neg
ι : Type u_1
α : Type u_2
β : Type u_3
M : Type u_4
N : Type u_5
P : Type u_6
G : Type u_7
inst✝ : DecidableEq α
p : α → Bool
a : α
as : List α
h : (map (fun x => count x as) (filter p as.dedup)).sum = countP p as
hp : ¬p a = true
⊢ (map (fun i => if i = a then 1 else 0) (filter p (a :: as).dedup)).sum = if p a = true then 1 else 0

tactic: refine _root_.trans (sum_map_eq_nsmul_single a _ fun _ h _ => by simp [h]) ?_
state_before: case pos
ι : Type u_1
α : Type u_2
β : Type u_3
M : Type u_4
N : Type u_5
P : Type u_6
G : Type u_7
inst✝ : DecidableEq α
p : α → Bool
a : α
as : List α
h : (map (fun x => count x as) (filter p as.dedup)).sum = countP p as
hp : p a = true
⊢ (map (fun i => if i = a then 1 else 0) (filter p (a :: as).dedup)).sum = if p a = true then 1 else 0
state_after: case pos
ι : Type u_1
α : Type u_2
β : Type u_3
M : Type u_4
N : Type u_5
P : Type u_6
G : Type u_7
inst✝ : DecidableEq α
p : α → Bool
a : α
as : List α
h : (map (fun x => count x as) (filter p as.dedup)).sum = countP p as
hp : p a = true
⊢ (count a (filter p (a :: as).dedup) • if a = a then 1 else 0) = if p a = true then 1 else 0

tactic: simp [hp, count_dedup]
state_before: case pos
ι : Type u_1
α : Type u_2
β : Type u_3
M : Type u_4
N : Type u_5
P : Type u_6
G : Type u_7
inst✝ : DecidableEq α
p : α → Bool
a : α
as : List α
h : (map (fun x => count x as) (filter p as.dedup)).sum = countP p as
hp : p a = true
⊢ (count a (filter p (a :: as).dedup) • if a = a then 1 else 0) = if p a = true then 1 else 0
state_after: no goals

tactic: simp [h]
state_before: ι : Type u_1
α : Type u_2
β : Type u_3
M : Type u_4
N : Type u_5
P : Type u_6
G : Type u_7
inst✝ : DecidableEq α
p : α → Bool
a : α
as : List α
h✝ : (map (fun x => count x as) (filter p as.dedup)).sum = countP p as
hp : p a = true
x✝¹ : α
h : x✝¹ ≠ a
x✝ : x✝¹ ∈ filter p (a :: as).dedup
⊢ (if x✝¹ = a then 1 else 0) = 0
state_after: no goals

tactic: refine _root_.trans (List.sum_eq_zero fun n hn => ?_) (by simp [hp])
state_before: case neg
ι : Type u_1
α : Type u_2
β : Type u_3
M : Type u_4
N : Type u_5
P : Type u_6
G : Type u_7
inst✝ : DecidableEq α
p : α → Bool
a : α
as : List α
h : (map (fun x => count x as) (filter p as.dedup)).sum = countP p as
hp : ¬p a = true
⊢ (map (fun i => if i = a then 1 else 0) (filter p (a :: as).dedup)).sum = if p a = true then 1 else 0
state_after: case neg
ι : Type u_1
α : Type u_2
β : Type u_3
M : Type u_4
N : Type u_5
P : Type u_6
G : Type u_7
inst✝ : DecidableEq α
p : α → Bool
a : α
as : List α
h : (map (fun x => count x as) (filter p as.dedup)).sum = countP p as
hp : ¬p a = true
n : ℕ
hn : n ∈ map (fun i => if i = a then 1 else 0) (filter p (a :: as).dedup)
⊢ n = 0

tactic: obtain ⟨a', ha'⟩ := List.mem_map.1 hn
state_before: case neg
ι : Type u_1
α : Type u_2
β : Type u_3
M : Type u_4
N : Type u_5
P : Type u_6
G : Type u_7
inst✝ : DecidableEq α
p : α → Bool
a : α
as : List α
h : (map (fun x => count x as) (filter p as.dedup)).sum = countP p as
hp : ¬p a = true
n : ℕ
hn : n ∈ map (fun i => if i = a then 1 else 0) (filter p (a :: as).dedup)
⊢ n = 0
state_after: case neg.intro
ι : Type u_1
α : Type u_2
β : Type u_3
M : Type u_4
N : Type u_5
P : Type u_6
G : Type u_7
inst✝ : DecidableEq α
p : α → Bool
a : α
as : List α
h : (map (fun x => count x as) (filter p as.dedup)).sum = countP p as
hp : ¬p a = true
n : ℕ
hn : n ∈ map (fun i => if i = a then 1 else 0) (filter p (a :: as).dedup)
a' : α
ha' : a' ∈ filter p (a :: as).dedup ∧ (if a' = a then 1 else 0) = n
⊢ n = 0

tactic: split_ifs at ha' with ha
state_before: case neg.intro
ι : Type u_1
α : Type u_2
β : Type u_3
M : Type u_4
N : Type u_5
P : Type u_6
G : Type u_7
inst✝ : DecidableEq α
p : α → Bool
a : α
as : List α
h : (map (fun x => count x as) (filter p as.dedup)).sum = countP p as
hp : ¬p a = true
n : ℕ
hn : n ∈ map (fun i => if i = a then 1 else 0) (filter p (a :: as).dedup)
a' : α
ha' : a' ∈ filter p (a :: as).dedup ∧ (if a' = a then 1 else 0) = n
⊢ n = 0
state_after: case pos
ι : Type u_1
α : Type u_2
β : Type u_3
M : Type u_4
N : Type u_5
P : Type u_6
G : Type u_7
inst✝ : DecidableEq α
p : α → Bool
a : α
as : List α
h : (map (fun x => count x as) (filter p as.dedup)).sum = countP p as
hp : ¬p a = true
n : ℕ
hn : n ∈ map (fun i => if i = a then 1 else 0) (filter p (a :: as).dedup)
a' : α
ha : a' = a
ha' : a' ∈ filter p (a :: as).dedup ∧ 1 = n
⊢ n = 0

case neg
ι : Type u_1
α : Type u_2
β : Type u_3
M : Type u_4
N : Type u_5
P : Type u_6
G : Type u_7
inst✝ : DecidableEq α
p : α → Bool
a : α
as : List α
h : (map (fun x => count x as) (filter p as.dedup)).sum = countP p as
hp : ¬p a = true
n : ℕ
hn : n ∈ map (fun i => if i = a then 1 else 0) (filter p (a :: as).dedup)
a' : α
ha : ¬a' = a
ha' : a' ∈ filter p (a :: as).dedup ∧ 0 = n
⊢ n = 0

tactic: simp [hp]
state_before: ι : Type u_1
α : Type u_2
β : Type u_3
M : Type u_4
N : Type u_5
P : Type u_6
G : Type u_7
inst✝ : DecidableEq α
p : α → Bool
a : α
as : List α
h : (map (fun x => count x as) (filter p as.dedup)).sum = countP p as
hp : ¬p a = true
⊢ 0 = if p a = true then 1 else 0
state_after: no goals

tactic: simp only [ha, mem_filter, mem_dedup, find?, mem_cons, true_or, hp,
  and_false, false_and] at ha'
state_before: case pos
ι : Type u_1
α : Type u_2
β : Type u_3
M : Type u_4
N : Type u_5
P : Type u_6
G : Type u_7
inst✝ : DecidableEq α
p : α → Bool
a : α
as : List α
h : (map (fun x => count x as) (filter p as.dedup)).sum = countP p as
hp : ¬p a = true
n : ℕ
hn : n ∈ map (fun i => if i = a then 1 else 0) (filter p (a :: as).dedup)
a' : α
ha : a' = a
ha' : a' ∈ filter p (a :: as).dedup ∧ 1 = n
⊢ n = 0
state_after: no goals

tactic: exact ha'.2.symm
state_before: case neg
ι : Type u_1
α : Type u_2
β : Type u_3
M : Type u_4
N : Type u_5
P : Type u_6
G : Type u_7
inst✝ : DecidableEq α
p : α → Bool
a : α
as : List α
h : (map (fun x => count x as) (filter p as.dedup)).sum = countP p as
hp : ¬p a = true
n : ℕ
hn : n ∈ map (fun i => if i = a then 1 else 0) (filter p (a :: as).dedup)
a' : α
ha : ¬a' = a
ha' : a' ∈ filter p (a :: as).dedup ∧ 0 = n
⊢ n = 0
state_after: no goals