Theorem: finprod_mem_finset_product'
File: Mathlib/Algebra/BigOperators/Finprod.lean

tactic: have :
  ∀ a,
    (∏ i : β in (s.filter fun ab => Prod.fst ab = a).image Prod.snd, f (a, i)) =
      (Finset.filter (fun ab => Prod.fst ab = a) s).prod f := by
  refine' fun a => Finset.prod_bij (fun b _ => (a, b)) _ _ _ _ <;>try simp; done
  suffices ∀ a' b, (a', b) ∈ s → a' = a → (a, b) ∈ s ∧ a' = a by simpa
  rintro a' b hp rfl
  exact ⟨hp, rfl⟩
state_before: α : Type u_1
β : Type u_2
ι : Type ?u.395682
G : Type ?u.395685
M : Type u_3
N : Type ?u.395691
inst✝³ : CommMonoid M
inst✝² : CommMonoid N
f✝ g : α → M
a b : α
s✝ t : Set α
inst✝¹ : DecidableEq α
inst✝ : DecidableEq β
s : Finset (α × β)
f : α × β → M
⊢ (∏ᶠ (ab : α × β) (_ : ab ∈ s), f ab) =
    ∏ᶠ (a : α) (b : β) (_ : b ∈ Finset.image Prod.snd (Finset.filter (fun ab => ab.fst = a) s)), f (a, b)

tactic: rw [finprod_mem_finset_eq_prod]
state_before: α : Type u_1
β : Type u_2
ι : Type ?u.395682
G : Type ?u.395685
M : Type u_3
N : Type ?u.395691
inst✝³ : CommMonoid M
inst✝² : CommMonoid N
f✝ g : α → M
a b : α
s✝ t : Set α
inst✝¹ : DecidableEq α
inst✝ : DecidableEq β
s : Finset (α × β)
f : α × β → M
this :
  ∀ (a : α),
    ∏ i in Finset.image Prod.snd (Finset.filter (fun ab => ab.fst = a) s), f (a, i) =
      Finset.prod (Finset.filter (fun ab => ab.fst = a) s) f
⊢ (∏ᶠ (ab : α × β) (_ : ab ∈ s), f ab) =
    ∏ᶠ (a : α) (b : β) (_ : b ∈ Finset.image Prod.snd (Finset.filter (fun ab => ab.fst = a) s)), f (a, b)

tactic: simp_rw [finprod_mem_finset_eq_prod, this]
state_before: α : Type u_1
β : Type u_2
ι : Type ?u.395682
G : Type ?u.395685
M : Type u_3
N : Type ?u.395691
inst✝³ : CommMonoid M
inst✝² : CommMonoid N
f✝ g : α → M
a b : α
s✝ t : Set α
inst✝¹ : DecidableEq α
inst✝ : DecidableEq β
s : Finset (α × β)
f : α × β → M
this :
  ∀ (a : α),
    ∏ i in Finset.image Prod.snd (Finset.filter (fun ab => ab.fst = a) s), f (a, i) =
      Finset.prod (Finset.filter (fun ab => ab.fst = a) s) f
⊢ ∏ i in s, f i = ∏ᶠ (a : α) (b : β) (_ : b ∈ Finset.image Prod.snd (Finset.filter (fun ab => ab.fst = a) s)), f (a, b)

tactic: rw [finprod_eq_prod_of_mulSupport_subset _
    (s.mulSupport_of_fiberwise_prod_subset_image f Prod.fst),
  ← Finset.prod_fiberwise_of_maps_to (t := Finset.image Prod.fst s) _ f]
state_before: α : Type u_1
β : Type u_2
ι : Type ?u.395682
G : Type ?u.395685
M : Type u_3
N : Type ?u.395691
inst✝³ : CommMonoid M
inst✝² : CommMonoid N
f✝ g : α → M
a b : α
s✝ t : Set α
inst✝¹ : DecidableEq α
inst✝ : DecidableEq β
s : Finset (α × β)
f : α × β → M
this :
  ∀ (a : α),
    ∏ i in Finset.image Prod.snd (Finset.filter (fun ab => ab.fst = a) s), f (a, i) =
      Finset.prod (Finset.filter (fun ab => ab.fst = a) s) f
⊢ ∏ i in s, f i = ∏ᶠ (a : α), Finset.prod (Finset.filter (fun ab => ab.fst = a) s) f

tactic: simp only [Finset.mem_image, Prod.mk.eta]
state_before: α : Type u_1
β : Type u_2
ι : Type ?u.395682
G : Type ?u.395685
M : Type u_3
N : Type ?u.395691
inst✝³ : CommMonoid M
inst✝² : CommMonoid N
f✝ g : α → M
a b : α
s✝ t : Set α
inst✝¹ : DecidableEq α
inst✝ : DecidableEq β
s : Finset (α × β)
f : α × β → M
this :
  ∀ (a : α),
    ∏ i in Finset.image Prod.snd (Finset.filter (fun ab => ab.fst = a) s), f (a, i) =
      Finset.prod (Finset.filter (fun ab => ab.fst = a) s) f
⊢ ∀ (x : α × β), x ∈ s → x.fst ∈ Finset.image Prod.fst s

tactic: exact fun x hx => ⟨x, hx, rfl⟩
state_before: α : Type u_1
β : Type u_2
ι : Type ?u.395682
G : Type ?u.395685
M : Type u_3
N : Type ?u.395691
inst✝³ : CommMonoid M
inst✝² : CommMonoid N
f✝ g : α → M
a b : α
s✝ t : Set α
inst✝¹ : DecidableEq α
inst✝ : DecidableEq β
s : Finset (α × β)
f : α × β → M
this :
  ∀ (a : α),
    ∏ i in Finset.image Prod.snd (Finset.filter (fun ab => ab.fst = a) s), f (a, i) =
      Finset.prod (Finset.filter (fun ab => ab.fst = a) s) f
⊢ ∀ (x : α × β), x ∈ s → ∃ a, a ∈ s ∧ a.fst = x.fst

tactic: refine' fun a => Finset.prod_bij (fun b _ => (a, b)) _ _ _ _ <;>try simp; done
state_before: α : Type u_1
β : Type u_2
ι : Type ?u.395682
G : Type ?u.395685
M : Type u_3
N : Type ?u.395691
inst✝³ : CommMonoid M
inst✝² : CommMonoid N
f✝ g : α → M
a b : α
s✝ t : Set α
inst✝¹ : DecidableEq α
inst✝ : DecidableEq β
s : Finset (α × β)
f : α × β → M
⊢ ∀ (a : α),
    ∏ i in Finset.image Prod.snd (Finset.filter (fun ab => ab.fst = a) s), f (a, i) =
      Finset.prod (Finset.filter (fun ab => ab.fst = a) s) f

tactic: suffices ∀ a' b, (a', b) ∈ s → a' = a → (a, b) ∈ s ∧ a' = a by simpa
state_before: case refine'_4
α : Type u_1
β : Type u_2
ι : Type ?u.395682
G : Type ?u.395685
M : Type u_3
N : Type ?u.395691
inst✝³ : CommMonoid M
inst✝² : CommMonoid N
f✝ g : α → M
a✝ b : α
s✝ t : Set α
inst✝¹ : DecidableEq α
inst✝ : DecidableEq β
s : Finset (α × β)
f : α × β → M
a : α
⊢ ∀ (b : α × β), b ∈ Finset.filter (fun ab => ab.fst = a) s → ∃ a_2 ha, b = (fun b x => (a, b)) a_2 ha

tactic: rintro a' b hp rfl
state_before: case refine'_4
α : Type u_1
β : Type u_2
ι : Type ?u.395682
G : Type ?u.395685
M : Type u_3
N : Type ?u.395691
inst✝³ : CommMonoid M
inst✝² : CommMonoid N
f✝ g : α → M
a✝ b : α
s✝ t : Set α
inst✝¹ : DecidableEq α
inst✝ : DecidableEq β
s : Finset (α × β)
f : α × β → M
a : α
⊢ ∀ (a' : α) (b : β), (a', b) ∈ s → a' = a → (a, b) ∈ s ∧ a' = a

tactic: exact ⟨hp, rfl⟩
state_before: case refine'_4
α : Type u_1
β : Type u_2
ι : Type ?u.395682
G : Type ?u.395685
M : Type u_3
N : Type ?u.395691
inst✝³ : CommMonoid M
inst✝² : CommMonoid N
f✝ g : α → M
a b✝ : α
s✝ t : Set α
inst✝¹ : DecidableEq α
inst✝ : DecidableEq β
s : Finset (α × β)
f : α × β → M
a' : α
b : β
hp : (a', b) ∈ s
⊢ (a', b) ∈ s ∧ a' = a'

tactic: simp
state_before: case refine'_4
α : Type u_1
β : Type u_2
ι : Type ?u.395682
G : Type ?u.395685
M : Type u_3
N : Type ?u.395691
inst✝³ : CommMonoid M
inst✝² : CommMonoid N
f✝ g : α → M
a✝ b : α
s✝ t : Set α
inst✝¹ : DecidableEq α
inst✝ : DecidableEq β
s : Finset (α × β)
f : α × β → M
a : α
⊢ ∀ (b : α × β), b ∈ Finset.filter (fun ab => ab.fst = a) s → ∃ a_2 ha, b = (fun b x => (a, b)) a_2 ha

tactic: done
state_before: case refine'_4
α : Type u_1
β : Type u_2
ι : Type ?u.395682
G : Type ?u.395685
M : Type u_3
N : Type ?u.395691
inst✝³ : CommMonoid M
inst✝² : CommMonoid N
f✝ g : α → M
a✝ b : α
s✝ t : Set α
inst✝¹ : DecidableEq α
inst✝ : DecidableEq β
s : Finset (α × β)
f : α × β → M
a : α
⊢ ∀ (a_1 : α) (b : β), (a_1, b) ∈ s → a_1 = a → (a, b) ∈ s ∧ a_1 = a

tactic: simpa
state_before: α : Type u_1
β : Type u_2
ι : Type ?u.395682
G : Type ?u.395685
M : Type u_3
N : Type ?u.395691
inst✝³ : CommMonoid M
inst✝² : CommMonoid N
f✝ g : α → M
a✝ b : α
s✝ t : Set α
inst✝¹ : DecidableEq α
inst✝ : DecidableEq β
s : Finset (α × β)
f : α × β → M
a : α
this : ∀ (a' : α) (b : β), (a', b) ∈ s → a' = a → (a, b) ∈ s ∧ a' = a
⊢ ∀ (b : α × β), b ∈ Finset.filter (fun ab => ab.fst = a) s → ∃ a_2 ha, b = (fun b x => (a, b)) a_2 ha