l3lab/ntp-mathlib huggingface dataset:
/-- `Finset.noncommProd` is “injective” in `f` if `f` maps into independent subgroups.  This
generalizes (one direction of) `Subgroup.disjoint_iff_mul_eq_one`. -/
@[to_additive "`Finset.noncommSum` is “injective” in `f` if `f` maps into independent subgroups.
This generalizes (one direction of) `AddSubgroup.disjoint_iff_add_eq_zero`. "]
theorem eq_one_of_noncommProd_eq_one_of_independent {ι : Type*} (s : Finset ι) (f : ι → G) (comm)
    (K : ι → Subgroup G) (hind : CompleteLattice.Independent K) (hmem : ∀ x ∈ s, f x ∈ K x)
    (heq1 : s.noncommProd f comm = 1) : ∀ i ∈ s, f i = 1 := by
  classical
    revert heq1
    induction' s using Finset.induction_on with i s hnmem ih
    · simp
    · have hcomm := comm.mono (Finset.coe_subset.2 <| Finset.subset_insert _ _)
      simp only [Finset.forall_mem_insert] at hmem
      have hmem_bsupr : s.noncommProd f hcomm ∈ ⨆ i ∈ (s : Set ι), K i := by
        refine' Subgroup.noncommProd_mem _ _ _
        intro x hx
        have : K x ≤ ⨆ i ∈ (s : Set ι), K i := le_iSup₂ (f := fun i _ => K i) x hx
        exact this (hmem.2 x hx)
      intro heq1
      rw [Finset.noncommProd_insert_of_not_mem _ _ _ _ hnmem] at heq1
      have hnmem' : i ∉ (s : Set ι) := by simpa
      obtain ⟨heq1i : f i = 1, heq1S : s.noncommProd f _ = 1⟩ :=
        Subgroup.disjoint_iff_mul_eq_one.mp (hind.disjoint_biSup hnmem') hmem.1 hmem_bsupr heq1
      intro i h
      simp only [Finset.mem_insert] at h
      rcases h with (rfl | h)
      · 

Proof state:
case insert.intro.inl
G : Type u_1
inst✝ : Group G
ι : Type u_2
f : ι → G
K : ι → Subgroup G
hind : CompleteLattice.Independent K
s : Finset ι
ih :
  ∀ (comm : Set.Pairwise ↑s fun a b => Commute (f a) (f b)),
    (∀ x ∈ s, f x ∈ K x) → Finset.noncommProd s f comm = 1 → ∀ i ∈ s, f i = 1
hcomm : Set.Pairwise ↑s fun a b => Commute (f a) (f b)
hmem_bsupr : Finset.noncommProd s f hcomm ∈ ⨆ i ∈ ↑s, K i
heq1S : Finset.noncommProd s f hcomm = 1
i : ι
hnmem : i ∉ s
comm : Set.Pairwise ↑(insert i s) fun a b => Commute (f a) (f b)
hmem : f i ∈ K i ∧ ∀ x ∈ s, f x ∈ K x
heq1 : f i * Finset.noncommProd s f (_ : Set.Pairwise ↑s fun a b => Commute (f a) (f b)) = 1
hnmem' : i ∉ ↑s
heq1i : f i = 1
⊢ f i = 1

Next tactic:
exact heq1i
/-- `Finset.noncommProd` is “injective” in `f` if `f` maps into independent subgroups.  This
generalizes (one direction of) `Subgroup.disjoint_iff_mul_eq_one`. -/
@[to_additive "`Finset.noncommSum` is “injective” in `f` if `f` maps into independent subgroups.
This generalizes (one direction of) `AddSubgroup.disjoint_iff_add_eq_zero`. "]
theorem eq_one_of_noncommProd_eq_one_of_independent {ι : Type*} (s : Finset ι) (f : ι → G) (comm)
    (K : ι → Subgroup G) (hind : CompleteLattice.Independent K) (hmem : ∀ x ∈ s, f x ∈ K x)
    (heq1 : s.noncommProd f comm = 1) : ∀ i ∈ s, f i = 1 := by
  classical
    revert heq1
    induction' s using Finset.induction_on with i s hnmem ih
    · simp
    · have hcomm := comm.mono (Finset.coe_subset.2 <| Finset.subset_insert _ _)
      simp only [Finset.forall_mem_insert] at hmem
      have hmem_bsupr : s.noncommProd f hcomm ∈ ⨆ i ∈ (s : Set ι), K i := by
        refine' Subgroup.noncommProd_mem _ _ _
        intro x hx
        have : K x ≤ ⨆ i ∈ (s : Set ι), K i := le_iSup₂ (f := fun i _ => K i) x hx
        exact this (hmem.2 x hx)
      intro heq1
      rw [Finset.noncommProd_insert_of_not_mem _ _ _ _ hnmem] at heq1
      have hnmem' : i ∉ (s : Set ι) := by simpa
      obtain ⟨heq1i : f i = 1, heq1S : s.noncommProd f _ = 1⟩ :=
        Subgroup.disjoint_iff_mul_eq_one.mp (hind.disjoint_biSup hnmem') hmem.1 hmem_bsupr heq1
      intro i h
      simp only [Finset.mem_insert] at h
      rcases h with (rfl | h)
      · exact heq1i
      · 

Proof state:
case insert.intro.inr
G : Type u_1
inst✝ : Group G
ι : Type u_2
f : ι → G
K : ι → Subgroup G
hind : CompleteLattice.Independent K
i✝ : ι
s : Finset ι
hnmem : i✝ ∉ s
ih :
  ∀ (comm : Set.Pairwise ↑s fun a b => Commute (f a) (f b)),
    (∀ x ∈ s, f x ∈ K x) → Finset.noncommProd s f comm = 1 → ∀ i ∈ s, f i = 1
comm : Set.Pairwise ↑(insert i✝ s) fun a b => Commute (f a) (f b)
hcomm : Set.Pairwise ↑s fun a b => Commute (f a) (f b)
hmem : f i✝ ∈ K i✝ ∧ ∀ x ∈ s, f x ∈ K x
hmem_bsupr : Finset.noncommProd s f hcomm ∈ ⨆ i ∈ ↑s, K i
heq1 : f i✝ * Finset.noncommProd s f (_ : Set.Pairwise ↑s fun a b => Commute (f a) (f b)) = 1
hnmem' : i✝ ∉ ↑s
heq1i : f i✝ = 1
heq1S : Finset.noncommProd s f hcomm = 1
i : ι
h : i ∈ s
⊢ f i = 1

Next tactic:
refine' ih hcomm hmem.2 heq1S _ h
/-- The canonical homomorphism from a family of monoids. -/
@[to_additive "The canonical homomorphism from a family of additive monoids. See also
`LinearMap.lsum` for a linear version without the commutativity assumption."]
def noncommPiCoprod : (∀ i : ι, N i) →* M
    where
  toFun f := Finset.univ.noncommProd (fun i => ϕ i (f i)) fun i _ j _ h => hcomm h _ _
  map_one' := by
    

Proof state:
M : Type u_1
inst✝² : Monoid M
ι : Type u_2
hdec : DecidableEq ι
inst✝¹ : Fintype ι
N : ι → Type u_3
inst✝ : (i : ι) → Monoid (N i)
ϕ : (i : ι) → N i →* M
hcomm : Pairwise fun i j => ∀ (x : N i) (y : N j), Commute ((ϕ i) x) ((ϕ j) y)
f g : (i : ι) → N i
⊢ (fun f =>
        Finset.noncommProd Finset.univ (fun i => (ϕ i) (f i))
          (_ : ∀ i ∈ ↑Finset.univ, ∀ j ∈ ↑Finset.univ, i ≠ j → Commute ((ϕ i) (f i)) ((ϕ j) (f j))))
      1 =
    1

Next tactic:
apply (Finset.noncommProd_eq_pow_card _ _ _ _ _).trans (one_pow _)
/-- The canonical homomorphism from a family of monoids. -/
@[to_additive "The canonical homomorphism from a family of additive monoids. See also
`LinearMap.lsum` for a linear version without the commutativity assumption."]
def noncommPiCoprod : (∀ i : ι, N i) →* M
    where
  toFun f := Finset.univ.noncommProd (fun i => ϕ i (f i)) fun i _ j _ h => hcomm h _ _
  map_one' := by
    apply (Finset.noncommProd_eq_pow_card _ _ _ _ _).trans (one_pow _)
    

Proof state:
M : Type u_1
inst✝² : Monoid M
ι : Type u_2
hdec : DecidableEq ι
inst✝¹ : Fintype ι
N : ι → Type u_3
inst✝ : (i : ι) → Monoid (N i)
ϕ : (i : ι) → N i →* M
hcomm : Pairwise fun i j => ∀ (x : N i) (y : N j), Commute ((ϕ i) x) ((ϕ j) y)
f g : (i : ι) → N i
⊢ ∀ x ∈ Finset.univ, (ϕ x) (OfNat.ofNat 1 x) = 1

Next tactic:
simp
/-- The canonical homomorphism from a family of monoids. -/
@[to_additive "The canonical homomorphism from a family of additive monoids. See also
`LinearMap.lsum` for a linear version without the commutativity assumption."]
def noncommPiCoprod : (∀ i : ι, N i) →* M
    where
  toFun f := Finset.univ.noncommProd (fun i => ϕ i (f i)) fun i _ j _ h => hcomm h _ _
  map_one' := by
    apply (Finset.noncommProd_eq_pow_card _ _ _ _ _).trans (one_pow _)
    simp
  map_mul' f g := by
    

Proof state:
M : Type u_1
inst✝² : Monoid M
ι : Type u_2
hdec : DecidableEq ι
inst✝¹ : Fintype ι
N : ι → Type u_3
inst✝ : (i : ι) → Monoid (N i)
ϕ : (i : ι) → N i →* M
hcomm : Pairwise fun i j => ∀ (x : N i) (y : N j), Commute ((ϕ i) x) ((ϕ j) y)
f✝ g✝ f g : (i : ι) → N i
⊢ OneHom.toFun
      {
        toFun := fun f =>
          Finset.noncommProd Finset.univ (fun i => (ϕ i) (f i))
            (_ : ∀ i ∈ ↑Finset.univ, ∀ j ∈ ↑Finset.univ, i ≠ j → Commute ((ϕ i) (f i)) ((ϕ j) (f j))),
        map_one' :=
          (_ :
            Finset.noncommProd Finset.univ (fun i => (ϕ i) (OfNat.ofNat 1 i))
                (_ :
                  ∀ i ∈ ↑Finset.univ,
                    ∀ j ∈ ↑Finset.univ, i ≠ j → Commute ((ϕ i) (OfNat.ofNat 1 i)) ((ϕ j) (OfNat.ofNat 1 j))) =
              1) }
      (f * g) =
    OneHom.toFun
        {
          toFun := fun f =>
            Finset.noncommProd Finset.univ (fun i => (ϕ i) (f i))
              (_ : ∀ i ∈ ↑Finset.univ, ∀ j ∈ ↑Finset.univ, i ≠ j → Commute ((ϕ i) (f i)) ((ϕ j) (f j))),
          map_one' :=
            (_ :
              Finset.noncommProd Finset.univ (fun i => (ϕ i) (OfNat.ofNat 1 i))
                  (_ :
                    ∀ i ∈ ↑Finset.univ,
                      ∀ j ∈ ↑Finset.univ, i ≠ j → Commute ((ϕ i) (OfNat.ofNat 1 i)) ((ϕ j) (OfNat.ofNat 1 j))) =
                1) }
        f *
      OneHom.toFun
        {
          toFun := fun f =>
            Finset.noncommProd Finset.univ (fun i => (ϕ i) (f i))
              (_ : ∀ i ∈ ↑Finset.univ, ∀ j ∈ ↑Finset.univ, i ≠ j → Commute ((ϕ i) (f i)) ((ϕ j) (f j))),
          map_one' :=
            (_ :
              Finset.noncommProd Finset.univ (fun i => (ϕ i) (OfNat.ofNat 1 i))
                  (_ :
                    ∀ i ∈ ↑Finset.univ,
                      ∀ j ∈ ↑Finset.univ, i ≠ j → Commute ((ϕ i) (OfNat.ofNat 1 i)) ((ϕ j) (OfNat.ofNat 1 j))) =
                1) }
        g

Next tactic:
classical
    simp only
    convert @Finset.noncommProd_mul_distrib _ _ _ _ (fun i => ϕ i (f i)) (fun i => ϕ i (g i)) _ _ _
    · exact map_mul _ _ _
    · rintro i - j - h
      exact hcomm h _ _
/-- The canonical homomorphism from a family of monoids. -/
@[to_additive "The canonical homomorphism from a family of additive monoids. See also
`LinearMap.lsum` for a linear version without the commutativity assumption."]
def noncommPiCoprod : (∀ i : ι, N i) →* M
    where
  toFun f := Finset.univ.noncommProd (fun i => ϕ i (f i)) fun i _ j _ h => hcomm h _ _
  map_one' := by
    apply (Finset.noncommProd_eq_pow_card _ _ _ _ _).trans (one_pow _)
    simp
  map_mul' f g := by
    classical
    

Proof state:
M : Type u_1
inst✝² : Monoid M
ι : Type u_2
hdec : DecidableEq ι
inst✝¹ : Fintype ι
N : ι → Type u_3
inst✝ : (i : ι) → Monoid (N i)
ϕ : (i : ι) → N i →* M
hcomm : Pairwise fun i j => ∀ (x : N i) (y : N j), Commute ((ϕ i) x) ((ϕ j) y)
f✝ g✝ f g : (i : ι) → N i
⊢ OneHom.toFun
      {
        toFun := fun f =>
          Finset.noncommProd Finset.univ (fun i => (ϕ i) (f i))
            (_ : ∀ i ∈ ↑Finset.univ, ∀ j ∈ ↑Finset.univ, i ≠ j → Commute ((ϕ i) (f i)) ((ϕ j) (f j))),
        map_one' :=
          (_ :
            Finset.noncommProd Finset.univ (fun i => (ϕ i) (OfNat.ofNat 1 i))
                (_ :
                  ∀ i ∈ ↑Finset.univ,
                    ∀ j ∈ ↑Finset.univ, i ≠ j → Commute ((ϕ i) (OfNat.ofNat 1 i)) ((ϕ j) (OfNat.ofNat 1 j))) =
              1) }
      (f * g) =
    OneHom.toFun
        {
          toFun := fun f =>
            Finset.noncommProd Finset.univ (fun i => (ϕ i) (f i))
              (_ : ∀ i ∈ ↑Finset.univ, ∀ j ∈ ↑Finset.univ, i ≠ j → Commute ((ϕ i) (f i)) ((ϕ j) (f j))),
          map_one' :=
            (_ :
              Finset.noncommProd Finset.univ (fun i => (ϕ i) (OfNat.ofNat 1 i))
                  (_ :
                    ∀ i ∈ ↑Finset.univ,
                      ∀ j ∈ ↑Finset.univ, i ≠ j → Commute ((ϕ i) (OfNat.ofNat 1 i)) ((ϕ j) (OfNat.ofNat 1 j))) =
                1) }
        f *
      OneHom.toFun
        {
          toFun := fun f =>
            Finset.noncommProd Finset.univ (fun i => (ϕ i) (f i))
              (_ : ∀ i ∈ ↑Finset.univ, ∀ j ∈ ↑Finset.univ, i ≠ j → Commute ((ϕ i) (f i)) ((ϕ j) (f j))),
          map_one' :=
            (_ :
              Finset.noncommProd Finset.univ (fun i => (ϕ i) (OfNat.ofNat 1 i))
                  (_ :
                    ∀ i ∈ ↑Finset.univ,
                      ∀ j ∈ ↑Finset.univ, i ≠ j → Commute ((ϕ i) (OfNat.ofNat 1 i)) ((ϕ j) (OfNat.ofNat 1 j))) =
                1) }
        g

Next tactic:
simp only
/-- The canonical homomorphism from a family of monoids. -/
@[to_additive "The canonical homomorphism from a family of additive monoids. See also
`LinearMap.lsum` for a linear version without the commutativity assumption."]
def noncommPiCoprod : (∀ i : ι, N i) →* M
    where
  toFun f := Finset.univ.noncommProd (fun i => ϕ i (f i)) fun i _ j _ h => hcomm h _ _
  map_one' := by
    apply (Finset.noncommProd_eq_pow_card _ _ _ _ _).trans (one_pow _)
    simp
  map_mul' f g := by
    classical
    simp only
    

Proof state:
M : Type u_1
inst✝² : Monoid M
ι : Type u_2
hdec : DecidableEq ι
inst✝¹ : Fintype ι
N : ι → Type u_3
inst✝ : (i : ι) → Monoid (N i)
ϕ : (i : ι) → N i →* M
hcomm : Pairwise fun i j => ∀ (x : N i) (y : N j), Commute ((ϕ i) x) ((ϕ j) y)
f✝ g✝ f g : (i : ι) → N i
⊢ Finset.noncommProd Finset.univ (fun i => (ϕ i) ((f * g) i))
      (_ : ∀ i ∈ ↑Finset.univ, ∀ j ∈ ↑Finset.univ, i ≠ j → Commute ((ϕ i) ((f * g) i)) ((ϕ j) ((f * g) j))) =
    Finset.noncommProd Finset.univ (fun i => (ϕ i) (f i))
        (_ : ∀ i ∈ ↑Finset.univ, ∀ j ∈ ↑Finset.univ, i ≠ j → Commute ((ϕ i) (f i)) ((ϕ j) (f j))) *
      Finset.noncommProd Finset.univ (fun i => (ϕ i) (g i))
        (_ : ∀ i ∈ ↑Finset.univ, ∀ j ∈ ↑Finset.univ, i ≠ j → Commute ((ϕ i) (g i)) ((ϕ j) (g j)))

Next tactic:
convert @Finset.noncommProd_mul_distrib _ _ _ _ (fun i => ϕ i (f i)) (fun i => ϕ i (g i)) _ _ _
/-- The canonical homomorphism from a family of monoids. -/
@[to_additive "The canonical homomorphism from a family of additive monoids. See also
`LinearMap.lsum` for a linear version without the commutativity assumption."]
def noncommPiCoprod : (∀ i : ι, N i) →* M
    where
  toFun f := Finset.univ.noncommProd (fun i => ϕ i (f i)) fun i _ j _ h => hcomm h _ _
  map_one' := by
    apply (Finset.noncommProd_eq_pow_card _ _ _ _ _).trans (one_pow _)
    simp
  map_mul' f g := by
    classical
    simp only
    convert @Finset.noncommProd_mul_distrib _ _ _ _ (fun i => ϕ i (f i)) (fun i => ϕ i (g i)) _ _ _
    · 

Proof state:
case h.e'_2.h₂
M : Type u_1
inst✝² : Monoid M
ι : Type u_2
hdec : DecidableEq ι
inst✝¹ : Fintype ι
N : ι → Type u_3
inst✝ : (i : ι) → Monoid (N i)
ϕ : (i : ι) → N i →* M
hcomm : Pairwise fun i j => ∀ (x : N i) (y : N j), Commute ((ϕ i) x) ((ϕ j) y)
f✝ g✝ f g : (i : ι) → N i
x✝ : ι
a✝ : x✝ ∈ Finset.univ
⊢ (ϕ x✝) ((f * g) x✝) = ((fun i => (ϕ i) (f i)) * fun i => (ϕ i) (g i)) x✝

Next tactic:
exact map_mul _ _ _
/-- The canonical homomorphism from a family of monoids. -/
@[to_additive "The canonical homomorphism from a family of additive monoids. See also
`LinearMap.lsum` for a linear version without the commutativity assumption."]
def noncommPiCoprod : (∀ i : ι, N i) →* M
    where
  toFun f := Finset.univ.noncommProd (fun i => ϕ i (f i)) fun i _ j _ h => hcomm h _ _
  map_one' := by
    apply (Finset.noncommProd_eq_pow_card _ _ _ _ _).trans (one_pow _)
    simp
  map_mul' f g := by
    classical
    simp only
    convert @Finset.noncommProd_mul_distrib _ _ _ _ (fun i => ϕ i (f i)) (fun i => ϕ i (g i)) _ _ _
    · exact map_mul _ _ _
    · 

Proof state:
case convert_4
M : Type u_1
inst✝² : Monoid M
ι : Type u_2
hdec : DecidableEq ι
inst✝¹ : Fintype ι
N : ι → Type u_3
inst✝ : (i : ι) → Monoid (N i)
ϕ : (i : ι) → N i →* M
hcomm : Pairwise fun i j => ∀ (x : N i) (y : N j), Commute ((ϕ i) x) ((ϕ j) y)
f✝ g✝ f g : (i : ι) → N i
⊢ Set.Pairwise ↑Finset.univ fun x y => Commute ((fun i => (ϕ i) (g i)) x) ((fun i => (ϕ i) (f i)) y)

Next tactic:
rintro i - j - h
/-- The canonical homomorphism from a family of monoids. -/
@[to_additive "The canonical homomorphism from a family of additive monoids. See also
`LinearMap.lsum` for a linear version without the commutativity assumption."]
def noncommPiCoprod : (∀ i : ι, N i) →* M
    where
  toFun f := Finset.univ.noncommProd (fun i => ϕ i (f i)) fun i _ j _ h => hcomm h _ _
  map_one' := by
    apply (Finset.noncommProd_eq_pow_card _ _ _ _ _).trans (one_pow _)
    simp
  map_mul' f g := by
    classical
    simp only
    convert @Finset.noncommProd_mul_distrib _ _ _ _ (fun i => ϕ i (f i)) (fun i => ϕ i (g i)) _ _ _
    · exact map_mul _ _ _
    · rintro i - j - h
      

Proof state:
case convert_4
M : Type u_1
inst✝² : Monoid M
ι : Type u_2
hdec : DecidableEq ι
inst✝¹ : Fintype ι
N : ι → Type u_3
inst✝ : (i : ι) → Monoid (N i)
ϕ : (i : ι) → N i →* M
hcomm : Pairwise fun i j => ∀ (x : N i) (y : N j), Commute ((ϕ i) x) ((ϕ j) y)
f✝ g✝ f g : (i : ι) → N i
i j : ι
h : i ≠ j
⊢ Commute ((fun i => (ϕ i) (g i)) i) ((fun i => (ϕ i) (f i)) j)

Next tactic:
exact hcomm h _ _
@[to_additive (attr := simp)]
theorem noncommPiCoprod_mulSingle (i : ι) (y : N i) :
    noncommPiCoprod ϕ hcomm (Pi.mulSingle i y) = ϕ i y := by
  

Proof state:
M : Type u_1
inst✝² : Monoid M
ι : Type u_2
hdec : DecidableEq ι
inst✝¹ : Fintype ι
N : ι → Type u_3
inst✝ : (i : ι) → Monoid (N i)
ϕ : (i : ι) → N i →* M
hcomm : Pairwise fun i j => ∀ (x : N i) (y : N j), Commute ((ϕ i) x) ((ϕ j) y)
f g : (i : ι) → N i
i : ι
y : N i
⊢ (noncommPiCoprod ϕ hcomm) (Pi.mulSingle i y) = (ϕ i) y

Next tactic:
change Finset.univ.noncommProd (fun j => ϕ j (Pi.mulSingle i y j)) (fun _ _ _ _ h => hcomm h _ _)
    = ϕ i y
@[to_additive (attr := simp)]
theorem noncommPiCoprod_mulSingle (i : ι) (y : N i) :
    noncommPiCoprod ϕ hcomm (Pi.mulSingle i y) = ϕ i y := by
  change Finset.univ.noncommProd (fun j => ϕ j (Pi.mulSingle i y j)) (fun _ _ _ _ h => hcomm h _ _)
    = ϕ i y
  

Proof state:
M : Type u_1
inst✝² : Monoid M
ι : Type u_2
hdec : DecidableEq ι
inst✝¹ : Fintype ι
N : ι → Type u_3
inst✝ : (i : ι) → Monoid (N i)
ϕ : (i : ι) → N i →* M
hcomm : Pairwise fun i j => ∀ (x : N i) (y : N j), Commute ((ϕ i) x) ((ϕ j) y)
f g : (i : ι) → N i
i : ι
y : N i
⊢ Finset.noncommProd Finset.univ (fun j => (ϕ j) (Pi.mulSingle i y j))
      (_ :
        ∀ x ∈ ↑Finset.univ,
          ∀ x_2 ∈ ↑Finset.univ, x ≠ x_2 → Commute ((ϕ x) (Pi.mulSingle i y x)) ((ϕ x_2) (Pi.mulSingle i y x_2))) =
    (ϕ i) y

Next tactic:
simp (config := { singlePass := true }) only [← Finset.insert_erase (Finset.mem_univ i)]
@[to_additive (attr := simp)]
theorem noncommPiCoprod_mulSingle (i : ι) (y : N i) :
    noncommPiCoprod ϕ hcomm (Pi.mulSingle i y) = ϕ i y := by
  change Finset.univ.noncommProd (fun j => ϕ j (Pi.mulSingle i y j)) (fun _ _ _ _ h => hcomm h _ _)
    = ϕ i y
  simp (config := { singlePass := true }) only [← Finset.insert_erase (Finset.mem_univ i)]
  

Proof state:
M : Type u_1
inst✝² : Monoid M
ι : Type u_2
hdec : DecidableEq ι
inst✝¹ : Fintype ι
N : ι → Type u_3
inst✝ : (i : ι) → Monoid (N i)
ϕ : (i : ι) → N i →* M
hcomm : Pairwise fun i j => ∀ (x : N i) (y : N j), Commute ((ϕ i) x) ((ϕ j) y)
f g : (i : ι) → N i
i : ι
y : N i
⊢ Finset.noncommProd (insert i (Finset.erase Finset.univ i)) (fun x => (ϕ x) (Pi.mulSingle i y x))
      (_ :
        ∀ x ∈ ↑(insert i (Finset.erase Finset.univ i)),
          ∀ y_1 ∈ ↑(insert i (Finset.erase Finset.univ i)),
            x ≠ y_1 → (fun a b => Commute ((ϕ a) (Pi.mulSingle i y a)) ((ϕ b) (Pi.mulSingle i y b))) x y_1) =
    (ϕ i) y

Next tactic:
rw [Finset.noncommProd_insert_of_not_mem _ _ _ _ (Finset.not_mem_erase i _)]
@[to_additive (attr := simp)]
theorem noncommPiCoprod_mulSingle (i : ι) (y : N i) :
    noncommPiCoprod ϕ hcomm (Pi.mulSingle i y) = ϕ i y := by
  change Finset.univ.noncommProd (fun j => ϕ j (Pi.mulSingle i y j)) (fun _ _ _ _ h => hcomm h _ _)
    = ϕ i y
  simp (config := { singlePass := true }) only [← Finset.insert_erase (Finset.mem_univ i)]
  rw [Finset.noncommProd_insert_of_not_mem _ _ _ _ (Finset.not_mem_erase i _)]
  

Proof state:
M : Type u_1
inst✝² : Monoid M
ι : Type u_2
hdec : DecidableEq ι
inst✝¹ : Fintype ι
N : ι → Type u_3
inst✝ : (i : ι) → Monoid (N i)
ϕ : (i : ι) → N i →* M
hcomm : Pairwise fun i j => ∀ (x : N i) (y : N j), Commute ((ϕ i) x) ((ϕ j) y)
f g : (i : ι) → N i
i : ι
y : N i
⊢ (ϕ i) (Pi.mulSingle i y i) *
      Finset.noncommProd (Finset.erase Finset.univ i) (fun x => (ϕ x) (Pi.mulSingle i y x))
        (_ :
          Set.Pairwise ↑(Finset.erase Finset.univ i) fun a b =>
            Commute ((ϕ a) (Pi.mulSingle i y a)) ((ϕ b) (Pi.mulSingle i y b))) =
    (ϕ i) y

Next tactic:
rw [Pi.mulSingle_eq_same]
@[to_additive (attr := simp)]
theorem noncommPiCoprod_mulSingle (i : ι) (y : N i) :
    noncommPiCoprod ϕ hcomm (Pi.mulSingle i y) = ϕ i y := by
  change Finset.univ.noncommProd (fun j => ϕ j (Pi.mulSingle i y j)) (fun _ _ _ _ h => hcomm h _ _)
    = ϕ i y
  simp (config := { singlePass := true }) only [← Finset.insert_erase (Finset.mem_univ i)]
  rw [Finset.noncommProd_insert_of_not_mem _ _ _ _ (Finset.not_mem_erase i _)]
  rw [Pi.mulSingle_eq_same]
  

Proof state:
M : Type u_1
inst✝² : Monoid M
ι : Type u_2
hdec : DecidableEq ι
inst✝¹ : Fintype ι
N : ι → Type u_3
inst✝ : (i : ι) → Monoid (N i)
ϕ : (i : ι) → N i →* M
hcomm : Pairwise fun i j => ∀ (x : N i) (y : N j), Commute ((ϕ i) x) ((ϕ j) y)
f g : (i : ι) → N i
i : ι
y : N i
⊢ (ϕ i) y *
      Finset.noncommProd (Finset.erase Finset.univ i) (fun x => (ϕ x) (Pi.mulSingle i y x))
        (_ :
          Set.Pairwise ↑(Finset.erase Finset.univ i) fun a b =>
            Commute ((ϕ a) (Pi.mulSingle i y a)) ((ϕ b) (Pi.mulSingle i y b))) =
    (ϕ i) y

Next tactic:
rw [Finset.noncommProd_eq_pow_card]
@[to_additive (attr := simp)]
theorem noncommPiCoprod_mulSingle (i : ι) (y : N i) :
    noncommPiCoprod ϕ hcomm (Pi.mulSingle i y) = ϕ i y := by
  change Finset.univ.noncommProd (fun j => ϕ j (Pi.mulSingle i y j)) (fun _ _ _ _ h => hcomm h _ _)
    = ϕ i y
  simp (config := { singlePass := true }) only [← Finset.insert_erase (Finset.mem_univ i)]
  rw [Finset.noncommProd_insert_of_not_mem _ _ _ _ (Finset.not_mem_erase i _)]
  rw [Pi.mulSingle_eq_same]
  rw [Finset.noncommProd_eq_pow_card]
  · 

Proof state:
M : Type u_1
inst✝² : Monoid M
ι : Type u_2
hdec : DecidableEq ι
inst✝¹ : Fintype ι
N : ι → Type u_3
inst✝ : (i : ι) → Monoid (N i)
ϕ : (i : ι) → N i →* M
hcomm : Pairwise fun i j => ∀ (x : N i) (y : N j), Commute ((ϕ i) x) ((ϕ j) y)
f g : (i : ι) → N i
i : ι
y : N i
⊢ (ϕ i) y * ?m ^ Finset.card (Finset.erase Finset.univ i) = (ϕ i) y

Next tactic:
rw [one_pow]
@[to_additive (attr := simp)]
theorem noncommPiCoprod_mulSingle (i : ι) (y : N i) :
    noncommPiCoprod ϕ hcomm (Pi.mulSingle i y) = ϕ i y := by
  change Finset.univ.noncommProd (fun j => ϕ j (Pi.mulSingle i y j)) (fun _ _ _ _ h => hcomm h _ _)
    = ϕ i y
  simp (config := { singlePass := true }) only [← Finset.insert_erase (Finset.mem_univ i)]
  rw [Finset.noncommProd_insert_of_not_mem _ _ _ _ (Finset.not_mem_erase i _)]
  rw [Pi.mulSingle_eq_same]
  rw [Finset.noncommProd_eq_pow_card]
  · rw [one_pow]
    

Proof state:
M : Type u_1
inst✝² : Monoid M
ι : Type u_2
hdec : DecidableEq ι
inst✝¹ : Fintype ι
N : ι → Type u_3
inst✝ : (i : ι) → Monoid (N i)
ϕ : (i : ι) → N i →* M
hcomm : Pairwise fun i j => ∀ (x : N i) (y : N j), Commute ((ϕ i) x) ((ϕ j) y)
f g : (i : ι) → N i
i : ι
y : N i
⊢ (ϕ i) y * 1 = (ϕ i) y

Next tactic:
exact mul_one _
@[to_additive (attr := simp)]
theorem noncommPiCoprod_mulSingle (i : ι) (y : N i) :
    noncommPiCoprod ϕ hcomm (Pi.mulSingle i y) = ϕ i y := by
  change Finset.univ.noncommProd (fun j => ϕ j (Pi.mulSingle i y j)) (fun _ _ _ _ h => hcomm h _ _)
    = ϕ i y
  simp (config := { singlePass := true }) only [← Finset.insert_erase (Finset.mem_univ i)]
  rw [Finset.noncommProd_insert_of_not_mem _ _ _ _ (Finset.not_mem_erase i _)]
  rw [Pi.mulSingle_eq_same]
  rw [Finset.noncommProd_eq_pow_card]
  · rw [one_pow]
    exact mul_one _
  · 

Proof state:
case h
M : Type u_1
inst✝² : Monoid M
ι : Type u_2
hdec : DecidableEq ι
inst✝¹ : Fintype ι
N : ι → Type u_3
inst✝ : (i : ι) → Monoid (N i)
ϕ : (i : ι) → N i →* M
hcomm : Pairwise fun i j => ∀ (x : N i) (y : N j), Commute ((ϕ i) x) ((ϕ j) y)
f g : (i : ι) → N i
i : ι
y : N i
⊢ ∀ x ∈ Finset.erase Finset.univ i, (ϕ x) (Pi.mulSingle i y x) = 1

Next tactic:
intro j hj
@[to_additive (attr := simp)]
theorem noncommPiCoprod_mulSingle (i : ι) (y : N i) :
    noncommPiCoprod ϕ hcomm (Pi.mulSingle i y) = ϕ i y := by
  change Finset.univ.noncommProd (fun j => ϕ j (Pi.mulSingle i y j)) (fun _ _ _ _ h => hcomm h _ _)
    = ϕ i y
  simp (config := { singlePass := true }) only [← Finset.insert_erase (Finset.mem_univ i)]
  rw [Finset.noncommProd_insert_of_not_mem _ _ _ _ (Finset.not_mem_erase i _)]
  rw [Pi.mulSingle_eq_same]
  rw [Finset.noncommProd_eq_pow_card]
  · rw [one_pow]
    exact mul_one _
  · intro j hj
    

Proof state:
case h
M : Type u_1
inst✝² : Monoid M
ι : Type u_2
hdec : DecidableEq ι
inst✝¹ : Fintype ι
N : ι → Type u_3
inst✝ : (i : ι) → Monoid (N i)
ϕ : (i : ι) → N i →* M
hcomm : Pairwise fun i j => ∀ (x : N i) (y : N j), Commute ((ϕ i) x) ((ϕ j) y)
f g : (i : ι) → N i
i : ι
y : N i
j : ι
hj : j ∈ Finset.erase Finset.univ i
⊢ (ϕ j) (Pi.mulSingle i y j) = 1

Next tactic:
simp only [Finset.mem_erase] at hj