l3lab/ntp-mathlib huggingface dataset:
theorem noncommProd_erase_mul [DecidableEq α] (s : Multiset α) {a : α} (h : a ∈ s) (comm)
    (comm' := fun x hx y hy hxy ↦ comm (s.mem_of_mem_erase hx) (s.mem_of_mem_erase hy) hxy) :
    (s.erase a).noncommProd comm' * a = s.noncommProd comm := by
  suffices ∀ b ∈ erase s a, Commute a b by
    rw [← (noncommProd_commute (s.erase a) comm' a this).eq, mul_noncommProd_erase s h comm comm']
  intro b hb
  rcases eq_or_ne a b with rfl | hab; 

Proof state:
case inl
F : Type u_1
ι : Type u_2
α : Type u_3
β : Type u_4
γ : Type u_5
f : α → β → β
op : α → α → α
inst✝² : Monoid α
inst✝¹ : Monoid β
inst✝ : DecidableEq α
s : Multiset α
a : α
h : a ∈ s
comm : Set.Pairwise {x | x ∈ s} Commute
comm' :
  optParam (∀ x ∈ {x | x ∈ erase s a}, ∀ y ∈ {x | x ∈ erase s a}, x ≠ y → Commute x y)
    (_ : ∀ x ∈ {x | x ∈ erase s a}, ∀ y ∈ {x | x ∈ erase s a}, x ≠ y → Commute x y)
hb : a ∈ erase s a
⊢ Commute a a
case inr
F : Type u_1
ι : Type u_2
α : Type u_3
β : Type u_4
γ : Type u_5
f : α → β → β
op : α → α → α
inst✝² : Monoid α
inst✝¹ : Monoid β
inst✝ : DecidableEq α
s : Multiset α
a : α
h : a ∈ s
comm : Set.Pairwise {x | x ∈ s} Commute
comm' :
  optParam (∀ x ∈ {x | x ∈ erase s a}, ∀ y ∈ {x | x ∈ erase s a}, x ≠ y → Commute x y)
    (_ : ∀ x ∈ {x | x ∈ erase s a}, ∀ y ∈ {x | x ∈ erase s a}, x ≠ y → Commute x y)
b : α
hb : b ∈ erase s a
hab : a ≠ b
⊢ Commute a b

Next tactic:
rfl
theorem noncommProd_erase_mul [DecidableEq α] (s : Multiset α) {a : α} (h : a ∈ s) (comm)
    (comm' := fun x hx y hy hxy ↦ comm (s.mem_of_mem_erase hx) (s.mem_of_mem_erase hy) hxy) :
    (s.erase a).noncommProd comm' * a = s.noncommProd comm := by
  suffices ∀ b ∈ erase s a, Commute a b by
    rw [← (noncommProd_commute (s.erase a) comm' a this).eq, mul_noncommProd_erase s h comm comm']
  intro b hb
  rcases eq_or_ne a b with rfl | hab; rfl
  

Proof state:
case inr
F : Type u_1
ι : Type u_2
α : Type u_3
β : Type u_4
γ : Type u_5
f : α → β → β
op : α → α → α
inst✝² : Monoid α
inst✝¹ : Monoid β
inst✝ : DecidableEq α
s : Multiset α
a : α
h : a ∈ s
comm : Set.Pairwise {x | x ∈ s} Commute
comm' :
  optParam (∀ x ∈ {x | x ∈ erase s a}, ∀ y ∈ {x | x ∈ erase s a}, x ≠ y → Commute x y)
    (_ : ∀ x ∈ {x | x ∈ erase s a}, ∀ y ∈ {x | x ∈ erase s a}, x ≠ y → Commute x y)
b : α
hb : b ∈ erase s a
hab : a ≠ b
⊢ Commute a b

Next tactic:
exact comm h (mem_of_mem_erase hb) hab
/-- Proof used in definition of `Finset.noncommProd` -/
@[to_additive]
theorem noncommProd_lemma (s : Finset α) (f : α → β)
    (comm : (s : Set α).Pairwise fun a b => Commute (f a) (f b)) :
    Set.Pairwise { x | x ∈ Multiset.map f s.val } Commute := by
  

Proof state:
F : Type u_1
ι : Type u_2
α : Type u_3
β : Type u_4
γ : Type u_5
f✝ : α → β → β
op : α → α → α
inst✝¹ : Monoid β
inst✝ : Monoid γ
s : Finset α
f : α → β
comm : Set.Pairwise ↑s fun a b => Commute (f a) (f b)
⊢ Set.Pairwise {x | x ∈ Multiset.map f s.val} Commute

Next tactic:
simp_rw [Multiset.mem_map]
/-- Proof used in definition of `Finset.noncommProd` -/
@[to_additive]
theorem noncommProd_lemma (s : Finset α) (f : α → β)
    (comm : (s : Set α).Pairwise fun a b => Commute (f a) (f b)) :
    Set.Pairwise { x | x ∈ Multiset.map f s.val } Commute := by
  simp_rw [Multiset.mem_map]
  

Proof state:
F : Type u_1
ι : Type u_2
α : Type u_3
β : Type u_4
γ : Type u_5
f✝ : α → β → β
op : α → α → α
inst✝¹ : Monoid β
inst✝ : Monoid γ
s : Finset α
f : α → β
comm : Set.Pairwise ↑s fun a b => Commute (f a) (f b)
⊢ Set.Pairwise {x | ∃ a ∈ s.val, f a = x} Commute

Next tactic:
rintro _ ⟨a, ha, rfl⟩ _ ⟨b, hb, rfl⟩ _
/-- Proof used in definition of `Finset.noncommProd` -/
@[to_additive]
theorem noncommProd_lemma (s : Finset α) (f : α → β)
    (comm : (s : Set α).Pairwise fun a b => Commute (f a) (f b)) :
    Set.Pairwise { x | x ∈ Multiset.map f s.val } Commute := by
  simp_rw [Multiset.mem_map]
  rintro _ ⟨a, ha, rfl⟩ _ ⟨b, hb, rfl⟩ _
  

Proof state:
case intro.intro.intro.intro
F : Type u_1
ι : Type u_2
α : Type u_3
β : Type u_4
γ : Type u_5
f✝ : α → β → β
op : α → α → α
inst✝¹ : Monoid β
inst✝ : Monoid γ
s : Finset α
f : α → β
comm : Set.Pairwise ↑s fun a b => Commute (f a) (f b)
a : α
ha : a ∈ s.val
b : α
hb : b ∈ s.val
a✝ : f a ≠ f b
⊢ Commute (f a) (f b)

Next tactic:
exact comm.of_refl ha hb
@[to_additive]
lemma noncommProd_induction (s : Finset α) (f : α → β) (comm)
    (p : β → Prop) (hom : ∀ a b, p a → p b → p (a * b)) (unit : p 1) (base : ∀ x ∈ s, p (f x)) :
    p (s.noncommProd f comm) := by
  

Proof state:
F : Type u_1
ι : Type u_2
α : Type u_3
β : Type u_4
γ : Type u_5
f✝ : α → β → β
op : α → α → α
inst✝¹ : Monoid β
inst✝ : Monoid γ
s : Finset α
f : α → β
comm : Set.Pairwise ↑s fun a b => Commute (f a) (f b)
p : β → Prop
hom : ∀ (a b : β), p a → p b → p (a * b)
unit : p 1
base : ∀ x ∈ s, p (f x)
⊢ p (noncommProd s f comm)

Next tactic:
refine Multiset.noncommProd_induction _ _ _ hom unit fun b hb ↦ ?_
@[to_additive]
lemma noncommProd_induction (s : Finset α) (f : α → β) (comm)
    (p : β → Prop) (hom : ∀ a b, p a → p b → p (a * b)) (unit : p 1) (base : ∀ x ∈ s, p (f x)) :
    p (s.noncommProd f comm) := by
  refine Multiset.noncommProd_induction _ _ _ hom unit fun b hb ↦ ?_
  

Proof state:
F : Type u_1
ι : Type u_2
α : Type u_3
β : Type u_4
γ : Type u_5
f✝ : α → β → β
op : α → α → α
inst✝¹ : Monoid β
inst✝ : Monoid γ
s : Finset α
f : α → β
comm : Set.Pairwise ↑s fun a b => Commute (f a) (f b)
p : β → Prop
hom : ∀ (a b : β), p a → p b → p (a * b)
unit : p 1
base : ∀ x ∈ s, p (f x)
b : β
hb : b ∈ Multiset.map f s.val
⊢ p b

Next tactic:
obtain (⟨a, ha : a ∈ s, rfl : f a = b⟩) := by simpa using hb
@[to_additive]
lemma noncommProd_induction (s : Finset α) (f : α → β) (comm)
    (p : β → Prop) (hom : ∀ a b, p a → p b → p (a * b)) (unit : p 1) (base : ∀ x ∈ s, p (f x)) :
    p (s.noncommProd f comm) := by
  refine Multiset.noncommProd_induction _ _ _ hom unit fun b hb ↦ ?_
  obtain (⟨a, ha : a ∈ s, rfl : f a = b⟩) := by 

Proof state:
F : Type u_1
ι : Type u_2
α : Type u_3
β : Type u_4
γ : Type u_5
f✝ : α → β → β
op : α → α → α
inst✝¹ : Monoid β
inst✝ : Monoid γ
s : Finset α
f : α → β
comm : Set.Pairwise ↑s fun a b => Commute (f a) (f b)
p : β → Prop
hom : ∀ (a b : β), p a → p b → p (a * b)
unit : p 1
base : ∀ x ∈ s, p (f x)
b : β
hb : b ∈ Multiset.map f s.val
⊢ ?m.126078

Next tactic:
simpa using hb
@[to_additive]
lemma noncommProd_induction (s : Finset α) (f : α → β) (comm)
    (p : β → Prop) (hom : ∀ a b, p a → p b → p (a * b)) (unit : p 1) (base : ∀ x ∈ s, p (f x)) :
    p (s.noncommProd f comm) := by
  refine Multiset.noncommProd_induction _ _ _ hom unit fun b hb ↦ ?_
  obtain (⟨a, ha : a ∈ s, rfl : f a = b⟩) := by simpa using hb
  

Proof state:
case intro.intro
F : Type u_1
ι : Type u_2
α : Type u_3
β : Type u_4
γ : Type u_5
f✝ : α → β → β
op : α → α → α
inst✝¹ : Monoid β
inst✝ : Monoid γ
s : Finset α
f : α → β
comm : Set.Pairwise ↑s fun a b => Commute (f a) (f b)
p : β → Prop
hom : ∀ (a b : β), p a → p b → p (a * b)
unit : p 1
base : ∀ x ∈ s, p (f x)
a : α
ha : a ∈ s
hb : f a ∈ Multiset.map f s.val
⊢ p (f a)

Next tactic:
exact base a ha
@[to_additive (attr := congr)]
theorem noncommProd_congr {s₁ s₂ : Finset α} {f g : α → β} (h₁ : s₁ = s₂)
    (h₂ : ∀ x ∈ s₂, f x = g x) (comm) :
    noncommProd s₁ f comm =
      noncommProd s₂ g fun x hx y hy h => by
        

Proof state:
F : Type u_1
ι : Type u_2
α : Type u_3
β : Type u_4
γ : Type u_5
f✝ : α → β → β
op : α → α → α
inst✝¹ : Monoid β
inst✝ : Monoid γ
s₁ s₂ : Finset α
f g : α → β
h₁ : s₁ = s₂
h₂ : ∀ x ∈ s₂, f x = g x
comm : Set.Pairwise ↑s₁ fun a b => Commute (f a) (f b)
x : α
hx : x ∈ ↑s₂
y : α
hy : y ∈ ↑s₂
h : x ≠ y
⊢ (fun a b => Commute (g a) (g b)) x y

Next tactic:
dsimp only
@[to_additive (attr := congr)]
theorem noncommProd_congr {s₁ s₂ : Finset α} {f g : α → β} (h₁ : s₁ = s₂)
    (h₂ : ∀ x ∈ s₂, f x = g x) (comm) :
    noncommProd s₁ f comm =
      noncommProd s₂ g fun x hx y hy h => by
        dsimp only
        

Proof state:
F : Type u_1
ι : Type u_2
α : Type u_3
β : Type u_4
γ : Type u_5
f✝ : α → β → β
op : α → α → α
inst✝¹ : Monoid β
inst✝ : Monoid γ
s₁ s₂ : Finset α
f g : α → β
h₁ : s₁ = s₂
h₂ : ∀ x ∈ s₂, f x = g x
comm : Set.Pairwise ↑s₁ fun a b => Commute (f a) (f b)
x : α
hx : x ∈ ↑s₂
y : α
hy : y ∈ ↑s₂
h : x ≠ y
⊢ Commute (g x) (g y)

Next tactic:
rw [← h₂ _ hx, ← h₂ _ hy]
@[to_additive (attr := congr)]
theorem noncommProd_congr {s₁ s₂ : Finset α} {f g : α → β} (h₁ : s₁ = s₂)
    (h₂ : ∀ x ∈ s₂, f x = g x) (comm) :
    noncommProd s₁ f comm =
      noncommProd s₂ g fun x hx y hy h => by
        dsimp only
        rw [← h₂ _ hx, ← h₂ _ hy]
        

Proof state:
F : Type u_1
ι : Type u_2
α : Type u_3
β : Type u_4
γ : Type u_5
f✝ : α → β → β
op : α → α → α
inst✝¹ : Monoid β
inst✝ : Monoid γ
s₁ s₂ : Finset α
f g : α → β
h₁ : s₁ = s₂
h₂ : ∀ x ∈ s₂, f x = g x
comm : Set.Pairwise ↑s₁ fun a b => Commute (f a) (f b)
x : α
hx : x ∈ ↑s₂
y : α
hy : y ∈ ↑s₂
h : x ≠ y
⊢ Commute (f x) (f y)

Next tactic:
subst h₁
@[to_additive (attr := congr)]
theorem noncommProd_congr {s₁ s₂ : Finset α} {f g : α → β} (h₁ : s₁ = s₂)
    (h₂ : ∀ x ∈ s₂, f x = g x) (comm) :
    noncommProd s₁ f comm =
      noncommProd s₂ g fun x hx y hy h => by
        dsimp only
        rw [← h₂ _ hx, ← h₂ _ hy]
        subst h₁
        

Proof state:
F : Type u_1
ι : Type u_2
α : Type u_3
β : Type u_4
γ : Type u_5
f✝ : α → β → β
op : α → α → α
inst✝¹ : Monoid β
inst✝ : Monoid γ
s₁ : Finset α
f g : α → β
comm : Set.Pairwise ↑s₁ fun a b => Commute (f a) (f b)
x y : α
h : x ≠ y
h₂ : ∀ x ∈ s₁, f x = g x
hx : x ∈ ↑s₁
hy : y ∈ ↑s₁
⊢ Commute (f x) (f y)

Next tactic:
exact comm hx hy h
@[to_additive (attr := congr)]
theorem noncommProd_congr {s₁ s₂ : Finset α} {f g : α → β} (h₁ : s₁ = s₂)
    (h₂ : ∀ x ∈ s₂, f x = g x) (comm) :
    noncommProd s₁ f comm =
      noncommProd s₂ g fun x hx y hy h => by
        dsimp only
        rw [← h₂ _ hx, ← h₂ _ hy]
        subst h₁
        exact comm hx hy h :=
  by 

Proof state:
F : Type u_1
ι : Type u_2
α : Type u_3
β : Type u_4
γ : Type u_5
f✝ : α → β → β
op : α → α → α
inst✝¹ : Monoid β
inst✝ : Monoid γ
s₁ s₂ : Finset α
f g : α → β
h₁ : s₁ = s₂
h₂ : ∀ x ∈ s₂, f x = g x
comm : Set.Pairwise ↑s₁ fun a b => Commute (f a) (f b)
⊢ noncommProd s₁ f comm = noncommProd s₂ g (_ : ∀ x ∈ ↑s₂, ∀ y ∈ ↑s₂, x ≠ y → (fun a b => Commute (g a) (g b)) x y)

Next tactic:
simp_rw [noncommProd, Multiset.map_congr (congr_arg _ h₁) h₂]
@[to_additive (attr := simp)]
theorem noncommProd_toFinset [DecidableEq α] (l : List α) (f : α → β) (comm) (hl : l.Nodup) :
    noncommProd l.toFinset f comm = (l.map f).prod := by
  

Proof state:
F : Type u_1
ι : Type u_2
α : Type u_3
β : Type u_4
γ : Type u_5
f✝ : α → β → β
op : α → α → α
inst✝² : Monoid β
inst✝¹ : Monoid γ
inst✝ : DecidableEq α
l : List α
f : α → β
comm : Set.Pairwise ↑(List.toFinset l) fun a b => Commute (f a) (f b)
hl : List.Nodup l
⊢ noncommProd (List.toFinset l) f comm = List.prod (List.map f l)

Next tactic:
rw [← List.dedup_eq_self] at hl
@[to_additive (attr := simp)]
theorem noncommProd_toFinset [DecidableEq α] (l : List α) (f : α → β) (comm) (hl : l.Nodup) :
    noncommProd l.toFinset f comm = (l.map f).prod := by
  rw [← List.dedup_eq_self] at hl
  

Proof state:
F : Type u_1
ι : Type u_2
α : Type u_3
β : Type u_4
γ : Type u_5
f✝ : α → β → β
op : α → α → α
inst✝² : Monoid β
inst✝¹ : Monoid γ
inst✝ : DecidableEq α
l : List α
f : α → β
comm : Set.Pairwise ↑(List.toFinset l) fun a b => Commute (f a) (f b)
hl : List.dedup l = l
⊢ noncommProd (List.toFinset l) f comm = List.prod (List.map f l)

Next tactic:
simp [noncommProd, hl]
@[to_additive (attr := simp)]
theorem noncommProd_insert_of_not_mem [DecidableEq α] (s : Finset α) (a : α) (f : α → β) (comm)
    (ha : a ∉ s) :
    noncommProd (insert a s) f comm =
      f a * noncommProd s f (comm.mono fun _ => mem_insert_of_mem) :=
  calc noncommProd (insert a s) f comm
     = Multiset.noncommProd ((insert a s).val.map f) _ := rfl
   _ = Multiset.noncommProd (f a ::ₘ s.1.map f)
     (by 

Proof state:
F : Type u_1
ι : Type u_2
α : Type u_3
β : Type u_4
γ : Type u_5
f✝ : α → β → β
op : α → α → α
inst✝² : Monoid β
inst✝¹ : Monoid γ
inst✝ : DecidableEq α
s : Finset α
a : α
f : α → β
comm : Set.Pairwise ↑(insert a s) fun a b => Commute (f a) (f b)
ha : a ∉ s
⊢ Set.Pairwise {x | x ∈ f a ::ₘ Multiset.map f s.val} Commute

Next tactic:
convert noncommProd_lemma _ f comm using 3
@[to_additive (attr := simp)]
theorem noncommProd_insert_of_not_mem [DecidableEq α] (s : Finset α) (a : α) (f : α → β) (comm)
    (ha : a ∉ s) :
    noncommProd (insert a s) f comm =
      f a * noncommProd s f (comm.mono fun _ => mem_insert_of_mem) :=
  calc noncommProd (insert a s) f comm
     = Multiset.noncommProd ((insert a s).val.map f) _ := rfl
   _ = Multiset.noncommProd (f a ::ₘ s.1.map f)
     (by convert noncommProd_lemma _ f comm using 3
         

Proof state:
case h.e'_2.h.e'_2.h.a
F : Type u_1
ι : Type u_2
α : Type u_3
β : Type u_4
γ : Type u_5
f✝ : α → β → β
op : α → α → α
inst✝² : Monoid β
inst✝¹ : Monoid γ
inst✝ : DecidableEq α
s : Finset α
a : α
f : α → β
comm : Set.Pairwise ↑(insert a s) fun a b => Commute (f a) (f b)
ha : a ∉ s
x✝ : β
⊢ x✝ ∈ f a ::ₘ Multiset.map f s.val ↔ x✝ ∈ Multiset.map f (insert a s).val

Next tactic:
simp [@eq_comm _ (f a)]
@[to_additive (attr := simp)]
theorem noncommProd_insert_of_not_mem [DecidableEq α] (s : Finset α) (a : α) (f : α → β) (comm)
    (ha : a ∉ s) :
    noncommProd (insert a s) f comm =
      f a * noncommProd s f (comm.mono fun _ => mem_insert_of_mem) :=
  calc noncommProd (insert a s) f comm
     = Multiset.noncommProd ((insert a s).val.map f) _ := rfl
   _ = Multiset.noncommProd (f a ::ₘ s.1.map f)
     (by convert noncommProd_lemma _ f comm using 3
         simp [@eq_comm _ (f a)]) := by
       

Proof state:
F : Type u_1
ι : Type u_2
α : Type u_3
β : Type u_4
γ : Type u_5
f✝ : α → β → β
op : α → α → α
inst✝² : Monoid β
inst✝¹ : Monoid γ
inst✝ : DecidableEq α
s : Finset α
a : α
f : α → β
comm : Set.Pairwise ↑(insert a s) fun a b => Commute (f a) (f b)
ha : a ∉ s
⊢ Multiset.noncommProd (Multiset.map f (insert a s).val)
      (_ : Set.Pairwise {x | x ∈ Multiset.map f (insert a s).val} Commute) =
    Multiset.noncommProd (f a ::ₘ Multiset.map f s.val)
      (_ : Set.Pairwise {x | x ∈ f a ::ₘ Multiset.map f s.val} Commute)

Next tactic:
{ congr
         rw [insert_val_of_not_mem ha, Multiset.map_cons] }
@[to_additive (attr := simp)]
theorem noncommProd_insert_of_not_mem [DecidableEq α] (s : Finset α) (a : α) (f : α → β) (comm)
    (ha : a ∉ s) :
    noncommProd (insert a s) f comm =
      f a * noncommProd s f (comm.mono fun _ => mem_insert_of_mem) :=
  calc noncommProd (insert a s) f comm
     = Multiset.noncommProd ((insert a s).val.map f) _ := rfl
   _ = Multiset.noncommProd (f a ::ₘ s.1.map f)
     (by convert noncommProd_lemma _ f comm using 3
         simp [@eq_comm _ (f a)]) := by
       { 

Proof state:
F : Type u_1
ι : Type u_2
α : Type u_3
β : Type u_4
γ : Type u_5
f✝ : α → β → β
op : α → α → α
inst✝² : Monoid β
inst✝¹ : Monoid γ
inst✝ : DecidableEq α
s : Finset α
a : α
f : α → β
comm : Set.Pairwise ↑(insert a s) fun a b => Commute (f a) (f b)
ha : a ∉ s
⊢ Multiset.noncommProd (Multiset.map f (insert a s).val)
      (_ : Set.Pairwise {x | x ∈ Multiset.map f (insert a s).val} Commute) =
    Multiset.noncommProd (f a ::ₘ Multiset.map f s.val)
      (_ : Set.Pairwise {x | x ∈ f a ::ₘ Multiset.map f s.val} Commute)

Next tactic:
congr
@[to_additive (attr := simp)]
theorem noncommProd_insert_of_not_mem [DecidableEq α] (s : Finset α) (a : α) (f : α → β) (comm)
    (ha : a ∉ s) :
    noncommProd (insert a s) f comm =
      f a * noncommProd s f (comm.mono fun _ => mem_insert_of_mem) :=
  calc noncommProd (insert a s) f comm
     = Multiset.noncommProd ((insert a s).val.map f) _ := rfl
   _ = Multiset.noncommProd (f a ::ₘ s.1.map f)
     (by convert noncommProd_lemma _ f comm using 3
         simp [@eq_comm _ (f a)]) := by
       { congr
         

Proof state:
case e_s
F : Type u_1
ι : Type u_2
α : Type u_3
β : Type u_4
γ : Type u_5
f✝ : α → β → β
op : α → α → α
inst✝² : Monoid β
inst✝¹ : Monoid γ
inst✝ : DecidableEq α
s : Finset α
a : α
f : α → β
comm : Set.Pairwise ↑(insert a s) fun a b => Commute (f a) (f b)
ha : a ∉ s
⊢ Multiset.map f (insert a s).val = f a ::ₘ Multiset.map f s.val

Next tactic:
rw [insert_val_of_not_mem ha, Multiset.map_cons]
@[to_additive (attr := simp)]
theorem noncommProd_insert_of_not_mem [DecidableEq α] (s : Finset α) (a : α) (f : α → β) (comm)
    (ha : a ∉ s) :
    noncommProd (insert a s) f comm =
      f a * noncommProd s f (comm.mono fun _ => mem_insert_of_mem) :=
  calc noncommProd (insert a s) f comm
     = Multiset.noncommProd ((insert a s).val.map f) _ := rfl
   _ = Multiset.noncommProd (f a ::ₘ s.1.map f)
     (by convert noncommProd_lemma _ f comm using 3
         simp [@eq_comm _ (f a)]) := by
       { congr
         rw [insert_val_of_not_mem ha, Multiset.map_cons] }
   _ = _ := by 

Proof state:
F : Type u_1
ι : Type u_2
α : Type u_3
β : Type u_4
γ : Type u_5
f✝ : α → β → β
op : α → α → α
inst✝² : Monoid β
inst✝¹ : Monoid γ
inst✝ : DecidableEq α
s : Finset α
a : α
f : α → β
comm : Set.Pairwise ↑(insert a s) fun a b => Commute (f a) (f b)
ha : a ∉ s
⊢ Multiset.noncommProd (f a ::ₘ Multiset.map f s.val)
      (_ : Set.Pairwise {x | x ∈ f a ::ₘ Multiset.map f s.val} Commute) =
    f a * noncommProd s f (_ : Set.Pairwise ↑s fun a b => Commute (f a) (f b))

Next tactic:
rw [Multiset.noncommProd_cons, noncommProd]
@[to_additive]
theorem noncommProd_insert_of_not_mem' [DecidableEq α] (s : Finset α) (a : α) (f : α → β) (comm)
    (ha : a ∉ s) :
    noncommProd (insert a s) f comm =
      noncommProd s f (comm.mono fun _ => mem_insert_of_mem) * f a :=
  calc noncommProd (insert a s) f comm
     = Multiset.noncommProd ((insert a s).val.map f) _ := rfl
   _ = Multiset.noncommProd (f a ::ₘ s.1.map f)
     (by 

Proof state:
F : Type u_1
ι : Type u_2
α : Type u_3
β : Type u_4
γ : Type u_5
f✝ : α → β → β
op : α → α → α
inst✝² : Monoid β
inst✝¹ : Monoid γ
inst✝ : DecidableEq α
s : Finset α
a : α
f : α → β
comm : Set.Pairwise ↑(insert a s) fun a b => Commute (f a) (f b)
ha : a ∉ s
⊢ Set.Pairwise {x | x ∈ f a ::ₘ Multiset.map f s.val} Commute

Next tactic:
convert noncommProd_lemma _ f comm using 3
@[to_additive]
theorem noncommProd_insert_of_not_mem' [DecidableEq α] (s : Finset α) (a : α) (f : α → β) (comm)
    (ha : a ∉ s) :
    noncommProd (insert a s) f comm =
      noncommProd s f (comm.mono fun _ => mem_insert_of_mem) * f a :=
  calc noncommProd (insert a s) f comm
     = Multiset.noncommProd ((insert a s).val.map f) _ := rfl
   _ = Multiset.noncommProd (f a ::ₘ s.1.map f)
     (by convert noncommProd_lemma _ f comm using 3
         

Proof state:
case h.e'_2.h.e'_2.h.a
F : Type u_1
ι : Type u_2
α : Type u_3
β : Type u_4
γ : Type u_5
f✝ : α → β → β
op : α → α → α
inst✝² : Monoid β
inst✝¹ : Monoid γ
inst✝ : DecidableEq α
s : Finset α
a : α
f : α → β
comm : Set.Pairwise ↑(insert a s) fun a b => Commute (f a) (f b)
ha : a ∉ s
x✝ : β
⊢ x✝ ∈ f a ::ₘ Multiset.map f s.val ↔ x✝ ∈ Multiset.map f (insert a s).val

Next tactic:
simp [@eq_comm _ (f a)]
@[to_additive]
theorem noncommProd_insert_of_not_mem' [DecidableEq α] (s : Finset α) (a : α) (f : α → β) (comm)
    (ha : a ∉ s) :
    noncommProd (insert a s) f comm =
      noncommProd s f (comm.mono fun _ => mem_insert_of_mem) * f a :=
  calc noncommProd (insert a s) f comm
     = Multiset.noncommProd ((insert a s).val.map f) _ := rfl
   _ = Multiset.noncommProd (f a ::ₘ s.1.map f)
     (by convert noncommProd_lemma _ f comm using 3
         simp [@eq_comm _ (f a)]) := by
       

Proof state:
F : Type u_1
ι : Type u_2
α : Type u_3
β : Type u_4
γ : Type u_5
f✝ : α → β → β
op : α → α → α
inst✝² : Monoid β
inst✝¹ : Monoid γ
inst✝ : DecidableEq α
s : Finset α
a : α
f : α → β
comm : Set.Pairwise ↑(insert a s) fun a b => Commute (f a) (f b)
ha : a ∉ s
⊢ Multiset.noncommProd (Multiset.map f (insert a s).val)
      (_ : Set.Pairwise {x | x ∈ Multiset.map f (insert a s).val} Commute) =
    Multiset.noncommProd (f a ::ₘ Multiset.map f s.val)
      (_ : Set.Pairwise {x | x ∈ f a ::ₘ Multiset.map f s.val} Commute)

Next tactic:
{ congr
         rw [insert_val_of_not_mem ha, Multiset.map_cons] }
@[to_additive]
theorem noncommProd_insert_of_not_mem' [DecidableEq α] (s : Finset α) (a : α) (f : α → β) (comm)
    (ha : a ∉ s) :
    noncommProd (insert a s) f comm =
      noncommProd s f (comm.mono fun _ => mem_insert_of_mem) * f a :=
  calc noncommProd (insert a s) f comm
     = Multiset.noncommProd ((insert a s).val.map f) _ := rfl
   _ = Multiset.noncommProd (f a ::ₘ s.1.map f)
     (by convert noncommProd_lemma _ f comm using 3
         simp [@eq_comm _ (f a)]) := by
       { 

Proof state:
F : Type u_1
ι : Type u_2
α : Type u_3
β : Type u_4
γ : Type u_5
f✝ : α → β → β
op : α → α → α
inst✝² : Monoid β
inst✝¹ : Monoid γ
inst✝ : DecidableEq α
s : Finset α
a : α
f : α → β
comm : Set.Pairwise ↑(insert a s) fun a b => Commute (f a) (f b)
ha : a ∉ s
⊢ Multiset.noncommProd (Multiset.map f (insert a s).val)
      (_ : Set.Pairwise {x | x ∈ Multiset.map f (insert a s).val} Commute) =
    Multiset.noncommProd (f a ::ₘ Multiset.map f s.val)
      (_ : Set.Pairwise {x | x ∈ f a ::ₘ Multiset.map f s.val} Commute)

Next tactic:
congr
@[to_additive]
theorem noncommProd_insert_of_not_mem' [DecidableEq α] (s : Finset α) (a : α) (f : α → β) (comm)
    (ha : a ∉ s) :
    noncommProd (insert a s) f comm =
      noncommProd s f (comm.mono fun _ => mem_insert_of_mem) * f a :=
  calc noncommProd (insert a s) f comm
     = Multiset.noncommProd ((insert a s).val.map f) _ := rfl
   _ = Multiset.noncommProd (f a ::ₘ s.1.map f)
     (by convert noncommProd_lemma _ f comm using 3
         simp [@eq_comm _ (f a)]) := by
       { congr
         

Proof state:
case e_s
F : Type u_1
ι : Type u_2
α : Type u_3
β : Type u_4
γ : Type u_5
f✝ : α → β → β
op : α → α → α
inst✝² : Monoid β
inst✝¹ : Monoid γ
inst✝ : DecidableEq α
s : Finset α
a : α
f : α → β
comm : Set.Pairwise ↑(insert a s) fun a b => Commute (f a) (f b)
ha : a ∉ s
⊢ Multiset.map f (insert a s).val = f a ::ₘ Multiset.map f s.val

Next tactic:
rw [insert_val_of_not_mem ha, Multiset.map_cons]
@[to_additive]
theorem noncommProd_insert_of_not_mem' [DecidableEq α] (s : Finset α) (a : α) (f : α → β) (comm)
    (ha : a ∉ s) :
    noncommProd (insert a s) f comm =
      noncommProd s f (comm.mono fun _ => mem_insert_of_mem) * f a :=
  calc noncommProd (insert a s) f comm
     = Multiset.noncommProd ((insert a s).val.map f) _ := rfl
   _ = Multiset.noncommProd (f a ::ₘ s.1.map f)
     (by convert noncommProd_lemma _ f comm using 3
         simp [@eq_comm _ (f a)]) := by
       { congr
         rw [insert_val_of_not_mem ha, Multiset.map_cons] }
   _ = _ := by 

Proof state:
F : Type u_1
ι : Type u_2
α : Type u_3
β : Type u_4
γ : Type u_5
f✝ : α → β → β
op : α → α → α
inst✝² : Monoid β
inst✝¹ : Monoid γ
inst✝ : DecidableEq α
s : Finset α
a : α
f : α → β
comm : Set.Pairwise ↑(insert a s) fun a b => Commute (f a) (f b)
ha : a ∉ s
⊢ Multiset.noncommProd (f a ::ₘ Multiset.map f s.val)
      (_ : Set.Pairwise {x | x ∈ f a ::ₘ Multiset.map f s.val} Commute) =
    noncommProd s f (_ : Set.Pairwise ↑s fun a b => Commute (f a) (f b)) * f a

Next tactic:
rw [Multiset.noncommProd_cons', noncommProd]
@[to_additive (attr := simp)]
theorem noncommProd_singleton (a : α) (f : α → β) :
    noncommProd ({a} : Finset α) f
        (by
          

Proof state:
F : Type u_1
ι : Type u_2
α : Type u_3
β : Type u_4
γ : Type u_5
f✝ : α → β → β
op : α → α → α
inst✝¹ : Monoid β
inst✝ : Monoid γ
a : α
f : α → β
⊢ Set.Pairwise ↑{a} fun a b => Commute (f a) (f b)

Next tactic:
norm_cast
@[to_additive (attr := simp)]
theorem noncommProd_singleton (a : α) (f : α → β) :
    noncommProd ({a} : Finset α) f
        (by
          norm_cast
          

Proof state:
F : Type u_1
ι : Type u_2
α : Type u_3
β : Type u_4
γ : Type u_5
f✝ : α → β → β
op : α → α → α
inst✝¹ : Monoid β
inst✝ : Monoid γ
a : α
f : α → β
⊢ Set.Pairwise {a} fun a b => Commute (f a) (f b)

Next tactic:
exact Set.pairwise_singleton _ _