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

tactic: induction' l with a s IH
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: 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
⊢ (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: by_cases has : a ∈ s.toFinset
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: 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 = ∏ 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: congr 1
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: 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
⊢ ∏ 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: rw [count_cons_of_ne]
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: 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
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: exact has hx
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: simp only [map_nil, prod_nil, count_nil, pow_zero, prod_const_one]
state_before: 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 []
state_after: no goals

tactic: rw [insert_eq_of_mem has, ← insert_erase has, prod_insert (not_mem_erase _ _),
  prod_insert (not_mem_erase _ _), ← mul_assoc, count_cons_self, pow_succ']
state_before: 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)
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 * f a ^ count a s * ∏ x ∈ s.toFinset.erase a, f x ^ count x s =
    f a * f a ^ count a s * ∏ x ∈ s.toFinset.erase a, f x ^ count x (a :: s)

tactic: congr 1
state_before: 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 * f a ^ count a s * ∏ x ∈ s.toFinset.erase a, f x ^ count x s =
    f a * f a ^ count a s * ∏ x ∈ s.toFinset.erase a, f x ^ count x (a :: s)
state_after: case pos.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 ∈ s.toFinset.erase a, f x ^ count x s = ∏ x ∈ s.toFinset.erase a, f x ^ count x (a :: s)

tactic: refine prod_congr rfl fun x hx => ?_
state_before: case pos.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 ∈ s.toFinset.erase a, f x ^ count x s = ∏ x ∈ s.toFinset.erase a, f x ^ count x (a :: s)
state_after: case pos.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.erase a
⊢ f x ^ count x s = f x ^ count x (a :: s)

tactic: rw [count_cons_of_ne (ne_of_mem_erase hx)]
state_before: case pos.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.erase a
⊢ f x ^ count x s = f x ^ count x (a :: s)
state_after: no goals