Theorem: Finset.prod_list_map_count
File: Mathlib/Algebra/BigOperators/Group/Finset.lean

Proof steps:
state_before: ι : Type u_1
κ : Type u_2
α : Type u_3
β : Type u_4
γ : Type u_5
s s₁ s₂ : Finset α
a : α
f✝ g : α → β
inst✝² : CommMonoid β
inst✝¹ : DecidableEq α
l : List α
M : Type u_6
inst✝ : CommMonoid M
f : α → M
⊢ (List.map f l).prod = ∏ m ∈ l.toFinset, f m ^ count m l
state_after: case nil
ι : Type u_1
κ : Type u_2
α : Type u_3
β : Type u_4
γ : Type u_5
s s₁ s₂ : Finset α
a : α
f✝ g : α → β
inst✝² : CommMonoid β
inst✝¹ : DecidableEq α
M : Type u_6
inst✝ : CommMonoid M
f : α → M
⊢ (List.map f []).prod = ∏ m ∈ [].toFinset, f m ^ count m []

case cons
ι : Type u_1
κ : Type u_2
α : Type u_3
β : Type u_4
γ : Type u_5
s✝ s₁ s₂ : Finset α
a✝ : α
f✝ g : α → β
inst✝² : CommMonoid β
inst✝¹ : DecidableEq α
M : Type u_6
inst✝ : CommMonoid M
f : α → M
a : α
s : List α
IH : (List.map f s).prod = ∏ m ∈ s.toFinset, f m ^ count m s
⊢ (List.map f (a :: s)).prod = ∏ m ∈ (a :: s).toFinset, f m ^ count m (a :: s)
tactic: induction' l with a s IH
state_before: case cons
ι : Type u_1
κ : Type u_2
α : Type u_3
β : Type u_4
γ : Type u_5
s✝ s₁ s₂ : Finset α
a✝ : α
f✝ g : α → β
inst✝² : CommMonoid β
inst✝¹ : DecidableEq α
M : Type u_6
inst✝ : CommMonoid M
f : α → M
a : α
s : List α
IH : (List.map f s).prod = ∏ m ∈ s.toFinset, f m ^ count m s
⊢ (List.map f (a :: s)).prod = ∏ m ∈ (a :: s).toFinset, f m ^ count m (a :: s)
state_after: case cons
ι : Type u_1
κ : Type u_2
α : Type u_3
β : Type u_4
γ : Type u_5
s✝ s₁ s₂ : Finset α
a✝ : α
f✝ g : α → β
inst✝² : CommMonoid β
inst✝¹ : DecidableEq α
M : Type u_6
inst✝ : CommMonoid M
f : α → M
a : α
s : List α
IH : (List.map f s).prod = ∏ m ∈ s.toFinset, f m ^ count m s
⊢ f a * ∏ m ∈ s.toFinset, f m ^ count m s = ∏ x ∈ insert a s.toFinset, f x ^ count x (a :: s)
tactic: simp only [List.map, List.prod_cons, toFinset_cons, IH]
state_before: case cons
ι : Type u_1
κ : Type u_2
α : Type u_3
β : Type u_4
γ : Type u_5
s✝ s₁ s₂ : Finset α
a✝ : α
f✝ g : α → β
inst✝² : CommMonoid β
inst✝¹ : DecidableEq α
M : Type u_6
inst✝ : CommMonoid M
f : α → M
a : α
s : List α
IH : (List.map f s).prod = ∏ m ∈ s.toFinset, f m ^ count m s
⊢ f a * ∏ m ∈ s.toFinset, f m ^ count m s = ∏ x ∈ insert a s.toFinset, f x ^ count x (a :: s)
state_after: case pos
ι : Type u_1
κ : Type u_2
α : Type u_3
β : Type u_4
γ : Type u_5
s✝ s₁ s₂ : Finset α
a✝ : α
f✝ g : α → β
inst✝² : CommMonoid β
inst✝¹ : DecidableEq α
M : Type u_6
inst✝ : CommMonoid M
f : α → M
a : α
s : List α
IH : (List.map f s).prod = ∏ m ∈ s.toFinset, f m ^ count m s
has : a ∈ s.toFinset
⊢ f a * ∏ m ∈ s.toFinset, f m ^ count m s = ∏ x ∈ insert a s.toFinset, f x ^ count x (a :: s)

case neg
ι : Type u_1
κ : Type u_2
α : Type u_3
β : Type u_4
γ : Type u_5
s✝ s₁ s₂ : Finset α
a✝ : α
f✝ g : α → β
inst✝² : CommMonoid β
inst✝¹ : DecidableEq α
M : Type u_6
inst✝ : CommMonoid M
f : α → M
a : α
s : List α
IH : (List.map f s).prod = ∏ m ∈ s.toFinset, f m ^ count m s
has : a ∉ s.toFinset
⊢ f a * ∏ m ∈ s.toFinset, f m ^ count m s = ∏ x ∈ insert a s.toFinset, f x ^ count x (a :: s)
tactic: by_cases has : a ∈ s.toFinset
state_before: case neg
ι : Type u_1
κ : Type u_2
α : Type u_3
β : Type u_4
γ : Type u_5
s✝ s₁ s₂ : Finset α
a✝ : α
f✝ g : α → β
inst✝² : CommMonoid β
inst✝¹ : DecidableEq α
M : Type u_6
inst✝ : CommMonoid M
f : α → M
a : α
s : List α
IH : (List.map f s).prod = ∏ m ∈ s.toFinset, f m ^ count m s
has : a ∉ s.toFinset
⊢ f a * ∏ m ∈ s.toFinset, f m ^ count m s = ∏ x ∈ insert a s.toFinset, f x ^ count x (a :: s)
state_after: case neg
ι : Type u_1
κ : Type u_2
α : Type u_3
β : Type u_4
γ : Type u_5
s✝ s₁ s₂ : Finset α
a✝ : α
f✝ g : α → β
inst✝² : CommMonoid β
inst✝¹ : DecidableEq α
M : Type u_6
inst✝ : CommMonoid M
f : α → M
a : α
s : List α
IH : (List.map f s).prod = ∏ m ∈ s.toFinset, f m ^ count m s
has : a ∉ s.toFinset
⊢ f a * ∏ m ∈ s.toFinset, f m ^ count m s = f a * ∏ x ∈ s.toFinset, f x ^ count x (a :: s)
tactic: rw [prod_insert has, count_cons_self, count_eq_zero_of_not_mem (mt mem_toFinset.2 has), pow_one]
state_before: case neg
ι : Type u_1
κ : Type u_2
α : Type u_3
β : Type u_4
γ : Type u_5
s✝ s₁ s₂ : Finset α
a✝ : α
f✝ g : α → β
inst✝² : CommMonoid β
inst✝¹ : DecidableEq α
M : Type u_6
inst✝ : CommMonoid M
f : α → M
a : α
s : List α
IH : (List.map f s).prod = ∏ m ∈ s.toFinset, f m ^ count m s
has : a ∉ s.toFinset
⊢ f a * ∏ m ∈ s.toFinset, f m ^ count m s = f a * ∏ x ∈ s.toFinset, f x ^ count x (a :: s)
state_after: case neg.e_a
ι : Type u_1
κ : Type u_2
α : Type u_3
β : Type u_4
γ : Type u_5
s✝ s₁ s₂ : Finset α
a✝ : α
f✝ g : α → β
inst✝² : CommMonoid β
inst✝¹ : DecidableEq α
M : Type u_6
inst✝ : CommMonoid M
f : α → M
a : α
s : List α
IH : (List.map f s).prod = ∏ m ∈ s.toFinset, f m ^ count m s
has : a ∉ s.toFinset
⊢ ∏ m ∈ s.toFinset, f m ^ count m s = ∏ x ∈ s.toFinset, f x ^ count x (a :: s)
tactic: congr 1
state_before: case neg.e_a
ι : Type u_1
κ : Type u_2
α : Type u_3
β : Type u_4
γ : Type u_5
s✝ s₁ s₂ : Finset α
a✝ : α
f✝ g : α → β
inst✝² : CommMonoid β
inst✝¹ : DecidableEq α
M : Type u_6
inst✝ : CommMonoid M
f : α → M
a : α
s : List α
IH : (List.map f s).prod = ∏ m ∈ s.toFinset, f m ^ count m s
has : a ∉ s.toFinset
⊢ ∏ m ∈ s.toFinset, f m ^ count m s = ∏ x ∈ s.toFinset, f x ^ count x (a :: s)
state_after: case neg.e_a
ι : Type u_1
κ : Type u_2
α : Type u_3
β : Type u_4
γ : Type u_5
s✝ s₁ s₂ : Finset α
a✝ : α
f✝ g : α → β
inst✝² : CommMonoid β
inst✝¹ : DecidableEq α
M : Type u_6
inst✝ : CommMonoid M
f : α → M
a : α
s : List α
IH : (List.map f s).prod = ∏ m ∈ s.toFinset, f m ^ count m s
has : a ∉ s.toFinset
x : α
hx : x ∈ s.toFinset
⊢ f x ^ count x s = f x ^ count x (a :: s)
tactic: refine prod_congr rfl fun x hx => ?_
state_before: case neg.e_a
ι : Type u_1
κ : Type u_2
α : Type u_3
β : Type u_4
γ : Type u_5
s✝ s₁ s₂ : Finset α
a✝ : α
f✝ g : α → β
inst✝² : CommMonoid β
inst✝¹ : DecidableEq α
M : Type u_6
inst✝ : CommMonoid M
f : α → M
a : α
s : List α
IH : (List.map f s).prod = ∏ m ∈ s.toFinset, f m ^ count m s
has : a ∉ s.toFinset
x : α
hx : x ∈ s.toFinset
⊢ f x ^ count x s = f x ^ count x (a :: s)
state_after: case neg.e_a.h
ι : Type u_1
κ : Type u_2
α : Type u_3
β : Type u_4
γ : Type u_5
s✝ s₁ s₂ : Finset α
a✝ : α
f✝ g : α → β
inst✝² : CommMonoid β
inst✝¹ : DecidableEq α
M : Type u_6
inst✝ : CommMonoid M
f : α → M
a : α
s : List α
IH : (List.map f s).prod = ∏ m ∈ s.toFinset, f m ^ count m s
has : a ∉ s.toFinset
x : α
hx : x ∈ s.toFinset
⊢ x ≠ a
tactic: rw [count_cons_of_ne]
state_before: case neg.e_a.h
ι : Type u_1
κ : Type u_2
α : Type u_3
β : Type u_4
γ : Type u_5
s✝ s₁ s₂ : Finset α
a✝ : α
f✝ g : α → β
inst✝² : CommMonoid β
inst✝¹ : DecidableEq α
M : Type u_6
inst✝ : CommMonoid M
f : α → M
a : α
s : List α
IH : (List.map f s).prod = ∏ m ∈ s.toFinset, f m ^ count m s
has : a ∉ s.toFinset
x : α
hx : x ∈ s.toFinset
⊢ x ≠ a
state_after: case neg.e_a.h
ι : Type u_1
κ : Type u_2
α : Type u_3
β : Type u_4
γ : Type u_5
s✝ s₁ s₂ : Finset α
a : α
f✝ g : α → β
inst✝² : CommMonoid β
inst✝¹ : DecidableEq α
M : Type u_6
inst✝ : CommMonoid M
f : α → M
s : List α
IH : (List.map f s).prod = ∏ m ∈ s.toFinset, f m ^ count m s
x : α
hx : x ∈ s.toFinset
has : x ∉ s.toFinset
⊢ False
tactic: rintro rfl
state_before: case neg.e_a.h
ι : Type u_1
κ : Type u_2
α : Type u_3
β : Type u_4
γ : Type u_5
s✝ s₁ s₂ : Finset α
a : α
f✝ g : α → β
inst✝² : CommMonoid β
inst✝¹ : DecidableEq α
M : Type u_6
inst✝ : CommMonoid M
f : α → M
s : List α
IH : (List.map f s).prod = ∏ m ∈ s.toFinset, f m ^ count m s
x : α
hx : x ∈ s.toFinset
has : x ∉ s.toFinset
⊢ False
state_after: no goals
tactic: exact has hx